diff options
Diffstat (limited to 'testing/web-platform/tests/top-level-storage-access-api')
7 files changed, 314 insertions, 0 deletions
diff --git a/testing/web-platform/tests/top-level-storage-access-api/README.md b/testing/web-platform/tests/top-level-storage-access-api/README.md new file mode 100644 index 0000000000..e3636a221e --- /dev/null +++ b/testing/web-platform/tests/top-level-storage-access-api/README.md @@ -0,0 +1,4 @@ +# requestStorageAccessFor Tests +These tests are tentative. They are based on a proposed requestStorageAccessFor extension to the Storage Access API which can be read about [in the explainer](https://github.com/privacycg/requestStorageAccessForOrigin). + +Note that the spec is in progress, and available [rendered](https://privacycg.github.io/requestStorageAccessForOrigin/) and [in bikeshed source](https://github.com/privacycg/requestStorageAccessForOrigin/blob/main/index.bs). diff --git a/testing/web-platform/tests/top-level-storage-access-api/tentative/requestStorageAccessFor-insecure.sub.window.js b/testing/web-platform/tests/top-level-storage-access-api/tentative/requestStorageAccessFor-insecure.sub.window.js new file mode 100644 index 0000000000..0852483ce5 --- /dev/null +++ b/testing/web-platform/tests/top-level-storage-access-api/tentative/requestStorageAccessFor-insecure.sub.window.js @@ -0,0 +1,62 @@ +// META: script=/storage-access-api/helpers.js +// META: script=/resources/testdriver.js +// META: script=/resources/testdriver-vendor.js +'use strict'; + +promise_test(async () => { + assert_not_equals(document.requestStorageAccessFor, undefined); +}, '[top-level-context] document.requestStorageAccessFor() should be supported on the document interface'); + +promise_test( + t => { + return promise_rejects_dom(t, 'NotAllowedError', + document.requestStorageAccessFor('https://test.com'), + 'document.requestStorageAccessFor() call without user gesture'); + }, + '[top-level-context] document.requestStorageAccessFor() should be rejected by default with no user gesture'); + +promise_test(async t => { + const description = + 'document.requestStorageAccessFor() call in a detached frame'; + // Can't use promise_rejects_dom here because the exception is from the wrong global. + return CreateDetachedFrame().requestStorageAccessFor('https://foo.com') + .then(t.unreached_func('Should have rejected: ' + description)) + .catch((e) => { + assert_equals(e.name, 'InvalidStateError', description); + }); +}, '[non-fully-active] document.requestStorageAccessFor() should not resolve when run in a detached frame'); + +promise_test(async t => { + const description = + 'document.requestStorageAccessFor() in a detached DOMParser result'; + return CreateDocumentViaDOMParser().requestStorageAccessFor('https://foo.com') + .then(t.unreached_func('Should have rejected: ' + description)) + .catch((e) => { + assert_equals(e.name, 'InvalidStateError', description); + }); +}, '[non-fully-active] document.requestStorageAccessFor() should not resolve when run in a detached DOMParser document'); + +promise_test( + async () => { + const frame = await CreateFrame( + '../storage-access-api/resources/script-with-cookie-header.py?script=embedded_responder.js'); + assert_not_equals(frame.contentWindow.document.requestStorageAccessFor, undefined); + }, + '[frame-on-insecure-page] document.requestStorageAccessFor() should be supported on the document interface in embedded iframes'); + +promise_test(async (t) => { + const frame = await CreateFrame( + '../storage-access-api/resources/script-with-cookie-header.py?script=embedded_responder.js'); + + await RunCallbackWithGesture(() => + promise_rejects_dom(t, 'NotAllowedError', frame.contentWindow.DOMException, + frame.contentWindow.document.requestStorageAccessFor(document.location.origin), + 'document.requestStorageAccessFor() call in a non-top-level context')); +}, '[frame-on-insecure-page] document.requestStorageAccessFor() should be rejected when called in an iframe'); + +promise_test( + async t => { + await RunCallbackWithGesture( + () => promise_rejects_dom(t, 'NotAllowedError', document.requestStorageAccessFor(document.location.origin), 'document.requestStorageAccessFor() call in insecure context')); + }, + '[top-level-context] document.requestStorageAccessFor() should be rejected when called in an insecure context'); diff --git a/testing/web-platform/tests/top-level-storage-access-api/tentative/requestStorageAccessFor.sub.https.window.js b/testing/web-platform/tests/top-level-storage-access-api/tentative/requestStorageAccessFor.sub.https.window.js new file mode 100644 index 0000000000..e82cce699f --- /dev/null +++ b/testing/web-platform/tests/top-level-storage-access-api/tentative/requestStorageAccessFor.sub.https.window.js @@ -0,0 +1,198 @@ +// META: script=/storage-access-api/helpers.js +// META: script=/resources/testdriver.js +// META: script=/resources/testdriver-vendor.js +'use strict'; + +const requestedOrigin = 'https://foo.com'; +const altOrigin = 'https://{{hosts[alt][www]}}:{{ports[https][0]}}'; + +promise_test( + async () => { + assert_not_equals(document.requestStorageAccessFor, undefined); + }, + '[top-level-context] document.requestStorageAccessFor() should be supported on the document interface'); + +promise_test( + t => { + return promise_rejects_js(t, TypeError, + document.requestStorageAccessFor(), + 'document.requestStorageAccessFor() call without origin argument'); + }, + '[top-level-context] document.requestStorageAccessFor() should be rejected when called with no argument'); + +// Most tests need to start with the feature in "prompt" state. +// For tests that rely on the permission state, this function is intended to be +// run prior to executing test logic, rather than using clean-up functions for +// the permission. +async function CommonSetup() { + await test_driver.set_permission( + { name: 'top-level-storage-access', requestedOrigin }, 'prompt'); + await test_driver.set_permission( + { name: 'top-level-storage-access', requestedOrigin: altOrigin }, 'prompt'); +} + +promise_test(async t => { + await CommonSetup(); + return promise_rejects_dom(t, 'NotAllowedError', + document.requestStorageAccessFor(requestedOrigin), + 'document.requestStorageAccessFor() call without user gesture'); + }, + '[top-level-context] document.requestStorageAccessFor() should be rejected by default with no user gesture'); + +promise_test(async t => { + const description = + 'document.requestStorageAccessFor() call in a detached frame'; + // Can't use promise_rejects_dom here because the exception is from the wrong global. + return CreateDetachedFrame().requestStorageAccessFor(requestedOrigin) + .then(t.unreached_func('Should have rejected: ' + description)) + .catch((e) => { + assert_equals(e.name, 'InvalidStateError', description); + }); +}, '[non-fully-active] document.requestStorageAccessFor() should not resolve when run in a detached frame'); + +promise_test(async t => { + const description = + 'document.requestStorageAccessFor() in a detached DOMParser result'; + return CreateDocumentViaDOMParser().requestStorageAccessFor(requestedOrigin) + .then(t.unreached_func('Should have rejected: ' + description)) + .catch((e) => { + assert_equals(e.name, 'InvalidStateError', description); + }); +}, '[non-fully-active] document.requestStorageAccessFor() should not resolve when run in a detached DOMParser document'); + +promise_test( + async t => { + await CommonSetup(); + await test_driver.set_permission( + {name: 'top-level-storage-access', requestedOrigin}, 'granted'); + + await document.requestStorageAccessFor(requestedOrigin); + }, + '[top-level-context] document.requestStorageAccessFor() should be resolved without a user gesture with an existing permission'); + +promise_test( + async t => { + await CommonSetup(); + await test_driver.set_permission( + {name: 'top-level-storage-access', requestedOrigin: altOrigin}, + 'granted'); + + const frame = await CreateFrame( + '/storage-access-api/resources/script-with-cookie-header.py?script=embedded_responder.js'); + + await RunCallbackWithGesture(() => document.requestStorageAccessFor(altOrigin)); + assert_true(await RequestStorageAccessInFrame(frame)); + }, + '[top-level-context] document.requestStorageAccess() should be resolved without a user gesture after a successful requestStorageAccessFor() call'); + +promise_test( + async t => { + await RunCallbackWithGesture( + () => document.requestStorageAccessFor(document.location.origin)); + }, + '[top-level-context] document.requestStorageAccessFor() should be resolved when called properly with a user gesture and the same origin'); + +promise_test( + async t => { + await RunCallbackWithGesture( + () => promise_rejects_dom(t, 'NotAllowedError', document.requestStorageAccessFor('bogus-url'), + 'document.requestStorageAccessFor() call with bogus URL')); + }, + '[top-level-context] document.requestStorageAccessFor() should be rejected when called with an invalid origin'); + +promise_test( + async t => { + await RunCallbackWithGesture( + () => promise_rejects_dom(t, 'NotAllowedError', document.requestStorageAccessFor('data:,Hello%2C%20World%21'), + 'document.requestStorageAccessFor() call with data URL')); + }, + '[top-level-context] document.requestStorageAccessFor() should be rejected when called with an opaque origin'); + +promise_test( + async (t) => { + const altEchoCookieHeaderUrl = + `${altOrigin}/storage-access-api/resources/echo-cookie-header.py`; + + await MaybeSetStorageAccess('*', '*', 'blocked'); + await CommonSetup(); + + await test_driver.set_permission( + {name: 'top-level-storage-access', requestedOrigin: altOrigin}, + 'granted'); + + // Set cross-site cookie for altOrigin. Note that this only works with + // an existing top-level storage access permission. + await fetch( + `${altOrigin}/cookies/resources/set-cookie.py?name=cookie&path=/&samesite=None&secure=`, + {mode: 'cors', credentials: 'include'}); + + const httpCookies1 = await fetch(altEchoCookieHeaderUrl, { + mode: 'cors', + credentials: 'include' + }).then((resp) => resp.text()); + assert_true( + httpCookies1.includes('cookie=1'), + 'After obtaining top-level storage access, cross-site subresource requests with CORS mode should have cookie access.'); + + const httpCookies2 = await fetch(altEchoCookieHeaderUrl, { + mode: 'no-cors', + credentials: 'include' + }).then((resp) => resp.text()); + assert_false( + httpCookies2.includes('cookie=1'), + 'Cross-site subresource requests without CORS mode cannot access cookie even with an existing permission.'); + }, + '[top-level-context] Top-level storage access only allows cross-site subresource requests to access cookie when using CORS mode.'); + +promise_test( + async () => { + const frame = await CreateFrame( + '/storage-access-api/resources/script-with-cookie-header.py?script=embedded_responder.js'); + assert_not_equals(frame.contentWindow.document.requestStorageAccessFor, undefined); + }, + '[same-origin-iframe] document.requestStorageAccessFor() should be supported on the document interface'); + +promise_test( + async t => { + const frame = await CreateFrame( + '/storage-access-api/resources/script-with-cookie-header.py?script=embedded_responder.js'); + return promise_rejects_js(t, frame.contentWindow.TypeError, + frame.contentWindow.document.requestStorageAccessFor(), + 'document.requestStorageAccessFor() call without origin argument'); + }, + '[same-origin-iframe] document.requestStorageAccessFor() should be rejected when called with no argument'); + +promise_test( + async t => { + const frame = await CreateFrame( + '/storage-access-api/resources/script-with-cookie-header.py?script=embedded_responder.js'); + + await RunCallbackWithGesture(() => + promise_rejects_dom(t, 'NotAllowedError', frame.contentWindow.DOMException, + frame.contentWindow.document.requestStorageAccessFor(document.location.origin), + 'document.requestStorageAccessFor() call in a non-top-level context')); + }, + '[same-origin-iframe] document.requestStorageAccessFor() should be rejected when called in an iframe'); + +promise_test( + async (t) => { + await MaybeSetStorageAccess('*', '*', 'blocked'); + await CommonSetup(); + + const frame = await CreateFrame( + `/storage-access-api/resources/script-with-cookie-header.py?script=embedded_responder.js`); + + // Set cross-site cookie for altOrigin. Note that cookie won't be set + // even with an existing top-level storage access permission in an + // iframe. + await FetchFromFrame(frame, + `${altOrigin}/cookies/resources/set-cookie.py?name=cookie&path=/&samesite=None&secure=`); + + await test_driver.set_permission( + {name: 'top-level-storage-access', requestedOrigin: altOrigin}, + 'granted'); + + const httpCookies = await FetchSubresourceCookiesFromFrame(frame, altOrigin); + assert_false(httpCookies.includes('cookie=1')); + }, + '[same-origin-iframe] Existing top-level storage access permission should not allow cookie access for the cross-site subresource requests made in a non-top-level context.'); diff --git a/testing/web-platform/tests/top-level-storage-access-api/tentative/resources/permissions-iframe.https.html b/testing/web-platform/tests/top-level-storage-access-api/tentative/resources/permissions-iframe.https.html new file mode 100644 index 0000000000..c990720332 --- /dev/null +++ b/testing/web-platform/tests/top-level-storage-access-api/tentative/resources/permissions-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="/storage-access-api/helpers.js"></script> +<div id=log></div> +<script src="/top-level-storage-access-api/top-level-storage-access-permission.sub.https.window.js"></script> diff --git a/testing/web-platform/tests/top-level-storage-access-api/tentative/resources/requestStorageAccessFor-iframe.html b/testing/web-platform/tests/top-level-storage-access-api/tentative/resources/requestStorageAccessFor-iframe.html new file mode 100644 index 0000000000..050196dfdb --- /dev/null +++ b/testing/web-platform/tests/top-level-storage-access-api/tentative/resources/requestStorageAccessFor-iframe.html @@ -0,0 +1,9 @@ +<!doctype html> +<meta charset=utf-8> + +<script src="/storage-access-api/helpers.js"></script> +<script src="/resources/testharness.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<div id=log></div> +<script src="../requestStorageAccessFor-insecure.sub.window.js"></script> diff --git a/testing/web-platform/tests/top-level-storage-access-api/tentative/resources/requestStorageAccessFor-iframe.https.html b/testing/web-platform/tests/top-level-storage-access-api/tentative/resources/requestStorageAccessFor-iframe.https.html new file mode 100644 index 0000000000..14da63b033 --- /dev/null +++ b/testing/web-platform/tests/top-level-storage-access-api/tentative/resources/requestStorageAccessFor-iframe.https.html @@ -0,0 +1,9 @@ +<!doctype html> +<meta charset=utf-8> + +<script src="/storage-access-api/helpers.js"></script> +<script src="/resources/testharness.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<div id=log></div> +<script src="../requestStorageAccessFor.sub.https.window.js"></script> diff --git a/testing/web-platform/tests/top-level-storage-access-api/tentative/top-level-storage-access-permission.sub.https.window.js b/testing/web-platform/tests/top-level-storage-access-api/tentative/top-level-storage-access-permission.sub.https.window.js new file mode 100644 index 0000000000..466b6f3bbe --- /dev/null +++ b/testing/web-platform/tests/top-level-storage-access-api/tentative/top-level-storage-access-permission.sub.https.window.js @@ -0,0 +1,22 @@ +// META: script=/storage-access-api/helpers.js +// META: script=/resources/testdriver.js +// META: script=/resources/testdriver-vendor.js +'use strict'; + +(async function() { + promise_test(async t => { + return promise_rejects_js( + t, TypeError, + navigator.permissions.query({name: 'top-level-storage-access'}), + 'top-level-storage-access query without origin'); + }, 'Permission queries without an origin are rejected'); + + promise_test(async t => { + const permission = await navigator.permissions.query({ + name: 'top-level-storage-access', + requestedOrigin: 'https://test.com' + }); + assert_equals(permission.name, 'top-level-storage-access'); + assert_equals(permission.state, 'prompt'); + }, 'Permission default state can be queried'); +})(); |