summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/storage-access-api
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/storage-access-api')
-rw-r--r--testing/web-platform/tests/storage-access-api/META.yml6
-rw-r--r--testing/web-platform/tests/storage-access-api/hasStorageAccess-insecure.sub.window.js42
-rw-r--r--testing/web-platform/tests/storage-access-api/hasStorageAccess.sub.https.window.js42
-rw-r--r--testing/web-platform/tests/storage-access-api/helpers.js63
-rw-r--r--testing/web-platform/tests/storage-access-api/idlharness.window.js14
-rw-r--r--testing/web-platform/tests/storage-access-api/requestStorageAccess-cross-origin-iframe.sub.https.window.js18
-rw-r--r--testing/web-platform/tests/storage-access-api/requestStorageAccess-insecure.sub.window.js83
-rw-r--r--testing/web-platform/tests/storage-access-api/requestStorageAccess-nested-cross-origin-iframe.sub.https.window.js19
-rw-r--r--testing/web-platform/tests/storage-access-api/requestStorageAccess-nested-same-origin-iframe.sub.https.window.js8
-rw-r--r--testing/web-platform/tests/storage-access-api/requestStorageAccess-non-fully-active.sub.https.window.js18
-rw-r--r--testing/web-platform/tests/storage-access-api/requestStorageAccess-same-origin-iframe.sub.https.window.js7
-rw-r--r--testing/web-platform/tests/storage-access-api/requestStorageAccess.sub.https.window.js67
-rw-r--r--testing/web-platform/tests/storage-access-api/resources/hasStorageAccess-iframe.html8
-rw-r--r--testing/web-platform/tests/storage-access-api/resources/hasStorageAccess-iframe.https.html8
-rw-r--r--testing/web-platform/tests/storage-access-api/resources/requestStorageAccess-iframe.html10
-rw-r--r--testing/web-platform/tests/storage-access-api/resources/requestStorageAccess-iframe.https.html10
-rw-r--r--testing/web-platform/tests/storage-access-api/resources/set-cookie.py27
-rw-r--r--testing/web-platform/tests/storage-access-api/sandboxAttribute.window.js7
-rw-r--r--testing/web-platform/tests/storage-access-api/storageAccess.testdriver.sub.html34
19 files changed, 491 insertions, 0 deletions
diff --git a/testing/web-platform/tests/storage-access-api/META.yml b/testing/web-platform/tests/storage-access-api/META.yml
new file mode 100644
index 0000000000..554bd31684
--- /dev/null
+++ b/testing/web-platform/tests/storage-access-api/META.yml
@@ -0,0 +1,6 @@
+spec: https://privacycg.github.io/storage-access/
+suggested_reviewers:
+ - Brandr0id
+ - cfredric
+ - ehsan
+ - johnwilander
diff --git a/testing/web-platform/tests/storage-access-api/hasStorageAccess-insecure.sub.window.js b/testing/web-platform/tests/storage-access-api/hasStorageAccess-insecure.sub.window.js
new file mode 100644
index 0000000000..35bb73a80a
--- /dev/null
+++ b/testing/web-platform/tests/storage-access-api/hasStorageAccess-insecure.sub.window.js
@@ -0,0 +1,42 @@
+// META: script=helpers.js
+'use strict';
+
+const {expectAccessAllowed, testPrefix, topLevelDocument} = processQueryParams();
+
+// Common tests to run in all frames.
+test(() => {
+ assert_not_equals(document.hasStorageAccess, undefined);
+}, "[" + testPrefix + "] document.hasStorageAccess() should be supported on the document interface");
+
+promise_test(async () => {
+ const hasAccess = await document.hasStorageAccess();
+ assert_false(hasAccess, "Access should be disallowed in insecure contexts");
+}, "[" + testPrefix + "] document.hasStorageAccess() should be disallowed in insecure contexts");
+
+promise_test(async () => {
+ const createdDocument = document.implementation.createDocument("", null);
+
+ const hasAccess = await createdDocument.hasStorageAccess();
+ assert_false(hasAccess, "Access should be denied to a generated document not part of the DOM.");
+}, "[" + testPrefix + "] document.hasStorageAccess() should work on a document object.");
+
+// Logic to load test cases within combinations of iFrames.
+if (topLevelDocument) {
+ // This specific test will run only as a top level test (not as a worker).
+ // Specific hasStorageAccess() scenarios will be tested within the context
+ // of various iFrames
+
+ // Create a test with a single-child same-origin iframe.
+ RunTestsInIFrame("resources/hasStorageAccess-iframe.html?testCase=same-origin-frame&rootdocument=false");
+
+ // Create a test with a single-child cross-origin iframe.
+ RunTestsInIFrame("http://{{domains[www]}}:{{ports[http][0]}}/storage-access-api/resources/hasStorageAccess-iframe.html?testCase=cross-origin-frame&rootdocument=false");
+
+ // Validate the nested-iframe scenario where the same-origin frame containing
+ // the tests is not the first child.
+ RunTestsInNestedIFrame("resources/hasStorageAccess-iframe.html?testCase=nested-same-origin-frame&rootdocument=false");
+
+ // Validate the nested-iframe scenario where the cross-origin frame containing
+ // the tests is not the first child.
+ RunTestsInNestedIFrame("http://{{domains[www]}}:{{ports[http][0]}}/storage-access-api/resources/hasStorageAccess-iframe.html?testCase=nested-cross-origin-frame&rootdocument=false");
+}
diff --git a/testing/web-platform/tests/storage-access-api/hasStorageAccess.sub.https.window.js b/testing/web-platform/tests/storage-access-api/hasStorageAccess.sub.https.window.js
new file mode 100644
index 0000000000..ede7dd62b5
--- /dev/null
+++ b/testing/web-platform/tests/storage-access-api/hasStorageAccess.sub.https.window.js
@@ -0,0 +1,42 @@
+// META: script=helpers.js
+'use strict';
+
+const {expectAccessAllowed, testPrefix, topLevelDocument} = processQueryParams();
+
+// Common tests to run in all frames.
+test(() => {
+ assert_not_equals(document.hasStorageAccess, undefined);
+}, "[" + testPrefix + "] document.hasStorageAccess() should exist on the document interface");
+
+promise_test(async () => {
+ const hasAccess = await document.hasStorageAccess();
+ assert_equals(hasAccess, expectAccessAllowed, "Access should be granted by default: " + expectAccessAllowed);
+}, "[" + testPrefix + "] document.hasStorageAccess() should be allowed by default: " + expectAccessAllowed);
+
+promise_test(async () => {
+ const createdDocument = document.implementation.createDocument("", null);
+
+ const hasAccess = await createdDocument.hasStorageAccess();
+ assert_false(hasAccess, "Access should be denied to a generated document not part of the DOM.");
+}, "[" + testPrefix + "] document.hasStorageAccess() should work on a document object.");
+
+// Logic to load test cases within combinations of iFrames.
+if (topLevelDocument) {
+ // This specific test will run only as a top level test (not as a worker).
+ // Specific hasStorageAccess() scenarios will be tested within the context
+ // of various iFrames
+
+ // Create a test with a single-child same-origin iframe.
+ RunTestsInIFrame("resources/hasStorageAccess-iframe.https.html?testCase=same-origin-frame&rootdocument=false");
+
+ // Create a test with a single-child cross-origin iframe.
+ RunTestsInIFrame("https://{{domains[www]}}:{{ports[https][0]}}/storage-access-api/resources/hasStorageAccess-iframe.https.html?testCase=cross-origin-frame&rootdocument=false");
+
+ // Validate the nested-iframe scenario where the same-origin frame containing
+ // the tests is not the first child.
+ RunTestsInNestedIFrame("resources/hasStorageAccess-iframe.https.html?testCase=nested-same-origin-frame&rootdocument=false");
+
+ // Validate the nested-iframe scenario where the cross-origin frame containing
+ // the tests is not the first child.
+ RunTestsInNestedIFrame("https://{{domains[www]}}:{{ports[https][0]}}/storage-access-api/resources/hasStorageAccess-iframe.https.html?testCase=nested-cross-origin-frame&rootdocument=false");
+}
diff --git a/testing/web-platform/tests/storage-access-api/helpers.js b/testing/web-platform/tests/storage-access-api/helpers.js
new file mode 100644
index 0000000000..de9fba2d1c
--- /dev/null
+++ b/testing/web-platform/tests/storage-access-api/helpers.js
@@ -0,0 +1,63 @@
+'use strict';
+
+function processQueryParams() {
+ const queryParams = new URL(window.location).searchParams;
+ return {
+ expectAccessAllowed: queryParams.get("allowed") != "false",
+ topLevelDocument: queryParams.get("rootdocument") != "false",
+ testPrefix: queryParams.get("testCase") || "top-level-context",
+ };
+}
+
+function CreateFrameAndRunTests(setUpFrame) {
+ const frame = document.createElement('iframe');
+ const promise = new Promise((resolve, reject) => {
+ frame.onload = resolve;
+ frame.onerror = reject;
+ });
+
+ setUpFrame(frame);
+
+ fetch_tests_from_window(frame.contentWindow);
+ return promise;
+}
+
+function RunTestsInIFrame(sourceURL) {
+ return CreateFrameAndRunTests((frame) => {
+ frame.src = sourceURL;
+ document.body.appendChild(frame);
+ });
+}
+
+function RunTestsInNestedIFrame(sourceURL) {
+ return CreateFrameAndRunTests((frame) => {
+ document.body.appendChild(frame);
+ frame.contentDocument.write(`
+ <script src="/resources/testharness.js"></script>
+ <script src="helpers.js"></script>
+ <body>
+ <script>
+ RunTestsInIFrame("${sourceURL}");
+ </script>
+ `);
+ frame.contentDocument.close();
+ });
+}
+
+function RunRequestStorageAccessInDetachedFrame() {
+ const frame = document.createElement('iframe');
+ document.body.append(frame);
+ const inner_doc = frame.contentDocument;
+ frame.remove();
+ return inner_doc.requestStorageAccess();
+}
+
+function RunRequestStorageAccessViaDomParser() {
+ const parser = new DOMParser();
+ const doc = parser.parseFromString('<html></html>', 'text/html');
+ return doc.requestStorageAccess();
+}
+
+function RunCallbackWithGesture(callback) {
+ return test_driver.bless('run callback with user gesture', callback);
+}
diff --git a/testing/web-platform/tests/storage-access-api/idlharness.window.js b/testing/web-platform/tests/storage-access-api/idlharness.window.js
new file mode 100644
index 0000000000..41c6b84d68
--- /dev/null
+++ b/testing/web-platform/tests/storage-access-api/idlharness.window.js
@@ -0,0 +1,14 @@
+// META: global=window,worker
+// META: script=/resources/WebIDLParser.js
+// META: script=/resources/idlharness.js
+'use strict';
+
+idl_test(
+ ['storage-access'],
+ ['dom'],
+ idl_array => {
+ idl_array.add_objects({
+ Document: ['document'],
+ });
+ }
+);
diff --git a/testing/web-platform/tests/storage-access-api/requestStorageAccess-cross-origin-iframe.sub.https.window.js b/testing/web-platform/tests/storage-access-api/requestStorageAccess-cross-origin-iframe.sub.https.window.js
new file mode 100644
index 0000000000..38e3fd6d9a
--- /dev/null
+++ b/testing/web-platform/tests/storage-access-api/requestStorageAccess-cross-origin-iframe.sub.https.window.js
@@ -0,0 +1,18 @@
+// META: script=helpers.js
+// META: script=/resources/testdriver.js
+// META: script=/resources/testdriver-vendor.js
+'use strict';
+
+(async function() {
+ // Set up storage access rules
+ try {
+ await test_driver.set_storage_access("https://{{domains[www]}}:{{ports[https][0]}}/", "*", "blocked");
+ } catch (e) {
+ // Ignore, can be unimplemented if the platform blocks cross-site cookies
+ // by default. If this failed without default blocking we'll notice it later
+ // in the test.
+ }
+
+ // Create a test with a single-child cross-origin iframe.
+ RunTestsInIFrame('https://{{domains[www]}}:{{ports[https][0]}}/storage-access-api/resources/requestStorageAccess-iframe.https.html?testCase=cross-origin-frame&rootdocument=false');
+})();
diff --git a/testing/web-platform/tests/storage-access-api/requestStorageAccess-insecure.sub.window.js b/testing/web-platform/tests/storage-access-api/requestStorageAccess-insecure.sub.window.js
new file mode 100644
index 0000000000..f845f0647c
--- /dev/null
+++ b/testing/web-platform/tests/storage-access-api/requestStorageAccess-insecure.sub.window.js
@@ -0,0 +1,83 @@
+// META: script=helpers.js
+// META: script=/resources/testdriver.js
+// META: script=/resources/testdriver-vendor.js
+'use strict';
+
+// Document-level test config flags:
+//
+// testPrefix: Prefix each test case with an indicator so we know what context
+// they are run in if they are used in multiple iframes.
+//
+// topLevelDocument: Keep track of if we run these tests in a nested context, we
+// don't want to recurse forever.
+const {testPrefix, topLevelDocument} = processQueryParams();
+
+// Common tests to run in all frames.
+test(() => {
+ assert_not_equals(document.requestStorageAccess, undefined);
+}, "[" + testPrefix + "] document.requestStorageAccess() should exist on the document interface");
+
+promise_test(t => {
+ return promise_rejects_dom(t, "NotAllowedError", document.requestStorageAccess(),
+ "document.requestStorageAccess() call without user gesture");
+}, "[" + testPrefix + "] document.requestStorageAccess() should be rejected in insecure context");
+
+// Logic to load test cases within combinations of iFrames.
+if (topLevelDocument) {
+ // This specific test will run only as a top level test (not as a worker).
+ // Specific requestStorageAccess() scenarios will be tested within the context
+ // of various iFrames
+ promise_test(t => {
+ const description = "document.requestStorageAccess() call in a detached frame";
+ // Can't use `promise_rejects_dom` here, since the error comes from the wrong global.
+ return RunRequestStorageAccessInDetachedFrame()
+ .then(t.unreached_func("Should have rejected: " + description), (e) => {
+ assert_equals(e.name, 'InvalidStateError', description);
+ });
+ }, "[non-fully-active] document.requestStorageAccess() should reject when run in a detached frame");
+
+ promise_test(t => {
+ return promise_rejects_dom(t, 'InvalidStateError', RunRequestStorageAccessViaDomParser(),
+ "document.requestStorageAccess() in a detached DOMParser result");
+ }, "[non-fully-active] document.requestStorageAccess() should reject when run in a detached DOMParser document");
+
+ // Create a test with a single-child same-origin iframe.
+ const sameOriginFramePromise = RunTestsInIFrame(
+ 'resources/requestStorageAccess-iframe.html?testCase=same-origin-frame&rootdocument=false');
+
+ // Create a test with a single-child cross-origin iframe.
+ const crossOriginFramePromise = RunTestsInIFrame(
+ 'http://{{domains[www]}}:{{ports[http][0]}}/storage-access-api/resources/requestStorageAccess-iframe.html?testCase=cross-origin-frame&rootdocument=false');
+
+ // Validate the nested-iframe scenario where the same-origin frame
+ // containing the tests is not the first child.
+ const nestedSameOriginFramePromise = RunTestsInNestedIFrame(
+ 'resources/requestStorageAccess-iframe.html?testCase=nested-same-origin-frame&rootdocument=false');
+
+ // Validate the nested-iframe scenario where the cross-origin frame
+ // containing the tests is not the first child.
+ const nestedCrossOriginFramePromise = RunTestsInNestedIFrame(
+ 'http://{{domains[www]}}:{{ports[http][0]}}/storage-access-api/resources/requestStorageAccess-iframe.html?testCase=nested-cross-origin-frame&rootdocument=false');
+
+ // Because the iframe tests expect no user activation, and because they
+ // load asynchronously, we want to first run those tests before simulating
+ // clicks on the page.
+ Promise
+ .all([
+ sameOriginFramePromise,
+ crossOriginFramePromise,
+ nestedSameOriginFramePromise,
+ nestedCrossOriginFramePromise,
+ ])
+ .then(() => {
+ promise_test(
+ async t => {
+ await RunCallbackWithGesture(() => {
+ return promise_rejects_dom(t, "NotAllowedError", document.requestStorageAccess(),
+ "should reject in insecure context");
+ });
+ },
+ '[' + testPrefix +
+ '] document.requestStorageAccess() should be rejected when called with a user gesture in insecure context');
+ });
+}
diff --git a/testing/web-platform/tests/storage-access-api/requestStorageAccess-nested-cross-origin-iframe.sub.https.window.js b/testing/web-platform/tests/storage-access-api/requestStorageAccess-nested-cross-origin-iframe.sub.https.window.js
new file mode 100644
index 0000000000..bdc5429e18
--- /dev/null
+++ b/testing/web-platform/tests/storage-access-api/requestStorageAccess-nested-cross-origin-iframe.sub.https.window.js
@@ -0,0 +1,19 @@
+// META: script=helpers.js
+// META: script=/resources/testdriver.js
+// META: script=/resources/testdriver-vendor.js
+'use strict';
+
+(async function() {
+ // Set up storage access rules
+ try {
+ await test_driver.set_storage_access("https://{{domains[www]}}:{{ports[https][0]}}/", "*", "blocked");
+ } catch (e) {
+ // Ignore, can be unimplemented if the platform blocks cross-site cookies
+ // by default. If this failed without default blocking we'll notice it later
+ // in the test.
+ }
+
+ // Validate the nested-iframe scenario where the cross-origin frame
+ // containing the tests is not the first child.
+ RunTestsInNestedIFrame('https://{{domains[www]}}:{{ports[https][0]}}/storage-access-api/resources/requestStorageAccess-iframe.https.html?testCase=nested-cross-origin-frame&rootdocument=false');
+})();
diff --git a/testing/web-platform/tests/storage-access-api/requestStorageAccess-nested-same-origin-iframe.sub.https.window.js b/testing/web-platform/tests/storage-access-api/requestStorageAccess-nested-same-origin-iframe.sub.https.window.js
new file mode 100644
index 0000000000..b3847bbc94
--- /dev/null
+++ b/testing/web-platform/tests/storage-access-api/requestStorageAccess-nested-same-origin-iframe.sub.https.window.js
@@ -0,0 +1,8 @@
+// META: script=helpers.js
+// META: script=/resources/testdriver.js
+// META: script=/resources/testdriver-vendor.js
+'use strict';
+
+// Validate the nested-iframe scenario where the same-origin frame
+// containing the tests is not the first child.
+RunTestsInNestedIFrame('resources/requestStorageAccess-iframe.https.html?testCase=nested-same-origin-frame&rootdocument=false');
diff --git a/testing/web-platform/tests/storage-access-api/requestStorageAccess-non-fully-active.sub.https.window.js b/testing/web-platform/tests/storage-access-api/requestStorageAccess-non-fully-active.sub.https.window.js
new file mode 100644
index 0000000000..b3aa19c25c
--- /dev/null
+++ b/testing/web-platform/tests/storage-access-api/requestStorageAccess-non-fully-active.sub.https.window.js
@@ -0,0 +1,18 @@
+// META: script=helpers.js
+// META: script=/resources/testdriver.js
+// META: script=/resources/testdriver-vendor.js
+'use strict';
+
+promise_test(t => {
+ const promise = RunRequestStorageAccessInDetachedFrame();
+ const description = "document.requestStorageAccess() call in a detached frame";
+ // Can't use `promise_rejects_dom` here, since the error comes from the wrong global.
+ return promise.then(t.unreached_func("Should have rejected: " + description), (e) => {
+ assert_equals(e.name, 'InvalidStateError', description);
+ });
+}, "[non-fully-active] document.requestStorageAccess() should not resolve when run in a detached frame");
+
+promise_test(t => {
+ return promise_rejects_dom(t, 'InvalidStateError', RunRequestStorageAccessViaDomParser(),
+ "document.requestStorageAccess() in a detached DOMParser result");
+}, "[non-fully-active] document.requestStorageAccess() should not resolve when run in a detached DOMParser document");
diff --git a/testing/web-platform/tests/storage-access-api/requestStorageAccess-same-origin-iframe.sub.https.window.js b/testing/web-platform/tests/storage-access-api/requestStorageAccess-same-origin-iframe.sub.https.window.js
new file mode 100644
index 0000000000..9c41d6cbbe
--- /dev/null
+++ b/testing/web-platform/tests/storage-access-api/requestStorageAccess-same-origin-iframe.sub.https.window.js
@@ -0,0 +1,7 @@
+// META: script=helpers.js
+// META: script=/resources/testdriver.js
+// META: script=/resources/testdriver-vendor.js
+'use strict';
+
+// Create a test with a single-child same-origin iframe.
+RunTestsInIFrame('resources/requestStorageAccess-iframe.html?testCase=same-origin-frame&rootdocument=false');
diff --git a/testing/web-platform/tests/storage-access-api/requestStorageAccess.sub.https.window.js b/testing/web-platform/tests/storage-access-api/requestStorageAccess.sub.https.window.js
new file mode 100644
index 0000000000..a74866e56b
--- /dev/null
+++ b/testing/web-platform/tests/storage-access-api/requestStorageAccess.sub.https.window.js
@@ -0,0 +1,67 @@
+// META: script=helpers.js
+// META: script=/resources/testdriver.js
+// META: script=/resources/testdriver-vendor.js
+'use strict';
+
+// Document-level test config flags:
+//
+// testPrefix: Prefix each test case with an indicator so we know what context
+// they are run in if they are used in multiple iframes.
+const {testPrefix} = processQueryParams();
+
+if (window !== window.top) {
+ // WPT synthesizes a top-level HTML test for this JS file, and in that case we
+ // don't want to, or need to, call set_test_context.
+ test_driver.set_test_context(window.top);
+}
+
+// Common tests to run in all frames.
+test(() => {
+ assert_not_equals(document.requestStorageAccess, undefined);
+}, "[" + testPrefix + "] document.requestStorageAccess() should exist on the document interface");
+
+// Promise tests should all start with the feature in "prompt" state.
+promise_setup(async () => {
+ await test_driver.set_permission(
+ { name: 'storage-access' }, 'prompt');
+});
+
+promise_test(t => {
+ return promise_rejects_dom(t, "NotAllowedError", document.requestStorageAccess(),
+ "document.requestStorageAccess() call without user gesture");
+}, "[" + testPrefix + "] document.requestStorageAccess() should be rejected with a NotAllowedError by default with no user gesture");
+
+promise_test(
+ async () => {
+ await test_driver.set_permission(
+ {name: 'storage-access'}, 'granted');
+
+ await RunCallbackWithGesture(() => document.requestStorageAccess());
+ },
+ '[' + testPrefix +
+ '] document.requestStorageAccess() should be resolved when called properly with a user gesture');
+
+if (testPrefix == 'cross-origin-frame' || testPrefix == 'nested-cross-origin-frame') {
+ promise_test(
+ async t => {
+ await RunCallbackWithGesture(() => {
+ return promise_rejects_dom(t, "NotAllowedError", document.requestStorageAccess(),
+ "document.requestStorageAccess() call without permission");
+ });
+ },
+ '[' + testPrefix +
+ '] document.requestStorageAccess() should be rejected with a NotAllowedError without permission grant');
+
+ promise_test(
+ async t => {
+ await test_driver.set_permission(
+ {name: 'storage-access'}, 'denied');
+
+ await RunCallbackWithGesture(() => {
+ return promise_rejects_dom(t, "NotAllowedError", document.requestStorageAccess(),
+ "document.requestStorageAccess() call without permission");
+ });
+ },
+ '[' + testPrefix +
+ '] document.requestStorageAccess() should be rejected with a NotAllowedError with denied permission');
+}
diff --git a/testing/web-platform/tests/storage-access-api/resources/hasStorageAccess-iframe.html b/testing/web-platform/tests/storage-access-api/resources/hasStorageAccess-iframe.html
new file mode 100644
index 0000000000..d57c3961e5
--- /dev/null
+++ b/testing/web-platform/tests/storage-access-api/resources/hasStorageAccess-iframe.html
@@ -0,0 +1,8 @@
+<!doctype html>
+<meta charset=utf-8>
+
+<script src="/resources/testharness.js"></script>
+<!-- no testharnessreport.js -->
+<script src="../helpers.js"></script>
+<div id=log></div>
+<script src="/storage-access-api/hasStorageAccess-insecure.sub.window.js"></script>
diff --git a/testing/web-platform/tests/storage-access-api/resources/hasStorageAccess-iframe.https.html b/testing/web-platform/tests/storage-access-api/resources/hasStorageAccess-iframe.https.html
new file mode 100644
index 0000000000..95169503c2
--- /dev/null
+++ b/testing/web-platform/tests/storage-access-api/resources/hasStorageAccess-iframe.https.html
@@ -0,0 +1,8 @@
+<!doctype html>
+<meta charset=utf-8>
+
+<script src="/resources/testharness.js"></script>
+<!-- no testharnessreport.js -->
+<script src="../helpers.js"></script>
+<div id=log></div>
+<script src="/storage-access-api/hasStorageAccess.sub.https.window.js"></script>
diff --git a/testing/web-platform/tests/storage-access-api/resources/requestStorageAccess-iframe.html b/testing/web-platform/tests/storage-access-api/resources/requestStorageAccess-iframe.html
new file mode 100644
index 0000000000..8b47786e17
--- /dev/null
+++ b/testing/web-platform/tests/storage-access-api/resources/requestStorageAccess-iframe.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<meta charset=utf-8>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<!-- no testharnessreport.js -->
+<script src="../helpers.js"></script>
+<div id=log></div>
+<script src="/storage-access-api/requestStorageAccess-insecure.sub.window.js"></script>
diff --git a/testing/web-platform/tests/storage-access-api/resources/requestStorageAccess-iframe.https.html b/testing/web-platform/tests/storage-access-api/resources/requestStorageAccess-iframe.https.html
new file mode 100644
index 0000000000..4880464a25
--- /dev/null
+++ b/testing/web-platform/tests/storage-access-api/resources/requestStorageAccess-iframe.https.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<meta charset=utf-8>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<!-- no testharnessreport.js -->
+<script src="../helpers.js"></script>
+<div id=log></div>
+<script src="/storage-access-api/requestStorageAccess.sub.https.window.js"></script>
diff --git a/testing/web-platform/tests/storage-access-api/resources/set-cookie.py b/testing/web-platform/tests/storage-access-api/resources/set-cookie.py
new file mode 100644
index 0000000000..019697a4a8
--- /dev/null
+++ b/testing/web-platform/tests/storage-access-api/resources/set-cookie.py
@@ -0,0 +1,27 @@
+def main(request, response):
+ name = request.GET.first(b"name")
+ value = request.GET.first(b"value")
+ testcase = request.GET.first(b"testcase")
+ response_headers = [(b"Set-Cookie", name + b"=" + value)]
+
+ body = b"""
+ <!DOCTYPE html>
+ <meta charset="utf-8">
+ <title>Set Storage Access Subframe</title>
+ <script src="/resources/testharness.js"></script>
+
+ <script>
+ let querystring = window.location.search.substring(1).split("&");
+ const allowed = querystring.some(param => param.toLowerCase() === "allowed=true");
+
+ test(() => {
+ if (allowed) {
+ assert_equals(document.cookie, "%s=%s");
+ } else {
+ assert_equals(document.cookie, "");
+ }
+ }, "[%s] Cookie access is allowed: " + allowed);
+ </script>
+ """ % (name, value, testcase)
+
+ return (200, response_headers, body)
diff --git a/testing/web-platform/tests/storage-access-api/sandboxAttribute.window.js b/testing/web-platform/tests/storage-access-api/sandboxAttribute.window.js
new file mode 100644
index 0000000000..de79cd07a9
--- /dev/null
+++ b/testing/web-platform/tests/storage-access-api/sandboxAttribute.window.js
@@ -0,0 +1,7 @@
+'use strict';
+
+test(() => {
+ let iframe = document.createElement('iframe');
+ assert_true(iframe.sandbox.supports('allow-storage-access-by-user-activation'), '`allow-storage-access-by-user-activation`' +
+ 'sandbox attribute should be supported');
+}, "`allow-storage-access-by-user-activation` sandbox attribute is supported");
diff --git a/testing/web-platform/tests/storage-access-api/storageAccess.testdriver.sub.html b/testing/web-platform/tests/storage-access-api/storageAccess.testdriver.sub.html
new file mode 100644
index 0000000000..80108b5190
--- /dev/null
+++ b/testing/web-platform/tests/storage-access-api/storageAccess.testdriver.sub.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<head>
+ <title>TestDriver - Set Storage Access Command Tests</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/resources/testdriver.js"></script>
+ <script src="/resources/testdriver-vendor.js"></script>
+ <script src="helpers.js"></script>
+</head>
+<body>
+ <script>
+ "use strict";
+
+ promise_test(async t => {
+ // Allow a third-party site embedded in this first-party site.
+ await window.test_driver.set_storage_access("http://{{domains[www]}}:{{ports[http][0]}}/", "http://{{domains[]}}:{{ports[http][0]}}/", "allowed");
+ await window.test_driver.set_storage_access("https://{{domains[www]}}:{{ports[https][0]}}/", "https://{{domains[]}}:{{ports[https][0]}}/", "allowed");
+ // Block a third-party site embedded in this first-party site.
+ await window.test_driver.set_storage_access("http://{{domains[www1]}}:{{ports[http][0]}}/", "http://{{domains[]}}:{{ports[http][0]}}/", "blocked");
+ await window.test_driver.set_storage_access("https://{{domains[www1]}}:{{ports[https][0]}}/", "https://{{domains[]}}:{{ports[https][0]}}/", "blocked");
+ // Block a third-party site on all first-party sites.
+ await window.test_driver.set_storage_access("http://{{domains[www2]}}:{{ports[http][0]}}/", "*", "blocked");
+ await window.test_driver.set_storage_access("https://{{domains[www2]}}:{{ports[https][0]}}/", "*", "blocked");
+ }, "Set up storage access rules");
+
+ RunTestsInIFrame("http://{{domains[]}}:{{ports[http][0]}}/storage-access-api/resources/set-cookie.py?name=hello0&value=world0&allowed=true&testcase=same-site");
+
+ RunTestsInIFrame("http://{{domains[www]}}:{{ports[http][0]}}/storage-access-api/resources/set-cookie.py?name=hello&value=world&allowed=true&testcase=third-party-allowed-on-first-party-site");
+
+ RunTestsInIFrame("http://{{domains[www1]}}:{{ports[http][0]}}/storage-access-api/resources/set-cookie.py?name=hello1&value=world1&allowed=false&testcase=third-party-blocked-on-first-party-site");
+
+ RunTestsInIFrame("http://{{domains[www2]}}:{{ports[http][0]}}/storage-access-api/resources/set-cookie.py?name=hello2&value=world2&allowed=false&testcase=third-party-blocked-all");
+ </script>
+</body>