summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/fetch/api/request/destination
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/fetch/api/request/destination')
-rw-r--r--testing/web-platform/tests/fetch/api/request/destination/fetch-destination-frame.https.html51
-rw-r--r--testing/web-platform/tests/fetch/api/request/destination/fetch-destination-iframe.https.html51
-rw-r--r--testing/web-platform/tests/fetch/api/request/destination/fetch-destination-no-load-event.https.html124
-rw-r--r--testing/web-platform/tests/fetch/api/request/destination/fetch-destination-prefetch.https.html46
-rw-r--r--testing/web-platform/tests/fetch/api/request/destination/fetch-destination-worker.https.html60
-rw-r--r--testing/web-platform/tests/fetch/api/request/destination/fetch-destination.https.html485
-rw-r--r--testing/web-platform/tests/fetch/api/request/destination/resources/dummy0
-rw-r--r--testing/web-platform/tests/fetch/api/request/destination/resources/dummy.css0
-rw-r--r--testing/web-platform/tests/fetch/api/request/destination/resources/dummy.es0
-rw-r--r--testing/web-platform/tests/fetch/api/request/destination/resources/dummy.es.headers1
-rw-r--r--testing/web-platform/tests/fetch/api/request/destination/resources/dummy.html0
-rw-r--r--testing/web-platform/tests/fetch/api/request/destination/resources/dummy.json1
-rw-r--r--testing/web-platform/tests/fetch/api/request/destination/resources/dummy.pngbin0 -> 18299 bytes
-rw-r--r--testing/web-platform/tests/fetch/api/request/destination/resources/dummy.ttfbin0 -> 2528 bytes
-rw-r--r--testing/web-platform/tests/fetch/api/request/destination/resources/dummy_audio.mp3bin0 -> 20498 bytes
-rw-r--r--testing/web-platform/tests/fetch/api/request/destination/resources/dummy_audio.ogabin0 -> 18541 bytes
-rw-r--r--testing/web-platform/tests/fetch/api/request/destination/resources/dummy_video.mp4bin0 -> 67369 bytes
-rw-r--r--testing/web-platform/tests/fetch/api/request/destination/resources/dummy_video.ogvbin0 -> 94372 bytes
-rw-r--r--testing/web-platform/tests/fetch/api/request/destination/resources/dummy_video.webmbin0 -> 96902 bytes
-rw-r--r--testing/web-platform/tests/fetch/api/request/destination/resources/empty.https.html0
-rw-r--r--testing/web-platform/tests/fetch/api/request/destination/resources/fetch-destination-worker-frame.js20
-rw-r--r--testing/web-platform/tests/fetch/api/request/destination/resources/fetch-destination-worker-iframe.js20
-rw-r--r--testing/web-platform/tests/fetch/api/request/destination/resources/fetch-destination-worker-no-load-event.js20
-rw-r--r--testing/web-platform/tests/fetch/api/request/destination/resources/fetch-destination-worker.js12
-rw-r--r--testing/web-platform/tests/fetch/api/request/destination/resources/import-declaration-type-css.js1
-rw-r--r--testing/web-platform/tests/fetch/api/request/destination/resources/import-declaration-type-json.js1
-rw-r--r--testing/web-platform/tests/fetch/api/request/destination/resources/importer.js1
27 files changed, 894 insertions, 0 deletions
diff --git a/testing/web-platform/tests/fetch/api/request/destination/fetch-destination-frame.https.html b/testing/web-platform/tests/fetch/api/request/destination/fetch-destination-frame.https.html
new file mode 100644
index 0000000000..f3f9f7856d
--- /dev/null
+++ b/testing/web-platform/tests/fetch/api/request/destination/fetch-destination-frame.https.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<title>Fetch destination tests for resources with no load event</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
+<script>
+let frame;
+const kScope = 'resources/dummy.html?dest=frame';
+
+// Set up the service worker and the frame.
+promise_test(t => {
+ const kScript = 'resources/fetch-destination-worker-frame.js';
+ return service_worker_unregister_and_register(t, kScript, kScope)
+ .then(registration => {
+ add_completion_callback(() => {
+ registration.unregister();
+ });
+
+ return wait_for_state(t, registration.installing, 'activated');
+ });
+ }, 'Initialize global state');
+
+var waitOnMessageFromSW = async t => {
+ await new Promise((resolve, reject) => {
+ navigator.serviceWorker.onmessage = t.step_func(event => {
+ if (event.data == "PASS") {
+ resolve();
+ } else {
+ reject();
+ }
+ });
+ }).catch(() => {;
+ assert_unreached("Wrong destination.");
+ });
+ t.add_cleanup(() => { frame.contentWindow.navigator.serviceWorker.onmessage = null; });
+}
+
+// Document destination
+///////////////////////
+promise_test(async t => {
+ var f = document.createElement('frame');
+ frame = f;
+ f.className = 'test-frame';
+ f.src = kScope;
+ document.body.appendChild(f);
+ await waitOnMessageFromSW(t);
+ add_completion_callback(() => { f.remove(); });
+}, 'frame fetches with a "frame" Request.destination');
+
+</script>
diff --git a/testing/web-platform/tests/fetch/api/request/destination/fetch-destination-iframe.https.html b/testing/web-platform/tests/fetch/api/request/destination/fetch-destination-iframe.https.html
new file mode 100644
index 0000000000..1aa5a5613b
--- /dev/null
+++ b/testing/web-platform/tests/fetch/api/request/destination/fetch-destination-iframe.https.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<title>Fetch destination tests for resources with no load event</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
+<script>
+let frame;
+const kScope = 'resources/dummy.html?dest=iframe';
+
+// Set up the service worker and the frame.
+promise_test(t => {
+ const kScript = 'resources/fetch-destination-worker-iframe.js';
+ return service_worker_unregister_and_register(t, kScript, kScope)
+ .then(registration => {
+ add_completion_callback(() => {
+ registration.unregister();
+ });
+
+ return wait_for_state(t, registration.installing, 'activated');
+ });
+ }, 'Initialize global state');
+
+var waitOnMessageFromSW = async t => {
+ await new Promise((resolve, reject) => {
+ navigator.serviceWorker.onmessage = t.step_func(event => {
+ if (event.data == "PASS") {
+ resolve();
+ } else {
+ reject();
+ }
+ });
+ }).catch(() => {;
+ assert_unreached("Wrong destination.");
+ });
+ t.add_cleanup(() => { frame.contentWindow.navigator.serviceWorker.onmessage = null; });
+}
+
+// Document destination
+///////////////////////
+promise_test(async t => {
+ var f = document.createElement('iframe');
+ frame = f;
+ f.className = 'test-iframe';
+ f.src = kScope;
+ document.body.appendChild(f);
+ await waitOnMessageFromSW(t);
+ add_completion_callback(() => { f.remove(); });
+}, 'iframe fetches with a "iframe" Request.destination');
+
+</script>
diff --git a/testing/web-platform/tests/fetch/api/request/destination/fetch-destination-no-load-event.https.html b/testing/web-platform/tests/fetch/api/request/destination/fetch-destination-no-load-event.https.html
new file mode 100644
index 0000000000..1778bf2581
--- /dev/null
+++ b/testing/web-platform/tests/fetch/api/request/destination/fetch-destination-no-load-event.https.html
@@ -0,0 +1,124 @@
+<!DOCTYPE html>
+<title>Fetch destination tests for resources with no load event</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
+<script>
+let frame;
+
+// Set up the service worker and the frame.
+promise_test(t => {
+ const kScope = 'resources/';
+ const kFrame = 'resources/empty.https.html';
+ const kScript = 'resources/fetch-destination-worker-no-load-event.js';
+ return service_worker_unregister_and_register(t, kScript, kScope)
+ .then(registration => {
+ add_completion_callback(() => {
+ registration.unregister();
+ });
+
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(() => {
+ return with_iframe(kFrame);
+ })
+ .then(f => {
+ frame = f;
+ add_completion_callback(() => { f.remove(); });
+ });
+ }, 'Initialize global state');
+
+var waitOnMessageFromSW = async t => {
+ await new Promise((resolve, reject) => {
+ frame.contentWindow.navigator.serviceWorker.onmessage = t.step_func(event => {
+ if (event.data == "PASS") {
+ resolve();
+ } else {
+ reject();
+ }
+ });
+ }).catch(() => {;
+ assert_unreached("Wrong destination.");
+ });
+ t.add_cleanup(() => { frame.contentWindow.navigator.serviceWorker.onmessage = null; });
+}
+// Actual tests
+
+// Image destination
+////////////////////
+
+// CSS background image - image destination
+promise_test(async t => {
+ let node = frame.contentWindow.document.createElement("div");
+ node.style = "background-image: url(dummy.png?t=bg2&dest=image)";
+ frame.contentWindow.document.body.appendChild(node);
+
+ await waitOnMessageFromSW(t);
+}, 'Background image fetches with an "image" Request.destination');
+
+// Font destination
+///////////////////
+
+// Font loading API - font destination
+promise_test(async t => {
+ let font = new frame.contentWindow.FontFace("foo", "url(dummy.ttf?t=api&dest=font)");
+ font.load();
+
+ await waitOnMessageFromSW(t);
+}, 'Font loading API fetches with an "font" Request.destination');
+
+// CSS font - font destination
+promise_test(async t => {
+ let style = frame.contentWindow.document.createElement("style");
+ style.innerHTML = "@font-face { font-family: foo; src: url(dummy.ttf?t=css&dest=font); }";
+ style.innerHTML += "div {font-family: foo; }";
+ let div = frame.contentWindow.document.createElement("div");
+ div.innerHTML = "bar";
+ frame.contentWindow.document.body.appendChild(style);
+ frame.contentWindow.document.body.appendChild(div);
+
+ await waitOnMessageFromSW(t);
+}, 'CSS font fetches with an "font" Request.destination');
+
+// Empty string destination
+///////////////////////////
+
+// sendBeacon() - empty string destination
+promise_test(async t => {
+ frame.contentWindow.navigator.sendBeacon("dummy?t=beacon&dest=", "foobar");
+
+ await waitOnMessageFromSW(t);
+}, 'sendBeacon() fetches with an empty string Request.destination');
+
+// Cache.add() - empty string destination
+promise_test(async t => {
+ frame.contentWindow.caches.open("foo").then(cache => {
+ cache.add("dummy?t=cache&dest=");
+ });
+
+ await waitOnMessageFromSW(t);
+}, 'Cache.add() fetches with an empty string Request.destination');
+
+// script destination
+/////////////////////
+
+// importScripts() - script destination
+promise_test(async t => {
+ let worker = new frame.contentWindow.Worker("importer.js");
+
+ await waitOnMessageFromSW(t);
+}, 'importScripts() fetches with a "script" Request.destination');
+
+// style destination
+/////////////////////
+// @import - style destination
+promise_test(async t => {
+ let node = frame.contentWindow.document.createElement("style");
+ node.innerHTML = '@import url("dummy?t=import&dest=style")';
+ frame.contentWindow.document.body.appendChild(node);
+
+ await waitOnMessageFromSW(t);
+}, '@import fetches with a "style" Request.destination');
+
+</script>
diff --git a/testing/web-platform/tests/fetch/api/request/destination/fetch-destination-prefetch.https.html b/testing/web-platform/tests/fetch/api/request/destination/fetch-destination-prefetch.https.html
new file mode 100644
index 0000000000..db99202df8
--- /dev/null
+++ b/testing/web-platform/tests/fetch/api/request/destination/fetch-destination-prefetch.https.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<title>Fetch destination test for prefetching</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="/common/media.js"></script>
+<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
+<script>
+let frame;
+
+// Set up the service worker and the frame.
+promise_test(t => {
+ const kScope = 'resources/empty.https.html';
+ const kScript = 'resources/fetch-destination-worker.js';
+ return service_worker_unregister_and_register(t, kScript, kScope)
+ .then(registration => {
+ add_completion_callback(() => {
+ registration.unregister();
+ });
+
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(() => {
+ return with_iframe(kScope);
+ })
+ .then(f => {
+ frame = f;
+ add_completion_callback(() => { f.remove(); });
+ });
+ }, 'Initialize global state');
+
+// HTMLLinkElement with rel=prefetch - empty string destination
+promise_test(async t => {
+ await new Promise((resolve, reject) => {
+ let node = frame.contentWindow.document.createElement("link");
+ node.rel = "prefetch";
+ node.onload = resolve;
+ node.onerror = reject;
+ node.href = "dummy?dest=";
+ frame.contentWindow.document.body.appendChild(node);
+ }).catch(() => {
+ assert_unreached("Fetch errored.");
+ });
+}, 'HTMLLinkElement with rel=prefetch fetches with an empty string Request.destination');
+
+</script>
diff --git a/testing/web-platform/tests/fetch/api/request/destination/fetch-destination-worker.https.html b/testing/web-platform/tests/fetch/api/request/destination/fetch-destination-worker.https.html
new file mode 100644
index 0000000000..5935c1ff31
--- /dev/null
+++ b/testing/web-platform/tests/fetch/api/request/destination/fetch-destination-worker.https.html
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<title>Fetch destination tests for resources with no load event</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
+<script>
+let frame;
+
+// Set up the service worker and the frame.
+promise_test(t => {
+ const kScope = 'resources/dummy.html';
+ const kScript = 'resources/fetch-destination-worker-no-load-event.js';
+ return service_worker_unregister_and_register(t, kScript, kScope)
+ .then(registration => {
+ add_completion_callback(() => {
+ registration.unregister();
+ });
+
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(() => {
+ return with_iframe(kScope);
+ })
+ .then(f => {
+ frame = f;
+ add_completion_callback(() => { f.remove(); });
+ });
+ }, 'Initialize global state');
+
+var waitOnMessageFromSW = async t => {
+ await new Promise((resolve, reject) => {
+ frame.contentWindow.navigator.serviceWorker.onmessage = t.step_func(event => {
+ if (event.data == "PASS") {
+ resolve();
+ } else {
+ reject();
+ }
+ });
+ }).catch(() => {;
+ assert_unreached("Wrong destination.");
+ });
+ t.add_cleanup(() => { frame.contentWindow.navigator.serviceWorker.onmessage = null; });
+}
+
+// worker destination
+/////////////////////
+promise_test(async t => {
+ // We can use an html file as we don't really care about the dedicated worker successfully loading.
+ let worker = new frame.contentWindow.Worker("dummy.html?t=worker&dest=worker");
+ await waitOnMessageFromSW(t);
+}, 'DedicatedWorker fetches with a "worker" Request.destination');
+
+promise_test(async t => {
+ // We can use an html file as we don't really care about the shared worker successfully loading.
+ let worker = new frame.contentWindow.SharedWorker("dummy.html?t=sharedworker&dest=sharedworker");
+ await waitOnMessageFromSW(t);
+}, 'SharedWorker fetches with a "sharedworker" Request.destination');
+
+</script>
diff --git a/testing/web-platform/tests/fetch/api/request/destination/fetch-destination.https.html b/testing/web-platform/tests/fetch/api/request/destination/fetch-destination.https.html
new file mode 100644
index 0000000000..1b6cf16914
--- /dev/null
+++ b/testing/web-platform/tests/fetch/api/request/destination/fetch-destination.https.html
@@ -0,0 +1,485 @@
+<!DOCTYPE html>
+<title>Fetch destination tests</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="/common/media.js"></script>
+<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
+<script>
+let frame;
+
+// Set up the service worker and the frame.
+promise_test(t => {
+ const kScope = 'resources/empty.https.html';
+ const kScript = 'resources/fetch-destination-worker.js';
+ return service_worker_unregister_and_register(t, kScript, kScope)
+ .then(registration => {
+ add_completion_callback(() => {
+ registration.unregister();
+ });
+
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(() => {
+ return with_iframe(kScope);
+ })
+ .then(f => {
+ frame = f;
+ add_completion_callback(() => { f.remove(); });
+ });
+ }, 'Initialize global state');
+
+// Actual tests
+
+// Image destination
+////////////////////
+
+// HTMLImageElement - image destination
+promise_test(async t => {
+ await new Promise((resolve, reject) => {
+ let node = frame.contentWindow.document.createElement("img");
+ node.onload = resolve;
+ node.onerror = reject;
+ node.src = "dummy.png?dest=image";
+ }).catch(() => {
+ assert_unreached("Fetch errored.");
+ });
+}, 'HTMLImageElement fetches with an "image" Request.destination');
+
+// HTMLImageElement with srcset attribute - image destination
+promise_test(async t => {
+ await new Promise((resolve, reject) => {
+ let node = frame.contentWindow.document.createElement("img");
+ node.onload = resolve;
+ node.onerror = reject;
+ node.srcset = "dummy.png?t=srcset&dest=image";
+ }).catch(() => {
+ assert_unreached("Fetch errored.");
+ });
+}, 'HTMLImageElement with srcset attribute fetches with an "image" Request.destination');
+
+// HTMLImageElement with srcset attribute - image destination
+promise_test(async t => {
+ await new Promise((resolve, reject) => {
+ let img = frame.contentWindow.document.createElement("img");
+ let picture = frame.contentWindow.document.createElement("picture");
+ let source = frame.contentWindow.document.createElement("source");
+ picture.appendChild(source);
+ picture.appendChild(img);
+ img.onload = resolve;
+ img.onerror = reject;
+ source.srcset = "dummy.png?t=picture&dest=image";
+ }).catch(() => {
+ assert_unreached("Fetch errored.");
+ });
+}, 'HTMLImageElement with a HTMLPictureElement parent attribute fetches with an "image" Request.destination');
+
+// SVGImageElement - image destination
+promise_test(async t => {
+ await new Promise((resolve, reject) => {
+ let svg = frame.contentWindow.document.createElementNS('http://www.w3.org/2000/svg','svg');
+ svg.setAttributeNS('http://www.w3.org/2000/svg','xlink','http://www.w3.org/1999/xlink');
+ let svgimg = frame.contentWindow.document.createElementNS('http://www.w3.org/2000/svg','image');
+ svgimg.onload = resolve;
+ svgimg.onerror = reject;
+ svgimg.setAttributeNS('http://www.w3.org/1999/xlink','href','dummy.png?t=svg&dest=image');
+ svg.appendChild(svgimg);
+ frame.contentWindow.document.documentElement.appendChild(svg);
+ }).catch(() => {
+ assert_unreached("Fetch errored.");
+ });
+}, 'SVGImageElement fetches with an "image" Request.destination');
+
+// Empty string destination
+///////////////////////////
+
+// fetch() - empty string destination
+promise_test(async t => {
+ let response = await frame.contentWindow.fetch("dummy?dest=");
+ assert_true(response.ok);
+}, 'fetch() fetches with an empty string Request.destination');
+
+// XMLHttpRequest - empty string destination
+promise_test(async t => {
+ let xhr;
+ await new Promise((resolve, reject) => {
+ xhr = new frame.contentWindow.XMLHttpRequest();
+ xhr.onload = resolve;
+ xhr.onerror = reject;
+ xhr.open("GET", "dummy?t=xhr&dest=");
+ xhr.send();
+ }).catch(() => {
+ assert_unreached("Fetch errored.");
+ });
+ assert_equals(xhr.status, 200);
+}, 'XMLHttpRequest() fetches with an empty string Request.destination');
+
+// EventSource - empty string destination
+promise_test(async t => {
+ let xhr;
+ await new Promise((resolve, reject) => {
+ eventSource = new frame.contentWindow.EventSource("dummy.es?t=eventsource&dest=");
+ eventSource.onopen = resolve;
+ eventSource.onerror = reject;
+ }).catch(() => {
+ assert_unreached("Fetch errored.");
+ });
+}, 'EventSource() fetches with an empty string Request.destination');
+
+// HTMLAudioElement - audio destination
+///////////////////////////////////////
+promise_test(async t => {
+ await new Promise((resolve, reject) => {
+ let audioURL = getAudioURI("dummy_audio");
+ let node = frame.contentWindow.document.createElement("audio");
+ node.onloadeddata = resolve;
+ node.onerror = reject;
+ node.src = audioURL + "?dest=audio";
+ }).catch(() => {
+ assert_unreached("Fetch errored.");
+ });
+}, 'HTMLAudioElement fetches with an "audio" Request.destination');
+
+// HTMLVideoElement - video destination
+///////////////////////////////////////
+promise_test(async t => {
+ await new Promise((resolve, reject) => {
+ let videoURL = getVideoURI("dummy_video");
+ let node = frame.contentWindow.document.createElement("video");
+ node.onloadeddata = resolve;
+ node.onerror = reject;
+ node.src = videoURL + "?dest=video";
+ }).catch(() => {
+ assert_unreached("Fetch errored.");
+ });
+}, 'HTMLVideoElement fetches with a "video" Request.destination');
+
+// script destinations
+//////////////////////
+
+// HTMLScriptElement - script destination
+promise_test(async t => {
+ await new Promise((resolve, reject) => {
+ let node = frame.contentWindow.document.createElement("script");
+ node.onload = resolve;
+ node.onerror = reject;
+ node.src = "dummy?dest=script";
+ frame.contentWindow.document.body.appendChild(node);
+ }).catch(() => {
+ assert_unreached("Fetch errored.");
+ });
+}, 'HTMLScriptElement fetches with a "script" Request.destination');
+
+// audioworklet destination
+//////////////////////
+promise_test(async t => {
+ let audioContext = new frame.contentWindow.AudioContext();
+ await audioContext.audioWorklet.addModule("dummy?dest=audioworklet");
+}, 'AudioWorklet module fetches with a "audioworklet" Request.destination');
+
+// Style destination
+////////////////////
+
+// HTMLLinkElement with rel=stylesheet - style destination
+promise_test(async t => {
+ await new Promise((resolve, reject) => {
+ let node = frame.contentWindow.document.createElement("link");
+ node.rel = "stylesheet";
+ node.onload = resolve;
+ node.onerror = reject;
+ node.href = "dummy?dest=style";
+ frame.contentWindow.document.body.appendChild(node);
+ }).catch(() => {
+ assert_unreached("Fetch errored.");
+ });
+}, 'HTMLLinkElement with rel=stylesheet fetches with a "style" Request.destination');
+
+// Import declaration with `type: "css"` - style destination
+promise_test(t => {
+ return new Promise((resolve, reject) => {
+ frame.contentWindow.onerror = reject;
+
+ let node = frame.contentWindow.document.createElement("script");
+ node.onload = resolve;
+ node.onerror = reject;
+ node.src = "import-declaration-type-css.js";
+ node.type = "module";
+ frame.contentWindow.document.body.appendChild(node);
+ }).then(() => {
+ frame.contentWindow.onerror = null;
+ });
+}, 'Import declaration with `type: "css"` fetches with a "style" Request.destination');
+
+// JSON destination
+///////////////////
+
+// Import declaration with `type: "json"` - json destination
+promise_test(t => {
+ return new Promise((resolve, reject) => {
+ frame.contentWindow.onerror = reject;
+ let node = frame.contentWindow.document.createElement("script");
+ node.onload = resolve;
+ node.onerror = reject;
+ node.src = "import-declaration-type-json.js";
+ node.type = "module";
+ frame.contentWindow.document.body.appendChild(node);
+ }).then(() => {
+ frame.contentWindow.onerror = null;
+ });
+}, 'Import declaration with `type: "json"` fetches with a "json" Request.destination');
+
+// Preload tests
+////////////////
+// HTMLLinkElement with rel=preload and as=fetch - empty string destination
+promise_test(async t => {
+ await new Promise((resolve, reject) => {
+ let node = frame.contentWindow.document.createElement("link");
+ node.rel = "preload";
+ node.as = "fetch";
+ if (node.as != "fetch") {
+ resolve();
+ }
+ node.onload = resolve;
+ node.onerror = reject;
+ node.href = "dummy?t=2&dest=";
+ frame.contentWindow.document.body.appendChild(node);
+ }).catch(() => {
+ assert_unreached("Fetch errored.");
+ });
+}, 'HTMLLinkElement with rel=preload and as=fetch fetches with an empty string Request.destination');
+
+// HTMLLinkElement with rel=preload and as=style - style destination
+promise_test(async t => {
+ await new Promise((resolve, reject) => {
+ let node = frame.contentWindow.document.createElement("link");
+ node.rel = "preload";
+ node.as = "style";
+ if (node.as != "style") {
+ resolve();
+ }
+ node.onload = resolve;
+ node.onerror = reject;
+ node.href = "dummy?t=2&dest=style";
+ frame.contentWindow.document.body.appendChild(node);
+ }).catch(() => {
+ assert_unreached("Fetch errored.");
+ });
+}, 'HTMLLinkElement with rel=preload and as=style fetches with a "style" Request.destination');
+
+// HTMLLinkElement with rel=preload and as=json - json destination
+promise_test(t => {
+ return new Promise((resolve, reject) => {
+ let node = frame.contentWindow.document.createElement("link");
+ node.rel = "preload";
+ node.as = "json";
+ if (node.as != "json") {
+ resolve();
+ }
+ node.onload = resolve;
+ node.onerror = reject;
+ node.href = "dummy.json?t=2&dest=json";
+ frame.contentWindow.document.body.appendChild(node);
+ });
+}, 'HTMLLinkElement with rel=preload and as=json fetches with a "json" Request.destination');
+
+// HTMLLinkElement with rel=preload and as=script - script destination
+promise_test(async t => {
+ await new Promise((resolve, reject) => {
+ let node = frame.contentWindow.document.createElement("link");
+ node.rel = "preload";
+ node.as = "script";
+ if (node.as != "script") {
+ resolve();
+ }
+ node.onload = resolve;
+ node.onerror = reject;
+ node.href = "dummy?t=2&dest=script";
+ frame.contentWindow.document.body.appendChild(node);
+ }).catch(() => {
+ assert_unreached("Fetch errored.");
+ });
+}, 'HTMLLinkElement with rel=preload and as=script fetches with a "script" Request.destination');
+
+// HTMLLinkElement with rel=preload and as=font - font destination
+promise_test(async t => {
+ await new Promise((resolve, reject) => {
+ let node = frame.contentWindow.document.createElement("link");
+ node.rel = "preload";
+ node.as = "font";
+ if (node.as != "font") {
+ resolve();
+ }
+ node.onload = resolve;
+ node.onerror = reject;
+ node.href = "dummy?t=2&dest=font";
+ frame.contentWindow.document.body.appendChild(node);
+ }).catch(() => {
+ assert_unreached("Fetch errored.");
+ });
+}, 'HTMLLinkElement with rel=preload and as=font fetches with a "font" Request.destination');
+
+// HTMLLinkElement with rel=preload and as=image - image destination
+promise_test(async t => {
+ await new Promise((resolve, reject) => {
+ let node = frame.contentWindow.document.createElement("link");
+ node.rel = "preload";
+ node.as = "image";
+ if (node.as != "image") {
+ resolve();
+ }
+ node.onload = resolve;
+ node.onerror = reject;
+ node.href = "dummy.png?t=2&dest=image";
+ frame.contentWindow.document.body.appendChild(node);
+ }).catch(() => {
+ assert_unreached("Fetch errored.");
+ });
+}, 'HTMLLinkElement with rel=preload and as=image fetches with a "image" Request.destination');
+
+// HTMLLinkElement with rel=preload and as=audio - audio destination
+promise_test(async t => {
+ await new Promise((resolve, reject) => {
+ let audioURL = getAudioURI("dummy_audio");
+ let node = frame.contentWindow.document.createElement("link");
+ node.rel = "preload";
+ node.as = "audio";
+ if (node.as != "audio") {
+ resolve();
+ }
+ node.onload = resolve;
+ node.onerror = reject;
+ node.href = audioURL + "?dest=audio";
+ frame.contentWindow.document.body.appendChild(node);
+ }).catch(() => {
+ assert_unreached("Fetch errored.");
+ });
+}, 'HTMLLinkElement with rel=preload and as=audio fetches with a "audio" Request.destination');
+
+// HTMLLinkElement with rel=preload and as=video - video destination
+promise_test(async t => {
+ await new Promise((resolve, reject) => {
+ let videoURL = getVideoURI("dummy_video");
+ let node = frame.contentWindow.document.createElement("link");
+ node.rel = "preload";
+ node.as = "video";
+ if (node.as != "video") {
+ resolve();
+ }
+ node.onload = resolve;
+ node.onerror = reject;
+ node.href = videoURL + "?dest=video";
+ frame.contentWindow.document.body.appendChild(node);
+ }).catch(() => {
+ assert_unreached("Fetch errored.");
+ });
+}, 'HTMLLinkElement with rel=preload and as=video fetches with a "video" Request.destination');
+
+// HTMLLinkElement with rel=preload and as=track - track destination
+promise_test(async t => {
+ await new Promise((resolve, reject) => {
+ let node = frame.contentWindow.document.createElement("link");
+ node.rel = "preload";
+ node.as = "track";
+ if (node.as != "track") {
+ resolve();
+ }
+ node.onload = resolve;
+ node.onerror = reject;
+ node.href = "dummy?dest=track";
+ frame.contentWindow.document.body.appendChild(node);
+ }).catch(() => {
+ assert_unreached("Fetch errored.");
+ });
+}, 'HTMLLinkElement with rel=preload and as=track fetches with a "track" Request.destination');
+
+// HTMLLinkElement with rel=preload and as=document - document destination
+promise_test(async t => {
+ await new Promise((resolve, reject) => {
+ let node = frame.contentWindow.document.createElement("link");
+ node.rel = "preload";
+ node.as = "document";
+ if (node.as != "document") {
+ resolve();
+ }
+ node.onload = resolve;
+ node.onerror = reject;
+ node.href = "dummy?dest=document";
+ frame.contentWindow.document.body.appendChild(node);
+ }).catch(() => {
+ assert_unreached("Fetch errored.");
+ });
+}, 'HTMLLinkElement with rel=preload and as=document fetches with a "document" Request.destination');
+
+// HTMLLinkElement with rel=preload and as=worker - worker destination
+promise_test(async t => {
+ await new Promise((resolve, reject) => {
+ let node = frame.contentWindow.document.createElement("link");
+ node.rel = "preload";
+ node.as = "worker";
+ if (node.as != "worker") {
+ resolve();
+ }
+ node.onload = resolve;
+ node.onerror = reject;
+ node.href = "dummy?dest=worker";
+ frame.contentWindow.document.body.appendChild(node);
+ }).catch(() => {
+ assert_unreached("Fetch errored.");
+ });
+}, 'HTMLLinkElement with rel=preload and as=worker fetches with a "worker" Request.destination');
+
+// HTMLLinkElement with rel=preload and as=sharedworker - sharedworker destination
+promise_test(async t => {
+ await new Promise((resolve, reject) => {
+ let node = frame.contentWindow.document.createElement("link");
+ node.rel = "preload";
+ node.as = "sharedworker";
+ if (node.as != "sharedworker") {
+ resolve();
+ }
+ node.onload = resolve;
+ node.onerror = reject;
+ node.href = "dummy?dest=sharedworker";
+ frame.contentWindow.document.body.appendChild(node);
+ }).catch(() => {
+ assert_unreached("Fetch errored.");
+ });
+}, 'HTMLLinkElement with rel=preload and as=sharedworker fetches with a "sharedworker" Request.destination');
+
+// HTMLLinkElement with rel=preload and as=xslt - xslt destination
+promise_test(async t => {
+ await new Promise((resolve, reject) => {
+ let node = frame.contentWindow.document.createElement("link");
+ node.rel = "preload";
+ node.as = "xslt";
+ if (node.as != "xslt") {
+ resolve();
+ }
+ node.onload = resolve;
+ node.onerror = reject;
+ node.href = "dummy?dest=xslt";
+ frame.contentWindow.document.body.appendChild(node);
+ }).catch(() => {
+ assert_unreached("Fetch errored.");
+ });
+}, 'HTMLLinkElement with rel=preload and as=xslt fetches with a "xslt" Request.destination');
+
+// HTMLLinkElement with rel=preload and as=manifest - manifest destination
+promise_test(async t => {
+ await new Promise((resolve, reject) => {
+ let node = frame.contentWindow.document.createElement("link");
+ node.rel = "preload";
+ node.as = "manifest";
+ if (node.as != "manifest") {
+ resolve();
+ }
+ node.onload = resolve;
+ node.onerror = reject;
+ node.href = "dummy?dest=manifest";
+ frame.contentWindow.document.body.appendChild(node);
+ }).catch(() => {
+ assert_unreached("Fetch errored.");
+ });
+}, 'HTMLLinkElement with rel=preload and as=manifest fetches with a "manifest" Request.destination');
+
+</script>
diff --git a/testing/web-platform/tests/fetch/api/request/destination/resources/dummy b/testing/web-platform/tests/fetch/api/request/destination/resources/dummy
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/testing/web-platform/tests/fetch/api/request/destination/resources/dummy
diff --git a/testing/web-platform/tests/fetch/api/request/destination/resources/dummy.css b/testing/web-platform/tests/fetch/api/request/destination/resources/dummy.css
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/testing/web-platform/tests/fetch/api/request/destination/resources/dummy.css
diff --git a/testing/web-platform/tests/fetch/api/request/destination/resources/dummy.es b/testing/web-platform/tests/fetch/api/request/destination/resources/dummy.es
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/testing/web-platform/tests/fetch/api/request/destination/resources/dummy.es
diff --git a/testing/web-platform/tests/fetch/api/request/destination/resources/dummy.es.headers b/testing/web-platform/tests/fetch/api/request/destination/resources/dummy.es.headers
new file mode 100644
index 0000000000..9bb8badcad
--- /dev/null
+++ b/testing/web-platform/tests/fetch/api/request/destination/resources/dummy.es.headers
@@ -0,0 +1 @@
+Content-Type: text/event-stream
diff --git a/testing/web-platform/tests/fetch/api/request/destination/resources/dummy.html b/testing/web-platform/tests/fetch/api/request/destination/resources/dummy.html
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/testing/web-platform/tests/fetch/api/request/destination/resources/dummy.html
diff --git a/testing/web-platform/tests/fetch/api/request/destination/resources/dummy.json b/testing/web-platform/tests/fetch/api/request/destination/resources/dummy.json
new file mode 100644
index 0000000000..0967ef424b
--- /dev/null
+++ b/testing/web-platform/tests/fetch/api/request/destination/resources/dummy.json
@@ -0,0 +1 @@
+{}
diff --git a/testing/web-platform/tests/fetch/api/request/destination/resources/dummy.png b/testing/web-platform/tests/fetch/api/request/destination/resources/dummy.png
new file mode 100644
index 0000000000..01c9666a8d
--- /dev/null
+++ b/testing/web-platform/tests/fetch/api/request/destination/resources/dummy.png
Binary files differ
diff --git a/testing/web-platform/tests/fetch/api/request/destination/resources/dummy.ttf b/testing/web-platform/tests/fetch/api/request/destination/resources/dummy.ttf
new file mode 100644
index 0000000000..9023592ef5
--- /dev/null
+++ b/testing/web-platform/tests/fetch/api/request/destination/resources/dummy.ttf
Binary files differ
diff --git a/testing/web-platform/tests/fetch/api/request/destination/resources/dummy_audio.mp3 b/testing/web-platform/tests/fetch/api/request/destination/resources/dummy_audio.mp3
new file mode 100644
index 0000000000..0091330f1e
--- /dev/null
+++ b/testing/web-platform/tests/fetch/api/request/destination/resources/dummy_audio.mp3
Binary files differ
diff --git a/testing/web-platform/tests/fetch/api/request/destination/resources/dummy_audio.oga b/testing/web-platform/tests/fetch/api/request/destination/resources/dummy_audio.oga
new file mode 100644
index 0000000000..239ad2bd08
--- /dev/null
+++ b/testing/web-platform/tests/fetch/api/request/destination/resources/dummy_audio.oga
Binary files differ
diff --git a/testing/web-platform/tests/fetch/api/request/destination/resources/dummy_video.mp4 b/testing/web-platform/tests/fetch/api/request/destination/resources/dummy_video.mp4
new file mode 100644
index 0000000000..7022e75c15
--- /dev/null
+++ b/testing/web-platform/tests/fetch/api/request/destination/resources/dummy_video.mp4
Binary files differ
diff --git a/testing/web-platform/tests/fetch/api/request/destination/resources/dummy_video.ogv b/testing/web-platform/tests/fetch/api/request/destination/resources/dummy_video.ogv
new file mode 100644
index 0000000000..de99616ece
--- /dev/null
+++ b/testing/web-platform/tests/fetch/api/request/destination/resources/dummy_video.ogv
Binary files differ
diff --git a/testing/web-platform/tests/fetch/api/request/destination/resources/dummy_video.webm b/testing/web-platform/tests/fetch/api/request/destination/resources/dummy_video.webm
new file mode 100644
index 0000000000..c3d433a3e0
--- /dev/null
+++ b/testing/web-platform/tests/fetch/api/request/destination/resources/dummy_video.webm
Binary files differ
diff --git a/testing/web-platform/tests/fetch/api/request/destination/resources/empty.https.html b/testing/web-platform/tests/fetch/api/request/destination/resources/empty.https.html
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/testing/web-platform/tests/fetch/api/request/destination/resources/empty.https.html
diff --git a/testing/web-platform/tests/fetch/api/request/destination/resources/fetch-destination-worker-frame.js b/testing/web-platform/tests/fetch/api/request/destination/resources/fetch-destination-worker-frame.js
new file mode 100644
index 0000000000..b69de0b7df
--- /dev/null
+++ b/testing/web-platform/tests/fetch/api/request/destination/resources/fetch-destination-worker-frame.js
@@ -0,0 +1,20 @@
+self.addEventListener('fetch', function(event) {
+ if (event.request.url.includes('dummy')) {
+ event.waitUntil(async function() {
+ let destination = new URL(event.request.url).searchParams.get("dest");
+ let clients = await self.clients.matchAll({"includeUncontrolled": true});
+ clients.forEach(function(client) {
+ if (client.url.includes("fetch-destination-frame")) {
+ if (event.request.destination == destination) {
+ client.postMessage("PASS");
+ } else {
+ client.postMessage("FAIL");
+ }
+ }
+ })
+ }());
+ }
+ event.respondWith(fetch(event.request));
+});
+
+
diff --git a/testing/web-platform/tests/fetch/api/request/destination/resources/fetch-destination-worker-iframe.js b/testing/web-platform/tests/fetch/api/request/destination/resources/fetch-destination-worker-iframe.js
new file mode 100644
index 0000000000..76345839ea
--- /dev/null
+++ b/testing/web-platform/tests/fetch/api/request/destination/resources/fetch-destination-worker-iframe.js
@@ -0,0 +1,20 @@
+self.addEventListener('fetch', function(event) {
+ if (event.request.url.includes('dummy')) {
+ event.waitUntil(async function() {
+ let destination = new URL(event.request.url).searchParams.get("dest");
+ let clients = await self.clients.matchAll({"includeUncontrolled": true});
+ clients.forEach(function(client) {
+ if (client.url.includes("fetch-destination-iframe")) {
+ if (event.request.destination == destination) {
+ client.postMessage("PASS");
+ } else {
+ client.postMessage("FAIL");
+ }
+ }
+ })
+ }());
+ }
+ event.respondWith(fetch(event.request));
+});
+
+
diff --git a/testing/web-platform/tests/fetch/api/request/destination/resources/fetch-destination-worker-no-load-event.js b/testing/web-platform/tests/fetch/api/request/destination/resources/fetch-destination-worker-no-load-event.js
new file mode 100644
index 0000000000..a583b1272a
--- /dev/null
+++ b/testing/web-platform/tests/fetch/api/request/destination/resources/fetch-destination-worker-no-load-event.js
@@ -0,0 +1,20 @@
+self.addEventListener('fetch', function(event) {
+ const url = event.request.url;
+ if (url.includes('dummy') && url.includes('?')) {
+ event.waitUntil(async function() {
+ let destination = new URL(url).searchParams.get("dest");
+ var result = "FAIL";
+ if (event.request.destination == destination ||
+ (event.request.destination == "empty" && destination == "")) {
+ result = "PASS";
+ }
+ let cl = await clients.matchAll({includeUncontrolled: true});
+ for (i = 0; i < cl.length; i++) {
+ cl[i].postMessage(result);
+ }
+ }())
+ }
+ event.respondWith(fetch(event.request));
+});
+
+
diff --git a/testing/web-platform/tests/fetch/api/request/destination/resources/fetch-destination-worker.js b/testing/web-platform/tests/fetch/api/request/destination/resources/fetch-destination-worker.js
new file mode 100644
index 0000000000..904009c172
--- /dev/null
+++ b/testing/web-platform/tests/fetch/api/request/destination/resources/fetch-destination-worker.js
@@ -0,0 +1,12 @@
+self.addEventListener('fetch', function(event) {
+ if (event.request.url.includes('dummy')) {
+ let destination = new URL(event.request.url).searchParams.get("dest");
+ if (event.request.destination == destination ||
+ (event.request.destination == "empty" && destination == "")) {
+ event.respondWith(fetch(event.request));
+ } else {
+ event.respondWith(Response.error());
+ }
+ }
+});
+
diff --git a/testing/web-platform/tests/fetch/api/request/destination/resources/import-declaration-type-css.js b/testing/web-platform/tests/fetch/api/request/destination/resources/import-declaration-type-css.js
new file mode 100644
index 0000000000..3c8cf1f44b
--- /dev/null
+++ b/testing/web-platform/tests/fetch/api/request/destination/resources/import-declaration-type-css.js
@@ -0,0 +1 @@
+import "./dummy.css?dest=style" with { type: "css" };
diff --git a/testing/web-platform/tests/fetch/api/request/destination/resources/import-declaration-type-json.js b/testing/web-platform/tests/fetch/api/request/destination/resources/import-declaration-type-json.js
new file mode 100644
index 0000000000..b2d964dd82
--- /dev/null
+++ b/testing/web-platform/tests/fetch/api/request/destination/resources/import-declaration-type-json.js
@@ -0,0 +1 @@
+import "./dummy.json?dest=json" with { type: "json" };
diff --git a/testing/web-platform/tests/fetch/api/request/destination/resources/importer.js b/testing/web-platform/tests/fetch/api/request/destination/resources/importer.js
new file mode 100644
index 0000000000..9568474d50
--- /dev/null
+++ b/testing/web-platform/tests/fetch/api/request/destination/resources/importer.js
@@ -0,0 +1 @@
+importScripts("dummy?t=importScripts&dest=script");