summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/fetch/metadata/generated
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/fetch/metadata/generated')
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/appcache-manifest.https.sub.html341
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/audioworklet.https.sub.html271
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/css-font-face.https.sub.tentative.html230
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/css-font-face.sub.tentative.html196
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/css-images.https.sub.tentative.html1384
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/css-images.sub.tentative.html1099
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/element-a.https.sub.html482
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/element-a.sub.html342
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/element-area.https.sub.html482
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/element-area.sub.html342
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/element-audio.https.sub.html325
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/element-audio.sub.html229
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/element-embed.https.sub.html224
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/element-embed.sub.html190
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/element-frame.https.sub.html309
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/element-frame.sub.html250
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/element-iframe.https.sub.html309
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/element-iframe.sub.html250
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/element-img-environment-change.https.sub.html357
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/element-img-environment-change.sub.html270
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/element-img.https.sub.html645
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/element-img.sub.html456
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/element-input-image.https.sub.html229
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/element-input-image.sub.html184
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/element-link-icon.https.sub.html371
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/element-link-icon.sub.html279
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/element-link-prefetch.https.optional.sub.html559
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/element-link-prefetch.optional.sub.html275
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/element-meta-refresh.https.optional.sub.html276
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/element-meta-refresh.optional.sub.html225
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/element-picture.https.sub.html997
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/element-picture.sub.html721
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/element-script.https.sub.html593
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/element-script.sub.html488
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/element-video-poster.https.sub.html243
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/element-video-poster.sub.html198
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/element-video.https.sub.html325
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/element-video.sub.html229
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/fetch-via-serviceworker.https.sub.html683
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/fetch.https.sub.html302
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/fetch.sub.html220
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/form-submission.https.sub.html522
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/form-submission.sub.html400
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/header-link.https.sub.html529
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/header-link.https.sub.tentative.html51
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/header-link.sub.html460
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/header-refresh.https.optional.sub.html273
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/header-refresh.optional.sub.html222
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/script-module-import-dynamic.https.sub.html254
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/script-module-import-dynamic.sub.html214
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/script-module-import-static.https.sub.html288
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/script-module-import-static.sub.html246
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/serviceworker.https.sub.html170
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/svg-image.https.sub.html367
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/svg-image.sub.html265
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/window-history.https.sub.html237
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/window-history.sub.html360
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/window-location.https.sub.html1184
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/window-location.sub.html894
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/worker-dedicated-constructor.https.sub.html118
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/worker-dedicated-constructor.sub.html204
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/worker-dedicated-importscripts.https.sub.html268
-rw-r--r--testing/web-platform/tests/fetch/metadata/generated/worker-dedicated-importscripts.sub.html228
63 files changed, 24134 insertions, 0 deletions
diff --git a/testing/web-platform/tests/fetch/metadata/generated/appcache-manifest.https.sub.html b/testing/web-platform/tests/fetch/metadata/generated/appcache-manifest.https.sub.html
new file mode 100644
index 0000000000..cf322fd34b
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/appcache-manifest.https.sub.html
@@ -0,0 +1,341 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/appcache-manifest.sub.https.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <title>HTTP headers on request for Appcache manifest</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ function induceRequest(url) {
+ const iframe = document.createElement('iframe');
+ iframe.src =
+ '/fetch/metadata/resources/appcache-iframe.sub.html?manifest=' + encodeURIComponent(url);
+
+ return new Promise((resolve) => {
+ addEventListener('message', function onMessage(event) {
+ if (event.source !== iframe.contentWindow) {
+ return;
+ }
+ removeEventListener('message', onMessage);
+ resolve(event.data);
+ });
+
+ document.body.appendChild(iframe);
+ })
+ .then((message) => {
+ if (message !== 'okay') {
+ throw message;
+ }
+ })
+ .then(() => iframe.remove());
+ }
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ assert_implements_optional(
+ !!window.applicationCache, 'Application Cache supported.'
+ );
+
+ induceRequest(makeRequestURL(key, ['httpsOrigin']))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ })
+ .then(() => t.done(), t.step_func((error) => { throw error; }));
+ }, 'sec-fetch-site - Same origin');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ assert_implements_optional(
+ !!window.applicationCache, 'Application Cache supported.'
+ );
+
+ induceRequest(makeRequestURL(key, ['httpsCrossSite']))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ })
+ .then(() => t.done(), t.step_func((error) => { throw error; }));
+ }, 'sec-fetch-site - Cross-site');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ assert_implements_optional(
+ !!window.applicationCache, 'Application Cache supported.'
+ );
+
+ induceRequest(makeRequestURL(key, ['httpsSameSite']))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ })
+ .then(() => t.done(), t.step_func((error) => { throw error; }));
+ }, 'sec-fetch-site - Same site');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ assert_implements_optional(
+ !!window.applicationCache, 'Application Cache supported.'
+ );
+
+ induceRequest(makeRequestURL(key, ['httpsOrigin', 'httpOrigin']))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ })
+ .then(() => t.done(), t.step_func((error) => { throw error; }));
+ }, 'sec-fetch-site - HTTPS downgrade (header not sent)');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ assert_implements_optional(
+ !!window.applicationCache, 'Application Cache supported.'
+ );
+
+ induceRequest(makeRequestURL(key, ['httpOrigin', 'httpsOrigin']))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ })
+ .then(() => t.done(), t.step_func((error) => { throw error; }));
+ }, 'sec-fetch-site - HTTPS upgrade');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ assert_implements_optional(
+ !!window.applicationCache, 'Application Cache supported.'
+ );
+
+ induceRequest(makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin']))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ })
+ .then(() => t.done(), t.step_func((error) => { throw error; }));
+ }, 'sec-fetch-site - HTTPS downgrade-upgrade');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ assert_implements_optional(
+ !!window.applicationCache, 'Application Cache supported.'
+ );
+
+ induceRequest(makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite', 'httpsOrigin']))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ })
+ .then(() => t.done(), t.step_func((error) => { throw error; }));
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ assert_implements_optional(
+ !!window.applicationCache, 'Application Cache supported.'
+ );
+
+ induceRequest(makeRequestURL(key, ['httpsOrigin', 'httpsSameSite', 'httpsOrigin']))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ })
+ .then(() => t.done(), t.step_func((error) => { throw error; }));
+ }, 'sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ assert_implements_optional(
+ !!window.applicationCache, 'Application Cache supported.'
+ );
+
+ induceRequest(makeRequestURL(key, ['httpsCrossSite', 'httpsOrigin']))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ })
+ .then(() => t.done(), t.step_func((error) => { throw error; }));
+ }, 'sec-fetch-site - Cross-Site -> Same Origin');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ assert_implements_optional(
+ !!window.applicationCache, 'Application Cache supported.'
+ );
+
+ induceRequest(makeRequestURL(key, ['httpsCrossSite', 'httpsSameSite']))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ })
+ .then(() => t.done(), t.step_func((error) => { throw error; }));
+ }, 'sec-fetch-site - Cross-Site -> Same-Site');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ assert_implements_optional(
+ !!window.applicationCache, 'Application Cache supported.'
+ );
+
+ induceRequest(makeRequestURL(key, ['httpsCrossSite', 'httpsCrossSite']))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ })
+ .then(() => t.done(), t.step_func((error) => { throw error; }));
+ }, 'sec-fetch-site - Cross-Site -> Cross-Site');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ assert_implements_optional(
+ !!window.applicationCache, 'Application Cache supported.'
+ );
+
+ induceRequest(makeRequestURL(key, ['httpsOrigin', 'httpsOrigin']))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ })
+ .then(() => t.done(), t.step_func((error) => { throw error; }));
+ }, 'sec-fetch-site - Same-Origin -> Same Origin');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ assert_implements_optional(
+ !!window.applicationCache, 'Application Cache supported.'
+ );
+
+ induceRequest(makeRequestURL(key, ['httpsOrigin', 'httpsSameSite']))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ })
+ .then(() => t.done(), t.step_func((error) => { throw error; }));
+ }, 'sec-fetch-site - Same-Origin -> Same-Site');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ assert_implements_optional(
+ !!window.applicationCache, 'Application Cache supported.'
+ );
+
+ induceRequest(makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite']))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ })
+ .then(() => t.done(), t.step_func((error) => { throw error; }));
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ assert_implements_optional(
+ !!window.applicationCache, 'Application Cache supported.'
+ );
+
+ induceRequest(makeRequestURL(key, ['httpsSameSite', 'httpsOrigin']))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ })
+ .then(() => t.done(), t.step_func((error) => { throw error; }));
+ }, 'sec-fetch-site - Same-Site -> Same Origin');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ assert_implements_optional(
+ !!window.applicationCache, 'Application Cache supported.'
+ );
+
+ induceRequest(makeRequestURL(key, ['httpsSameSite', 'httpsSameSite']))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ })
+ .then(() => t.done(), t.step_func((error) => { throw error; }));
+ }, 'sec-fetch-site - Same-Site -> Same-Site');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ assert_implements_optional(
+ !!window.applicationCache, 'Application Cache supported.'
+ );
+
+ induceRequest(makeRequestURL(key, ['httpsSameSite', 'httpsCrossSite']))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ })
+ .then(() => t.done(), t.step_func((error) => { throw error; }));
+ }, 'sec-fetch-site - Same-Site -> Cross-Site');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ assert_implements_optional(
+ !!window.applicationCache, 'Application Cache supported.'
+ );
+
+ induceRequest(makeRequestURL(key, []))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['no-cors']);
+ })
+ .then(() => t.done(), t.step_func((error) => { throw error; }));
+ }, 'sec-fetch-mode');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ assert_implements_optional(
+ !!window.applicationCache, 'Application Cache supported.'
+ );
+
+ induceRequest(makeRequestURL(key, []))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['empty']);
+ })
+ .then(() => t.done(), t.step_func((error) => { throw error; }));
+ }, 'sec-fetch-dest');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ assert_implements_optional(
+ !!window.applicationCache, 'Application Cache supported.'
+ );
+
+ induceRequest(makeRequestURL(key, []))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ })
+ .then(() => t.done(), t.step_func((error) => { throw error; }));
+ }, 'sec-fetch-user');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/audioworklet.https.sub.html b/testing/web-platform/tests/fetch/metadata/generated/audioworklet.https.sub.html
new file mode 100644
index 0000000000..64fb7607e2
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/audioworklet.https.sub.html
@@ -0,0 +1,271 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/audioworklet.https.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <title>HTTP headers on request for AudioWorklet module</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="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ function induceRequest(url, test) {
+ return test_driver.bless(
+ 'Enable WebAudio playback',
+ () => {
+ const audioContext = new AudioContext();
+
+ test.add_cleanup(() => audioContext.close());
+
+ return audioContext.audioWorklet.addModule(url);
+ }
+ );
+ }
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin'], {mime: 'text/javascript'}),
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same origin');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite'], {mime: 'text/javascript'}),
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite'], {mime: 'text/javascript'}),
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite', 'httpsOrigin'], {mime: 'text/javascript'}),
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsSameSite', 'httpsOrigin'], {mime: 'text/javascript'}),
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsOrigin'], {mime: 'text/javascript'}),
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same Origin');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsSameSite'], {mime: 'text/javascript'}),
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsCrossSite'], {mime: 'text/javascript'}),
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Cross-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsOrigin'], {mime: 'text/javascript'}),
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same Origin');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsSameSite'], {mime: 'text/javascript'}),
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite'], {mime: 'text/javascript'}),
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsOrigin'], {mime: 'text/javascript'}),
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same Origin');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsSameSite'], {mime: 'text/javascript'}),
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsCrossSite'], {mime: 'text/javascript'}),
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Cross-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, [], {mime: 'text/javascript'}),
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['cors']);
+ });
+ }, 'sec-fetch-mode');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, [], {mime: 'text/javascript'}),
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['audioworklet']);
+ });
+ }, 'sec-fetch-dest');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, [], {mime: 'text/javascript'}),
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/css-font-face.https.sub.tentative.html b/testing/web-platform/tests/fetch/metadata/generated/css-font-face.https.sub.tentative.html
new file mode 100644
index 0000000000..332effeb1f
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/css-font-face.https.sub.tentative.html
@@ -0,0 +1,230 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/css-font-face.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <title>HTTP headers on request for CSS font-face</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ let count = 0;
+
+ function induceRequest(t, url) {
+ const id = `el-${count += 1}`;
+ const style = document.createElement('style');
+ style.appendChild(document.createTextNode(`
+ @font-face {
+ font-family: wpt-font-family${id};
+ src: url(${url});
+ }
+ #el-${id} {
+ font-family: wpt-font-family${id};
+ }
+ `));
+ const div = document.createElement('div');
+ div.setAttribute('id', 'el-' + id);
+ div.appendChild(style);
+ div.appendChild(document.createTextNode('x'));
+ document.body.appendChild(div);
+
+ t.add_cleanup(() => div.remove());
+
+ return document.fonts.ready;
+ }
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpsOrigin']))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same origin');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpsCrossSite']))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpsSameSite']))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite', 'httpsOrigin']))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpsOrigin', 'httpsSameSite', 'httpsOrigin']))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpsCrossSite', 'httpsOrigin']))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same Origin');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpsCrossSite', 'httpsSameSite']))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpsCrossSite', 'httpsCrossSite']))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Cross-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpsOrigin', 'httpsOrigin']))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same Origin');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpsOrigin', 'httpsSameSite']))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite']))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpsSameSite', 'httpsOrigin']))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same Origin');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpsSameSite', 'httpsSameSite']))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpsSameSite', 'httpsCrossSite']))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Cross-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, []))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['cors']);
+ });
+ }, 'sec-fetch-mode');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, []))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['font']);
+ });
+ }, 'sec-fetch-dest');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, []))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/css-font-face.sub.tentative.html b/testing/web-platform/tests/fetch/metadata/generated/css-font-face.sub.tentative.html
new file mode 100644
index 0000000000..8a0b90cee1
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/css-font-face.sub.tentative.html
@@ -0,0 +1,196 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/css-font-face.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <title>HTTP headers on request for CSS font-face</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ let count = 0;
+
+ function induceRequest(t, url) {
+ const id = `el-${count += 1}`;
+ const style = document.createElement('style');
+ style.appendChild(document.createTextNode(`
+ @font-face {
+ font-family: wpt-font-family${id};
+ src: url(${url});
+ }
+ #el-${id} {
+ font-family: wpt-font-family${id};
+ }
+ `));
+ const div = document.createElement('div');
+ div.setAttribute('id', 'el-' + id);
+ div.appendChild(style);
+ div.appendChild(document.createTextNode('x'));
+ document.body.appendChild(div);
+
+ t.add_cleanup(() => div.remove());
+
+ return document.fonts.ready;
+ }
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpOrigin']))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-origin destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpSameSite']))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpCrossSite']))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy cross-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpOrigin']))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-origin destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpSameSite']))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpCrossSite']))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy cross-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpOrigin']))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-origin destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpSameSite']))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpCrossSite']))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy cross-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpOrigin']))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-origin destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpSameSite']))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpCrossSite']))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy cross-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpsOrigin', 'httpOrigin']))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - HTTPS downgrade (header not sent)');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpOrigin', 'httpsOrigin']))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS upgrade');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin']))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS downgrade-upgrade');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/css-images.https.sub.tentative.html b/testing/web-platform/tests/fetch/metadata/generated/css-images.https.sub.tentative.html
new file mode 100644
index 0000000000..3fa2401928
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/css-images.https.sub.tentative.html
@@ -0,0 +1,1384 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/css-images.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <meta name="timeout" content="long">
+ <title>HTTP headers on request for CSS image-accepting properties</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ /**
+ * The subtests in this file use an iframe to induce requests for CSS
+ * resources because an iframe's `onload` event is the most direct and
+ * generic mechanism to detect loading of CSS resources. As an optimization,
+ * the subtests share the same iframe and document.
+ */
+ const declarations = [];
+ const iframe = document.createElement('iframe');
+ const whenIframeReady = new Promise((resolve, reject) => {
+ iframe.onload = resolve;
+ iframe.onerror = reject;
+ });
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin']);
+
+ declarations.push(`background-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_equals(headers['sec-fetch-site'], 'same-origin');
+ })
+ .then(t.step_func_done(), (error) => t.unreached_func());
+ }, 'background-image sec-fetch-site - Same origin');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin']);
+
+ declarations.push(`border-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'border-image sec-fetch-site - Same origin');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin']);
+
+ declarations.push(`content: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'content sec-fetch-site - Same origin');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin']);
+
+ declarations.push(`cursor: url("${url}"), auto;`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'cursor sec-fetch-site - Same origin');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin']);
+
+ declarations.push(`list-style-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'list-style-image sec-fetch-site - Same origin');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsCrossSite']);
+
+ declarations.push(`background-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_equals(headers['sec-fetch-site'], 'cross-site');
+ })
+ .then(t.step_func_done(), (error) => t.unreached_func());
+ }, 'background-image sec-fetch-site - Cross-site');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsCrossSite']);
+
+ declarations.push(`border-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'border-image sec-fetch-site - Cross-site');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsCrossSite']);
+
+ declarations.push(`content: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'content sec-fetch-site - Cross-site');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsCrossSite']);
+
+ declarations.push(`cursor: url("${url}"), auto;`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'cursor sec-fetch-site - Cross-site');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsCrossSite']);
+
+ declarations.push(`list-style-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'list-style-image sec-fetch-site - Cross-site');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsSameSite']);
+
+ declarations.push(`background-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_equals(headers['sec-fetch-site'], 'same-site');
+ })
+ .then(t.step_func_done(), (error) => t.unreached_func());
+ }, 'background-image sec-fetch-site - Same site');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsSameSite']);
+
+ declarations.push(`border-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'border-image sec-fetch-site - Same site');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsSameSite']);
+
+ declarations.push(`content: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'content sec-fetch-site - Same site');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsSameSite']);
+
+ declarations.push(`cursor: url("${url}"), auto;`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'cursor sec-fetch-site - Same site');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsSameSite']);
+
+ declarations.push(`list-style-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'list-style-image sec-fetch-site - Same site');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite', 'httpsOrigin']);
+
+ declarations.push(`background-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_equals(headers['sec-fetch-site'], 'cross-site');
+ })
+ .then(t.step_func_done(), (error) => t.unreached_func());
+ }, 'background-image sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite', 'httpsOrigin']);
+
+ declarations.push(`border-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'border-image sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite', 'httpsOrigin']);
+
+ declarations.push(`content: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'content sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite', 'httpsOrigin']);
+
+ declarations.push(`cursor: url("${url}"), auto;`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'cursor sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite', 'httpsOrigin']);
+
+ declarations.push(`list-style-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'list-style-image sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsSameSite', 'httpsOrigin']);
+
+ declarations.push(`background-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_equals(headers['sec-fetch-site'], 'same-site');
+ })
+ .then(t.step_func_done(), (error) => t.unreached_func());
+ }, 'background-image sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsSameSite', 'httpsOrigin']);
+
+ declarations.push(`border-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'border-image sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsSameSite', 'httpsOrigin']);
+
+ declarations.push(`content: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'content sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsSameSite', 'httpsOrigin']);
+
+ declarations.push(`cursor: url("${url}"), auto;`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'cursor sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsSameSite', 'httpsOrigin']);
+
+ declarations.push(`list-style-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'list-style-image sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsCrossSite', 'httpsOrigin']);
+
+ declarations.push(`background-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_equals(headers['sec-fetch-site'], 'cross-site');
+ })
+ .then(t.step_func_done(), (error) => t.unreached_func());
+ }, 'background-image sec-fetch-site - Cross-Site -> Same Origin');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsCrossSite', 'httpsOrigin']);
+
+ declarations.push(`border-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'border-image sec-fetch-site - Cross-Site -> Same Origin');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsCrossSite', 'httpsOrigin']);
+
+ declarations.push(`content: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'content sec-fetch-site - Cross-Site -> Same Origin');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsCrossSite', 'httpsOrigin']);
+
+ declarations.push(`cursor: url("${url}"), auto;`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'cursor sec-fetch-site - Cross-Site -> Same Origin');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsCrossSite', 'httpsOrigin']);
+
+ declarations.push(`list-style-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'list-style-image sec-fetch-site - Cross-Site -> Same Origin');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsCrossSite', 'httpsSameSite']);
+
+ declarations.push(`background-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_equals(headers['sec-fetch-site'], 'cross-site');
+ })
+ .then(t.step_func_done(), (error) => t.unreached_func());
+ }, 'background-image sec-fetch-site - Cross-Site -> Same-Site');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsCrossSite', 'httpsSameSite']);
+
+ declarations.push(`border-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'border-image sec-fetch-site - Cross-Site -> Same-Site');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsCrossSite', 'httpsSameSite']);
+
+ declarations.push(`content: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'content sec-fetch-site - Cross-Site -> Same-Site');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsCrossSite', 'httpsSameSite']);
+
+ declarations.push(`cursor: url("${url}"), auto;`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'cursor sec-fetch-site - Cross-Site -> Same-Site');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsCrossSite', 'httpsSameSite']);
+
+ declarations.push(`list-style-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'list-style-image sec-fetch-site - Cross-Site -> Same-Site');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsCrossSite', 'httpsCrossSite']);
+
+ declarations.push(`background-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_equals(headers['sec-fetch-site'], 'cross-site');
+ })
+ .then(t.step_func_done(), (error) => t.unreached_func());
+ }, 'background-image sec-fetch-site - Cross-Site -> Cross-Site');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsCrossSite', 'httpsCrossSite']);
+
+ declarations.push(`border-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'border-image sec-fetch-site - Cross-Site -> Cross-Site');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsCrossSite', 'httpsCrossSite']);
+
+ declarations.push(`content: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'content sec-fetch-site - Cross-Site -> Cross-Site');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsCrossSite', 'httpsCrossSite']);
+
+ declarations.push(`cursor: url("${url}"), auto;`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'cursor sec-fetch-site - Cross-Site -> Cross-Site');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsCrossSite', 'httpsCrossSite']);
+
+ declarations.push(`list-style-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'list-style-image sec-fetch-site - Cross-Site -> Cross-Site');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsOrigin']);
+
+ declarations.push(`background-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_equals(headers['sec-fetch-site'], 'same-origin');
+ })
+ .then(t.step_func_done(), (error) => t.unreached_func());
+ }, 'background-image sec-fetch-site - Same-Origin -> Same Origin');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsOrigin']);
+
+ declarations.push(`border-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'border-image sec-fetch-site - Same-Origin -> Same Origin');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsOrigin']);
+
+ declarations.push(`content: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'content sec-fetch-site - Same-Origin -> Same Origin');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsOrigin']);
+
+ declarations.push(`cursor: url("${url}"), auto;`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'cursor sec-fetch-site - Same-Origin -> Same Origin');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsOrigin']);
+
+ declarations.push(`list-style-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'list-style-image sec-fetch-site - Same-Origin -> Same Origin');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsSameSite']);
+
+ declarations.push(`background-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_equals(headers['sec-fetch-site'], 'same-site');
+ })
+ .then(t.step_func_done(), (error) => t.unreached_func());
+ }, 'background-image sec-fetch-site - Same-Origin -> Same-Site');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsSameSite']);
+
+ declarations.push(`border-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'border-image sec-fetch-site - Same-Origin -> Same-Site');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsSameSite']);
+
+ declarations.push(`content: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'content sec-fetch-site - Same-Origin -> Same-Site');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsSameSite']);
+
+ declarations.push(`cursor: url("${url}"), auto;`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'cursor sec-fetch-site - Same-Origin -> Same-Site');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsSameSite']);
+
+ declarations.push(`list-style-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'list-style-image sec-fetch-site - Same-Origin -> Same-Site');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite']);
+
+ declarations.push(`background-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_equals(headers['sec-fetch-site'], 'cross-site');
+ })
+ .then(t.step_func_done(), (error) => t.unreached_func());
+ }, 'background-image sec-fetch-site - Same-Origin -> Cross-Site');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite']);
+
+ declarations.push(`border-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'border-image sec-fetch-site - Same-Origin -> Cross-Site');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite']);
+
+ declarations.push(`content: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'content sec-fetch-site - Same-Origin -> Cross-Site');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite']);
+
+ declarations.push(`cursor: url("${url}"), auto;`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'cursor sec-fetch-site - Same-Origin -> Cross-Site');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite']);
+
+ declarations.push(`list-style-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'list-style-image sec-fetch-site - Same-Origin -> Cross-Site');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsSameSite', 'httpsOrigin']);
+
+ declarations.push(`background-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_equals(headers['sec-fetch-site'], 'same-site');
+ })
+ .then(t.step_func_done(), (error) => t.unreached_func());
+ }, 'background-image sec-fetch-site - Same-Site -> Same Origin');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsSameSite', 'httpsOrigin']);
+
+ declarations.push(`border-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'border-image sec-fetch-site - Same-Site -> Same Origin');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsSameSite', 'httpsOrigin']);
+
+ declarations.push(`content: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'content sec-fetch-site - Same-Site -> Same Origin');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsSameSite', 'httpsOrigin']);
+
+ declarations.push(`cursor: url("${url}"), auto;`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'cursor sec-fetch-site - Same-Site -> Same Origin');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsSameSite', 'httpsOrigin']);
+
+ declarations.push(`list-style-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'list-style-image sec-fetch-site - Same-Site -> Same Origin');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsSameSite', 'httpsSameSite']);
+
+ declarations.push(`background-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_equals(headers['sec-fetch-site'], 'same-site');
+ })
+ .then(t.step_func_done(), (error) => t.unreached_func());
+ }, 'background-image sec-fetch-site - Same-Site -> Same-Site');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsSameSite', 'httpsSameSite']);
+
+ declarations.push(`border-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'border-image sec-fetch-site - Same-Site -> Same-Site');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsSameSite', 'httpsSameSite']);
+
+ declarations.push(`content: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'content sec-fetch-site - Same-Site -> Same-Site');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsSameSite', 'httpsSameSite']);
+
+ declarations.push(`cursor: url("${url}"), auto;`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'cursor sec-fetch-site - Same-Site -> Same-Site');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsSameSite', 'httpsSameSite']);
+
+ declarations.push(`list-style-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'list-style-image sec-fetch-site - Same-Site -> Same-Site');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsSameSite', 'httpsCrossSite']);
+
+ declarations.push(`background-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_equals(headers['sec-fetch-site'], 'cross-site');
+ })
+ .then(t.step_func_done(), (error) => t.unreached_func());
+ }, 'background-image sec-fetch-site - Same-Site -> Cross-Site');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsSameSite', 'httpsCrossSite']);
+
+ declarations.push(`border-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'border-image sec-fetch-site - Same-Site -> Cross-Site');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsSameSite', 'httpsCrossSite']);
+
+ declarations.push(`content: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'content sec-fetch-site - Same-Site -> Cross-Site');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsSameSite', 'httpsCrossSite']);
+
+ declarations.push(`cursor: url("${url}"), auto;`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'cursor sec-fetch-site - Same-Site -> Cross-Site');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsSameSite', 'httpsCrossSite']);
+
+ declarations.push(`list-style-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'list-style-image sec-fetch-site - Same-Site -> Cross-Site');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin']);
+
+ declarations.push(`background-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_equals(headers['sec-fetch-site'], 'cross-site');
+ })
+ .then(t.step_func_done(), (error) => t.unreached_func());
+ }, 'background-image sec-fetch-site - HTTPS downgrade-upgrade');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin']);
+
+ declarations.push(`border-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'border-image sec-fetch-site - HTTPS downgrade-upgrade');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin']);
+
+ declarations.push(`content: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'content sec-fetch-site - HTTPS downgrade-upgrade');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin']);
+
+ declarations.push(`cursor: url("${url}"), auto;`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'cursor sec-fetch-site - HTTPS downgrade-upgrade');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin']);
+
+ declarations.push(`list-style-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'list-style-image sec-fetch-site - HTTPS downgrade-upgrade');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, []);
+
+ declarations.push(`background-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_equals(headers['sec-fetch-mode'], 'no-cors');
+ })
+ .then(t.step_func_done(), (error) => t.unreached_func());
+ }, 'background-image sec-fetch-mode');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, []);
+
+ declarations.push(`border-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['no-cors']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'border-image sec-fetch-mode');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, []);
+
+ declarations.push(`content: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['no-cors']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'content sec-fetch-mode');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, []);
+
+ declarations.push(`cursor: url("${url}"), auto;`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['no-cors']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'cursor sec-fetch-mode');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, []);
+
+ declarations.push(`list-style-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['no-cors']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'list-style-image sec-fetch-mode');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, []);
+
+ declarations.push(`background-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_equals(headers['sec-fetch-dest'], 'image');
+ })
+ .then(t.step_func_done(), (error) => t.unreached_func());
+ }, 'background-image sec-fetch-dest');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, []);
+
+ declarations.push(`border-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['image']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'border-image sec-fetch-dest');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, []);
+
+ declarations.push(`content: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['image']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'content sec-fetch-dest');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, []);
+
+ declarations.push(`cursor: url("${url}"), auto;`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['image']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'cursor sec-fetch-dest');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, []);
+
+ declarations.push(`list-style-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['image']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'list-style-image sec-fetch-dest');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, []);
+
+ declarations.push(`background-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ })
+ .then(t.step_func_done(), (error) => t.unreached_func());
+ }, 'background-image sec-fetch-user');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, []);
+
+ declarations.push(`border-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'border-image sec-fetch-user');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, []);
+
+ declarations.push(`content: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'content sec-fetch-user');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, []);
+
+ declarations.push(`cursor: url("${url}"), auto;`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'cursor sec-fetch-user');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, []);
+
+ declarations.push(`list-style-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'list-style-image sec-fetch-user');
+
+ iframe.srcdoc = declarations.map((declaration, index) => `
+ <style>.el${index} { ${declaration} }</style><div class="el${index}"></div>`
+ ).join('');
+ document.body.appendChild(iframe);
+
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/css-images.sub.tentative.html b/testing/web-platform/tests/fetch/metadata/generated/css-images.sub.tentative.html
new file mode 100644
index 0000000000..f1ef27cf08
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/css-images.sub.tentative.html
@@ -0,0 +1,1099 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/css-images.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <meta name="timeout" content="long">
+ <title>HTTP headers on request for CSS image-accepting properties</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ /**
+ * The subtests in this file use an iframe to induce requests for CSS
+ * resources because an iframe's `onload` event is the most direct and
+ * generic mechanism to detect loading of CSS resources. As an optimization,
+ * the subtests share the same iframe and document.
+ */
+ const declarations = [];
+ const iframe = document.createElement('iframe');
+ const whenIframeReady = new Promise((resolve, reject) => {
+ iframe.onload = resolve;
+ iframe.onerror = reject;
+ });
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin']);
+
+ declarations.push(`background-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ })
+ .then(t.step_func_done(), (error) => t.unreached_func());
+ }, 'background-image sec-fetch-site - Not sent to non-trustworthy same-origin destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin']);
+
+ declarations.push(`border-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'border-image sec-fetch-site - Not sent to non-trustworthy same-origin destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin']);
+
+ declarations.push(`content: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'content sec-fetch-site - Not sent to non-trustworthy same-origin destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin']);
+
+ declarations.push(`cursor: url("${url}"), auto;`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'cursor sec-fetch-site - Not sent to non-trustworthy same-origin destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin']);
+
+ declarations.push(`list-style-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'list-style-image sec-fetch-site - Not sent to non-trustworthy same-origin destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite']);
+
+ declarations.push(`background-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ })
+ .then(t.step_func_done(), (error) => t.unreached_func());
+ }, 'background-image sec-fetch-site - Not sent to non-trustworthy same-site destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite']);
+
+ declarations.push(`border-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'border-image sec-fetch-site - Not sent to non-trustworthy same-site destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite']);
+
+ declarations.push(`content: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'content sec-fetch-site - Not sent to non-trustworthy same-site destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite']);
+
+ declarations.push(`cursor: url("${url}"), auto;`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'cursor sec-fetch-site - Not sent to non-trustworthy same-site destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite']);
+
+ declarations.push(`list-style-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'list-style-image sec-fetch-site - Not sent to non-trustworthy same-site destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite']);
+
+ declarations.push(`background-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ })
+ .then(t.step_func_done(), (error) => t.unreached_func());
+ }, 'background-image sec-fetch-site - Not sent to non-trustworthy cross-site destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite']);
+
+ declarations.push(`border-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'border-image sec-fetch-site - Not sent to non-trustworthy cross-site destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite']);
+
+ declarations.push(`content: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'content sec-fetch-site - Not sent to non-trustworthy cross-site destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite']);
+
+ declarations.push(`cursor: url("${url}"), auto;`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'cursor sec-fetch-site - Not sent to non-trustworthy cross-site destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite']);
+
+ declarations.push(`list-style-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'list-style-image sec-fetch-site - Not sent to non-trustworthy cross-site destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin']);
+
+ declarations.push(`background-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ })
+ .then(t.step_func_done(), (error) => t.unreached_func());
+ }, 'background-image sec-fetch-mode - Not sent to non-trustworthy same-origin destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin']);
+
+ declarations.push(`border-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'border-image sec-fetch-mode - Not sent to non-trustworthy same-origin destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin']);
+
+ declarations.push(`content: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'content sec-fetch-mode - Not sent to non-trustworthy same-origin destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin']);
+
+ declarations.push(`cursor: url("${url}"), auto;`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'cursor sec-fetch-mode - Not sent to non-trustworthy same-origin destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin']);
+
+ declarations.push(`list-style-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'list-style-image sec-fetch-mode - Not sent to non-trustworthy same-origin destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite']);
+
+ declarations.push(`background-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ })
+ .then(t.step_func_done(), (error) => t.unreached_func());
+ }, 'background-image sec-fetch-mode - Not sent to non-trustworthy same-site destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite']);
+
+ declarations.push(`border-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'border-image sec-fetch-mode - Not sent to non-trustworthy same-site destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite']);
+
+ declarations.push(`content: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'content sec-fetch-mode - Not sent to non-trustworthy same-site destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite']);
+
+ declarations.push(`cursor: url("${url}"), auto;`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'cursor sec-fetch-mode - Not sent to non-trustworthy same-site destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite']);
+
+ declarations.push(`list-style-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'list-style-image sec-fetch-mode - Not sent to non-trustworthy same-site destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite']);
+
+ declarations.push(`background-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ })
+ .then(t.step_func_done(), (error) => t.unreached_func());
+ }, 'background-image sec-fetch-mode - Not sent to non-trustworthy cross-site destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite']);
+
+ declarations.push(`border-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'border-image sec-fetch-mode - Not sent to non-trustworthy cross-site destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite']);
+
+ declarations.push(`content: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'content sec-fetch-mode - Not sent to non-trustworthy cross-site destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite']);
+
+ declarations.push(`cursor: url("${url}"), auto;`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'cursor sec-fetch-mode - Not sent to non-trustworthy cross-site destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite']);
+
+ declarations.push(`list-style-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'list-style-image sec-fetch-mode - Not sent to non-trustworthy cross-site destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin']);
+
+ declarations.push(`background-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ })
+ .then(t.step_func_done(), (error) => t.unreached_func());
+ }, 'background-image sec-fetch-dest - Not sent to non-trustworthy same-origin destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin']);
+
+ declarations.push(`border-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'border-image sec-fetch-dest - Not sent to non-trustworthy same-origin destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin']);
+
+ declarations.push(`content: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'content sec-fetch-dest - Not sent to non-trustworthy same-origin destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin']);
+
+ declarations.push(`cursor: url("${url}"), auto;`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'cursor sec-fetch-dest - Not sent to non-trustworthy same-origin destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin']);
+
+ declarations.push(`list-style-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'list-style-image sec-fetch-dest - Not sent to non-trustworthy same-origin destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite']);
+
+ declarations.push(`background-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ })
+ .then(t.step_func_done(), (error) => t.unreached_func());
+ }, 'background-image sec-fetch-dest - Not sent to non-trustworthy same-site destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite']);
+
+ declarations.push(`border-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'border-image sec-fetch-dest - Not sent to non-trustworthy same-site destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite']);
+
+ declarations.push(`content: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'content sec-fetch-dest - Not sent to non-trustworthy same-site destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite']);
+
+ declarations.push(`cursor: url("${url}"), auto;`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'cursor sec-fetch-dest - Not sent to non-trustworthy same-site destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite']);
+
+ declarations.push(`list-style-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'list-style-image sec-fetch-dest - Not sent to non-trustworthy same-site destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite']);
+
+ declarations.push(`background-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ })
+ .then(t.step_func_done(), (error) => t.unreached_func());
+ }, 'background-image sec-fetch-dest - Not sent to non-trustworthy cross-site destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite']);
+
+ declarations.push(`border-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'border-image sec-fetch-dest - Not sent to non-trustworthy cross-site destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite']);
+
+ declarations.push(`content: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'content sec-fetch-dest - Not sent to non-trustworthy cross-site destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite']);
+
+ declarations.push(`cursor: url("${url}"), auto;`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'cursor sec-fetch-dest - Not sent to non-trustworthy cross-site destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite']);
+
+ declarations.push(`list-style-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'list-style-image sec-fetch-dest - Not sent to non-trustworthy cross-site destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin']);
+
+ declarations.push(`background-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ })
+ .then(t.step_func_done(), (error) => t.unreached_func());
+ }, 'background-image sec-fetch-user - Not sent to non-trustworthy same-origin destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin']);
+
+ declarations.push(`border-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'border-image sec-fetch-user - Not sent to non-trustworthy same-origin destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin']);
+
+ declarations.push(`content: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'content sec-fetch-user - Not sent to non-trustworthy same-origin destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin']);
+
+ declarations.push(`cursor: url("${url}"), auto;`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'cursor sec-fetch-user - Not sent to non-trustworthy same-origin destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin']);
+
+ declarations.push(`list-style-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'list-style-image sec-fetch-user - Not sent to non-trustworthy same-origin destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite']);
+
+ declarations.push(`background-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ })
+ .then(t.step_func_done(), (error) => t.unreached_func());
+ }, 'background-image sec-fetch-user - Not sent to non-trustworthy same-site destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite']);
+
+ declarations.push(`border-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'border-image sec-fetch-user - Not sent to non-trustworthy same-site destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite']);
+
+ declarations.push(`content: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'content sec-fetch-user - Not sent to non-trustworthy same-site destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite']);
+
+ declarations.push(`cursor: url("${url}"), auto;`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'cursor sec-fetch-user - Not sent to non-trustworthy same-site destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite']);
+
+ declarations.push(`list-style-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'list-style-image sec-fetch-user - Not sent to non-trustworthy same-site destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite']);
+
+ declarations.push(`background-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ })
+ .then(t.step_func_done(), (error) => t.unreached_func());
+ }, 'background-image sec-fetch-user - Not sent to non-trustworthy cross-site destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite']);
+
+ declarations.push(`border-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'border-image sec-fetch-user - Not sent to non-trustworthy cross-site destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite']);
+
+ declarations.push(`content: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'content sec-fetch-user - Not sent to non-trustworthy cross-site destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite']);
+
+ declarations.push(`cursor: url("${url}"), auto;`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'cursor sec-fetch-user - Not sent to non-trustworthy cross-site destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite']);
+
+ declarations.push(`list-style-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'list-style-image sec-fetch-user - Not sent to non-trustworthy cross-site destination');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpOrigin']);
+
+ declarations.push(`background-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ })
+ .then(t.step_func_done(), (error) => t.unreached_func());
+ }, 'background-image sec-fetch-site - HTTPS downgrade (header not sent)');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpOrigin']);
+
+ declarations.push(`border-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'border-image sec-fetch-site - HTTPS downgrade (header not sent)');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpOrigin']);
+
+ declarations.push(`content: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'content sec-fetch-site - HTTPS downgrade (header not sent)');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpOrigin']);
+
+ declarations.push(`cursor: url("${url}"), auto;`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'cursor sec-fetch-site - HTTPS downgrade (header not sent)');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpOrigin']);
+
+ declarations.push(`list-style-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'list-style-image sec-fetch-site - HTTPS downgrade (header not sent)');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin', 'httpsOrigin']);
+
+ declarations.push(`background-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_equals(headers['sec-fetch-site'], 'cross-site');
+ })
+ .then(t.step_func_done(), (error) => t.unreached_func());
+ }, 'background-image sec-fetch-site - HTTPS upgrade');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin', 'httpsOrigin']);
+
+ declarations.push(`border-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'border-image sec-fetch-site - HTTPS upgrade');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin', 'httpsOrigin']);
+
+ declarations.push(`content: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'content sec-fetch-site - HTTPS upgrade');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin', 'httpsOrigin']);
+
+ declarations.push(`cursor: url("${url}"), auto;`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'cursor sec-fetch-site - HTTPS upgrade');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin', 'httpsOrigin']);
+
+ declarations.push(`list-style-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'list-style-image sec-fetch-site - HTTPS upgrade');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin']);
+
+ declarations.push(`background-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_equals(headers['sec-fetch-site'], 'cross-site');
+ })
+ .then(t.step_func_done(), (error) => t.unreached_func());
+ }, 'background-image sec-fetch-site - HTTPS downgrade-upgrade');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin']);
+
+ declarations.push(`border-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'border-image sec-fetch-site - HTTPS downgrade-upgrade');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin']);
+
+ declarations.push(`content: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'content sec-fetch-site - HTTPS downgrade-upgrade');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin']);
+
+ declarations.push(`cursor: url("${url}"), auto;`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'cursor sec-fetch-site - HTTPS downgrade-upgrade');
+
+ async_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin']);
+
+ declarations.push(`list-style-image: url("${url}");`);
+
+ whenIframeReady
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ })
+ .then(t.step_func_done(), t.unreached_func());
+ }, 'list-style-image sec-fetch-site - HTTPS downgrade-upgrade');
+
+ iframe.srcdoc = declarations.map((declaration, index) => `
+ <style>.el${index} { ${declaration} }</style><div class="el${index}"></div>`
+ ).join('');
+ document.body.appendChild(iframe);
+
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/element-a.https.sub.html b/testing/web-platform/tests/fetch/metadata/generated/element-a.https.sub.html
new file mode 100644
index 0000000000..dffd36c73e
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/element-a.https.sub.html
@@ -0,0 +1,482 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/element-a.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <meta name="timeout" content="long">
+ <title>HTTP headers on request for HTML "a" element navigation</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="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ function induceRequest(url, {test, userActivated, attributes}) {
+ const win = window.open();
+ const anchor = win.document.createElement('a');
+ anchor.setAttribute('href', url);
+
+ for (const [ name, value ] of Object.entries(attributes)) {
+ anchor.setAttribute(name, value);
+ }
+
+ win.document.body.appendChild(anchor);
+
+ test.add_cleanup(() => win.close());
+
+ if (userActivated) {
+ test_driver.bless('enable user activation', () => anchor.click());
+ } else {
+ anchor.click();
+ }
+ }
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpsOrigin'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same origin - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpsCrossSite'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-site - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpsSameSite'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same site - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite', 'httpsOrigin'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsSameSite', 'httpsOrigin'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsOrigin'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same Origin - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsSameSite'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same-Site - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsCrossSite'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Cross-Site - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsOrigin'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same Origin - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsSameSite'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsOrigin'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same Origin - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsSameSite'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same-Site - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsCrossSite'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Cross-Site - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS downgrade-upgrade - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, [], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['navigate']);
+ });
+ }, 'sec-fetch-mode - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, [], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {"download": ""}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['no-cors']);
+ });
+ }, 'sec-fetch-mode - attributes: download');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, [], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['document']);
+ });
+ }, 'sec-fetch-dest - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, [], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {"download": ""}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['empty']);
+ });
+ }, 'sec-fetch-dest - attributes: download');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, [], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, [], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: true,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-user');
+ assert_array_equals(headers['sec-fetch-user'], ['?1']);
+ });
+ }, 'sec-fetch-user - no attributes with user activation');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/element-a.sub.html b/testing/web-platform/tests/fetch/metadata/generated/element-a.sub.html
new file mode 100644
index 0000000000..0661de3c87
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/element-a.sub.html
@@ -0,0 +1,342 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/element-a.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <meta name="timeout" content="long">
+ <title>HTTP headers on request for HTML "a" element navigation</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ function induceRequest(url, {test, userActivated, attributes}) {
+ const win = window.open();
+ const anchor = win.document.createElement('a');
+ anchor.setAttribute('href', url);
+
+ for (const [ name, value ] of Object.entries(attributes)) {
+ anchor.setAttribute(name, value);
+ }
+
+ win.document.body.appendChild(anchor);
+
+ test.add_cleanup(() => win.close());
+
+ if (userActivated) {
+ test_driver.bless('enable user activation', () => anchor.click());
+ } else {
+ anchor.click();
+ }
+ }
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpOrigin'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-origin destination - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpSameSite'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-site destination - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpCrossSite'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy cross-site destination - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpOrigin'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-origin destination - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpSameSite'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-site destination - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpCrossSite'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy cross-site destination - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpOrigin'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-origin destination - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpSameSite'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-site destination - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpCrossSite'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy cross-site destination - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpOrigin'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-origin destination - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpSameSite'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-site destination - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpCrossSite'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy cross-site destination - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpOrigin'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - HTTPS downgrade (header not sent) - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpOrigin', 'httpsOrigin'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS upgrade - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS downgrade-upgrade - no attributes');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/element-area.https.sub.html b/testing/web-platform/tests/fetch/metadata/generated/element-area.https.sub.html
new file mode 100644
index 0000000000..be3f5f9b62
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/element-area.https.sub.html
@@ -0,0 +1,482 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/element-area.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <meta name="timeout" content="long">
+ <title>HTTP headers on request for HTML "area" element navigation</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="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ function induceRequest(url, {test, userActivated, attributes}) {
+ const win = window.open();
+ const area = win.document.createElement('area');
+ area.setAttribute('href', url);
+
+ for (const [ name, value ] of Object.entries(attributes)) {
+ area.setAttribute(name, value);
+ }
+
+ win.document.body.appendChild(area);
+
+ test.add_cleanup(() => win.close());
+
+ if (userActivated) {
+ test_driver.bless('enable user activation', () => area.click());
+ } else {
+ area.click();
+ }
+ }
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpsOrigin'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same origin - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpsCrossSite'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-site - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpsSameSite'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same site - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite', 'httpsOrigin'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsSameSite', 'httpsOrigin'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsOrigin'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same Origin - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsSameSite'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same-Site - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsCrossSite'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Cross-Site - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsOrigin'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same Origin - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsSameSite'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsOrigin'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same Origin - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsSameSite'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same-Site - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsCrossSite'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Cross-Site - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS downgrade-upgrade - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, [], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['navigate']);
+ });
+ }, 'sec-fetch-mode - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, [], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {"download": ""}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['no-cors']);
+ });
+ }, 'sec-fetch-mode - attributes: download');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, [], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['document']);
+ });
+ }, 'sec-fetch-dest - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, [], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {"download": ""}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['empty']);
+ });
+ }, 'sec-fetch-dest - attributes: download');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, [], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, [], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: true,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-user');
+ assert_array_equals(headers['sec-fetch-user'], ['?1']);
+ });
+ }, 'sec-fetch-user - no attributes with user activation');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/element-area.sub.html b/testing/web-platform/tests/fetch/metadata/generated/element-area.sub.html
new file mode 100644
index 0000000000..5f5c338324
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/element-area.sub.html
@@ -0,0 +1,342 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/element-area.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <meta name="timeout" content="long">
+ <title>HTTP headers on request for HTML "area" element navigation</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ function induceRequest(url, {test, userActivated, attributes}) {
+ const win = window.open();
+ const area = win.document.createElement('area');
+ area.setAttribute('href', url);
+
+ for (const [ name, value ] of Object.entries(attributes)) {
+ area.setAttribute(name, value);
+ }
+
+ win.document.body.appendChild(area);
+
+ test.add_cleanup(() => win.close());
+
+ if (userActivated) {
+ test_driver.bless('enable user activation', () => area.click());
+ } else {
+ area.click();
+ }
+ }
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpOrigin'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-origin destination - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpSameSite'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-site destination - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpCrossSite'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy cross-site destination - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpOrigin'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-origin destination - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpSameSite'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-site destination - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpCrossSite'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy cross-site destination - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpOrigin'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-origin destination - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpSameSite'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-site destination - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpCrossSite'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy cross-site destination - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpOrigin'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-origin destination - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpSameSite'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-site destination - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpCrossSite'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy cross-site destination - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpOrigin'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - HTTPS downgrade (header not sent) - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpOrigin', 'httpsOrigin'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS upgrade - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin'], {mime: 'text/html'}),
+ {
+ test: t,
+ userActivated: false,
+ attributes: {}
+ }
+ );
+
+ // `induceRequest` does not necessarily trigger a navigation, so the Python
+ // handler must be polled until it has received the initial request.
+ return retrieve(key, {poll: true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS downgrade-upgrade - no attributes');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/element-audio.https.sub.html b/testing/web-platform/tests/fetch/metadata/generated/element-audio.https.sub.html
new file mode 100644
index 0000000000..a9d951233e
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/element-audio.https.sub.html
@@ -0,0 +1,325 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/element-audio.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <title>HTTP headers on request for HTML "audio" element source</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ function induceRequest(url, attributes) {
+ const audio = document.createElement('audio');
+
+ for (const [ name, value ] of Object.entries(attributes)) {
+ audio.setAttribute(name, value);
+ }
+
+ return new Promise((resolve) => {
+ audio.setAttribute('src', url);
+ audio.onload = audio.onerror = resolve;
+ });
+ }
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same origin, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite', 'httpsOrigin']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsSameSite', 'httpsOrigin']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsOrigin']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same Origin, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsSameSite']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same-Site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsCrossSite']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Cross-Site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsOrigin']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same Origin, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsSameSite']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsOrigin']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same Origin, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsSameSite']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same-Site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsCrossSite']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Cross-Site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS downgrade-upgrade, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, []),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['no-cors']);
+ });
+ }, 'sec-fetch-mode - no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, []),
+ {"crossorigin": ""}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['cors']);
+ });
+ }, 'sec-fetch-mode - attributes: crossorigin');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, []),
+ {"crossorigin": "anonymous"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['cors']);
+ });
+ }, 'sec-fetch-mode - attributes: crossorigin=anonymous');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, []),
+ {"crossorigin": "use-credentials"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['cors']);
+ });
+ }, 'sec-fetch-mode - attributes: crossorigin=use-credentials');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, []),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['audio']);
+ });
+ }, 'sec-fetch-dest - no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, []),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - no attributes');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/element-audio.sub.html b/testing/web-platform/tests/fetch/metadata/generated/element-audio.sub.html
new file mode 100644
index 0000000000..2b62632ac2
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/element-audio.sub.html
@@ -0,0 +1,229 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/element-audio.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <title>HTTP headers on request for HTML "audio" element source</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ function induceRequest(url, attributes) {
+ const audio = document.createElement('audio');
+
+ for (const [ name, value ] of Object.entries(attributes)) {
+ audio.setAttribute(name, value);
+ }
+
+ return new Promise((resolve) => {
+ audio.setAttribute('src', url);
+ audio.onload = audio.onerror = resolve;
+ });
+ }
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-origin destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy cross-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-origin destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy cross-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-origin destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy cross-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-origin destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy cross-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpOrigin']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - HTTPS downgrade (header not sent), no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin', 'httpsOrigin']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS upgrade, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS downgrade-upgrade, no attributes');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/element-embed.https.sub.html b/testing/web-platform/tests/fetch/metadata/generated/element-embed.https.sub.html
new file mode 100644
index 0000000000..819bed888e
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/element-embed.https.sub.html
@@ -0,0 +1,224 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/element-embed.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <title>HTTP headers on request for HTML "embed" element source</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ const params = {
+ body: `
+ <svg xmlns="http://www.w3.org/2000/svg" width="123" height="123">
+ <rect fill="lime" width="123" height="123"/>
+ </svg>
+ `,
+ mime: 'image/svg+xml'
+ };
+
+ function induceRequest(t, url) {
+ const embed = document.createElement('embed');
+ embed.setAttribute('src', url);
+ document.body.appendChild(embed);
+
+ t.add_cleanup(() => embed.remove());
+
+ return new Promise((resolve) => embed.addEventListener('load', resolve));
+ }
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpsOrigin'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same origin');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpsCrossSite'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpsSameSite'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite', 'httpsOrigin'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpsOrigin', 'httpsSameSite', 'httpsOrigin'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpsCrossSite', 'httpsOrigin'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same Origin');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpsCrossSite', 'httpsSameSite'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpsCrossSite', 'httpsCrossSite'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Cross-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpsOrigin', 'httpsOrigin'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same Origin');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpsOrigin', 'httpsSameSite'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpsSameSite', 'httpsOrigin'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same Origin');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpsSameSite', 'httpsSameSite'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpsSameSite', 'httpsCrossSite'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Cross-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, [], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['no-cors']);
+ });
+ }, 'sec-fetch-mode');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, [], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['embed']);
+ });
+ }, 'sec-fetch-dest');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, [], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/element-embed.sub.html b/testing/web-platform/tests/fetch/metadata/generated/element-embed.sub.html
new file mode 100644
index 0000000000..b6e14a55e4
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/element-embed.sub.html
@@ -0,0 +1,190 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/element-embed.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <title>HTTP headers on request for HTML "embed" element source</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ const params = {
+ body: `
+ <svg xmlns="http://www.w3.org/2000/svg" width="123" height="123">
+ <rect fill="lime" width="123" height="123"/>
+ </svg>
+ `,
+ mime: 'image/svg+xml'
+ };
+
+ function induceRequest(t, url) {
+ const embed = document.createElement('embed');
+ embed.setAttribute('src', url);
+ document.body.appendChild(embed);
+
+ t.add_cleanup(() => embed.remove());
+
+ return new Promise((resolve) => embed.addEventListener('load', resolve));
+ }
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpOrigin'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-origin destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpSameSite'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpCrossSite'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy cross-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpOrigin'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-origin destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpSameSite'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpCrossSite'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy cross-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpOrigin'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-origin destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpSameSite'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpCrossSite'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy cross-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpOrigin'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-origin destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpSameSite'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpCrossSite'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy cross-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpsOrigin', 'httpOrigin'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - HTTPS downgrade (header not sent)');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpOrigin', 'httpsOrigin'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS upgrade');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS downgrade-upgrade');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/element-frame.https.sub.html b/testing/web-platform/tests/fetch/metadata/generated/element-frame.https.sub.html
new file mode 100644
index 0000000000..17504ff563
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/element-frame.https.sub.html
@@ -0,0 +1,309 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/element-frame.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <title>HTTP headers on request for HTML "frame" element source</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="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ function induceRequest(url, test, userActivated) {
+ const frame = document.createElement('frame');
+
+ const setSrc = () => frame.setAttribute('src', url);
+
+ document.body.appendChild(frame);
+ test.add_cleanup(() => frame.remove());
+
+ return new Promise((resolve) => {
+ if (userActivated) {
+ test_driver.bless('enable user activation', setSrc);
+ } else {
+ setSrc();
+ }
+
+ frame.onload = frame.onerror = resolve;
+ });
+ }
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same origin');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite', 'httpsOrigin'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsSameSite', 'httpsOrigin'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsOrigin'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same Origin');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsSameSite'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsCrossSite'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Cross-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsOrigin'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same Origin');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsSameSite'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsOrigin'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same Origin');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsSameSite'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsCrossSite'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Cross-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, [], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['navigate']);
+ });
+ }, 'sec-fetch-mode');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, [], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['frame']);
+ });
+ }, 'sec-fetch-dest');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, [], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, [], {mime: 'text/html'}),
+ t,
+ true
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-user');
+ assert_array_equals(headers['sec-fetch-user'], ['?1']);
+ });
+ }, 'sec-fetch-user with user activation');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/element-frame.sub.html b/testing/web-platform/tests/fetch/metadata/generated/element-frame.sub.html
new file mode 100644
index 0000000000..2d9a7ec97d
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/element-frame.sub.html
@@ -0,0 +1,250 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/element-frame.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <title>HTTP headers on request for HTML "frame" element source</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ function induceRequest(url, test, userActivated) {
+ const frame = document.createElement('frame');
+
+ const setSrc = () => frame.setAttribute('src', url);
+
+ document.body.appendChild(frame);
+ test.add_cleanup(() => frame.remove());
+
+ return new Promise((resolve) => {
+ if (userActivated) {
+ test_driver.bless('enable user activation', setSrc);
+ } else {
+ setSrc();
+ }
+
+ frame.onload = frame.onerror = resolve;
+ });
+ }
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-origin destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy cross-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-origin destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy cross-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-origin destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy cross-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-origin destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy cross-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpOrigin'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - HTTPS downgrade (header not sent)');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin', 'httpsOrigin'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS upgrade');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS downgrade-upgrade');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/element-iframe.https.sub.html b/testing/web-platform/tests/fetch/metadata/generated/element-iframe.https.sub.html
new file mode 100644
index 0000000000..fba1c8b9e0
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/element-iframe.https.sub.html
@@ -0,0 +1,309 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/element-iframe.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <title>HTTP headers on request for HTML "frame" element source</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="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ function induceRequest(url, test, userActivated) {
+ const iframe = document.createElement('iframe');
+
+ const setSrc = () => iframe.setAttribute('src', url);
+
+ document.body.appendChild(iframe);
+ test.add_cleanup(() => iframe.remove());
+
+ return new Promise((resolve) => {
+ if (userActivated) {
+ test_driver.bless('enable user activation', setSrc);
+ } else {
+ setSrc();
+ }
+
+ iframe.onload = iframe.onerror = resolve;
+ });
+ }
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same origin');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite', 'httpsOrigin'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsSameSite', 'httpsOrigin'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsOrigin'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same Origin');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsSameSite'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsCrossSite'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Cross-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsOrigin'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same Origin');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsSameSite'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsOrigin'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same Origin');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsSameSite'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsCrossSite'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Cross-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, [], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['navigate']);
+ });
+ }, 'sec-fetch-mode');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, [], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['iframe']);
+ });
+ }, 'sec-fetch-dest');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, [], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, [], {mime: 'text/html'}),
+ t,
+ true
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-user');
+ assert_array_equals(headers['sec-fetch-user'], ['?1']);
+ });
+ }, 'sec-fetch-user with user activation');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/element-iframe.sub.html b/testing/web-platform/tests/fetch/metadata/generated/element-iframe.sub.html
new file mode 100644
index 0000000000..6f71cc0d25
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/element-iframe.sub.html
@@ -0,0 +1,250 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/element-iframe.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <title>HTTP headers on request for HTML "frame" element source</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ function induceRequest(url, test, userActivated) {
+ const iframe = document.createElement('iframe');
+
+ const setSrc = () => iframe.setAttribute('src', url);
+
+ document.body.appendChild(iframe);
+ test.add_cleanup(() => iframe.remove());
+
+ return new Promise((resolve) => {
+ if (userActivated) {
+ test_driver.bless('enable user activation', setSrc);
+ } else {
+ setSrc();
+ }
+
+ iframe.onload = iframe.onerror = resolve;
+ });
+ }
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-origin destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy cross-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-origin destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy cross-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-origin destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy cross-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-origin destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy cross-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpOrigin'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - HTTPS downgrade (header not sent)');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin', 'httpsOrigin'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS upgrade');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin'], {mime: 'text/html'}),
+ t,
+ false
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS downgrade-upgrade');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/element-img-environment-change.https.sub.html b/testing/web-platform/tests/fetch/metadata/generated/element-img-environment-change.https.sub.html
new file mode 100644
index 0000000000..a19aa117c4
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/element-img-environment-change.https.sub.html
@@ -0,0 +1,357 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/element-img-environment-change.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <title>HTTP headers on image request triggered by change to environment</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ // The response to the request under test must describe a valid image
+ // resource in order for the `load` event to be fired.
+ const params = {
+ body: `
+ <svg xmlns="http://www.w3.org/2000/svg" width="123" height="123">
+ <rect fill="lime" width="123" height="123"/>
+ </svg>
+ `,
+ mime: 'image/svg+xml'
+ };
+
+ function induceRequest(t, url, attributes) {
+ const iframe = document.createElement('iframe');
+ iframe.style.width = '50px';
+ document.body.appendChild(iframe);
+ t.add_cleanup(() => iframe.remove());
+ iframe.contentDocument.open();
+ iframe.contentDocument.close();
+
+ const image = iframe.contentDocument.createElement('img');
+ for (const [ name, value ] of Object.entries(attributes)) {
+ image.setAttribute(name, value);
+ }
+ iframe.contentDocument.body.appendChild(image);
+
+ image.setAttribute('srcset', `${url} 100w, /media/1x1-green.png 1w`);
+ image.setAttribute('sizes', '(max-width: 100px) 1px, (min-width: 150px) 123px');
+
+ return new Promise((resolve) => {
+ image.onload = image.onerror = resolve;
+ })
+ .then(() => {
+
+ iframe.style.width = '200px';
+
+ return new Promise((resolve) => image.onload = resolve);
+ });
+ }
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsOrigin'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same origin, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsCrossSite'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-site, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsSameSite'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same site, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite', 'httpsOrigin'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsOrigin', 'httpsSameSite', 'httpsOrigin'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsCrossSite', 'httpsOrigin'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same Origin, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsCrossSite', 'httpsSameSite'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same-Site, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsCrossSite', 'httpsCrossSite'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Cross-Site, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsOrigin', 'httpsOrigin'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same Origin, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsOrigin', 'httpsSameSite'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsSameSite', 'httpsOrigin'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same Origin, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsSameSite', 'httpsSameSite'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same-Site, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsSameSite', 'httpsCrossSite'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Cross-Site, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, [], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['no-cors']);
+ });
+ }, 'sec-fetch-mode - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, [], params),
+ {"crossorigin": ""}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['cors']);
+ });
+ }, 'sec-fetch-mode - attributes: crossorigin');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, [], params),
+ {"crossorigin": "anonymous"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['cors']);
+ });
+ }, 'sec-fetch-mode - attributes: crossorigin=anonymous');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, [], params),
+ {"crossorigin": "use-credentials"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['cors']);
+ });
+ }, 'sec-fetch-mode - attributes: crossorigin=use-credentials');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, [], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['image']);
+ });
+ }, 'sec-fetch-dest - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, [], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - no attributes');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/element-img-environment-change.sub.html b/testing/web-platform/tests/fetch/metadata/generated/element-img-environment-change.sub.html
new file mode 100644
index 0000000000..96658726ba
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/element-img-environment-change.sub.html
@@ -0,0 +1,270 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/element-img-environment-change.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <title>HTTP headers on image request triggered by change to environment</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ // The response to the request under test must describe a valid image
+ // resource in order for the `load` event to be fired.
+ const params = {
+ body: `
+ <svg xmlns="http://www.w3.org/2000/svg" width="123" height="123">
+ <rect fill="lime" width="123" height="123"/>
+ </svg>
+ `,
+ mime: 'image/svg+xml'
+ };
+
+ function induceRequest(t, url, attributes) {
+ const iframe = document.createElement('iframe');
+ iframe.style.width = '50px';
+ document.body.appendChild(iframe);
+ t.add_cleanup(() => iframe.remove());
+ iframe.contentDocument.open();
+ iframe.contentDocument.close();
+
+ const image = iframe.contentDocument.createElement('img');
+ for (const [ name, value ] of Object.entries(attributes)) {
+ image.setAttribute(name, value);
+ }
+ iframe.contentDocument.body.appendChild(image);
+
+ image.setAttribute('srcset', `${url} 100w, /media/1x1-green.png 1w`);
+ image.setAttribute('sizes', '(max-width: 100px) 1px, (min-width: 150px) 123px');
+
+ return new Promise((resolve) => {
+ image.onload = image.onerror = resolve;
+ })
+ .then(() => {
+
+ iframe.style.width = '200px';
+
+ return new Promise((resolve) => image.onload = resolve);
+ });
+ }
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpOrigin'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-origin destination, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpSameSite'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-site destination, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpCrossSite'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy cross-site destination, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpOrigin'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-origin destination, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpSameSite'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-site destination, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpCrossSite'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy cross-site destination, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpOrigin'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-origin destination, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpSameSite'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-site destination, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpCrossSite'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy cross-site destination, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpOrigin'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-origin destination, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpSameSite'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-site destination, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpCrossSite'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy cross-site destination, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsOrigin', 'httpOrigin'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - HTTPS downgrade (header not sent), no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpOrigin', 'httpsOrigin'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS upgrade, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS downgrade-upgrade, no attributes');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/element-img.https.sub.html b/testing/web-platform/tests/fetch/metadata/generated/element-img.https.sub.html
new file mode 100644
index 0000000000..51d6e082b0
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/element-img.https.sub.html
@@ -0,0 +1,645 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/element-img.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <title>HTTP headers on request for HTML "img" element source</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ function induceRequest(url, sourceAttr, attributes) {
+ const image = document.createElement('img');
+
+ for (const [ name, value ] of Object.entries(attributes)) {
+ image.setAttribute(name, value);
+ }
+
+ return new Promise((resolve) => {
+ image.setAttribute(sourceAttr, url);
+ image.onload = image.onerror = resolve;
+ });
+ }
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin']),
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - src - Same origin, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin']),
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - srcset - Same origin, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite']),
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - src - Cross-site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite']),
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - srcset - Cross-site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite']),
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - src - Same site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite']),
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - srcset - Same site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite', 'httpsOrigin']),
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - src - Same-Origin -> Cross-Site -> Same-Origin redirect, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite', 'httpsOrigin']),
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - srcset - Same-Origin -> Cross-Site -> Same-Origin redirect, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsSameSite', 'httpsOrigin']),
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - src - Same-Origin -> Same-Site -> Same-Origin redirect, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsSameSite', 'httpsOrigin']),
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - srcset - Same-Origin -> Same-Site -> Same-Origin redirect, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsOrigin']),
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - src - Cross-Site -> Same Origin, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsOrigin']),
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - srcset - Cross-Site -> Same Origin, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsSameSite']),
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - src - Cross-Site -> Same-Site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsSameSite']),
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - srcset - Cross-Site -> Same-Site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsCrossSite']),
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - src - Cross-Site -> Cross-Site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsCrossSite']),
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - srcset - Cross-Site -> Cross-Site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsOrigin']),
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - src - Same-Origin -> Same Origin, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsOrigin']),
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - srcset - Same-Origin -> Same Origin, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsSameSite']),
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - src - Same-Origin -> Same-Site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsSameSite']),
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - srcset - Same-Origin -> Same-Site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite']),
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - src - Same-Origin -> Cross-Site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite']),
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - srcset - Same-Origin -> Cross-Site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsOrigin']),
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - src - Same-Site -> Same Origin, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsOrigin']),
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - srcset - Same-Site -> Same Origin, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsSameSite']),
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - src - Same-Site -> Same-Site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsSameSite']),
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - srcset - Same-Site -> Same-Site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsCrossSite']),
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - src - Same-Site -> Cross-Site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsCrossSite']),
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - srcset - Same-Site -> Cross-Site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin']),
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - src - HTTPS downgrade-upgrade, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, []),
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['no-cors']);
+ });
+ }, 'sec-fetch-mode - src - no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, []),
+ 'src',
+ {"crossorigin": ""}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['cors']);
+ });
+ }, 'sec-fetch-mode - src - attributes: crossorigin');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, []),
+ 'src',
+ {"crossorigin": "anonymous"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['cors']);
+ });
+ }, 'sec-fetch-mode - src - attributes: crossorigin=anonymous');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, []),
+ 'src',
+ {"crossorigin": "use-credentials"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['cors']);
+ });
+ }, 'sec-fetch-mode - src - attributes: crossorigin=use-credentials');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, []),
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['no-cors']);
+ });
+ }, 'sec-fetch-mode - srcset - no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, []),
+ 'srcset',
+ {"crossorigin": ""}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['cors']);
+ });
+ }, 'sec-fetch-mode - srcset - attributes: crossorigin');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, []),
+ 'srcset',
+ {"crossorigin": "anonymous"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['cors']);
+ });
+ }, 'sec-fetch-mode - srcset - attributes: crossorigin=anonymous');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, []),
+ 'srcset',
+ {"crossorigin": "use-credentials"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['cors']);
+ });
+ }, 'sec-fetch-mode - srcset - attributes: crossorigin=use-credentials');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, []),
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['image']);
+ });
+ }, 'sec-fetch-dest - src - no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, []),
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['image']);
+ });
+ }, 'sec-fetch-dest - srcset - no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, []),
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - src - no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, []),
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - srcset - no attributes');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/element-img.sub.html b/testing/web-platform/tests/fetch/metadata/generated/element-img.sub.html
new file mode 100644
index 0000000000..5a4b152c55
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/element-img.sub.html
@@ -0,0 +1,456 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/element-img.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <title>HTTP headers on request for HTML "img" element source</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ function induceRequest(url, sourceAttr, attributes) {
+ const image = document.createElement('img');
+
+ for (const [ name, value ] of Object.entries(attributes)) {
+ image.setAttribute(name, value);
+ }
+
+ return new Promise((resolve) => {
+ image.setAttribute(sourceAttr, url);
+ image.onload = image.onerror = resolve;
+ });
+ }
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin']),
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - src - Not sent to non-trustworthy same-origin destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin']),
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - srcset - Not sent to non-trustworthy same-origin destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite']),
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - src - Not sent to non-trustworthy same-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite']),
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - srcset - Not sent to non-trustworthy same-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite']),
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - src - Not sent to non-trustworthy cross-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite']),
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - srcset - Not sent to non-trustworthy cross-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin']),
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - src - Not sent to non-trustworthy same-origin destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin']),
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - srcset - Not sent to non-trustworthy same-origin destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite']),
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - src - Not sent to non-trustworthy same-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite']),
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - srcset - Not sent to non-trustworthy same-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite']),
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - src - Not sent to non-trustworthy cross-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite']),
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - srcset - Not sent to non-trustworthy cross-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin']),
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - src - Not sent to non-trustworthy same-origin destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin']),
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - srcset - Not sent to non-trustworthy same-origin destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite']),
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - src - Not sent to non-trustworthy same-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite']),
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - srcset - Not sent to non-trustworthy same-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite']),
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - src - Not sent to non-trustworthy cross-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite']),
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - srcset - Not sent to non-trustworthy cross-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin']),
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - src - Not sent to non-trustworthy same-origin destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin']),
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - srcset - Not sent to non-trustworthy same-origin destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite']),
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - src - Not sent to non-trustworthy same-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite']),
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - srcset - Not sent to non-trustworthy same-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite']),
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - src - Not sent to non-trustworthy cross-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite']),
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - srcset - Not sent to non-trustworthy cross-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpOrigin']),
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - src - HTTPS downgrade (header not sent), no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpOrigin']),
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - srcset - HTTPS downgrade (header not sent), no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin', 'httpsOrigin']),
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - src - HTTPS upgrade, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin', 'httpsOrigin']),
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - srcset - HTTPS upgrade, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin']),
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - src - HTTPS downgrade-upgrade, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin']),
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - srcset - HTTPS downgrade-upgrade, no attributes');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/element-input-image.https.sub.html b/testing/web-platform/tests/fetch/metadata/generated/element-input-image.https.sub.html
new file mode 100644
index 0000000000..7fa674043e
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/element-input-image.https.sub.html
@@ -0,0 +1,229 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/element-input-image.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <title>HTTP headers on request for HTML "input" element with type="button"</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ function induceRequest(url, test) {
+ const input = document.createElement('input');
+ input.setAttribute('type', 'image');
+
+ document.body.appendChild(input);
+ test.add_cleanup(() => input.remove());
+
+ return new Promise((resolve) => {
+ input.onload = input.onerror = resolve;
+ input.setAttribute('src', url);
+ });
+ }
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(makeRequestURL(key, ['httpsOrigin']), t)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same origin, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(makeRequestURL(key, ['httpsCrossSite']), t)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-site, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(makeRequestURL(key, ['httpsSameSite']), t)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same site, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite', 'httpsOrigin']), t)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(makeRequestURL(key, ['httpsOrigin', 'httpsSameSite', 'httpsOrigin']), t)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(makeRequestURL(key, ['httpsCrossSite', 'httpsOrigin']), t)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same Origin, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(makeRequestURL(key, ['httpsCrossSite', 'httpsSameSite']), t)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same-Site, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(makeRequestURL(key, ['httpsCrossSite', 'httpsCrossSite']), t)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Cross-Site, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(makeRequestURL(key, ['httpsOrigin', 'httpsOrigin']), t)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same Origin, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(makeRequestURL(key, ['httpsOrigin', 'httpsSameSite']), t)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite']), t)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(makeRequestURL(key, ['httpsSameSite', 'httpsOrigin']), t)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same Origin, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(makeRequestURL(key, ['httpsSameSite', 'httpsSameSite']), t)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same-Site, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(makeRequestURL(key, ['httpsSameSite', 'httpsCrossSite']), t)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Cross-Site, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin']), t)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS downgrade-upgrade, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(makeRequestURL(key, []), t)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['no-cors']);
+ });
+ }, 'sec-fetch-mode - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(makeRequestURL(key, []), t)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['image']);
+ });
+ }, 'sec-fetch-dest - no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(makeRequestURL(key, []), t)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - no attributes');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/element-input-image.sub.html b/testing/web-platform/tests/fetch/metadata/generated/element-input-image.sub.html
new file mode 100644
index 0000000000..fb2a146b19
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/element-input-image.sub.html
@@ -0,0 +1,184 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/element-input-image.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <title>HTTP headers on request for HTML "input" element with type="button"</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ function induceRequest(url, test) {
+ const input = document.createElement('input');
+ input.setAttribute('type', 'image');
+
+ document.body.appendChild(input);
+ test.add_cleanup(() => input.remove());
+
+ return new Promise((resolve) => {
+ input.onload = input.onerror = resolve;
+ input.setAttribute('src', url);
+ });
+ }
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(makeRequestURL(key, ['httpOrigin']), t)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-origin destination, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(makeRequestURL(key, ['httpSameSite']), t)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-site destination, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(makeRequestURL(key, ['httpCrossSite']), t)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy cross-site destination, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(makeRequestURL(key, ['httpOrigin']), t)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-origin destination, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(makeRequestURL(key, ['httpSameSite']), t)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-site destination, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(makeRequestURL(key, ['httpCrossSite']), t)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy cross-site destination, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(makeRequestURL(key, ['httpOrigin']), t)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-origin destination, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(makeRequestURL(key, ['httpSameSite']), t)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-site destination, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(makeRequestURL(key, ['httpCrossSite']), t)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy cross-site destination, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(makeRequestURL(key, ['httpOrigin']), t)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-origin destination, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(makeRequestURL(key, ['httpSameSite']), t)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-site destination, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(makeRequestURL(key, ['httpCrossSite']), t)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy cross-site destination, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(makeRequestURL(key, ['httpsOrigin', 'httpOrigin']), t)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - HTTPS downgrade (header not sent), no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(makeRequestURL(key, ['httpOrigin', 'httpsOrigin']), t)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS upgrade, no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin']), t)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS downgrade-upgrade, no attributes');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/element-link-icon.https.sub.html b/testing/web-platform/tests/fetch/metadata/generated/element-link-icon.https.sub.html
new file mode 100644
index 0000000000..b244960755
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/element-link-icon.https.sub.html
@@ -0,0 +1,371 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/element-link-icon.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <meta name="timeout" content="long">
+ <title>HTTP headers on request for HTML "link" element with rel="icon"</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ const params = {
+ body: `
+ <svg xmlns="http://www.w3.org/2000/svg" width="123" height="123">
+ <rect fill="lime" width="123" height="123"/>
+ </svg>
+ `,
+ mime: 'image/svg+xml'
+ };
+
+ /**
+ * The `link` element supports a `load` event. That event would reliably
+ * indicate that the browser had received the request. Multiple major
+ * browsers do not implement the event, however, so in order to promote the
+ * visibility of this test, a less efficient polling-based detection
+ * mechanism is used.
+ *
+ * https://bugzilla.mozilla.org/show_bug.cgi?id=1638188
+ * https://bugs.chromium.org/p/chromium/issues/detail?id=1083034
+ */
+ function induceRequest(t, url, attributes) {
+ const link = document.createElement('link');
+ link.setAttribute('rel', 'icon');
+ link.setAttribute('href', url);
+
+ for (const [ name, value ] of Object.entries(attributes)) {
+ link.setAttribute(name, value);
+ }
+
+ document.head.appendChild(link);
+ t.add_cleanup(() => link.remove());
+ }
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpsOrigin'], params),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same origin no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpsCrossSite'], params),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-site no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpsSameSite'], params),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same site no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite', 'httpsOrigin'], params),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpsOrigin', 'httpsSameSite', 'httpsOrigin'], params),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpsCrossSite', 'httpsOrigin'], params),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same Origin no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpsCrossSite', 'httpsSameSite'], params),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same-Site no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpsCrossSite', 'httpsCrossSite'], params),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Cross-Site no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpsOrigin', 'httpsOrigin'], params),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same Origin no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpsOrigin', 'httpsSameSite'], params),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite'], params),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpsSameSite', 'httpsOrigin'], params),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same Origin no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpsSameSite', 'httpsSameSite'], params),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same-Site no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpsSameSite', 'httpsCrossSite'], params),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Cross-Site no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, [], params),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['no-cors']);
+ });
+ }, 'sec-fetch-mode no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, [], params),
+ {"crossorigin": ""}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['cors']);
+ });
+ }, 'sec-fetch-mode attributes: crossorigin');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, [], params),
+ {"crossorigin": "anonymous"}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['cors']);
+ });
+ }, 'sec-fetch-mode attributes: crossorigin=anonymous');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, [], params),
+ {"crossorigin": "use-credentials"}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['cors']);
+ });
+ }, 'sec-fetch-mode attributes: crossorigin=use-credentials');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, [], params),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['empty']);
+ });
+ }, 'sec-fetch-dest no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, [], params),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user no attributes');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/element-link-icon.sub.html b/testing/web-platform/tests/fetch/metadata/generated/element-link-icon.sub.html
new file mode 100644
index 0000000000..e9226c190a
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/element-link-icon.sub.html
@@ -0,0 +1,279 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/element-link-icon.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <meta name="timeout" content="long">
+ <title>HTTP headers on request for HTML "link" element with rel="icon"</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ const params = {
+ body: `
+ <svg xmlns="http://www.w3.org/2000/svg" width="123" height="123">
+ <rect fill="lime" width="123" height="123"/>
+ </svg>
+ `,
+ mime: 'image/svg+xml'
+ };
+
+ /**
+ * The `link` element supports a `load` event. That event would reliably
+ * indicate that the browser had received the request. Multiple major
+ * browsers do not implement the event, however, so in order to promote the
+ * visibility of this test, a less efficient polling-based detection
+ * mechanism is used.
+ *
+ * https://bugzilla.mozilla.org/show_bug.cgi?id=1638188
+ * https://bugs.chromium.org/p/chromium/issues/detail?id=1083034
+ */
+ function induceRequest(t, url, attributes) {
+ const link = document.createElement('link');
+ link.setAttribute('rel', 'icon');
+ link.setAttribute('href', url);
+
+ for (const [ name, value ] of Object.entries(attributes)) {
+ link.setAttribute(name, value);
+ }
+
+ document.head.appendChild(link);
+ t.add_cleanup(() => link.remove());
+ }
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpOrigin'], params),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-origin destination no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpSameSite'], params),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-site destination no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpCrossSite'], params),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy cross-site destination no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpOrigin'], params),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-origin destination no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpSameSite'], params),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-site destination no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpCrossSite'], params),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy cross-site destination no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpOrigin'], params),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-origin destination no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpSameSite'], params),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-site destination no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpCrossSite'], params),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy cross-site destination no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpOrigin'], params),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-origin destination no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpSameSite'], params),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-site destination no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpCrossSite'], params),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy cross-site destination no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpsOrigin', 'httpOrigin'], params),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - HTTPS downgrade (header not sent) no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpOrigin', 'httpsOrigin'], params),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS upgrade no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin'], params),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS downgrade-upgrade no attributes');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/element-link-prefetch.https.optional.sub.html b/testing/web-platform/tests/fetch/metadata/generated/element-link-prefetch.https.optional.sub.html
new file mode 100644
index 0000000000..bdd684a267
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/element-link-prefetch.https.optional.sub.html
@@ -0,0 +1,559 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/element-link-prefetch.optional.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <meta name="timeout" content="long">
+ <title>HTTP headers on request for HTML "link" element with rel="prefetch"</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ /**
+ * The `link` element supports a `load` event. That event would reliably
+ * indicate that the browser had received the request. Multiple major
+ * browsers do not implement the event, however, so in order to promote the
+ * visibility of this test, a less efficient polling-based detection
+ * mechanism is used.
+ *
+ * https://bugzilla.mozilla.org/show_bug.cgi?id=1638188
+ * https://bugs.chromium.org/p/chromium/issues/detail?id=1083034
+ */
+ function induceRequest(t, url, attributes) {
+ const link = document.createElement('link');
+ link.setAttribute('rel', 'prefetch');
+ link.setAttribute('href', url);
+
+ for (const [ name, value ] of Object.entries(attributes)) {
+ link.setAttribute(name, value);
+ }
+
+ document.head.appendChild(link);
+ t.add_cleanup(() => link.remove());
+ }
+
+ setup(() => {
+ assert_implements_optional(document.createElement('link').relList.supports('prefetch'));
+ });
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpsOrigin']),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same origin no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpsCrossSite']),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-site no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpsSameSite']),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same site no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite', 'httpsOrigin']),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpsOrigin', 'httpsSameSite', 'httpsOrigin']),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpsCrossSite', 'httpsOrigin']),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same Origin no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpsCrossSite', 'httpsSameSite']),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same-Site no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpsCrossSite', 'httpsCrossSite']),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Cross-Site no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpsOrigin', 'httpsOrigin']),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same Origin no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpsOrigin', 'httpsSameSite']),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite']),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpsSameSite', 'httpsOrigin']),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same Origin no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpsSameSite', 'httpsSameSite']),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same-Site no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpsSameSite', 'httpsCrossSite']),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Cross-Site no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, []),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['no-cors']);
+ });
+ }, 'sec-fetch-mode no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, []),
+ {"crossorigin": ""}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['cors']);
+ });
+ }, 'sec-fetch-mode attributes: crossorigin');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, []),
+ {"crossorigin": "anonymous"}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['cors']);
+ });
+ }, 'sec-fetch-mode attributes: crossorigin=anonymous');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, []),
+ {"crossorigin": "use-credentials"}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['cors']);
+ });
+ }, 'sec-fetch-mode attributes: crossorigin=use-credentials');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, []),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['empty']);
+ });
+ }, 'sec-fetch-dest no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, []),
+ {"as": "audio"}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['audio']);
+ });
+ }, 'sec-fetch-dest attributes: as=audio');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, []),
+ {"as": "document"}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['document']);
+ });
+ }, 'sec-fetch-dest attributes: as=document');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, []),
+ {"as": "embed"}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['embed']);
+ });
+ }, 'sec-fetch-dest attributes: as=embed');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, []),
+ {"as": "fetch"}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['fetch']);
+ });
+ }, 'sec-fetch-dest attributes: as=fetch');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, []),
+ {"as": "font"}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['font']);
+ });
+ }, 'sec-fetch-dest attributes: as=font');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, []),
+ {"as": "image"}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['image']);
+ });
+ }, 'sec-fetch-dest attributes: as=image');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, []),
+ {"as": "object"}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['object']);
+ });
+ }, 'sec-fetch-dest attributes: as=object');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, []),
+ {"as": "script"}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['script']);
+ });
+ }, 'sec-fetch-dest attributes: as=script');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, []),
+ {"as": "style"}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['style']);
+ });
+ }, 'sec-fetch-dest attributes: as=style');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, []),
+ {"as": "track"}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['track']);
+ });
+ }, 'sec-fetch-dest attributes: as=track');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, []),
+ {"as": "video"}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['video']);
+ });
+ }, 'sec-fetch-dest attributes: as=video');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, []),
+ {"as": "worker"}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['worker']);
+ });
+ }, 'sec-fetch-dest attributes: as=worker');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, []),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user no attributes');
+ </script>
+ </body>
+</html>
+
diff --git a/testing/web-platform/tests/fetch/metadata/generated/element-link-prefetch.optional.sub.html b/testing/web-platform/tests/fetch/metadata/generated/element-link-prefetch.optional.sub.html
new file mode 100644
index 0000000000..c2244883cc
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/element-link-prefetch.optional.sub.html
@@ -0,0 +1,275 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/element-link-prefetch.optional.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <meta name="timeout" content="long">
+ <title>HTTP headers on request for HTML "link" element with rel="prefetch"</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ /**
+ * The `link` element supports a `load` event. That event would reliably
+ * indicate that the browser had received the request. Multiple major
+ * browsers do not implement the event, however, so in order to promote the
+ * visibility of this test, a less efficient polling-based detection
+ * mechanism is used.
+ *
+ * https://bugzilla.mozilla.org/show_bug.cgi?id=1638188
+ * https://bugs.chromium.org/p/chromium/issues/detail?id=1083034
+ */
+ function induceRequest(t, url, attributes) {
+ const link = document.createElement('link');
+ link.setAttribute('rel', 'prefetch');
+ link.setAttribute('href', url);
+
+ for (const [ name, value ] of Object.entries(attributes)) {
+ link.setAttribute(name, value);
+ }
+
+ document.head.appendChild(link);
+ t.add_cleanup(() => link.remove());
+ }
+
+ setup(() => {
+ assert_implements_optional(document.createElement('link').relList.supports('prefetch'));
+ });
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpOrigin']),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-origin destination no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpSameSite']),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-site destination no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpCrossSite']),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy cross-site destination no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpOrigin']),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-origin destination no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpSameSite']),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-site destination no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpCrossSite']),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy cross-site destination no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpOrigin']),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-origin destination no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpSameSite']),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-site destination no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpCrossSite']),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy cross-site destination no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpOrigin']),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-origin destination no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpSameSite']),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-site destination no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpCrossSite']),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy cross-site destination no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpsOrigin', 'httpOrigin']),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - HTTPS downgrade (header not sent) no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpOrigin', 'httpsOrigin']),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS upgrade no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ induceRequest(
+ t,
+ makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin']),
+ {}
+ );
+
+ return retrieve(key, {poll:true})
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS downgrade-upgrade no attributes');
+ </script>
+ </body>
+</html>
+
diff --git a/testing/web-platform/tests/fetch/metadata/generated/element-meta-refresh.https.optional.sub.html b/testing/web-platform/tests/fetch/metadata/generated/element-meta-refresh.https.optional.sub.html
new file mode 100644
index 0000000000..3a1a8eb49a
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/element-meta-refresh.https.optional.sub.html
@@ -0,0 +1,276 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/element-meta-refresh.optional.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <title>HTTP headers on request for HTML "meta" element with http-equiv="refresh"</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ function induceRequest(url, test) {
+ const win = window.open();
+ test.add_cleanup(() => win.close());
+
+ win.document.open();
+ win.document.write(
+ `<meta http-equiv="Refresh" content="0; URL=${url}">`
+ );
+ win.document.close();
+
+ return new Promise((resolve) => {
+ addEventListener('message', (event) => {
+ if (event.source === win) {
+ resolve();
+ }
+ });
+ });
+ }
+
+ const responseParams = {
+ mime: 'text/html',
+ body: `<script>opener.postMessage(0, '*')</${''}script>`
+ };
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same origin');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite', 'httpsOrigin'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsSameSite', 'httpsOrigin'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsOrigin'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same Origin');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsSameSite'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsCrossSite'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Cross-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsOrigin'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same Origin');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsSameSite'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsOrigin'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same Origin');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsSameSite'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsCrossSite'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Cross-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS downgrade-upgrade');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, [], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['navigate']);
+ });
+ }, 'sec-fetch-mode');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, [], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['document']);
+ });
+ }, 'sec-fetch-dest');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, [], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/element-meta-refresh.optional.sub.html b/testing/web-platform/tests/fetch/metadata/generated/element-meta-refresh.optional.sub.html
new file mode 100644
index 0000000000..df3e92e2c8
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/element-meta-refresh.optional.sub.html
@@ -0,0 +1,225 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/element-meta-refresh.optional.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <title>HTTP headers on request for HTML "meta" element with http-equiv="refresh"</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ function induceRequest(url, test) {
+ const win = window.open();
+ test.add_cleanup(() => win.close());
+
+ win.document.open();
+ win.document.write(
+ `<meta http-equiv="Refresh" content="0; URL=${url}">`
+ );
+ win.document.close();
+
+ return new Promise((resolve) => {
+ addEventListener('message', (event) => {
+ if (event.source === win) {
+ resolve();
+ }
+ });
+ });
+ }
+
+ const responseParams = {
+ mime: 'text/html',
+ body: `<script>opener.postMessage(0, '*')</${''}script>`
+ };
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-origin destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy cross-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-origin destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy cross-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-origin destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy cross-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-origin destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy cross-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpOrigin'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - HTTPS downgrade (header not sent)');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin', 'httpsOrigin'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS upgrade');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS downgrade-upgrade');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/element-picture.https.sub.html b/testing/web-platform/tests/fetch/metadata/generated/element-picture.https.sub.html
new file mode 100644
index 0000000000..ba6636a019
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/element-picture.https.sub.html
@@ -0,0 +1,997 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/element-picture.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <title>HTTP headers on request for HTML "picture" element source</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ function induceRequest(url, sourceEl, sourceAttr, attributes) {
+ const picture = document.createElement('picture');
+ const els = {
+ img: document.createElement('img'),
+ source: document.createElement('source')
+ };
+ picture.appendChild(els.source);
+ picture.appendChild(els.img);
+ document.body.appendChild(picture);
+
+ for (const [ name, value ] of Object.entries(attributes)) {
+ els.img.setAttribute(name, value);
+ }
+
+ return new Promise((resolve) => {
+ els[sourceEl].setAttribute(sourceAttr, url);
+ els.img.onload = els.img.onerror = resolve;
+ });
+ }
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin']),
+ 'img',
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - img[src] - Same origin, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin']),
+ 'img',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - img[srcset] - Same origin, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin']),
+ 'source',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - source[srcset] - Same origin, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite']),
+ 'img',
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - img[src] - Cross-site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite']),
+ 'img',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - img[srcset] - Cross-site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite']),
+ 'source',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - source[srcset] - Cross-site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite']),
+ 'img',
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - img[src] - Same site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite']),
+ 'img',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - img[srcset] - Same site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite']),
+ 'source',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - source[srcset] - Same site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite', 'httpsOrigin']),
+ 'img',
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - img[src] - Same-Origin -> Cross-Site -> Same-Origin redirect, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite', 'httpsOrigin']),
+ 'img',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - img[srcset] - Same-Origin -> Cross-Site -> Same-Origin redirect, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite', 'httpsOrigin']),
+ 'source',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - source[srcset] - Same-Origin -> Cross-Site -> Same-Origin redirect, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsSameSite', 'httpsOrigin']),
+ 'img',
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - img[src] - Same-Origin -> Same-Site -> Same-Origin redirect, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsSameSite', 'httpsOrigin']),
+ 'img',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - img[srcset] - Same-Origin -> Same-Site -> Same-Origin redirect, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsSameSite', 'httpsOrigin']),
+ 'source',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - source[srcset] - Same-Origin -> Same-Site -> Same-Origin redirect, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsOrigin']),
+ 'img',
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - img[src] - Cross-Site -> Same Origin, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsOrigin']),
+ 'img',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - img[srcset] - Cross-Site -> Same Origin, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsOrigin']),
+ 'source',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - source[srcset] - Cross-Site -> Same Origin, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsSameSite']),
+ 'img',
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - img[src] - Cross-Site -> Same-Site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsSameSite']),
+ 'img',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - img[srcset] - Cross-Site -> Same-Site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsSameSite']),
+ 'source',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - source[srcset] - Cross-Site -> Same-Site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsCrossSite']),
+ 'img',
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - img[src] - Cross-Site -> Cross-Site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsCrossSite']),
+ 'img',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - img[srcset] - Cross-Site -> Cross-Site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsCrossSite']),
+ 'source',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - source[srcset] - Cross-Site -> Cross-Site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsOrigin']),
+ 'img',
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - img[src] - Same-Origin -> Same Origin, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsOrigin']),
+ 'img',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - img[srcset] - Same-Origin -> Same Origin, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsOrigin']),
+ 'source',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - source[srcset] - Same-Origin -> Same Origin, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsSameSite']),
+ 'img',
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - img[src] - Same-Origin -> Same-Site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsSameSite']),
+ 'img',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - img[srcset] - Same-Origin -> Same-Site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsSameSite']),
+ 'source',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - source[srcset] - Same-Origin -> Same-Site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite']),
+ 'img',
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - img[src] - Same-Origin -> Cross-Site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite']),
+ 'img',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - img[srcset] - Same-Origin -> Cross-Site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite']),
+ 'source',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - source[srcset] - Same-Origin -> Cross-Site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsOrigin']),
+ 'img',
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - img[src] - Same-Site -> Same Origin, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsOrigin']),
+ 'img',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - img[srcset] - Same-Site -> Same Origin, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsOrigin']),
+ 'source',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - source[srcset] - Same-Site -> Same Origin, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsSameSite']),
+ 'img',
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - img[src] - Same-Site -> Same-Site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsSameSite']),
+ 'img',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - img[srcset] - Same-Site -> Same-Site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsSameSite']),
+ 'source',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - source[srcset] - Same-Site -> Same-Site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsCrossSite']),
+ 'img',
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - img[src] - Same-Site -> Cross-Site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsCrossSite']),
+ 'img',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - img[srcset] - Same-Site -> Cross-Site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsCrossSite']),
+ 'source',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - source[srcset] - Same-Site -> Cross-Site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, []),
+ 'img',
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['no-cors']);
+ });
+ }, 'sec-fetch-mode - img[src] - no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, []),
+ 'img',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['no-cors']);
+ });
+ }, 'sec-fetch-mode - img[srcset] - no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, []),
+ 'source',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['no-cors']);
+ });
+ }, 'sec-fetch-mode - source[srcset] - no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, []),
+ 'img',
+ 'src',
+ {"crossorigin": ""}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['cors']);
+ });
+ }, 'sec-fetch-mode - img[src] - attributes: crossorigin');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, []),
+ 'img',
+ 'srcset',
+ {"crossorigin": ""}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['cors']);
+ });
+ }, 'sec-fetch-mode - img[srcset] - attributes: crossorigin');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, []),
+ 'source',
+ 'srcset',
+ {"crossorigin": ""}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['cors']);
+ });
+ }, 'sec-fetch-mode - source[srcset] - attributes: crossorigin');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, []),
+ 'img',
+ 'src',
+ {"crossorigin": "anonymous"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['cors']);
+ });
+ }, 'sec-fetch-mode - img[src] - attributes: crossorigin=anonymous');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, []),
+ 'img',
+ 'srcset',
+ {"crossorigin": "anonymous"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['cors']);
+ });
+ }, 'sec-fetch-mode - img[srcset] - attributes: crossorigin=anonymous');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, []),
+ 'source',
+ 'srcset',
+ {"crossorigin": "anonymous"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['cors']);
+ });
+ }, 'sec-fetch-mode - source[srcset] - attributes: crossorigin=anonymous');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, []),
+ 'img',
+ 'src',
+ {"crossorigin": "use-credentials"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['cors']);
+ });
+ }, 'sec-fetch-mode - img[src] - attributes: crossorigin=use-credentials');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, []),
+ 'img',
+ 'srcset',
+ {"crossorigin": "use-credentials"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['cors']);
+ });
+ }, 'sec-fetch-mode - img[srcset] - attributes: crossorigin=use-credentials');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, []),
+ 'source',
+ 'srcset',
+ {"crossorigin": "use-credentials"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['cors']);
+ });
+ }, 'sec-fetch-mode - source[srcset] - attributes: crossorigin=use-credentials');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, []),
+ 'img',
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['image']);
+ });
+ }, 'sec-fetch-dest - img[src] - no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, []),
+ 'img',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['image']);
+ });
+ }, 'sec-fetch-dest - img[srcset] - no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, []),
+ 'source',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['image']);
+ });
+ }, 'sec-fetch-dest - source[srcset] - no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, []),
+ 'img',
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - img[src] - no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, []),
+ 'img',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - img[srcset] - no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, []),
+ 'source',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - source[srcset] - no attributes');
+ </script>
+ </body>
+</html>
+
diff --git a/testing/web-platform/tests/fetch/metadata/generated/element-picture.sub.html b/testing/web-platform/tests/fetch/metadata/generated/element-picture.sub.html
new file mode 100644
index 0000000000..64f851c682
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/element-picture.sub.html
@@ -0,0 +1,721 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/element-picture.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <title>HTTP headers on request for HTML "picture" element source</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ function induceRequest(url, sourceEl, sourceAttr, attributes) {
+ const picture = document.createElement('picture');
+ const els = {
+ img: document.createElement('img'),
+ source: document.createElement('source')
+ };
+ picture.appendChild(els.source);
+ picture.appendChild(els.img);
+ document.body.appendChild(picture);
+
+ for (const [ name, value ] of Object.entries(attributes)) {
+ els.img.setAttribute(name, value);
+ }
+
+ return new Promise((resolve) => {
+ els[sourceEl].setAttribute(sourceAttr, url);
+ els.img.onload = els.img.onerror = resolve;
+ });
+ }
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin']),
+ 'img',
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - img[src] - Not sent to non-trustworthy same-origin destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin']),
+ 'img',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - img[srcset] - Not sent to non-trustworthy same-origin destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin']),
+ 'source',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - source[srcset] - Not sent to non-trustworthy same-origin destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite']),
+ 'img',
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - img[src] - Not sent to non-trustworthy same-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite']),
+ 'img',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - img[srcset] - Not sent to non-trustworthy same-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite']),
+ 'source',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - source[srcset] - Not sent to non-trustworthy same-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite']),
+ 'img',
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - img[src] - Not sent to non-trustworthy cross-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite']),
+ 'img',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - img[srcset] - Not sent to non-trustworthy cross-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite']),
+ 'source',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - source[srcset] - Not sent to non-trustworthy cross-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin']),
+ 'img',
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - img[src] - Not sent to non-trustworthy same-origin destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin']),
+ 'img',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - img[srcset] - Not sent to non-trustworthy same-origin destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin']),
+ 'source',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - source[srcset] - Not sent to non-trustworthy same-origin destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite']),
+ 'img',
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - img[src] - Not sent to non-trustworthy same-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite']),
+ 'img',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - img[srcset] - Not sent to non-trustworthy same-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite']),
+ 'source',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - source[srcset] - Not sent to non-trustworthy same-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite']),
+ 'img',
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - img[src] - Not sent to non-trustworthy cross-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite']),
+ 'img',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - img[srcset] - Not sent to non-trustworthy cross-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite']),
+ 'source',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - source[srcset] - Not sent to non-trustworthy cross-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin']),
+ 'img',
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - img[src] - Not sent to non-trustworthy same-origin destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin']),
+ 'img',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - img[srcset] - Not sent to non-trustworthy same-origin destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin']),
+ 'source',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - source[srcset] - Not sent to non-trustworthy same-origin destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite']),
+ 'img',
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - img[src] - Not sent to non-trustworthy same-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite']),
+ 'img',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - img[srcset] - Not sent to non-trustworthy same-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite']),
+ 'source',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - source[srcset] - Not sent to non-trustworthy same-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite']),
+ 'img',
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - img[src] - Not sent to non-trustworthy cross-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite']),
+ 'img',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - img[srcset] - Not sent to non-trustworthy cross-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite']),
+ 'source',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - source[srcset] - Not sent to non-trustworthy cross-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin']),
+ 'img',
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - img[src] - Not sent to non-trustworthy same-origin destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin']),
+ 'img',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - img[srcset] - Not sent to non-trustworthy same-origin destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin']),
+ 'source',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - source[srcset] - Not sent to non-trustworthy same-origin destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite']),
+ 'img',
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - img[src] - Not sent to non-trustworthy same-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite']),
+ 'img',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - img[srcset] - Not sent to non-trustworthy same-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite']),
+ 'source',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - source[srcset] - Not sent to non-trustworthy same-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite']),
+ 'img',
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - img[src] - Not sent to non-trustworthy cross-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite']),
+ 'img',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - img[srcset] - Not sent to non-trustworthy cross-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite']),
+ 'source',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - source[srcset] - Not sent to non-trustworthy cross-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpOrigin']),
+ 'img',
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - img[src] - HTTPS downgrade (header not sent), no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpOrigin']),
+ 'img',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - img[srcset] - HTTPS downgrade (header not sent), no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpOrigin']),
+ 'source',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - source[srcset] - HTTPS downgrade (header not sent), no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin', 'httpsOrigin']),
+ 'img',
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - img[src] - HTTPS upgrade, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin', 'httpsOrigin']),
+ 'img',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - img[srcset] - HTTPS upgrade, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin', 'httpsOrigin']),
+ 'source',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - source[srcset] - HTTPS upgrade, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin']),
+ 'img',
+ 'src',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - img[src] - HTTPS downgrade-upgrade, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin']),
+ 'img',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - img[srcset] - HTTPS downgrade-upgrade, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin']),
+ 'source',
+ 'srcset',
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - source[srcset] - HTTPS downgrade-upgrade, no attributes');
+ </script>
+ </body>
+</html>
+
diff --git a/testing/web-platform/tests/fetch/metadata/generated/element-script.https.sub.html b/testing/web-platform/tests/fetch/metadata/generated/element-script.https.sub.html
new file mode 100644
index 0000000000..dcdcba2792
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/element-script.https.sub.html
@@ -0,0 +1,593 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/element-script.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <title>HTTP headers on request for HTML "script" element source</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ function induceRequest(url, attributes) {
+ const script = document.createElement('script');
+ script.setAttribute('src', url);
+
+ for (const [ name, value ] of Object.entries(attributes)) {
+ script.setAttribute(name, value);
+ }
+
+ return new Promise((resolve, reject) => {
+ script.onload = resolve;
+ script.onerror = () => reject('Failed to load script');
+ document.body.appendChild(script);
+ })
+ .then(() => script.remove());
+ }
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsOrigin'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same origin, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsOrigin'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {"type": "module"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same origin, attributes: type=module');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsCrossSite'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsCrossSite'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {"type": "module"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-site, attributes: type=module');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsSameSite'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsSameSite'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {"type": "module"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same site, attributes: type=module');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsOrigin', 'httpsCrossSite', 'httpsOrigin'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsOrigin', 'httpsCrossSite', 'httpsOrigin'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {"type": "module"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect, attributes: type=module');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsOrigin', 'httpsSameSite', 'httpsOrigin'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsOrigin', 'httpsSameSite', 'httpsOrigin'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {"type": "module"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect, attributes: type=module');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsCrossSite', 'httpsOrigin'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same Origin, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsCrossSite', 'httpsOrigin'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {"type": "module"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same Origin, attributes: type=module');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsCrossSite', 'httpsSameSite'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same-Site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsCrossSite', 'httpsSameSite'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {"type": "module"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same-Site, attributes: type=module');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsCrossSite', 'httpsCrossSite'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Cross-Site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsCrossSite', 'httpsCrossSite'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {"type": "module"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Cross-Site, attributes: type=module');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsOrigin', 'httpsOrigin'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same Origin, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsOrigin', 'httpsOrigin'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {"type": "module"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same Origin, attributes: type=module');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsOrigin', 'httpsSameSite'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsOrigin', 'httpsSameSite'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {"type": "module"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site, attributes: type=module');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsOrigin', 'httpsCrossSite'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsOrigin', 'httpsCrossSite'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {"type": "module"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site, attributes: type=module');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsSameSite', 'httpsOrigin'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same Origin, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsSameSite', 'httpsOrigin'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {"type": "module"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same Origin, attributes: type=module');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsSameSite', 'httpsSameSite'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same-Site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsSameSite', 'httpsSameSite'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {"type": "module"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same-Site, attributes: type=module');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsSameSite', 'httpsCrossSite'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Cross-Site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsSameSite', 'httpsCrossSite'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {"type": "module"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Cross-Site, attributes: type=module');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, [], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['no-cors']);
+ });
+ }, 'sec-fetch-mode - no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, [], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {"type": "module"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['cors']);
+ });
+ }, 'sec-fetch-mode - attributes: type=module');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, [], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {"crossorigin": ""}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['cors']);
+ });
+ }, 'sec-fetch-mode - attributes: crossorigin');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, [], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {"crossorigin": "anonymous"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['cors']);
+ });
+ }, 'sec-fetch-mode - attributes: crossorigin=anonymous');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, [], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {"crossorigin": "use-credentials"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['cors']);
+ });
+ }, 'sec-fetch-mode - attributes: crossorigin=use-credentials');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, [], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['script']);
+ });
+ }, 'sec-fetch-dest - no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, [], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - no attributes');
+ </script>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/element-script.sub.html b/testing/web-platform/tests/fetch/metadata/generated/element-script.sub.html
new file mode 100644
index 0000000000..a2526698fb
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/element-script.sub.html
@@ -0,0 +1,488 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/element-script.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <title>HTTP headers on request for HTML "script" element source</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ function induceRequest(url, attributes) {
+ const script = document.createElement('script');
+ script.setAttribute('src', url);
+
+ for (const [ name, value ] of Object.entries(attributes)) {
+ script.setAttribute(name, value);
+ }
+
+ return new Promise((resolve, reject) => {
+ script.onload = resolve;
+ script.onerror = () => reject('Failed to load script');
+ document.body.appendChild(script);
+ })
+ .then(() => script.remove());
+ }
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpOrigin'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-origin destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpOrigin'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {"type": "module"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-origin destination, attributes: type=module');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpSameSite'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpSameSite'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {"type": "module"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-site destination, attributes: type=module');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpCrossSite'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy cross-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpCrossSite'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {"type": "module"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy cross-site destination, attributes: type=module');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpOrigin'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-origin destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpOrigin'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {"type": "module"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-origin destination, attributes: type=module');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpSameSite'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpSameSite'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {"type": "module"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-site destination, attributes: type=module');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpCrossSite'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy cross-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpCrossSite'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {"type": "module"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy cross-site destination, attributes: type=module');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpOrigin'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-origin destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpOrigin'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {"type": "module"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-origin destination, attributes: type=module');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpSameSite'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpSameSite'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {"type": "module"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-site destination, attributes: type=module');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpCrossSite'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy cross-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpCrossSite'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {"type": "module"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy cross-site destination, attributes: type=module');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpOrigin'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-origin destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpOrigin'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {"type": "module"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-origin destination, attributes: type=module');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpSameSite'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpSameSite'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {"type": "module"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-site destination, attributes: type=module');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpCrossSite'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy cross-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpCrossSite'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {"type": "module"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy cross-site destination, attributes: type=module');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsOrigin', 'httpOrigin'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - HTTPS downgrade (header not sent), no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsOrigin', 'httpOrigin'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {"type": "module"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - HTTPS downgrade (header not sent), attributes: type=module');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpOrigin', 'httpsOrigin'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS upgrade, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpOrigin', 'httpsOrigin'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {"type": "module"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS upgrade, attributes: type=module');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS downgrade-upgrade, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url,
+ {"type": "module"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS downgrade-upgrade, attributes: type=module');
+ </script>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/element-video-poster.https.sub.html b/testing/web-platform/tests/fetch/metadata/generated/element-video-poster.https.sub.html
new file mode 100644
index 0000000000..5805b46bd0
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/element-video-poster.https.sub.html
@@ -0,0 +1,243 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/element-video-poster.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <title>HTTP headers on request for HTML "video" element "poster"</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ const params = {
+ body: `
+ <svg xmlns="http://www.w3.org/2000/svg" width="123" height="123">
+ <rect fill="lime" width="123" height="123"/>
+ </svg>
+ `,
+ mime: 'image/svg+xml'
+ };
+
+ function induceRequest(t, url) {
+ var video = document.createElement('video');
+ video.setAttribute('poster', url);
+ document.body.appendChild(video);
+
+ const poll = () => {
+ if (video.clientWidth === 123) {
+ return;
+ }
+
+ return new Promise((resolve) => t.step_timeout(resolve, 0))
+ .then(poll);
+ };
+ t.add_cleanup(() => video.remove());
+
+ return poll();
+ }
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpsOrigin'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same origin');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpsCrossSite'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpsSameSite'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite', 'httpsOrigin'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpsOrigin', 'httpsSameSite', 'httpsOrigin'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpsCrossSite', 'httpsOrigin'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same Origin');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpsCrossSite', 'httpsSameSite'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpsCrossSite', 'httpsCrossSite'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Cross-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpsOrigin', 'httpsOrigin'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same Origin');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpsOrigin', 'httpsSameSite'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpsSameSite', 'httpsOrigin'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same Origin');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpsSameSite', 'httpsSameSite'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpsSameSite', 'httpsCrossSite'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Cross-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS downgrade-upgrade');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, [], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['no-cors']);
+ });
+ }, 'sec-fetch-mode');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, [], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['image']);
+ });
+ }, 'sec-fetch-dest');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, [], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/element-video-poster.sub.html b/testing/web-platform/tests/fetch/metadata/generated/element-video-poster.sub.html
new file mode 100644
index 0000000000..e6cc5ee7e0
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/element-video-poster.sub.html
@@ -0,0 +1,198 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/element-video-poster.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <title>HTTP headers on request for HTML "video" element "poster"</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ const params = {
+ body: `
+ <svg xmlns="http://www.w3.org/2000/svg" width="123" height="123">
+ <rect fill="lime" width="123" height="123"/>
+ </svg>
+ `,
+ mime: 'image/svg+xml'
+ };
+
+ function induceRequest(t, url) {
+ var video = document.createElement('video');
+ video.setAttribute('poster', url);
+ document.body.appendChild(video);
+
+ const poll = () => {
+ if (video.clientWidth === 123) {
+ return;
+ }
+
+ return new Promise((resolve) => t.step_timeout(resolve, 0))
+ .then(poll);
+ };
+ t.add_cleanup(() => video.remove());
+
+ return poll();
+ }
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpOrigin'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-origin destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpSameSite'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpCrossSite'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy cross-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpOrigin'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-origin destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpSameSite'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpCrossSite'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy cross-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpOrigin'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-origin destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpSameSite'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpCrossSite'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy cross-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpOrigin'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-origin destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpSameSite'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpCrossSite'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy cross-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpsOrigin', 'httpOrigin'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - HTTPS downgrade (header not sent)');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpOrigin', 'httpsOrigin'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS upgrade');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(t, makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin'], params))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS downgrade-upgrade');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/element-video.https.sub.html b/testing/web-platform/tests/fetch/metadata/generated/element-video.https.sub.html
new file mode 100644
index 0000000000..971360dcee
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/element-video.https.sub.html
@@ -0,0 +1,325 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/element-video.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <title>HTTP headers on request for HTML "video" element source</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ function induceRequest(url, attributes) {
+ const video = document.createElement('video');
+
+ for (const [ name, value ] of Object.entries(attributes)) {
+ video.setAttribute(name, value);
+ }
+
+ return new Promise((resolve) => {
+ video.setAttribute('src', url);
+ video.onload = video.onerror = resolve;
+ });
+ }
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same origin, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite', 'httpsOrigin']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsSameSite', 'httpsOrigin']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsOrigin']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same Origin, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsSameSite']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same-Site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsCrossSite']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Cross-Site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsOrigin']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same Origin, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsSameSite']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsOrigin']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same Origin, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsSameSite']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same-Site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsCrossSite']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Cross-Site, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS downgrade-upgrade, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, []),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['no-cors']);
+ });
+ }, 'sec-fetch-mode - no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, []),
+ {"crossorigin": ""}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['cors']);
+ });
+ }, 'sec-fetch-mode - attributes: crossorigin');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, []),
+ {"crossorigin": "anonymous"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['cors']);
+ });
+ }, 'sec-fetch-mode - attributes: crossorigin=anonymous');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, []),
+ {"crossorigin": "use-credentials"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['cors']);
+ });
+ }, 'sec-fetch-mode - attributes: crossorigin=use-credentials');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, []),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['video']);
+ });
+ }, 'sec-fetch-dest - no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, []),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - no attributes');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/element-video.sub.html b/testing/web-platform/tests/fetch/metadata/generated/element-video.sub.html
new file mode 100644
index 0000000000..9707413ab6
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/element-video.sub.html
@@ -0,0 +1,229 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/element-video.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <title>HTTP headers on request for HTML "video" element source</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ function induceRequest(url, attributes) {
+ const video = document.createElement('video');
+
+ for (const [ name, value ] of Object.entries(attributes)) {
+ video.setAttribute(name, value);
+ }
+
+ return new Promise((resolve) => {
+ video.setAttribute('src', url);
+ video.onload = video.onerror = resolve;
+ });
+ }
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-origin destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy cross-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-origin destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy cross-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-origin destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy cross-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-origin destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy cross-site destination, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpOrigin']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - HTTPS downgrade (header not sent), no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin', 'httpsOrigin']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS upgrade, no attributes');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS downgrade-upgrade, no attributes');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/fetch-via-serviceworker.https.sub.html b/testing/web-platform/tests/fetch/metadata/generated/fetch-via-serviceworker.https.sub.html
new file mode 100644
index 0000000000..22f930960d
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/fetch-via-serviceworker.https.sub.html
@@ -0,0 +1,683 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/fetch-via-serviceworker.https.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <meta name="timeout" content="long">
+ <title>HTTP headers on request using the "fetch" API and passing through a Serive Worker</title>
+ <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 src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ const scripts = {
+ fallback: '/fetch/metadata/resources/fetch-via-serviceworker--fallback--sw.js',
+ respondWith: '/fetch/metadata/resources/fetch-via-serviceworker--respondWith--sw.js'
+ };
+
+ function induceRequest(t, url, init, script) {
+ const SCOPE = '/fetch/metadata/resources/fetch-via-serviceworker-frame.html';
+ const SCRIPT = scripts[script];
+
+ return service_worker_unregister_and_register(t, SCRIPT, SCOPE)
+ .then((registration) => {
+ t.add_cleanup(() => registration.unregister());
+
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(() => with_iframe(SCOPE))
+ .then((frame) => {
+ t.add_cleanup(() => frame.remove());
+
+ return frame.contentWindow.fetch(url, init);
+ });
+ }
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsOrigin']),
+ {"mode": "no-cors"},
+ 'respondWith'
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same origin, init: mode=no-cors - respondWith');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsOrigin']),
+ {"mode": "no-cors"},
+ 'fallback'
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same origin, init: mode=no-cors - fallback');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsCrossSite']),
+ {"mode": "no-cors"},
+ 'respondWith'
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-site, init: mode=no-cors - respondWith');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsCrossSite']),
+ {"mode": "no-cors"},
+ 'fallback'
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-site, init: mode=no-cors - fallback');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsSameSite']),
+ {"mode": "no-cors"},
+ 'respondWith'
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same site, init: mode=no-cors - respondWith');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsSameSite']),
+ {"mode": "no-cors"},
+ 'fallback'
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same site, init: mode=no-cors - fallback');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite', 'httpsOrigin']),
+ {"mode": "no-cors"},
+ 'respondWith'
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect, init: mode=no-cors - respondWith');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite', 'httpsOrigin']),
+ {"mode": "no-cors"},
+ 'fallback'
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect, init: mode=no-cors - fallback');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsOrigin', 'httpsSameSite', 'httpsOrigin']),
+ {"mode": "no-cors"},
+ 'respondWith'
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect, init: mode=no-cors - respondWith');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsOrigin', 'httpsSameSite', 'httpsOrigin']),
+ {"mode": "no-cors"},
+ 'fallback'
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect, init: mode=no-cors - fallback');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsCrossSite', 'httpsOrigin']),
+ {"mode": "no-cors"},
+ 'respondWith'
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same Origin, init: mode=no-cors - respondWith');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsCrossSite', 'httpsOrigin']),
+ {"mode": "no-cors"},
+ 'fallback'
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same Origin, init: mode=no-cors - fallback');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsCrossSite', 'httpsSameSite']),
+ {"mode": "no-cors"},
+ 'respondWith'
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same-Site, init: mode=no-cors - respondWith');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsCrossSite', 'httpsSameSite']),
+ {"mode": "no-cors"},
+ 'fallback'
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same-Site, init: mode=no-cors - fallback');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsCrossSite', 'httpsCrossSite']),
+ {"mode": "no-cors"},
+ 'respondWith'
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Cross-Site, init: mode=no-cors - respondWith');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsCrossSite', 'httpsCrossSite']),
+ {"mode": "no-cors"},
+ 'fallback'
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Cross-Site, init: mode=no-cors - fallback');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsOrigin', 'httpsOrigin']),
+ {"mode": "no-cors"},
+ 'respondWith'
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same Origin, init: mode=no-cors - respondWith');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsOrigin', 'httpsOrigin']),
+ {"mode": "no-cors"},
+ 'fallback'
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same Origin, init: mode=no-cors - fallback');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsOrigin', 'httpsSameSite']),
+ {"mode": "no-cors"},
+ 'respondWith'
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site, init: mode=no-cors - respondWith');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsOrigin', 'httpsSameSite']),
+ {"mode": "no-cors"},
+ 'fallback'
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site, init: mode=no-cors - fallback');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite']),
+ {"mode": "no-cors"},
+ 'respondWith'
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site, init: mode=no-cors - respondWith');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite']),
+ {"mode": "no-cors"},
+ 'fallback'
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site, init: mode=no-cors - fallback');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsSameSite', 'httpsOrigin']),
+ {"mode": "no-cors"},
+ 'respondWith'
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same Origin, init: mode=no-cors - respondWith');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsSameSite', 'httpsOrigin']),
+ {"mode": "no-cors"},
+ 'fallback'
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same Origin, init: mode=no-cors - fallback');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsSameSite', 'httpsSameSite']),
+ {"mode": "no-cors"},
+ 'respondWith'
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same-Site, init: mode=no-cors - respondWith');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsSameSite', 'httpsSameSite']),
+ {"mode": "no-cors"},
+ 'fallback'
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same-Site, init: mode=no-cors - fallback');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsSameSite', 'httpsCrossSite']),
+ {"mode": "no-cors"},
+ 'respondWith'
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Cross-Site, init: mode=no-cors - respondWith');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsSameSite', 'httpsCrossSite']),
+ {"mode": "no-cors"},
+ 'fallback'
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Cross-Site, init: mode=no-cors - fallback');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, []),
+ {},
+ 'respondWith'
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['cors']);
+ });
+ }, 'sec-fetch-mode - no init - respondWith');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, []),
+ {},
+ 'fallback'
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['cors']);
+ });
+ }, 'sec-fetch-mode - no init - fallback');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, []),
+ {"mode": "cors"},
+ 'respondWith'
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['cors']);
+ });
+ }, 'sec-fetch-mode - init: mode=cors - respondWith');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, []),
+ {"mode": "cors"},
+ 'fallback'
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['cors']);
+ });
+ }, 'sec-fetch-mode - init: mode=cors - fallback');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, []),
+ {"mode": "no-cors"},
+ 'respondWith'
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['no-cors']);
+ });
+ }, 'sec-fetch-mode - init: mode=no-cors - respondWith');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, []),
+ {"mode": "no-cors"},
+ 'fallback'
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['no-cors']);
+ });
+ }, 'sec-fetch-mode - init: mode=no-cors - fallback');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, []),
+ {"mode": "same-origin"},
+ 'respondWith'
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['same-origin']);
+ });
+ }, 'sec-fetch-mode - init: mode=same-origin - respondWith');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, []),
+ {"mode": "same-origin"},
+ 'fallback'
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['same-origin']);
+ });
+ }, 'sec-fetch-mode - init: mode=same-origin - fallback');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, []),
+ {},
+ 'respondWith'
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['empty']);
+ });
+ }, 'sec-fetch-dest - no init - respondWith');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, []),
+ {},
+ 'fallback'
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['empty']);
+ });
+ }, 'sec-fetch-dest - no init - fallback');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, []),
+ {},
+ 'respondWith'
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - no init - respondWith');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, []),
+ {},
+ 'fallback'
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - no init - fallback');
+
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/fetch.https.sub.html b/testing/web-platform/tests/fetch/metadata/generated/fetch.https.sub.html
new file mode 100644
index 0000000000..dde1daede4
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/fetch.https.sub.html
@@ -0,0 +1,302 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/fetch.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <title>HTTP headers on request using the "fetch" API</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ function induceRequest(url, init) {
+ return fetch(url, init);
+ }
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin']),
+ {"mode": "no-cors"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same origin, init: mode=no-cors');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite']),
+ {"mode": "no-cors"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-site, init: mode=no-cors');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite']),
+ {"mode": "no-cors"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same site, init: mode=no-cors');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite', 'httpsOrigin']),
+ {"mode": "no-cors"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect, init: mode=no-cors');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsSameSite', 'httpsOrigin']),
+ {"mode": "no-cors"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect, init: mode=no-cors');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsOrigin']),
+ {"mode": "no-cors"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same Origin, init: mode=no-cors');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsSameSite']),
+ {"mode": "no-cors"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same-Site, init: mode=no-cors');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsCrossSite']),
+ {"mode": "no-cors"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Cross-Site, init: mode=no-cors');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsOrigin']),
+ {"mode": "no-cors"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same Origin, init: mode=no-cors');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsSameSite']),
+ {"mode": "no-cors"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site, init: mode=no-cors');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite']),
+ {"mode": "no-cors"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site, init: mode=no-cors');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsOrigin']),
+ {"mode": "no-cors"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same Origin, init: mode=no-cors');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsSameSite']),
+ {"mode": "no-cors"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same-Site, init: mode=no-cors');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsCrossSite']),
+ {"mode": "no-cors"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Cross-Site, init: mode=no-cors');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, []),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['cors']);
+ });
+ }, 'sec-fetch-mode - no init');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, []),
+ {"mode": "cors"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['cors']);
+ });
+ }, 'sec-fetch-mode - init: mode=cors');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, []),
+ {"mode": "no-cors"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['no-cors']);
+ });
+ }, 'sec-fetch-mode - init: mode=no-cors');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, []),
+ {"mode": "same-origin"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['same-origin']);
+ });
+ }, 'sec-fetch-mode - init: mode=same-origin');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, []),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['empty']);
+ });
+ }, 'sec-fetch-dest - no init');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, []),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - no init');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/fetch.sub.html b/testing/web-platform/tests/fetch/metadata/generated/fetch.sub.html
new file mode 100644
index 0000000000..d28ea9bb90
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/fetch.sub.html
@@ -0,0 +1,220 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/fetch.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <title>HTTP headers on request using the "fetch" API</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ function induceRequest(url, init) {
+ return fetch(url, init);
+ }
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-origin destination, no init');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-site destination, no init');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy cross-site destination, no init');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-origin destination, no init');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-site destination, no init');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy cross-site destination, no init');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-origin destination, no init');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-site destination, no init');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy cross-site destination, no init');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-origin destination, no init');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-site destination, no init');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy cross-site destination, no init');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpOrigin']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - HTTPS downgrade (header not sent), no init');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin', 'httpsOrigin']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS upgrade, no init');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin']),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS downgrade-upgrade, no init');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/form-submission.https.sub.html b/testing/web-platform/tests/fetch/metadata/generated/form-submission.https.sub.html
new file mode 100644
index 0000000000..988b07c74a
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/form-submission.https.sub.html
@@ -0,0 +1,522 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/form-submission.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <meta name="timeout" content="long">
+ <title>HTTP headers on request for HTML form navigation</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="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ function induceRequest(method, url, userActivated) {
+ const windowName = String(Math.random());
+ const form = document.createElement('form');
+ const submit = document.createElement('input');
+ submit.setAttribute('type', 'submit');
+ form.appendChild(submit);
+ const win = open('about:blank', windowName);
+ form.setAttribute('method', method);
+ form.setAttribute('action', url);
+ form.setAttribute('target', windowName);
+ document.body.appendChild(form);
+
+ // Query parameters must be expressed as form values so that they are sent
+ // with the submission of forms whose method is POST.
+ Array.from(new URL(url, location.origin).searchParams)
+ .forEach(([name, value]) => {
+ const input = document.createElement('input');
+ input.setAttribute('type', 'hidden');
+ input.setAttribute('name', name);
+ input.setAttribute('value', value);
+ form.appendChild(input);
+ });
+
+ return new Promise((resolve) => {
+ addEventListener('message', function(event) {
+ if (event.source === win) {
+ resolve();
+ }
+ });
+
+ if (userActivated) {
+ test_driver.click(submit);
+ } else {
+ submit.click();
+ }
+ })
+ .then(() => {
+ form.remove();
+ win.close();
+ });
+ }
+ const responseParams = {
+ mime: 'text/html',
+ body: `<script>opener.postMessage('done', '*')</${''}script>`
+ };
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin'], responseParams);
+ const userActivated = false;
+ return induceRequest('GET', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same origin - GET');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin'], responseParams);
+ const userActivated = false;
+ return induceRequest('POST', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same origin - POST');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsCrossSite'], responseParams);
+ const userActivated = false;
+ return induceRequest('GET', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-site - GET');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsCrossSite'], responseParams);
+ const userActivated = false;
+ return induceRequest('POST', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-site - POST');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsSameSite'], responseParams);
+ const userActivated = false;
+ return induceRequest('GET', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same site - GET');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsSameSite'], responseParams);
+ const userActivated = false;
+ return induceRequest('POST', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same site - POST');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite', 'httpsOrigin'], responseParams);
+ const userActivated = false;
+ return induceRequest('GET', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect - GET');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite', 'httpsOrigin'], responseParams);
+ const userActivated = false;
+ return induceRequest('POST', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect - POST');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsSameSite', 'httpsOrigin'], responseParams);
+ const userActivated = false;
+ return induceRequest('GET', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect - GET');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsSameSite', 'httpsOrigin'], responseParams);
+ const userActivated = false;
+ return induceRequest('POST', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect - POST');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsCrossSite', 'httpsOrigin'], responseParams);
+ const userActivated = false;
+ return induceRequest('GET', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same Origin - GET');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsCrossSite', 'httpsOrigin'], responseParams);
+ const userActivated = false;
+ return induceRequest('POST', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same Origin - POST');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsCrossSite', 'httpsSameSite'], responseParams);
+ const userActivated = false;
+ return induceRequest('GET', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same-Site - GET');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsCrossSite', 'httpsSameSite'], responseParams);
+ const userActivated = false;
+ return induceRequest('POST', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same-Site - POST');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsCrossSite', 'httpsCrossSite'], responseParams);
+ const userActivated = false;
+ return induceRequest('GET', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Cross-Site - GET');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsCrossSite', 'httpsCrossSite'], responseParams);
+ const userActivated = false;
+ return induceRequest('POST', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Cross-Site - POST');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsOrigin'], responseParams);
+ const userActivated = false;
+ return induceRequest('GET', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same Origin - GET');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsOrigin'], responseParams);
+ const userActivated = false;
+ return induceRequest('POST', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same Origin - POST');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsSameSite'], responseParams);
+ const userActivated = false;
+ return induceRequest('GET', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site - GET');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsSameSite'], responseParams);
+ const userActivated = false;
+ return induceRequest('POST', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site - POST');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite'], responseParams);
+ const userActivated = false;
+ return induceRequest('GET', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site - GET');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite'], responseParams);
+ const userActivated = false;
+ return induceRequest('POST', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site - POST');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsSameSite', 'httpsOrigin'], responseParams);
+ const userActivated = false;
+ return induceRequest('GET', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same Origin - GET');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsSameSite', 'httpsOrigin'], responseParams);
+ const userActivated = false;
+ return induceRequest('POST', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same Origin - POST');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsSameSite', 'httpsSameSite'], responseParams);
+ const userActivated = false;
+ return induceRequest('GET', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same-Site - GET');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsSameSite', 'httpsSameSite'], responseParams);
+ const userActivated = false;
+ return induceRequest('POST', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same-Site - POST');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsSameSite', 'httpsCrossSite'], responseParams);
+ const userActivated = false;
+ return induceRequest('GET', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Cross-Site - GET');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsSameSite', 'httpsCrossSite'], responseParams);
+ const userActivated = false;
+ return induceRequest('POST', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Cross-Site - POST');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin'], responseParams);
+ const userActivated = false;
+ return induceRequest('GET', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS downgrade-upgrade - GET');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin'], responseParams);
+ const userActivated = false;
+ return induceRequest('POST', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS downgrade-upgrade - POST');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, [], responseParams);
+ const userActivated = false;
+ return induceRequest('GET', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['navigate']);
+ });
+ }, 'sec-fetch-mode - GET');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, [], responseParams);
+ const userActivated = false;
+ return induceRequest('POST', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['navigate']);
+ });
+ }, 'sec-fetch-mode - POST');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, [], responseParams);
+ const userActivated = false;
+ return induceRequest('GET', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['document']);
+ });
+ }, 'sec-fetch-dest - GET');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, [], responseParams);
+ const userActivated = false;
+ return induceRequest('POST', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['document']);
+ });
+ }, 'sec-fetch-dest - POST');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, [], responseParams);
+ const userActivated = false;
+ return induceRequest('GET', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - GET');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, [], responseParams);
+ const userActivated = true;
+ return induceRequest('GET', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-user');
+ assert_array_equals(headers['sec-fetch-user'], ['?1']);
+ });
+ }, 'sec-fetch-user - GET with user activation');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, [], responseParams);
+ const userActivated = false;
+ return induceRequest('POST', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - POST');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, [], responseParams);
+ const userActivated = true;
+ return induceRequest('POST', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-user');
+ assert_array_equals(headers['sec-fetch-user'], ['?1']);
+ });
+ }, 'sec-fetch-user - POST with user activation');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/form-submission.sub.html b/testing/web-platform/tests/fetch/metadata/generated/form-submission.sub.html
new file mode 100644
index 0000000000..f862062aeb
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/form-submission.sub.html
@@ -0,0 +1,400 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/form-submission.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <meta name="timeout" content="long">
+ <title>HTTP headers on request for HTML form navigation</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ function induceRequest(method, url, userActivated) {
+ const windowName = String(Math.random());
+ const form = document.createElement('form');
+ const submit = document.createElement('input');
+ submit.setAttribute('type', 'submit');
+ form.appendChild(submit);
+ const win = open('about:blank', windowName);
+ form.setAttribute('method', method);
+ form.setAttribute('action', url);
+ form.setAttribute('target', windowName);
+ document.body.appendChild(form);
+
+ // Query parameters must be expressed as form values so that they are sent
+ // with the submission of forms whose method is POST.
+ Array.from(new URL(url, location.origin).searchParams)
+ .forEach(([name, value]) => {
+ const input = document.createElement('input');
+ input.setAttribute('type', 'hidden');
+ input.setAttribute('name', name);
+ input.setAttribute('value', value);
+ form.appendChild(input);
+ });
+
+ return new Promise((resolve) => {
+ addEventListener('message', function(event) {
+ if (event.source === win) {
+ resolve();
+ }
+ });
+
+ if (userActivated) {
+ test_driver.click(submit);
+ } else {
+ submit.click();
+ }
+ })
+ .then(() => {
+ form.remove();
+ win.close();
+ });
+ }
+ const responseParams = {
+ mime: 'text/html',
+ body: `<script>opener.postMessage('done', '*')</${''}script>`
+ };
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin'], responseParams);
+ const userActivated = false;
+ return induceRequest('GET', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-origin destination - GET');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin'], responseParams);
+ const userActivated = false;
+ return induceRequest('POST', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-origin destination - POST');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite'], responseParams);
+ const userActivated = false;
+ return induceRequest('GET', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-site destination - GET');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite'], responseParams);
+ const userActivated = false;
+ return induceRequest('POST', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-site destination - POST');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite'], responseParams);
+ const userActivated = false;
+ return induceRequest('GET', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy cross-site destination - GET');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite'], responseParams);
+ const userActivated = false;
+ return induceRequest('POST', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy cross-site destination - POST');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin'], responseParams);
+ const userActivated = false;
+ return induceRequest('GET', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-origin destination - GET');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin'], responseParams);
+ const userActivated = false;
+ return induceRequest('POST', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-origin destination - POST');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite'], responseParams);
+ const userActivated = false;
+ return induceRequest('GET', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-site destination - GET');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite'], responseParams);
+ const userActivated = false;
+ return induceRequest('POST', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-site destination - POST');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite'], responseParams);
+ const userActivated = false;
+ return induceRequest('GET', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy cross-site destination - GET');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite'], responseParams);
+ const userActivated = false;
+ return induceRequest('POST', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy cross-site destination - POST');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin'], responseParams);
+ const userActivated = false;
+ return induceRequest('GET', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-origin destination - GET');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin'], responseParams);
+ const userActivated = false;
+ return induceRequest('POST', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-origin destination - POST');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite'], responseParams);
+ const userActivated = false;
+ return induceRequest('GET', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-site destination - GET');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite'], responseParams);
+ const userActivated = false;
+ return induceRequest('POST', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-site destination - POST');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite'], responseParams);
+ const userActivated = false;
+ return induceRequest('GET', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy cross-site destination - GET');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite'], responseParams);
+ const userActivated = false;
+ return induceRequest('POST', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy cross-site destination - POST');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin'], responseParams);
+ const userActivated = false;
+ return induceRequest('GET', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-origin destination - GET');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin'], responseParams);
+ const userActivated = false;
+ return induceRequest('POST', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-origin destination - POST');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite'], responseParams);
+ const userActivated = false;
+ return induceRequest('GET', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-site destination - GET');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite'], responseParams);
+ const userActivated = false;
+ return induceRequest('POST', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-site destination - POST');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite'], responseParams);
+ const userActivated = false;
+ return induceRequest('GET', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy cross-site destination - GET');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite'], responseParams);
+ const userActivated = false;
+ return induceRequest('POST', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy cross-site destination - POST');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpOrigin'], responseParams);
+ const userActivated = false;
+ return induceRequest('GET', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - HTTPS downgrade (header not sent) - GET');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpOrigin'], responseParams);
+ const userActivated = false;
+ return induceRequest('POST', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - HTTPS downgrade (header not sent) - POST');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin', 'httpsOrigin'], responseParams);
+ const userActivated = false;
+ return induceRequest('GET', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS upgrade - GET');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin', 'httpsOrigin'], responseParams);
+ const userActivated = false;
+ return induceRequest('POST', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS upgrade - POST');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin'], responseParams);
+ const userActivated = false;
+ return induceRequest('GET', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS downgrade-upgrade - GET');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin'], responseParams);
+ const userActivated = false;
+ return induceRequest('POST', url, userActivated)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS downgrade-upgrade - POST');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/header-link.https.sub.html b/testing/web-platform/tests/fetch/metadata/generated/header-link.https.sub.html
new file mode 100644
index 0000000000..09f0113895
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/header-link.https.sub.html
@@ -0,0 +1,529 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/header-link.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <title>HTTP headers on request for HTTP "Link" header</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ function induceRequest(url, rel, test) {
+ const iframe = document.createElement('iframe');
+
+ iframe.setAttribute(
+ 'src',
+ '/fetch/metadata/resources/header-link.py' +
+ `?location=${encodeURIComponent(url)}&rel=${rel}`
+ );
+
+ document.body.appendChild(iframe);
+ test.add_cleanup(() => iframe.remove());
+
+ return new Promise((resolve) => {
+ iframe.onload = iframe.onerror = resolve;
+ });
+ }
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin'], {mime: 'text/html'}),
+ 'icon',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site rel=icon - Same origin');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin'], {mime: 'text/html'}),
+ 'stylesheet',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site rel=stylesheet - Same origin');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite'], {mime: 'text/html'}),
+ 'icon',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site rel=icon - Cross-site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite'], {mime: 'text/html'}),
+ 'stylesheet',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site rel=stylesheet - Cross-site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite'], {mime: 'text/html'}),
+ 'icon',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site rel=icon - Same site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite'], {mime: 'text/html'}),
+ 'stylesheet',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site rel=stylesheet - Same site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite', 'httpsOrigin'], {mime: 'text/html'}),
+ 'icon',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site rel=icon - Same-Origin -> Cross-Site -> Same-Origin redirect');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite', 'httpsOrigin'], {mime: 'text/html'}),
+ 'stylesheet',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site rel=stylesheet - Same-Origin -> Cross-Site -> Same-Origin redirect');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsSameSite', 'httpsOrigin'], {mime: 'text/html'}),
+ 'icon',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site rel=icon - Same-Origin -> Same-Site -> Same-Origin redirect');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsSameSite', 'httpsOrigin'], {mime: 'text/html'}),
+ 'stylesheet',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site rel=stylesheet - Same-Origin -> Same-Site -> Same-Origin redirect');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsOrigin'], {mime: 'text/html'}),
+ 'icon',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site rel=icon - Cross-Site -> Same Origin');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsOrigin'], {mime: 'text/html'}),
+ 'stylesheet',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site rel=stylesheet - Cross-Site -> Same Origin');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsSameSite'], {mime: 'text/html'}),
+ 'icon',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site rel=icon - Cross-Site -> Same-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsSameSite'], {mime: 'text/html'}),
+ 'stylesheet',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site rel=stylesheet - Cross-Site -> Same-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsCrossSite'], {mime: 'text/html'}),
+ 'icon',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site rel=icon - Cross-Site -> Cross-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsCrossSite'], {mime: 'text/html'}),
+ 'stylesheet',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site rel=stylesheet - Cross-Site -> Cross-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsOrigin'], {mime: 'text/html'}),
+ 'icon',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site rel=icon - Same-Origin -> Same Origin');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsOrigin'], {mime: 'text/html'}),
+ 'stylesheet',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site rel=stylesheet - Same-Origin -> Same Origin');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsSameSite'], {mime: 'text/html'}),
+ 'icon',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site rel=icon - Same-Origin -> Same-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsSameSite'], {mime: 'text/html'}),
+ 'stylesheet',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site rel=stylesheet - Same-Origin -> Same-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite'], {mime: 'text/html'}),
+ 'icon',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site rel=icon - Same-Origin -> Cross-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite'], {mime: 'text/html'}),
+ 'stylesheet',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site rel=stylesheet - Same-Origin -> Cross-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsOrigin'], {mime: 'text/html'}),
+ 'icon',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site rel=icon - Same-Site -> Same Origin');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsOrigin'], {mime: 'text/html'}),
+ 'stylesheet',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site rel=stylesheet - Same-Site -> Same Origin');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsSameSite'], {mime: 'text/html'}),
+ 'icon',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site rel=icon - Same-Site -> Same-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsSameSite'], {mime: 'text/html'}),
+ 'stylesheet',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site rel=stylesheet - Same-Site -> Same-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsCrossSite'], {mime: 'text/html'}),
+ 'icon',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site rel=icon - Same-Site -> Cross-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsCrossSite'], {mime: 'text/html'}),
+ 'stylesheet',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site rel=stylesheet - Same-Site -> Cross-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, [], {mime: 'text/html'}),
+ 'icon',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['no-cors']);
+ });
+ }, 'sec-fetch-mode rel=icon');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, [], {mime: 'text/html'}),
+ 'stylesheet',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['no-cors']);
+ });
+ }, 'sec-fetch-mode rel=stylesheet');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, [], {mime: 'text/html'}),
+ 'icon',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['empty']);
+ });
+ }, 'sec-fetch-dest rel=icon');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, [], {mime: 'text/html'}),
+ 'icon',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user rel=icon');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, [], {mime: 'text/html'}),
+ 'stylesheet',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user rel=stylesheet');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/header-link.https.sub.tentative.html b/testing/web-platform/tests/fetch/metadata/generated/header-link.https.sub.tentative.html
new file mode 100644
index 0000000000..307c37fbf7
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/header-link.https.sub.tentative.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/header-link.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <title>HTTP headers on request for HTTP "Link" header</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ function induceRequest(url, rel, test) {
+ const iframe = document.createElement('iframe');
+
+ iframe.setAttribute(
+ 'src',
+ '/fetch/metadata/resources/header-link.py' +
+ `?location=${encodeURIComponent(url)}&rel=${rel}`
+ );
+
+ document.body.appendChild(iframe);
+ test.add_cleanup(() => iframe.remove());
+
+ return new Promise((resolve) => {
+ iframe.onload = iframe.onerror = resolve;
+ });
+ }
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, [], {mime: 'text/html'}),
+ 'stylesheet',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['style']);
+ });
+ }, 'sec-fetch-dest rel=stylesheet');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/header-link.sub.html b/testing/web-platform/tests/fetch/metadata/generated/header-link.sub.html
new file mode 100644
index 0000000000..8b6cdae0ed
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/header-link.sub.html
@@ -0,0 +1,460 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/header-link.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <title>HTTP headers on request for HTTP "Link" header</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ function induceRequest(url, rel, test) {
+ const iframe = document.createElement('iframe');
+
+ iframe.setAttribute(
+ 'src',
+ '/fetch/metadata/resources/header-link.py' +
+ `?location=${encodeURIComponent(url)}&rel=${rel}`
+ );
+
+ document.body.appendChild(iframe);
+ test.add_cleanup(() => iframe.remove());
+
+ return new Promise((resolve) => {
+ iframe.onload = iframe.onerror = resolve;
+ });
+ }
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin'], {mime: 'text/html'}),
+ 'icon',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site rel=icon - Not sent to non-trustworthy same-origin destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin'], {mime: 'text/html'}),
+ 'stylesheet',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site rel=stylesheet - Not sent to non-trustworthy same-origin destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite'], {mime: 'text/html'}),
+ 'icon',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site rel=icon - Not sent to non-trustworthy same-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite'], {mime: 'text/html'}),
+ 'stylesheet',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site rel=stylesheet - Not sent to non-trustworthy same-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite'], {mime: 'text/html'}),
+ 'icon',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site rel=icon - Not sent to non-trustworthy cross-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite'], {mime: 'text/html'}),
+ 'stylesheet',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site rel=stylesheet - Not sent to non-trustworthy cross-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin'], {mime: 'text/html'}),
+ 'icon',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode rel=icon - Not sent to non-trustworthy same-origin destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin'], {mime: 'text/html'}),
+ 'stylesheet',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode rel=stylesheet - Not sent to non-trustworthy same-origin destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite'], {mime: 'text/html'}),
+ 'icon',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode rel=icon - Not sent to non-trustworthy same-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite'], {mime: 'text/html'}),
+ 'stylesheet',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode rel=stylesheet - Not sent to non-trustworthy same-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite'], {mime: 'text/html'}),
+ 'icon',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode rel=icon - Not sent to non-trustworthy cross-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite'], {mime: 'text/html'}),
+ 'stylesheet',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode rel=stylesheet - Not sent to non-trustworthy cross-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin'], {mime: 'text/html'}),
+ 'icon',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest rel=icon - Not sent to non-trustworthy same-origin destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin'], {mime: 'text/html'}),
+ 'stylesheet',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest rel=stylesheet - Not sent to non-trustworthy same-origin destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite'], {mime: 'text/html'}),
+ 'icon',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest rel=icon - Not sent to non-trustworthy same-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite'], {mime: 'text/html'}),
+ 'stylesheet',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest rel=stylesheet - Not sent to non-trustworthy same-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite'], {mime: 'text/html'}),
+ 'icon',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest rel=icon - Not sent to non-trustworthy cross-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite'], {mime: 'text/html'}),
+ 'stylesheet',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest rel=stylesheet - Not sent to non-trustworthy cross-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin'], {mime: 'text/html'}),
+ 'icon',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user rel=icon - Not sent to non-trustworthy same-origin destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin'], {mime: 'text/html'}),
+ 'stylesheet',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user rel=stylesheet - Not sent to non-trustworthy same-origin destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite'], {mime: 'text/html'}),
+ 'icon',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user rel=icon - Not sent to non-trustworthy same-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite'], {mime: 'text/html'}),
+ 'stylesheet',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user rel=stylesheet - Not sent to non-trustworthy same-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite'], {mime: 'text/html'}),
+ 'icon',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user rel=icon - Not sent to non-trustworthy cross-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite'], {mime: 'text/html'}),
+ 'stylesheet',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user rel=stylesheet - Not sent to non-trustworthy cross-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpOrigin'], {mime: 'text/html'}),
+ 'icon',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site rel=icon - HTTPS downgrade (header not sent)');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpOrigin'], {mime: 'text/html'}),
+ 'stylesheet',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site rel=stylesheet - HTTPS downgrade (header not sent)');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin', 'httpsOrigin'], {mime: 'text/html'}),
+ 'icon',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site rel=icon - HTTPS upgrade');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin', 'httpsOrigin'], {mime: 'text/html'}),
+ 'stylesheet',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site rel=stylesheet - HTTPS upgrade');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin'], {mime: 'text/html'}),
+ 'icon',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site rel=icon - HTTPS downgrade-upgrade');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin'], {mime: 'text/html'}),
+ 'stylesheet',
+ t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site rel=stylesheet - HTTPS downgrade-upgrade');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/header-refresh.https.optional.sub.html b/testing/web-platform/tests/fetch/metadata/generated/header-refresh.https.optional.sub.html
new file mode 100644
index 0000000000..e63ee423cd
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/header-refresh.https.optional.sub.html
@@ -0,0 +1,273 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/header-refresh.optional.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <meta name="timeout" content="long">
+ <title>HTTP headers on request for HTTP "Refresh" header</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ function induceRequest(url, test) {
+ const win = window.open();
+ test.add_cleanup(() => win.close());
+
+ win.location = `/common/refresh.py?location=${encodeURIComponent(url)}`
+
+ return new Promise((resolve) => {
+ addEventListener('message', (event) => {
+ if (event.source === win) {
+ resolve();
+ }
+ });
+ });
+ }
+
+ const responseParams = {
+ mime: 'text/html',
+ body: `<script>opener.postMessage(0, '*')</${''}script>`
+ };
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same origin');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite', 'httpsOrigin'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsSameSite', 'httpsOrigin'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsOrigin'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same Origin');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsSameSite'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsCrossSite', 'httpsCrossSite'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Cross-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsOrigin'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same Origin');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsSameSite'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsOrigin'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same Origin');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsSameSite'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsSameSite', 'httpsCrossSite'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Cross-Site');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS downgrade-upgrade');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, [], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['navigate']);
+ });
+ }, 'sec-fetch-mode');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, [], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['document']);
+ });
+ }, 'sec-fetch-dest');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, [], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/header-refresh.optional.sub.html b/testing/web-platform/tests/fetch/metadata/generated/header-refresh.optional.sub.html
new file mode 100644
index 0000000000..4674ada9c6
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/header-refresh.optional.sub.html
@@ -0,0 +1,222 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/header-refresh.optional.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <meta name="timeout" content="long">
+ <title>HTTP headers on request for HTTP "Refresh" header</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ function induceRequest(url, test) {
+ const win = window.open();
+ test.add_cleanup(() => win.close());
+
+ win.location = `/common/refresh.py?location=${encodeURIComponent(url)}`
+
+ return new Promise((resolve) => {
+ addEventListener('message', (event) => {
+ if (event.source === win) {
+ resolve();
+ }
+ });
+ });
+ }
+
+ const responseParams = {
+ mime: 'text/html',
+ body: `<script>opener.postMessage(0, '*')</${''}script>`
+ };
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-origin destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy cross-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-origin destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy cross-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-origin destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy cross-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-origin destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpSameSite'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpCrossSite'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy cross-site destination');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpOrigin'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - HTTPS downgrade (header not sent)');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpOrigin', 'httpsOrigin'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS upgrade');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin'], responseParams), t
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS downgrade-upgrade');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/script-module-import-dynamic.https.sub.html b/testing/web-platform/tests/fetch/metadata/generated/script-module-import-dynamic.https.sub.html
new file mode 100644
index 0000000000..72d60fc30c
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/script-module-import-dynamic.https.sub.html
@@ -0,0 +1,254 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/script-module-import-dynamic.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <title>HTTP headers on request for dynamic ECMAScript module import</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <script type="module">
+ 'use strict';
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsOrigin'], { mime: 'application/javascript' }
+ );
+
+ return import(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same origin');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsCrossSite'], { mime: 'application/javascript' }
+ );
+
+ return import(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-site');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsSameSite'], { mime: 'application/javascript' }
+ );
+
+ return import(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same site');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsOrigin', 'httpsCrossSite', 'httpsOrigin'], { mime: 'application/javascript' }
+ );
+
+ return import(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsOrigin', 'httpsSameSite', 'httpsOrigin'], { mime: 'application/javascript' }
+ );
+
+ return import(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsCrossSite', 'httpsOrigin'], { mime: 'application/javascript' }
+ );
+
+ return import(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same Origin');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsCrossSite', 'httpsSameSite'], { mime: 'application/javascript' }
+ );
+
+ return import(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same-Site');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsCrossSite', 'httpsCrossSite'], { mime: 'application/javascript' }
+ );
+
+ return import(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Cross-Site');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsOrigin', 'httpsOrigin'], { mime: 'application/javascript' }
+ );
+
+ return import(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same Origin');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsOrigin', 'httpsSameSite'], { mime: 'application/javascript' }
+ );
+
+ return import(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsOrigin', 'httpsCrossSite'], { mime: 'application/javascript' }
+ );
+
+ return import(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsSameSite', 'httpsOrigin'], { mime: 'application/javascript' }
+ );
+
+ return import(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same Origin');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsSameSite', 'httpsSameSite'], { mime: 'application/javascript' }
+ );
+
+ return import(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same-Site');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsSameSite', 'httpsCrossSite'], { mime: 'application/javascript' }
+ );
+
+ return import(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Cross-Site');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, [], { mime: 'application/javascript' }
+ );
+
+ return import(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['cors']);
+ });
+ }, 'sec-fetch-mode');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, [], { mime: 'application/javascript' }
+ );
+
+ return import(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['script']);
+ });
+ }, 'sec-fetch-dest');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, [], { mime: 'application/javascript' }
+ );
+
+ return import(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user');
+ </script>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/script-module-import-dynamic.sub.html b/testing/web-platform/tests/fetch/metadata/generated/script-module-import-dynamic.sub.html
new file mode 100644
index 0000000000..088720c23e
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/script-module-import-dynamic.sub.html
@@ -0,0 +1,214 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/script-module-import-dynamic.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <title>HTTP headers on request for dynamic ECMAScript module import</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <script type="module">
+ 'use strict';
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpOrigin'], { mime: 'application/javascript' }
+ );
+
+ return import(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-origin destination');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpSameSite'], { mime: 'application/javascript' }
+ );
+
+ return import(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-site destination');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpCrossSite'], { mime: 'application/javascript' }
+ );
+
+ return import(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy cross-site destination');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpOrigin'], { mime: 'application/javascript' }
+ );
+
+ return import(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-origin destination');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpSameSite'], { mime: 'application/javascript' }
+ );
+
+ return import(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-site destination');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpCrossSite'], { mime: 'application/javascript' }
+ );
+
+ return import(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy cross-site destination');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpOrigin'], { mime: 'application/javascript' }
+ );
+
+ return import(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-origin destination');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpSameSite'], { mime: 'application/javascript' }
+ );
+
+ return import(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-site destination');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpCrossSite'], { mime: 'application/javascript' }
+ );
+
+ return import(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy cross-site destination');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpOrigin'], { mime: 'application/javascript' }
+ );
+
+ return import(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-origin destination');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpSameSite'], { mime: 'application/javascript' }
+ );
+
+ return import(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-site destination');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpCrossSite'], { mime: 'application/javascript' }
+ );
+
+ return import(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy cross-site destination');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsOrigin', 'httpOrigin'], { mime: 'application/javascript' }
+ );
+
+ return import(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - HTTPS downgrade (header not sent)');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpOrigin', 'httpsOrigin'], { mime: 'application/javascript' }
+ );
+
+ return import(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS upgrade');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin'], { mime: 'application/javascript' }
+ );
+
+ return import(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS downgrade-upgrade');
+ </script>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/script-module-import-static.https.sub.html b/testing/web-platform/tests/fetch/metadata/generated/script-module-import-static.https.sub.html
new file mode 100644
index 0000000000..cea3464f80
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/script-module-import-static.https.sub.html
@@ -0,0 +1,288 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/script-module-import-static.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <title>HTTP headers on request for static ECMAScript module import</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ function induceRequest(url) {
+ const script = document.createElement('script');
+ script.setAttribute('type', 'module');
+ script.setAttribute(
+ 'src',
+ '/fetch/metadata/resources/es-module.sub.js?moduleId=' + encodeURIComponent(url)
+ );
+
+ return new Promise((resolve, reject) => {
+ script.onload = resolve;
+ script.onerror = () => reject('Failed to load script');
+ document.body.appendChild(script);
+ })
+ .then(() => script.remove());
+ }
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(
+ key, ['httpsOrigin'], { mime: 'application/javascript' }
+ )
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same origin');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(
+ key, ['httpsCrossSite'], { mime: 'application/javascript' }
+ )
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-site');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(
+ key, ['httpsSameSite'], { mime: 'application/javascript' }
+ )
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same site');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(
+ key, ['httpsOrigin', 'httpsCrossSite', 'httpsOrigin'], { mime: 'application/javascript' }
+ )
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(
+ key, ['httpsOrigin', 'httpsSameSite', 'httpsOrigin'], { mime: 'application/javascript' }
+ )
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(
+ key, ['httpsCrossSite', 'httpsOrigin'], { mime: 'application/javascript' }
+ )
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same Origin');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(
+ key, ['httpsCrossSite', 'httpsSameSite'], { mime: 'application/javascript' }
+ )
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same-Site');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(
+ key, ['httpsCrossSite', 'httpsCrossSite'], { mime: 'application/javascript' }
+ )
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Cross-Site');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(
+ key, ['httpsOrigin', 'httpsOrigin'], { mime: 'application/javascript' }
+ )
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same Origin');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(
+ key, ['httpsOrigin', 'httpsSameSite'], { mime: 'application/javascript' }
+ )
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(
+ key, ['httpsOrigin', 'httpsCrossSite'], { mime: 'application/javascript' }
+ )
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(
+ key, ['httpsSameSite', 'httpsOrigin'], { mime: 'application/javascript' }
+ )
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same Origin');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(
+ key, ['httpsSameSite', 'httpsSameSite'], { mime: 'application/javascript' }
+ )
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same-Site');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(
+ key, ['httpsSameSite', 'httpsCrossSite'], { mime: 'application/javascript' }
+ )
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Cross-Site');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(
+ key, [], { mime: 'application/javascript' }
+ )
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['cors']);
+ });
+ }, 'sec-fetch-mode');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(
+ key, [], { mime: 'application/javascript' }
+ )
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['script']);
+ });
+ }, 'sec-fetch-dest');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(
+ key, [], { mime: 'application/javascript' }
+ )
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user');
+ </script>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/script-module-import-static.sub.html b/testing/web-platform/tests/fetch/metadata/generated/script-module-import-static.sub.html
new file mode 100644
index 0000000000..0f94f71cf6
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/script-module-import-static.sub.html
@@ -0,0 +1,246 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/script-module-import-static.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <title>HTTP headers on request for static ECMAScript module import</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ function induceRequest(url) {
+ const script = document.createElement('script');
+ script.setAttribute('type', 'module');
+ script.setAttribute(
+ 'src',
+ '/fetch/metadata/resources/es-module.sub.js?moduleId=' + encodeURIComponent(url)
+ );
+
+ return new Promise((resolve, reject) => {
+ script.onload = resolve;
+ script.onerror = () => reject('Failed to load script');
+ document.body.appendChild(script);
+ })
+ .then(() => script.remove());
+ }
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(
+ key, ['httpOrigin'], { mime: 'application/javascript' }
+ )
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-origin destination');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(
+ key, ['httpSameSite'], { mime: 'application/javascript' }
+ )
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-site destination');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(
+ key, ['httpCrossSite'], { mime: 'application/javascript' }
+ )
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy cross-site destination');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(
+ key, ['httpOrigin'], { mime: 'application/javascript' }
+ )
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-origin destination');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(
+ key, ['httpSameSite'], { mime: 'application/javascript' }
+ )
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-site destination');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(
+ key, ['httpCrossSite'], { mime: 'application/javascript' }
+ )
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy cross-site destination');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(
+ key, ['httpOrigin'], { mime: 'application/javascript' }
+ )
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-origin destination');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(
+ key, ['httpSameSite'], { mime: 'application/javascript' }
+ )
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-site destination');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(
+ key, ['httpCrossSite'], { mime: 'application/javascript' }
+ )
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy cross-site destination');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(
+ key, ['httpOrigin'], { mime: 'application/javascript' }
+ )
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-origin destination');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(
+ key, ['httpSameSite'], { mime: 'application/javascript' }
+ )
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-site destination');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(
+ key, ['httpCrossSite'], { mime: 'application/javascript' }
+ )
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy cross-site destination');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(
+ key, ['httpsOrigin', 'httpOrigin'], { mime: 'application/javascript' }
+ )
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - HTTPS downgrade (header not sent)');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(
+ key, ['httpOrigin', 'httpsOrigin'], { mime: 'application/javascript' }
+ )
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS upgrade');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ makeRequestURL(
+ key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin'], { mime: 'application/javascript' }
+ )
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS downgrade-upgrade');
+ </script>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/serviceworker.https.sub.html b/testing/web-platform/tests/fetch/metadata/generated/serviceworker.https.sub.html
new file mode 100644
index 0000000000..12e37369a4
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/serviceworker.https.sub.html
@@ -0,0 +1,170 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/serviceworker.https.sub.html
+-->
+<!DOCTYPE html>
+<html lang="en">
+ <meta charset="utf-8">
+ <title>HTTP headers on request for Service Workers</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ function induceRequest(t, url, options, event, clear) {
+ // Register a service worker and check the request header.
+ return navigator.serviceWorker.register(url, options)
+ .then((registration) => {
+ t.add_cleanup(() => registration.unregister());
+ if (event === 'register') {
+ return;
+ }
+ return clear().then(() => registration.update());
+ });
+ }
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsOrigin'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(t, url, {}, 'register')
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same origin, no options - registration');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsOrigin'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(t, url, {}, 'update', () => retrieve(key))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same origin, no options - updating');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, [], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(t, url, {"type": "classic"}, 'register')
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['same-origin']);
+ });
+ }, 'sec-fetch-mode - options: type=classic - registration');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, [], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(t, url, {"type": "classic"}, 'update', () => retrieve(key))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['same-origin']);
+ });
+ }, 'sec-fetch-mode - options: type=classic - updating');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, [], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(t, url, {}, 'register')
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['same-origin']);
+ });
+ }, 'sec-fetch-mode - no options - registration');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, [], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(t, url, {}, 'update', () => retrieve(key))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['same-origin']);
+ });
+ }, 'sec-fetch-mode - no options - updating');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, [], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(t, url, {}, 'register')
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['serviceworker']);
+ });
+ }, 'sec-fetch-dest - no options - registration');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, [], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(t, url, {}, 'update', () => retrieve(key))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['serviceworker']);
+ });
+ }, 'sec-fetch-dest - no options - updating');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, [], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(t, url, {}, 'register')
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - no options - registration');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, [], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(t, url, {}, 'update', () => retrieve(key))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - no options - updating');
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/svg-image.https.sub.html b/testing/web-platform/tests/fetch/metadata/generated/svg-image.https.sub.html
new file mode 100644
index 0000000000..b059eb3145
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/svg-image.https.sub.html
@@ -0,0 +1,367 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/svg-image.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <meta name="timeout" content="long">
+ <title>HTTP headers on request for SVG "image" element source</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ const params = {
+ body: `
+ <svg xmlns="http://www.w3.org/2000/svg" width="123" height="123">
+ <rect fill="lime" width="123" height="123"/>
+ </svg>
+ `,
+ mime: 'image/svg+xml'
+ };
+
+ function induceRequest(t, url, attributes) {
+ const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
+ svg.setAttributeNS(
+ "http://www.w3.org/2000/xmlns/",
+ "xmlns:xlink",
+ "http://www.w3.org/1999/xlink"
+ );
+ const image = document.createElementNS("http://www.w3.org/2000/svg", "image");
+ image.setAttribute("href", url);
+ svg.appendChild(image);
+
+ for (const [ name, value ] of Object.entries(attributes)) {
+ image.setAttribute(name, value);
+ }
+
+ document.body.appendChild(svg);
+ t.add_cleanup(() => svg.remove());
+
+ return new Promise((resolve, reject) => {
+ image.onload = resolve;
+ image.onerror = reject;
+ });
+ }
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsOrigin'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same origin no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsCrossSite'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-site no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsSameSite'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same site no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite', 'httpsOrigin'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsOrigin', 'httpsSameSite', 'httpsOrigin'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsCrossSite', 'httpsOrigin'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same Origin no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsCrossSite', 'httpsSameSite'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same-Site no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsCrossSite', 'httpsCrossSite'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Cross-Site no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsOrigin', 'httpsOrigin'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same Origin no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsOrigin', 'httpsSameSite'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsSameSite', 'httpsOrigin'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same Origin no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsSameSite', 'httpsSameSite'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same-Site no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsSameSite', 'httpsCrossSite'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Cross-Site no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS downgrade-upgrade no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, [], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['no-cors']);
+ });
+ }, 'sec-fetch-mode no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, [], params),
+ {"crossorigin": ""}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['cors']);
+ });
+ }, 'sec-fetch-mode attributes: crossorigin');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, [], params),
+ {"crossorigin": "anonymous"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['cors']);
+ });
+ }, 'sec-fetch-mode attributes: crossorigin=anonymous');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, [], params),
+ {"crossorigin": "use-credentials"}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['cors']);
+ });
+ }, 'sec-fetch-mode attributes: crossorigin=use-credentials');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, [], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['empty']);
+ });
+ }, 'sec-fetch-dest no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, [], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user no attributes');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/svg-image.sub.html b/testing/web-platform/tests/fetch/metadata/generated/svg-image.sub.html
new file mode 100644
index 0000000000..a28bbb12eb
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/svg-image.sub.html
@@ -0,0 +1,265 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/svg-image.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <meta name="timeout" content="long">
+ <title>HTTP headers on request for SVG "image" element source</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ const params = {
+ body: `
+ <svg xmlns="http://www.w3.org/2000/svg" width="123" height="123">
+ <rect fill="lime" width="123" height="123"/>
+ </svg>
+ `,
+ mime: 'image/svg+xml'
+ };
+
+ function induceRequest(t, url, attributes) {
+ const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
+ svg.setAttributeNS(
+ "http://www.w3.org/2000/xmlns/",
+ "xmlns:xlink",
+ "http://www.w3.org/1999/xlink"
+ );
+ const image = document.createElementNS("http://www.w3.org/2000/svg", "image");
+ image.setAttribute("href", url);
+ svg.appendChild(image);
+
+ for (const [ name, value ] of Object.entries(attributes)) {
+ image.setAttribute(name, value);
+ }
+
+ document.body.appendChild(svg);
+ t.add_cleanup(() => svg.remove());
+
+ return new Promise((resolve, reject) => {
+ image.onload = resolve;
+ image.onerror = reject;
+ });
+ }
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpOrigin'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-origin destination no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpSameSite'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-site destination no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpCrossSite'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy cross-site destination no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpOrigin'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-origin destination no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpSameSite'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-site destination no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpCrossSite'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy cross-site destination no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpOrigin'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-origin destination no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpSameSite'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-site destination no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpCrossSite'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy cross-site destination no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpOrigin'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-origin destination no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpSameSite'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-site destination no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpCrossSite'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy cross-site destination no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsOrigin', 'httpOrigin'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - HTTPS downgrade (header not sent) no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpOrigin', 'httpsOrigin'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS upgrade no attributes');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+
+ return induceRequest(
+ t,
+ makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin'], params),
+ {}
+ )
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS downgrade-upgrade no attributes');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/window-history.https.sub.html b/testing/web-platform/tests/fetch/metadata/generated/window-history.https.sub.html
new file mode 100644
index 0000000000..c2b3079a6d
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/window-history.https.sub.html
@@ -0,0 +1,237 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/window-history.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <title>HTTP headers on request for navigation via the HTML History API</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ const whenDone = (win) => {
+ return new Promise((resolve) => {
+ addEventListener('message', function handle(event) {
+ if (event.source === win) {
+ resolve();
+ removeEventListener('message', handle);
+ }
+ });
+ })
+ };
+
+ /**
+ * Prime the UA's session history such that the location of the request is
+ * immediately behind the current entry. Because the location may not be
+ * same-origin with the current browsing context, this must be done via a
+ * true navigation and not, e.g. the `history.pushState` API. The initial
+ * navigation will alter the WPT server's internal state; in order to avoid
+ * false positives, clear that state prior to initiating the second
+ * navigation via `history.back`.
+ */
+ function induceBackRequest(url, test, clear) {
+ const win = window.open(url);
+
+ test.add_cleanup(() => win.close());
+
+ return whenDone(win)
+ .then(clear)
+ .then(() => win.history.back())
+ .then(() => whenDone(win));
+ }
+
+ /**
+ * Prime the UA's session history such that the location of the request is
+ * immediately ahead of the current entry. Because the location may not be
+ * same-origin with the current browsing context, this must be done via a
+ * true navigation and not, e.g. the `history.pushState` API. The initial
+ * navigation will alter the WPT server's internal state; in order to avoid
+ * false positives, clear that state prior to initiating the second
+ * navigation via `history.forward`.
+ */
+ function induceForwardRequest(url, test, clear) {
+ const win = window.open(messageOpenerUrl);
+
+ test.add_cleanup(() => win.close());
+
+ return whenDone(win)
+ .then(() => win.location = url)
+ .then(() => whenDone(win))
+ .then(clear)
+ .then(() => win.history.go(-2))
+ .then(() => whenDone(win))
+ .then(() => win.history.forward())
+ .then(() => whenDone(win));
+ }
+
+ const messageOpenerUrl = new URL(
+ '/fetch/metadata/resources/message-opener.html', location
+ );
+ // For these tests to function, replacement must *not* be enabled during
+ // navigation. Assignment must therefore take place after the document has
+ // completely loaded [1]. This event is not directly observable, but it is
+ // scheduled as a task immediately following the global object's `load`
+ // event [2]. By queuing a task during the dispatch of the `load` event,
+ // navigation can be consistently triggered without replacement.
+ //
+ // [1] https://html.spec.whatwg.org/multipage/history.html#location-object-setter-navigate
+ // [2] https://html.spec.whatwg.org/multipage/parsing.html#the-end
+ const responseParams = {
+ mime: 'text/html',
+ body: `<script>
+ window.addEventListener('load', () => {
+ set`+`Timeout(() => location.assign('${messageOpenerUrl}'));
+ });
+ <`+`/script>`
+ };
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin'], responseParams);
+
+ return induceBackRequest(url, t, () => retrieve(key))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same origin - history.back');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin'], responseParams);
+
+ return induceForwardRequest(url, t, () => retrieve(key))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same origin - history.forward');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsCrossSite'], responseParams);
+
+ return induceBackRequest(url, t, () => retrieve(key))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-site - history.back');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsCrossSite'], responseParams);
+
+ return induceForwardRequest(url, t, () => retrieve(key))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-site - history.forward');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsSameSite'], responseParams);
+
+ return induceBackRequest(url, t, () => retrieve(key))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same site - history.back');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsSameSite'], responseParams);
+
+ return induceForwardRequest(url, t, () => retrieve(key))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same site - history.forward');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, [], responseParams);
+
+ return induceBackRequest(url, t, () => retrieve(key))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['navigate']);
+ });
+ }, 'sec-fetch-mode - history.back');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, [], responseParams);
+
+ return induceForwardRequest(url, t, () => retrieve(key))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['navigate']);
+ });
+ }, 'sec-fetch-mode - history.forward');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, [], responseParams);
+
+ return induceBackRequest(url, t, () => retrieve(key))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['document']);
+ });
+ }, 'sec-fetch-dest - history.back');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, [], responseParams);
+
+ return induceForwardRequest(url, t, () => retrieve(key))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['document']);
+ });
+ }, 'sec-fetch-dest - history.forward');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, [], responseParams);
+
+ return induceBackRequest(url, t, () => retrieve(key))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - history.back');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, [], responseParams);
+
+ return induceForwardRequest(url, t, () => retrieve(key))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - history.forward');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/window-history.sub.html b/testing/web-platform/tests/fetch/metadata/generated/window-history.sub.html
new file mode 100644
index 0000000000..333d90c286
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/window-history.sub.html
@@ -0,0 +1,360 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/window-history.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <meta name="timeout" content="long">
+ <title>HTTP headers on request for navigation via the HTML History API</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ const whenDone = (win) => {
+ return new Promise((resolve) => {
+ addEventListener('message', function handle(event) {
+ if (event.source === win) {
+ resolve();
+ removeEventListener('message', handle);
+ }
+ });
+ })
+ };
+
+ /**
+ * Prime the UA's session history such that the location of the request is
+ * immediately behind the current entry. Because the location may not be
+ * same-origin with the current browsing context, this must be done via a
+ * true navigation and not, e.g. the `history.pushState` API. The initial
+ * navigation will alter the WPT server's internal state; in order to avoid
+ * false positives, clear that state prior to initiating the second
+ * navigation via `history.back`.
+ */
+ function induceBackRequest(url, test, clear) {
+ const win = window.open(url);
+
+ test.add_cleanup(() => win.close());
+
+ return whenDone(win)
+ .then(clear)
+ .then(() => win.history.back())
+ .then(() => whenDone(win));
+ }
+
+ /**
+ * Prime the UA's session history such that the location of the request is
+ * immediately ahead of the current entry. Because the location may not be
+ * same-origin with the current browsing context, this must be done via a
+ * true navigation and not, e.g. the `history.pushState` API. The initial
+ * navigation will alter the WPT server's internal state; in order to avoid
+ * false positives, clear that state prior to initiating the second
+ * navigation via `history.forward`.
+ */
+ function induceForwardRequest(url, test, clear) {
+ const win = window.open(messageOpenerUrl);
+
+ test.add_cleanup(() => win.close());
+
+ return whenDone(win)
+ .then(() => win.location = url)
+ .then(() => whenDone(win))
+ .then(clear)
+ .then(() => win.history.go(-2))
+ .then(() => whenDone(win))
+ .then(() => win.history.forward())
+ .then(() => whenDone(win));
+ }
+
+ const messageOpenerUrl = new URL(
+ '/fetch/metadata/resources/message-opener.html', location
+ );
+ // For these tests to function, replacement must *not* be enabled during
+ // navigation. Assignment must therefore take place after the document has
+ // completely loaded [1]. This event is not directly observable, but it is
+ // scheduled as a task immediately following the global object's `load`
+ // event [2]. By queuing a task during the dispatch of the `load` event,
+ // navigation can be consistently triggered without replacement.
+ //
+ // [1] https://html.spec.whatwg.org/multipage/history.html#location-object-setter-navigate
+ // [2] https://html.spec.whatwg.org/multipage/parsing.html#the-end
+ const responseParams = {
+ mime: 'text/html',
+ body: `<script>
+ window.addEventListener('load', () => {
+ set`+`Timeout(() => location.assign('${messageOpenerUrl}'));
+ });
+ <`+`/script>`
+ };
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin'], responseParams);
+
+ return induceBackRequest(url, t, () => retrieve(key))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-origin destination - history.back');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin'], responseParams);
+
+ return induceForwardRequest(url, t, () => retrieve(key))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-origin destination - history.forward');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite'], responseParams);
+
+ return induceBackRequest(url, t, () => retrieve(key))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-site destination - history.back');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite'], responseParams);
+
+ return induceForwardRequest(url, t, () => retrieve(key))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-site destination - history.forward');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite'], responseParams);
+
+ return induceBackRequest(url, t, () => retrieve(key))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy cross-site destination - history.back');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite'], responseParams);
+
+ return induceForwardRequest(url, t, () => retrieve(key))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy cross-site destination - history.forward');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin'], responseParams);
+
+ return induceBackRequest(url, t, () => retrieve(key))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-origin destination - history.back');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin'], responseParams);
+
+ return induceForwardRequest(url, t, () => retrieve(key))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-origin destination - history.forward');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite'], responseParams);
+
+ return induceBackRequest(url, t, () => retrieve(key))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-site destination - history.back');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite'], responseParams);
+
+ return induceForwardRequest(url, t, () => retrieve(key))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-site destination - history.forward');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite'], responseParams);
+
+ return induceBackRequest(url, t, () => retrieve(key))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy cross-site destination - history.back');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite'], responseParams);
+
+ return induceForwardRequest(url, t, () => retrieve(key))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy cross-site destination - history.forward');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin'], responseParams);
+
+ return induceBackRequest(url, t, () => retrieve(key))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-origin destination - history.back');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin'], responseParams);
+
+ return induceForwardRequest(url, t, () => retrieve(key))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-origin destination - history.forward');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite'], responseParams);
+
+ return induceBackRequest(url, t, () => retrieve(key))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-site destination - history.back');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite'], responseParams);
+
+ return induceForwardRequest(url, t, () => retrieve(key))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-site destination - history.forward');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite'], responseParams);
+
+ return induceBackRequest(url, t, () => retrieve(key))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy cross-site destination - history.back');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite'], responseParams);
+
+ return induceForwardRequest(url, t, () => retrieve(key))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy cross-site destination - history.forward');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin'], responseParams);
+
+ return induceBackRequest(url, t, () => retrieve(key))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-origin destination - history.back');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin'], responseParams);
+
+ return induceForwardRequest(url, t, () => retrieve(key))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-origin destination - history.forward');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite'], responseParams);
+
+ return induceBackRequest(url, t, () => retrieve(key))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-site destination - history.back');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite'], responseParams);
+
+ return induceForwardRequest(url, t, () => retrieve(key))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-site destination - history.forward');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite'], responseParams);
+
+ return induceBackRequest(url, t, () => retrieve(key))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy cross-site destination - history.back');
+
+ promise_test((t) => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite'], responseParams);
+
+ return induceForwardRequest(url, t, () => retrieve(key))
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy cross-site destination - history.forward');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/window-location.https.sub.html b/testing/web-platform/tests/fetch/metadata/generated/window-location.https.sub.html
new file mode 100644
index 0000000000..4a0d2fdc06
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/window-location.https.sub.html
@@ -0,0 +1,1184 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/window-location.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <meta name="timeout" content="long">
+ <title>HTTP headers on request for navigation via the HTML Location API</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="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ function induceRequest(url, navigate, userActivated) {
+ const win = window.open();
+
+ return new Promise((resolve) => {
+ addEventListener('message', function(event) {
+ if (event.source === win) {
+ resolve();
+ }
+ });
+
+ if (userActivated) {
+ test_driver.bless('enable user activation', () => {
+ navigate(win, url);
+ });
+ } else {
+ navigate(win, url);
+ }
+ })
+ .then(() => win.close());
+ }
+
+ const responseParams = {
+ mime: 'text/html',
+ body: `<script>opener.postMessage('done', '*')</${''}script>`
+ };
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same origin - location');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.href = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same origin - location.href');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.assign(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same origin - location.assign');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.replace(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same origin - location.replace');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsCrossSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-site - location');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsCrossSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.href = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-site - location.href');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsCrossSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.assign(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-site - location.assign');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsCrossSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.replace(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-site - location.replace');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsSameSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same site - location');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsSameSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.href = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same site - location.href');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsSameSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.assign(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same site - location.assign');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsSameSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.replace(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same site - location.replace');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite', 'httpsOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect - location');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite', 'httpsOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.href = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect - location.href');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite', 'httpsOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.assign(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect - location.assign');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite', 'httpsOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.replace(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect - location.replace');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsSameSite', 'httpsOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect - location');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsSameSite', 'httpsOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.href = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect - location.href');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsSameSite', 'httpsOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.assign(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect - location.assign');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsSameSite', 'httpsOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.replace(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect - location.replace');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsCrossSite', 'httpsOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same Origin - location');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsCrossSite', 'httpsOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.href = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same Origin - location.href');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsCrossSite', 'httpsOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.assign(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same Origin - location.assign');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsCrossSite', 'httpsOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.replace(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same Origin - location.replace');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsCrossSite', 'httpsSameSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same-Site - location');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsCrossSite', 'httpsSameSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.href = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same-Site - location.href');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsCrossSite', 'httpsSameSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.assign(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same-Site - location.assign');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsCrossSite', 'httpsSameSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.replace(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same-Site - location.replace');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsCrossSite', 'httpsCrossSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Cross-Site - location');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsCrossSite', 'httpsCrossSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.href = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Cross-Site - location.href');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsCrossSite', 'httpsCrossSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.assign(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Cross-Site - location.assign');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsCrossSite', 'httpsCrossSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.replace(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Cross-Site - location.replace');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same Origin - location');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.href = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same Origin - location.href');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.assign(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same Origin - location.assign');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.replace(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same Origin - location.replace');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsSameSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site - location');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsSameSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.href = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site - location.href');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsSameSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.assign(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site - location.assign');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsSameSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.replace(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site - location.replace');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site - location');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.href = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site - location.href');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.assign(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site - location.assign');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpsCrossSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.replace(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site - location.replace');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsSameSite', 'httpsOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same Origin - location');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsSameSite', 'httpsOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.href = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same Origin - location.href');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsSameSite', 'httpsOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.assign(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same Origin - location.assign');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsSameSite', 'httpsOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.replace(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same Origin - location.replace');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsSameSite', 'httpsSameSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same-Site - location');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsSameSite', 'httpsSameSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.href = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same-Site - location.href');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsSameSite', 'httpsSameSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.assign(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same-Site - location.assign');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsSameSite', 'httpsSameSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.replace(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same-Site - location.replace');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsSameSite', 'httpsCrossSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Cross-Site - location');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsSameSite', 'httpsCrossSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.href = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Cross-Site - location.href');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsSameSite', 'httpsCrossSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.assign(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Cross-Site - location.assign');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsSameSite', 'httpsCrossSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.replace(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Cross-Site - location.replace');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS downgrade-upgrade - location');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.href = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS downgrade-upgrade - location.href');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.assign(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS downgrade-upgrade - location.assign');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.replace(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS downgrade-upgrade - location.replace');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, [], responseParams);
+
+ const navigate = (win, path) => {
+ win.location = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['navigate']);
+ });
+ }, 'sec-fetch-mode - location');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, [], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.href = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['navigate']);
+ });
+ }, 'sec-fetch-mode - location.href');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, [], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.assign(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['navigate']);
+ });
+ }, 'sec-fetch-mode - location.assign');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, [], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.replace(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['navigate']);
+ });
+ }, 'sec-fetch-mode - location.replace');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, [], responseParams);
+
+ const navigate = (win, path) => {
+ win.location = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['document']);
+ });
+ }, 'sec-fetch-dest - location');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, [], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.href = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['document']);
+ });
+ }, 'sec-fetch-dest - location.href');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, [], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.assign(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['document']);
+ });
+ }, 'sec-fetch-dest - location.assign');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, [], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.replace(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['document']);
+ });
+ }, 'sec-fetch-dest - location.replace');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, [], responseParams);
+
+ const navigate = (win, path) => {
+ win.location = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - location');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, [], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.href = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - location.href');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, [], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.assign(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - location.assign');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, [], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.replace(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - location.replace');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, [], responseParams);
+
+ const navigate = (win, path) => {
+ win.location = path;
+ };
+ return induceRequest(url, navigate, true)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-user');
+ assert_array_equals(headers['sec-fetch-user'], ['?1']);
+ });
+ }, 'sec-fetch-user - location with user activation');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, [], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.href = path;
+ };
+ return induceRequest(url, navigate, true)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-user');
+ assert_array_equals(headers['sec-fetch-user'], ['?1']);
+ });
+ }, 'sec-fetch-user - location.href with user activation');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, [], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.assign(path);
+ };
+ return induceRequest(url, navigate, true)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-user');
+ assert_array_equals(headers['sec-fetch-user'], ['?1']);
+ });
+ }, 'sec-fetch-user - location.assign with user activation');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, [], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.replace(path);
+ };
+ return induceRequest(url, navigate, true)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-user');
+ assert_array_equals(headers['sec-fetch-user'], ['?1']);
+ });
+ }, 'sec-fetch-user - location.replace with user activation');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/window-location.sub.html b/testing/web-platform/tests/fetch/metadata/generated/window-location.sub.html
new file mode 100644
index 0000000000..bb3e6805cb
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/window-location.sub.html
@@ -0,0 +1,894 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/window-location.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <meta name="timeout" content="long">
+ <title>HTTP headers on request for navigation via the HTML Location API</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <body>
+ <script>
+ 'use strict';
+
+ function induceRequest(url, navigate, userActivated) {
+ const win = window.open();
+
+ return new Promise((resolve) => {
+ addEventListener('message', function(event) {
+ if (event.source === win) {
+ resolve();
+ }
+ });
+
+ if (userActivated) {
+ test_driver.bless('enable user activation', () => {
+ navigate(win, url);
+ });
+ } else {
+ navigate(win, url);
+ }
+ })
+ .then(() => win.close());
+ }
+
+ const responseParams = {
+ mime: 'text/html',
+ body: `<script>opener.postMessage('done', '*')</${''}script>`
+ };
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-origin destination - location');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.href = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-origin destination - location.href');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.assign(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-origin destination - location.assign');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.replace(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-origin destination - location.replace');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-site destination - location');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.href = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-site destination - location.href');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.assign(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-site destination - location.assign');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.replace(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-site destination - location.replace');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy cross-site destination - location');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.href = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy cross-site destination - location.href');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.assign(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy cross-site destination - location.assign');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.replace(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy cross-site destination - location.replace');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-origin destination - location');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.href = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-origin destination - location.href');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.assign(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-origin destination - location.assign');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.replace(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-origin destination - location.replace');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-site destination - location');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.href = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-site destination - location.href');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.assign(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-site destination - location.assign');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.replace(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-site destination - location.replace');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy cross-site destination - location');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.href = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy cross-site destination - location.href');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.assign(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy cross-site destination - location.assign');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.replace(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy cross-site destination - location.replace');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-origin destination - location');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.href = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-origin destination - location.href');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.assign(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-origin destination - location.assign');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.replace(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-origin destination - location.replace');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-site destination - location');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.href = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-site destination - location.href');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.assign(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-site destination - location.assign');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.replace(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-site destination - location.replace');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy cross-site destination - location');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.href = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy cross-site destination - location.href');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.assign(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy cross-site destination - location.assign');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.replace(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy cross-site destination - location.replace');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-origin destination - location');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.href = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-origin destination - location.href');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.assign(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-origin destination - location.assign');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.replace(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-origin destination - location.replace');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-site destination - location');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.href = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-site destination - location.href');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.assign(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-site destination - location.assign');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpSameSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.replace(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-site destination - location.replace');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy cross-site destination - location');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.href = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy cross-site destination - location.href');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.assign(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy cross-site destination - location.assign');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpCrossSite'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.replace(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy cross-site destination - location.replace');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - HTTPS downgrade (header not sent) - location');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.href = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - HTTPS downgrade (header not sent) - location.href');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.assign(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - HTTPS downgrade (header not sent) - location.assign');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.replace(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - HTTPS downgrade (header not sent) - location.replace');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin', 'httpsOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS upgrade - location');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin', 'httpsOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.href = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS upgrade - location.href');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin', 'httpsOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.assign(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS upgrade - location.assign');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpOrigin', 'httpsOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.replace(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS upgrade - location.replace');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS downgrade-upgrade - location');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.href = path;
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS downgrade-upgrade - location.href');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.assign(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS downgrade-upgrade - location.assign');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin'], responseParams);
+
+ const navigate = (win, path) => {
+ win.location.replace(path);
+ };
+ return induceRequest(url, navigate, false)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS downgrade-upgrade - location.replace');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/worker-dedicated-constructor.https.sub.html b/testing/web-platform/tests/fetch/metadata/generated/worker-dedicated-constructor.https.sub.html
new file mode 100644
index 0000000000..86f1760755
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/worker-dedicated-constructor.https.sub.html
@@ -0,0 +1,118 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/worker-dedicated-constructor.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <title>HTTP headers on request for dedicated worker via the "Worker" constructor</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <script type="module">
+ 'use strict';
+ function induceRequest(url, options) {
+ return new Promise((resolve, reject) => {
+ const worker = new Worker(url, options);
+ worker.onmessage = resolve;
+ worker.onerror = reject;
+ });
+ }
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key,
+ [],
+ { mime: 'application/javascript', body: 'postMessage("")' }
+ );
+
+ return induceRequest(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['same-origin']);
+ });
+ }, 'sec-fetch-mode - no options');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key,
+ [],
+ { mime: 'application/javascript', body: 'postMessage("")' }
+ );
+
+ return induceRequest(url, {"type": "module"})
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['same-origin']);
+ });
+ }, 'sec-fetch-mode - options: type=module');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key,
+ [],
+ { mime: 'application/javascript', body: 'postMessage("")' }
+ );
+
+ return induceRequest(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['worker']);
+ });
+ }, 'sec-fetch-dest - no options');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key,
+ [],
+ { mime: 'application/javascript', body: 'postMessage("")' }
+ );
+
+ return induceRequest(url, {"type": "module"})
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['worker']);
+ });
+ }, 'sec-fetch-dest - options: type=module');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key,
+ [],
+ { mime: 'application/javascript', body: 'postMessage("")' }
+ );
+
+ return induceRequest(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - no options');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key,
+ [],
+ { mime: 'application/javascript', body: 'postMessage("")' }
+ );
+
+ return induceRequest(url, {"type": "module"})
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - options: type=module');
+ </script>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/worker-dedicated-constructor.sub.html b/testing/web-platform/tests/fetch/metadata/generated/worker-dedicated-constructor.sub.html
new file mode 100644
index 0000000000..69ac7682a5
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/worker-dedicated-constructor.sub.html
@@ -0,0 +1,204 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/worker-dedicated-constructor.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <title>HTTP headers on request for dedicated worker via the "Worker" constructor</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <script type="module">
+ 'use strict';
+ function induceRequest(url, options) {
+ return new Promise((resolve, reject) => {
+ const worker = new Worker(url, options);
+ worker.onmessage = resolve;
+ worker.onerror = reject;
+ });
+ }
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key,
+ ['httpOrigin'],
+ { mime: 'application/javascript', body: 'postMessage("")' }
+ );
+
+ return induceRequest(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-origin destination, no options');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key,
+ ['httpSameSite'],
+ { mime: 'application/javascript', body: 'postMessage("")' }
+ );
+
+ return induceRequest(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-site destination, no options');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key,
+ ['httpCrossSite'],
+ { mime: 'application/javascript', body: 'postMessage("")' }
+ );
+
+ return induceRequest(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy cross-site destination, no options');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key,
+ ['httpOrigin'],
+ { mime: 'application/javascript', body: 'postMessage("")' }
+ );
+
+ return induceRequest(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-origin destination, no options');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key,
+ ['httpSameSite'],
+ { mime: 'application/javascript', body: 'postMessage("")' }
+ );
+
+ return induceRequest(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-site destination, no options');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key,
+ ['httpCrossSite'],
+ { mime: 'application/javascript', body: 'postMessage("")' }
+ );
+
+ return induceRequest(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy cross-site destination, no options');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key,
+ ['httpOrigin'],
+ { mime: 'application/javascript', body: 'postMessage("")' }
+ );
+
+ return induceRequest(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-origin destination, no options');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key,
+ ['httpSameSite'],
+ { mime: 'application/javascript', body: 'postMessage("")' }
+ );
+
+ return induceRequest(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-site destination, no options');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key,
+ ['httpCrossSite'],
+ { mime: 'application/javascript', body: 'postMessage("")' }
+ );
+
+ return induceRequest(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy cross-site destination, no options');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key,
+ ['httpOrigin'],
+ { mime: 'application/javascript', body: 'postMessage("")' }
+ );
+
+ return induceRequest(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-origin destination, no options');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key,
+ ['httpSameSite'],
+ { mime: 'application/javascript', body: 'postMessage("")' }
+ );
+
+ return induceRequest(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-site destination, no options');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key,
+ ['httpCrossSite'],
+ { mime: 'application/javascript', body: 'postMessage("")' }
+ );
+
+ return induceRequest(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy cross-site destination, no options');
+ </script>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/worker-dedicated-importscripts.https.sub.html b/testing/web-platform/tests/fetch/metadata/generated/worker-dedicated-importscripts.https.sub.html
new file mode 100644
index 0000000000..0cd9f35d58
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/worker-dedicated-importscripts.https.sub.html
@@ -0,0 +1,268 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/worker-dedicated-importscripts.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <title>HTTP headers on request for dedicated worker via the "importScripts" API</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <script type="module">
+ 'use strict';
+ function induceRequest(url, options) {
+ const src = `
+ importScripts('${url}');
+ postMessage('done');
+ `;
+ const workerUrl = URL.createObjectURL(
+ new Blob([src], { type: 'application/javascript' })
+ );
+ return new Promise((resolve, reject) => {
+ const worker = new Worker(workerUrl, options);
+ worker.onmessage = resolve;
+ worker.onerror = reject;
+ });
+ }
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsOrigin'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same origin');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsCrossSite'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-site');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsSameSite'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same site');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsOrigin', 'httpsCrossSite', 'httpsOrigin'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsOrigin', 'httpsSameSite', 'httpsOrigin'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsCrossSite', 'httpsOrigin'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same Origin');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsCrossSite', 'httpsSameSite'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Same-Site');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsCrossSite', 'httpsCrossSite'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Cross-Site -> Cross-Site');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsOrigin', 'httpsOrigin'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-origin']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same Origin');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsOrigin', 'httpsSameSite'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Same-Site');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsOrigin', 'httpsCrossSite'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Origin -> Cross-Site');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsSameSite', 'httpsOrigin'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same Origin');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsSameSite', 'httpsSameSite'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['same-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Same-Site');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsSameSite', 'httpsCrossSite'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - Same-Site -> Cross-Site');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, [], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-mode');
+ assert_array_equals(headers['sec-fetch-mode'], ['no-cors']);
+ });
+ }, 'sec-fetch-mode');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, [], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-dest');
+ assert_array_equals(headers['sec-fetch-dest'], ['script']);
+ });
+ }, 'sec-fetch-dest');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, [], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user');
+ </script>
+</html>
diff --git a/testing/web-platform/tests/fetch/metadata/generated/worker-dedicated-importscripts.sub.html b/testing/web-platform/tests/fetch/metadata/generated/worker-dedicated-importscripts.sub.html
new file mode 100644
index 0000000000..0555bbaf43
--- /dev/null
+++ b/testing/web-platform/tests/fetch/metadata/generated/worker-dedicated-importscripts.sub.html
@@ -0,0 +1,228 @@
+<!DOCTYPE html>
+<!--
+This test was procedurally generated. Please do not modify it directly.
+Sources:
+- fetch/metadata/tools/fetch-metadata.conf.yml
+- fetch/metadata/tools/templates/worker-dedicated-importscripts.sub.html
+-->
+<html lang="en">
+ <meta charset="utf-8">
+ <title>HTTP headers on request for dedicated worker via the "importScripts" API</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/fetch/metadata/resources/helper.sub.js"></script>
+ <script type="module">
+ 'use strict';
+ function induceRequest(url, options) {
+ const src = `
+ importScripts('${url}');
+ postMessage('done');
+ `;
+ const workerUrl = URL.createObjectURL(
+ new Blob([src], { type: 'application/javascript' })
+ );
+ return new Promise((resolve, reject) => {
+ const worker = new Worker(workerUrl, options);
+ worker.onmessage = resolve;
+ worker.onerror = reject;
+ });
+ }
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpOrigin'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-origin destination');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpSameSite'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy same-site destination');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpCrossSite'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - Not sent to non-trustworthy cross-site destination');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpOrigin'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-origin destination');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpSameSite'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy same-site destination');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpCrossSite'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-mode');
+ });
+ }, 'sec-fetch-mode - Not sent to non-trustworthy cross-site destination');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpOrigin'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-origin destination');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpSameSite'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy same-site destination');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpCrossSite'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-dest');
+ });
+ }, 'sec-fetch-dest - Not sent to non-trustworthy cross-site destination');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpOrigin'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-origin destination');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpSameSite'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy same-site destination');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpCrossSite'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-user');
+ });
+ }, 'sec-fetch-user - Not sent to non-trustworthy cross-site destination');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsOrigin', 'httpOrigin'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_not_own_property(headers, 'sec-fetch-site');
+ });
+ }, 'sec-fetch-site - HTTPS downgrade (header not sent)');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpOrigin', 'httpsOrigin'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS upgrade');
+
+ promise_test(() => {
+ const key = '{{uuid()}}';
+ const url = makeRequestURL(
+ key, ['httpsOrigin', 'httpOrigin', 'httpsOrigin'], { mime: 'application/javascript' }
+ );
+
+ return induceRequest(url)
+ .then(() => retrieve(key))
+ .then((headers) => {
+ assert_own_property(headers, 'sec-fetch-site');
+ assert_array_equals(headers['sec-fetch-site'], ['cross-site']);
+ });
+ }, 'sec-fetch-site - HTTPS downgrade-upgrade');
+ </script>
+</html>