diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /testing/web-platform/tests/background-fetch/service_workers | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/background-fetch/service_workers')
4 files changed, 151 insertions, 0 deletions
diff --git a/testing/web-platform/tests/background-fetch/service_workers/sw-abort.js b/testing/web-platform/tests/background-fetch/service_workers/sw-abort.js new file mode 100644 index 0000000000..c61377758d --- /dev/null +++ b/testing/web-platform/tests/background-fetch/service_workers/sw-abort.js @@ -0,0 +1,23 @@ +importScripts('sw-helpers.js'); + +async function getFetchResult(record) { + try { + await record.responseReady; + } catch (e) { + return { + response: false, + name: e.name, + }; + } + + return { + response: true, + }; +} +self.addEventListener('backgroundfetchabort', event => { + event.waitUntil( + event.registration.matchAll() + .then(records => + Promise.all(records.map(record => getFetchResult(record)))) + .then(results => sendMessageToDocument({results}))); +}); diff --git a/testing/web-platform/tests/background-fetch/service_workers/sw-helpers.js b/testing/web-platform/tests/background-fetch/service_workers/sw-helpers.js new file mode 100644 index 0000000000..e4c772135d --- /dev/null +++ b/testing/web-platform/tests/background-fetch/service_workers/sw-helpers.js @@ -0,0 +1,31 @@ +// The source to post setup and completion results to. +let source = null; + +function sendMessageToDocument(msg) { + source.postMessage(msg); +} + +// This is needed to create a local javascript object identical to the +// one returned by a BackgroundFetchEvent, so that it can be serialized +// and transmitted from the service worker context to the document. +function cloneRegistration(registration) { + function deepCopy(src) { + if (typeof src !== 'object' || src === null) + return src; + var dst = Array.isArray(src) ? [] : {}; + for (var property in src) { + if (typeof src[property] === 'function') + continue; + dst[property] = deepCopy(src[property]); + } + return dst; + } + + return deepCopy(registration); +} + +// Notify the document that the SW is registered and ready. +self.addEventListener('message', event => { + source = event.source; + sendMessageToDocument('ready'); +}); diff --git a/testing/web-platform/tests/background-fetch/service_workers/sw-update-ui.js b/testing/web-platform/tests/background-fetch/service_workers/sw-update-ui.js new file mode 100644 index 0000000000..3848dc4402 --- /dev/null +++ b/testing/web-platform/tests/background-fetch/service_workers/sw-update-ui.js @@ -0,0 +1,33 @@ +importScripts('/resources/testharness.js'); +importScripts('sw-helpers.js'); + +async function updateUI(event) { + let updateParams = []; + switch (event.registration.id) { + case 'update-once': + updateParams = [{title: 'Title1'}]; + break; + case 'update-twice': + updateParams = [{title: 'Title1'}, {title: 'Title2'}]; + break; + } + + return Promise.all(updateParams.map(param => event.updateUI(param))) + .then(() => 'update success') + .catch(e => e.name); +} + +self.addEventListener('backgroundfetchsuccess', event => { + if (event.registration.id === 'update-inactive') { + // Post an async task before calling updateUI from the inactive event. + // Any async behaviour outside `waitUntil` should mark the event as + // inactive, and subsequent calls to `updateUI` should fail. + new Promise(r => step_timeout(r, 0)) + .then(() => event.updateUI({ title: 'New title' })) + .catch(e => sendMessageToDocument({ update: e.name })); + return; + } + + event.waitUntil(updateUI(event) + .then(update => sendMessageToDocument({ update }))); +}); diff --git a/testing/web-platform/tests/background-fetch/service_workers/sw.js b/testing/web-platform/tests/background-fetch/service_workers/sw.js new file mode 100644 index 0000000000..be43629f03 --- /dev/null +++ b/testing/web-platform/tests/background-fetch/service_workers/sw.js @@ -0,0 +1,64 @@ + +importScripts('sw-helpers.js'); + +async function getFetchResult(record) { + const response = await record.responseReady.catch(() => null); + if (!response) return null; + + return { + url: response.url, + status: response.status, + text: await response.text().catch(() => 'error'), + }; +} + +function handleBackgroundFetchEvent(event) { + let matchFunction = null; + + switch (event.registration.id) { + case 'matchexistingrequest': + matchFunction = event.registration.match.bind( + event.registration, '/background-fetch/resources/feature-name.txt'); + break; + case 'matchexistingrequesttwice': + matchFunction = (async () => { + const match1 = await event.registration.match('/background-fetch/resources/feature-name.txt'); + const match2 = await event.registration.match('/background-fetch/resources/feature-name.txt'); + return [match1, match2]; + }).bind(event.registration); + break; + case 'matchmissingrequest': + matchFunction = event.registration.match.bind( + event.registration, '/background-fetch/resources/missing.txt'); + break; + default: + matchFunction = event.registration.matchAll.bind(event.registration); + break; + } + + event.waitUntil( + matchFunction() + // Format `match(All)?` function results. + .then(records => { + if (!records) return []; // Nothing was matched. + if (!records.map) return [records]; // One entry was returned. + return records; // Already in a list. + }) + // Extract responses. + .then(records => + Promise.all(records.map(record => getFetchResult(record)))) + // Clone registration and send message. + .then(results => { + const registrationCopy = cloneRegistration(event.registration); + sendMessageToDocument( + { type: event.type, eventRegistration: registrationCopy, results }) + }) + .catch(error => { + sendMessageToDocument( + { type: event.type, eventRegistration:{}, results:[], error:true }) + })); +} + +self.addEventListener('backgroundfetchsuccess', handleBackgroundFetchEvent); +self.addEventListener('backgroundfetchfail', handleBackgroundFetchEvent); +self.addEventListener('backgroundfetchabort', handleBackgroundFetchEvent); |