summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/web-locks/partitioned-web-locks.tentative.https.html
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /testing/web-platform/tests/web-locks/partitioned-web-locks.tentative.https.html
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/web-locks/partitioned-web-locks.tentative.https.html')
-rw-r--r--testing/web-platform/tests/web-locks/partitioned-web-locks.tentative.https.html172
1 files changed, 172 insertions, 0 deletions
diff --git a/testing/web-platform/tests/web-locks/partitioned-web-locks.tentative.https.html b/testing/web-platform/tests/web-locks/partitioned-web-locks.tentative.https.html
new file mode 100644
index 0000000000..aa9c9b6984
--- /dev/null
+++ b/testing/web-platform/tests/web-locks/partitioned-web-locks.tentative.https.html
@@ -0,0 +1,172 @@
+
+<!DOCTYPE html>
+<meta charset="utf-8"/>
+<title>Web Locks API: Partitioned WebLocks</title>
+
+<!-- Pull in get_host_info() -->
+<script src="/common/get-host-info.sub.js"></script>
+<script src="/common/utils.js"></script>
+<script src="/common/dispatcher/dispatcher.js"></script>
+<script src="resources/helpers.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<body>
+<script>
+
+const { HTTPS_ORIGIN, HTTPS_NOTSAMESITE_ORIGIN } = get_host_info();
+// Map of lock_id => function that releases a lock.
+const held = new Map();
+let next_lock_id = 1;
+
+// How this test works:
+// Step 1 (top-frame): request an exclusive web-lock and store its id
+// and release for clean-up.
+// Step 2 (top-frame): open a pop-up window and load a not-same-site
+// ./web-locks/resources/partitioned-parent.html
+// Step 3 (pop-up): load a same-site iframe inside the pop-up.
+// Step 4 (pop-up): send a web-lock request to the same-site iframe.
+// Step 5 (iframe): process the web-lock request and message the result
+// back to the pop-up.
+// Step 6 (pop-up): intercept the result message from the iframe and
+// send it to the top-frame.
+// Step 7 (top-frame): add cleanup hook.
+// Step 8 (top-frame): ensure that the same-site iframe's web-lock
+// request succeeds since it and the top-level site are successfully
+// partitioned and each can hold an exclusive lock.
+
+async function third_party_test(t) {
+ let target_url = HTTPS_ORIGIN + '/web-locks/resources/iframe.html';
+ target_url = new URL(
+ `/web-locks/resources/partitioned-parent.html?target=${encodeURIComponent(target_url)}`,
+ HTTPS_NOTSAMESITE_ORIGIN + self.location.pathname);
+
+ // Step 1.
+ let lock_id = next_lock_id++;
+ let [ promise, release ] = makePromiseAndResolveFunc();
+ let released = navigator.locks.request('testLock', {mode: 'exclusive', ifAvailable: true},
+ lock => {
+ if (lock === null) {
+ assert_true(false)
+ return;
+ }
+ return promise;
+ });
+ held.set(lock_id, { release, released });
+
+ // Step 2.
+ const w = window.open(target_url);
+ const result = await new Promise(resolve => window.onmessage = resolve);
+
+ // Step 7.
+ t.add_cleanup(() => {
+ w.close();
+ let released = [];
+ for(let i = 1; i < next_lock_id; i++){
+ let h = held.get(i);
+ h.release();
+ released.push(h.released);
+ }
+ return Promise.allSettled(released);
+ });
+
+ // Step 8.
+ // When 3rd party storage partitioning is enabled, the iframe should be able
+ // to acquire a lock with the same name as one exclusively held by the opener
+ // of its top window, even when that opener has the same origin.
+ assert_equals(result.data.failed, undefined,
+ 'The 1p iframe failed to acquire the lock');
+}
+
+promise_test(t => {
+ return third_party_test(t);
+}, 'WebLocks of an iframe under a 3rd-party site are partitioned');
+
+
+// Optional Test: Checking for partitioned web locks in an A->B->A
+// (nested-iframe with cross-site ancestor chain) scenario.
+//
+// How this test works:
+// Nested Step 1 (top frame): request an exclusive web-lock and
+// store its id and release for clean-up.
+// Nested Step 2 (top frame): open a pop-up window and load a
+// same-site /web-locks/resources/partitioned-parent.html.
+// Nested Step 3 (pop-up): load a not-same-site "parent" iframe (A->B)
+// (/web-locks/resources/iframe-parent.html) inside the pop-up.
+// Nested Step 4 (pop-up): send a web-lock request to the parent iframe.
+// Nested Step 5 (parent iframe): load a "child" iframe (A->B->A)
+// (/web-locks/resources/iframe.html) that is same-site with the
+// pop-up inside the "parent" iframe.
+// Nested Step 6 (parent iframe): pass on the web-lock request message to
+// the "child" iframe.
+// Nested Step 7 (child iframe): process the web-lock request and message
+// the result to the parent iframe.
+// Nested Step 8 (parent iframe): intercept the result message from the
+// child iframe and send it to the pop-up.
+// Nested Step 9 (pop-up): intercept the result message from the parent
+// iframe and send it to the top frame.
+// Nested Step 10 (top frame): add cleanup hook
+// Nested Step 11 (top frame): ensure that the same-site iframe's web-lock
+// request succeeds since it and the top-level are successfully
+// partitioned and each can hold an exclusive lock.
+
+// Map of lock_id => function that releases a lock.
+const held_2 = new Map();
+let next_lock_id_2 = 1;
+
+async function nested_iframe_test(t) {
+ // Create innermost child iframe (leaf).
+ let leaf_url = HTTPS_ORIGIN + '/web-locks/resources/iframe.html';
+ // Wrap the child iframe in its cross-origin parent (middle).
+ let middle_url = new URL(
+ `/web-locks/resources/iframe-parent.html?target=${encodeURIComponent(leaf_url)}`,
+ HTTPS_NOTSAMESITE_ORIGIN + self.location.pathname);
+ // Embed the parent iframe in the top-level site (top).
+ let top_url = new URL(
+ `/web-locks/resources/partitioned-parent.html?target=${encodeURIComponent(middle_url)}`,
+ HTTPS_ORIGIN + self.location.pathname);
+
+ // Nested Step 1.
+ // Request the weblock for the top-level site.
+ let lock_id = next_lock_id_2++;
+ let [ promise, release ] = makePromiseAndResolveFunc();
+ let released = navigator.locks.request('testLock', {mode: 'exclusive', ifAvailable: true},
+ lock => {
+ if (lock === null) {
+ assert_true(false)
+ return;
+ }
+ return promise;
+ }).catch(error => alert(error.message));
+ held_2.set(lock_id, { release, released });
+
+ // Nested Step 2.
+ // Open the nested iframes. The script in the innermost child iframe
+ // will attempt to obtain the same weblock as above.
+ const w = window.open(top_url);
+ const result = await new Promise(resolve => window.onmessage = resolve);
+
+ // Nested Step 10.
+ t.add_cleanup(() => {
+ w.close();
+ let released = [];
+ for(let i = 1; i < next_lock_id; i++){
+ let h = held_2.get(i);
+ h.release();
+ released.push(h.released);
+ }
+ return Promise.allSettled(released);
+ });
+
+ // Nested Step 11.
+ // With third-party storage partitioning enabled, the same-site iframe
+ // should be able to acquire the lock as it has a cross-site ancestor
+ // and is partitioned separately from the top-level site.
+ assert_equals(result.data.failed, undefined,
+ 'The 1p iframe failed to acquire the lock');
+}
+
+promise_test(t => {
+ return nested_iframe_test(t);
+}, 'WebLocks of a nested iframe with a cross-site ancestor are partitioned');
+</script>
+</body>