summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/mozilla/tests/service-workers
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
commit36d22d82aa202bb199967e9512281e9a53db42c9 (patch)
tree105e8c98ddea1c1e4784a60a5a6410fa416be2de /testing/web-platform/mozilla/tests/service-workers
parentInitial commit. (diff)
downloadfirefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz
firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/mozilla/tests/service-workers')
-rw-r--r--testing/web-platform/mozilla/tests/service-workers/bug1675097.https.html34
-rw-r--r--testing/web-platform/mozilla/tests/service-workers/no_intercept_for_crossorigin_media.https.html42
-rw-r--r--testing/web-platform/mozilla/tests/service-workers/resources/blank.html2
-rw-r--r--testing/web-platform/mozilla/tests/service-workers/resources/bug1675097-iframe.html15
-rw-r--r--testing/web-platform/mozilla/tests/service-workers/resources/bug1675097-sw.js26
-rw-r--r--testing/web-platform/mozilla/tests/service-workers/resources/crossorigin_media_iframe.html24
-rw-r--r--testing/web-platform/mozilla/tests/service-workers/resources/crossorigin_media_iframe_nonrange.html22
-rw-r--r--testing/web-platform/mozilla/tests/service-workers/resources/empty.js0
-rw-r--r--testing/web-platform/mozilla/tests/service-workers/resources/fetch_video.py14
-rw-r--r--testing/web-platform/mozilla/tests/service-workers/resources/green.pngbin0 -> 87 bytes
-rw-r--r--testing/web-platform/mozilla/tests/service-workers/resources/intercept_media_sw.js14
-rw-r--r--testing/web-platform/mozilla/tests/service-workers/update_completes_in_disconnected_global.https.html63
12 files changed, 256 insertions, 0 deletions
diff --git a/testing/web-platform/mozilla/tests/service-workers/bug1675097.https.html b/testing/web-platform/mozilla/tests/service-workers/bug1675097.https.html
new file mode 100644
index 0000000000..e093f616c1
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/service-workers/bug1675097.https.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<title>Controlled iframe with initial about:blank becomes sandboxed</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>
+<body>
+<script>
+
+// This test creates an iframe controlled by a service worker, which in turn has
+// another iframe in it. The inner iframe's fetch is intercepted by the service
+// worker, which notifies the outer iframe, which then adds the sandbox
+// attribute to the inner iframe. The outer iframe then signals the service
+// worker that it should evaluate self.clients.matchAll() and finally respond to
+// the inner iframe's fetch.
+// Evaluating self.clients.matchAll() causes the creation of the initial
+// about:blank document for the inner iframe, and if the sandboxing flags used
+// for that document are not the original flags for the inner iframe (i.e. none)
+// then the document will have an opaque origin, a case that we need to handle
+// properly.
+promise_test(async t => {
+ const URL = 'resources/bug1675097-sw.js';
+ const SCOPE = 'resources/';
+
+ const registration = await service_worker_unregister_and_register(t, URL, SCOPE);
+ t.add_cleanup(() => registration.unregister());
+
+ await wait_for_state(t, registration.installing, 'activated');
+
+ const outer = await with_iframe(SCOPE + 'bug1675097-iframe.html');
+ t.add_cleanup(() => outer.remove());
+}, 'Regression test for bug 1675097');
+
+</script>
+</body>
diff --git a/testing/web-platform/mozilla/tests/service-workers/no_intercept_for_crossorigin_media.https.html b/testing/web-platform/mozilla/tests/service-workers/no_intercept_for_crossorigin_media.https.html
new file mode 100644
index 0000000000..245522f5fc
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/service-workers/no_intercept_for_crossorigin_media.https.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Don't intercept cross-origin media requests</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>
+<body>
+<script>
+
+'use strict';
+
+const scope = './resources/';
+
+/**
+ * Ensure service workers don't intercept cross-origin media range requests.
+ */
+promise_test(async t => {
+ const registration = await service_worker_unregister_and_register(
+ t, scope + 'intercept_media_sw.js', scope);
+ t.add_cleanup(() => registration.unregister());
+ await wait_for_state(t, registration.installing, 'activated');
+
+ const frame = await with_iframe(scope + 'crossorigin_media_iframe.html');
+ return frame.contentWindow.create_media_promise()
+}, 'Service worker does not intercept a cross-origin media range request');
+
+/**
+ * Ensure service workers do intercept cross-origin media non-range requests.
+ */
+promise_test(async t => {
+ const registration = await service_worker_unregister_and_register(
+ t, scope + 'intercept_media_sw.js', scope);
+ t.add_cleanup(() => registration.unregister());
+ await wait_for_state(t, registration.installing, 'activated');
+
+ const frame = await with_iframe(scope + 'crossorigin_media_iframe_nonrange.html');
+ return frame.contentWindow.create_media_promise()
+}, 'Service worker intercepts a cross-origin non-range media request');
+
+</script>
+</body>
diff --git a/testing/web-platform/mozilla/tests/service-workers/resources/blank.html b/testing/web-platform/mozilla/tests/service-workers/resources/blank.html
new file mode 100644
index 0000000000..a3c3a4689a
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/service-workers/resources/blank.html
@@ -0,0 +1,2 @@
+<!DOCTYPE html>
+<title>Empty doc</title>
diff --git a/testing/web-platform/mozilla/tests/service-workers/resources/bug1675097-iframe.html b/testing/web-platform/mozilla/tests/service-workers/resources/bug1675097-iframe.html
new file mode 100644
index 0000000000..5ad7b95594
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/service-workers/resources/bug1675097-iframe.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<body>
+<script>
+let channel = new MessageChannel();
+channel.port1.onmessage = event => {
+ if (event.data === 'intercepted') {
+ const iframe = document.querySelector('iframe');
+ iframe.sandbox = '';
+ navigator.serviceWorker.controller.postMessage({ type: 'ack' });
+ }
+};
+navigator.serviceWorker.controller.postMessage({ type: 'register', port: channel.port2 }, [channel.port2]);
+</script>
+<iframe src='inner'></iframe>
+</body>
diff --git a/testing/web-platform/mozilla/tests/service-workers/resources/bug1675097-sw.js b/testing/web-platform/mozilla/tests/service-workers/resources/bug1675097-sw.js
new file mode 100644
index 0000000000..e2894e1032
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/service-workers/resources/bug1675097-sw.js
@@ -0,0 +1,26 @@
+// We use promises because the message and fetch events do not have a guaranteed
+// order, since they come from different task sources.
+var resolvePortPromise;
+var portPromise = new Promise(resolve => resolvePortPromise = resolve);
+var resolveResolveResponsePromise;
+var resolveResponsePromise = new Promise(resolve => resolveResolveResponsePromise = resolve);
+
+self.addEventListener('fetch', event => {
+ if (event.request.url.indexOf('inner') !== -1) {
+ event.respondWith(new Promise(resolve => {
+ resolveResolveResponsePromise(resolve);
+ }));
+ portPromise.then(port => port.postMessage('intercepted'));
+ }
+});
+
+self.addEventListener('message', event => {
+ if (event.data.type === 'register') {
+ resolvePortPromise(event.data.port);
+ }
+ else if (event.data.type === 'ack') {
+ self.clients.matchAll()
+ .then(() => resolveResponsePromise)
+ .then(resolveResponse => resolveResponse(new Response('inner iframe')));
+ }
+});
diff --git a/testing/web-platform/mozilla/tests/service-workers/resources/crossorigin_media_iframe.html b/testing/web-platform/mozilla/tests/service-workers/resources/crossorigin_media_iframe.html
new file mode 100644
index 0000000000..54cdcaa8dd
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/service-workers/resources/crossorigin_media_iframe.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<body>
+<script>
+
+'use strict';
+
+function remoteize(relpath) {
+ let curdir = location.href.replace(/\/[^\/]*$/, '/')
+ return curdir.replace('://', '://www1.') + relpath
+}
+
+function create_media_promise() {
+ return new Promise((resolve, reject) => {
+ let video = document.createElement('video')
+ video.autoplay = true
+ video.muted = true
+ video.onplay = () => resolve('ok')
+ video.onerror = () => reject('video error')
+ video.src = remoteize('fetch_video.py')
+ })
+}
+
+</script>
+</body>
diff --git a/testing/web-platform/mozilla/tests/service-workers/resources/crossorigin_media_iframe_nonrange.html b/testing/web-platform/mozilla/tests/service-workers/resources/crossorigin_media_iframe_nonrange.html
new file mode 100644
index 0000000000..8e3c20fdeb
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/service-workers/resources/crossorigin_media_iframe_nonrange.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<body>
+<script>
+
+'use strict';
+
+function remoteize(relpath) {
+ let curdir = location.href.replace(/\/[^\/]*$/, '/')
+ return curdir.replace('://', '://www1.') + relpath
+}
+
+function create_media_promise() {
+ return new Promise((resolve, reject) => {
+ let image = document.createElement('img')
+ image.onload = () => resolve('ok')
+ image.onerror = () => reject('image error')
+ image.src = remoteize('blank.html') // sw will replace with an image
+ })
+}
+
+</script>
+</body>
diff --git a/testing/web-platform/mozilla/tests/service-workers/resources/empty.js b/testing/web-platform/mozilla/tests/service-workers/resources/empty.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/service-workers/resources/empty.js
diff --git a/testing/web-platform/mozilla/tests/service-workers/resources/fetch_video.py b/testing/web-platform/mozilla/tests/service-workers/resources/fetch_video.py
new file mode 100644
index 0000000000..541f00c019
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/service-workers/resources/fetch_video.py
@@ -0,0 +1,14 @@
+import os
+
+
+def main(request, response):
+ filename = os.path.join(request.doc_root, u"media", u"2x2-green.ogv")
+ body = open(filename, "rb").read()
+ length = len(body)
+ headers = [
+ (b"Content-Type", b"video/ogg"),
+ (b"Accept-Ranges", b"bytes"),
+ (b"Content-Length", b"%d" % length),
+ (b"Content-Range", b"bytes 0-%d/%d" % (length - 1, length)),
+ ]
+ return headers, body
diff --git a/testing/web-platform/mozilla/tests/service-workers/resources/green.png b/testing/web-platform/mozilla/tests/service-workers/resources/green.png
new file mode 100644
index 0000000000..28a1faab37
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/service-workers/resources/green.png
Binary files differ
diff --git a/testing/web-platform/mozilla/tests/service-workers/resources/intercept_media_sw.js b/testing/web-platform/mozilla/tests/service-workers/resources/intercept_media_sw.js
new file mode 100644
index 0000000000..6c373aa0de
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/service-workers/resources/intercept_media_sw.js
@@ -0,0 +1,14 @@
+'use strict';
+
+self.addEventListener('fetch', event => {
+ if (event.request.url.indexOf('fetch_video.py') !== -1) {
+ // A no-cors media range request /should not/ be intercepted.
+ // Respond with some text to cause an error.
+ event.respondWith(new Response('intercepted'));
+ }
+ else if (event.request.url.indexOf('blank.html') !== -1) {
+ // A no-cors media non-range request /should/ be intercepted.
+ // Respond with an image to avoid an error.
+ event.respondWith(fetch('green.png'));
+ }
+});
diff --git a/testing/web-platform/mozilla/tests/service-workers/update_completes_in_disconnected_global.https.html b/testing/web-platform/mozilla/tests/service-workers/update_completes_in_disconnected_global.https.html
new file mode 100644
index 0000000000..371fa81161
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/service-workers/update_completes_in_disconnected_global.https.html
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<title>Service Worker: Disconnected Global Update()</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>
+'use strict';
+
+/**
+ * Gecko-only pseudo-crash-test to verify that if we call
+ * ServiceWorkerRegistration.update() from a global that will be destroyed
+ * before any IPC call could return that we don't crash.
+ *
+ * We use an iframe to create a global that we can destroy on demand.
+ */
+promise_test(async function(t) {
+ const scope = 'resources/blank.html';
+ const sw_url = 'resources/empty.js';
+
+ let reg = await service_worker_unregister_and_register(t, sw_url, scope);
+ t.add_cleanup(function() {
+ return service_worker_unregister(t, scope);
+ });
+
+ // Wait for the worker to be activated so that we are in a known state.
+ await wait_for_state(t, reg.installing, 'activated');
+
+ let f = await with_iframe(scope);
+ let f_global = f.contentWindow;
+ // The frame should be controlled, although it's not necessary for the test.
+ assert_true(!!f_global.navigator.serviceWorker.controller);
+ t.add_cleanup(function() {
+ if (f) {
+ f.remove();
+ }
+ });
+
+ // Get a registration object that lives in the iframe's global.
+ let f_reg = await f_global.navigator.serviceWorker.getRegistration(reg.scope);
+ assert_true(!!f_reg, 'got registration');
+ assert_equals(reg.scope, f_reg.scope, 'Right registration');
+
+ // Trigger the update and destroy the global.
+ let update_resolved = false;
+ let update_rejected = false;
+
+ let update_promise = f_reg.update();
+ update_promise.then(
+ () => { update_resolved = true; }, () => { update_rejected = true; });
+
+ f.remove();
+ f = null;
+ f_global = null;
+
+ // Now we want to wait on an update call that should fire strictly after the
+ // update call above.
+ await reg.update();
+
+ assert_false(update_resolved, "frame update() should not have resolved");
+ assert_true(update_rejected, "frame update() should have rejected");
+}, 'ServiceWorkerRegistration.update() concluding in a disconnected global');
+
+</script>