summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/background-fetch/service_workers
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/background-fetch/service_workers')
-rw-r--r--testing/web-platform/tests/background-fetch/service_workers/sw-abort.js23
-rw-r--r--testing/web-platform/tests/background-fetch/service_workers/sw-helpers.js31
-rw-r--r--testing/web-platform/tests/background-fetch/service_workers/sw-update-ui.js33
-rw-r--r--testing/web-platform/tests/background-fetch/service_workers/sw.js64
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);