diff options
Diffstat (limited to 'test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources')
17 files changed, 643 insertions, 0 deletions
diff --git a/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/close-worker.js b/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/close-worker.js new file mode 100644 index 0000000..41a8bc0 --- /dev/null +++ b/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/close-worker.js @@ -0,0 +1,5 @@ +importScripts('../../resources/worker-testharness.js'); + +test(function() { + assert_false('close' in self); +}, 'ServiceWorkerGlobalScope close operation'); diff --git a/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/error-worker.js b/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/error-worker.js new file mode 100644 index 0000000..f6838ff --- /dev/null +++ b/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/error-worker.js @@ -0,0 +1,12 @@ +var source; + +self.addEventListener('message', function(e) { + source = e.source; + throw 'testError'; +}); + +self.addEventListener('error', function(e) { + source.postMessage({ + error: e.error, filename: e.filename, message: e.message, lineno: e.lineno, + colno: e.colno}); +}); diff --git a/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/extendable-message-event-constructor-worker.js b/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/extendable-message-event-constructor-worker.js new file mode 100644 index 0000000..42da582 --- /dev/null +++ b/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/extendable-message-event-constructor-worker.js @@ -0,0 +1,197 @@ +importScripts('/resources/testharness.js'); + +const TEST_OBJECT = { wanwan: 123 }; +const CHANNEL1 = new MessageChannel(); +const CHANNEL2 = new MessageChannel(); +const PORTS = [CHANNEL1.port1, CHANNEL1.port2, CHANNEL2.port1]; +function createEvent(initializer) { + if (initializer === undefined) + return new ExtendableMessageEvent('type'); + return new ExtendableMessageEvent('type', initializer); +} + +// These test cases are mostly copied from the following file in the Chromium +// project (as of commit 848ad70823991e0f12b437d789943a4ab24d65bb): +// third_party/WebKit/LayoutTests/fast/events/constructors/message-event-constructor.html + +test(function() { + assert_false(createEvent().bubbles); + assert_false(createEvent().cancelable); + assert_equals(createEvent().data, null); + assert_equals(createEvent().origin, ''); + assert_equals(createEvent().lastEventId, ''); + assert_equals(createEvent().source, null); + assert_array_equals(createEvent().ports, []); +}, 'no initializer specified'); + +test(function() { + assert_false(createEvent({ bubbles: false }).bubbles); + assert_true(createEvent({ bubbles: true }).bubbles); +}, '`bubbles` is specified'); + +test(function() { + assert_false(createEvent({ cancelable: false }).cancelable); + assert_true(createEvent({ cancelable: true }).cancelable); +}, '`cancelable` is specified'); + +test(function() { + assert_equals(createEvent({ data: TEST_OBJECT }).data, TEST_OBJECT); + assert_equals(createEvent({ data: undefined }).data, null); + assert_equals(createEvent({ data: null }).data, null); + assert_equals(createEvent({ data: false }).data, false); + assert_equals(createEvent({ data: true }).data, true); + assert_equals(createEvent({ data: '' }).data, ''); + assert_equals(createEvent({ data: 'chocolate' }).data, 'chocolate'); + assert_equals(createEvent({ data: 12345 }).data, 12345); + assert_equals(createEvent({ data: 18446744073709551615 }).data, + 18446744073709552000); + assert_equals(createEvent({ data: NaN }).data, NaN); + // Note that valueOf() is not called, when the left hand side is + // evaluated. + assert_false( + createEvent({ data: { + valueOf: function() { return TEST_OBJECT; } } }).data == + TEST_OBJECT); + assert_equals(createEvent({ get data(){ return 123; } }).data, 123); + let thrown = { name: 'Error' }; + assert_throws_exactly(thrown, function() { + createEvent({ get data() { throw thrown; } }); }); +}, '`data` is specified'); + +test(function() { + assert_equals(createEvent({ origin: 'melancholy' }).origin, 'melancholy'); + assert_equals(createEvent({ origin: '' }).origin, ''); + assert_equals(createEvent({ origin: null }).origin, 'null'); + assert_equals(createEvent({ origin: false }).origin, 'false'); + assert_equals(createEvent({ origin: true }).origin, 'true'); + assert_equals(createEvent({ origin: 12345 }).origin, '12345'); + assert_equals( + createEvent({ origin: 18446744073709551615 }).origin, + '18446744073709552000'); + assert_equals(createEvent({ origin: NaN }).origin, 'NaN'); + assert_equals(createEvent({ origin: [] }).origin, ''); + assert_equals(createEvent({ origin: [1, 2, 3] }).origin, '1,2,3'); + assert_equals( + createEvent({ origin: { melancholy: 12345 } }).origin, + '[object Object]'); + // Note that valueOf() is not called, when the left hand side is + // evaluated. + assert_equals( + createEvent({ origin: { + valueOf: function() { return 'melancholy'; } } }).origin, + '[object Object]'); + assert_equals( + createEvent({ get origin() { return 123; } }).origin, '123'); + let thrown = { name: 'Error' }; + assert_throws_exactly(thrown, function() { + createEvent({ get origin() { throw thrown; } }); }); +}, '`origin` is specified'); + +test(function() { + assert_equals( + createEvent({ lastEventId: 'melancholy' }).lastEventId, 'melancholy'); + assert_equals(createEvent({ lastEventId: '' }).lastEventId, ''); + assert_equals(createEvent({ lastEventId: null }).lastEventId, 'null'); + assert_equals(createEvent({ lastEventId: false }).lastEventId, 'false'); + assert_equals(createEvent({ lastEventId: true }).lastEventId, 'true'); + assert_equals(createEvent({ lastEventId: 12345 }).lastEventId, '12345'); + assert_equals( + createEvent({ lastEventId: 18446744073709551615 }).lastEventId, + '18446744073709552000'); + assert_equals(createEvent({ lastEventId: NaN }).lastEventId, 'NaN'); + assert_equals(createEvent({ lastEventId: [] }).lastEventId, ''); + assert_equals( + createEvent({ lastEventId: [1, 2, 3] }).lastEventId, '1,2,3'); + assert_equals( + createEvent({ lastEventId: { melancholy: 12345 } }).lastEventId, + '[object Object]'); + // Note that valueOf() is not called, when the left hand side is + // evaluated. + assert_equals( + createEvent({ lastEventId: { + valueOf: function() { return 'melancholy'; } } }).lastEventId, + '[object Object]'); + assert_equals( + createEvent({ get lastEventId() { return 123; } }).lastEventId, + '123'); + let thrown = { name: 'Error' }; + assert_throws_exactly(thrown, function() { + createEvent({ get lastEventId() { throw thrown; } }); }); +}, '`lastEventId` is specified'); + +test(function() { + assert_equals(createEvent({ source: CHANNEL1.port1 }).source, CHANNEL1.port1); + assert_equals( + createEvent({ source: self.registration.active }).source, + self.registration.active); + assert_equals( + createEvent({ source: CHANNEL1.port1 }).source, CHANNEL1.port1); + assert_throws_js( + TypeError, function() { createEvent({ source: this }); }, + 'source should be Client or ServiceWorker or MessagePort'); +}, '`source` is specified'); + +test(function() { + // Valid message ports. + var passed_ports = createEvent({ ports: PORTS}).ports; + assert_equals(passed_ports[0], CHANNEL1.port1); + assert_equals(passed_ports[1], CHANNEL1.port2); + assert_equals(passed_ports[2], CHANNEL2.port1); + assert_array_equals(createEvent({ ports: [] }).ports, []); + assert_array_equals(createEvent({ ports: undefined }).ports, []); + + // Invalid message ports. + assert_throws_js(TypeError, + function() { createEvent({ ports: [1, 2, 3] }); }); + assert_throws_js(TypeError, + function() { createEvent({ ports: TEST_OBJECT }); }); + assert_throws_js(TypeError, + function() { createEvent({ ports: null }); }); + assert_throws_js(TypeError, + function() { createEvent({ ports: this }); }); + assert_throws_js(TypeError, + function() { createEvent({ ports: false }); }); + assert_throws_js(TypeError, + function() { createEvent({ ports: true }); }); + assert_throws_js(TypeError, + function() { createEvent({ ports: '' }); }); + assert_throws_js(TypeError, + function() { createEvent({ ports: 'chocolate' }); }); + assert_throws_js(TypeError, + function() { createEvent({ ports: 12345 }); }); + assert_throws_js(TypeError, + function() { createEvent({ ports: 18446744073709551615 }); }); + assert_throws_js(TypeError, + function() { createEvent({ ports: NaN }); }); + assert_throws_js(TypeError, + function() { createEvent({ get ports() { return 123; } }); }); + let thrown = { name: 'Error' }; + assert_throws_exactly(thrown, function() { + createEvent({ get ports() { throw thrown; } }); }); + // Note that valueOf() is not called, when the left hand side is + // evaluated. + var valueOf = function() { return PORTS; }; + assert_throws_js(TypeError, function() { + createEvent({ ports: { valueOf: valueOf } }); }); +}, '`ports` is specified'); + +test(function() { + var initializers = { + bubbles: true, + cancelable: true, + data: TEST_OBJECT, + origin: 'wonderful', + lastEventId: 'excellent', + source: CHANNEL1.port1, + ports: PORTS + }; + assert_equals(createEvent(initializers).bubbles, true); + assert_equals(createEvent(initializers).cancelable, true); + assert_equals(createEvent(initializers).data, TEST_OBJECT); + assert_equals(createEvent(initializers).origin, 'wonderful'); + assert_equals(createEvent(initializers).lastEventId, 'excellent'); + assert_equals(createEvent(initializers).source, CHANNEL1.port1); + assert_equals(createEvent(initializers).ports[0], PORTS[0]); + assert_equals(createEvent(initializers).ports[1], PORTS[1]); + assert_equals(createEvent(initializers).ports[2], PORTS[2]); +}, 'all initial values are specified'); diff --git a/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/extendable-message-event-loopback-worker.js b/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/extendable-message-event-loopback-worker.js new file mode 100644 index 0000000..13cae88 --- /dev/null +++ b/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/extendable-message-event-loopback-worker.js @@ -0,0 +1,36 @@ +importScripts('./extendable-message-event-utils.js'); + +self.addEventListener('message', function(event) { + switch (event.data.type) { + case 'start': + self.registration.active.postMessage( + {type: '1st', client_id: event.source.id}); + break; + case '1st': + // 1st loopback message via ServiceWorkerRegistration.active. + var results = { + trial: 1, + event: ExtendableMessageEventUtils.serialize(event) + }; + var client_id = event.data.client_id; + event.source.postMessage({type: '2nd', client_id: client_id}); + event.waitUntil(clients.get(client_id) + .then(function(client) { + client.postMessage({type: 'record', results: results}); + })); + break; + case '2nd': + // 2nd loopback message via ExtendableMessageEvent.source. + var results = { + trial: 2, + event: ExtendableMessageEventUtils.serialize(event) + }; + var client_id = event.data.client_id; + event.waitUntil(clients.get(client_id) + .then(function(client) { + client.postMessage({type: 'record', results: results}); + client.postMessage({type: 'finish'}); + })); + break; + } + }); diff --git a/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/extendable-message-event-ping-worker.js b/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/extendable-message-event-ping-worker.js new file mode 100644 index 0000000..d07b229 --- /dev/null +++ b/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/extendable-message-event-ping-worker.js @@ -0,0 +1,23 @@ +importScripts('./extendable-message-event-utils.js'); + +self.addEventListener('message', function(event) { + switch (event.data.type) { + case 'start': + // Send a ping message to another service worker. + self.registration.waiting.postMessage( + {type: 'ping', client_id: event.source.id}); + break; + case 'pong': + var results = { + pingOrPong: 'pong', + event: ExtendableMessageEventUtils.serialize(event) + }; + var client_id = event.data.client_id; + event.waitUntil(clients.get(client_id) + .then(function(client) { + client.postMessage({type: 'record', results: results}); + client.postMessage({type: 'finish'}); + })); + break; + } + }); diff --git a/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/extendable-message-event-pong-worker.js b/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/extendable-message-event-pong-worker.js new file mode 100644 index 0000000..5e9669e --- /dev/null +++ b/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/extendable-message-event-pong-worker.js @@ -0,0 +1,18 @@ +importScripts('./extendable-message-event-utils.js'); + +self.addEventListener('message', function(event) { + switch (event.data.type) { + case 'ping': + var results = { + pingOrPong: 'ping', + event: ExtendableMessageEventUtils.serialize(event) + }; + var client_id = event.data.client_id; + event.waitUntil(clients.get(client_id) + .then(function(client) { + client.postMessage({type: 'record', results: results}); + event.source.postMessage({type: 'pong', client_id: client_id}); + })); + break; + } + }); diff --git a/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/extendable-message-event-utils.js b/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/extendable-message-event-utils.js new file mode 100644 index 0000000..d6a3b48 --- /dev/null +++ b/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/extendable-message-event-utils.js @@ -0,0 +1,78 @@ +var ExtendableMessageEventUtils = {}; + +// Create a representation of a given ExtendableMessageEvent that is suitable +// for transmission via the `postMessage` API. +ExtendableMessageEventUtils.serialize = function(event) { + var ports = event.ports.map(function(port) { + return { constructor: { name: port.constructor.name } }; + }); + return { + constructor: { + name: event.constructor.name + }, + origin: event.origin, + lastEventId: event.lastEventId, + source: { + constructor: { + name: event.source.constructor.name + }, + url: event.source.url, + frameType: event.source.frameType, + visibilityState: event.source.visibilityState, + focused: event.source.focused + }, + ports: ports + }; +}; + +// Compare the actual and expected values of an ExtendableMessageEvent that has +// been transformed using the `serialize` function defined in this file. +ExtendableMessageEventUtils.assert_equals = function(actual, expected) { + assert_equals( + actual.constructor.name, expected.constructor.name, 'event constructor' + ); + assert_equals(actual.origin, expected.origin, 'event `origin` property'); + assert_equals( + actual.lastEventId, + expected.lastEventId, + 'event `lastEventId` property' + ); + + assert_equals( + actual.source.constructor.name, + expected.source.constructor.name, + 'event `source` property constructor' + ); + assert_equals( + actual.source.url, expected.source.url, 'event `source` property `url`' + ); + assert_equals( + actual.source.frameType, + expected.source.frameType, + 'event `source` property `frameType`' + ); + assert_equals( + actual.source.visibilityState, + expected.source.visibilityState, + 'event `source` property `visibilityState`' + ); + assert_equals( + actual.source.focused, + expected.source.focused, + 'event `source` property `focused`' + ); + + assert_equals( + actual.ports.length, + expected.ports.length, + 'event `ports` property length' + ); + + for (var idx = 0; idx < expected.ports.length; ++idx) { + assert_equals( + actual.ports[idx].constructor.name, + expected.ports[idx].constructor.name, + 'MessagePort #' + idx + ' constructor' + ); + } +}; diff --git a/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/extendable-message-event-worker.js b/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/extendable-message-event-worker.js new file mode 100644 index 0000000..f5e7647 --- /dev/null +++ b/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/extendable-message-event-worker.js @@ -0,0 +1,5 @@ +importScripts('./extendable-message-event-utils.js'); + +self.addEventListener('message', function(event) { + event.source.postMessage(ExtendableMessageEventUtils.serialize(event)); + }); diff --git a/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/postmessage-loopback-worker.js b/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/postmessage-loopback-worker.js new file mode 100644 index 0000000..083e9aa --- /dev/null +++ b/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/postmessage-loopback-worker.js @@ -0,0 +1,15 @@ +self.addEventListener('message', function(event) { + if ('port' in event.data) { + var port = event.data.port; + + var channel = new MessageChannel(); + channel.port1.onmessage = function(event) { + if ('pong' in event.data) + port.postMessage(event.data.pong); + }; + self.registration.active.postMessage({ping: channel.port2}, + [channel.port2]); + } else if ('ping' in event.data) { + event.data.ping.postMessage({pong: 'OK'}); + } + }); diff --git a/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/postmessage-ping-worker.js b/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/postmessage-ping-worker.js new file mode 100644 index 0000000..ebb1ecc --- /dev/null +++ b/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/postmessage-ping-worker.js @@ -0,0 +1,15 @@ +self.addEventListener('message', function(event) { + if ('port' in event.data) { + var port = event.data.port; + + var channel = new MessageChannel(); + channel.port1.onmessage = function(event) { + if ('pong' in event.data) + port.postMessage(event.data.pong); + }; + + // Send a ping message to another service worker. + self.registration.waiting.postMessage({ping: channel.port2}, + [channel.port2]); + } + }); diff --git a/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/postmessage-pong-worker.js b/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/postmessage-pong-worker.js new file mode 100644 index 0000000..4a0d90b --- /dev/null +++ b/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/postmessage-pong-worker.js @@ -0,0 +1,4 @@ +self.addEventListener('message', function(event) { + if ('ping' in event.data) + event.data.ping.postMessage({pong: 'OK'}); + }); diff --git a/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/registration-attribute-newer-worker.js b/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/registration-attribute-newer-worker.js new file mode 100644 index 0000000..44f3e2e --- /dev/null +++ b/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/registration-attribute-newer-worker.js @@ -0,0 +1,33 @@ +// TODO(nhiroki): stop using global states because service workers can be killed +// at any point. Instead, we could post a message to the page on each event via +// Client object (http://crbug.com/558244). +var results = []; + +function stringify(worker) { + return worker ? worker.scriptURL : 'empty'; +} + +function record(event_name) { + results.push(event_name); + results.push(' installing: ' + stringify(self.registration.installing)); + results.push(' waiting: ' + stringify(self.registration.waiting)); + results.push(' active: ' + stringify(self.registration.active)); +} + +record('evaluate'); + +self.registration.addEventListener('updatefound', function() { + record('updatefound'); + var worker = self.registration.installing; + self.registration.installing.addEventListener('statechange', function() { + record('statechange(' + worker.state + ')'); + }); + }); + +self.addEventListener('install', function(e) { record('install'); }); + +self.addEventListener('activate', function(e) { record('activate'); }); + +self.addEventListener('message', function(e) { + e.data.port.postMessage(results); + }); diff --git a/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/registration-attribute-worker.js b/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/registration-attribute-worker.js new file mode 100644 index 0000000..315f437 --- /dev/null +++ b/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/registration-attribute-worker.js @@ -0,0 +1,139 @@ +importScripts('../../resources/test-helpers.sub.js'); +importScripts('../../resources/worker-testharness.js'); + +// TODO(nhiroki): stop using global states because service workers can be killed +// at any point. Instead, we could post a message to the page on each event via +// Client object (http://crbug.com/558244). +var events_seen = []; + +// TODO(nhiroki): Move these assertions to registration-attribute.html because +// an assertion failure on the worker is not shown on the result page and +// handled as timeout. See registration-attribute-newer-worker.js for example. + +assert_equals( + self.registration.scope, + normalizeURL('scope/registration-attribute'), + 'On worker script evaluation, registration attribute should be set'); +assert_equals( + self.registration.installing, + null, + 'On worker script evaluation, installing worker should be null'); +assert_equals( + self.registration.waiting, + null, + 'On worker script evaluation, waiting worker should be null'); +assert_equals( + self.registration.active, + null, + 'On worker script evaluation, active worker should be null'); + +self.registration.addEventListener('updatefound', function() { + events_seen.push('updatefound'); + + assert_equals( + self.registration.scope, + normalizeURL('scope/registration-attribute'), + 'On updatefound event, registration attribute should be set'); + assert_equals( + self.registration.installing.scriptURL, + normalizeURL('registration-attribute-worker.js'), + 'On updatefound event, installing worker should be set'); + assert_equals( + self.registration.waiting, + null, + 'On updatefound event, waiting worker should be null'); + assert_equals( + self.registration.active, + null, + 'On updatefound event, active worker should be null'); + + assert_equals( + self.registration.installing.state, + 'installing', + 'On updatefound event, worker should be in the installing state'); + + var worker = self.registration.installing; + self.registration.installing.addEventListener('statechange', function() { + events_seen.push('statechange(' + worker.state + ')'); + }); + }); + +self.addEventListener('install', function(e) { + events_seen.push('install'); + + assert_equals( + self.registration.scope, + normalizeURL('scope/registration-attribute'), + 'On install event, registration attribute should be set'); + assert_equals( + self.registration.installing.scriptURL, + normalizeURL('registration-attribute-worker.js'), + 'On install event, installing worker should be set'); + assert_equals( + self.registration.waiting, + null, + 'On install event, waiting worker should be null'); + assert_equals( + self.registration.active, + null, + 'On install event, active worker should be null'); + + assert_equals( + self.registration.installing.state, + 'installing', + 'On install event, worker should be in the installing state'); + }); + +self.addEventListener('activate', function(e) { + events_seen.push('activate'); + + assert_equals( + self.registration.scope, + normalizeURL('scope/registration-attribute'), + 'On activate event, registration attribute should be set'); + assert_equals( + self.registration.installing, + null, + 'On activate event, installing worker should be null'); + assert_equals( + self.registration.waiting, + null, + 'On activate event, waiting worker should be null'); + assert_equals( + self.registration.active.scriptURL, + normalizeURL('registration-attribute-worker.js'), + 'On activate event, active worker should be set'); + + assert_equals( + self.registration.active.state, + 'activating', + 'On activate event, worker should be in the activating state'); + }); + +self.addEventListener('fetch', function(e) { + events_seen.push('fetch'); + + assert_equals( + self.registration.scope, + normalizeURL('scope/registration-attribute'), + 'On fetch event, registration attribute should be set'); + assert_equals( + self.registration.installing, + null, + 'On fetch event, installing worker should be null'); + assert_equals( + self.registration.waiting, + null, + 'On fetch event, waiting worker should be null'); + assert_equals( + self.registration.active.scriptURL, + normalizeURL('registration-attribute-worker.js'), + 'On fetch event, active worker should be set'); + + assert_equals( + self.registration.active.state, + 'activated', + 'On fetch event, worker should be in the activated state'); + + e.respondWith(new Response(events_seen)); + }); diff --git a/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/unregister-controlling-worker.html b/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/unregister-controlling-worker.html new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/unregister-controlling-worker.html diff --git a/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/unregister-worker.js b/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/unregister-worker.js new file mode 100644 index 0000000..6da397d --- /dev/null +++ b/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/unregister-worker.js @@ -0,0 +1,25 @@ +function matchQuery(query) { + return self.location.href.indexOf(query) != -1; +} + +if (matchQuery('?evaluation')) + self.registration.unregister(); + +self.addEventListener('install', function(e) { + if (matchQuery('?install')) { + // Don't do waitUntil(unregister()) as that would deadlock as specified. + self.registration.unregister(); + } + }); + +self.addEventListener('activate', function(e) { + if (matchQuery('?activate')) + e.waitUntil(self.registration.unregister()); + }); + +self.addEventListener('message', function(e) { + e.waitUntil(self.registration.unregister() + .then(function(result) { + e.data.port.postMessage({result: result}); + })); + }); diff --git a/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/update-worker.js b/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/update-worker.js new file mode 100644 index 0000000..8be8a1f --- /dev/null +++ b/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/update-worker.js @@ -0,0 +1,22 @@ +var events_seen = []; + +self.registration.addEventListener('updatefound', function() { + events_seen.push('updatefound'); + }); + +self.addEventListener('activate', function(e) { + events_seen.push('activate'); + }); + +self.addEventListener('fetch', function(e) { + events_seen.push('fetch'); + e.respondWith(new Response(events_seen)); + }); + +self.addEventListener('message', function(e) { + events_seen.push('message'); + self.registration.update(); + }); + +// update() during the script evaluation should be ignored. +self.registration.update(); diff --git a/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/update-worker.py b/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/update-worker.py new file mode 100644 index 0000000..8a87e1b --- /dev/null +++ b/test/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/update-worker.py @@ -0,0 +1,16 @@ +import os +import time + +from wptserve.utils import isomorphic_decode + +def main(request, response): + # update() does not bypass cache so set the max-age to 0 such that update() + # can find a new version in the network. + headers = [(b'Cache-Control', b'max-age: 0'), + (b'Content-Type', b'application/javascript')] + with open(os.path.join(os.path.dirname(isomorphic_decode(__file__)), + u'update-worker.js'), u'r') as file: + script = file.read() + # Return a different script for each access. + return headers, u'// %s\n%s' % (time.time(), script) + |