summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/pointerlock
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/pointerlock')
-rw-r--r--testing/web-platform/tests/pointerlock/OWNERS2
-rw-r--r--testing/web-platform/tests/pointerlock/constructor.html53
-rw-r--r--testing/web-platform/tests/pointerlock/idlharness.html85
-rw-r--r--testing/web-platform/tests/pointerlock/movementX_Y_basic-manual.html124
-rw-r--r--testing/web-platform/tests/pointerlock/movementX_Y_no-jumps-manual.html140
-rw-r--r--testing/web-platform/tests/pointerlock/pointerlock_basic-manual.html149
-rw-r--r--testing/web-platform/tests/pointerlock/pointerlock_fullscreen-manual.html173
-rw-r--r--testing/web-platform/tests/pointerlock/pointerlock_indefinite-manual.html107
-rw-r--r--testing/web-platform/tests/pointerlock/pointerlock_leave_Tab-manual.html85
-rw-r--r--testing/web-platform/tests/pointerlock/pointerlock_leave_UA-manual.html85
-rw-r--r--testing/web-platform/tests/pointerlock/pointerlock_remove_target-manual.html87
-rw-r--r--testing/web-platform/tests/pointerlock/pointerlock_shadow-manual.html83
12 files changed, 1173 insertions, 0 deletions
diff --git a/testing/web-platform/tests/pointerlock/OWNERS b/testing/web-platform/tests/pointerlock/OWNERS
new file mode 100644
index 000000000..640884d64
--- /dev/null
+++ b/testing/web-platform/tests/pointerlock/OWNERS
@@ -0,0 +1,2 @@
+@scheib
+@siusin \ No newline at end of file
diff --git a/testing/web-platform/tests/pointerlock/constructor.html b/testing/web-platform/tests/pointerlock/constructor.html
new file mode 100644
index 000000000..8c43cf6da
--- /dev/null
+++ b/testing/web-platform/tests/pointerlock/constructor.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Pointer Lock event constructor</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="http://www.w3.org/TR/pointerlock/#pointerlockchange-and-pointerlockerror-events">
+ <link rel="help" href="http://www.w3.org/TR/dom/#interface-event">
+ </head>
+ <body>
+ <p>Create Pointer Lock events and check each default value.</p>
+ <div id='log'></div>
+ <script>
+test(function() {
+ var ev = new MouseEvent("pointerlockchange");
+ assert_equals(ev.type, "pointerlockchange");
+ assert_equals(ev.target, null);
+ assert_equals(ev.currentTarget, null);
+ assert_equals(ev.bubbles, false);
+ assert_equals(ev.eventPhase, Event.NONE);
+ assert_equals(ev.cancelable, false);
+ assert_true("preventDefault" in ev);
+ assert_equals(ev.defaultPrevented, false);
+ assert_true(ev.timeStamp > 0);
+ assert_true("initEvent" in ev);
+ assert_true("movementX" in ev, "movementX exists");
+ assert_true("movementY" in ev, "movementY exists");
+ assert_equals(ev.movementX, 0);
+ assert_equals(ev.movementY, 0);
+}, "Default event values for mouse event interface and its pointer lock extensions.");
+test(function() {
+ var ev = new MouseEvent("pointerlockerror",
+ { type: "trololol",
+ bubbles: true,
+ cancelable: false,
+ get defaultPrevented() {
+ assert_unreached("Should not look at the defaultPrevented property.");
+ },
+ movementX: 10,
+ movementY: 10});
+ assert_equals(ev.type, "pointerlockerror");
+ assert_equals(ev.bubbles, true); // this is synthetic event, so follow the dictionary
+ assert_equals(ev.cancelable, false);
+ assert_equals(ev.defaultPrevented, false);
+ assert_equals(ev.movementX, 10); // this is synthetic event, so follow the dictionary
+ assert_equals(ev.movementY, 10); // this is synthetic event, so follow the dictionary
+}, "Default event values for pointerlockerror using a dictionary");
+ </script>
+
+</body>
+
+</html>
diff --git a/testing/web-platform/tests/pointerlock/idlharness.html b/testing/web-platform/tests/pointerlock/idlharness.html
new file mode 100644
index 000000000..aa876f58f
--- /dev/null
+++ b/testing/web-platform/tests/pointerlock/idlharness.html
@@ -0,0 +1,85 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Pointer Lock IDL tests</title>
+<link rel="author" title="W3C" href="http://www.w3.org/" />
+<link rel="help" href="http://www.w3.org/TR/pointerlock/#element-interface"/>
+<link rel="help" href="http://www.w3.org/TR/pointerlock/#extensions-to-the-document-interface">
+<link rel="help" href="http://www.w3.org/TR/pointerlock/#extensions-to-the-mouseevent-interface">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/WebIDLParser.js"></script>
+<script src="/resources/idlharness.js"></script>
+</head>
+
+<body>
+<h1>Pointer Lock IDL tests</h1>
+
+<pre id='untested_idl' style='display:none'>
+
+interface EventTarget {
+};
+
+interface Node : EventTarget {
+};
+
+interface Element : Node {
+};
+
+interface Document : Node {
+};
+
+interface Event {
+};
+
+interface MouseEvent : Event {
+};
+</pre>
+
+<pre id='idl'>
+
+partial interface Element {
+ void requestPointerLock ();
+};
+
+partial interface Document {
+ attribute EventHandler onpointerlockchange;
+ attribute EventHandler onpointerlockerror;
+ readonly attribute Element? pointerLockElement;
+ void exitPointerLock ();
+};
+
+partial interface MouseEvent {
+ readonly attribute long movementX;
+ readonly attribute long movementY;
+};
+
+partial dictionary MouseEventInit {
+ long movementX = 0;
+ long movementY = 0;
+};
+
+
+</pre>
+
+<div id="log"></div>
+
+<script>
+
+var idl_array = new IdlArray();
+
+setup(function() {
+ idl_array.add_untested_idls(document.getElementById("untested_idl").textContent);
+ idl_array.add_idls(document.getElementById("idl").textContent);
+
+ idl_array.add_objects({ Document: ["window.document"],
+ Element: ["window.document.documentElement"],
+ MouseEvent: ["new MouseEvent('mousemove')", "new MouseEvent('pointerlockchange')"] });
+});
+
+idl_array.test();
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/pointerlock/movementX_Y_basic-manual.html b/testing/web-platform/tests/pointerlock/movementX_Y_basic-manual.html
new file mode 100644
index 000000000..1e8fc1f53
--- /dev/null
+++ b/testing/web-platform/tests/pointerlock/movementX_Y_basic-manual.html
@@ -0,0 +1,124 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<meta name='flags' content='interact'>
+<meta name="timeout" content="long">
+<style type="text/css">
+ #status-log {
+ margin: 10px 0;
+ color: green;
+ color: green;
+ }
+</style>
+</head>
+<body>
+ <h2>Description</h2>
+ <p>This test if movementX/Y can provide the change in position of the pointer, as if movementX/Y = eNow.screenX/Y-ePrevious.screenX/Y</p>
+ <hr/>
+
+ <h2>Manual Test Steps:</h2>
+ <p>
+ <ol>
+ <li>Click to start Test1.</li>
+ <li>Move the mouse within the window, slow and fast, like a scribble.</li>
+ <li>Click again to end test.</li>
+ </ol>
+ </p>
+ <hr/>
+
+ <div id="status-log">Waiting... Click to start loging.</div>
+ <div class="data-log">
+ <table>
+ <tr><td></td><td>X</td><td>Y</td></tr>
+ <tr><td>client_init:</td><td id="clientX_init-log">X</td><td id="clientY_init-log">Y</td></tr>
+ <tr><td>client_last:</td><td id="clientX_last-log">X</td><td id="clientY_last-log">Y</td></tr>
+ <tr><td>client_delta:</td><td id="clientX_delta-log">X</td><td id="clientY_delta-log">Y</td></tr>
+ <tr><td>movement_sum:</td><td id="movementX_sum-log">X</td><td id="movementY_sum-log">Y</td></tr>
+ <tr><td>movement:</td><td id="movementX-log">X</td><td id="movementY-log">Y</td></tr>
+ </table>
+ </div>
+ <hr/>
+
+ <div id="log"></div>
+
+ <script type="text/javascript" >
+ var status_log = document.querySelector('#status-log'),
+ movementX_log = document.querySelector('#movementX-log'),
+ movementY_log = document.querySelector('#movementY-log'),
+ movementX_sum_log = document.querySelector('#movementX_sum-log'),
+ movementY_sum_log = document.querySelector('#movementY_sum-log'),
+ clientX_init_log = document.querySelector('#clientX_init-log'),
+ clientY_init_log = document.querySelector('#clientY_init-log'),
+ clientX_last_log = document.querySelector('#clientX_last-log'),
+ clientY_last_log = document.querySelector('#clientY_last-log');
+ clientX_delta_log = document.querySelector('#clientX_delta-log'),
+ clientY_delta_log = document.querySelector('#clientY_delta-log');
+
+ var click_counter = 0;
+
+ var clientX_init, clientY_init, movementX, movementY, movementX_sum, movementY_sum, clientX_last, clientY_last;
+
+ var movementX_Y_inside_window_Test = async_test("Test that movementX/Y = eNow.screenX/Y-ePrevious.screenX/Y.");
+
+ document.addEventListener("click", function (e) {
+ click_counter++;
+
+ switch(click_counter) {
+ case 1:
+ status_log.innerHTML = "inside window: logging...";
+ break;
+ case 2:
+ status_log.innerHTML = "inside window: done";
+
+ // approximately(+/- 10)
+ // a little drift should be tollerated
+ movementX_Y_inside_window_Test.step(function() {
+ assert_equals(movementX_sum, clientX_last - clientX_init, "sum of movementX = clientX_init - clientX_last");
+ assert_equals(movementY_sum, clientY_last - clientY_init, "sum of movementY = clientY_init - clientY_last");
+ });
+ movementX_Y_inside_window_Test.done();
+ break;
+ }
+ });
+
+ document.addEventListener("mousemove", function (e) {
+ movementX = e.movementX;
+ movementY = e.movementY;
+
+ if(click_counter === 1) {
+ if(!clientX_init) {
+ clientX_init = e.clientX;
+ clientY_init = e.clientY;
+ movementX_sum = movementX;
+ movementY_sum = movementY;
+ }
+
+ movementX_sum += movementX;
+ movementY_sum += movementY;
+
+ clientX_last = e.clientX;
+ clientY_last = e.clientY;
+ clientX_delta = clientX_last - clientX_init;
+ clientY_delta = clientY_last - clientY_init;
+
+ updateData();
+ }
+ });
+
+ function updateData() {
+ clientX_init_log.innerHTML = clientX_init;
+ clientY_init_log.innerHTML = clientY_init;
+ clientX_last_log.innerHTML = clientX_last;
+ clientY_last_log.innerHTML = clientY_last;
+ clientX_delta_log.innerHTML = clientX_delta;
+ clientY_delta_log.innerHTML = clientY_delta;
+ movementX_log.innerHTML = movementX;
+ movementY_log.innerHTML = movementY;
+ movementX_sum_log.innerHTML = movementX_sum;
+ movementY_sum_log.innerHTML = movementY_sum;
+ }
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/pointerlock/movementX_Y_no-jumps-manual.html b/testing/web-platform/tests/pointerlock/movementX_Y_no-jumps-manual.html
new file mode 100644
index 000000000..9c8fabd28
--- /dev/null
+++ b/testing/web-platform/tests/pointerlock/movementX_Y_no-jumps-manual.html
@@ -0,0 +1,140 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<meta name='flags' content='interact'>
+<meta name="timeout" content="long">
+<style type="text/css">
+ #status-log {
+ margin: 10px 0;
+ color: green;
+ color: green;
+ }
+</style>
+</head>
+<body>
+ <h2>Description</h2>
+ <p>This test that movementX/Y do not jump by a large value when exiting and re-entering the window.</p>
+ <hr/>
+
+ <h2>Manual Test Steps:</h2>
+ <p>
+ <ol>
+ <li>Make sure the window is not maximized.</li>
+ <li>Click to start Test.</li>
+ <li>Move the mouse slowly out of the window.
+ <li>Move as fast as needed to a different location outside the window at least 100 pixels away</li>
+ <li>Slowly re-enter the window.</li>
+ <li>Click again to end tests.</li>
+ </ol>
+ </p>
+ <hr/>
+
+ <div id="status-log">Waiting... Click to start loging.</div>
+ <div class="data-log">
+ <table>
+ <tr><td></td><td>X</td><td>Y</td></tr>
+ <tr><td>client_init:</td><td id="clientX_init-log">X</td><td id="clientY_init-log">Y</td></tr>
+ <tr><td>client_last:</td><td id="clientX_last-log">X</td><td id="clientY_last-log">Y</td></tr>
+ <tr><td>client_delta:</td><td id="clientX_delta-log">X</td><td id="clientY_delta-log">Y</td></tr>
+ <tr><td>movement_sum:</td><td id="movementX_sum-log">X</td><td id="movementY_sum-log">Y</td></tr>
+ <tr><td>movement:</td><td id="movementX-log">X</td><td id="movementY-log">Y</td></tr>
+ </table>
+ </div>
+ <hr/>
+
+ <div id="log"></div>
+
+ <script type="text/javascript" >
+ var status_log = document.querySelector('#status-log'),
+ movementX_log = document.querySelector('#movementX-log'),
+ movementY_log = document.querySelector('#movementY-log'),
+ movementX_sum_log = document.querySelector('#movementX_sum-log'),
+ movementY_sum_log = document.querySelector('#movementY_sum-log'),
+ clientX_init_log = document.querySelector('#clientX_init-log'),
+ clientY_init_log = document.querySelector('#clientY_init-log'),
+ clientX_last_log = document.querySelector('#clientX_last-log'),
+ clientY_last_log = document.querySelector('#clientY_last-log');
+ clientX_delta_log = document.querySelector('#clientX_delta-log'),
+ clientY_delta_log = document.querySelector('#clientY_delta-log');
+
+ var click_counter = 0;
+
+ var clientX_init, clientY_init, movementX, movementY, movementX_sum, movementY_sum, clientX_last, clientY_last;
+
+ var movementX_Y_outside_window_Test = async_test("Test that movementX/Y do not have large values when re-entering from outside the window.");
+
+ document.addEventListener("click", function (e) {
+ click_counter++;
+
+ switch(click_counter) {
+ case 1:
+ status_log.innerHTML = "logging...";
+ break;
+ case 2:
+ status_log.innerHTML = "done";
+
+ // approximately(+/- 10)
+ // a little drift should be tollerated
+ movementX_Y_outside_window_Test.step(function() {
+ assert_equals(movementX_sum, clientX_last - clientX_init, "sum of movementX = clientX_init - clientX_last");
+ assert_equals(movementY_sum, clientY_last - clientY_init, "sum of movementY = clientY_init - clientY_last");
+ });
+ movementX_Y_outside_window_Test.done();
+ break;
+ }
+ });
+
+ document.addEventListener("mousemove", function (e) {
+ movementX = e.movementX;
+ movementY = e.movementY;
+
+ if(click_counter === 1) {
+ if(!clientX_init) {
+ clientX_init = e.clientX;
+ clientY_init = e.clientY;
+ movementX_sum = movementX;
+ movementY_sum = movementY;
+ }
+
+ movementX_Y_outside_window_Test.step(function() {
+ assert_less_than(Math.abs(movementX), 50, "movementX should not have large jumps in value.");
+ assert_less_than(Math.abs(movementY), 50, "movementY should not have large jumps in value.");
+ });
+
+ movementX_sum += movementX;
+ movementY_sum += movementY;
+
+ clientX_last = e.clientX;
+ clientY_last = e.clientY;
+ clientX_delta = clientX_last - clientX_init;
+ clientY_delta = clientY_last - clientY_init;
+
+ updateData();
+ }
+ });
+
+ document.addEventListener("mouseenter", function (e) {
+ if(click_counter === 1) {
+ movementX_Y_outside_window_Test.step(function() {
+ assert_greater_than(Math.abs(e.clientX-clientX_last) + Math.abs(e.clientY-clientY_last), 100, "Test requires mouse to be moved at least 100 pixels outside of window.");
+ });
+ }
+ });
+
+ function updateData() {
+ clientX_init_log.innerHTML = clientX_init;
+ clientY_init_log.innerHTML = clientY_init;
+ clientX_last_log.innerHTML = clientX_last;
+ clientY_last_log.innerHTML = clientY_last;
+ clientX_delta_log.innerHTML = clientX_delta;
+ clientY_delta_log.innerHTML = clientY_delta;
+ movementX_log.innerHTML = movementX;
+ movementY_log.innerHTML = movementY;
+ movementX_sum_log.innerHTML = movementX_sum;
+ movementY_sum_log.innerHTML = movementY_sum;
+ }
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/pointerlock/pointerlock_basic-manual.html b/testing/web-platform/tests/pointerlock/pointerlock_basic-manual.html
new file mode 100644
index 000000000..d926318ab
--- /dev/null
+++ b/testing/web-platform/tests/pointerlock/pointerlock_basic-manual.html
@@ -0,0 +1,149 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<meta name='flags' content='interact'>
+<meta name="timeout" content="long">
+<style type="text/css">
+ button {
+ color: blue;
+ }
+
+ #locktarget {
+ position: relative;
+ background-color: grey;
+ width: 50px;
+ color: white;
+ line-height: 30px;
+ height: 30px;
+ }
+
+ #basic-log {
+ margin: 10px 0;
+ color: green;
+ }
+</style>
+</head>
+<body>
+ <h2>Description</h2>
+ <p>This test validates that the pointer properly be locked in a DOM element, and exit afterwards.</p>
+ <hr/>
+
+ <h2>Manual Test Steps:</h2>
+ <p>
+ <ol>
+ <li>Click the "Lock Target" to test if requestPointerLock() and exitPointerLock() causing a pointerlockchange event.</li>
+ <li>Confirm the lock with a user action (in Firefox).</li>
+ <li>Exit the pointer lock with a user action (usually 'esc'), to test if the cursor is at the same location.</li>
+ <li>Click the "ReEnterLock" to test that no engagement gesture is required to reenter pointer lock if pointer lock is exited via exitPointerLock.</li>
+ <li>Exit the pointer lock with a user action (usually 'esc').</li>
+ <li>Click the "RepeatLock" to validate that each requestPointerLock() will fire a pointerlockchange event.</li>
+ <li>Exit the pointer lock with a user action (usually 'esc').</li>
+ </ol>
+ </p>
+ <hr/>
+
+ <button onclick="LockTarget();">Lock Target</button>
+ <button onclick="ReEnterLock();">ReEnter Lock</button>
+ <button onclick="RepeatLock();">Repeat Lock</button>
+ <div id="basic-log">Waiting... Please click the "Lock Target" button.</div>
+ <div id="locktarget">Target</div>
+ <hr/>
+
+ <div id="log"></div>
+
+ <script type="text/javascript" >
+ var locktarget = document.querySelector('#locktarget'),
+ lock_log = document.querySelector('#basic-log');
+
+ var pointerlockchangeIsFiredonRequest = false;
+ var posX = posY = 0;
+ var event_counter = 0;
+ var request_counter = 0;
+
+ var requestPointerLockTest = async_test("Test that the pointer properly be locked in a DOM element.");
+ var exitPointerLockTest = async_test("Test that the pointer lock properly be exited, the cursor is at the same location when exited.");
+ var reenterPointerLockTest = async_test("Test that no engagement gesture is required to reenter pointer lock if pointer lock is exited via exitPointerLock.");
+ var repeatLockPointerTest = async_test("Test validates that each requestPointerLock() will fire a pointerlockchange event.");
+
+ document.addEventListener("pointerlockchange", function() {
+ event_counter ++;
+
+ if(event_counter === 1) {
+ pointerlockchangeIsFiredonRequest = true;
+ runRequestPointerLockTest();
+ } else if(event_counter === 2) {
+ runExitPointerLockTest();
+ } else if(event_counter === 3) {
+ runReEnterPointerLockTest()
+ } else if(event_counter > 104) {
+ runRepeatLockPointerTest();
+ }
+ });
+
+ function runRequestPointerLockTest() {
+ posX = window.screenX;
+ posY = window.screenY;
+
+ requestPointerLockTest.step(function() {
+ assert_true(pointerlockchangeIsFiredonRequest === true, "pointerlockchange is fired when requesting pointerlock");
+ assert_true(document.pointerLockElement === locktarget, "pointer is locked at the target element");
+ });
+
+ lock_log.innerHTML = "Pointer is locked on the target element;";
+
+ requestPointerLockTest.done();
+ }
+
+ function runExitPointerLockTest() {
+ locktarget.requestPointerLock(); // To re-enter pointer lock
+
+ exitPointerLockTest.step(function() {
+ assert_true(document.pointerLockElement === null, "pointer is unlocked");
+ assert_equals(posX, window.screenX, "mouse cursor X is at the same location that it was when pointer lock was entered");
+ assert_equals(posY, window.screenY, "mouse cursor Y is at the same location that it was when pointer lock was entered");
+ });
+
+ lock_log.innerHTML = "Status: Exited pointer lock; Please click the 'Re-enter Lock' button and exit the lock.";
+
+ exitPointerLockTest.done();
+ }
+
+ function runReEnterPointerLockTest() {
+ reenterPointerLockTest.step(function() {
+ assert_true(document.pointerLockElement === locktarget, "Pointer is locked again without engagement gesture");
+ });
+
+ lock_log.innerHTML = "Status: Exited pointer lock; Please click the 'Repeat Lock' button and exit the lock.";
+
+ reenterPointerLockTest.done();
+ }
+
+ function runRepeatLockPointerTest() {
+ repeatLockPointerTest.step(function() {
+ assert_equals(request_counter + 5, event_counter, "Each requestPointerLock() will fire a pointerlockchange event");
+ });
+
+ lock_log.innerHTML = "Status: Test over.";
+
+ repeatLockPointerTest.done();
+ }
+
+ function LockTarget() {
+ locktarget.requestPointerLock();
+ }
+
+ function ReEnterLock() {
+ locktarget.requestPointerLock();
+ }
+
+ function RepeatLock() {
+ for(var i = 0; i < 100; i++) {
+ request_counter++;
+ locktarget.requestPointerLock();
+ }
+ }
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/pointerlock/pointerlock_fullscreen-manual.html b/testing/web-platform/tests/pointerlock/pointerlock_fullscreen-manual.html
new file mode 100644
index 000000000..7ce91ad16
--- /dev/null
+++ b/testing/web-platform/tests/pointerlock/pointerlock_fullscreen-manual.html
@@ -0,0 +1,173 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<meta name='flags' content='interact'>
+<meta name="timeout" content="long">
+<style type="text/css">
+ button {
+ color: blue;
+ }
+
+ #test-element-wrap {
+ position: relative;
+ background-color: lightgrey;
+ width: 400px;
+ height: 200px;
+ border: grey 1px solid;
+ }
+
+ #test-element {
+ position: relative;
+ background-color: lightyellow;
+ width: 100px;
+ height: 30px;
+ border: yellow 1px solid;
+ }
+
+ #status-log {
+ margin: 10px 0;
+ color: green;
+ }
+</style>
+</head>
+<body>
+ <h2>Description</h2>
+ <p>This test validates that pointer lock won't be exited when fullscreen is entered or exited, unless fullscreen is exited with the same user gesture as pointer lock.</p>
+ <hr/>
+
+ <h2>Manual Test Steps:</h2>
+ <p>
+ <ol>
+ <li>Click the "scriptExitFullscreen" button.</li>
+ <li>If the exitFullscreen doesn't work, use the menu (or any other interaction except for the "esc" key) to exit fullscreen.</li>
+ <li>First test case done.</li>
+ <li>Click the "gestureExitFullscreen" button.</li>
+ <li>Use the "esc" key to exit fullscreen.</li>
+ <li>Second test case done.</li>
+ </ol>
+ </p>
+ <hr/>
+
+ <button onclick="scriptExitFullscreen();">scriptExitFullscreen</button>
+ <button onclick="gestureExitFullscreen();">gestureExitFullscreen</button>
+
+ <div id="test-element-wrap">
+ <div id="status-log">Waiting... Please click the "scriptExitFullscreen" button.</div>
+ <div id="test-element">Target</div>
+ </div>
+ <hr/>
+
+ <div id="log"></div>
+
+ <script type="text/javascript" >
+ var test_element = document.querySelector('#test-element'),
+ test_element_wrap = document.querySelector('#test-element-wrap')
+ status_log = document.querySelector('#status-log');
+ var enable_gestureExitFullscreen = false;
+ var gestureExit_pl = false;
+ var gestureExit_fs = false;
+ var gestureLock = false;
+
+ var scriptExitFullscreenTest = async_test("Test that pointer lock won't be exited when fullscreen is entered or exited with script.");
+ var gestureExitFullscreenTest = async_test("Test that pointer lock is exited when fullscreen is entered or exited with the same user gesture.");
+
+ function RequestFullscreen(element) {
+ var requestFullscreen = element.requestFullscreen || element.webkitRequestFullscreen || element.mozRequestFullscreen || element.msRequestFullscreen;
+ requestFullscreen.call(element);
+ }
+
+ function ExitFullscreen() {
+ var exitFullscreen = document.exitFullscreen || document.webkitExitFullscreen || document.mozExitFullscreen || document.msExitFullscreen;
+ exitFullscreen.call(document);
+ }
+
+ function FullscreenElement() {
+ var fullscreenElement = document.fullscreenElement || document.webkitFullscreenElement || document.mozFullscreenElement || document.msFullscreenElement;
+ return fullscreenElement ? fullscreenElement : null;
+ }
+
+ document.addEventListener("pointerlockchange", function() {
+ if(!enable_gestureExitFullscreen) {
+ // first test, enable fullscreen and pointer lock
+ if(document.pointerLockElement) {
+ ExitFullscreen();
+ logStatus();
+
+ scriptExitFullscreenTest.step(function() {
+ assert_true(FullscreenElement() === null, "fullscreen is sucessfully exited");
+ assert_true(document.pointerLockElement === test_element, "pointer is still locked at the target element");
+ });
+ scriptExitFullscreenTest.done();
+ document.exitPointerLock();
+ } else{
+ // first test, fullscreen and pointer lock are exited
+ enable_gestureExitFullscreen = true;
+ }
+ } else {
+ gestureLock = true;
+ if(!document.pointerLockElement) {
+ // second test, pointer lock exited
+ gestureExit_pl = true;
+
+ if(gestureExit_fs) {
+ // second test, fullscreen and pointer lock both exited
+ gestureExitFullscreenTest.step(function() {
+ assert_true(document.pointerLockElement === null, "pointer is sucessfully exited");
+ assert_true(FullscreenElement() === null, "fullscreen is sucessfully exited");
+ });
+ gestureExitFullscreenTest.done();
+ }
+ }
+ }
+ });
+
+ document.addEventListener("fullscreenchange", fullscreenChangeHandler);
+
+ document.addEventListener("webkitfullscreenchange",fullscreenChangeHandler);
+
+ function fullscreenChangeHandler() {
+ if(enable_gestureExitFullscreen && gestureLock && !FullscreenElement()) {
+ if(gestureExit_pl) {
+ // second test, fullscreen and pointer lock both exited
+ gestureExitFullscreenTest.step(function() {
+ assert_true(document.pointerLockElement === null, "pointer is sucessfully exited");
+ assert_true(FullscreenElement() === null, "fullscreen is sucessfully exited");
+ });
+
+ gestureExitFullscreenTest.done();
+ } else {
+ gestureExit_fs = true;
+ }
+ }
+ }
+
+ function logStatus() {
+ var status = "";
+ if(document.pointerLockElement) {
+ status = "<p>Pointer is Locked.</p>"
+ } else {
+ status = "<p>Pointer Lock exited.</p>"
+ }
+ if(FullscreenElement()) {
+ status += "<p>Fullscreen is on now.</p>"
+ } else {
+ status += "<p>Fullscreen exited.</p>"
+ }
+
+ status_log.innerHTML = status;
+ }
+
+ function scriptExitFullscreen() {
+ test_element.requestPointerLock();
+ RequestFullscreen(test_element_wrap);
+ }
+
+ function gestureExitFullscreen() {
+ RequestFullscreen(test_element_wrap);
+ test_element.requestPointerLock();
+ }
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/pointerlock/pointerlock_indefinite-manual.html b/testing/web-platform/tests/pointerlock/pointerlock_indefinite-manual.html
new file mode 100644
index 000000000..0db1227ad
--- /dev/null
+++ b/testing/web-platform/tests/pointerlock/pointerlock_indefinite-manual.html
@@ -0,0 +1,107 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<meta name='flags' content='interact'>
+<meta name="timeout" content="long">
+<style type="text/css">
+ button {
+ color: blue;
+ }
+
+ #target-wrap {
+ position: relative;
+ background-color: lightgrey;
+ width: 400px;
+ height: 150px;
+ border: grey 1px solid;
+ }
+
+ #target-wrap span, #status-log {
+ color: green;
+ }
+</style>
+</head>
+<body>
+ <h2>Description</h2>
+ <p>This test validates that movementX/Y provided indefinitely even when the mouse cursor would have otherwise hit the edge of a screen.</p>
+ <hr/>
+
+ <h2>Manual Test Steps:</h2>
+ <p>
+ <ol>
+ <li>Click the "lockTarget" button to request a pointer lock.</li>
+ <li>Move the pointer constantly in a diagonal direction (e.g. up and right).</li>
+ <li>Test is done.</li>
+ </ol>
+ </p>
+ <hr/>
+
+ <button onclick="lockTarget();">lockTarget</button>
+
+ <div id="target-wrap">
+ <div id="status-log">Click the "lockTarget" button.</div>
+ <p>screenSize: <span id="screenSize-log">NaN</span></p>
+ <p>movementX_sum: <span id="movementX_sum-log">NaN</span></p>
+ <p>movementY_sum: <span id="movementY_sum-log">NaN</span></p>
+ </div>
+ <hr/>
+
+ <div id="log"></div>
+
+ <script type="text/javascript" >
+ var screenSize_log = document.querySelector('#screenSize-log'),
+ movementX_sum_log = document.querySelector('#movementX_sum-log'),
+ movementY_sum_log = document.querySelector('#movementY_sum-log'),
+ status_log = document.querySelector('#status-log'),
+ target = document.querySelector('#target-wrap');
+ var movementX_sum = 0,
+ movementY_sum = 0;
+ var screenWidth = screen.width,
+ screenHeight = screen.height;
+
+ var enable_logging = false;
+
+ screenSize_log.innerHTML = "width: " + screenWidth + " px, " + "height: " + screenHeight + " px"
+
+ var movementXYIndefiniteTest = async_test("Test that movementX/Y provided indefinitely even when the mouse cursor would have otherwise hit the edge of a screen.");
+
+ document.addEventListener("pointerlockchange", function() {
+ if(document.pointerLockElement) {
+ status_log.innerHTML = "Keep moving...";
+ enable_logging = true;
+ }
+ });
+
+ document.addEventListener("mousemove", function (e) {
+ if(enable_logging) {
+ movementX_sum += Math.abs(e.movementX);
+ movementY_sum += Math.abs(e.movementY);
+
+ movementX_sum_log.innerHTML = movementX_sum + "px";
+ movementY_sum_log.innerHTML = movementY_sum + "px";
+
+ if(movementX_sum > 2 * screen.width && movementY_sum > 2 * screen.height) {
+ movementXYIndefiniteTest.step(function() {
+ assert_greater_than(movementX_sum, 2 * screenWidth, "Sum of movementX is greater than 2 times of screen width");
+ assert_greater_than(movementY_sum, 2 * screenHeight, "Sum of movementY is greater than 2 times of screen height");
+ });
+
+ movementXYIndefiniteTest.done();
+
+ status_log.innerHTML = "Test succeeds...";
+
+ enable_logging = false;
+
+ document.exitPointerLock();
+ }
+ }
+ });
+
+ function lockTarget() {
+ target.requestPointerLock();
+ }
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/pointerlock/pointerlock_leave_Tab-manual.html b/testing/web-platform/tests/pointerlock/pointerlock_leave_Tab-manual.html
new file mode 100644
index 000000000..198e2fe63
--- /dev/null
+++ b/testing/web-platform/tests/pointerlock/pointerlock_leave_Tab-manual.html
@@ -0,0 +1,85 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<meta name='flags' content='interact'>
+<meta name="timeout" content="long">
+<style type="text/css">
+ button {
+ color: blue;
+ }
+
+ #target-wrap {
+ position: relative;
+ background-color: lightgrey;
+ width: 200px;
+ height: 100px;
+ border: grey 1px solid;
+ }
+
+ #target {
+ position: relative;
+ background-color: lightyellow;
+ width: 100px;
+ height: 30px;
+ border: yellow 1px solid;
+ }
+
+ #status-log {
+ margin: 10px 0;
+ color: green;
+ }
+</style>
+</head>
+<body>
+ <h2>Description</h2>
+ <p>This test validates that pointer lock will be lost the user agent / window loses focus.</p>
+ <hr/>
+
+ <h2>Manual Test Steps:</h2>
+ <p>
+ <ol>
+ <li>Click the "lockTarget" button to request a pointer lock.</li>
+ <li>Focus to another tab with keyboard (Ctrl-TAB).</li>
+ <li>Test is done.</li>
+ </ol>
+ </p>
+ <hr/>
+
+ <button onclick="lockTarget();">lockTarget</button>
+
+ <div id="target-wrap">
+ <div id="status-log">Click the "lockTarget" button.</div>
+ <div id="target">Target</div>
+ </div>
+ <hr/>
+
+ <div id="log"></div>
+
+ <script type="text/javascript" >
+ var target = document.querySelector('#target'),
+ status_log = document.querySelector('#status-log');
+
+ var leaveTabTest = async_test("Test that pointer lock will be lost when the current Tab loses focus.");
+
+ document.addEventListener("pointerlockchange", function() {
+ if(document.pointerLockElement) {
+ status_log.innerHTML = "Please leave the current tab.";
+ } else {
+ status_log.innerHTML = "Pointer lock exited!";
+
+ leaveTabTest.step(function() {
+ assert_true(document.pointerLockElement === null, "Pointer lock exited!");
+ });
+
+ leaveTabTest.done();
+ }
+ });
+
+ function lockTarget() {
+ target.requestPointerLock();
+ }
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/pointerlock/pointerlock_leave_UA-manual.html b/testing/web-platform/tests/pointerlock/pointerlock_leave_UA-manual.html
new file mode 100644
index 000000000..e14400844
--- /dev/null
+++ b/testing/web-platform/tests/pointerlock/pointerlock_leave_UA-manual.html
@@ -0,0 +1,85 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<meta name='flags' content='interact'>
+<meta name="timeout" content="long">
+<style type="text/css">
+ button {
+ color: blue;
+ }
+
+ #target-wrap {
+ position: relative;
+ background-color: lightgrey;
+ width: 200px;
+ height: 100px;
+ border: grey 1px solid;
+ }
+
+ #target {
+ position: relative;
+ background-color: lightyellow;
+ width: 100px;
+ height: 30px;
+ border: yellow 1px solid;
+ }
+
+ #status-log {
+ margin: 10px 0;
+ color: green;
+ }
+</style>
+</head>
+<body>
+ <h2>Description</h2>
+ <p>This test validates that pointer lock will be lost the user agent / window loses focus.</p>
+ <hr/>
+
+ <h2>Manual Test Steps:</h2>
+ <p>
+ <ol>
+ <li>Click the "lockTarget" button to request a pointer lock.</li>
+ <li>Focus to another window with keyboard (ALT-TAB).</li>
+ <li>Test is done.</li>
+ </ol>
+ </p>
+ <hr/>
+
+ <button onclick="lockTarget();">lockTarget</button>
+
+ <div id="target-wrap">
+ <div id="status-log">Click the "lockTarget" button.</div>
+ <div id="target">Target</div>
+ </div>
+ <hr/>
+
+ <div id="log"></div>
+
+ <script type="text/javascript" >
+ var target = document.querySelector('#target'),
+ status_log = document.querySelector('#status-log');
+
+ var leaveUATest = async_test("Test that pointer lock will be lost when the user agent / window loses focus.");
+
+ document.addEventListener("pointerlockchange", function() {
+ if(document.pointerLockElement) {
+ status_log.innerHTML = "Please leave the current window.";
+ } else {
+ status_log.innerHTML = "Pointer lock exited!";
+
+ leaveUATest.step(function() {
+ assert_true(document.pointerLockElement === null, "Pointer lock exited!");
+ });
+
+ leaveUATest.done();
+ }
+ });
+
+ function lockTarget() {
+ target.requestPointerLock();
+ }
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/pointerlock/pointerlock_remove_target-manual.html b/testing/web-platform/tests/pointerlock/pointerlock_remove_target-manual.html
new file mode 100644
index 000000000..210365090
--- /dev/null
+++ b/testing/web-platform/tests/pointerlock/pointerlock_remove_target-manual.html
@@ -0,0 +1,87 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<meta name='flags' content='interact'>
+<meta name="timeout" content="long">
+<style type="text/css">
+ button {
+ color: blue;
+ }
+
+ #target-wrap {
+ position: relative;
+ background-color: lightgrey;
+ width: 200px;
+ height: 100px;
+ border: grey 1px solid;
+ }
+
+ #target {
+ position: relative;
+ background-color: lightyellow;
+ width: 100px;
+ height: 30px;
+ border: yellow 1px solid;
+ }
+
+ #status-log {
+ margin: 10px 0;
+ color: green;
+ }
+</style>
+</head>
+<body>
+ <h2>Description</h2>
+ <p>This test validates that pointer lock will be lost when the target is disconnected.</p>
+ <hr/>
+
+ <h2>Manual Test Steps:</h2>
+ <p>
+ <ol>
+ <li>Click the "lockTarget" button to request a pointer lock.</li>
+ <li>Test is done.</li>
+ </ol>
+ </p>
+ <hr/>
+
+ <button onclick="lockTarget();">lockTarget</button>
+
+ <div id="target-wrap">
+ <div id="status-log">Click the "lockTarget" button.</div>
+ <div id="target">Target</div>
+ </div>
+ <hr/>
+
+ <div id="log"></div>
+
+ <script type="text/javascript" >
+ var target = document.querySelector('#target'),
+ target_wrap = document.querySelector('#target-wrap')
+ status_log = document.querySelector('#status-log');
+
+ var removeTargetTest = async_test("Test that pointer lock will be lost when taking the target element out of the DOM.");
+
+ document.addEventListener("pointerlockchange", function() {
+ if(document.pointerLockElement) {
+ status_log.innerHTML = "Target is locked!";
+
+ target_wrap.removeChild(target);
+ } else {
+ status_log.innerHTML = "Pointer lock exited!";
+
+ removeTargetTest.step(function() {
+ assert_true(document.pointerLockElement === null, "Pointer lock exited!");
+ });
+
+ removeTargetTest.done();
+ }
+ });
+
+ function lockTarget() {
+ target.requestPointerLock();
+ }
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/pointerlock/pointerlock_shadow-manual.html b/testing/web-platform/tests/pointerlock/pointerlock_shadow-manual.html
new file mode 100644
index 000000000..e7893c33b
--- /dev/null
+++ b/testing/web-platform/tests/pointerlock/pointerlock_shadow-manual.html
@@ -0,0 +1,83 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta name='author' title='Takayoshi Kochi' href='mailto:kochi@chromium.org'>
+<meta name='assert' content='Test for DocumentOrShadowRoot.pointerLockElement.'>
+<link rel='help' href='https://w3c.github.io/pointerlock/#widl-DocumentOrShadowRoot-pointerLockElement'>
+<meta name='flags' content='interact'>
+<meta name='timeout' content='long'>
+<script src='/resources/testharness.js'></script>
+<script src='/resources/testharnessreport.js'></script>
+<script src='../shadow-dom/resources/shadow-dom.js'></script>
+</head>
+<body>
+<div id='host'>
+ <template data-mode='open' id='root'>
+ <slot></slot>
+ </template>
+ <div id='host2'>
+ <template data-mode='open' id='root2'>
+ <div id='host3'>
+ <template data-mode='open' id='root3'>
+ <canvas id='canvas'></canvas>
+ <div id='host4'>
+ <template data-mode='open' id='root4'>
+ <div></div>
+ </template>
+ </div>
+ </template>
+ </div>
+ <div id='host5'>
+ <template data-mode='open' id='root5'>
+ <div></div>
+ </template>
+ </div>
+ </template>
+ </div>
+</div>
+
+<script>
+function run_test() {
+ async_test((test) => {
+ document.onpointerlockerror = test.unreached_func('onpointerlockerror is not expected.');
+
+ document.onpointerlockchange = test.step_func_done(() => {
+ // Not interested in handling before or after exitPointerLock.
+ if (document.pointerLockElement === null)
+ return;
+
+ assert_equals(document.pointerLockElement, ids.host2, 'document.pointerLockElement should be shadow #host2.');
+ assert_equals(ids.root.pointerLockElement, null, '#root\'s shadowRoot.pointerLockElement should be null.');
+ assert_equals(ids.root2.pointerLockElement, ids.host3, '#root2\'s shadowRoot.pointerLockElement should be host3.');
+ assert_equals(ids.root3.pointerLockElement, ids.canvas, '#root3\'s shadowRoot.pointerLockElement should be canvas element.');
+ assert_equals(ids.root4.pointerLockElement, null, '#root4\'s shadowRoot.pointerLockElement should be null.');
+ assert_equals(ids.root5.pointerLockElement, null, '#root5\'s shadowRoot.pointerLockElement should be null.');
+
+ document.exitPointerLock();
+ });
+
+ var ids = createTestTree(host);
+ document.body.appendChild(ids.host);
+
+ // All pointerLockElement should default to null.
+ test.step(() => {
+ assert_equals(document.pointerLockElement, null);
+ assert_equals(ids.root.pointerLockElement, null);
+ assert_equals(ids.root2.pointerLockElement, null);
+ assert_equals(ids.root3.pointerLockElement, null);
+ assert_equals(ids.root4.pointerLockElement, null);
+ assert_equals(ids.root5.pointerLockElement, null);
+ });
+
+ var canvas = ids.canvas;
+ canvas.requestPointerLock();
+ }, 'Test for pointerLockElement adjustment for Shadow DOM.');
+}
+</script>
+<div>
+ <h2>Description</h2>
+ <p>Click the button below to trigger pointer lock on an element in a shadow root.</p>
+ <button onclick="run_test()">Click Me!</button>
+</div>
+</body>
+</html>