summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/browsing-topics
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 01:47:29 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 01:47:29 +0000
commit0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d (patch)
treea31f07c9bcca9d56ce61e9a1ffd30ef350d513aa /testing/web-platform/tests/browsing-topics
parentInitial commit. (diff)
downloadfirefox-esr-0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d.tar.xz
firefox-esr-0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d.zip
Adding upstream version 115.8.0esr.upstream/115.8.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/browsing-topics')
-rw-r--r--testing/web-platform/tests/browsing-topics/browsing-topics-permissions-policy-default.tentative.https.sub.html55
-rw-r--r--testing/web-platform/tests/browsing-topics/browsing-topics-permissions-policy-none.tentative.https.sub.html59
-rw-r--r--testing/web-platform/tests/browsing-topics/browsing-topics-permissions-policy-none.tentative.https.sub.html.headers1
-rw-r--r--testing/web-platform/tests/browsing-topics/browsing-topics-permissions-policy-self.tentative.https.sub.html66
-rw-r--r--testing/web-platform/tests/browsing-topics/browsing-topics-permissions-policy-self.tentative.https.sub.html.headers1
-rw-r--r--testing/web-platform/tests/browsing-topics/document-api-insecure-context.tentative.http.html17
-rw-r--r--testing/web-platform/tests/browsing-topics/document-api.tentative.https.html15
-rw-r--r--testing/web-platform/tests/browsing-topics/fetch-topics-header-not-visible-in-service-worker.tentative.https.html36
-rw-r--r--testing/web-platform/tests/browsing-topics/fetch-topics-insecure-context.tentative.http.html17
-rw-r--r--testing/web-platform/tests/browsing-topics/fetch-topics.tentative.https.html16
-rw-r--r--testing/web-platform/tests/browsing-topics/fetch-without-topics-flag.tentative.https.html15
-rw-r--r--testing/web-platform/tests/browsing-topics/iframe-topics-attribute-insecure-context.tentative.http.sub.html36
-rw-r--r--testing/web-platform/tests/browsing-topics/iframe-topics-attribute.tentative.https.html19
-rw-r--r--testing/web-platform/tests/browsing-topics/resources/check-topics-request-header-notify-parent.py18
-rw-r--r--testing/web-platform/tests/browsing-topics/resources/check-topics-request-header.py4
-rw-r--r--testing/web-platform/tests/browsing-topics/resources/document-api-notify-parent.tentative.https.html11
-rw-r--r--testing/web-platform/tests/browsing-topics/resources/empty.html1
-rw-r--r--testing/web-platform/tests/browsing-topics/resources/fetch-topics-header-not-visible-in-service-worker-helper.tentative.https.html21
-rw-r--r--testing/web-platform/tests/browsing-topics/resources/fetch-topics.js14
-rw-r--r--testing/web-platform/tests/browsing-topics/resources/intercept-request.js12
-rw-r--r--testing/web-platform/tests/browsing-topics/resources/navigation-header-util.sub.js36
-rw-r--r--testing/web-platform/tests/browsing-topics/resources/permissions-policy-util.sub.js30
-rw-r--r--testing/web-platform/tests/browsing-topics/resources/topics-not-allowed-for-service-worker-fetch-helper.tentative.https.html19
-rw-r--r--testing/web-platform/tests/browsing-topics/topics-not-allowed-for-service-worker-fetch.tentative.https.html36
-rw-r--r--testing/web-platform/tests/browsing-topics/xhr-topics-insecure-context.tentative.http.html27
-rw-r--r--testing/web-platform/tests/browsing-topics/xhr-topics.tentative.https.html29
-rw-r--r--testing/web-platform/tests/browsing-topics/xhr-without-topics-attribute.tentative.https.html26
27 files changed, 637 insertions, 0 deletions
diff --git a/testing/web-platform/tests/browsing-topics/browsing-topics-permissions-policy-default.tentative.https.sub.html b/testing/web-platform/tests/browsing-topics/browsing-topics-permissions-policy-default.tentative.https.sub.html
new file mode 100644
index 0000000000..884ad9276a
--- /dev/null
+++ b/testing/web-platform/tests/browsing-topics/browsing-topics-permissions-policy-default.tentative.https.sub.html
@@ -0,0 +1,55 @@
+<!doctype html>
+<body>
+ <script src=/resources/testharness.js></script>
+ <script src=/resources/testharnessreport.js></script>
+ <script src=/browsing-topics/resources/navigation-header-util.sub.js></script>
+ <script src=/browsing-topics/resources/permissions-policy-util.sub.js></script>
+ <script>
+ 'use strict';
+ const header = 'Default permissions policy';
+
+ promise_test(async t => {
+ let topics = await document.browsingTopics();
+ assert_equals(topics.length, 0);
+ }, header + ' allows document.browsingTopics() in the current page.');
+
+ async_test(t => {
+ test_topics_feature_availability_in_subframe(t, /*is_same_origin=*/true,
+ expect_topics_feature_available);
+ }, header + ' allows document.browsingTopics() in same-origin iframes.');
+
+ async_test(t => {
+ test_topics_feature_availability_in_subframe(t, /*is_same_origin=*/false,
+ expect_topics_feature_available);
+ }, header + ' allows document.browsingTopics() in cross-origin iframes.');
+
+ const same_origin_url = '/browsing-topics/resources/check-topics-request-header.py';
+ const cross_origin_url = 'https://{{domains[www]}}:{{ports[https][0]}}' +
+ same_origin_url;
+
+ promise_test(async t => {
+ let response = await fetch(same_origin_url, {browsingTopics: true});
+ let topics_header = await response.text();
+ assert_equals(topics_header, "");
+ }, header + 'allows the \'Sec-Browsing-Topics\' header to be sent for the same-origin topics fetch request.');
+
+ promise_test(async t => {
+ let response = await fetch(cross_origin_url, {browsingTopics: true});
+ let topics_header = await response.text();
+ assert_equals(topics_header, "");
+ }, header + 'allows the \'Sec-Browsing-Topics\' header to be sent for the cross-origin topics fetch request.');
+
+ async_test(t => {
+ test_topics_iframe_navigation_header(
+ t, /*has_browsing_topics_attribute=*/true, /*is_same_origin=*/true,
+ expect_topics_header_available);
+ }, header + ' allows the \'Sec-Browsing-Topics\' header to be sent for the same-origin iframe navigation request.');
+
+ async_test(t => {
+ test_topics_iframe_navigation_header(
+ t, /*has_browsing_topics_attribute=*/true, /*is_same_origin=*/false,
+ expect_topics_header_available);
+ }, header + ' allows the \'Sec-Browsing-Topics\' header to be sent for the cross-origin iframe navigation request.');
+
+ </script>
+</body>
diff --git a/testing/web-platform/tests/browsing-topics/browsing-topics-permissions-policy-none.tentative.https.sub.html b/testing/web-platform/tests/browsing-topics/browsing-topics-permissions-policy-none.tentative.https.sub.html
new file mode 100644
index 0000000000..2f80daa271
--- /dev/null
+++ b/testing/web-platform/tests/browsing-topics/browsing-topics-permissions-policy-none.tentative.https.sub.html
@@ -0,0 +1,59 @@
+<!doctype html>
+<body>
+ <script src=/resources/testharness.js></script>
+ <script src=/resources/testharnessreport.js></script>
+ <script src=/browsing-topics/resources/navigation-header-util.sub.js></script>
+ <script src=/browsing-topics/resources/permissions-policy-util.sub.js></script>
+ <script>
+ 'use strict';
+ const header = 'permissions policy header browsing-topics=()';
+
+ promise_test(async t => {
+ try {
+ await document.browsingTopics();
+ } catch (e) {
+ assert_equals(e.message, TOPICS_PERMISSIONS_POLICY_ERROR_MESSAGE);
+ return;
+ }
+ assert_unreached("did not reject");
+ }, header + ' disallows document.browsingTopics() in the current page.');
+
+ async_test(t => {
+ test_topics_feature_availability_in_subframe(t, /*is_same_origin=*/true,
+ expect_topics_feature_unavailable);
+ }, header + ' disallows document.browsingTopics() in same-origin iframes.');
+
+ async_test(t => {
+ test_topics_feature_availability_in_subframe(t, /*is_same_origin=*/false,
+ expect_topics_feature_unavailable);
+ }, header + ' disallows document.browsingTopics() in cross-origin iframes.');
+
+ const same_origin_url = '/browsing-topics/resources/check-topics-request-header.py';
+ const cross_origin_url = 'https://{{domains[www]}}:{{ports[https][0]}}' +
+ same_origin_url;
+
+ promise_test(async t => {
+ let response = await fetch(same_origin_url, {browsingTopics: true});
+ let topics_header = await response.text();
+ assert_equals(topics_header, "NO_TOPICS_HEADER");
+ }, header + 'disallows the \'Sec-Browsing-Topics\' header to be sent for the same-origin topics fetch request.');
+
+ promise_test(async t => {
+ let response = await fetch(cross_origin_url, {browsingTopics: true});
+ let topics_header = await response.text();
+ assert_equals(topics_header, "NO_TOPICS_HEADER");
+ }, header + 'disallows the \'Sec-Browsing-Topics\' header to be sent for the cross-origin topics fetch request.');
+
+ async_test(t => {
+ test_topics_iframe_navigation_header(
+ t, /*has_browsing_topics_attribute=*/true, /*is_same_origin=*/true,
+ expect_topics_header_unavailable);
+ }, header + ' disallows the \'Sec-Browsing-Topics\' header to be sent for the same-origin iframe navigation request.');
+
+ async_test(t => {
+ test_topics_iframe_navigation_header(
+ t, /*has_browsing_topics_attribute=*/true, /*is_same_origin=*/false,
+ expect_topics_header_unavailable);
+ }, header + ' disallows the \'Sec-Browsing-Topics\' header to be sent for the cross-origin iframe navigation request.');
+ </script>
+</body>
diff --git a/testing/web-platform/tests/browsing-topics/browsing-topics-permissions-policy-none.tentative.https.sub.html.headers b/testing/web-platform/tests/browsing-topics/browsing-topics-permissions-policy-none.tentative.https.sub.html.headers
new file mode 100644
index 0000000000..9c93ff7384
--- /dev/null
+++ b/testing/web-platform/tests/browsing-topics/browsing-topics-permissions-policy-none.tentative.https.sub.html.headers
@@ -0,0 +1 @@
+Permissions-Policy: browsing-topics=()
diff --git a/testing/web-platform/tests/browsing-topics/browsing-topics-permissions-policy-self.tentative.https.sub.html b/testing/web-platform/tests/browsing-topics/browsing-topics-permissions-policy-self.tentative.https.sub.html
new file mode 100644
index 0000000000..6012667947
--- /dev/null
+++ b/testing/web-platform/tests/browsing-topics/browsing-topics-permissions-policy-self.tentative.https.sub.html
@@ -0,0 +1,66 @@
+<!doctype html>
+<body>
+ <script src=/resources/testharness.js></script>
+ <script src=/resources/testharnessreport.js></script>
+ <script src=/browsing-topics/resources/navigation-header-util.sub.js></script>
+ <script src=/browsing-topics/resources/permissions-policy-util.sub.js></script>
+ <script>
+ 'use strict';
+ const header = 'permissions policy header browsing-topics=(self)';
+
+ promise_test(async t => {
+ let topics = await document.browsingTopics();
+ assert_equals(topics.length, 0);
+ }, header + ' allows document.browsingTopics() in the current page.');
+
+ async_test(t => {
+ test_topics_feature_availability_in_subframe(t, /*is_same_origin=*/true,
+ expect_topics_feature_available);
+ }, header + ' allows document.browsingTopics() in same-origin iframes.');
+
+ async_test(t => {
+ test_topics_feature_availability_in_subframe(t, /*is_same_origin=*/false,
+ expect_topics_feature_unavailable);
+ }, header + ' disallows document.browsingTopics() in cross-origin iframes.');
+
+ const same_origin_url = '/browsing-topics/resources/check-topics-request-header.py';
+ const cross_origin_url = 'https://{{domains[www]}}:{{ports[https][0]}}' +
+ same_origin_url;
+
+ promise_test(async t => {
+ let response = await fetch(same_origin_url, {browsingTopics: true});
+ let topics_header = await response.text();
+ assert_equals(topics_header, "");
+ }, header + 'allows the \'Sec-Browsing-Topics\' header to be sent for the same-origin topics fetch request.');
+
+ promise_test(async t => {
+ let response = await fetch(cross_origin_url, {browsingTopics: true});
+ let topics_header = await response.text();
+ assert_equals(topics_header, "NO_TOPICS_HEADER");
+ }, header + 'disallows the \'Sec-Browsing-Topics\' header to be sent for the cross-origin topics fetch request.');
+
+ promise_test(async t => {
+ let response = await fetch('/common/redirect.py?location=' + same_origin_url, {browsingTopics: true});
+ let topics_header = await response.text();
+ assert_equals(topics_header, "");
+ }, header + 'allows the \'Sec-Browsing-Topics\' header to be sent for the redirect of a topics fetch request, where the redirect has a same-origin URL.');
+
+ promise_test(async t => {
+ let response = await fetch('/common/redirect.py?location=' + cross_origin_url, {browsingTopics: true});
+ let topics_header = await response.text();
+ assert_equals(topics_header, "NO_TOPICS_HEADER");
+ }, header + 'disallows the \'Sec-Browsing-Topics\' header to be sent for the redirect of a topics fetch request, where the redirect has a cross-origin URL.');
+
+ async_test(t => {
+ test_topics_iframe_navigation_header(
+ t, /*has_browsing_topics_attribute=*/true, /*is_same_origin=*/true,
+ expect_topics_header_available);
+ }, header + ' allows the \'Sec-Browsing-Topics\' header to be sent for the same-origin iframe navigation request.');
+
+ async_test(t => {
+ test_topics_iframe_navigation_header(
+ t, /*has_browsing_topics_attribute=*/true, /*is_same_origin=*/false,
+ expect_topics_header_unavailable);
+ }, header + ' disallows the \'Sec-Browsing-Topics\' header to be sent for the cross-origin iframe navigation request.');
+ </script>
+</body>
diff --git a/testing/web-platform/tests/browsing-topics/browsing-topics-permissions-policy-self.tentative.https.sub.html.headers b/testing/web-platform/tests/browsing-topics/browsing-topics-permissions-policy-self.tentative.https.sub.html.headers
new file mode 100644
index 0000000000..6eb902eb68
--- /dev/null
+++ b/testing/web-platform/tests/browsing-topics/browsing-topics-permissions-policy-self.tentative.https.sub.html.headers
@@ -0,0 +1 @@
+Permissions-Policy: browsing-topics=(self)
diff --git a/testing/web-platform/tests/browsing-topics/document-api-insecure-context.tentative.http.html b/testing/web-platform/tests/browsing-topics/document-api-insecure-context.tentative.http.html
new file mode 100644
index 0000000000..b2f0abf8e0
--- /dev/null
+++ b/testing/web-platform/tests/browsing-topics/document-api-insecure-context.tentative.http.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<body>
+ <script src=/resources/testharness.js></script>
+ <script src=/resources/testharnessreport.js></script>
+ <script>
+ promise_test(async t => {
+ try {
+ await document.browsingTopics();
+ } catch (e) {
+ assert_equals(e.name, 'TypeError');
+ assert_equals(e.message, 'document.browsingTopics is not a function');
+ return;
+ }
+ assert_unreached("did not reject");
+ }, 'test document.browsingTopics() in insecure context');
+ </script>
+</body>
diff --git a/testing/web-platform/tests/browsing-topics/document-api.tentative.https.html b/testing/web-platform/tests/browsing-topics/document-api.tentative.https.html
new file mode 100644
index 0000000000..d1d515ccba
--- /dev/null
+++ b/testing/web-platform/tests/browsing-topics/document-api.tentative.https.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<body>
+ <script src=/resources/testharness.js></script>
+ <script src=/resources/testharnessreport.js></script>
+ <script>
+ promise_test(async t => {
+ let topics = await document.browsingTopics();
+
+ // An empty result indicates that the request was eligible for topics.
+ // Currently, the web-platform-tests framework does not support actually
+ // handling the topics request.
+ assert_equals(topics.length, 0);
+ }, 'test document.browsingTopics()');
+ </script>
+</body>
diff --git a/testing/web-platform/tests/browsing-topics/fetch-topics-header-not-visible-in-service-worker.tentative.https.html b/testing/web-platform/tests/browsing-topics/fetch-topics-header-not-visible-in-service-worker.tentative.https.html
new file mode 100644
index 0000000000..76f7b90957
--- /dev/null
+++ b/testing/web-platform/tests/browsing-topics/fetch-topics-header-not-visible-in-service-worker.tentative.https.html
@@ -0,0 +1,36 @@
+<!doctype html>
+<body>
+ <script src=/resources/testharness.js></script>
+ <script src=/resources/testharnessreport.js></script>
+ <script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
+ <script>
+ promise_test(async t => {
+ let url = 'resources/fetch-topics-header-not-visible-in-service-worker-helper.tentative.https.html';
+
+ let r = await service_worker_unregister_and_register(t,
+ 'resources/intercept-request.js', url);
+ await wait_for_state(t, r.installing, 'activated');
+
+ var popup_window = window.open("/common/blank.html");
+
+ t.add_cleanup(async _=>{
+ popup_window.close();
+ await r.unregister();
+ });
+
+ // The current page isn't yet controlled by the service worker. Thus,
+ // execute the actual test in a new page and let it post its result back
+ // to this page.
+ test_helper_popup_page_result = new Promise((resolve, reject) => {
+ window.addEventListener('message', t.step_func((e) => {
+ assert_equals(e.data.testResult,
+ 'Service worker intercepted no topics header');
+ resolve();
+ }));
+ });
+
+ popup_window.location = url;
+ await test_helper_popup_page_result;
+ }, 'test that the topics header for fetch(<url>, {browsingTopics: true}) is not visible in a service worker context');
+ </script>
+</body>
diff --git a/testing/web-platform/tests/browsing-topics/fetch-topics-insecure-context.tentative.http.html b/testing/web-platform/tests/browsing-topics/fetch-topics-insecure-context.tentative.http.html
new file mode 100644
index 0000000000..d4cdd9ae95
--- /dev/null
+++ b/testing/web-platform/tests/browsing-topics/fetch-topics-insecure-context.tentative.http.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<body>
+ <script src=/resources/testharness.js></script>
+ <script src=/resources/testharnessreport.js></script>
+ <script>
+ promise_test(async t => {
+ try {
+ let response = await fetch('./resources/check-topics-request-header.py', {browsingTopics: true});
+ } catch (e) {
+ assert_equals(e.name, 'TypeError');
+ assert_equals(e.message, 'Failed to execute \'fetch\' on \'Window\': browsingTopics: Topics operations are only available in secure contexts.');
+ return;
+ }
+ assert_unreached("did not reject");
+ }, 'test fetch(<url>, {browsingTopics: true}) in insecure context');
+ </script>
+</body>
diff --git a/testing/web-platform/tests/browsing-topics/fetch-topics.tentative.https.html b/testing/web-platform/tests/browsing-topics/fetch-topics.tentative.https.html
new file mode 100644
index 0000000000..e5dd1d9b98
--- /dev/null
+++ b/testing/web-platform/tests/browsing-topics/fetch-topics.tentative.https.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<body>
+ <script src=/resources/testharness.js></script>
+ <script src=/resources/testharnessreport.js></script>
+ <script>
+ promise_test(async t => {
+ let response = await fetch('./resources/check-topics-request-header.py', {browsingTopics: true});
+ let topics_header = await response.text();
+
+ // An empty result indicates that the request was eligible for topics.
+ // Currently, the web-platform-tests framework does not support actually
+ // handling the topics request.
+ assert_equals(topics_header, "");
+ }, 'test fetch(<url>, {browsingTopics: true})');
+ </script>
+</body>
diff --git a/testing/web-platform/tests/browsing-topics/fetch-without-topics-flag.tentative.https.html b/testing/web-platform/tests/browsing-topics/fetch-without-topics-flag.tentative.https.html
new file mode 100644
index 0000000000..f942915a7f
--- /dev/null
+++ b/testing/web-platform/tests/browsing-topics/fetch-without-topics-flag.tentative.https.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<body>
+ <script src=/resources/testharness.js></script>
+ <script src=/resources/testharnessreport.js></script>
+ <script>
+ promise_test(async t => {
+ let response = await fetch('./resources/check-topics-request-header.py');
+ let topics_header = await response.text();
+
+ // The request was not eligible for topics, as the `browsingTopics` flag
+ // was not set.
+ assert_equals(topics_header, "NO_TOPICS_HEADER");
+ }, 'test fetch(<url>)');
+ </script>
+</body>
diff --git a/testing/web-platform/tests/browsing-topics/iframe-topics-attribute-insecure-context.tentative.http.sub.html b/testing/web-platform/tests/browsing-topics/iframe-topics-attribute-insecure-context.tentative.http.sub.html
new file mode 100644
index 0000000000..19c79e0d7f
--- /dev/null
+++ b/testing/web-platform/tests/browsing-topics/iframe-topics-attribute-insecure-context.tentative.http.sub.html
@@ -0,0 +1,36 @@
+<!doctype html>
+<body>
+ <script src=/resources/testharness.js></script>
+ <script src=/resources/testharnessreport.js></script>
+ <script src=/browsing-topics/resources/navigation-header-util.sub.js></script>
+ <script>
+ async_test(t => {
+ test_topics_iframe_navigation_header(
+ t, /*has_browsing_topics_attribute=*/true, /*is_same_origin=*/false,
+ expect_topics_header_unavailable);
+ }, 'test <iframe browsingtopics src=[url]></iframe> in an insecure context, where the browsingtopics attribute is set via IDL.');
+
+ async_test(t => {
+ const same_origin_src = '/browsing-topics/resources/check-topics-request-header-notify-parent.py';
+ const cross_origin_src = 'https://{{domains[www]}}:{{ports[https][0]}}' +
+ same_origin_src;
+
+ let frame = document.createElement('iframe');
+
+ window.addEventListener('message', t.step_func(function handler(evt) {
+ if (evt.source === frame.contentWindow) {
+ assert_equals(evt.data.topicsHeader, 'NO_TOPICS_HEADER');
+
+ document.body.removeChild(frame);
+ window.removeEventListener('message', handler);
+ t.done();
+ }
+ }));
+
+ document.body.appendChild(frame);
+
+ frame.setAttribute("browsingtopics", "123");
+ frame.src = cross_origin_src;
+ }, 'test <iframe browsingtopics src=[url]></iframe> in an insecure context, where the browsingtopics attribute is set via setAttribute().');
+ </script>
+</body>
diff --git a/testing/web-platform/tests/browsing-topics/iframe-topics-attribute.tentative.https.html b/testing/web-platform/tests/browsing-topics/iframe-topics-attribute.tentative.https.html
new file mode 100644
index 0000000000..b90f967146
--- /dev/null
+++ b/testing/web-platform/tests/browsing-topics/iframe-topics-attribute.tentative.https.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<body>
+ <script src=/resources/testharness.js></script>
+ <script src=/resources/testharnessreport.js></script>
+ <script src=/browsing-topics/resources/navigation-header-util.sub.js></script>
+ <script>
+ async_test(t => {
+ test_topics_iframe_navigation_header(
+ t, /*has_browsing_topics_attribute=*/false, /*is_same_origin=*/false,
+ expect_topics_header_unavailable);
+ }, 'test <iframe src=[url]></iframe>');
+
+ async_test(t => {
+ test_topics_iframe_navigation_header(
+ t, /*has_browsing_topics_attribute=*/true, /*is_same_origin=*/false,
+ expect_topics_header_available);
+ }, 'test <iframe browsingtopics src=[url]></iframe>');
+ </script>
+</body>
diff --git a/testing/web-platform/tests/browsing-topics/resources/check-topics-request-header-notify-parent.py b/testing/web-platform/tests/browsing-topics/resources/check-topics-request-header-notify-parent.py
new file mode 100644
index 0000000000..98c77c2b0b
--- /dev/null
+++ b/testing/web-platform/tests/browsing-topics/resources/check-topics-request-header-notify-parent.py
@@ -0,0 +1,18 @@
+def main(request, response):
+ """
+ Returns an HTML response that notifies its parent frame the topics header
+ via postMessage
+ """
+
+ topics_header = request.headers.get(b"sec-browsing-topics", b"NO_TOPICS_HEADER")
+
+ headers = [(b"Content-Type", b"text/html"),
+ (b"Access-Control-Allow-Origin", b"*")]
+ content = b'''
+<script>
+ let parentOrOpener = window.opener || window.parent;
+ parentOrOpener.postMessage({ topicsHeader: '%s'}, "*");
+</script>
+''' % (topics_header)
+
+ return 200, headers, content
diff --git a/testing/web-platform/tests/browsing-topics/resources/check-topics-request-header.py b/testing/web-platform/tests/browsing-topics/resources/check-topics-request-header.py
new file mode 100644
index 0000000000..569b754496
--- /dev/null
+++ b/testing/web-platform/tests/browsing-topics/resources/check-topics-request-header.py
@@ -0,0 +1,4 @@
+def main(request, response):
+ topics_header = request.headers.get(b"sec-browsing-topics", b"NO_TOPICS_HEADER")
+ response.headers.append(b"Access-Control-Allow-Origin", b"*")
+ response.content = topics_header
diff --git a/testing/web-platform/tests/browsing-topics/resources/document-api-notify-parent.tentative.https.html b/testing/web-platform/tests/browsing-topics/resources/document-api-notify-parent.tentative.https.html
new file mode 100644
index 0000000000..2fd55ebeb2
--- /dev/null
+++ b/testing/web-platform/tests/browsing-topics/resources/document-api-notify-parent.tentative.https.html
@@ -0,0 +1,11 @@
+<!doctype html>
+<body>
+ <script>
+ document.browsingTopics().then((topics) => {
+ window.parent.postMessage({error: 'No error'}, '*');
+ })
+ .catch((err) => {
+ window.parent.postMessage({error: err.message}, '*');
+ });
+ </script>
+</body>
diff --git a/testing/web-platform/tests/browsing-topics/resources/empty.html b/testing/web-platform/tests/browsing-topics/resources/empty.html
new file mode 100644
index 0000000000..c50eddd41f
--- /dev/null
+++ b/testing/web-platform/tests/browsing-topics/resources/empty.html
@@ -0,0 +1 @@
+<!doctype html>
diff --git a/testing/web-platform/tests/browsing-topics/resources/fetch-topics-header-not-visible-in-service-worker-helper.tentative.https.html b/testing/web-platform/tests/browsing-topics/resources/fetch-topics-header-not-visible-in-service-worker-helper.tentative.https.html
new file mode 100644
index 0000000000..e9cb8144e0
--- /dev/null
+++ b/testing/web-platform/tests/browsing-topics/resources/fetch-topics-header-not-visible-in-service-worker-helper.tentative.https.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<body>
+ <script>
+ var current_url = window.location.href;
+ var fetch_url = current_url.substring(0, current_url.lastIndexOf("/")) + '/empty.html'
+
+ navigator.serviceWorker.addEventListener('message', e => {
+ if (e.data.fetchUrl == fetch_url) {
+ if (e.data.topicsHeader === 'null') {
+ window.opener.postMessage(
+ {testResult: 'Service worker intercepted no topics header'}, '*');
+ } else {
+ window.opener.postMessage(
+ {testResult: 'Service worker intercepted topics header'}, '*');
+ }
+ }
+ });
+
+ fetch(fetch_url, {browsingTopics: true});
+ </script>
+</body>
diff --git a/testing/web-platform/tests/browsing-topics/resources/fetch-topics.js b/testing/web-platform/tests/browsing-topics/resources/fetch-topics.js
new file mode 100644
index 0000000000..71064a90c5
--- /dev/null
+++ b/testing/web-platform/tests/browsing-topics/resources/fetch-topics.js
@@ -0,0 +1,14 @@
+self.addEventListener('message', event => {
+ if (event.data.fetchUrl) {
+ clients.matchAll().then((clients) => {
+ fetch(event.data.fetchUrl, {browsingTopics: true}).then((response) => {
+ response.text().then((topics_header) => {
+ // clients[0] is the most recently focused one
+ clients[0].postMessage({
+ topicsHeader: topics_header
+ });
+ });
+ });
+ });
+ }
+});
diff --git a/testing/web-platform/tests/browsing-topics/resources/intercept-request.js b/testing/web-platform/tests/browsing-topics/resources/intercept-request.js
new file mode 100644
index 0000000000..c19efb5f2f
--- /dev/null
+++ b/testing/web-platform/tests/browsing-topics/resources/intercept-request.js
@@ -0,0 +1,12 @@
+self.addEventListener('fetch', event => {
+ event.waitUntil(async function () {
+ if (!event.clientId) return;
+ const client = await clients.get(event.clientId);
+ if (!client) return;
+
+ client.postMessage({
+ fetchUrl: event.request.url,
+ topicsHeader: String(event.request.headers.get("Sec-Browsing-Topics"))
+ });
+ }());
+});
diff --git a/testing/web-platform/tests/browsing-topics/resources/navigation-header-util.sub.js b/testing/web-platform/tests/browsing-topics/resources/navigation-header-util.sub.js
new file mode 100644
index 0000000000..b3bec79651
--- /dev/null
+++ b/testing/web-platform/tests/browsing-topics/resources/navigation-header-util.sub.js
@@ -0,0 +1,36 @@
+function test_topics_iframe_navigation_header(
+ test, has_browsing_topics_attribute, is_same_origin, expect_topics_header_available_func) {
+ const same_origin_src = '/browsing-topics/resources/check-topics-request-header-notify-parent.py';
+ const cross_origin_src = 'https://{{domains[www]}}:{{ports[https][0]}}' +
+ same_origin_src;
+
+ let frame = document.createElement('iframe');
+ frame.src = is_same_origin ? same_origin_src : cross_origin_src;
+
+ if (has_browsing_topics_attribute) {
+ frame.browsingTopics = true;
+ }
+
+ window.addEventListener('message', test.step_func(function handler(evt) {
+ if (evt.source === frame.contentWindow) {
+ expect_topics_header_available_func(evt.data);
+
+ document.body.removeChild(frame);
+ window.removeEventListener('message', handler);
+ test.done();
+ }
+ }));
+
+ document.body.appendChild(frame);
+}
+
+function expect_topics_header_unavailable(data) {
+ assert_equals(data.topicsHeader, 'NO_TOPICS_HEADER');
+}
+
+function expect_topics_header_available(data) {
+ // An empty result indicates that the request was eligible for topics.
+ // Currently, the web-platform-tests framework does not support actually
+ // handling the topics request.
+ assert_equals(data.topicsHeader, '');
+} \ No newline at end of file
diff --git a/testing/web-platform/tests/browsing-topics/resources/permissions-policy-util.sub.js b/testing/web-platform/tests/browsing-topics/resources/permissions-policy-util.sub.js
new file mode 100644
index 0000000000..e8bf45049c
--- /dev/null
+++ b/testing/web-platform/tests/browsing-topics/resources/permissions-policy-util.sub.js
@@ -0,0 +1,30 @@
+const TOPICS_PERMISSIONS_POLICY_ERROR_MESSAGE = 'The \"browsing-topics\" Permissions Policy denied the use of document.browsingTopics().';
+
+function test_topics_feature_availability_in_subframe(test, is_same_origin, expect_feature_available_func) {
+ const same_origin_src = '/browsing-topics/resources/document-api-notify-parent.tentative.https.html';
+ const cross_origin_src = 'https://{{domains[www]}}:{{ports[https][0]}}' +
+ same_origin_src;
+
+ let frame = document.createElement('iframe');
+ frame.src = is_same_origin ? same_origin_src : cross_origin_src;
+
+ window.addEventListener('message', test.step_func(function handler(evt) {
+ if (evt.source === frame.contentWindow) {
+ expect_feature_available_func(evt.data);
+
+ document.body.removeChild(frame);
+ window.removeEventListener('message', handler);
+ test.done();
+ }
+ }));
+
+ document.body.appendChild(frame);
+}
+
+function expect_topics_feature_unavailable(data) {
+ assert_equals(data.error, TOPICS_PERMISSIONS_POLICY_ERROR_MESSAGE);
+}
+
+function expect_topics_feature_available(data) {
+ assert_equals(data.error, 'No error');
+}
diff --git a/testing/web-platform/tests/browsing-topics/resources/topics-not-allowed-for-service-worker-fetch-helper.tentative.https.html b/testing/web-platform/tests/browsing-topics/resources/topics-not-allowed-for-service-worker-fetch-helper.tentative.https.html
new file mode 100644
index 0000000000..2278d5bc76
--- /dev/null
+++ b/testing/web-platform/tests/browsing-topics/resources/topics-not-allowed-for-service-worker-fetch-helper.tentative.https.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<body>
+ <script>
+ var current_url = window.location.href;
+ var fetch_url = current_url.substring(0, current_url.lastIndexOf("/")) + '/check-topics-request-header.py'
+
+ navigator.serviceWorker.addEventListener('message', e => {
+ if (e.data.topicsHeader === 'NO_TOPICS_HEADER') {
+ window.opener.postMessage({testResult: 'Topics fetch initiated from service worker did not include the topics header'}, '*');
+ } else {
+ window.opener.postMessage({testResult: 'Topics fetch initiated from service worker included the topics header'}, '*');
+ }
+ });
+
+ navigator.serviceWorker.controller.postMessage({
+ fetchUrl: fetch_url
+ });
+ </script>
+</body>
diff --git a/testing/web-platform/tests/browsing-topics/topics-not-allowed-for-service-worker-fetch.tentative.https.html b/testing/web-platform/tests/browsing-topics/topics-not-allowed-for-service-worker-fetch.tentative.https.html
new file mode 100644
index 0000000000..1bd578e9bf
--- /dev/null
+++ b/testing/web-platform/tests/browsing-topics/topics-not-allowed-for-service-worker-fetch.tentative.https.html
@@ -0,0 +1,36 @@
+<!doctype html>
+<body>
+ <script src=/resources/testharness.js></script>
+ <script src=/resources/testharnessreport.js></script>
+ <script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
+ <script>
+ promise_test(async t => {
+ let url = 'resources/topics-not-allowed-for-service-worker-fetch-helper.tentative.https.html';
+
+ let r = await service_worker_unregister_and_register(t,
+ 'resources/fetch-topics.js', url);
+ await wait_for_state(t, r.installing, 'activated');
+
+ var popup_window = window.open("/common/blank.html");
+
+ t.add_cleanup(async _=>{
+ popup_window.close();
+ await r.unregister();
+ });
+
+ // The current page isn't yet controlled by the service worker. Thus,
+ // execute the actual test in a new page and let it post its result back
+ // to this page.
+ test_helper_popup_page_result = new Promise((resolve, reject) => {
+ window.addEventListener('message', t.step_func((e) => {
+ assert_equals(e.data.testResult,
+ 'Topics fetch initiated from service worker did not include the topics header');
+ resolve();
+ }));
+ });
+
+ popup_window.location = url;
+ await test_helper_popup_page_result;
+ }, 'test that fetch(<url>, {browsingTopics: true}) from a service worker context will not include the topics header');
+ </script>
+</body>
diff --git a/testing/web-platform/tests/browsing-topics/xhr-topics-insecure-context.tentative.http.html b/testing/web-platform/tests/browsing-topics/xhr-topics-insecure-context.tentative.http.html
new file mode 100644
index 0000000000..5e32b83f9e
--- /dev/null
+++ b/testing/web-platform/tests/browsing-topics/xhr-topics-insecure-context.tentative.http.html
@@ -0,0 +1,27 @@
+<!doctype html>
+<body>
+ <script src=/resources/testharness.js></script>
+ <script src=/resources/testharnessreport.js></script>
+ <script>
+ promise_test(async t => {
+ const xhr = new XMLHttpRequest();
+
+ let xhr_response = new Promise((resolve, reject) => {
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState == XMLHttpRequest.DONE) {
+ // The request was not eligible for topics, as the context is not
+ // secure.
+ assert_equals(xhr.responseText, "NO_TOPICS_HEADER");
+ resolve();
+ }
+ }
+ });
+
+ xhr.open('GET', './resources/check-topics-request-header.py');
+ xhr.deprecatedBrowsingTopics = true;
+ xhr.send();
+
+ await xhr_response;
+ }, 'test XHR in insecure context that sets the deprecatedBrowsingTopics attribtue');
+ </script>
+</body>
diff --git a/testing/web-platform/tests/browsing-topics/xhr-topics.tentative.https.html b/testing/web-platform/tests/browsing-topics/xhr-topics.tentative.https.html
new file mode 100644
index 0000000000..532a040424
--- /dev/null
+++ b/testing/web-platform/tests/browsing-topics/xhr-topics.tentative.https.html
@@ -0,0 +1,29 @@
+<!doctype html>
+<body>
+ <script src=/resources/testharness.js></script>
+ <script src=/resources/testharnessreport.js></script>
+ <script>
+ promise_test(async t => {
+ const xhr = new XMLHttpRequest();
+
+ let xhr_response = new Promise((resolve, reject) => {
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState == XMLHttpRequest.DONE) {
+ // An empty result indicates that the request was eligible for
+ // topics. Currently, the web-platform-tests framework does not
+ // support actually handling the topics request.
+ assert_equals(xhr.responseText, "");
+ resolve();
+ }
+ }
+ });
+
+
+ xhr.open('GET', './resources/check-topics-request-header.py');
+ xhr.deprecatedBrowsingTopics = true;
+ xhr.send();
+
+ await xhr_response;
+ }, 'test XHR that sets the deprecatedBrowsingTopics attribtue');
+ </script>
+</body>
diff --git a/testing/web-platform/tests/browsing-topics/xhr-without-topics-attribute.tentative.https.html b/testing/web-platform/tests/browsing-topics/xhr-without-topics-attribute.tentative.https.html
new file mode 100644
index 0000000000..47bc1049e4
--- /dev/null
+++ b/testing/web-platform/tests/browsing-topics/xhr-without-topics-attribute.tentative.https.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<body>
+ <script src=/resources/testharness.js></script>
+ <script src=/resources/testharnessreport.js></script>
+ <script>
+ promise_test(async t => {
+ const xhr = new XMLHttpRequest();
+
+ let xhr_response = new Promise((resolve, reject) => {
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState == XMLHttpRequest.DONE) {
+ // The request was not eligible for topics, as the
+ // `deprecatedBrowsingTopics` attribtue was not set.
+ assert_equals(xhr.responseText, "NO_TOPICS_HEADER");
+ resolve();
+ }
+ }
+ });
+
+ xhr.open('GET', './resources/check-topics-request-header.py');
+ xhr.send();
+
+ await xhr_response;
+ }, 'test XHR that does not set the deprecatedBrowsingTopics attribtue');
+ </script>
+</body>