diff options
Diffstat (limited to 'testing/web-platform/tests/web-locks/frames.tentative.https.html')
-rw-r--r-- | testing/web-platform/tests/web-locks/frames.tentative.https.html | 265 |
1 files changed, 265 insertions, 0 deletions
diff --git a/testing/web-platform/tests/web-locks/frames.tentative.https.html b/testing/web-platform/tests/web-locks/frames.tentative.https.html new file mode 100644 index 0000000000..980b2fe747 --- /dev/null +++ b/testing/web-platform/tests/web-locks/frames.tentative.https.html @@ -0,0 +1,265 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Web Locks API: Frames</title> +<link rel=help href="https://w3c.github.io/web-locks/"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="resources/helpers.js"></script> +<style>iframe { display: none; }</style> +<script> +'use strict'; + +promise_test(async t => { + assert_implements(navigator.locks); + const res = uniqueName(t); + + const frame = await iframe('resources/iframe.html'); + t.add_cleanup(() => { frame.remove(); }); + + const lock_id = (await postToFrameAndWait( + frame, {op: 'request', name: res, mode: 'shared'})).lock_id; + + await navigator.locks.request(res, {mode: 'shared'}, async lock => { + await postToFrameAndWait(frame, {op: 'release', lock_id}); + }); + +}, 'Window and Frame - shared mode'); + +promise_test(async t => { + assert_implements(navigator.locks); + const res = uniqueName(t); + + const frame = await iframe('resources/iframe.html'); + t.add_cleanup(() => { frame.remove(); }); + + // frame acquires the lock. + const lock_id = (await postToFrameAndWait( + frame, {op: 'request', name: res})).lock_id; + + // This request should be blocked. + let lock_granted = false; + const blocked = navigator.locks.request(res, lock => { lock_granted = true; }); + + // Verify that we can't get it. + let available = undefined; + await navigator.locks.request( + res, {ifAvailable: true}, lock => { available = lock !== null; }); + assert_false(available); + assert_false(lock_granted); + + // Ask the frame to release it. + await postToFrameAndWait(frame, {op: 'release', lock_id}); + + await blocked; + // Now we've got it. + assert_true(lock_granted); +}, 'Window and Frame - exclusive mode'); + +promise_test(async t => { + assert_implements(navigator.locks); + const res = uniqueName(t); + + const frame1 = await iframe('resources/iframe.html'); + const frame2 = await iframe('resources/iframe.html'); + + // frame1 acquires the lock. + const lock_id = (await postToFrameAndWait( + frame1, {op: 'request', name: res})).lock_id; + + // frame2's request should be blocked. + let lock_granted = false; + const blocked = postToFrameAndWait( + frame2, {op: 'request', name: res}); + blocked.then(f => { lock_granted = true; }); + + // Verify that frame2 can't get it. + assert_true((await postToFrameAndWait(frame2, { + op: 'request', name: res, ifAvailable: true + })).failed, 'Lock request should have failed'); + assert_false(lock_granted); + + // Ask frame1 to release it. + await postToFrameAndWait(frame1, {op: 'release', lock_id}); + + await blocked; + // Now frame2 can get it. + assert_true(lock_granted); + frame1.parentElement.removeChild(frame1); + frame2.parentElement.removeChild(frame2); +}, 'Frame and Frame - exclusive mode'); + +promise_test(async t => { + assert_implements(navigator.locks); + const res = uniqueName(t); + + const frame = await iframe('resources/iframe.html'); + + // Frame acquires the lock. + await postToFrameAndWait(frame, {op: 'request', name: res}); + + // This request should be blocked. + let lock_granted = false; + const blocked = navigator.locks.request( + res, lock => { lock_granted = true; }); + + // Verify that we can't get it. + let available = undefined; + await navigator.locks.request( + res, {ifAvailable: true}, lock => { available = lock !== null; }); + assert_false(available); + assert_false(lock_granted); + + // Implicitly release it by terminating the frame. + frame.remove(); + await blocked; + // Now we've got it. + assert_true(lock_granted); + +}, 'Terminated Frame with held lock'); + +promise_test(async t => { + assert_implements(navigator.locks); + const res = uniqueName(t); + + const frame = await iframe('resources/iframe.html'); + + // Frame acquires the lock. + await postToFrameAndWait(frame, {op: 'request', name: res}); + + // This request should be blocked. + let lock_granted = false; + const blocked = navigator.locks.request( + res, lock => { lock_granted = true; }); + + // Verify that we can't get it. + let available = undefined; + await navigator.locks.request( + res, {ifAvailable: true}, lock => { available = lock !== null; }); + assert_false(available); + assert_false(lock_granted); + + // Implicitly release it by navigating the frame. + frame.src = 'about:blank'; + await blocked; + // Now we've got it. + assert_true(lock_granted); + +}, 'Navigated Frame with held lock'); + +promise_test(async t => { + assert_implements(navigator.locks); + const res = uniqueName(t); + + // frame1 requests and holds res - should be granted immediately. + // frame2 requests res - should be blocked. + // frame3 requests res - should be blocked. + // frame2 is navigated. + // frame1 releases res. + // frame3's request should be granted. + + const frame1 = await iframe('resources/iframe.html'); + const frame2 = await iframe('resources/iframe.html'); + const frame3 = await iframe('resources/iframe.html'); + t.add_cleanup(() => { frame1.remove(); }); + t.add_cleanup(() => { frame2.remove(); }); + t.add_cleanup(() => { frame3.remove(); }); + + // frame1 requests and holds res - should be granted immediately. + const lock_id = (await postToFrameAndWait( + frame1, {op: 'request', name: res})).lock_id; + + // frame2 requests res - should be blocked. + // (don't attach listeners as they will keep the frame alive) + frame2.contentWindow.postMessage({op: 'request', name: res}, '*'); + + // frame3 requests res - should be blocked. + let lock_granted = false; + const blocked = postToFrameAndWait(frame3, {op: 'request', name: res}); + blocked.then(f => { lock_granted = true; }); + + // Verify that frame3 can't get it. + assert_true((await postToFrameAndWait(frame3, { + op: 'request', name: res, ifAvailable: true + })).failed, 'Lock request should have failed'); + assert_false(lock_granted); + + // Navigate frame2. + frame2.src = 'about:blank'; + + // frame1 releases lock + await postToFrameAndWait(frame1, {op: 'release', lock_id}); + + // frame3's request should be granted. + await blocked; + assert_true(lock_granted); + +}, 'Navigated Frame with pending request'); + +promise_test(async t => { + assert_implements(navigator.locks); + const res = uniqueName(t); + + // frame1 requests and holds res - should be granted immediately. + // frame2 requests res - should be blocked. + // frame3 requests res - should be blocked. + // frame2 is removed. + // frame1 drops lock. + // frame3's request should be granted. + + const frame1 = await iframe('resources/iframe.html'); + const frame2 = await iframe('resources/iframe.html'); + const frame3 = await iframe('resources/iframe.html'); + t.add_cleanup(() => { frame1.remove(); }); + t.add_cleanup(() => { frame3.remove(); }); + + // frame1 requests and holds res - should be granted immediately. + const lock_id = (await postToFrameAndWait( + frame1, {op: 'request', name: res})).lock_id; + + // frame2 requests res - should be blocked. + // (don't attach listeners as they will keep the frame alive) + frame2.contentWindow.postMessage({op: 'request', name: res}, '*'); + + // frame3 requests res - should be blocked. + let lock_granted = false; + const blocked = postToFrameAndWait(frame3, {op: 'request', name: res}); + blocked.then(f => { lock_granted = true; }); + + // So frame3 can't get it + assert_true((await postToFrameAndWait(frame3, { + op: 'request', name: res, ifAvailable: true + })).failed, 'Lock request should have failed'); + assert_false(lock_granted); + + // Remove frame2. + frame2.remove(); + + // frame1 releases lock + await postToFrameAndWait(frame1, {op: 'release', lock_id}); + + // frame3's request should be granted. + await blocked; + assert_true(lock_granted); + +}, 'Removed Frame with pending request'); + +promise_test(async t => { + assert_implements(navigator.locks); + const res = uniqueName(t); + + const frame = await iframe('about:blank'); + + // Remove a frame while it is in the process of requesting a lock. + // The promise returned by `request` will never resolve since its frame no + // longer exists, but the lock should still be released. + await new Promise(resolve => { + frame.contentWindow.navigator.locks.request(res, () => { + frame.remove(); + resolve(); + }); + }); + + assert_false((await navigator.locks.query()).held.includes(res)); +}, 'Removed Frame as lock is granted'); + +</script> |