summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/shared-storage/resources
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/shared-storage/resources
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/shared-storage/resources')
-rw-r--r--testing/web-platform/tests/shared-storage/resources/cors-redirect.py21
-rw-r--r--testing/web-platform/tests/shared-storage/resources/credentials-test-helper.py22
-rw-r--r--testing/web-platform/tests/shared-storage/resources/delete-key.https.html19
-rw-r--r--testing/web-platform/tests/shared-storage/resources/delete-key.https.html.headers1
-rw-r--r--testing/web-platform/tests/shared-storage/resources/embedder-context-inner.https.html23
-rw-r--r--testing/web-platform/tests/shared-storage/resources/embedder-context-inner.https.html.headers1
-rw-r--r--testing/web-platform/tests/shared-storage/resources/embedder-context-module.js16
-rw-r--r--testing/web-platform/tests/shared-storage/resources/embedder-context-nested-iframe.https.html31
-rw-r--r--testing/web-platform/tests/shared-storage/resources/embedder-context-nested-inner.https.html33
-rw-r--r--testing/web-platform/tests/shared-storage/resources/embedder-context-nested-inner.https.html.headers1
-rw-r--r--testing/web-platform/tests/shared-storage/resources/frame0.html14
-rw-r--r--testing/web-platform/tests/shared-storage/resources/frame0.html.headers1
-rw-r--r--testing/web-platform/tests/shared-storage/resources/frame1.html14
-rw-r--r--testing/web-platform/tests/shared-storage/resources/frame1.html.headers1
-rw-r--r--testing/web-platform/tests/shared-storage/resources/register-service-worker-iframe.https.html66
-rw-r--r--testing/web-platform/tests/shared-storage/resources/report.py25
-rw-r--r--testing/web-platform/tests/shared-storage/resources/select-url-permissions-policy-helper.html18
-rw-r--r--testing/web-platform/tests/shared-storage/resources/sender0.html21
-rw-r--r--testing/web-platform/tests/shared-storage/resources/sender0.html.headers1
-rw-r--r--testing/web-platform/tests/shared-storage/resources/set-key-value.https.html20
-rw-r--r--testing/web-platform/tests/shared-storage/resources/shared-storage-permissions-policy-helper.html18
-rw-r--r--testing/web-platform/tests/shared-storage/resources/shared-storage-writable-fetch-request-fallback-to-network-iframe.https.html56
-rw-r--r--testing/web-platform/tests/shared-storage/resources/shared-storage-writable-fetch-request-fallback-to-network-worker.js15
-rw-r--r--testing/web-platform/tests/shared-storage/resources/shared-storage-writable-iframe-in-fenced-inner.https.sub.html29
-rw-r--r--testing/web-platform/tests/shared-storage/resources/shared-storage-writable-iframe-in-fenced-inner.https.sub.html.headers1
-rw-r--r--testing/web-platform/tests/shared-storage/resources/shared-storage-writable-pixel-write.pngbin0 -> 119 bytes
-rw-r--r--testing/web-platform/tests/shared-storage/resources/shared-storage-writable-pixel-write.png.sub.headers3
-rw-r--r--testing/web-platform/tests/shared-storage/resources/shared-storage-writable-pixel.pngbin0 -> 119 bytes
-rw-r--r--testing/web-platform/tests/shared-storage/resources/shared-storage-writable-pixel.png.sub.headers3
-rw-r--r--testing/web-platform/tests/shared-storage/resources/shared-storage-write-notify-parent.py23
-rw-r--r--testing/web-platform/tests/shared-storage/resources/shared-storage-write.py16
-rw-r--r--testing/web-platform/tests/shared-storage/resources/simple-module.js53
-rw-r--r--testing/web-platform/tests/shared-storage/resources/util.js217
-rw-r--r--testing/web-platform/tests/shared-storage/resources/util.sub.js117
-rw-r--r--testing/web-platform/tests/shared-storage/resources/verify-get-undefined-module.js17
-rw-r--r--testing/web-platform/tests/shared-storage/resources/verify-key-not-found.https.html34
-rw-r--r--testing/web-platform/tests/shared-storage/resources/verify-key-value.https.html34
-rw-r--r--testing/web-platform/tests/shared-storage/resources/verify-key-value.https.html.headers1
-rw-r--r--testing/web-platform/tests/shared-storage/resources/verify-shared-storage.https.html13
-rw-r--r--testing/web-platform/tests/shared-storage/resources/verify-storage-entries-module.js26
40 files changed, 1025 insertions, 0 deletions
diff --git a/testing/web-platform/tests/shared-storage/resources/cors-redirect.py b/testing/web-platform/tests/shared-storage/resources/cors-redirect.py
new file mode 100644
index 0000000000..a475ee4f96
--- /dev/null
+++ b/testing/web-platform/tests/shared-storage/resources/cors-redirect.py
@@ -0,0 +1,21 @@
+def main(request, response):
+ """Simple handler that causes redirection but also adds the
+ "Access-Control-Allow-Origin: *" header.
+
+ The request should typically have two query parameters:
+ status - The status to use for the redirection. Defaults to 302.
+ location - The resource to redirect to.
+ """
+ status = 302
+ if b"status" in request.GET:
+ try:
+ status = int(request.GET.first(b"status"))
+ except ValueError:
+ pass
+
+ response.status = status
+
+ location = request.GET.first(b"location")
+
+ response.headers.set(b"Location", location)
+ response.headers.append(b"Access-Control-Allow-Origin", b"*")
diff --git a/testing/web-platform/tests/shared-storage/resources/credentials-test-helper.py b/testing/web-platform/tests/shared-storage/resources/credentials-test-helper.py
new file mode 100644
index 0000000000..81a988e358
--- /dev/null
+++ b/testing/web-platform/tests/shared-storage/resources/credentials-test-helper.py
@@ -0,0 +1,22 @@
+def main(request, response):
+ """
+ A handler that does either one of the following based on the provided
+ "action" parameter:
+ 1) action="store-cookie": Stores the provided token and the request cookie
+ to the stash, and returns a regular module script content.
+ 2) action="get-cookie": Retrieves and returns the content stored in the
+ stash at the provided token.
+ """
+ token = request.GET[b"token"]
+ action = request.GET[b"action"]
+
+ response.status = 200
+ response.headers.append(b"Content-Type", b"text/javascript")
+
+ if action == b"store-cookie":
+ cookie = request.headers.get(b"Cookie", b"NO_COOKIE_HEADER")
+ request.server.stash.put(token, cookie)
+ return b""
+ else:
+ assert action == b"get-cookie"
+ return request.server.stash.take(token)
diff --git a/testing/web-platform/tests/shared-storage/resources/delete-key.https.html b/testing/web-platform/tests/shared-storage/resources/delete-key.https.html
new file mode 100644
index 0000000000..41595f3ee3
--- /dev/null
+++ b/testing/web-platform/tests/shared-storage/resources/delete-key.https.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+<script src=/resources/testharness.js></script>
+<script src=/shared-storage/resources/util.js></script>
+<script src=/fenced-frame/resources/utils.js></script>
+<body>
+<script>
+
+async function init() {
+ const [outerKey] = parseKeylist();
+ const parsedData = parseExpectedKeyData();
+ await sharedStorage.delete(parsedData['expectedKey']);
+ await writeValueToServer(outerKey, "delete_key_loaded");
+}
+
+init();
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/shared-storage/resources/delete-key.https.html.headers b/testing/web-platform/tests/shared-storage/resources/delete-key.https.html.headers
new file mode 100644
index 0000000000..1b63235b7c
--- /dev/null
+++ b/testing/web-platform/tests/shared-storage/resources/delete-key.https.html.headers
@@ -0,0 +1 @@
+Supports-Loading-Mode: fenced-frame
diff --git a/testing/web-platform/tests/shared-storage/resources/embedder-context-inner.https.html b/testing/web-platform/tests/shared-storage/resources/embedder-context-inner.https.html
new file mode 100644
index 0000000000..e4b59f7f7a
--- /dev/null
+++ b/testing/web-platform/tests/shared-storage/resources/embedder-context-inner.https.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<script src="/shared-storage/resources/util.js"></script>
+<script src="/fenced-frame/resources/utils.js"></script>
+<body>
+<script>
+
+async function init() {
+ const [ancestorKey] = parseKeylist();
+
+ await addModuleOnce("/shared-storage/resources/embedder-context-module.js");
+ await sharedStorage.run("report-context",
+ {
+ data: {'ancestorKey': ancestorKey}
+ });
+
+ await writeValueToServer(ancestorKey, "embedder_context_inner_loaded");
+}
+
+init();
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/shared-storage/resources/embedder-context-inner.https.html.headers b/testing/web-platform/tests/shared-storage/resources/embedder-context-inner.https.html.headers
new file mode 100644
index 0000000000..1b63235b7c
--- /dev/null
+++ b/testing/web-platform/tests/shared-storage/resources/embedder-context-inner.https.html.headers
@@ -0,0 +1 @@
+Supports-Loading-Mode: fenced-frame
diff --git a/testing/web-platform/tests/shared-storage/resources/embedder-context-module.js b/testing/web-platform/tests/shared-storage/resources/embedder-context-module.js
new file mode 100644
index 0000000000..782b97aea9
--- /dev/null
+++ b/testing/web-platform/tests/shared-storage/resources/embedder-context-module.js
@@ -0,0 +1,16 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+class ReportContext {
+ async run(data) {
+ if (!data || !data.hasOwnProperty('ancestorKey')) {
+ return;
+ }
+ const ancestorKey = data['ancestorKey'];
+ const context = sharedStorage.context;
+ await sharedStorage.set(ancestorKey, context);
+ }
+}
+
+register('report-context', ReportContext);
diff --git a/testing/web-platform/tests/shared-storage/resources/embedder-context-nested-iframe.https.html b/testing/web-platform/tests/shared-storage/resources/embedder-context-nested-iframe.https.html
new file mode 100644
index 0000000000..2ba25d1ed9
--- /dev/null
+++ b/testing/web-platform/tests/shared-storage/resources/embedder-context-nested-iframe.https.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+<script src="/resources/testharness.js"></script>
+<script src="/shared-storage/resources/util.js"></script>
+<script src="/fenced-frame/resources/utils.js"></script>
+<body>
+<script>
+
+async function init() {
+ const [outerKey, innerKey] = parseKeylist();
+ let url0 = generateURL("/shared-storage/resources/frame0.html", [innerKey]);
+ let url1 = generateURL("/shared-storage/resources/frame1.html", [innerKey]);
+
+ await addModuleOnce("simple-module.js");
+ let fencedFrameConfig = await sharedStorage.selectURL(
+ "verify-key-value", [{url: url0}, {url: url1}],
+ {data: {'expectedKey': innerKey, 'expectedValue': 'undefined'},
+ resolveToConfig: true});
+ assert_true(validateSelectURLResult(fencedFrameConfig, true));
+
+ attachFencedFrame(fencedFrameConfig, 'opaque-ads');
+ const result = await nextValueFromServer(innerKey);
+ assert_equals(result, "frame1_loaded");
+
+ await writeValueToServer(outerKey, "embedder_context_nested_iframe_loaded");
+}
+
+init();
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/shared-storage/resources/embedder-context-nested-inner.https.html b/testing/web-platform/tests/shared-storage/resources/embedder-context-nested-inner.https.html
new file mode 100644
index 0000000000..c704a00b73
--- /dev/null
+++ b/testing/web-platform/tests/shared-storage/resources/embedder-context-nested-inner.https.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<script src="/resources/testharness.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="/fenced-frame/resources/utils.js"></script>
+<body>
+<script>
+async function init() {
+ const [outerKey, innerKey0, innerKey1] = parseKeylist();
+ let url0 = generateURL(
+ "/shared-storage/resources/embedder-context-inner.https.html",
+ [innerKey0]);
+
+ attachIFrame(url0);
+ const result0 = await nextValueFromServer(innerKey0);
+ assert_equals(result0, "embedder_context_inner_loaded");
+
+ let url1 = generateURL(
+ "/shared-storage/resources/embedder-context-inner.https.html",
+ [innerKey1]);
+ url1 = getRemoteOriginURL(url1);
+
+ attachIFrame(url1);
+ const result1 = await nextValueFromServer(innerKey1);
+ assert_equals(result1, "embedder_context_inner_loaded");
+
+ await writeValueToServer(outerKey, "embedder_context_nested_inner_loaded");
+}
+
+init();
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/shared-storage/resources/embedder-context-nested-inner.https.html.headers b/testing/web-platform/tests/shared-storage/resources/embedder-context-nested-inner.https.html.headers
new file mode 100644
index 0000000000..1b63235b7c
--- /dev/null
+++ b/testing/web-platform/tests/shared-storage/resources/embedder-context-nested-inner.https.html.headers
@@ -0,0 +1 @@
+Supports-Loading-Mode: fenced-frame
diff --git a/testing/web-platform/tests/shared-storage/resources/frame0.html b/testing/web-platform/tests/shared-storage/resources/frame0.html
new file mode 100644
index 0000000000..c9b559fe83
--- /dev/null
+++ b/testing/web-platform/tests/shared-storage/resources/frame0.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+<script src="/fenced-frame/resources/utils.js"></script>
+<body>
+<script>
+async function init() {
+ const [ancestor_key] = parseKeylist();
+ writeValueToServer(ancestor_key, "frame0_loaded");
+}
+
+init();
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/shared-storage/resources/frame0.html.headers b/testing/web-platform/tests/shared-storage/resources/frame0.html.headers
new file mode 100644
index 0000000000..1b63235b7c
--- /dev/null
+++ b/testing/web-platform/tests/shared-storage/resources/frame0.html.headers
@@ -0,0 +1 @@
+Supports-Loading-Mode: fenced-frame
diff --git a/testing/web-platform/tests/shared-storage/resources/frame1.html b/testing/web-platform/tests/shared-storage/resources/frame1.html
new file mode 100644
index 0000000000..a34990dc03
--- /dev/null
+++ b/testing/web-platform/tests/shared-storage/resources/frame1.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+<script src="/fenced-frame/resources/utils.js"></script>
+<body>
+<script>
+async function init() {
+ const [ancestor_key] = parseKeylist();
+ writeValueToServer(ancestor_key, "frame1_loaded");
+}
+
+init();
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/shared-storage/resources/frame1.html.headers b/testing/web-platform/tests/shared-storage/resources/frame1.html.headers
new file mode 100644
index 0000000000..1b63235b7c
--- /dev/null
+++ b/testing/web-platform/tests/shared-storage/resources/frame1.html.headers
@@ -0,0 +1 @@
+Supports-Loading-Mode: fenced-frame
diff --git a/testing/web-platform/tests/shared-storage/resources/register-service-worker-iframe.https.html b/testing/web-platform/tests/shared-storage/resources/register-service-worker-iframe.https.html
new file mode 100644
index 0000000000..547ab1d93d
--- /dev/null
+++ b/testing/web-platform/tests/shared-storage/resources/register-service-worker-iframe.https.html
@@ -0,0 +1,66 @@
+<!doctype html>
+<body>
+ <script src=/resources/testharness.js></script>
+ <script src=/common/utils.js></script>
+ <script src=/fenced-frame/resources/utils.js></script>
+ <script src=/shared-storage/resources/util.js></script>
+ <script src=/shared-storage/resources/util.sub.js></script>
+ <script src=/service-workers/service-worker/resources/test-helpers.sub.js></script>
+ <script>
+ const INTERMEDIATE_FRAME_SUFFIX =
+ 'able-fetch-request-fallback-to-network-iframe.https.html'
+ const ORIGIN = new URL("", location.href).origin;
+
+ window.addEventListener('message', async function handler(event) {
+ const data = event.data;
+ if (data.script && data.scope && data.port) {
+ var absoluteScope = (new URL(data.scope, window.location).href);
+ let oldReg =await navigator.serviceWorker.getRegistration(data.scope);
+ if (oldReg && oldReg.scope === absoluteScope) {
+ await oldReg.unregister();
+ }
+ let reg = await navigator.serviceWorker.register(data.script,
+ { scope: data.scope });
+ let worker = reg.installing;
+ await new Promise(function(resolve) {
+ worker.addEventListener('statechange', function() {
+ if (worker.state == 'activated') {
+ resolve();
+ }
+ });
+ });
+ assert_not_equals(worker, null, 'worker is installing');
+
+ let result = await loadNestedSharedStorageFrameInNewFrame({
+ key: 'c', value: 'd',
+ hasSharedStorageWritableAttribute: true,
+ // Same-origin to this frame, cross-origin to top.
+ isSameOrigin: true,
+ });
+ const urls = [
+ {
+ "url": ORIGIN + data.scope + INTERMEDIATE_FRAME_SUFFIX,
+ "mode": "navigate",
+ "SSWHeader": "null"
+ },
+ {
+ "url": ORIGIN + "/resources/testharness.js",
+ "mode": "no-cors",
+ "SSWHeader": "null"
+ },
+ {
+ "url": ORIGIN + result.nestedFrameUrl,
+ "mode": "navigate",
+ "SSWHeader": "null"
+ },
+ ];
+ await checkInterceptedUrls(worker, urls);
+ await verifyKeyValueForOrigin('c', 'd', ORIGIN);
+ await deleteKeyForOrigin('c', ORIGIN);
+ data.port.postMessage({msg: 'test completed'});
+ reg.unregister()
+ window.removeEventListener('message', handler);
+ }
+ });
+ </script>
+</body>
diff --git a/testing/web-platform/tests/shared-storage/resources/report.py b/testing/web-platform/tests/shared-storage/resources/report.py
new file mode 100644
index 0000000000..7d0fa36019
--- /dev/null
+++ b/testing/web-platform/tests/shared-storage/resources/report.py
@@ -0,0 +1,25 @@
+def main(request, response):
+
+ # `token` should be a unique UUID request parameter for the duration of this
+ # request. It will get stored in the server stash and will be used later in
+ # a query request.
+ # `query` should be a request parameter indicating the request would like
+ # to know how many times the server has seen the request (with the
+ # same token).
+ token = request.GET.first(b"token", None)
+ is_query = request.GET.first(b"query", None) is not None
+ with request.server.stash.lock:
+ value = request.server.stash.take(token)
+ count = 0
+ if value is not None:
+ count = int(value)
+ if is_query:
+ request.server.stash.put(token, count)
+ else:
+ count += 1
+ request.server.stash.put(token, count)
+
+ headers = []
+ if is_query:
+ headers = [(b"Count", count)]
+ return (200, headers, b"")
diff --git a/testing/web-platform/tests/shared-storage/resources/select-url-permissions-policy-helper.html b/testing/web-platform/tests/shared-storage/resources/select-url-permissions-policy-helper.html
new file mode 100644
index 0000000000..b70d763ad4
--- /dev/null
+++ b/testing/web-platform/tests/shared-storage/resources/select-url-permissions-policy-helper.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<body>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/shared-storage/resources/util.js"></script>
+ <script>
+ 'use strict';
+
+ window.onload = async function() {
+ if (await IsSharedStorageSelectUrlAllowedByPermissionsPolicy()) {
+ parent.postMessage({ type: 'availability-result', enabled: true }, '*');
+ return;
+ }
+
+ parent.postMessage({ type: 'availability-result', enabled: false }, '*');
+ }
+ </script>
+</body>
diff --git a/testing/web-platform/tests/shared-storage/resources/sender0.html b/testing/web-platform/tests/shared-storage/resources/sender0.html
new file mode 100644
index 0000000000..e3d0475f12
--- /dev/null
+++ b/testing/web-platform/tests/shared-storage/resources/sender0.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+<script src="/fenced-frame/resources/utils.js"></script>
+<body>
+<script>
+async function init() {
+ const [ancestor_key] = parseKeylist();
+
+ window.fence.reportEvent({
+ eventType: 'click',
+ eventData: "user clicked",
+ destination: ['shared-storage-select-url']
+ });
+
+ writeValueToServer(ancestor_key, "sender0_reported");
+}
+
+init();
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/shared-storage/resources/sender0.html.headers b/testing/web-platform/tests/shared-storage/resources/sender0.html.headers
new file mode 100644
index 0000000000..1b63235b7c
--- /dev/null
+++ b/testing/web-platform/tests/shared-storage/resources/sender0.html.headers
@@ -0,0 +1 @@
+Supports-Loading-Mode: fenced-frame
diff --git a/testing/web-platform/tests/shared-storage/resources/set-key-value.https.html b/testing/web-platform/tests/shared-storage/resources/set-key-value.https.html
new file mode 100644
index 0000000000..ba0a24ceb2
--- /dev/null
+++ b/testing/web-platform/tests/shared-storage/resources/set-key-value.https.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<script src=/resources/testharness.js></script>
+<script src=/shared-storage/resources/util.js></script>
+<script src=/fenced-frame/resources/utils.js></script>
+<body>
+<script>
+
+async function init() {
+ const [outerKey] = parseKeylist();
+ const parsedData = parseExpectedKeyAndValueData();
+ await sharedStorage.set(parsedData['expectedKey'],
+ parsedData['expectedValue']);
+ await writeValueToServer(outerKey, "set_key_value_loaded");
+}
+
+init();
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/shared-storage/resources/shared-storage-permissions-policy-helper.html b/testing/web-platform/tests/shared-storage/resources/shared-storage-permissions-policy-helper.html
new file mode 100644
index 0000000000..d87092aad1
--- /dev/null
+++ b/testing/web-platform/tests/shared-storage/resources/shared-storage-permissions-policy-helper.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<body>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/shared-storage/resources/util.js"></script>
+ <script>
+ 'use strict';
+
+ window.onload = async function() {
+ if (await AreSharedStorageMethodsAllowedByPermissionsPolicy()) {
+ parent.postMessage({ type: 'availability-result', enabled: true }, '*');
+ return;
+ }
+
+ parent.postMessage({ type: 'availability-result', enabled: false }, '*');
+ }
+ </script>
+</body>
diff --git a/testing/web-platform/tests/shared-storage/resources/shared-storage-writable-fetch-request-fallback-to-network-iframe.https.html b/testing/web-platform/tests/shared-storage/resources/shared-storage-writable-fetch-request-fallback-to-network-iframe.https.html
new file mode 100644
index 0000000000..3451d91477
--- /dev/null
+++ b/testing/web-platform/tests/shared-storage/resources/shared-storage-writable-fetch-request-fallback-to-network-iframe.https.html
@@ -0,0 +1,56 @@
+<!doctype html>
+<body>
+ <script src=/resources/testharness.js></script>
+ <script>
+ function loadImage(url, hasSharedStorageWritableAttribute) {
+ return new Promise(function(resolve, reject) {
+ var img = document.createElement('img');
+ document.body.appendChild(img);
+ img.onload = function() {
+ resolve(img);
+ };
+ img.onerror = function() {
+ reject(new Error('Image load failed'));
+ };
+ if (hasSharedStorageWritableAttribute) {
+ img.sharedStorageWritable = true;
+ }
+ img.src = url;
+ });
+ }
+
+ function loadFrame(url, hasSharedStorageWritableAttribute) {
+ return new Promise(function(resolve, reject) {
+ var frame = document.createElement('iframe');
+ document.body.appendChild(frame);
+ frame.onload = function() {
+ window.parent.postMessage({msg: 'iframe loaded'}, "*");
+ resolve(frame);
+ };
+ frame.onerror = function() {
+ reject(new Error('Nested iframe load failed'));
+ };
+ if (hasSharedStorageWritableAttribute) {
+ frame.sharedStorageWritable = true;
+ }
+ frame.src = url;
+ });
+ }
+
+ function fetchUrl(url, hasSharedStorageWritableAttribute) {
+ return new Promise(function(resolve, reject) {
+ fetch(url, {sharedStorageWritable:
+ hasSharedStorageWritableAttribute})
+ .then(response => {
+ if (!response.ok) {
+ throw new Error('Failed to fetch ' + url + '; '
+ + String(response.status) + ' ' + response.statusText);
+ }
+ resolve(response);
+ }).catch(error => {
+ reject(error);
+ });
+ });
+ }
+ </script>
+</body>
diff --git a/testing/web-platform/tests/shared-storage/resources/shared-storage-writable-fetch-request-fallback-to-network-worker.js b/testing/web-platform/tests/shared-storage/resources/shared-storage-writable-fetch-request-fallback-to-network-worker.js
new file mode 100644
index 0000000000..d304669ea1
--- /dev/null
+++ b/testing/web-platform/tests/shared-storage/resources/shared-storage-writable-fetch-request-fallback-to-network-worker.js
@@ -0,0 +1,15 @@
+var requests = [];
+
+self.addEventListener('message', function(event) {
+ event.data.port.postMessage({requests: requests});
+ requests = [];
+});
+
+self.addEventListener('fetch', function(event) {
+ let maybeHeader = event.request.headers.get('Sec-Shared-Storage-Writable');
+ requests.push({
+ url: event.request.url,
+ mode: event.request.mode,
+ SSWHeader: String(maybeHeader),
+ });
+});
diff --git a/testing/web-platform/tests/shared-storage/resources/shared-storage-writable-iframe-in-fenced-inner.https.sub.html b/testing/web-platform/tests/shared-storage/resources/shared-storage-writable-iframe-in-fenced-inner.https.sub.html
new file mode 100644
index 0000000000..87dbe81a2b
--- /dev/null
+++ b/testing/web-platform/tests/shared-storage/resources/shared-storage-writable-iframe-in-fenced-inner.https.sub.html
@@ -0,0 +1,29 @@
+<!doctype html>
+<body>
+ <script src=/resources/testharness.js></script>
+ <script src=/common/utils.js></script>
+ <script src=/fenced-frame/resources/utils.js></script>
+ <script src=/shared-storage/resources/util.js></script>
+ <script src=/shared-storage/resources/util.sub.js></script>
+ <script>
+
+async function init() {
+ const sameOrigin = new URL("", location.href).origin;
+ const [outerKey] = parseKeylist();
+ let {expectedKey, expectedValue} = parseExpectedKeyAndValueData();
+ const promise = navigateSharedStorageIframe({
+ hasSharedStorageWritableAttribute: true,
+ rawWriteHeader: `set;key=${expectedKey};value=${expectedValue}`,
+ isSameOrigin: true,
+ expectSharedStorageWritableHeader: true,
+ });
+ promise.then(() => {
+ verifyKeyValueForOrigin(expectedKey, expectedValue, sameOrigin);
+ deleteKeyForOrigin(expectedKey, sameOrigin);
+ writeValueToServer(outerKey, "writable_iframe_in_fenced_inner_loaded");
+ });
+}
+
+init();
+ </script>
+</body>
diff --git a/testing/web-platform/tests/shared-storage/resources/shared-storage-writable-iframe-in-fenced-inner.https.sub.html.headers b/testing/web-platform/tests/shared-storage/resources/shared-storage-writable-iframe-in-fenced-inner.https.sub.html.headers
new file mode 100644
index 0000000000..1b63235b7c
--- /dev/null
+++ b/testing/web-platform/tests/shared-storage/resources/shared-storage-writable-iframe-in-fenced-inner.https.sub.html.headers
@@ -0,0 +1 @@
+Supports-Loading-Mode: fenced-frame
diff --git a/testing/web-platform/tests/shared-storage/resources/shared-storage-writable-pixel-write.png b/testing/web-platform/tests/shared-storage/resources/shared-storage-writable-pixel-write.png
new file mode 100644
index 0000000000..818c71d03f
--- /dev/null
+++ b/testing/web-platform/tests/shared-storage/resources/shared-storage-writable-pixel-write.png
Binary files differ
diff --git a/testing/web-platform/tests/shared-storage/resources/shared-storage-writable-pixel-write.png.sub.headers b/testing/web-platform/tests/shared-storage/resources/shared-storage-writable-pixel-write.png.sub.headers
new file mode 100644
index 0000000000..9f2cb718aa
--- /dev/null
+++ b/testing/web-platform/tests/shared-storage/resources/shared-storage-writable-pixel-write.png.sub.headers
@@ -0,0 +1,3 @@
+Timing-Allow-Origin: *
+Access-Control-Allow-Origin: *
+Shared-Storage-Write: {{GET[write]}}
diff --git a/testing/web-platform/tests/shared-storage/resources/shared-storage-writable-pixel.png b/testing/web-platform/tests/shared-storage/resources/shared-storage-writable-pixel.png
new file mode 100644
index 0000000000..818c71d03f
--- /dev/null
+++ b/testing/web-platform/tests/shared-storage/resources/shared-storage-writable-pixel.png
Binary files differ
diff --git a/testing/web-platform/tests/shared-storage/resources/shared-storage-writable-pixel.png.sub.headers b/testing/web-platform/tests/shared-storage/resources/shared-storage-writable-pixel.png.sub.headers
new file mode 100644
index 0000000000..8b541e7b13
--- /dev/null
+++ b/testing/web-platform/tests/shared-storage/resources/shared-storage-writable-pixel.png.sub.headers
@@ -0,0 +1,3 @@
+Timing-Allow-Origin: *
+Access-Control-Allow-Origin: *
+Shared-Storage-Write: set;key={{GET[key]}};value={{GET[value]}}
diff --git a/testing/web-platform/tests/shared-storage/resources/shared-storage-write-notify-parent.py b/testing/web-platform/tests/shared-storage/resources/shared-storage-write-notify-parent.py
new file mode 100644
index 0000000000..63041218c8
--- /dev/null
+++ b/testing/web-platform/tests/shared-storage/resources/shared-storage-write-notify-parent.py
@@ -0,0 +1,23 @@
+from wptserve.utils import isomorphic_decode
+from wptserve.utils import isomorphic_encode
+from urllib.parse import unquote
+
+def unescape_query_value(query_value_bytes):
+ return isomorphic_encode(unquote(isomorphic_decode(query_value_bytes)))
+
+def main(request, response):
+ writable_header = request.headers.get(
+ b"Sec-Shared-Storage-Writable",
+ b"NO_SHARED_STORAGE_WRITABLE_HEADER")
+ response.headers.append(b"Content-Type", b"text/html")
+ response.headers.append(b"Access-Control-Allow-Origin", b"*")
+ response.headers.append(b"Supports-Loading-Mode", b"fenced-frame")
+ if writable_header == b"?1" and b'write' in request.GET:
+ write_header = unescape_query_value(request.GET[b'write'])
+ response.headers.append(b"Shared-Storage-Write", write_header)
+ response.content = b'''
+<script>
+ let parentOrOpener = window.opener || window.parent;
+ parentOrOpener.postMessage({ sharedStorageWritableHeader: '%s'}, "*");
+</script>
+''' % (writable_header)
diff --git a/testing/web-platform/tests/shared-storage/resources/shared-storage-write.py b/testing/web-platform/tests/shared-storage/resources/shared-storage-write.py
new file mode 100644
index 0000000000..fabe1eba26
--- /dev/null
+++ b/testing/web-platform/tests/shared-storage/resources/shared-storage-write.py
@@ -0,0 +1,16 @@
+from wptserve.utils import isomorphic_decode
+from wptserve.utils import isomorphic_encode
+from urllib.parse import unquote
+
+def unescape_query_value(query_value_bytes):
+ return isomorphic_encode(unquote(isomorphic_decode(query_value_bytes)))
+
+def main(request, response):
+ writable_header = request.headers.get(
+ b"Sec-Shared-Storage-Writable",
+ b"NO_SHARED_STORAGE_WRITABLE_HEADER")
+ response.headers.append(b"Access-Control-Allow-Origin", b"*")
+ if writable_header == b"?1" and b'write' in request.GET:
+ write_header = unescape_query_value(request.GET[b'write'])
+ response.headers.append(b"Shared-Storage-Write", write_header)
+ response.content = writable_header
diff --git a/testing/web-platform/tests/shared-storage/resources/simple-module.js b/testing/web-platform/tests/shared-storage/resources/simple-module.js
new file mode 100644
index 0000000000..620a3592f2
--- /dev/null
+++ b/testing/web-platform/tests/shared-storage/resources/simple-module.js
@@ -0,0 +1,53 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+var globalVar = 0;
+
+class TestURLSelectionOperation {
+ async run(urls, data) {
+ if (data && data.hasOwnProperty('mockResult')) {
+ return data['mockResult'];
+ }
+
+ return -1;
+ }
+}
+
+class IncrementGlobalVariableAndReturnOriginalValueOperation {
+ async run(urls, data) {
+ return globalVar++;
+ }
+}
+
+class VerifyKeyValue {
+ async run(urls, data) {
+ if (data && data.hasOwnProperty('expectedKey') &&
+ data.hasOwnProperty('expectedValue')) {
+ const expectedValue = data['expectedValue'];
+ const value = await sharedStorage.get(data['expectedKey']);
+ if (value === expectedValue) {
+ return 1;
+ }
+ }
+ return -1;
+ }
+}
+
+class VerifyKeyNotFound {
+ async run(urls, data) {
+ if (data && data.hasOwnProperty('expectedKey')) {
+ const value = await sharedStorage.get(data['expectedKey']);
+ if (typeof value === 'undefined') {
+ return 1;
+ }
+ }
+ return -1;
+ }
+}
+
+register('test-url-selection-operation', TestURLSelectionOperation);
+register('increment-global-variable-and-return-original-value-operation',
+ IncrementGlobalVariableAndReturnOriginalValueOperation);
+register('verify-key-value', VerifyKeyValue);
+register('verify-key-not-found', VerifyKeyNotFound);
diff --git a/testing/web-platform/tests/shared-storage/resources/util.js b/testing/web-platform/tests/shared-storage/resources/util.js
new file mode 100644
index 0000000000..4a7fcc4590
--- /dev/null
+++ b/testing/web-platform/tests/shared-storage/resources/util.js
@@ -0,0 +1,217 @@
+// META: script=/common/utils.js
+// META: script=/fenced-frame/resources/utils.js
+'use strict';
+
+async function IsSharedStorageSelectUrlAllowedByPermissionsPolicy() {
+ const errorMessage = 'The \"shared-storage-select-url\" Permissions Policy denied the usage of window.sharedStorage.selectURL().';
+ let allowedByPermissionsPolicy = true;
+ try {
+ // Run selectURL() with without addModule() and this should always fail.
+ // Check the error message to distinguish between the permissions policy
+ // error and the missing addModule() error.
+ await sharedStorage.selectURL("operation", [{url: "1.html"}]);
+ assert_unreached("did not fail");
+ } catch (e) {
+ if (e.message === errorMessage) {
+ allowedByPermissionsPolicy = false;
+ }
+ }
+
+ return allowedByPermissionsPolicy;
+}
+
+// Execute all shared storage methods and capture their errors. Return true if
+// the permissions policy allows all of them; return false if the permissions
+// policy disallows all of them. Precondition: only these two outcomes are
+// possible.
+async function AreSharedStorageMethodsAllowedByPermissionsPolicy() {
+ let permissionsPolicyDeniedCount = 0;
+ const errorMessage = 'The \"shared-storage\" Permissions Policy denied the method on window.sharedStorage.';
+
+ try {
+ await window.sharedStorage.worklet.addModule('/shared-storage/resources/simple-module.js');
+ } catch (e) {
+ assert_equals(e.message, errorMessage);
+ ++permissionsPolicyDeniedCount;
+ }
+
+ try {
+ await window.sharedStorage.run('operation');
+ } catch (e) {
+ assert_equals(e.message, errorMessage);
+ ++permissionsPolicyDeniedCount;
+ }
+
+ try {
+ // Run selectURL() with without addModule() and this should always fail.
+ // Check the error message to distinguish between the permissions policy
+ // error and the missing addModule() error.
+ await sharedStorage.selectURL("operation", [{url: "1.html"}]);
+ assert_unreached("did not fail");
+ } catch (e) {
+ if (e.message === errorMessage) {
+ ++permissionsPolicyDeniedCount;
+ }
+ }
+
+ try {
+ await window.sharedStorage.set('a', 'b');
+ } catch (e) {
+ assert_equals(e.message, errorMessage);
+ ++permissionsPolicyDeniedCount;
+ }
+
+ try {
+ await window.sharedStorage.append('a', 'b');
+ } catch (e) {
+ assert_equals(e.message, errorMessage);
+ ++permissionsPolicyDeniedCount;
+ }
+
+ try {
+ await window.sharedStorage.clear();
+ } catch (e) {
+ assert_equals(e.message, errorMessage);
+ ++permissionsPolicyDeniedCount;
+ }
+
+ try {
+ await window.sharedStorage.delete('a');
+ } catch (e) {
+ assert_equals(e.message, errorMessage);
+ ++permissionsPolicyDeniedCount;
+ }
+
+ if (permissionsPolicyDeniedCount === 0)
+ return true;
+
+ return false;
+}
+
+// Run sharedStorage.worklet.addModule once.
+// @param {string} module - The URL to the module.
+async function addModuleOnce(module) {
+ try {
+ await sharedStorage.worklet.addModule(module);
+ } catch (e) {
+ // Shared Storage needs to have a module added before we can operate on it.
+ // It is generated on the fly with this call, and since there's no way to
+ // tell through the API if a module already exists, wrap the addModule call
+ // in a try/catch so that if it runs a second time in a test, it will
+ // gracefully fail rather than bring the whole test down.
+ }
+}
+
+// Validate the type of the result of sharedStorage.worklet.selectURL.
+// @param result - The result of sharedStorage.worklet.selectURL.
+// @param {boolean} - Whether sharedStorage.worklet.selectURL is resolved to
+// a fenced frame config (true) or an urn:uuid (false).
+// @return {boolean} Whether sharedStorage.worklet.selectURL returns an expected
+// result type or not.
+function validateSelectURLResult(result, resolve_to_config) {
+ if (resolve_to_config) {
+ return result instanceof FencedFrameConfig;
+ }
+
+ return result.startsWith('urn:uuid:');
+}
+
+function updateUrlToUseNewOrigin(url, newOriginString) {
+ const origin = url.origin;
+ return new URL(url.toString().replace(origin, newOriginString));
+}
+
+function appendExpectedKeyAndValue(url, expectedKey, expectedValue) {
+ url.searchParams.append('expectedKey', expectedKey);
+ url.searchParams.append('expectedValue', expectedValue);
+ return url;
+}
+
+function parseExpectedKeyAndValueData() {
+ const url = new URL(location.href);
+ const key = url.searchParams.get('expectedKey');
+ const value = url.searchParams.get('expectedValue');
+ return {'expectedKey': key, 'expectedValue': value};
+}
+
+function appendExpectedKey(url, expectedKey) {
+ url.searchParams.append('expectedKey', expectedKey);
+ return url;
+}
+
+function parseExpectedKeyData() {
+ const url = new URL(location.href);
+ const key = url.searchParams.get('expectedKey');
+ return {'expectedKey': key};
+}
+
+async function verifyKeyValueForOrigin(key, value, origin) {
+ const outerKey = token();
+ const innerKey = token();
+ let iframeUrl = generateURL(
+ '/shared-storage/resources/verify-key-value.https.html',
+ [outerKey, innerKey]);
+ iframeUrl = updateUrlToUseNewOrigin(iframeUrl, origin);
+ iframeUrl = appendExpectedKeyAndValue(iframeUrl, key, value);
+
+ attachIFrame(iframeUrl);
+ const result = await nextValueFromServer(outerKey);
+ assert_equals(result, 'verify_key_value_loaded');
+}
+
+async function verifyKeyNotFoundForOrigin(key, origin) {
+ const outerKey = token();
+ const innerKey = token();
+ let iframeUrl = generateURL(
+ '/shared-storage/resources/verify-key-not-found.https.html',
+ [outerKey, innerKey]);
+ iframeUrl = updateUrlToUseNewOrigin(iframeUrl, origin);
+ iframeUrl = appendExpectedKey(iframeUrl, key);
+
+ attachIFrame(iframeUrl);
+ const result = await nextValueFromServer(outerKey);
+ assert_equals(result, 'verify_key_not_found_loaded');
+}
+
+async function setKeyValueForOrigin(key, value, origin) {
+ const outerKey = token();
+ let setIframeUrl = generateURL(
+ '/shared-storage/resources/set-key-value.https.html', [outerKey]);
+ setIframeUrl = updateUrlToUseNewOrigin(setIframeUrl, origin);
+ setIframeUrl = appendExpectedKeyAndValue(setIframeUrl, key, value);
+
+ attachIFrame(setIframeUrl);
+ const result = await nextValueFromServer(outerKey);
+ assert_equals(result, 'set_key_value_loaded');
+}
+
+async function deleteKeyForOrigin(key, origin) {
+ const outerKey = token();
+ let deleteIframeUrl = generateURL(
+ '/shared-storage/resources/delete-key.https.html', [outerKey]);
+ deleteIframeUrl = updateUrlToUseNewOrigin(deleteIframeUrl, origin);
+ deleteIframeUrl = appendExpectedKey(deleteIframeUrl, key);
+
+ attachIFrame(deleteIframeUrl);
+ const result = await nextValueFromServer(outerKey);
+ assert_equals(result, 'delete_key_loaded');
+}
+
+function getFetchedUrls(worker) {
+ return new Promise(function(resolve) {
+ var channel = new MessageChannel();
+ channel.port1.onmessage = function(msg) {
+ resolve(msg);
+ };
+ worker.postMessage({port: channel.port2}, [channel.port2]);
+ });
+}
+
+function checkInterceptedUrls(worker, expectedRequests) {
+ return getFetchedUrls(worker).then(function(msg) {
+ let actualRequests = msg.data.requests;
+ assert_equals(actualRequests.length, expectedRequests.length);
+ assert_equals(
+ JSON.stringify(actualRequests), JSON.stringify(expectedRequests));
+ });
+}
diff --git a/testing/web-platform/tests/shared-storage/resources/util.sub.js b/testing/web-platform/tests/shared-storage/resources/util.sub.js
new file mode 100644
index 0000000000..f147209d60
--- /dev/null
+++ b/testing/web-platform/tests/shared-storage/resources/util.sub.js
@@ -0,0 +1,117 @@
+function loadSharedStorageImage(data) {
+ let {key, value, hasSharedStorageWritableAttribute, isSameOrigin} = data;
+ const sameOriginSrc = `/shared-storage/resources/` +
+ `shared-storage-writable-pixel.png?key=${key}&value=${value}`;
+ const crossOriginSrc =
+ 'https://{{domains[www]}}:{{ports[https][0]}}' + sameOriginSrc;
+
+ let image = document.createElement('img');
+ image.src = isSameOrigin ? sameOriginSrc : crossOriginSrc;
+ if (hasSharedStorageWritableAttribute) {
+ image.sharedStorageWritable = true;
+ }
+
+ const promise = new Promise((resolve, reject) => {
+ image.addEventListener('load', () => {
+ resolve(image);
+ });
+ image.addEventListener('error', () => {
+ reject(new Error('Image load failed'));
+ });
+ });
+
+ document.body.appendChild(image);
+ return promise;
+}
+
+function navigateSharedStorageIframe(data) {
+ let {
+ hasSharedStorageWritableAttribute,
+ rawWriteHeader,
+ isSameOrigin,
+ expectSharedStorageWritableHeader
+ } = data;
+ const writeHeader = encodeURIComponent(rawWriteHeader);
+ const sameOriginSrc =
+ `/shared-storage/resources/shared-storage-write-notify-parent.py` +
+ `?write=${writeHeader}`;
+ const crossOriginSrc =
+ 'https://{{domains[www]}}:{{ports[https][0]}}' + sameOriginSrc;
+
+ let frame = document.createElement('iframe');
+ frame.src = isSameOrigin ? sameOriginSrc : crossOriginSrc;
+ if (hasSharedStorageWritableAttribute) {
+ frame.sharedStorageWritable = true;
+ }
+
+ const expectedResult = expectSharedStorageWritableHeader ?
+ '?1' :
+ 'NO_SHARED_STORAGE_WRITABLE_HEADER';
+
+ function checkExpectedResult(data) {
+ assert_equals(data.sharedStorageWritableHeader, expectedResult);
+ }
+
+ const promise = new Promise((resolve, reject) => {
+ window.addEventListener('message', async function handler(evt) {
+ if (evt.source === frame.contentWindow) {
+ checkExpectedResult(evt.data);
+ document.body.removeChild(frame);
+ window.removeEventListener('message', handler);
+ resolve();
+ }
+ });
+ window.addEventListener('error', () => {
+ reject(new Error('Navigation error'));
+ });
+ });
+
+ document.body.appendChild(frame);
+ return promise;
+}
+
+async function loadNestedSharedStorageFrameInNewFrame(data) {
+ const SCOPE = '/shared-storage/resources/shared-storage-writ';
+ const INTERMEDIATE_FRAME_SUFFIX =
+ 'able-fetch-request-fallback-to-network-iframe.https.html'
+ const CROSS_ORIGIN = 'https://{{domains[www]}}:{{ports[https][0]}}';
+
+ let {key, value, hasSharedStorageWritableAttribute, isSameOrigin} = data;
+
+ const windowPromise = new Promise((resolve, reject) => {
+ window.addEventListener('message', async function handler(evt) {
+ if (evt.data.msg && evt.data.msg === 'iframe loaded') {
+ window.removeEventListener('message', handler);
+ resolve();
+ }
+ });
+ window.addEventListener('error', () => {
+ reject(new Error('Navigation error'));
+ });
+ });
+
+ const framePromise = new Promise((resolve, reject) => {
+ let frame = document.createElement('iframe');
+ frame.src = SCOPE + INTERMEDIATE_FRAME_SUFFIX;
+ frame.onload = function() {
+ resolve(frame);
+ };
+ frame.onerror = function() {
+ reject(new Error('Iframe load failed'));
+ };
+ document.body.appendChild(frame);
+ });
+ let frame = await framePromise;
+
+ let rawWriteHeader = `set;key=${key};value=${value}`;
+ let writeHeader = encodeURIComponent(rawWriteHeader);
+ const sameOriginNestedSrc = `/shared-storage/resources/` +
+ `shared-storage-write.py?write=${writeHeader}`;
+ const nestedSrc =
+ isSameOrigin ? sameOriginNestedSrc : CROSS_ORIGIN + sameOriginNestedSrc;
+
+ let nestedFrame = frame.contentWindow.loadFrame(
+ nestedSrc, hasSharedStorageWritableAttribute);
+ await windowPromise;
+ return {frame: frame, nestedFrame: nestedFrame, nestedFrameUrl: nestedSrc};
+}
diff --git a/testing/web-platform/tests/shared-storage/resources/verify-get-undefined-module.js b/testing/web-platform/tests/shared-storage/resources/verify-get-undefined-module.js
new file mode 100644
index 0000000000..56bc2f51e2
--- /dev/null
+++ b/testing/web-platform/tests/shared-storage/resources/verify-get-undefined-module.js
@@ -0,0 +1,17 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+class VerifyGetUndefinedURLSelectionOperation {
+ async run(urls, data) {
+ if (await sharedStorage.get('key-not-previously-set') === undefined) {
+ return 1;
+ }
+
+ return -1;
+ }
+}
+
+register(
+ 'verify-get-undefined-url-selection-operation',
+ VerifyGetUndefinedURLSelectionOperation);
diff --git a/testing/web-platform/tests/shared-storage/resources/verify-key-not-found.https.html b/testing/web-platform/tests/shared-storage/resources/verify-key-not-found.https.html
new file mode 100644
index 0000000000..f1c7919c19
--- /dev/null
+++ b/testing/web-platform/tests/shared-storage/resources/verify-key-not-found.https.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+<script src=/resources/testharness.js></script>
+<script src=/shared-storage/resources/util.js></script>
+<script src=/fenced-frame/resources/utils.js></script>
+<body>
+<script>
+
+async function init() {
+ const [outerKey, innerKey] = parseKeylist();
+ const parsedData = parseExpectedKeyData();
+ let url0 = generateURL("/shared-storage/resources/frame0.html", [innerKey]);
+ let url1 = generateURL("/shared-storage/resources/frame1.html", [innerKey]);
+
+ await addModuleOnce("/shared-storage/resources/simple-module.js");
+ let fencedFrameConfig = await sharedStorage.selectURL(
+ "verify-key-not-found", [{url: url0}, {url: url1}],
+ {data: parsedData, resolveToConfig: true});
+ assert_true(validateSelectURLResult(fencedFrameConfig, true));
+
+ attachFencedFrame(fencedFrameConfig, 'opaque-ads');
+ const result = await nextValueFromServer(innerKey);
+ const dataStr = JSON.stringify(parsedData);
+ assert_equals(result, "frame1_loaded",
+ `verifying key ${dataStr} not found for ${location.origin};`);
+
+ await writeValueToServer(outerKey,
+ "verify_key_not_found_loaded");
+}
+
+init();
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/shared-storage/resources/verify-key-value.https.html b/testing/web-platform/tests/shared-storage/resources/verify-key-value.https.html
new file mode 100644
index 0000000000..20c4694104
--- /dev/null
+++ b/testing/web-platform/tests/shared-storage/resources/verify-key-value.https.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+<script src=/resources/testharness.js></script>
+<script src=/shared-storage/resources/util.js></script>
+<script src=/fenced-frame/resources/utils.js></script>
+<body>
+<script>
+
+async function init() {
+ const [outerKey, innerKey] = parseKeylist();
+ const parsedData = parseExpectedKeyAndValueData();
+ let url0 = generateURL("/shared-storage/resources/frame0.html", [innerKey]);
+ let url1 = generateURL("/shared-storage/resources/frame1.html", [innerKey]);
+
+ await addModuleOnce("/shared-storage/resources/simple-module.js");
+ let fencedFrameConfig = await sharedStorage.selectURL(
+ "verify-key-value", [{url: url0}, {url: url1}],
+ {data: parsedData, resolveToConfig: true});
+ assert_true(validateSelectURLResult(fencedFrameConfig, true));
+
+ attachFencedFrame(fencedFrameConfig, 'opaque-ads');
+ const result = await nextValueFromServer(innerKey);
+ const dataStr = JSON.stringify(parsedData);
+ assert_equals(result, "frame1_loaded",
+ `verifying key, value ${dataStr} found for ${location.origin};`);
+
+ await writeValueToServer(outerKey,
+ "verify_key_value_loaded");
+}
+
+init();
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/shared-storage/resources/verify-key-value.https.html.headers b/testing/web-platform/tests/shared-storage/resources/verify-key-value.https.html.headers
new file mode 100644
index 0000000000..1b63235b7c
--- /dev/null
+++ b/testing/web-platform/tests/shared-storage/resources/verify-key-value.https.html.headers
@@ -0,0 +1 @@
+Supports-Loading-Mode: fenced-frame
diff --git a/testing/web-platform/tests/shared-storage/resources/verify-shared-storage.https.html b/testing/web-platform/tests/shared-storage/resources/verify-shared-storage.https.html
new file mode 100644
index 0000000000..52c79e7e85
--- /dev/null
+++ b/testing/web-platform/tests/shared-storage/resources/verify-shared-storage.https.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script>
+ try {
+ window.sharedStorage;
+ window.parent.postMessage({ accessSharedStorageResult: 'success'}, "*");
+ } catch (error) {
+ window.parent.postMessage({ accessSharedStorageResult: 'failure'}, "*");
+ }
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/shared-storage/resources/verify-storage-entries-module.js b/testing/web-platform/tests/shared-storage/resources/verify-storage-entries-module.js
new file mode 100644
index 0000000000..ee0c636cd1
--- /dev/null
+++ b/testing/web-platform/tests/shared-storage/resources/verify-storage-entries-module.js
@@ -0,0 +1,26 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+class SetKey0Operation {
+ async run(data) {
+ sharedStorage.set('key0-set-from-worklet', 'value0');
+ }
+}
+
+class VerifyStorageEntriesURLSelectionOperation {
+ async run(urls, data) {
+ if (await sharedStorage.get('key0-set-from-worklet') === 'value0' &&
+ await sharedStorage.get('key0-set-from-document') === 'value0') {
+ return 1;
+ }
+
+ return -1;
+ }
+}
+
+register('set-key0-operation', SetKey0Operation);
+
+register(
+ 'verify-storage-entries-url-selection-operation',
+ VerifyStorageEntriesURLSelectionOperation);