Skip to content

Commit

Permalink
[CapturedMouseEvents] Export web platform tests (web-platform-tests#4…
Browse files Browse the repository at this point in the history
…0868)

This patch exports existing WPT tests added in [1], using the directory
recently introduced in [2] and taking into account the recent renaming
to "captured mouse events".

It also adds a manual test that is verified to pass with [3] applied.
WPT does not provide support for more complex and automated tests,
so this is just a minimal verification. More advanced internal tests
with wider coverage will be added in [3].

[1] https://chromium-review.googlesource.com/c/chromium/src/+/4517372
[2] web-platform-tests#40826
[3] https://chromium-review.googlesource.com/c/chromium/src/+/4549484

Bug: 1444712
Change-Id: I8ed455c406d6cba81cb4df0651509b6d6f7bd991
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4661012
Commit-Queue: Frédéric Wang <[email protected]>
Reviewed-by: Elad Alon <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1167752}

Co-authored-by: Frédéric Wang <[email protected]>
  • Loading branch information
chromium-wpt-export-bot and fred-wang authored Jul 8, 2023
1 parent eaf2ccf commit 72a4f49
Show file tree
Hide file tree
Showing 6 changed files with 257 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<!doctype html>
<meta charset=utf-8>
<link rel='help' href='https://screen-share.github.io/captured-mouse-events/#capture-controller-extensions'>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
test(() => {
const controller = new CaptureController();
assert_equals(controller.oncapturedmousechange, null);
}, "oncapturedmousechange is initially unset");

test(() => {
const controller = new CaptureController();
let result = undefined;
controller.oncapturedmousechange = (e) => {
result = {
target: e.currentTarget,
surfaceX: e.surfaceX,
surfaceY: e.surfaceY,
};
};
const init = {surfaceX: 5, surfaceY: 7};
controller.dispatchEvent(
new CapturedMouseEvent("capturedmousechange", init)
);
assert_equals(result.target, controller);
assert_equals(result.surfaceX, init.surfaceX);
assert_equals(result.surfaceY, init.surfaceY);
}, "dispatching a CapturedMouseEvent on CaptureController should trigger oncapturedmousechange");
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<!doctype html>
<meta charset=utf-8>
<link rel='help' href='https://screen-share.github.io/captured-mouse-events/#captured-mouse-change-event'>
<link rel='help' href='https://dom.spec.whatwg.org/#event'>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
test(() => {
assert_equals((new CapturedMouseEvent("custom")).type, "custom");
}, "type argument is passed to the Event's constructor");

const inherited_options = ["bubbles", "cancelable", "composed"];
test(() => {
const event = new CapturedMouseEvent("");
inherited_options.forEach(name => {
assert_equals(event[name], false, `event.${name} with default eventInitDict`);
});

inherited_options.forEach(name => {
const options = {};
options[name] = true;
const event = new CapturedMouseEvent("", options);
inherited_options.forEach(other_name => {
assert_equals(event[other_name], other_name == name,
`event.${other_name} with eventInitDict={${name}: true}`);
});
});
}, "EventInit options are passed to the Event's constructor");
</script>
68 changes: 68 additions & 0 deletions captured-mouse-events/captured-mouse-event-constructor.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<!doctype html>
<meta charset=utf-8>
<link rel='help' href='https://screen-share.github.io/captured-mouse-events/#captured-mouse-change-event'>
<link rel='help' href='https://screen-share.github.io/captured-mouse-events/#captured-mouse-change-event-init'>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
// See https://webidl.spec.whatwg.org/#idl-long
const maxLongValue = 2147483647;

test(() => {
assert_throws_js(TypeError, () => new CapturedMouseEvent());
}, "type argument is mandatory");

test(() => {
[
{surfaceX: -5, surfaceY: -5}, /* X, Y negative */
{surfaceX: -5, surfaceY: +5}, /* X negative, Y non-negative */
{surfaceX: +5, surfaceY: -5}, /* X non-negative, Y negative */
{surfaceX: -1, surfaceY: +5}, /* X equal to -1, Y non-negative */
{/* surfaceX: -1, */ surfaceY: +5}, /* Same with implicit surfaceX */
{surfaceX: +5, surfaceY: -1}, /* X non-negative, Y equal to -1 */
{surfaceX: +5 /*, surfaceY: -1 */}, /* Same with implicit surfaceY */
{surfaceX: maxLongValue+1, surfaceY: +5}, /* 'long' overflow for X */
{surfaceX: +5, surfaceY: maxLongValue+1}, /* 'long' overflow for Y */
].forEach(init => {
assert_throws_js(RangeError, () => new CapturedMouseEvent("", init),
`eventInitDict=${JSON.stringify(init)}`);
});
}, "Invalid surfaceX/surfaceY options cause a RangeError to be thrown");

test(() => {
[
{surfaceX: +5, surfaceY: +7}, /* Two positive values */
{surfaceX: -1, surfaceY: -1}, /* Valid case with negative values */
{surfaceX: 0, surfaceY: 0}, /* Minimal non-negative values */
{surfaceX: 0, surfaceY: 5}, /* Minimal non-negative X and positive Y */
{surfaceX: 5, surfaceY: 0}, /* Positive X and minimal non-negative Y */
{surfaceX: maxLongValue, surfaceY: maxLongValue}, /* Maximal values */
].forEach(init => {
let event = new CapturedMouseEvent("", init);
assert_equals(event.surfaceX, init.surfaceX,
`surfaceX with eventInitDict=${JSON.stringify(init)}`);
assert_equals(event.surfaceY, init.surfaceY,
`surfaceY with eventInitDict=${JSON.stringify(init)}`);
});
}, "Valid surfaceX/surfaceY options are used as initial values");

test(() => {
let event = new CapturedMouseEvent("");
assert_equals(event.surfaceX, -1,
`surfaceX with implicit eventInitDict={}`);
assert_equals(event.surfaceY, -1,
`surfaceY with implicit eventInitDict={}`);

[
{},
{surfaceX: -1},
{surfaceY: -1},
].forEach(init => {
let event = new CapturedMouseEvent("", init);
assert_equals(event.surfaceX, -1,
`surfaceX with eventInitDict=${JSON.stringify(init)}`);
assert_equals(event.surfaceY, -1,
`surfaceY with eventInitDict=${JSON.stringify(init)}`);
});
}, "surfaceX/surfaceY default to -1");
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
<!DOCTYPE html>
<meta charset="utf-8" />
<h1>Capturing mouse coordinates</h1>
<link rel="help" href="https://screen-share.github.io/captured-mouse-events" />
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>
li.highlight {
font-weight: bold;
}
#latest_captured_mouse_event {
font-family: monospace;
}
</style>
<ol class="instructions">
<li>
<button id="start_capture">Click here</button> and share this window as a
captured surface.
</li>
<li>Move the mouse near the top left corner of the window.</li>
<li>Move the mouse near the top right corner of the window.</li>
<li>Move the mouse near the bottom right corner of the window.</li>
<li>Move the mouse near the bottom left corner of the window.</li>
<li>Move the mouse near the center of the window.</li>
<li>Move the mouse outside the window.</li>
<li>Move the mouse inside the window.</li>
</ol>
<pre id="log"></pre>
<video width="1024" height="512" id="captured_content" autoplay></video>
<div id="latest_captured_mouse_event"></div>
<script>
setup({explicit_timeout: true});

const items = document.querySelectorAll('ol.instructions > li');
let highlighted_item_index = 0;
function clear_all_highlight() {
Array.from(items).forEach(item => item.classList.remove('highlight'));
}
function highlight_next_item() {
clear_all_highlight();
items[highlighted_item_index].classList.add('highlight');
highlighted_item_index++;
}
add_completion_callback(clear_all_highlight);

let capture_controller;
let latest_captured_mouse_event_index = 0;
function observe_mouse_coordinates(check_condition) {
assert_true(!!capture_controller, 'Screen capture started.');
assert_own_property(window, 'CapturedMouseEvent');
return new Promise(resolve => {
const listener = (event) => {
if (check_condition(event.surfaceX, event.surfaceY)) {
capture_controller.removeEventListener(
'capturedmousechange', listener);
resolve();
}
};
capture_controller.addEventListener('capturedmousechange', listener);
});
}

promise_test(async () => {
assert_own_property(window, 'CaptureController');
const controller = new CaptureController();
highlight_next_item();
await new Promise(resolve => {
document.getElementById('start_capture')
.addEventListener('click', (event) => {
event.target.disabled = true;
resolve();
});
});
const video = document.getElementById('captured_content');
video.srcObject =
await navigator.mediaDevices.getDisplayMedia({controller});
await new Promise(resolve => video.onloadedmetadata = resolve);
controller.addEventListener('capturedmousechange', (event) => {
document.getElementById('latest_captured_mouse_event').textContent =
`Last event (#${++latest_captured_mouse_event_index}) observed at ${
(new Date()).toTimeString()}, was {surfaceX: ${
event.surfaceX}, surfaceY: ${event.surfaceY}}.`;
});
capture_controller = controller;
}, 'Starting Screen Capture');

const max_distance = 100;
[{x: 0, y: 0, name: 'top left corner'},
{x: window.outerWidth, y: 0, name: 'top right corner'},
{x: window.outerWidth, y: window.outerHeight, name: 'bottom right corner'},
{x: 0, y: window.outerHeight, name: 'bottom left corner'},
{x: window.outerWidth / 2, y: window.outerHeight / 2, name: 'center'},
].forEach(target => {
promise_test(async () => {
highlight_next_item();
assert_less_than(
max_distance, Math.min(window.outerWidth, window.outerHeight) / 4,
'window is large enough');
await observe_mouse_coordinates((x, y) => {
return x >= 0 && y >= 0 &&
Math.hypot(target.x - x, target.y - y) < max_distance;
})
}, `Moving mouse to the ${target.name} of the window.`);
});

promise_test(async () => {
highlight_next_item();
await observe_mouse_coordinates((x, y) => {
return x == -1 && y == -1;
})
}, `Moving mouse outside the window.`);

promise_test(async () => {
highlight_next_item();
await observe_mouse_coordinates((x, y) => {
return x >= 0 && y >= 0;
})
}, `Moving mouse inside the window.`);
</script>
11 changes: 11 additions & 0 deletions captured-mouse-events/idlharness.https.window.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// META: script=/resources/WebIDLParser.js
// META: script=/resources/idlharness.js

'use strict';

// https://screen-share.github.io/captured-mouse-events/

idl_test(
['captured-mouse-events.tentative'],
['html', 'dom']
);

0 comments on commit 72a4f49

Please sign in to comment.