diff options
Diffstat (limited to 'testing/web-platform/tests/pointerlock')
14 files changed, 1253 insertions, 0 deletions
diff --git a/testing/web-platform/tests/pointerlock/META.yml b/testing/web-platform/tests/pointerlock/META.yml new file mode 100644 index 0000000000..bb639b4417 --- /dev/null +++ b/testing/web-platform/tests/pointerlock/META.yml @@ -0,0 +1,4 @@ +spec: https://w3c.github.io/pointerlock/ +suggested_reviewers: + - scheib + - siusin diff --git a/testing/web-platform/tests/pointerlock/constructor.html b/testing/web-platform/tests/pointerlock/constructor.html new file mode 100644 index 0000000000..8c43cf6daf --- /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.window.js b/testing/web-platform/tests/pointerlock/idlharness.window.js new file mode 100644 index 0000000000..f176343a48 --- /dev/null +++ b/testing/web-platform/tests/pointerlock/idlharness.window.js @@ -0,0 +1,18 @@ +// META: script=/resources/WebIDLParser.js +// META: script=/resources/idlharness.js + +'use strict'; + +// https://w3c.github.io/pointerlock/ + +idl_test( + ['pointerlock'], + ['uievents', 'html', 'dom'], + idl_array => { + idl_array.add_objects({ + Document: ["window.document"], + Element: ["window.document.documentElement"], + MouseEvent: ["new MouseEvent('foo')"] + }); + } +); diff --git a/testing/web-platform/tests/pointerlock/mouse_buttons_back_forward.html b/testing/web-platform/tests/pointerlock/mouse_buttons_back_forward.html new file mode 100644 index 0000000000..6f4e764983 --- /dev/null +++ b/testing/web-platform/tests/pointerlock/mouse_buttons_back_forward.html @@ -0,0 +1,70 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8" /> + <title>Mouse Button Back/Forward</title> + <link rel="author" title="Google" href="http://www.google.com/" /> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/resources/testdriver.js"></script> + <script src="/resources/testdriver-actions.js"></script> + <script src="/resources/testdriver-vendor.js"></script> + <script> + var testMouseUp = async_test('Tests that when pointer is locked, the mouseup is preventable.'); + var received_back = false; + var received_forward = false; + const left_button = 0; + const back_button = 3; + const forward_button = 4; + window.addEventListener('mouseup', function(e) { + if (e.button == left_button) { + document.body.requestPointerLock(); + } else if (e.button == back_button) { + received_back = true; + e.preventDefault(); + } else if (e.button == forward_button) { + received_forward = true; + e.preventDefault(); + } + if (document.pointerLockElement && received_back && received_forward) { + testMouseUp.done(); + document.exitPointerLock(); + } + }); + + document.addEventListener("pointerlockchange", function() { + assert_equals(document.pointerLockElement, document.body); + + // Inject mouse input + var actions = new test_driver.Actions(); + actions.pointerMove(1, 1) + .pointerDown({button: actions.ButtonType.BACK}) + .pointerUp({button: actions.ButtonType.BACK}) + .pointerDown({button: actions.ButtonType.FORWARD}) + .pointerUp({button: actions.ButtonType.FORWARD}) + .send(); + }, { once: true }); + + document.addEventListener("pointerlockerror", function() { + assert_unreached("Pointer lock error"); + }); + + // Inject mouse input + var actions = new test_driver.Actions(); + actions.pointerMove(1, 1) + .pointerDown({button: actions.ButtonType.LEFT}) + .pointerUp({button: actions.ButtonType.LEFT}) + .send(); + </script> + + </head> + <body id="target"> + <h4>Test Description: Tests that the mouseup event is prevented. + <ol> + <li>Click the left mouse button to lock pointer</li> + <li>Click the back mouse button</li> + <li>Click the forward mouse button</li> + </ol> + </h4> + </body> +</html> diff --git a/testing/web-platform/tests/pointerlock/movementX_Y_basic.html b/testing/web-platform/tests/pointerlock/movementX_Y_basic.html new file mode 100644 index 0000000000..a317130190 --- /dev/null +++ b/testing/web-platform/tests/pointerlock/movementX_Y_basic.html @@ -0,0 +1,150 @@ +<!DOCTYPE html> +<html> +<body> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-actions.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<style type="text/css"> + #status-log { + margin: 10px 0; + color: green; + color: green; + } +</style> +</head> +<body onload="run_test()"> + <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>screen_init:</td><td id="screenX_init-log">X</td><td id="screenY_init-log">Y</td></tr> + <tr><td>screen_last:</td><td id="screenX_last-log">X</td><td id="screenY_last-log">Y</td></tr> + <tr><td>screen_delta:</td><td id="screenX_delta-log">X</td><td id="screenY_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'), + screenX_init_log = document.querySelector('#screenX_init-log'), + screenY_init_log = document.querySelector('#screenY_init-log'), + screenX_last_log = document.querySelector('#screenX_last-log'), + screenY_last_log = document.querySelector('#screenY_last-log'); + screenX_delta_log = document.querySelector('#screenX_delta-log'), + screenY_delta_log = document.querySelector('#screenY_delta-log'); + + var click_counter = 0; + + var screenX_init, screenY_init, movementX, movementY, movementX_sum, movementY_sum, screenX_last, screenY_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"; + + movementX_Y_inside_window_Test.step(function() { + assert_equals(movementX_sum, screenX_last - screenX_init, "sum of movementX = screenX_last - screenX_init"); + assert_equals(movementY_sum, screenY_last - screenY_init, "sum of movementY = screenY_last - screenY_init"); + }); + movementX_Y_inside_window_Test.done(); + break; + } + }); + + document.addEventListener("mousemove", function (e) { + movementX = e.movementX; + movementY = e.movementY; + + if(click_counter === 1) { + if(!screenX_init) { + screenX_init = screenX_last = e.screenX; + screenY_init = screenY_last = e.screenY; + movementX_sum = 0; + movementY_sum = 0; + } + else { + movementX_sum += movementX; + movementY_sum += movementY; + + screenX_delta = e.screenX - screenX_last; + screenY_delta = e.screenY - screenY_last; + + movementX_Y_inside_window_Test.step(function() { + assert_equals(movementX, screenX_delta, "movementX = screen_delta"); + assert_equals(movementY, screenY_delta, "movementY = screen_delta"); + }); + + screenX_last = e.screenX; + screenY_last = e.screenY; + + updateData(); + } + } + }); + + function updateData() { + screenX_init_log.innerHTML = screenX_init; + screenY_init_log.innerHTML = screenY_init; + screenX_last_log.innerHTML = screenX_last; + screenY_last_log.innerHTML = screenY_last; + screenX_delta_log.innerHTML = screenX_delta; + screenY_delta_log.innerHTML = screenY_delta; + movementX_log.innerHTML = movementX; + movementY_log.innerHTML = movementY; + movementX_sum_log.innerHTML = movementX_sum; + movementY_sum_log.innerHTML = movementY_sum; + } + + function run_test() { + x = Math.round(window.innerWidth / 2); + y = Math.round(window.innerHeight / 2); + var actions = new test_driver.Actions(); + actions.pointerMove(x, y) + .pointerDown() + .pointerUp(); + for (var i = 0; i < 10; i++) { + // Alternatively move left/right and up/down. + x += ((-1)**i) * i * 10; + y -= ((-1)**i) * i * 10; + actions.pointerMove(x, y); + } + actions.pointerMove(x, y) + .pointerDown() + .pointerUp() + .send(); + } + </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 0000000000..7667ece753 --- /dev/null +++ b/testing/web-platform/tests/pointerlock/movementX_Y_no-jumps-manual.html @@ -0,0 +1,140 @@ +<!DOCTYPE html> +<html> +<body> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<meta name='flags' content='interact'> +<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 0000000000..0efe9db29c --- /dev/null +++ b/testing/web-platform/tests/pointerlock/pointerlock_basic-manual.html @@ -0,0 +1,149 @@ +<!DOCTYPE html> +<html> +<body> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<meta name='flags' content='interact'> +<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_equals(pointerlockchangeIsFiredonRequest, true, "pointerlockchange is fired when requesting pointerlock"); + assert_equals(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_equals(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_equals(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 0000000000..d04bc2a3ef --- /dev/null +++ b/testing/web-platform/tests/pointerlock/pointerlock_fullscreen-manual.html @@ -0,0 +1,173 @@ +<!DOCTYPE html> +<html> +<body> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<meta name='flags' content='interact'> +<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_equals(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_equals(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_equals(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 0000000000..96d5f94e65 --- /dev/null +++ b/testing/web-platform/tests/pointerlock/pointerlock_indefinite-manual.html @@ -0,0 +1,107 @@ +<!DOCTYPE html> +<html> +<body> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<meta name='flags' content='interact'> +<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 0000000000..7618a9ae68 --- /dev/null +++ b/testing/web-platform/tests/pointerlock/pointerlock_leave_Tab-manual.html @@ -0,0 +1,85 @@ +<!DOCTYPE html> +<html> +<body> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<meta name='flags' content='interact'> +<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_equals(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 0000000000..d883f326b4 --- /dev/null +++ b/testing/web-platform/tests/pointerlock/pointerlock_leave_UA-manual.html @@ -0,0 +1,85 @@ +<!DOCTYPE html> +<html> +<body> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<meta name='flags' content='interact'> +<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_equals(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.html b/testing/web-platform/tests/pointerlock/pointerlock_remove_target.html new file mode 100644 index 0000000000..f0bd89497e --- /dev/null +++ b/testing/web-platform/tests/pointerlock/pointerlock_remove_target.html @@ -0,0 +1,96 @@ +<!DOCTYPE html> +<html> +<body> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-actions.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<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 id="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_equals(document.pointerLockElement, null, "Pointer lock exited!"); + }); + + removeTargetTest.done(); + } + }); + + function lockTarget() { + target.requestPointerLock(); + } + + // Inject mouse inputs. + new test_driver.Actions() + .pointerMove(0, 0, {origin: Button}) + .pointerDown() + .pointerUp() + .send(); + </script> + </body> +</html> diff --git a/testing/web-platform/tests/pointerlock/pointerlock_remove_target_on_mouseup.html b/testing/web-platform/tests/pointerlock/pointerlock_remove_target_on_mouseup.html new file mode 100644 index 0000000000..e5256c7d7b --- /dev/null +++ b/testing/web-platform/tests/pointerlock/pointerlock_remove_target_on_mouseup.html @@ -0,0 +1,30 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Remove PointerLock target on mouseup</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-actions.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<p>Click anywhere to run the test. If a "PASS" result appears the test passes, otherwise it fails</p> +<div id="target"></div> +<script> +async_test(t => { + const target = document.getElementById('target'); + document.addEventListener('mousedown', t.step_func(() => { + target.requestPointerLock(); + document.addEventListener('mouseup', t.step_func(() => { + target.remove(); + assert_equals(document.pointerLockElement, null, 'Pointer lock exited!'); + t.done(); + })); + })); +}) + +// Inject mouse input. +new test_driver.Actions() + .pointerMove(50, 50) + .pointerDown() + .pointerUp() + .send(); +</script> diff --git a/testing/web-platform/tests/pointerlock/pointerlock_shadow.html b/testing/web-platform/tests/pointerlock/pointerlock_shadow.html new file mode 100644 index 0000000000..21f3a928cd --- /dev/null +++ b/testing/web-platform/tests/pointerlock/pointerlock_shadow.html @@ -0,0 +1,93 @@ +<!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='timeout' content='long'> +<script src='/resources/testharness.js'></script> +<script src='/resources/testharnessreport.js'></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-actions.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src='../shadow-dom/resources/shadow-dom.js'></script> +</head> +<body onload="inject_input()"> +<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> +<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()" id="button">Click Me!</button> +</div> +</body> +<script> +function run_test() { + async_test((test) => { + document.onpointerlockerror = test.unreached_func('onpointerlockerror is not expected.'); + + document.onpointerlockchange = test.step_func(() => { + // 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(); + test.done(); + }); + + 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.'); + } + + function inject_input() { + new test_driver.Actions() + .pointerMove(0, 0, {origin: button}) + .pointerDown() + .pointerUp() + .send(); + } +</script> +</html> |