diff --git a/benchmark/misc/startup-core.js b/benchmark/misc/startup-core.js index 414b00176ad2..d673d415b505 100644 --- a/benchmark/misc/startup-core.js +++ b/benchmark/misc/startup-core.js @@ -64,6 +64,7 @@ function main({ n, script, mode }) { const warmup = 3; const state = { n, finished: -warmup }; if (mode === 'worker') { + // eslint-disable-next-line no-global-assign Worker = require('worker_threads').Worker; spawnWorker(script, bench, state); } else { diff --git a/doc/api/cli.md b/doc/api/cli.md index 9434e19d3b73..c41fe51d8466 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -1527,6 +1527,14 @@ changes: Enable experimental WebAssembly System Interface (WASI) support. +### `--experimental-web-worker` + + + +Enable experimental support for the Web Worker API. + ### `--experimental-worker-inspection` + +> Stability: 1 - Experimental. Enable this API with the +> [`--experimental-web-worker`][] CLI flag. + +A browser-compatible implementation of Web Workers of the [HTML Standard][], +implemented on top of [`node:worker_threads`][]. Threads created with it +are given the {DedicatedWorkerGlobalScope} API (`self`, +`name`, `location`, `navigator`, `postMessage()`, `close()`, and +`importScripts()`), in addition to the usual Node.js globals, such as `process`. + +```js +// worker.js +addEventListener('message', (event) => { + postMessage(`${event.data} from ${name}!`); +}); +``` + +```js +// main.js +const worker = new Worker('./worker.js', { name: 'greeter' }); + +worker.addEventListener('message', (event) => { + console.log(event.data); // Prints: Hello from greeter! + worker.terminate(); +}); + +worker.postMessage('Hello'); +``` + +Because their lifetime and sharing model depend on origins and +browsing contexts, Node.js does not currently implement `SharedWorker`. + +### Loading worker scripts + +Worker scripts are read synchronously from the local file system or from +memory rather than fetched over the network, which changes which URLs are +accepted and how failures are reported: + +* `new Worker()` and `importScripts()` accept only `file:`, `data:`, and + `blob:` URLs. Any other scheme makes `new Worker()` throw a + `NotSupportedError` and `importScripts()` throw a `NetworkError`. +* A script that cannot be read makes `importScripts()` throw a `NetworkError`; + for `new Worker()` it fires an `error` event at the `Worker` object. +* Redirects, the `nosniff` check, and HTTP MIME type validation do not apply. + MIME types are validated only for `data:` and `blob:` URLs. The + `credentials` option is validated for API compatibility but has no effect, + since no network request is made. +* On the main thread, relative script URLs are resolved against the current + working directory, because there is no document base URL. Within a worker + they are resolved against the worker's own URL (as is done in the spec). +* For `blob:` URLs, the script must be held in memory, so blobs backed by a file, + such as those returned by [`fs.openAsBlob()`][], cannot be used. + +### Differences from the HTML Standard + +Besides script loading, mentioned above: + +* Node.js has no origin model, so same-origin and cross-origin distinctions do + not exist and `location.origin` is `'null'` for every supported scheme. +* `close()` terminates the worker immediately instead of following the + specification's "closing flag" algorithm, so code remaining in the current + task after `close()` is not executed. +* The worker global is the normal Node.js global object with + `DedicatedWorkerGlobalScope` inserted into its prototype chain, rather than + a fresh global created from the interface. Node.js globals such as + `process`, `Buffer`, and `require()` remain available to worker scripts. +* `ErrorEvent`s dispatched at `Worker` instances include `message` and + `error`, but `filename`, `lineno`, and `colno` are always `''`, `0`, and + `0`. An uncaught exception terminates the worker thread, and an unhandled + `error` event is not propagated further: it neither reaches the parent's + global scope nor affects the exit code of the process. +* The following {WorkerGlobalScope} events are never dispatched, although + their handler properties exist: `languagechange`, `online`, and `offline`, + since these concepts do not exist in Node.js; `rejectionhandled` and + `unhandledrejection`, since Node.js exposes the equivalent does not + implement the `PromiseRejectionEvent` interface or the per-rejection + `preventDefault()` behavior required by the HTML Standard. + +### Web Workers and `node:worker_threads` + +Every Web Worker is backed by a [`node:worker_threads`][] {Worker}, so the +two APIs share their threading, structured clone, and transfer semantics. +Inside a worker, \[`worker_threads.parentPort`]\[] is the port behind +`self.postMessage()` and the worker's `message` events, `isMainThread` is +`false`, and `workerData` is `undefined`. + +As a rule of thumb, use [`node:worker_threads`][] directly when a program +needs `workerData`, a custom `env` or `execArgv`, resource limits, stdio +redirection, the `'online'` and `'exit'` events, or `worker.threadId`; +`Worker` accepts only the `name`, `type`, and `credentials` options and, +per the specification, its `terminate()` returns `undefined`, rather than +a promise. Threads started through [`node:worker_threads`][] are ordinary +Node.js threads and do not get the worker global scope APIs. + ## Class: `WritableStream` + + + + + + diff --git a/test/fixtures/wpt/service-workers/cache-storage/resources/blank.html b/test/fixtures/wpt/service-workers/cache-storage/resources/blank.html new file mode 100644 index 000000000000..a3c3a4689a62 --- /dev/null +++ b/test/fixtures/wpt/service-workers/cache-storage/resources/blank.html @@ -0,0 +1,2 @@ + +Empty doc diff --git a/test/fixtures/wpt/service-workers/cache-storage/resources/cache-keys-attributes-for-service-worker.js b/test/fixtures/wpt/service-workers/cache-storage/resources/cache-keys-attributes-for-service-worker.js new file mode 100644 index 000000000000..ee574d2cb77a --- /dev/null +++ b/test/fixtures/wpt/service-workers/cache-storage/resources/cache-keys-attributes-for-service-worker.js @@ -0,0 +1,22 @@ +self.addEventListener('fetch', (event) => { + const params = new URL(event.request.url).searchParams; + if (params.has('ignore')) { + return; + } + if (!params.has('name')) { + event.respondWith(Promise.reject(TypeError('No name is provided.'))); + return; + } + + event.respondWith(Promise.resolve().then(async () => { + const name = params.get('name'); + await caches.delete('foo'); + const cache = await caches.open('foo'); + await cache.put(event.request, new Response('hello')); + const keys = await cache.keys(); + + const original = event.request[name]; + const stored = keys[0][name]; + return new Response(`original: ${original}, stored: ${stored}`); + })); + }); diff --git a/test/fixtures/wpt/service-workers/cache-storage/resources/common-worker.js b/test/fixtures/wpt/service-workers/cache-storage/resources/common-worker.js new file mode 100644 index 000000000000..d0e8544b56c2 --- /dev/null +++ b/test/fixtures/wpt/service-workers/cache-storage/resources/common-worker.js @@ -0,0 +1,15 @@ +self.onmessage = function(e) { + var cache_name = e.data.name; + + self.caches.open(cache_name) + .then(function(cache) { + return Promise.all([ + cache.put('https://example.com/a', new Response('a')), + cache.put('https://example.com/b', new Response('b')), + cache.put('https://example.com/c', new Response('c')) + ]); + }) + .then(function() { + self.postMessage('ok'); + }); +}; diff --git a/test/fixtures/wpt/service-workers/cache-storage/resources/credentials-iframe.html b/test/fixtures/wpt/service-workers/cache-storage/resources/credentials-iframe.html new file mode 100644 index 000000000000..00702df9e5b1 --- /dev/null +++ b/test/fixtures/wpt/service-workers/cache-storage/resources/credentials-iframe.html @@ -0,0 +1,38 @@ + + +Controlled frame for Cache API test with credentials + + +Hello? Yes, this is iframe. + diff --git a/test/fixtures/wpt/service-workers/cache-storage/resources/credentials-worker.js b/test/fixtures/wpt/service-workers/cache-storage/resources/credentials-worker.js new file mode 100644 index 000000000000..43965b5fe4c9 --- /dev/null +++ b/test/fixtures/wpt/service-workers/cache-storage/resources/credentials-worker.js @@ -0,0 +1,59 @@ +var cache_name = 'credentials'; + +function assert_equals(actual, expected, message) { + if (!Object.is(actual, expected)) + throw Error(message + ': expected: ' + expected + ', actual: ' + actual); +} + +self.onfetch = function(e) { + if (!/\.txt$/.test(e.request.url)) return; + var content = e.request.url; + var cache; + e.respondWith( + self.caches.open(cache_name) + .then(function(result) { + cache = result; + return cache.put(e.request, new Response(content)); + }) + + .then(function() { return cache.match(e.request); }) + .then(function(result) { return result.text(); }) + .then(function(text) { + assert_equals(text, content, 'Cache.match() body should match'); + }) + + .then(function() { return cache.matchAll(e.request); }) + .then(function(results) { + assert_equals(results.length, 1, 'Should have one response'); + return results[0].text(); + }) + .then(function(text) { + assert_equals(text, content, 'Cache.matchAll() body should match'); + }) + + .then(function() { return self.caches.match(e.request); }) + .then(function(result) { return result.text(); }) + .then(function(text) { + assert_equals(text, content, 'CacheStorage.match() body should match'); + }) + + .then(function() { + return new Response('dummy'); + }) + ); +}; + +self.onmessage = function(e) { + if (e.data === 'keys') { + self.caches.open(cache_name) + .then(function(cache) { return cache.keys(); }) + .then(function(requests) { + var urls = requests.map(function(request) { return request.url; }); + self.clients.matchAll().then(function(clients) { + clients.forEach(function(client) { + client.postMessage(urls); + }); + }); + }); + } +}; diff --git a/test/fixtures/wpt/service-workers/cache-storage/resources/iframe.html b/test/fixtures/wpt/service-workers/cache-storage/resources/iframe.html new file mode 100644 index 000000000000..a2f1e502bb39 --- /dev/null +++ b/test/fixtures/wpt/service-workers/cache-storage/resources/iframe.html @@ -0,0 +1,18 @@ + +ok + diff --git a/test/fixtures/wpt/service-workers/cache-storage/resources/simple.txt b/test/fixtures/wpt/service-workers/cache-storage/resources/simple.txt new file mode 100644 index 000000000000..9e3cb91fb9b9 --- /dev/null +++ b/test/fixtures/wpt/service-workers/cache-storage/resources/simple.txt @@ -0,0 +1 @@ +a simple text file diff --git a/test/fixtures/wpt/service-workers/cache-storage/resources/test-helpers.js b/test/fixtures/wpt/service-workers/cache-storage/resources/test-helpers.js new file mode 100644 index 000000000000..050ac0b54245 --- /dev/null +++ b/test/fixtures/wpt/service-workers/cache-storage/resources/test-helpers.js @@ -0,0 +1,272 @@ +(function() { + var next_cache_index = 1; + + // Returns a promise that resolves to a newly created Cache object. The + // returned Cache will be destroyed when |test| completes. + function create_temporary_cache(test) { + var uniquifier = String(++next_cache_index); + var cache_name = self.location.pathname + '/' + uniquifier; + + test.add_cleanup(function() { + self.caches.delete(cache_name); + }); + + return self.caches.delete(cache_name) + .then(function() { + return self.caches.open(cache_name); + }); + } + + self.create_temporary_cache = create_temporary_cache; +})(); + +// Runs |test_function| with a temporary unique Cache passed in as the only +// argument. The function is run as a part of Promise chain owned by +// promise_test(). As such, it is expected to behave in a manner identical (with +// the exception of the argument) to a function passed into promise_test(). +// +// E.g.: +// cache_test(function(cache) { +// // Do something with |cache|, which is a Cache object. +// }, "Some Cache test"); +function cache_test(test_function, description) { + promise_test(function(test) { + return create_temporary_cache(test) + .then(function(cache) { return test_function(cache, test); }); + }, description); +} + +// A set of Request/Response pairs to be used with prepopulated_cache_test(). +var simple_entries = [ + { + name: 'a', + request: new Request('http://example.com/a'), + response: new Response('') + }, + + { + name: 'b', + request: new Request('http://example.com/b'), + response: new Response('') + }, + + { + name: 'a_with_query', + request: new Request('http://example.com/a?q=r'), + response: new Response('') + }, + + { + name: 'A', + request: new Request('http://example.com/A'), + response: new Response('') + }, + + { + name: 'a_https', + request: new Request('https://example.com/a'), + response: new Response('') + }, + + { + name: 'a_org', + request: new Request('http://example.org/a'), + response: new Response('') + }, + + { + name: 'cat', + request: new Request('http://example.com/cat'), + response: new Response('') + }, + + { + name: 'catmandu', + request: new Request('http://example.com/catmandu'), + response: new Response('') + }, + + { + name: 'cat_num_lives', + request: new Request('http://example.com/cat?lives=9'), + response: new Response('') + }, + + { + name: 'cat_in_the_hat', + request: new Request('http://example.com/cat/in/the/hat'), + response: new Response('') + }, + + { + name: 'non_2xx_response', + request: new Request('http://example.com/non2xx'), + response: new Response('', {status: 404, statusText: 'nope'}) + }, + + { + name: 'error_response', + request: new Request('http://example.com/error'), + response: Response.error() + }, +]; + +// A set of Request/Response pairs to be used with prepopulated_cache_test(). +// These contain a mix of test cases that use Vary headers. +var vary_entries = [ + { + name: 'vary_cookie_is_cookie', + request: new Request('http://example.com/c', + {headers: {'Cookies': 'is-for-cookie'}}), + response: new Response('', + {headers: {'Vary': 'Cookies'}}) + }, + + { + name: 'vary_cookie_is_good', + request: new Request('http://example.com/c', + {headers: {'Cookies': 'is-good-enough-for-me'}}), + response: new Response('', + {headers: {'Vary': 'Cookies'}}) + }, + + { + name: 'vary_cookie_absent', + request: new Request('http://example.com/c'), + response: new Response('', + {headers: {'Vary': 'Cookies'}}) + } +]; + +// Run |test_function| with a Cache object and a map of entries. Prior to the +// call, the Cache is populated by cache entries from |entries|. The latter is +// expected to be an Object mapping arbitrary keys to objects of the form +// {request: , response: }. Entries are +// serially added to the cache in the order specified. +// +// |test_function| should return a Promise that can be used with promise_test. +function prepopulated_cache_test(entries, test_function, description) { + cache_test(function(cache) { + var p = Promise.resolve(); + var hash = {}; + entries.forEach(function(entry) { + hash[entry.name] = entry; + p = p.then(function() { + return cache.put(entry.request.clone(), entry.response.clone()) + .catch(function(e) { + assert_unreached( + 'Test setup failed for entry ' + entry.name + ': ' + e + ); + }); + }); + }); + return p + .then(function() { + assert_equals(Object.keys(hash).length, entries.length); + }) + .then(function() { + return test_function(cache, hash); + }); + }, description); +} + +// Helper for testing with Headers objects. Compares Headers instances +// by serializing |expected| and |actual| to arrays and comparing. +function assert_header_equals(actual, expected, description) { + assert_class_string(actual, "Headers", description); + var header; + var actual_headers = []; + var expected_headers = []; + for (header of actual) + actual_headers.push(header[0] + ": " + header[1]); + for (header of expected) + expected_headers.push(header[0] + ": " + header[1]); + assert_array_equals(actual_headers, expected_headers, + description + " Headers differ."); +} + +// Helper for testing with Response objects. Compares simple +// attributes defined on the interfaces, as well as the headers. It +// does not compare the response bodies. +function assert_response_equals(actual, expected, description) { + assert_class_string(actual, "Response", description); + ["type", "url", "status", "ok", "statusText"].forEach(function(attribute) { + assert_equals(actual[attribute], expected[attribute], + description + " Attributes differ: " + attribute + "."); + }); + assert_header_equals(actual.headers, expected.headers, description); +} + +// Assert that the two arrays |actual| and |expected| contain the same +// set of Responses as determined by assert_response_equals. The order +// is not significant. +// +// |expected| is assumed to not contain any duplicates. +function assert_response_array_equivalent(actual, expected, description) { + assert_true(Array.isArray(actual), description); + assert_equals(actual.length, expected.length, description); + expected.forEach(function(expected_element) { + // assert_response_in_array treats the first argument as being + // 'actual', and the second as being 'expected array'. We are + // switching them around because we want to be resilient + // against the |actual| array containing duplicates. + assert_response_in_array(expected_element, actual, description); + }); +} + +// Asserts that two arrays |actual| and |expected| contain the same +// set of Responses as determined by assert_response_equals(). The +// corresponding elements must occupy corresponding indices in their +// respective arrays. +function assert_response_array_equals(actual, expected, description) { + assert_true(Array.isArray(actual), description); + assert_equals(actual.length, expected.length, description); + actual.forEach(function(value, index) { + assert_response_equals(value, expected[index], + description + " : object[" + index + "]"); + }); +} + +// Equivalent to assert_in_array, but uses assert_response_equals. +function assert_response_in_array(actual, expected_array, description) { + assert_true(expected_array.some(function(element) { + try { + assert_response_equals(actual, element); + return true; + } catch (e) { + return false; + } + }), description); +} + +// Helper for testing with Request objects. Compares simple +// attributes defined on the interfaces, as well as the headers. +function assert_request_equals(actual, expected, description) { + assert_class_string(actual, "Request", description); + ["url"].forEach(function(attribute) { + assert_equals(actual[attribute], expected[attribute], + description + " Attributes differ: " + attribute + "."); + }); + assert_header_equals(actual.headers, expected.headers, description); +} + +// Asserts that two arrays |actual| and |expected| contain the same +// set of Requests as determined by assert_request_equals(). The +// corresponding elements must occupy corresponding indices in their +// respective arrays. +function assert_request_array_equals(actual, expected, description) { + assert_true(Array.isArray(actual), description); + assert_equals(actual.length, expected.length, description); + actual.forEach(function(value, index) { + assert_request_equals(value, expected[index], + description + " : object[" + index + "]"); + }); +} + +// Deletes all caches, returning a promise indicating success. +function delete_all_caches() { + return self.caches.keys() + .then(function(keys) { + return Promise.all(keys.map(self.caches.delete.bind(self.caches))); + }); +} diff --git a/test/fixtures/wpt/service-workers/cache-storage/sandboxed-iframes.https.html b/test/fixtures/wpt/service-workers/cache-storage/sandboxed-iframes.https.html new file mode 100644 index 000000000000..098fa89daf44 --- /dev/null +++ b/test/fixtures/wpt/service-workers/cache-storage/sandboxed-iframes.https.html @@ -0,0 +1,66 @@ + +Cache Storage: Verify access in sandboxed iframes + + + + + diff --git a/test/fixtures/wpt/service-workers/idlharness.https.any.js b/test/fixtures/wpt/service-workers/idlharness.https.any.js new file mode 100644 index 000000000000..8db5d4d10ff7 --- /dev/null +++ b/test/fixtures/wpt/service-workers/idlharness.https.any.js @@ -0,0 +1,53 @@ +// META: global=window,worker +// META: script=/resources/WebIDLParser.js +// META: script=/resources/idlharness.js +// META: script=cache-storage/resources/test-helpers.js +// META: script=service-worker/resources/test-helpers.sub.js +// META: timeout=long + +// https://w3c.github.io/ServiceWorker + +idl_test( + ['service-workers'], + ['dom', 'html'], + async (idl_array, t) => { + self.cacheInstance = await create_temporary_cache(t); + + idl_array.add_objects({ + CacheStorage: ['caches'], + Cache: ['self.cacheInstance'], + ServiceWorkerContainer: ['navigator.serviceWorker'] + }); + + // TODO: Add ServiceWorker and ServiceWorkerRegistration instances for the + // other worker scopes. + if (self.GLOBAL.isWindow()) { + idl_array.add_objects({ + ServiceWorkerRegistration: ['registrationInstance'], + ServiceWorker: ['registrationInstance.installing'] + }); + + const scope = 'service-worker/resources/scope/idlharness'; + const registration = await service_worker_unregister_and_register( + t, 'service-worker/resources/empty-worker.js', scope); + t.add_cleanup(() => registration.unregister()); + + self.registrationInstance = registration; + } else if (self.ServiceWorkerGlobalScope) { + // self.ServiceWorkerGlobalScope should only be defined for the + // ServiceWorker scope, which allows us to detect and test the interfaces + // exposed only for ServiceWorker. + idl_array.add_objects({ + Clients: ['clients'], + ExtendableEvent: ['new ExtendableEvent("type")'], + FetchEvent: ['new FetchEvent("type", { request: new Request("") })'], + ServiceWorkerGlobalScope: ['self'], + ServiceWorkerRegistration: ['registration'], + ServiceWorker: ['serviceWorker'], + // TODO: Test instances of Client and WindowClient, e.g. + // Client: ['self.clientInstance'], + // WindowClient: ['self.windowClientInstance'] + }); + } + } +); diff --git a/test/fixtures/wpt/service-workers/service-worker/Service-Worker-Allowed-header.https.html b/test/fixtures/wpt/service-workers/service-worker/Service-Worker-Allowed-header.https.html new file mode 100644 index 000000000000..6f44bb17e7da --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/Service-Worker-Allowed-header.https.html @@ -0,0 +1,88 @@ + +Service Worker: Service-Worker-Allowed header + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/WEB_FEATURES.yml b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/WEB_FEATURES.yml new file mode 100644 index 000000000000..41cd63e4cb42 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/WEB_FEATURES.yml @@ -0,0 +1,3 @@ +rules: +- isSecureContext*: [is-secure-context] +- "*": [service-workers] diff --git a/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/close.https.html b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/close.https.html new file mode 100644 index 000000000000..3e3cc8b2b089 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/close.https.html @@ -0,0 +1,11 @@ + +ServiceWorkerGlobalScope: close operation + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/error-message-event-worker.js b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/error-message-event-worker.js new file mode 100644 index 000000000000..525bc96e763e --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/error-message-event-worker.js @@ -0,0 +1,2 @@ +self.onmessageerror = e => { e.source.postMessage("received error event"); }; +self.onmessage = e => { e.source.postMessage("received message event"); }; diff --git a/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/error-message-event.https.html b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/error-message-event.https.html new file mode 100644 index 000000000000..0a35cc7c39cf --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/error-message-event.https.html @@ -0,0 +1,48 @@ + + + +Service Worker GlobalScope onerror event + + + + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/extendable-message-event-constructor.https.html b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/extendable-message-event-constructor.https.html new file mode 100644 index 000000000000..525245fe9ece --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/extendable-message-event-constructor.https.html @@ -0,0 +1,10 @@ + +ServiceWorkerGlobalScope: ExtendableMessageEvent Constructor + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/extendable-message-event.https.html b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/extendable-message-event.https.html new file mode 100644 index 000000000000..89efd7a4a615 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/extendable-message-event.https.html @@ -0,0 +1,226 @@ + +ServiceWorkerGlobalScope: ExtendableMessageEvent + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/fetch-on-the-right-interface.https.any.js b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/fetch-on-the-right-interface.https.any.js new file mode 100644 index 000000000000..5ca5f65680c9 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/fetch-on-the-right-interface.https.any.js @@ -0,0 +1,14 @@ +// META: title=fetch method on the right interface +// META: global=serviceworker + +test(function() { + assert_false(self.hasOwnProperty('fetch'), 'ServiceWorkerGlobalScope ' + + 'instance should not have "fetch" method as its property.'); + assert_inherits(self, 'fetch', 'ServiceWorkerGlobalScope should ' + + 'inherit "fetch" method.'); + assert_own_property(Object.getPrototypeOf(Object.getPrototypeOf(self)), 'fetch', + 'WorkerGlobalScope should have "fetch" propery in its prototype.'); + assert_equals(self.fetch, Object.getPrototypeOf(Object.getPrototypeOf(self)).fetch, + 'ServiceWorkerGlobalScope.fetch should be the same as ' + + 'WorkerGlobalScope.fetch.'); +}, 'Fetch method on the right interface'); diff --git a/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/isSecureContext.https.html b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/isSecureContext.https.html new file mode 100644 index 000000000000..399820dd2c31 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/isSecureContext.https.html @@ -0,0 +1,32 @@ + + + +Service Worker: isSecureContext + + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/isSecureContext.serviceworker.js b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/isSecureContext.serviceworker.js new file mode 100644 index 000000000000..5033594e34ba --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/isSecureContext.serviceworker.js @@ -0,0 +1,5 @@ +importScripts("/resources/testharness.js"); + +test(() => { + assert_true(self.isSecureContext, true); +}, "isSecureContext"); diff --git a/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/message-event-ports-worker.js b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/message-event-ports-worker.js new file mode 100644 index 000000000000..78cd0d86c010 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/message-event-ports-worker.js @@ -0,0 +1,3 @@ +self.onmessage = e => { + e.source.postMessage(e.ports === e.ports ? "same ports array" : "different ports array"); +}; diff --git a/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/message-event-ports.https.html b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/message-event-ports.https.html new file mode 100644 index 000000000000..a0eac39e9b35 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/message-event-ports.https.html @@ -0,0 +1,43 @@ + + + +Service Worker GlobalScope onerror event + + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/postmessage.https.html b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/postmessage.https.html new file mode 100644 index 000000000000..99dedebf2e56 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/postmessage.https.html @@ -0,0 +1,83 @@ + +ServiceWorkerGlobalScope: postMessage + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/registration-attribute.https.html b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/registration-attribute.https.html new file mode 100644 index 000000000000..aa3c74a13bb2 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/registration-attribute.https.html @@ -0,0 +1,107 @@ + +ServiceWorkerGlobalScope: registration + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/resources/close-worker.js b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/resources/close-worker.js new file mode 100644 index 000000000000..41a8bc069af8 --- /dev/null +++ b/test/fixtures/wpt/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/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/resources/error-worker.js b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/resources/error-worker.js new file mode 100644 index 000000000000..f6838ffb3947 --- /dev/null +++ b/test/fixtures/wpt/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/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/resources/extendable-message-event-constructor-worker.js b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/resources/extendable-message-event-constructor-worker.js new file mode 100644 index 000000000000..42da5825c56d --- /dev/null +++ b/test/fixtures/wpt/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/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/resources/extendable-message-event-loopback-worker.js b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/resources/extendable-message-event-loopback-worker.js new file mode 100644 index 000000000000..13cae88d800d --- /dev/null +++ b/test/fixtures/wpt/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/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/resources/extendable-message-event-ping-worker.js b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/resources/extendable-message-event-ping-worker.js new file mode 100644 index 000000000000..d07b22959cc0 --- /dev/null +++ b/test/fixtures/wpt/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/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/resources/extendable-message-event-pong-worker.js b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/resources/extendable-message-event-pong-worker.js new file mode 100644 index 000000000000..5e9669e83c4b --- /dev/null +++ b/test/fixtures/wpt/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/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/resources/extendable-message-event-utils.js b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/resources/extendable-message-event-utils.js new file mode 100644 index 000000000000..d6a3b483f539 --- /dev/null +++ b/test/fixtures/wpt/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/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/resources/extendable-message-event-worker.js b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/resources/extendable-message-event-worker.js new file mode 100644 index 000000000000..f5e7647e3e76 --- /dev/null +++ b/test/fixtures/wpt/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/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/resources/postmessage-loopback-worker.js b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/resources/postmessage-loopback-worker.js new file mode 100644 index 000000000000..083e9aa2a85d --- /dev/null +++ b/test/fixtures/wpt/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/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/resources/postmessage-ping-worker.js b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/resources/postmessage-ping-worker.js new file mode 100644 index 000000000000..ebb1eccce2da --- /dev/null +++ b/test/fixtures/wpt/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/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/resources/postmessage-pong-worker.js b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/resources/postmessage-pong-worker.js new file mode 100644 index 000000000000..4a0d90b6182f --- /dev/null +++ b/test/fixtures/wpt/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/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/resources/registration-attribute-newer-worker.js b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/resources/registration-attribute-newer-worker.js new file mode 100644 index 000000000000..44f3e2e8e9bd --- /dev/null +++ b/test/fixtures/wpt/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/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/resources/registration-attribute-worker.js b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/resources/registration-attribute-worker.js new file mode 100644 index 000000000000..315f43759324 --- /dev/null +++ b/test/fixtures/wpt/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/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/resources/unregister-controlling-worker.html b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/resources/unregister-controlling-worker.html new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/resources/unregister-worker.js b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/resources/unregister-worker.js new file mode 100644 index 000000000000..6da397dd1526 --- /dev/null +++ b/test/fixtures/wpt/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/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/resources/update-worker.js b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/resources/update-worker.js new file mode 100644 index 000000000000..8be8a1ffebe0 --- /dev/null +++ b/test/fixtures/wpt/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/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/service-worker-error-event.https.html b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/service-worker-error-event.https.html new file mode 100644 index 000000000000..988f5466b9e1 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/service-worker-error-event.https.html @@ -0,0 +1,31 @@ + +ServiceWorkerGlobalScope: Error event error message + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/unregister.https.html b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/unregister.https.html new file mode 100644 index 000000000000..1a124d727687 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/unregister.https.html @@ -0,0 +1,139 @@ + +ServiceWorkerGlobalScope: unregister + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/update.https.html b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/update.https.html new file mode 100644 index 000000000000..a7dde2233972 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/update.https.html @@ -0,0 +1,48 @@ + +ServiceWorkerGlobalScope: update + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/WEB_FEATURES.yml b/test/fixtures/wpt/service-workers/service-worker/WEB_FEATURES.yml new file mode 100644 index 000000000000..d729f2cd79b2 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/WEB_FEATURES.yml @@ -0,0 +1,4 @@ +rules: +- registration-script-module.https.html: [js-modules-service-workers] +- update-registration-with-type.https.html: [js-modules-service-workers] +- "*": [service-workers] diff --git a/test/fixtures/wpt/service-workers/service-worker/about-blank-replacement.https.html b/test/fixtures/wpt/service-workers/service-worker/about-blank-replacement.https.html new file mode 100644 index 000000000000..b6efe3ec5620 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/about-blank-replacement.https.html @@ -0,0 +1,181 @@ + +Service Worker: about:blank replacement handling + + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/activate-event-after-install-state-change.https.html b/test/fixtures/wpt/service-workers/service-worker/activate-event-after-install-state-change.https.html new file mode 100644 index 000000000000..016a52c13c82 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/activate-event-after-install-state-change.https.html @@ -0,0 +1,33 @@ + +Service Worker: registration events + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/activation-after-registration.https.html b/test/fixtures/wpt/service-workers/service-worker/activation-after-registration.https.html new file mode 100644 index 000000000000..29f97e3e3f4c --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/activation-after-registration.https.html @@ -0,0 +1,28 @@ + +Service Worker: Activation occurs after registration + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/activation.https.html b/test/fixtures/wpt/service-workers/service-worker/activation.https.html new file mode 100644 index 000000000000..278454d3383e --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/activation.https.html @@ -0,0 +1,168 @@ + + + +service worker: activation + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/active.https.html b/test/fixtures/wpt/service-workers/service-worker/active.https.html new file mode 100644 index 000000000000..350a34b802f7 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/active.https.html @@ -0,0 +1,50 @@ + +ServiceWorker: navigator.serviceWorker.active + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/add-routes.https.html b/test/fixtures/wpt/service-workers/service-worker/add-routes.https.html new file mode 100644 index 000000000000..fbab7cdedfa3 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/add-routes.https.html @@ -0,0 +1,27 @@ + + +Service Worker: addRoutes() executes in installing + + + + + + \ No newline at end of file diff --git a/test/fixtures/wpt/service-workers/service-worker/claim-affect-other-registration.https.html b/test/fixtures/wpt/service-workers/service-worker/claim-affect-other-registration.https.html new file mode 100644 index 000000000000..52555ac271b5 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/claim-affect-other-registration.https.html @@ -0,0 +1,136 @@ + + +Service Worker: claim() should affect other registration + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/claim-fetch.https.html b/test/fixtures/wpt/service-workers/service-worker/claim-fetch.https.html new file mode 100644 index 000000000000..ae0082df06bf --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/claim-fetch.https.html @@ -0,0 +1,90 @@ + + + + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/claim-not-using-registration.https.html b/test/fixtures/wpt/service-workers/service-worker/claim-not-using-registration.https.html new file mode 100644 index 000000000000..fd61d05ba4ea --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/claim-not-using-registration.https.html @@ -0,0 +1,131 @@ + +Service Worker: claim client not using registration + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/claim-shared-worker-fetch.https.html b/test/fixtures/wpt/service-workers/service-worker/claim-shared-worker-fetch.https.html new file mode 100644 index 000000000000..f5f44886baa2 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/claim-shared-worker-fetch.https.html @@ -0,0 +1,71 @@ + + + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/claim-using-registration.https.html b/test/fixtures/wpt/service-workers/service-worker/claim-using-registration.https.html new file mode 100644 index 000000000000..a02f8e9ca6f1 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/claim-using-registration.https.html @@ -0,0 +1,103 @@ + +Service Worker: claim client using registration + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/claim-with-redirect.https.html b/test/fixtures/wpt/service-workers/service-worker/claim-with-redirect.https.html new file mode 100644 index 000000000000..fd89cb9b00a1 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/claim-with-redirect.https.html @@ -0,0 +1,59 @@ + +Service Worker: Claim() when update happens after redirect + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/claim-worker-fetch.https.html b/test/fixtures/wpt/service-workers/service-worker/claim-worker-fetch.https.html new file mode 100644 index 000000000000..7cb26c742b97 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/claim-worker-fetch.https.html @@ -0,0 +1,83 @@ + + + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/client-id.https.html b/test/fixtures/wpt/service-workers/service-worker/client-id.https.html new file mode 100644 index 000000000000..b93b34189999 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/client-id.https.html @@ -0,0 +1,60 @@ + +Service Worker: Client.id + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/client-navigate.https.html b/test/fixtures/wpt/service-workers/service-worker/client-navigate.https.html new file mode 100644 index 000000000000..f40a08635cfd --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/client-navigate.https.html @@ -0,0 +1,107 @@ + + + +Service Worker: WindowClient.navigate + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/client-url-creation-url.https.html b/test/fixtures/wpt/service-workers/service-worker/client-url-creation-url.https.html new file mode 100644 index 000000000000..ba597d893d34 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/client-url-creation-url.https.html @@ -0,0 +1,129 @@ + +Service Worker: Client.url is Window creation URL tests + + + + \ No newline at end of file diff --git a/test/fixtures/wpt/service-workers/service-worker/client-url-of-blob-url-worker.https.html b/test/fixtures/wpt/service-workers/service-worker/client-url-of-blob-url-worker.https.html new file mode 100644 index 000000000000..97a2fcf98f29 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/client-url-of-blob-url-worker.https.html @@ -0,0 +1,29 @@ + +Service Worker: client.url of a worker created from a blob URL + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/clients-get-client-types.https.html b/test/fixtures/wpt/service-workers/service-worker/clients-get-client-types.https.html new file mode 100644 index 000000000000..63e3e51b3202 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/clients-get-client-types.https.html @@ -0,0 +1,108 @@ + +Service Worker: Clients.get with window and worker clients + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/clients-get-cross-origin.https.html b/test/fixtures/wpt/service-workers/service-worker/clients-get-cross-origin.https.html new file mode 100644 index 000000000000..1e4acfb286c6 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/clients-get-cross-origin.https.html @@ -0,0 +1,69 @@ + +Service Worker: Clients.get across origins + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/clients-get-resultingClientId.https.html b/test/fixtures/wpt/service-workers/service-worker/clients-get-resultingClientId.https.html new file mode 100644 index 000000000000..3419cf14b523 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/clients-get-resultingClientId.https.html @@ -0,0 +1,177 @@ + + +Test clients.get(resultingClientId) + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/clients-get.https.html b/test/fixtures/wpt/service-workers/service-worker/clients-get.https.html new file mode 100644 index 000000000000..4cfbf595cade --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/clients-get.https.html @@ -0,0 +1,154 @@ + +Service Worker: Clients.get + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/clients-matchall-blob-url-worker.https.html b/test/fixtures/wpt/service-workers/service-worker/clients-matchall-blob-url-worker.https.html new file mode 100644 index 000000000000..c29bac8b894a --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/clients-matchall-blob-url-worker.https.html @@ -0,0 +1,85 @@ + +Service Worker: Clients.matchAll with a blob URL worker client + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/clients-matchall-client-types.https.html b/test/fixtures/wpt/service-workers/service-worker/clients-matchall-client-types.https.html new file mode 100644 index 000000000000..54f182b6202c --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/clients-matchall-client-types.https.html @@ -0,0 +1,92 @@ + +Service Worker: Clients.matchAll with various clientTypes + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/clients-matchall-exact-controller.https.html b/test/fixtures/wpt/service-workers/service-worker/clients-matchall-exact-controller.https.html new file mode 100644 index 000000000000..a61c8af70196 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/clients-matchall-exact-controller.https.html @@ -0,0 +1,67 @@ + +Service Worker: Clients.matchAll with exact controller + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/clients-matchall-frozen.https.html b/test/fixtures/wpt/service-workers/service-worker/clients-matchall-frozen.https.html new file mode 100644 index 000000000000..479c28a60f2e --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/clients-matchall-frozen.https.html @@ -0,0 +1,64 @@ + +Service Worker: Clients.matchAll + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/clients-matchall-include-uncontrolled.https.html b/test/fixtures/wpt/service-workers/service-worker/clients-matchall-include-uncontrolled.https.html new file mode 100644 index 000000000000..9f34e5709eb3 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/clients-matchall-include-uncontrolled.https.html @@ -0,0 +1,117 @@ + +Service Worker: Clients.matchAll with includeUncontrolled + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/clients-matchall-on-evaluation.https.html b/test/fixtures/wpt/service-workers/service-worker/clients-matchall-on-evaluation.https.html new file mode 100644 index 000000000000..8705f85b5684 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/clients-matchall-on-evaluation.https.html @@ -0,0 +1,24 @@ + +Service Worker: Clients.matchAll on script evaluation + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/clients-matchall-order.https.html b/test/fixtures/wpt/service-workers/service-worker/clients-matchall-order.https.html new file mode 100644 index 000000000000..ec650f2264df --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/clients-matchall-order.https.html @@ -0,0 +1,427 @@ + +Service Worker: Clients.matchAll ordering + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/clients-matchall.https.html b/test/fixtures/wpt/service-workers/service-worker/clients-matchall.https.html new file mode 100644 index 000000000000..ce44f1924d54 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/clients-matchall.https.html @@ -0,0 +1,50 @@ + +Service Worker: Clients.matchAll + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/controlled-dedicatedworker-postMessage.https.html b/test/fixtures/wpt/service-workers/service-worker/controlled-dedicatedworker-postMessage.https.html new file mode 100644 index 000000000000..5ef91dd1b11c --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/controlled-dedicatedworker-postMessage.https.html @@ -0,0 +1,45 @@ + + + + + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/controlled-iframe-postMessage.https.html b/test/fixtures/wpt/service-workers/service-worker/controlled-iframe-postMessage.https.html new file mode 100644 index 000000000000..c3f390a5a455 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/controlled-iframe-postMessage.https.html @@ -0,0 +1,68 @@ + + + + + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/controller-on-disconnect.https.html b/test/fixtures/wpt/service-workers/service-worker/controller-on-disconnect.https.html new file mode 100644 index 000000000000..f23dfe71bac5 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/controller-on-disconnect.https.html @@ -0,0 +1,40 @@ + +Service Worker: Controller on load + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/controller-on-load.https.html b/test/fixtures/wpt/service-workers/service-worker/controller-on-load.https.html new file mode 100644 index 000000000000..e4c5e5f81f81 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/controller-on-load.https.html @@ -0,0 +1,46 @@ + +Service Worker: Controller on load + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/controller-on-reload.https.html b/test/fixtures/wpt/service-workers/service-worker/controller-on-reload.https.html new file mode 100644 index 000000000000..2e966d425788 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/controller-on-reload.https.html @@ -0,0 +1,58 @@ + +Service Worker: Controller on reload + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/controller-with-no-fetch-event-handler.https.html b/test/fixtures/wpt/service-workers/service-worker/controller-with-no-fetch-event-handler.https.html new file mode 100644 index 000000000000..d947139c9e21 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/controller-with-no-fetch-event-handler.https.html @@ -0,0 +1,56 @@ + + +Service Worker: controller without a fetch event handler + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/credentials.https.html b/test/fixtures/wpt/service-workers/service-worker/credentials.https.html new file mode 100644 index 000000000000..0a90dc2897c2 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/credentials.https.html @@ -0,0 +1,100 @@ + + +Credentials for service worker scripts + + + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/css-sw-same-origin-substitution.https.html b/test/fixtures/wpt/service-workers/service-worker/css-sw-same-origin-substitution.https.html new file mode 100644 index 000000000000..3a79c07f95c2 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/css-sw-same-origin-substitution.https.html @@ -0,0 +1,31 @@ + +Service Worker: a same-origin response substituted for a cross-origin CSS request must not taint the stylesheet + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/data-iframe.html b/test/fixtures/wpt/service-workers/service-worker/data-iframe.html new file mode 100644 index 000000000000..d767d574345b --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/data-iframe.html @@ -0,0 +1,25 @@ + +Service Workers in data iframes + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/data-transfer-files.https.html b/test/fixtures/wpt/service-workers/service-worker/data-transfer-files.https.html new file mode 100644 index 000000000000..c503a28f965b --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/data-transfer-files.https.html @@ -0,0 +1,41 @@ + + +Post a file in a navigation controlled by a service worker + + + + + +
+ +
+ + diff --git a/test/fixtures/wpt/service-workers/service-worker/dedicated-worker-service-worker-interception.https.html b/test/fixtures/wpt/service-workers/service-worker/dedicated-worker-service-worker-interception.https.html new file mode 100644 index 000000000000..2144f4827121 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/dedicated-worker-service-worker-interception.https.html @@ -0,0 +1,40 @@ + +DedicatedWorker: ServiceWorker interception + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/detached-context.https.html b/test/fixtures/wpt/service-workers/service-worker/detached-context.https.html new file mode 100644 index 000000000000..ce8e4cc8400c --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/detached-context.https.html @@ -0,0 +1,124 @@ + + +Service WorkerRegistration from a removed iframe + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/detached-register-crash.https.html b/test/fixtures/wpt/service-workers/service-worker/detached-register-crash.https.html new file mode 100644 index 000000000000..2785142a3cf4 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/detached-register-crash.https.html @@ -0,0 +1,14 @@ + + +Assures navigator.serviceWorker.register() doesn't crash when rejecting being called in a detached frame + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/embed-and-object-are-not-intercepted.https.html b/test/fixtures/wpt/service-workers/service-worker/embed-and-object-are-not-intercepted.https.html new file mode 100644 index 000000000000..581dbeca9772 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/embed-and-object-are-not-intercepted.https.html @@ -0,0 +1,104 @@ + + +embed and object are not intercepted + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/extendable-event-async-waituntil.https.html b/test/fixtures/wpt/service-workers/service-worker/extendable-event-async-waituntil.https.html new file mode 100644 index 000000000000..04e98266b4f1 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/extendable-event-async-waituntil.https.html @@ -0,0 +1,120 @@ + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/extendable-event-waituntil.https.html b/test/fixtures/wpt/service-workers/service-worker/extendable-event-waituntil.https.html new file mode 100644 index 000000000000..33b4eac5c185 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/extendable-event-waituntil.https.html @@ -0,0 +1,140 @@ + +ExtendableEvent: waitUntil + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-audio-tainting.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-audio-tainting.https.html new file mode 100644 index 000000000000..9821759bc7b3 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-audio-tainting.https.html @@ -0,0 +1,47 @@ + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-canvas-tainting-double-write.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-canvas-tainting-double-write.https.html new file mode 100644 index 000000000000..dab2153baa6f --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-canvas-tainting-double-write.https.html @@ -0,0 +1,57 @@ + + + + + + +canvas tainting when written twice + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-canvas-tainting-image-cache.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-canvas-tainting-image-cache.https.html new file mode 100644 index 000000000000..213238112257 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-canvas-tainting-image-cache.https.html @@ -0,0 +1,16 @@ + + +Service Worker: canvas tainting of the fetched image using cached responses + + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-canvas-tainting-image.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-canvas-tainting-image.https.html new file mode 100644 index 000000000000..57dc7d98caa2 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-canvas-tainting-image.https.html @@ -0,0 +1,16 @@ + + +Service Worker: canvas tainting of the fetched image + + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-canvas-tainting-video-cache.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-canvas-tainting-video-cache.https.html new file mode 100644 index 000000000000..c37e8e562448 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-canvas-tainting-video-cache.https.html @@ -0,0 +1,17 @@ + + +Service Worker: canvas tainting of the fetched video using cache responses + + + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-canvas-tainting-video-with-range-request.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-canvas-tainting-video-with-range-request.https.html new file mode 100644 index 000000000000..0ee41e96f298 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-canvas-tainting-video-with-range-request.https.html @@ -0,0 +1,115 @@ + + +Canvas tainting due to video whose responses are fetched via a service worker including range requests + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-canvas-tainting-video.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-canvas-tainting-video.https.html new file mode 100644 index 000000000000..e8c23a2edd63 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-canvas-tainting-video.https.html @@ -0,0 +1,17 @@ + + +Service Worker: canvas tainting of the fetched video + + + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-cors-exposed-header-names.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-cors-exposed-header-names.https.html new file mode 100644 index 000000000000..317b02175f2f --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-cors-exposed-header-names.https.html @@ -0,0 +1,30 @@ + +Service Worker: CORS-exposed header names should be transferred correctly + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-cors-xhr.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-cors-xhr.https.html new file mode 100644 index 000000000000..f8ff445673bd --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-cors-xhr.https.html @@ -0,0 +1,49 @@ + +Service Worker: CORS XHR of fetch() + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-csp.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-csp.https.html new file mode 100644 index 000000000000..9e7b242b69aa --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-csp.https.html @@ -0,0 +1,138 @@ + +Service Worker: CSP control of fetch() + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-error.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-error.https.html new file mode 100644 index 000000000000..e9fdf5743120 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-error.https.html @@ -0,0 +1,29 @@ + + + + + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-event-add-async.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-event-add-async.https.html new file mode 100644 index 000000000000..ac13e4f41675 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-event-add-async.https.html @@ -0,0 +1,11 @@ + +Service Worker: Fetch event added asynchronously doesn't throw + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-event-after-navigation-within-page.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-event-after-navigation-within-page.https.html new file mode 100644 index 000000000000..4812d8a91551 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-event-after-navigation-within-page.https.html @@ -0,0 +1,71 @@ + +ServiceWorker: navigator.serviceWorker.waiting + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-event-async-respond-with.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-event-async-respond-with.https.html new file mode 100644 index 000000000000..d9147f85494c --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-event-async-respond-with.https.html @@ -0,0 +1,73 @@ + + +respondWith cannot be called asynchronously + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-event-handled.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-event-handled.https.html new file mode 100644 index 000000000000..08b88ce3773d --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-event-handled.https.html @@ -0,0 +1,86 @@ + + +Service Worker: FetchEvent.handled + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-event-is-history-backward-navigation-manual.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-event-is-history-backward-navigation-manual.https.html new file mode 100644 index 000000000000..3cf5922f396a --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-event-is-history-backward-navigation-manual.https.html @@ -0,0 +1,8 @@ + + +

Click this link. + Once you see "method = GET,..." in the page, go to another page, and then go back to the page using the Backward button. + You should see "method = GET, isHistoryNavigation = true". +

+ + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-event-is-history-forward-navigation-manual.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-event-is-history-forward-navigation-manual.https.html new file mode 100644 index 000000000000..401939b3cb2d --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-event-is-history-forward-navigation-manual.https.html @@ -0,0 +1,8 @@ + + +

Click this link. + Once you see "method = GET,..." in the page, go back to this page using the Backward button, and then go to the second page using the Forward button. + You should see "method = GET, isHistoryNavigation = true". +

+ + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-event-is-reload-iframe-navigation-manual.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-event-is-reload-iframe-navigation-manual.https.html new file mode 100644 index 000000000000..cf1feccf6e44 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-event-is-reload-iframe-navigation-manual.https.html @@ -0,0 +1,31 @@ + + + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-event-is-reload-navigation-manual.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-event-is-reload-navigation-manual.https.html new file mode 100644 index 000000000000..a349f07c36c2 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-event-is-reload-navigation-manual.https.html @@ -0,0 +1,8 @@ + + +

Click this link. + Once you see "method = GET,..." in the page, reload the page. + You will see "method = GET, isReloadNavigation = true". +

+ + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-event-network-error.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-event-network-error.https.html new file mode 100644 index 000000000000..fea2ad1e3c26 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-event-network-error.https.html @@ -0,0 +1,44 @@ + +Service Worker: Fetch event network error + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-event-redirect.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-event-redirect.https.html new file mode 100644 index 000000000000..522928475702 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-event-redirect.https.html @@ -0,0 +1,1038 @@ + +Service Worker: Fetch Event Redirect Handling + + + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-event-referrer-policy.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-event-referrer-policy.https.html new file mode 100644 index 000000000000..af4b20a9a4a7 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-event-referrer-policy.https.html @@ -0,0 +1,274 @@ + + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-event-respond-with-argument.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-event-respond-with-argument.https.html new file mode 100644 index 000000000000..05e22105243f --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-event-respond-with-argument.https.html @@ -0,0 +1,44 @@ + +Service Worker: FetchEvent.respondWith() argument type test. + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-event-respond-with-body-loaded-in-chunk.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-event-respond-with-body-loaded-in-chunk.https.html new file mode 100644 index 000000000000..932f9030c51c --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-event-respond-with-body-loaded-in-chunk.https.html @@ -0,0 +1,24 @@ + + +respondWith with a response whose body is being loaded from the network by chunks + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-event-respond-with-custom-response.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-event-respond-with-custom-response.https.html new file mode 100644 index 000000000000..645a29c9b4f1 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-event-respond-with-custom-response.https.html @@ -0,0 +1,82 @@ + + +respondWith with a new Response + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-event-respond-with-partial-stream.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-event-respond-with-partial-stream.https.html new file mode 100644 index 000000000000..505cef297268 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-event-respond-with-partial-stream.https.html @@ -0,0 +1,62 @@ + + +respondWith streams data to an intercepted fetch() + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-event-respond-with-readable-stream-chunk.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-event-respond-with-readable-stream-chunk.https.html new file mode 100644 index 000000000000..4544a9e08f56 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-event-respond-with-readable-stream-chunk.https.html @@ -0,0 +1,23 @@ + + +respondWith with a response built from a ReadableStream + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-event-respond-with-readable-stream.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-event-respond-with-readable-stream.https.html new file mode 100644 index 000000000000..4651258e6ab2 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-event-respond-with-readable-stream.https.html @@ -0,0 +1,88 @@ + + +respondWith with a response built from a ReadableStream + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-event-respond-with-response-body-with-invalid-chunk.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-event-respond-with-response-body-with-invalid-chunk.https.html new file mode 100644 index 000000000000..2a44811461a6 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-event-respond-with-response-body-with-invalid-chunk.https.html @@ -0,0 +1,46 @@ + + +respondWith with response body having invalid chunks + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-event-respond-with-stops-propagation.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-event-respond-with-stops-propagation.https.html new file mode 100644 index 000000000000..31fd616b6d6f --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-event-respond-with-stops-propagation.https.html @@ -0,0 +1,37 @@ + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-event-throws-after-respond-with.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-event-throws-after-respond-with.https.html new file mode 100644 index 000000000000..d98fb22ff423 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-event-throws-after-respond-with.https.html @@ -0,0 +1,37 @@ + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-event-within-sw-manual.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-event-within-sw-manual.https.html new file mode 100644 index 000000000000..15a2e95bd39d --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-event-within-sw-manual.https.html @@ -0,0 +1,122 @@ + + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-event-within-sw.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-event-within-sw.https.html new file mode 100644 index 000000000000..0b52b18305fa --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-event-within-sw.https.html @@ -0,0 +1,53 @@ + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-event.https.h2.html b/test/fixtures/wpt/service-workers/service-worker/fetch-event.https.h2.html new file mode 100644 index 000000000000..5cd381ec98db --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-event.https.h2.html @@ -0,0 +1,112 @@ + + + + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-event.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-event.https.html new file mode 100644 index 000000000000..2edb5b0e032a --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-event.https.html @@ -0,0 +1,1000 @@ + + + + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-frame-resource.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-frame-resource.https.html new file mode 100644 index 000000000000..0d8e38d8b84c --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-frame-resource.https.html @@ -0,0 +1,238 @@ + +Service Worker: Fetch for the frame loading. + + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-header-visibility.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-header-visibility.https.html new file mode 100644 index 000000000000..1f4813c4f8e6 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-header-visibility.https.html @@ -0,0 +1,54 @@ + +Service Worker: Visibility of headers during fetch. + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-mixed-content-to-inscope.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-mixed-content-to-inscope.https.html new file mode 100644 index 000000000000..0e8fa93b32c0 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-mixed-content-to-inscope.https.html @@ -0,0 +1,21 @@ + +Service Worker: Mixed content of fetch() + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-mixed-content-to-outscope.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-mixed-content-to-outscope.https.html new file mode 100644 index 000000000000..391dc5d2c19a --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-mixed-content-to-outscope.https.html @@ -0,0 +1,21 @@ + +Service Worker: Mixed content of fetch() + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-request-body-cancel-worker.js b/test/fixtures/wpt/service-workers/service-worker/fetch-request-body-cancel-worker.js new file mode 100644 index 000000000000..0a45a02880f2 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-request-body-cancel-worker.js @@ -0,0 +1,14 @@ +async function cancelBodyTest(event) +{ + await new Promise(resolve => setTimeout(resolve, 100)); + event.request.body.cancel("service worker cancelled body"); + await new Promise(resolve => setTimeout(resolve, 100)); + return new Response("PASS"); +} + +self.addEventListener("fetch", (event) => { + if (!event.request.url.includes("cancel-body-test")) + return; + + event.respondWith(cancelBodyTest(event)); +}); diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-request-body-cancel.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-request-body-cancel.https.html new file mode 100644 index 000000000000..f06633c78442 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-request-body-cancel.https.html @@ -0,0 +1,56 @@ + + +Service Worker cancelling a fetch upload stream body + + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-request-css-base-url.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-request-css-base-url.https.html new file mode 100644 index 000000000000..467a66cee464 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-request-css-base-url.https.html @@ -0,0 +1,87 @@ + +Service Worker: CSS's base URL must be the response URL + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-request-css-cross-origin.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-request-css-cross-origin.https.html new file mode 100644 index 000000000000..d9c1c7f5df2c --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-request-css-cross-origin.https.html @@ -0,0 +1,81 @@ + +Service Worker: Cross-origin CSS files fetched via SW. + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-request-css-images.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-request-css-images.https.html new file mode 100644 index 000000000000..586dea26135f --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-request-css-images.https.html @@ -0,0 +1,214 @@ + +Service Worker: FetchEvent for css image + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-request-fallback.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-request-fallback.https.html new file mode 100644 index 000000000000..a29f31d127bc --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-request-fallback.https.html @@ -0,0 +1,282 @@ + +Service Worker: the fallback behavior of FetchEvent + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-request-no-freshness-headers.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-request-no-freshness-headers.https.html new file mode 100644 index 000000000000..03b7d357610a --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-request-no-freshness-headers.https.html @@ -0,0 +1,55 @@ + +Service Worker: the headers of FetchEvent shouldn't contain freshness headers + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-request-redirect.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-request-redirect.https.html new file mode 100644 index 000000000000..5ce015b421fc --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-request-redirect.https.html @@ -0,0 +1,385 @@ + +Service Worker: FetchEvent for resources + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-request-resources.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-request-resources.https.html new file mode 100644 index 000000000000..9524e6d4749b --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-request-resources.https.html @@ -0,0 +1,375 @@ + +Service Worker: FetchEvent for resources + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-request-xhr-sync-error.https.window.js b/test/fixtures/wpt/service-workers/service-worker/fetch-request-xhr-sync-error.https.window.js new file mode 100644 index 000000000000..e6c021392866 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-request-xhr-sync-error.https.window.js @@ -0,0 +1,19 @@ +// META: script=resources/test-helpers.sub.js + +"use strict"; + +promise_test(async t => { + const url = "resources/fetch-request-xhr-sync-error-worker.js"; + const scope = "resources/fetch-request-xhr-sync-iframe.html"; + + 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 frame = await with_iframe(scope); + t.add_cleanup(() => frame.remove()); + + assert_throws_dom("NetworkError", frame.contentWindow.DOMException, () => frame.contentWindow.performSyncXHR("non-existent-stream-1.txt")); + assert_throws_dom("NetworkError", frame.contentWindow.DOMException, () => frame.contentWindow.performSyncXHR("non-existent-stream-2.txt")); + assert_throws_dom("NetworkError", frame.contentWindow.DOMException, () => frame.contentWindow.performSyncXHR("non-existent-stream-3.txt")); +}, "Verify synchronous XMLHttpRequest always throws a NetworkError for ReadableStream errors"); diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-request-xhr-sync-on-worker.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-request-xhr-sync-on-worker.https.html new file mode 100644 index 000000000000..9f18096aa29b --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-request-xhr-sync-on-worker.https.html @@ -0,0 +1,41 @@ + +Service Worker: Synchronous XHR on Worker is intercepted + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-request-xhr-sync.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-request-xhr-sync.https.html new file mode 100644 index 000000000000..ec27fb898343 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-request-xhr-sync.https.html @@ -0,0 +1,53 @@ + +Service Worker: Synchronous XHR is intercepted + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-request-xhr.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-request-xhr.https.html new file mode 100644 index 000000000000..37a457393b05 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-request-xhr.https.html @@ -0,0 +1,75 @@ + +Service Worker: the body of FetchEvent using XMLHttpRequest + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-response-taint.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-response-taint.https.html new file mode 100644 index 000000000000..8e190f48506c --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-response-taint.https.html @@ -0,0 +1,223 @@ + +Service Worker: Tainting of responses fetched via SW. + + + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-response-xhr.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-response-xhr.https.html new file mode 100644 index 000000000000..891eb029422b --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-response-xhr.https.html @@ -0,0 +1,50 @@ + +Service Worker: the response of FetchEvent using XMLHttpRequest + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-waits-for-activate.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-waits-for-activate.https.html new file mode 100644 index 000000000000..7c888450f0d5 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-waits-for-activate.https.html @@ -0,0 +1,128 @@ + +Service Worker: Fetch Event Waits for Activate Event + + + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/fetch-with-body.https.html b/test/fixtures/wpt/service-workers/service-worker/fetch-with-body.https.html new file mode 100644 index 000000000000..21ded3f32725 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/fetch-with-body.https.html @@ -0,0 +1,44 @@ + + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/getregistration.https.html b/test/fixtures/wpt/service-workers/service-worker/getregistration.https.html new file mode 100644 index 000000000000..634c2efa1246 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/getregistration.https.html @@ -0,0 +1,108 @@ + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/getregistrations.https.html b/test/fixtures/wpt/service-workers/service-worker/getregistrations.https.html new file mode 100644 index 000000000000..3a9b9a23317b --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/getregistrations.https.html @@ -0,0 +1,134 @@ + +Service Worker: getRegistrations() + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/global-serviceworker.https.any.js b/test/fixtures/wpt/service-workers/service-worker/global-serviceworker.https.any.js new file mode 100644 index 000000000000..19d77847c426 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/global-serviceworker.https.any.js @@ -0,0 +1,53 @@ +// META: title=serviceWorker on service worker global +// META: global=serviceworker + +test(() => { + assert_equals(registration.installing, null, 'registration.installing'); + assert_equals(registration.waiting, null, 'registration.waiting'); + assert_equals(registration.active, null, 'registration.active'); + assert_true('serviceWorker' in self, 'self.serviceWorker exists'); + assert_equals(serviceWorker.state, 'parsed', 'serviceWorker.state'); + assert_readonly(self, 'serviceWorker', `self.serviceWorker is read only`); +}, 'First run'); + +// Cache this for later tests. +const initialServiceWorker = self.serviceWorker; + +async_test((t) => { + assert_true('serviceWorker' in self, 'self.serviceWorker exists'); + serviceWorker.postMessage({ messageTest: true }); + + // The rest of the test runs once this receives the above message. + addEventListener('message', t.step_func((event) => { + // Ignore unrelated messages. + if (!event.data.messageTest) return; + assert_equals(event.source, serviceWorker, 'event.source'); + t.done(); + })); +}, 'Can post message to self during startup'); + +// The test is registered now so there isn't a race condition when collecting tests, but the asserts +// don't happen until the 'install' event fires. +async_test((t) => { + addEventListener('install', t.step_func_done(() => { + assert_true('serviceWorker' in self, 'self.serviceWorker exists'); + assert_equals(serviceWorker, initialServiceWorker, `self.serviceWorker hasn't changed`); + assert_equals(registration.installing, serviceWorker, 'registration.installing'); + assert_equals(registration.waiting, null, 'registration.waiting'); + assert_equals(registration.active, null, 'registration.active'); + assert_equals(serviceWorker.state, 'installing', 'serviceWorker.state'); + })); +}, 'During install'); + +// The test is registered now so there isn't a race condition when collecting tests, but the asserts +// don't happen until the 'activate' event fires. +async_test((t) => { + addEventListener('activate', t.step_func_done(() => { + assert_true('serviceWorker' in self, 'self.serviceWorker exists'); + assert_equals(serviceWorker, initialServiceWorker, `self.serviceWorker hasn't changed`); + assert_equals(registration.installing, null, 'registration.installing'); + assert_equals(registration.waiting, null, 'registration.waiting'); + assert_equals(registration.active, serviceWorker, 'registration.active'); + assert_equals(serviceWorker.state, 'activating', 'serviceWorker.state'); + })); +}, 'During activate'); diff --git a/test/fixtures/wpt/service-workers/service-worker/historical.https.any.js b/test/fixtures/wpt/service-workers/service-worker/historical.https.any.js new file mode 100644 index 000000000000..20b3ddfbf7b8 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/historical.https.any.js @@ -0,0 +1,5 @@ +// META: global=serviceworker + +test((t) => { + assert_false('targetClientId' in FetchEvent.prototype) +}, 'targetClientId should not be on FetchEvent'); diff --git a/test/fixtures/wpt/service-workers/service-worker/http-to-https-redirect-and-register.https.html b/test/fixtures/wpt/service-workers/service-worker/http-to-https-redirect-and-register.https.html new file mode 100644 index 000000000000..5626237dcccb --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/http-to-https-redirect-and-register.https.html @@ -0,0 +1,49 @@ + +register on a secure page after redirect from an non-secure url + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/immutable-prototype-serviceworker.https.html b/test/fixtures/wpt/service-workers/service-worker/immutable-prototype-serviceworker.https.html new file mode 100644 index 000000000000..e63f6b348a86 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/immutable-prototype-serviceworker.https.html @@ -0,0 +1,23 @@ + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/import-scripts-cross-origin.https.html b/test/fixtures/wpt/service-workers/service-worker/import-scripts-cross-origin.https.html new file mode 100644 index 000000000000..773708a9fbce --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/import-scripts-cross-origin.https.html @@ -0,0 +1,18 @@ + + +Tests for importScripts: cross-origin + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/import-scripts-data-url.https.html b/test/fixtures/wpt/service-workers/service-worker/import-scripts-data-url.https.html new file mode 100644 index 000000000000..f0922193dd01 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/import-scripts-data-url.https.html @@ -0,0 +1,18 @@ + + +Tests for importScripts: data: URL + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/import-scripts-mime-types.https.html b/test/fixtures/wpt/service-workers/service-worker/import-scripts-mime-types.https.html new file mode 100644 index 000000000000..1679831d0f2b --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/import-scripts-mime-types.https.html @@ -0,0 +1,30 @@ + + +Tests for importScripts: MIME types + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/import-scripts-redirect.https.html b/test/fixtures/wpt/service-workers/service-worker/import-scripts-redirect.https.html new file mode 100644 index 000000000000..07ea49439eba --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/import-scripts-redirect.https.html @@ -0,0 +1,55 @@ + + +Tests for importScripts: redirect + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/import-scripts-resource-map.https.html b/test/fixtures/wpt/service-workers/service-worker/import-scripts-resource-map.https.html new file mode 100644 index 000000000000..4742bd012683 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/import-scripts-resource-map.https.html @@ -0,0 +1,34 @@ + + +Tests for importScripts: script resource map + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/import-scripts-updated-flag.https.html b/test/fixtures/wpt/service-workers/service-worker/import-scripts-updated-flag.https.html new file mode 100644 index 000000000000..09b4496aa0ec --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/import-scripts-updated-flag.https.html @@ -0,0 +1,83 @@ + + +Tests for importScripts: import scripts updated flag + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/indexeddb.https.html b/test/fixtures/wpt/service-workers/service-worker/indexeddb.https.html new file mode 100644 index 000000000000..be9be4968f7b --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/indexeddb.https.html @@ -0,0 +1,78 @@ + +Service Worker: Indexed DB + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/install-event-type.https.html b/test/fixtures/wpt/service-workers/service-worker/install-event-type.https.html new file mode 100644 index 000000000000..7e74af85c3ae --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/install-event-type.https.html @@ -0,0 +1,30 @@ + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/installing.https.html b/test/fixtures/wpt/service-workers/service-worker/installing.https.html new file mode 100644 index 000000000000..0f257b6aba4f --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/installing.https.html @@ -0,0 +1,48 @@ + +ServiceWorker: navigator.serviceWorker.installing + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/intercepted-referrer.https.html b/test/fixtures/wpt/service-workers/service-worker/intercepted-referrer.https.html new file mode 100644 index 000000000000..72d789451390 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/intercepted-referrer.https.html @@ -0,0 +1,51 @@ + + +Service Worker intercepted navigation preserves document.referrer + + + + + +

Service Worker intercepted navigation preserves document.referrer

+ + diff --git a/test/fixtures/wpt/service-workers/service-worker/interface-requirements-sw.https.html b/test/fixtures/wpt/service-workers/service-worker/interface-requirements-sw.https.html new file mode 100644 index 000000000000..eef868c889f0 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/interface-requirements-sw.https.html @@ -0,0 +1,16 @@ + +Service Worker Global Scope Interfaces + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/invalid-blobtype.https.html b/test/fixtures/wpt/service-workers/service-worker/invalid-blobtype.https.html new file mode 100644 index 000000000000..1c5920fb0391 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/invalid-blobtype.https.html @@ -0,0 +1,40 @@ + +Service Worker: respondWith with header value containing a null byte + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/invalid-header.https.html b/test/fixtures/wpt/service-workers/service-worker/invalid-header.https.html new file mode 100644 index 000000000000..1bc976979046 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/invalid-header.https.html @@ -0,0 +1,39 @@ + +Service Worker: respondWith with header value containing a null byte + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/iso-latin1-header.https.html b/test/fixtures/wpt/service-workers/service-worker/iso-latin1-header.https.html new file mode 100644 index 000000000000..c27a5f48a5b9 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/iso-latin1-header.https.html @@ -0,0 +1,40 @@ + +Service Worker: respondWith with header value containing an ISO Latin 1 (ISO-8859-1 Character Set) string + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/local-url-inherit-controller.https.html b/test/fixtures/wpt/service-workers/service-worker/local-url-inherit-controller.https.html new file mode 100644 index 000000000000..867e1b006d65 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/local-url-inherit-controller.https.html @@ -0,0 +1,133 @@ + +Service Worker: local URL windows and workers inherit controller + + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/mime-sniffing.https.html b/test/fixtures/wpt/service-workers/service-worker/mime-sniffing.https.html new file mode 100644 index 000000000000..8175bcdf8779 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/mime-sniffing.https.html @@ -0,0 +1,24 @@ + +Service Worker: MIME sniffing + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/multi-globals/WEB_FEATURES.yml b/test/fixtures/wpt/service-workers/service-worker/multi-globals/WEB_FEATURES.yml new file mode 100644 index 000000000000..5bee18ab21d0 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/multi-globals/WEB_FEATURES.yml @@ -0,0 +1,2 @@ +rules: +- "**": [service-workers] diff --git a/test/fixtures/wpt/service-workers/service-worker/multi-globals/current/current.https.html b/test/fixtures/wpt/service-workers/service-worker/multi-globals/current/current.https.html new file mode 100644 index 000000000000..82a48d409901 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/multi-globals/current/current.https.html @@ -0,0 +1,2 @@ + +Current page used as a test helper diff --git a/test/fixtures/wpt/service-workers/service-worker/multi-globals/current/test-sw.js b/test/fixtures/wpt/service-workers/service-worker/multi-globals/current/test-sw.js new file mode 100644 index 000000000000..e673292f2c0c --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/multi-globals/current/test-sw.js @@ -0,0 +1 @@ +// Service worker for current/ \ No newline at end of file diff --git a/test/fixtures/wpt/service-workers/service-worker/multi-globals/incumbent/incumbent.https.html b/test/fixtures/wpt/service-workers/service-worker/multi-globals/incumbent/incumbent.https.html new file mode 100644 index 000000000000..4585f15b0f45 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/multi-globals/incumbent/incumbent.https.html @@ -0,0 +1,20 @@ + +Incumbent page used as a test helper + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/multi-globals/incumbent/test-sw.js b/test/fixtures/wpt/service-workers/service-worker/multi-globals/incumbent/test-sw.js new file mode 100644 index 000000000000..e2a0e93b5839 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/multi-globals/incumbent/test-sw.js @@ -0,0 +1 @@ +// Service worker for incumbent/ \ No newline at end of file diff --git a/test/fixtures/wpt/service-workers/service-worker/multi-globals/relevant/relevant.https.html b/test/fixtures/wpt/service-workers/service-worker/multi-globals/relevant/relevant.https.html new file mode 100644 index 000000000000..44f42eda493c --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/multi-globals/relevant/relevant.https.html @@ -0,0 +1,2 @@ + +Relevant page used as a test helper diff --git a/test/fixtures/wpt/service-workers/service-worker/multi-globals/relevant/test-sw.js b/test/fixtures/wpt/service-workers/service-worker/multi-globals/relevant/test-sw.js new file mode 100644 index 000000000000..ff44cdf0867b --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/multi-globals/relevant/test-sw.js @@ -0,0 +1 @@ +// Service worker for relevant/ \ No newline at end of file diff --git a/test/fixtures/wpt/service-workers/service-worker/multi-globals/test-sw.js b/test/fixtures/wpt/service-workers/service-worker/multi-globals/test-sw.js new file mode 100644 index 000000000000..ce3c940eced8 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/multi-globals/test-sw.js @@ -0,0 +1 @@ +// Service worker for / \ No newline at end of file diff --git a/test/fixtures/wpt/service-workers/service-worker/multi-globals/url-parsing.https.html b/test/fixtures/wpt/service-workers/service-worker/multi-globals/url-parsing.https.html new file mode 100644 index 000000000000..b9dfe3634353 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/multi-globals/url-parsing.https.html @@ -0,0 +1,73 @@ + +register()/getRegistration() URL parsing, with multiple globals in play + + + + + + + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/multipart-image.https.html b/test/fixtures/wpt/service-workers/service-worker/multipart-image.https.html new file mode 100644 index 000000000000..00c20d25f90a --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/multipart-image.https.html @@ -0,0 +1,68 @@ + +Tests for cross-origin multipart image returned by service worker + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/multiple-register.https.html b/test/fixtures/wpt/service-workers/service-worker/multiple-register.https.html new file mode 100644 index 000000000000..752e132fc13a --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/multiple-register.https.html @@ -0,0 +1,117 @@ + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/multiple-update.https.html b/test/fixtures/wpt/service-workers/service-worker/multiple-update.https.html new file mode 100644 index 000000000000..6a83f73a054f --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/multiple-update.https.html @@ -0,0 +1,94 @@ + + +Service Worker: Trigger multiple updates + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/navigate-window.https.html b/test/fixtures/wpt/service-workers/service-worker/navigate-window.https.html new file mode 100644 index 000000000000..46d32a48a0ad --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/navigate-window.https.html @@ -0,0 +1,151 @@ + +Service Worker: Navigate a Window + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/navigation-headers.https.html b/test/fixtures/wpt/service-workers/service-worker/navigation-headers.https.html new file mode 100644 index 000000000000..a4b52035e221 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/navigation-headers.https.html @@ -0,0 +1,819 @@ + + + +Service Worker: Navigation Post Request Origin Header + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/navigation-preload/WEB_FEATURES.yml b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/WEB_FEATURES.yml new file mode 100644 index 000000000000..5bee18ab21d0 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/WEB_FEATURES.yml @@ -0,0 +1,2 @@ +rules: +- "**": [service-workers] diff --git a/test/fixtures/wpt/service-workers/service-worker/navigation-preload/broken-chunked-encoding.https.html b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/broken-chunked-encoding.https.html new file mode 100644 index 000000000000..ec74282ac330 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/broken-chunked-encoding.https.html @@ -0,0 +1,42 @@ + + +Navigation Preload with chunked encoding + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/navigation-preload/chunked-encoding.https.html b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/chunked-encoding.https.html new file mode 100644 index 000000000000..830ce32cea5a --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/chunked-encoding.https.html @@ -0,0 +1,25 @@ + + +Navigation Preload with chunked encoding + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/navigation-preload/content-encoding.https.html b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/content-encoding.https.html new file mode 100644 index 000000000000..d6135d95c880 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/content-encoding.https.html @@ -0,0 +1,25 @@ + + +Navigation Preload with content encoding + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/navigation-preload/empty-preload-response-body.https.html b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/empty-preload-response-body.https.html new file mode 100644 index 000000000000..7e8aacdd36a5 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/empty-preload-response-body.https.html @@ -0,0 +1,25 @@ + + +Navigation Preload empty response body + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/navigation-preload/get-state.https.html b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/get-state.https.html new file mode 100644 index 000000000000..08e2f4976c59 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/get-state.https.html @@ -0,0 +1,217 @@ + + +NavigationPreloadManager.getState + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/navigation-preload/navigationPreload.https.html b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/navigationPreload.https.html new file mode 100644 index 000000000000..392e5c14dc8c --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/navigationPreload.https.html @@ -0,0 +1,20 @@ + + +ServiceWorker: navigator.serviceWorker.navigationPreload + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/navigation-preload/redirect.https.html b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/redirect.https.html new file mode 100644 index 000000000000..5970f053e369 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/redirect.https.html @@ -0,0 +1,93 @@ + + +Navigation Preload redirect response + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/navigation-preload/request-headers.https.html b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/request-headers.https.html new file mode 100644 index 000000000000..09642010218a --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/request-headers.https.html @@ -0,0 +1,41 @@ + + +Navigation Preload request headers + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resource-timing.https.html b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resource-timing.https.html new file mode 100644 index 000000000000..468a1f51e857 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resource-timing.https.html @@ -0,0 +1,92 @@ + + +Navigation Preload Resource Timing + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/broken-chunked-encoding-scope.asis b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/broken-chunked-encoding-scope.asis new file mode 100644 index 000000000000..2a719536fb89 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/broken-chunked-encoding-scope.asis @@ -0,0 +1,6 @@ +HTTP/1.1 200 OK +Content-type: text/html; charset=UTF-8 +Transfer-encoding: chunked + +hello +world diff --git a/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/broken-chunked-encoding-worker.js b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/broken-chunked-encoding-worker.js new file mode 100644 index 000000000000..7a453e4055f0 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/broken-chunked-encoding-worker.js @@ -0,0 +1,11 @@ +self.addEventListener('activate', event => { + event.waitUntil( + self.registration.navigationPreload.enable()); + }); + +self.addEventListener('fetch', event => { + event.respondWith(event.preloadResponse + .then( + _ => new Response('PASS: preloadResponse resolved'), + _ => new Response('FAIL: preloadResponse rejected'))); + }); diff --git a/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/chunked-encoding-worker.js b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/chunked-encoding-worker.js new file mode 100644 index 000000000000..f30e5ed274dd --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/chunked-encoding-worker.js @@ -0,0 +1,8 @@ +self.addEventListener('activate', event => { + event.waitUntil( + self.registration.navigationPreload.enable()); + }); + +self.addEventListener('fetch', event => { + event.respondWith(event.preloadResponse); + }); diff --git a/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/content-encoding-worker.js b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/content-encoding-worker.js new file mode 100644 index 000000000000..f30e5ed274dd --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/content-encoding-worker.js @@ -0,0 +1,8 @@ +self.addEventListener('activate', event => { + event.waitUntil( + self.registration.navigationPreload.enable()); + }); + +self.addEventListener('fetch', event => { + event.respondWith(event.preloadResponse); + }); diff --git a/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/empty-preload-response-body-scope.html b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/empty-preload-response-body-scope.html new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/empty-preload-response-body-worker.js b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/empty-preload-response-body-worker.js new file mode 100644 index 000000000000..48c14b7916f3 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/empty-preload-response-body-worker.js @@ -0,0 +1,15 @@ +self.addEventListener('activate', event => { + event.waitUntil( + self.registration.navigationPreload.enable()); + }); + +self.addEventListener('fetch', event => { + event.respondWith( + event.preloadResponse + .then(res => res.text()) + .then(text => { + return new Response( + '[' + text + ']', + {headers: [['content-type', 'text/html']]}); + })); + }); diff --git a/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/get-state-worker.js b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/get-state-worker.js new file mode 100644 index 000000000000..a14ffb4faaad --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/get-state-worker.js @@ -0,0 +1,21 @@ +// This worker listens for commands from the page and messages back +// the result. + +function handle(message) { + const np = self.registration.navigationPreload; + switch (message) { + case 'getState': + return np.getState(); + case 'enable': + return np.enable(); + case 'disable': + return np.disable(); + case 'setHeaderValue': + return np.setHeaderValue('insightful'); + } + return Promise.reject('bad message'); +} + +self.addEventListener('message', e => { + e.waitUntil(handle(e.data).then(result => e.source.postMessage(result))); + }); diff --git a/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/helpers.js b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/helpers.js new file mode 100644 index 000000000000..86f0c0916ec9 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/helpers.js @@ -0,0 +1,5 @@ +function expect_navigation_preload_state(state, enabled, header, desc) { + assert_equals(Object.keys(state).length, 2, desc + ': # of keys'); + assert_equals(state.enabled, enabled, desc + ': enabled'); + assert_equals(state.headerValue, header, desc + ': header'); +} diff --git a/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/navigation-preload-worker.js b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/navigation-preload-worker.js new file mode 100644 index 000000000000..6e1ab232907f --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/navigation-preload-worker.js @@ -0,0 +1,3 @@ +self.addEventListener('fetch', event => { + event.respondWith(event.preloadResponse); +}); diff --git a/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/redirect-redirected.html b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/redirect-redirected.html new file mode 100644 index 000000000000..f9bfce5e8953 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/redirect-redirected.html @@ -0,0 +1,3 @@ + + +redirected diff --git a/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/redirect-worker.js b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/redirect-worker.js new file mode 100644 index 000000000000..1b55f2ef0d98 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/redirect-worker.js @@ -0,0 +1,35 @@ +self.addEventListener('activate', event => { + event.waitUntil( + self.registration.navigationPreload.enable()); + }); + +function get_response_info(r) { + var info = { + type: r.type, + url: r.url, + status: r.status, + ok: r.ok, + statusText: r.statusText, + headers: [] + }; + r.headers.forEach((value, name) => { info.headers.push([value, name]); }); + return info; +} + +function post_to_page(data) { + return self.clients.matchAll() + .then(clients => clients.forEach(client => client.postMessage(data))); +} + +self.addEventListener('fetch', event => { + event.respondWith( + event.preloadResponse + .then( + res => { + if (res.url.includes("base")) { + return res; + } + return post_to_page(get_response_info(res)).then(_ => res); + }, + err => new Response(err.toString()))); + }); diff --git a/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/request-headers-worker.js b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/request-headers-worker.js new file mode 100644 index 000000000000..1006cf27913a --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/request-headers-worker.js @@ -0,0 +1,10 @@ +self.addEventListener('activate', event => { + event.waitUntil( + Promise.all[ + self.registration.navigationPreload.enable(), + self.registration.navigationPreload.setHeaderValue('hello')]); + }); + +self.addEventListener('fetch', event => { + event.respondWith(event.preloadResponse); + }); diff --git a/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/resource-timing-worker.js b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/resource-timing-worker.js new file mode 100644 index 000000000000..fac0d8de2a73 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/resource-timing-worker.js @@ -0,0 +1,37 @@ +async function wait_for_performance_entries(url) { + let entries = performance.getEntriesByName(url); + if (entries.length > 0) { + return entries; + } + return new Promise((resolve) => { + new PerformanceObserver((list) => { + const entries = list.getEntriesByName(url); + if (entries.length > 0) { + resolve(entries); + } + }).observe({ entryTypes: ['resource'] }); + }); +} + +self.addEventListener('activate', event => { + event.waitUntil(self.registration.navigationPreload.enable()); + }); + +self.addEventListener('fetch', event => { + let headers; + event.respondWith( + event.preloadResponse + .then(response => { + headers = response.headers; + return response.text() + }) + .then(_ => wait_for_performance_entries(event.request.url)) + .then(entries => + new Response( + JSON.stringify({ + decodedBodySize: headers.get('X-Decoded-Body-Size'), + encodedBodySize: headers.get('X-Encoded-Body-Size'), + timingEntries: entries + }), + {headers: {'Content-Type': 'text/html'}}))); + }); diff --git a/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/samesite-iframe.html b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/samesite-iframe.html new file mode 100644 index 000000000000..a28b61261e82 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/samesite-iframe.html @@ -0,0 +1,10 @@ + + +samesite + diff --git a/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/samesite-sw-helper.html b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/samesite-sw-helper.html new file mode 100644 index 000000000000..51fdc9ec74bd --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/samesite-sw-helper.html @@ -0,0 +1,34 @@ + + +Navigation Preload Same Site SW registrator + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/samesite-worker.js b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/samesite-worker.js new file mode 100644 index 000000000000..f30e5ed274dd --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/samesite-worker.js @@ -0,0 +1,8 @@ +self.addEventListener('activate', event => { + event.waitUntil( + self.registration.navigationPreload.enable()); + }); + +self.addEventListener('fetch', event => { + event.respondWith(event.preloadResponse); + }); diff --git a/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/wait-for-activate-worker.js b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/wait-for-activate-worker.js new file mode 100644 index 000000000000..87791d2e487d --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/wait-for-activate-worker.js @@ -0,0 +1,40 @@ +// This worker remains in the installing phase so that the +// navigation preload API can be tested when there is no +// active worker. +importScripts('/resources/testharness.js'); +importScripts('helpers.js'); + +function expect_rejection(promise) { + return promise.then( + () => { return Promise.reject('unexpected fulfillment'); }, + err => { assert_equals('InvalidStateError', err.name); }); +} + +function test_before_activation() { + const np = self.registration.navigationPreload; + return expect_rejection(np.enable()) + .then(() => expect_rejection(np.disable())) + .then(() => expect_rejection(np.setHeaderValue('hi'))) + .then(() => np.getState()) + .then(state => expect_navigation_preload_state( + state, false, 'true', 'state should be the default')) + .then(() => 'PASS') + .catch(err => 'FAIL: ' + err); +} + +var resolve_done_promise; +var done_promise = new Promise(resolve => { resolve_done_promise = resolve; }); + +// Run the test once the page messages this worker. +self.addEventListener('message', e => { + e.waitUntil(test_before_activation() + .then(result => { + e.source.postMessage(result); + resolve_done_promise(); + })); + }); + +// Don't become the active worker until the test is done. +self.addEventListener('install', e => { + e.waitUntil(done_promise); + }); diff --git a/test/fixtures/wpt/service-workers/service-worker/navigation-preload/samesite-cookies.https.html b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/samesite-cookies.https.html new file mode 100644 index 000000000000..a860d9545662 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/samesite-cookies.https.html @@ -0,0 +1,61 @@ + + + +Navigation Preload: SameSite cookies + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/navigation-preload/samesite-iframe.https.html b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/samesite-iframe.https.html new file mode 100644 index 000000000000..633da9926a8c --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/samesite-iframe.https.html @@ -0,0 +1,67 @@ + + +Navigation Preload for same site iframe + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/navigation-redirect-body.https.html b/test/fixtures/wpt/service-workers/service-worker/navigation-redirect-body.https.html new file mode 100644 index 000000000000..0441c610b179 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/navigation-redirect-body.https.html @@ -0,0 +1,53 @@ + +Service Worker: Navigation redirection must clear body + + + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/navigation-redirect-resolution.https.html b/test/fixtures/wpt/service-workers/service-worker/navigation-redirect-resolution.https.html new file mode 100644 index 000000000000..59e1cafec348 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/navigation-redirect-resolution.https.html @@ -0,0 +1,58 @@ + +Service Worker: Navigation Redirect Resolution + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/navigation-redirect-to-http.https.html b/test/fixtures/wpt/service-workers/service-worker/navigation-redirect-to-http.https.html new file mode 100644 index 000000000000..d4d2788c5891 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/navigation-redirect-to-http.https.html @@ -0,0 +1,25 @@ + +Service Worker: Service Worker can receive HTTP opaqueredirect response. + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/navigation-redirect.https.html b/test/fixtures/wpt/service-workers/service-worker/navigation-redirect.https.html new file mode 100644 index 000000000000..a87de5693163 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/navigation-redirect.https.html @@ -0,0 +1,846 @@ + +Service Worker: Navigation redirection + + + + + + + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/navigation-sets-cookie.https.html b/test/fixtures/wpt/service-workers/service-worker/navigation-sets-cookie.https.html new file mode 100644 index 000000000000..7f6c756f5572 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/navigation-sets-cookie.https.html @@ -0,0 +1,133 @@ + + + +Service Worker: Navigation setting cookies + + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/navigation-timing-extended.https.html b/test/fixtures/wpt/service-workers/service-worker/navigation-timing-extended.https.html new file mode 100644 index 000000000000..acb02c6fe1f5 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/navigation-timing-extended.https.html @@ -0,0 +1,55 @@ + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/navigation-timing-sizes.https.html b/test/fixtures/wpt/service-workers/service-worker/navigation-timing-sizes.https.html new file mode 100644 index 000000000000..e726a31f1706 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/navigation-timing-sizes.https.html @@ -0,0 +1,113 @@ + + +Service Worker Navigation Timing + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/navigation-timing.https.html b/test/fixtures/wpt/service-workers/service-worker/navigation-timing.https.html new file mode 100644 index 000000000000..75cab40458c6 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/navigation-timing.https.html @@ -0,0 +1,77 @@ + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/nested-blob-url-workers.https.html b/test/fixtures/wpt/service-workers/service-worker/nested-blob-url-workers.https.html new file mode 100644 index 000000000000..7269cbb701fa --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/nested-blob-url-workers.https.html @@ -0,0 +1,42 @@ + + +Service Worker: nested blob URL worker clients + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/next-hop-protocol.https.html b/test/fixtures/wpt/service-workers/service-worker/next-hop-protocol.https.html new file mode 100644 index 000000000000..0805db9e24db --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/next-hop-protocol.https.html @@ -0,0 +1,49 @@ + + +Service Worker: Verify nextHopProtocol is set correctly + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/no-dynamic-import-in-module.any.js b/test/fixtures/wpt/service-workers/service-worker/no-dynamic-import-in-module.any.js new file mode 100644 index 000000000000..f7c2ef37b8b9 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/no-dynamic-import-in-module.any.js @@ -0,0 +1,7 @@ +// META: global=serviceworker-module + +// This is imported to ensure import('./basic-module-2.js') fails even if +// it has been previously statically imported. +import './resources/basic-module-2.js'; + +import './resources/no-dynamic-import.js'; diff --git a/test/fixtures/wpt/service-workers/service-worker/no-dynamic-import.any.js b/test/fixtures/wpt/service-workers/service-worker/no-dynamic-import.any.js new file mode 100644 index 000000000000..25b370b7094b --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/no-dynamic-import.any.js @@ -0,0 +1,3 @@ +// META: global=serviceworker + +importScripts('resources/no-dynamic-import.js'); diff --git a/test/fixtures/wpt/service-workers/service-worker/onactivate-script-error.https.html b/test/fixtures/wpt/service-workers/service-worker/onactivate-script-error.https.html new file mode 100644 index 000000000000..f5e80bb9a456 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/onactivate-script-error.https.html @@ -0,0 +1,74 @@ + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/oninstall-script-error.https.html b/test/fixtures/wpt/service-workers/service-worker/oninstall-script-error.https.html new file mode 100644 index 000000000000..fe7f6e901206 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/oninstall-script-error.https.html @@ -0,0 +1,72 @@ + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/opaque-response-preloaded.https.html b/test/fixtures/wpt/service-workers/service-worker/opaque-response-preloaded.https.html new file mode 100644 index 000000000000..417aa4ebec83 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/opaque-response-preloaded.https.html @@ -0,0 +1,50 @@ + + +Opaque responses should not be reused for XHRs + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/opaque-script.https.html b/test/fixtures/wpt/service-workers/service-worker/opaque-script.https.html new file mode 100644 index 000000000000..7d2121855dfa --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/opaque-script.https.html @@ -0,0 +1,71 @@ + +Cache Storage: verify scripts loaded from cache_storage are marked opaque + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/partitioned-claim.tentative.https.html b/test/fixtures/wpt/service-workers/service-worker/partitioned-claim.tentative.https.html new file mode 100644 index 000000000000..1f42c528e0b3 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/partitioned-claim.tentative.https.html @@ -0,0 +1,74 @@ + + +Service Worker: Partitioned Service Workers + + + + + + + +This test creates a iframe in a first-party context and then registers a +service worker (such that the iframe client is unclaimed). +A third-party iframe is then created which has its SW call clients.claim() +and then the test checks that the 1p iframe was not claimed int he process. +Finally the test has its SW call clients.claim() and confirms the 1p iframe is +claimed. + + + + \ No newline at end of file diff --git a/test/fixtures/wpt/service-workers/service-worker/partitioned-cookies.tentative.https.html b/test/fixtures/wpt/service-workers/service-worker/partitioned-cookies.tentative.https.html new file mode 100644 index 000000000000..7a8bd3f5cf85 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/partitioned-cookies.tentative.https.html @@ -0,0 +1,100 @@ + + + + +Service Worker: Partitioned Cookies + + + + + + + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/partitioned-getRegistrations.tentative.https.html b/test/fixtures/wpt/service-workers/service-worker/partitioned-getRegistrations.tentative.https.html new file mode 100644 index 000000000000..7c4d4f1e028b --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/partitioned-getRegistrations.tentative.https.html @@ -0,0 +1,99 @@ + + +Service Worker: Partitioned Service Workers + + + + + + + +This test loads a SW in a first-party context and gets the SW's (randomly) +generated ID. It does the same thing for the SW but in a third-party context +and then confirms that the IDs are different. + + + + \ No newline at end of file diff --git a/test/fixtures/wpt/service-workers/service-worker/partitioned-matchAll.tentative.https.html b/test/fixtures/wpt/service-workers/service-worker/partitioned-matchAll.tentative.https.html new file mode 100644 index 000000000000..46beec819c8e --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/partitioned-matchAll.tentative.https.html @@ -0,0 +1,65 @@ + + +Service Worker: Partitioned Service Workers + + + + + + + +This test loads a SW in a first-party context and gets has the SW send +its list of clients from client.matchAll(). It does the same thing for the +SW in a third-party context as well and confirms that each SW see's the correct +clients and that they don't see eachother's clients. + + + + \ No newline at end of file diff --git a/test/fixtures/wpt/service-workers/service-worker/partitioned.tentative.https.html b/test/fixtures/wpt/service-workers/service-worker/partitioned.tentative.https.html new file mode 100644 index 000000000000..17a375f9c732 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/partitioned.tentative.https.html @@ -0,0 +1,188 @@ + + +Service Worker: Partitioned Service Workers + + + + + + + + + The 3p iframe's postMessage: +

No message received

+ + The nested iframe's postMessage: +

No message received

+ + + \ No newline at end of file diff --git a/test/fixtures/wpt/service-workers/service-worker/performance-timeline.https.html b/test/fixtures/wpt/service-workers/service-worker/performance-timeline.https.html new file mode 100644 index 000000000000..e56e6fe416ff --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/performance-timeline.https.html @@ -0,0 +1,49 @@ + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/postMessage-client-worker.js b/test/fixtures/wpt/service-workers/service-worker/postMessage-client-worker.js new file mode 100644 index 000000000000..64d944d2b546 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/postMessage-client-worker.js @@ -0,0 +1,23 @@ +async function doTest(e) +{ + if (e.resultingClientId) { + const promise = new Promise(async resolve => { + let counter = 0; + const client = await self.clients.get(e.resultingClientId); + if (client) + client.postMessage(counter++); + if (e.request.url.includes("repeatMessage")) { + setInterval(() => { + if (client) + client.postMessage(counter++); + }, 100); + } + setTimeout(() => { + resolve(fetch(e.request)); + }, 1000); + }); + e.respondWith(promise); + } +} + +self.addEventListener("fetch", e => e.waitUntil(doTest(e))); diff --git a/test/fixtures/wpt/service-workers/service-worker/postmessage-blob-url.https.html b/test/fixtures/wpt/service-workers/service-worker/postmessage-blob-url.https.html new file mode 100644 index 000000000000..16fddd57b835 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/postmessage-blob-url.https.html @@ -0,0 +1,33 @@ + +Service Worker: postMessage Blob URL + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/postmessage-from-waiting-serviceworker.https.html b/test/fixtures/wpt/service-workers/service-worker/postmessage-from-waiting-serviceworker.https.html new file mode 100644 index 000000000000..117def9eb2a6 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/postmessage-from-waiting-serviceworker.https.html @@ -0,0 +1,50 @@ + +Service Worker: postMessage from waiting serviceworker + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/postmessage-msgport-to-client.https.html b/test/fixtures/wpt/service-workers/service-worker/postmessage-msgport-to-client.https.html new file mode 100644 index 000000000000..29c056080c79 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/postmessage-msgport-to-client.https.html @@ -0,0 +1,43 @@ + +Service Worker: postMessage via MessagePort to Client + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/postmessage-to-client-message-queue.https.html b/test/fixtures/wpt/service-workers/service-worker/postmessage-to-client-message-queue.https.html new file mode 100644 index 000000000000..83e5f4540d14 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/postmessage-to-client-message-queue.https.html @@ -0,0 +1,212 @@ + +Service Worker: postMessage to Client (message queue) + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/postmessage-to-client.https.html b/test/fixtures/wpt/service-workers/service-worker/postmessage-to-client.https.html new file mode 100644 index 000000000000..f834a4bffe20 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/postmessage-to-client.https.html @@ -0,0 +1,42 @@ + +Service Worker: postMessage to Client + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/postmessage.https.html b/test/fixtures/wpt/service-workers/service-worker/postmessage.https.html new file mode 100644 index 000000000000..7abb3022f91a --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/postmessage.https.html @@ -0,0 +1,202 @@ + +Service Worker: postMessage + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/ready.https.window.js b/test/fixtures/wpt/service-workers/service-worker/ready.https.window.js new file mode 100644 index 000000000000..6c4e270682c2 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/ready.https.window.js @@ -0,0 +1,223 @@ +// META: title=Service Worker: navigator.serviceWorker.ready +// META: script=resources/test-helpers.sub.js + +test(() => { + assert_equals( + navigator.serviceWorker.ready, + navigator.serviceWorker.ready, + 'repeated access to ready without intervening registrations should return the same Promise object' + ); +}, 'ready returns the same Promise object'); + +promise_test(async t => { + const frame = await with_iframe('resources/blank.html?uncontrolled'); + t.add_cleanup(() => frame.remove()); + + const promise = frame.contentWindow.navigator.serviceWorker.ready; + + assert_equals( + Object.getPrototypeOf(promise), + frame.contentWindow.Promise.prototype, + 'the Promise should be in the context of the related document' + ); +}, 'ready returns a Promise object in the context of the related document'); + +promise_test(async t => { + const url = 'resources/empty-worker.js'; + const scope = 'resources/blank.html?ready-controlled'; + const expectedURL = normalizeURL(url); + 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 frame = await with_iframe(scope); + t.add_cleanup(() => frame.remove()); + + const readyReg = await frame.contentWindow.navigator.serviceWorker.ready; + + assert_equals(readyReg.installing, null, 'installing should be null'); + assert_equals(readyReg.waiting, null, 'waiting should be null'); + assert_equals(readyReg.active.scriptURL, expectedURL, 'active after ready should not be null'); + assert_equals( + frame.contentWindow.navigator.serviceWorker.controller, + readyReg.active, + 'the controller should be the active worker' + ); + assert_in_array( + readyReg.active.state, + ['activating', 'activated'], + '.ready should be resolved when the registration has an active worker' + ); +}, 'ready on a controlled document'); + +promise_test(async t => { + const url = 'resources/empty-worker.js'; + const scope = 'resources/blank.html?ready-potential-controlled'; + const expected_url = normalizeURL(url); + const frame = await with_iframe(scope); + t.add_cleanup(() => frame.remove()); + + const registration = await navigator.serviceWorker.register(url, { scope }); + t.add_cleanup(() => registration.unregister()); + + const readyReg = await frame.contentWindow.navigator.serviceWorker.ready; + + assert_equals(readyReg.installing, null, 'installing should be null'); + assert_equals(readyReg.waiting, null, 'waiting should be null.') + assert_equals(readyReg.active.scriptURL, expected_url, 'active after ready should not be null'); + assert_in_array( + readyReg.active.state, + ['activating', 'activated'], + '.ready should be resolved when the registration has an active worker' + ); + assert_equals( + frame.contentWindow.navigator.serviceWorker.controller, + null, + 'uncontrolled document should not have a controller' + ); +}, 'ready on a potential controlled document'); + +promise_test(async t => { + const url = 'resources/empty-worker.js'; + const scope = 'resources/blank.html?ready-installing'; + + await service_worker_unregister(t, scope); + + const frame = await with_iframe(scope); + const promise = frame.contentWindow.navigator.serviceWorker.ready; + navigator.serviceWorker.register(url, { scope }); + const registration = await promise; + + t.add_cleanup(async () => { + await registration.unregister(); + frame.remove(); + }); + + assert_equals(registration.installing, null, 'installing should be null'); + assert_equals(registration.waiting, null, 'waiting should be null'); + assert_not_equals(registration.active, null, 'active after ready should not be null'); + assert_in_array( + registration.active.state, + ['activating', 'activated'], + '.ready should be resolved when the registration has an active worker' + ); +}, 'ready on an iframe whose parent registers a new service worker'); + +promise_test(async t => { + const scope = 'resources/register-iframe.html'; + const frame = await with_iframe(scope); + + const registration = await frame.contentWindow.navigator.serviceWorker.ready; + + t.add_cleanup(async () => { + await registration.unregister(); + frame.remove(); + }); + + assert_equals(registration.installing, null, 'installing should be null'); + assert_equals(registration.waiting, null, 'waiting should be null'); + assert_not_equals(registration.active, null, 'active after ready should not be null'); + assert_in_array( + registration.active.state, + ['activating', 'activated'], + '.ready should be resolved with "active worker"' + ); + }, 'ready on an iframe that installs a new service worker'); + +promise_test(async t => { + const url = 'resources/empty-worker.js'; + const matchedScope = 'resources/blank.html?ready-after-match'; + const longerMatchedScope = 'resources/blank.html?ready-after-match-longer'; + + await service_worker_unregister(t, matchedScope); + await service_worker_unregister(t, longerMatchedScope); + + const frame = await with_iframe(longerMatchedScope); + const registration = await navigator.serviceWorker.register(url, { scope: matchedScope }); + + t.add_cleanup(async () => { + await registration.unregister(); + frame.remove(); + }); + + await wait_for_state(t, registration.installing, 'activated'); + + const longerRegistration = await navigator.serviceWorker.register(url, { scope: longerMatchedScope }); + + t.add_cleanup(() => longerRegistration.unregister()); + + const readyReg = await frame.contentWindow.navigator.serviceWorker.ready; + + assert_equals( + readyReg.scope, + normalizeURL(longerMatchedScope), + 'longer matched registration should be returned' + ); + assert_equals( + frame.contentWindow.navigator.serviceWorker.controller, + null, + 'controller should be null' + ); +}, 'ready after a longer matched registration registered'); + +promise_test(async t => { + const url = 'resources/empty-worker.js'; + const matchedScope = 'resources/blank.html?ready-after-resolve'; + const longerMatchedScope = 'resources/blank.html?ready-after-resolve-longer'; + const registration = await service_worker_unregister_and_register(t, url, matchedScope); + t.add_cleanup(() => registration.unregister()); + + await wait_for_state(t, registration.installing, 'activated'); + + const frame = await with_iframe(longerMatchedScope); + t.add_cleanup(() => frame.remove()); + + const readyReg1 = await frame.contentWindow.navigator.serviceWorker.ready; + + assert_equals( + readyReg1.scope, + normalizeURL(matchedScope), + 'matched registration should be returned' + ); + + const longerReg = await navigator.serviceWorker.register(url, { scope: longerMatchedScope }); + t.add_cleanup(() => longerReg.unregister()); + + const readyReg2 = await frame.contentWindow.navigator.serviceWorker.ready; + + assert_equals( + readyReg2.scope, + normalizeURL(matchedScope), + 'ready should only be resolved once' + ); +}, 'access ready after it has been resolved'); + +promise_test(async t => { + const url1 = 'resources/empty-worker.js'; + const url2 = url1 + '?2'; + const matchedScope = 'resources/blank.html?ready-after-unregister'; + const reg1 = await service_worker_unregister_and_register(t, url1, matchedScope); + t.add_cleanup(() => reg1.unregister()); + + await wait_for_state(t, reg1.installing, 'activating'); + + const frame = await with_iframe(matchedScope); + t.add_cleanup(() => frame.remove()); + + await reg1.unregister(); + + // Ready promise should be pending, waiting for a new registration to arrive + const readyPromise = frame.contentWindow.navigator.serviceWorker.ready; + + const reg2 = await navigator.serviceWorker.register(url2, { scope: matchedScope }); + t.add_cleanup(() => reg2.unregister()); + + const readyReg = await readyPromise; + + // Wait for registration update, since it comes from another global, the states are racy. + await wait_for_state(t, reg2.installing || reg2.waiting || reg2.active, 'activated'); + + assert_equals(readyReg.active.scriptURL, reg2.active.scriptURL, 'Resolves with the second registration'); + assert_not_equals(reg1, reg2, 'Registrations should be different'); +}, 'resolve ready after unregistering'); diff --git a/test/fixtures/wpt/service-workers/service-worker/redirected-response.https.html b/test/fixtures/wpt/service-workers/service-worker/redirected-response.https.html new file mode 100644 index 000000000000..71b35d0e1205 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/redirected-response.https.html @@ -0,0 +1,471 @@ + +Service Worker: Redirected response + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/referer.https.html b/test/fixtures/wpt/service-workers/service-worker/referer.https.html new file mode 100644 index 000000000000..0957e4c53301 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/referer.https.html @@ -0,0 +1,40 @@ + +Service Worker: check referer of fetch() + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/referrer-policy-header.https.html b/test/fixtures/wpt/service-workers/service-worker/referrer-policy-header.https.html new file mode 100644 index 000000000000..784343e6d8f1 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/referrer-policy-header.https.html @@ -0,0 +1,67 @@ + +Service Worker: check referer of fetch() with Referrer Policy + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/referrer-toplevel-script-fetch.https.html b/test/fixtures/wpt/service-workers/service-worker/referrer-toplevel-script-fetch.https.html new file mode 100644 index 000000000000..65c60a11db20 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/referrer-toplevel-script-fetch.https.html @@ -0,0 +1,64 @@ + +Service Worker: check referrer of top-level script fetch + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/register-closed-window.https.html b/test/fixtures/wpt/service-workers/service-worker/register-closed-window.https.html new file mode 100644 index 000000000000..9c1b639bb757 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/register-closed-window.https.html @@ -0,0 +1,35 @@ + +Service Worker: Register() on Closed Window + + + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/register-default-scope.https.html b/test/fixtures/wpt/service-workers/service-worker/register-default-scope.https.html new file mode 100644 index 000000000000..1d86548eb5ee --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/register-default-scope.https.html @@ -0,0 +1,69 @@ + +register() and scope + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/register-same-scope-different-script-url.https.html b/test/fixtures/wpt/service-workers/service-worker/register-same-scope-different-script-url.https.html new file mode 100644 index 000000000000..6eb00f3071a2 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/register-same-scope-different-script-url.https.html @@ -0,0 +1,233 @@ + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/register-wait-forever-in-install-worker.https.html b/test/fixtures/wpt/service-workers/service-worker/register-wait-forever-in-install-worker.https.html new file mode 100644 index 000000000000..0920b5cb223d --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/register-wait-forever-in-install-worker.https.html @@ -0,0 +1,57 @@ + +Service Worker: Register wait-forever-in-install-worker + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/registration-basic.https.html b/test/fixtures/wpt/service-workers/service-worker/registration-basic.https.html new file mode 100644 index 000000000000..759b4244a269 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/registration-basic.https.html @@ -0,0 +1,39 @@ + +Service Worker: Registration (basic) + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/registration-end-to-end.https.html b/test/fixtures/wpt/service-workers/service-worker/registration-end-to-end.https.html new file mode 100644 index 000000000000..1af4582d3874 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/registration-end-to-end.https.html @@ -0,0 +1,88 @@ + +Service Worker: registration end-to-end + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/registration-events.https.html b/test/fixtures/wpt/service-workers/service-worker/registration-events.https.html new file mode 100644 index 000000000000..5bcfd66846bc --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/registration-events.https.html @@ -0,0 +1,42 @@ + +Service Worker: registration events + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/registration-iframe.https.html b/test/fixtures/wpt/service-workers/service-worker/registration-iframe.https.html new file mode 100644 index 000000000000..ae39ddfea3e5 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/registration-iframe.https.html @@ -0,0 +1,116 @@ + + +Service Worker: Registration for iframe + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/registration-mime-types.https.html b/test/fixtures/wpt/service-workers/service-worker/registration-mime-types.https.html new file mode 100644 index 000000000000..3a21aac5c75c --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/registration-mime-types.https.html @@ -0,0 +1,10 @@ + +Service Worker: Registration (MIME types) + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/registration-schedule-job.https.html b/test/fixtures/wpt/service-workers/service-worker/registration-schedule-job.https.html new file mode 100644 index 000000000000..25d758ee8f0e --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/registration-schedule-job.https.html @@ -0,0 +1,107 @@ + + + +Service Worker: Schedule Job algorithm + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/registration-scope-module-static-import.https.html b/test/fixtures/wpt/service-workers/service-worker/registration-scope-module-static-import.https.html new file mode 100644 index 000000000000..5c75295aed1c --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/registration-scope-module-static-import.https.html @@ -0,0 +1,41 @@ + +Service Worker: Static imports from module top-level scripts shouldn't be affected by the service worker script path restriction + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/registration-scope.https.html b/test/fixtures/wpt/service-workers/service-worker/registration-scope.https.html new file mode 100644 index 000000000000..141875f5847c --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/registration-scope.https.html @@ -0,0 +1,9 @@ + +Service Worker: Registration (scope) + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/registration-script-module.https.html b/test/fixtures/wpt/service-workers/service-worker/registration-script-module.https.html new file mode 100644 index 000000000000..9e39a1f75b27 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/registration-script-module.https.html @@ -0,0 +1,13 @@ + +Service Worker: Registration (module script) + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/registration-script-url.https.html b/test/fixtures/wpt/service-workers/service-worker/registration-script-url.https.html new file mode 100644 index 000000000000..bda61adb0027 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/registration-script-url.https.html @@ -0,0 +1,9 @@ + +Service Worker: Registration (scriptURL) + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/registration-script.https.html b/test/fixtures/wpt/service-workers/service-worker/registration-script.https.html new file mode 100644 index 000000000000..f1e51fd265e2 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/registration-script.https.html @@ -0,0 +1,12 @@ + +Service Worker: Registration (script) + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/registration-security-error.https.html b/test/fixtures/wpt/service-workers/service-worker/registration-security-error.https.html new file mode 100644 index 000000000000..860c2d22ea93 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/registration-security-error.https.html @@ -0,0 +1,9 @@ + +Service Worker: Registration (SecurityError) + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/registration-service-worker-attributes.https.html b/test/fixtures/wpt/service-workers/service-worker/registration-service-worker-attributes.https.html new file mode 100644 index 000000000000..f7b52d5ddced --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/registration-service-worker-attributes.https.html @@ -0,0 +1,72 @@ + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/registration-updateviacache.https.html b/test/fixtures/wpt/service-workers/service-worker/registration-updateviacache.https.html new file mode 100644 index 000000000000..b2f6bbc6f849 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/registration-updateviacache.https.html @@ -0,0 +1,204 @@ + +Service Worker: Registration-updateViaCache + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/rejections.https.html b/test/fixtures/wpt/service-workers/service-worker/rejections.https.html new file mode 100644 index 000000000000..8002ad9a81b9 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/rejections.https.html @@ -0,0 +1,21 @@ + +Service Worker: Rejection Types + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/request-end-to-end.https.html b/test/fixtures/wpt/service-workers/service-worker/request-end-to-end.https.html new file mode 100644 index 000000000000..82475eabc4ab --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/request-end-to-end.https.html @@ -0,0 +1,44 @@ + +Service Worker: FetchEvent.request passed to onfetch + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resource-timing-bodySize.https.html b/test/fixtures/wpt/service-workers/service-worker/resource-timing-bodySize.https.html new file mode 100644 index 000000000000..5c2b1eba8c81 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resource-timing-bodySize.https.html @@ -0,0 +1,55 @@ + + + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resource-timing-cross-origin.https.html b/test/fixtures/wpt/service-workers/service-worker/resource-timing-cross-origin.https.html new file mode 100644 index 000000000000..9184a5933a8a --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resource-timing-cross-origin.https.html @@ -0,0 +1,47 @@ + + + + +This test validates Resource Timing for cross origin content fetched by Service Worker from an originally same-origin URL. + + + + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resource-timing-fetch-variants.https.html b/test/fixtures/wpt/service-workers/service-worker/resource-timing-fetch-variants.https.html new file mode 100644 index 000000000000..8d4f0be01a8a --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resource-timing-fetch-variants.https.html @@ -0,0 +1,121 @@ + + + +Test various interactions between fetch, service-workers and resource timing + + + + + + + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resource-timing.sub.https.html b/test/fixtures/wpt/service-workers/service-worker/resource-timing.sub.https.html new file mode 100644 index 000000000000..e8328f3597ba --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resource-timing.sub.https.html @@ -0,0 +1,150 @@ + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/about-blank-replacement-blank-dynamic-nested-frame.html b/test/fixtures/wpt/service-workers/service-worker/resources/about-blank-replacement-blank-dynamic-nested-frame.html new file mode 100644 index 000000000000..1e0c6209bfc0 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/about-blank-replacement-blank-dynamic-nested-frame.html @@ -0,0 +1,21 @@ + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/about-blank-replacement-blank-nested-frame.html b/test/fixtures/wpt/service-workers/service-worker/resources/about-blank-replacement-blank-nested-frame.html new file mode 100644 index 000000000000..16f7e7c60ffa --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/about-blank-replacement-blank-nested-frame.html @@ -0,0 +1,21 @@ + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/about-blank-replacement-srcdoc-nested-frame.html b/test/fixtures/wpt/service-workers/service-worker/resources/about-blank-replacement-srcdoc-nested-frame.html new file mode 100644 index 000000000000..0122a00aa432 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/about-blank-replacement-srcdoc-nested-frame.html @@ -0,0 +1,22 @@ + + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/about-blank-replacement-uncontrolled-nested-frame.html b/test/fixtures/wpt/service-workers/service-worker/resources/about-blank-replacement-uncontrolled-nested-frame.html new file mode 100644 index 000000000000..89509159a410 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/about-blank-replacement-uncontrolled-nested-frame.html @@ -0,0 +1,22 @@ + + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/about-blank-replacement-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/about-blank-replacement-worker.js new file mode 100644 index 000000000000..f43598e41c1a --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/about-blank-replacement-worker.js @@ -0,0 +1,95 @@ +// Helper routine to find a client that matches a particular URL. Note, we +// require that Client to be controlled to avoid false matches with other +// about:blank windows the browser might have. The initial about:blank should +// inherit the controller from its parent. +async function getClientByURL(url) { + let list = await clients.matchAll(); + return list.find(client => client.url === url); +} + +// Helper routine to perform a ping-pong with the given target client. We +// expect the Client to respond with its location URL. +async function pingPong(target) { + function waitForPong() { + return new Promise(resolve => { + self.addEventListener('message', function onMessage(evt) { + if (evt.data.type === 'PONG') { + resolve(evt.data.location); + } + }); + }); + } + + target.postMessage({ type: 'PING' }) + return await waitForPong(target); +} + +addEventListener('fetch', async evt => { + let url = new URL(evt.request.url); + if (!url.searchParams.get('nested')) { + return; + } + + evt.respondWith(async function() { + // Find the initial about:blank document. + const client = await getClientByURL('about:blank'); + if (!client) { + return new Response('failure: could not find about:blank client'); + } + + // If the nested frame is configured to support a ping-pong, then + // ping it now to verify its message listener exists. We also + // verify the Client's idea of its own location URL while we are doing + // this. + if (url.searchParams.get('ping')) { + const loc = await pingPong(client); + if (loc !== 'about:blank') { + return new Response(`failure: got location {$loc}, expected about:blank`); + } + } + + // Finally, allow the nested frame to complete loading. We place the + // Client ID we found for the initial about:blank in the body. + return new Response(client.id); + }()); +}); + +addEventListener('message', evt => { + if (evt.data.type !== 'GET_CLIENT_ID') { + return; + } + + evt.waitUntil(async function() { + let url = new URL(evt.data.url); + + // Find the given Client by its URL. + let client = await getClientByURL(evt.data.url); + if (!client) { + evt.source.postMessage({ + type: 'GET_CLIENT_ID', + result: `failure: could not find ${evt.data.url} client` + }); + return; + } + + // If the Client supports a ping-pong, then do it now to verify + // the message listener exists and its location matches the + // Client object. + if (url.searchParams.get('ping')) { + let loc = await pingPong(client); + if (loc !== evt.data.url) { + evt.source.postMessage({ + type: 'GET_CLIENT_ID', + result: `failure: got location ${loc}, expected ${evt.data.url}` + }); + return; + } + } + + // Finally, send the client ID back. + evt.source.postMessage({ + type: 'GET_CLIENT_ID', + result: client.id + }); + }()); +}); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/add-routes.js b/test/fixtures/wpt/service-workers/service-worker/resources/add-routes.js new file mode 100644 index 000000000000..796acd19c12f --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/add-routes.js @@ -0,0 +1,37 @@ +let globalAddRoutes; +let addRoutesError = {}; + +self.addEventListener('install', event => { + globalAddRoutes = event.addRoutes.bind(event); + globalAddRoutes([ + { + condition: { urlPattern: '/', runningStatus: 'not-running' }, + source: 'network', + }, + ]) + .then(() => { + addRoutesError.install = null; + }) + .catch(error => { + addRoutesError.install = error; + }); +}); + +self.addEventListener('activate', event => { + globalAddRoutes([ + { + condition: { urlPattern: '/', runningStatus: 'not-running' }, + source: 'network', + }, + ]) + .then(() => { + addRoutesError.activate = null; + }) + .catch(error => { + addRoutesError.activate = error; + }); +}); + +self.addEventListener('message', event => { + event.ports[0].postMessage(addRoutesError); +}); \ No newline at end of file diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/ancestorOrigins.html b/test/fixtures/wpt/service-workers/service-worker/resources/ancestorOrigins.html new file mode 100644 index 000000000000..f69b8de78256 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/ancestorOrigins.html @@ -0,0 +1,41 @@ + + +WindowClient ancestorOrigins helper + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/ancestorOrigins.js b/test/fixtures/wpt/service-workers/service-worker/resources/ancestorOrigins.js new file mode 100644 index 000000000000..7e4bf018fc4e --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/ancestorOrigins.js @@ -0,0 +1,6 @@ +self.onmessage = (evt) => { + evt.source.postMessage({ + ancestorOrigins: evt.source.ancestorOrigins, + sameObject: evt.source.ancestorOrigins === evt.source.ancestorOrigins + }); +}; diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/basic-module-2.js b/test/fixtures/wpt/service-workers/service-worker/resources/basic-module-2.js new file mode 100644 index 000000000000..189b1c87fee7 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/basic-module-2.js @@ -0,0 +1 @@ +export default 'hello again!'; diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/basic-module.js b/test/fixtures/wpt/service-workers/service-worker/resources/basic-module.js new file mode 100644 index 000000000000..789a89bc6308 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/basic-module.js @@ -0,0 +1 @@ +export default 'hello!'; diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/blank.html b/test/fixtures/wpt/service-workers/service-worker/resources/blank.html new file mode 100644 index 000000000000..a3c3a4689a62 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/blank.html @@ -0,0 +1,2 @@ + +Empty doc diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/claim-blob-url-worker-fetch-iframe.html b/test/fixtures/wpt/service-workers/service-worker/resources/claim-blob-url-worker-fetch-iframe.html new file mode 100644 index 000000000000..12ae1a87258f --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/claim-blob-url-worker-fetch-iframe.html @@ -0,0 +1,21 @@ + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/claim-nested-worker-fetch-iframe.html b/test/fixtures/wpt/service-workers/service-worker/resources/claim-nested-worker-fetch-iframe.html new file mode 100644 index 000000000000..2fa15db61d9c --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/claim-nested-worker-fetch-iframe.html @@ -0,0 +1,16 @@ + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/claim-nested-worker-fetch-parent-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/claim-nested-worker-fetch-parent-worker.js new file mode 100644 index 000000000000..f5ff7c234b42 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/claim-nested-worker-fetch-parent-worker.js @@ -0,0 +1,12 @@ +try { + var worker = new Worker('./claim-worker-fetch-worker.js'); + + self.onmessage = (event) => { + worker.postMessage(event.data); + } + worker.onmessage = (event) => { + self.postMessage(event.data); + }; +} catch (e) { + self.postMessage("Fail: " + e.data); +} diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/claim-shared-worker-fetch-iframe.html b/test/fixtures/wpt/service-workers/service-worker/resources/claim-shared-worker-fetch-iframe.html new file mode 100644 index 000000000000..ad865b848f8e --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/claim-shared-worker-fetch-iframe.html @@ -0,0 +1,13 @@ + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/claim-shared-worker-fetch-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/claim-shared-worker-fetch-worker.js new file mode 100644 index 000000000000..ddc8bea7af47 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/claim-shared-worker-fetch-worker.js @@ -0,0 +1,8 @@ +self.onconnect = (event) => { + var port = event.ports[0]; + event.ports[0].onmessage = (evt) => { + fetch(evt.data) + .then(response => response.text()) + .then(text => port.postMessage(text)); + }; +}; diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/claim-with-redirect-iframe.html b/test/fixtures/wpt/service-workers/service-worker/resources/claim-with-redirect-iframe.html new file mode 100644 index 000000000000..4150d7e68574 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/claim-with-redirect-iframe.html @@ -0,0 +1,48 @@ + + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/claim-worker-fetch-iframe.html b/test/fixtures/wpt/service-workers/service-worker/resources/claim-worker-fetch-iframe.html new file mode 100644 index 000000000000..92c5d15def0f --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/claim-worker-fetch-iframe.html @@ -0,0 +1,13 @@ + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/claim-worker-fetch-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/claim-worker-fetch-worker.js new file mode 100644 index 000000000000..7080181c85cb --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/claim-worker-fetch-worker.js @@ -0,0 +1,5 @@ +self.onmessage = (event) => { + fetch(event.data) + .then(response => response.text()) + .then(text => self.postMessage(text)); +}; diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/claim-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/claim-worker.js new file mode 100644 index 000000000000..18004079475e --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/claim-worker.js @@ -0,0 +1,19 @@ +self.addEventListener('message', function(event) { + self.clients.claim() + .then(function(result) { + if (result !== undefined) { + event.data.port.postMessage( + 'FAIL: claim() should be resolved with undefined'); + return; + } + event.data.port.postMessage('PASS'); + }) + .catch(function(error) { + event.data.port.postMessage('FAIL: exception: ' + error.name); + }); + }); + +self.addEventListener('fetch', function(event) { + if (!/404/.test(event.request.url)) + event.respondWith(new Response('Intercepted!')); + }); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/classic-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/classic-worker.js new file mode 100644 index 000000000000..36a32b1a1f84 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/classic-worker.js @@ -0,0 +1 @@ +importScripts('./imported-classic-script.js'); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/client-id-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/client-id-worker.js new file mode 100644 index 000000000000..ec71b3458b72 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/client-id-worker.js @@ -0,0 +1,27 @@ +self.onmessage = function(e) { + var port = e.data.port; + var message = []; + + var promise = Promise.resolve() + .then(function() { + // 1st matchAll() + return self.clients.matchAll().then(function(clients) { + clients.forEach(function(client) { + message.push(client.id); + }); + }); + }) + .then(function() { + // 2nd matchAll() + return self.clients.matchAll().then(function(clients) { + clients.forEach(function(client) { + message.push(client.id); + }); + }); + }) + .then(function() { + // Send an array containing ids of clients from 1st and 2nd matchAll() + port.postMessage(message); + }); + e.waitUntil(promise); +}; diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/client-navigate-frame.html b/test/fixtures/wpt/service-workers/service-worker/resources/client-navigate-frame.html new file mode 100644 index 000000000000..7e186f8ee798 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/client-navigate-frame.html @@ -0,0 +1,12 @@ + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/client-navigate-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/client-navigate-worker.js new file mode 100644 index 000000000000..6101d5d8f92c --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/client-navigate-worker.js @@ -0,0 +1,92 @@ +importScripts("worker-testharness.js"); +importScripts("test-helpers.sub.js"); +importScripts("/common/get-host-info.sub.js") +importScripts("testharness-helpers.js") + +setup({ explicit_done: true }); + +self.onfetch = function(e) { + if (e.request.url.indexOf("client-navigate-frame.html") >= 0) { + return; + } + e.respondWith(new Response(e.clientId)); +}; + +function pass(test, url) { + return { result: test, + url: url }; +} + +function fail(test, reason) { + return { result: "FAILED " + test + " " + reason } +} + +self.onmessage = function(e) { + var port = e.data.port; + var test = e.data.test; + var clientId = e.data.clientId; + var clientUrl = ""; + if (test === "test_client_navigate_success") { + promise_test(function(t) { + this.add_cleanup(() => port.postMessage(pass(test, clientUrl))); + return self.clients.get(clientId) + .then(client => client.navigate("client-navigated-frame.html")) + .then(client => { + clientUrl = client.url; + assert_true(client instanceof WindowClient); + }) + .catch(unreached_rejection(t)); + }, "Return value should be instance of WindowClient"); + done(); + } else if (test === "test_client_navigate_cross_origin") { + promise_test(function(t) { + this.add_cleanup(() => port.postMessage(pass(test, clientUrl))); + var path = new URL('client-navigated-frame.html', self.location.href).pathname; + var url = get_host_info()['HTTPS_REMOTE_ORIGIN'] + path; + return self.clients.get(clientId) + .then(client => client.navigate(url)) + .then(client => { + clientUrl = (client && client.url) || ""; + assert_equals(client, null, + 'cross-origin navigate resolves with null'); + }) + .catch(unreached_rejection(t)); + }, "Navigating to different origin should resolve with null"); + done(); + } else if (test === "test_client_navigate_about_blank") { + promise_test(function(t) { + this.add_cleanup(function() { port.postMessage(pass(test, "")); }); + return self.clients.get(clientId) + .then(client => promise_rejects_js(t, TypeError, client.navigate("about:blank"))) + .catch(unreached_rejection(t)); + }, "Navigating to about:blank should reject with TypeError"); + done(); + } else if (test === "test_client_navigate_mixed_content") { + promise_test(function(t) { + this.add_cleanup(function() { port.postMessage(pass(test, "")); }); + var path = new URL('client-navigated-frame.html', self.location.href).pathname; + // Insecure URL should fail since the frame is owned by a secure parent + // and navigating to http:// would create a mixed-content violation. + var url = get_host_info()['HTTP_REMOTE_ORIGIN'] + path; + return self.clients.get(clientId) + .then(client => promise_rejects_js(t, TypeError, client.navigate(url))) + .catch(unreached_rejection(t)); + }, "Navigating to mixed-content iframe should reject with TypeError"); + done(); + } else if (test === "test_client_navigate_redirect") { + var host_info = get_host_info(); + var url = new URL(host_info['HTTPS_REMOTE_ORIGIN']).toString() + + new URL("client-navigated-frame.html", location).pathname.substring(1); + promise_test(function(t) { + this.add_cleanup(() => port.postMessage(pass(test, clientUrl))); + return self.clients.get(clientId) + .then(client => client.navigate("redirect.py?Redirect=" + url)) + .then(client => { + clientUrl = (client && client.url) || "" + assert_equals(client, null); + }) + .catch(unreached_rejection(t)); + }, "Redirecting to another origin should resolve with null"); + done(); + } +}; diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/client-navigated-frame.html b/test/fixtures/wpt/service-workers/service-worker/resources/client-navigated-frame.html new file mode 100644 index 000000000000..307f7f9ac6ea --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/client-navigated-frame.html @@ -0,0 +1,3 @@ + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/client-url-creation-url-iframe.html b/test/fixtures/wpt/service-workers/service-worker/resources/client-url-creation-url-iframe.html new file mode 100644 index 000000000000..db2b9e5bbd91 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/client-url-creation-url-iframe.html @@ -0,0 +1,85 @@ + +Service Worker: Client.url is Window creation URL iframe resource + \ No newline at end of file diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/client-url-creation-url-sw.js b/test/fixtures/wpt/service-workers/service-worker/resources/client-url-creation-url-sw.js new file mode 100644 index 000000000000..013d9be4caeb --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/client-url-creation-url-sw.js @@ -0,0 +1,24 @@ +// This is a service worker script used by the client-url-creation-url test. +// It exists only to look up the client URL of the test iframe and send it back +// to the test page. +addEventListener('message', message_event => { + const port = message_event.data.port; + + const async_work = async () => { + try { + const clients = await self.clients.matchAll(); + + // In our test there should be exactly one client that is our test + // navigation iframe. + if (clients.length == 1) { + const client = clients[0]; + port.postMessage(client.url); + } else { + port.postMessage(`error: expected 1 client, not ${clients.length}`); + } + } catch (error) { + port.postMessage(`error: ${error.message}`); + } + }; + message_event.waitUntil(async_work()); +}); \ No newline at end of file diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/client-url-of-blob-url-worker.html b/test/fixtures/wpt/service-workers/service-worker/resources/client-url-of-blob-url-worker.html new file mode 100644 index 000000000000..00f6acede8eb --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/client-url-of-blob-url-worker.html @@ -0,0 +1,26 @@ + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/client-url-of-blob-url-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/client-url-of-blob-url-worker.js new file mode 100644 index 000000000000..fd754f8250da --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/client-url-of-blob-url-worker.js @@ -0,0 +1,10 @@ +addEventListener('fetch', e => { + if (e.request.url.includes('get-worker-client-url')) { + e.respondWith((async () => { + const clients = await self.clients.matchAll({type: 'worker'}); + if (clients.length != 1) + return new Response('one worker client should exist'); + return new Response(clients[0].url); + })()); + } +}); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/clients-frame-freeze.html b/test/fixtures/wpt/service-workers/service-worker/resources/clients-frame-freeze.html new file mode 100644 index 000000000000..7468a660e908 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/clients-frame-freeze.html @@ -0,0 +1,15 @@ + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/clients-get-client-types-frame-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/clients-get-client-types-frame-worker.js new file mode 100644 index 000000000000..0a1461b40e08 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/clients-get-client-types-frame-worker.js @@ -0,0 +1,11 @@ +onmessage = function(e) { + if (e.data.cmd == 'GetClientId') { + fetch('clientId') + .then(function(response) { + return response.text(); + }) + .then(function(text) { + e.data.port.postMessage({clientId: text}); + }); + } +}; diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/clients-get-client-types-frame.html b/test/fixtures/wpt/service-workers/service-worker/resources/clients-get-client-types-frame.html new file mode 100644 index 000000000000..4324e6d4054f --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/clients-get-client-types-frame.html @@ -0,0 +1,17 @@ + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/clients-get-client-types-shared-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/clients-get-client-types-shared-worker.js new file mode 100644 index 000000000000..fadef970374b --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/clients-get-client-types-shared-worker.js @@ -0,0 +1,10 @@ +onconnect = function(e) { + var port = e.ports[0]; + fetch('clientId') + .then(function(response) { + return response.text(); + }) + .then(function(text) { + port.postMessage({clientId: text}); + }); +}; diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/clients-get-client-types-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/clients-get-client-types-worker.js new file mode 100644 index 000000000000..0a1461b40e08 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/clients-get-client-types-worker.js @@ -0,0 +1,11 @@ +onmessage = function(e) { + if (e.data.cmd == 'GetClientId') { + fetch('clientId') + .then(function(response) { + return response.text(); + }) + .then(function(text) { + e.data.port.postMessage({clientId: text}); + }); + } +}; diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/clients-get-cross-origin-frame.html b/test/fixtures/wpt/service-workers/service-worker/resources/clients-get-cross-origin-frame.html new file mode 100644 index 000000000000..e16bb1116dc8 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/clients-get-cross-origin-frame.html @@ -0,0 +1,50 @@ + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/clients-get-frame.html b/test/fixtures/wpt/service-workers/service-worker/resources/clients-get-frame.html new file mode 100644 index 000000000000..27143d4b99b0 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/clients-get-frame.html @@ -0,0 +1,12 @@ + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/clients-get-other-origin.html b/test/fixtures/wpt/service-workers/service-worker/resources/clients-get-other-origin.html new file mode 100644 index 000000000000..6342fe04f404 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/clients-get-other-origin.html @@ -0,0 +1,64 @@ + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/clients-get-resultingClientId-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/clients-get-resultingClientId-worker.js new file mode 100644 index 000000000000..5a46ff9cf440 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/clients-get-resultingClientId-worker.js @@ -0,0 +1,60 @@ +let savedPort = null; +let savedResultingClientId = null; + +async function getTestingPage() { + const clientList = await self.clients.matchAll({ type: 'window', includeUncontrolled: true }); + for (let c of clientList) { + if (c.url.endsWith('clients-get.https.html')) { + c.focus(); + return c; + } + } + return null; +} + +async function destroyResultingClient(testingPage) { + const destroyedPromise = new Promise(resolve => { + self.addEventListener('message', e => { + if (e.data.msg == 'resultingClientDestroyed') { + resolve(); + } + }, {once: true}); + }); + testingPage.postMessage({ msg: 'destroyResultingClient' }); + return destroyedPromise; +} + +self.addEventListener('fetch', async (e) => { + let { resultingClientId } = e; + savedResultingClientId = resultingClientId; + + if (e.request.url.endsWith('simple.html?fail')) { + e.waitUntil((async () => { + const testingPage = await getTestingPage(); + await destroyResultingClient(testingPage); + testingPage.postMessage({ msg: 'resultingClientDestroyedAck', + resultingDestroyedClientId: savedResultingClientId }); + })()); + return; + } + + e.respondWith(fetch(e.request)); +}); + +self.addEventListener('message', (e) => { + let { msg, resultingClientId } = e.data; + e.waitUntil((async () => { + if (msg == 'getIsResultingClientUndefined') { + const client = await self.clients.get(resultingClientId); + let isUndefined = typeof client == 'undefined'; + e.source.postMessage({ msg: 'getIsResultingClientUndefined', + isResultingClientUndefined: isUndefined }); + return; + } + if (msg == 'getResultingClientId') { + e.source.postMessage({ msg: 'getResultingClientId', + resultingClientId: savedResultingClientId }); + return; + } + })()); +}); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/clients-get-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/clients-get-worker.js new file mode 100644 index 000000000000..8effa56c98c9 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/clients-get-worker.js @@ -0,0 +1,41 @@ +// This worker is designed to expose information about clients that is only available from Service Worker contexts. +// +// In the case of the `onfetch` handler, it provides the `clientId` property of +// the `event` object. In the case of the `onmessage` handler, it provides the +// Client instance attributes of the requested clients. +self.onfetch = function(e) { + if (/\/clientId$/.test(e.request.url)) { + e.respondWith(new Response(e.clientId)); + return; + } +}; + +self.onmessage = function(e) { + var client_ids = e.data.clientIds; + var message = []; + + e.waitUntil(Promise.all( + client_ids.map(function(client_id) { + return self.clients.get(client_id); + })) + .then(function(clients) { + // No matching client for a given id or a matched client is off-origin + // from the service worker. + if (clients.length == 1 && clients[0] == undefined) { + e.source.postMessage(clients[0]); + } else { + clients.forEach(function(client) { + if (client instanceof Client) { + message.push([client.visibilityState, + client.focused, + client.url, + client.type, + client.frameType]); + } else { + message.push(client); + } + }); + e.source.postMessage(message); + } + })); +}; diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/clients-matchall-blob-url-worker.html b/test/fixtures/wpt/service-workers/service-worker/resources/clients-matchall-blob-url-worker.html new file mode 100644 index 000000000000..ee89a0d8b3ee --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/clients-matchall-blob-url-worker.html @@ -0,0 +1,20 @@ + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/clients-matchall-client-types-dedicated-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/clients-matchall-client-types-dedicated-worker.js new file mode 100644 index 000000000000..5a3f04d33aaa --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/clients-matchall-client-types-dedicated-worker.js @@ -0,0 +1,3 @@ +onmessage = function(e) { + postMessage(e.data); +}; diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/clients-matchall-client-types-iframe.html b/test/fixtures/wpt/service-workers/service-worker/resources/clients-matchall-client-types-iframe.html new file mode 100644 index 000000000000..7607b035de31 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/clients-matchall-client-types-iframe.html @@ -0,0 +1,8 @@ + +Empty doc + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/clients-matchall-client-types-shared-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/clients-matchall-client-types-shared-worker.js new file mode 100644 index 000000000000..1ae72fb89445 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/clients-matchall-client-types-shared-worker.js @@ -0,0 +1,4 @@ +onconnect = function(e) { + var port = e.ports[0]; + port.postMessage('started'); +}; diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/clients-matchall-on-evaluation-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/clients-matchall-on-evaluation-worker.js new file mode 100644 index 000000000000..f1559aca39b6 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/clients-matchall-on-evaluation-worker.js @@ -0,0 +1,11 @@ +importScripts('test-helpers.sub.js'); + +var page_url = normalizeURL('../clients-matchall-on-evaluation.https.html'); + +self.clients.matchAll({includeUncontrolled: true}) + .then(function(clients) { + clients.forEach(function(client) { + if (client.url == page_url) + client.postMessage('matched'); + }); + }); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/clients-matchall-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/clients-matchall-worker.js new file mode 100644 index 000000000000..13e111a2f914 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/clients-matchall-worker.js @@ -0,0 +1,40 @@ +self.onmessage = function(e) { + var port = e.data.port; + var options = e.data.options; + + e.waitUntil(self.clients.matchAll(options) + .then(function(clients) { + var message = []; + clients.forEach(function(client) { + var frame_type = client.frameType; + if (client.url.indexOf('clients-matchall-include-uncontrolled.https.html') > -1 && + client.frameType == 'auxiliary') { + // The test tab might be opened using window.open() by the test framework. + // In that case, just pretend it's top-level! + frame_type = 'top-level'; + } + if (e.data.includeLifecycleState) { + message.push({visibilityState: client.visibilityState, + focused: client.focused, + url: client.url, + lifecycleState: client.lifecycleState, + type: client.type, + frameType: frame_type}); + } else { + message.push([client.visibilityState, + client.focused, + client.url, + client.type, + frame_type]); + } + }); + // Sort by url + if (!e.data.disableSort) { + message.sort(function(a, b) { return a[2] > b[2] ? 1 : -1; }); + } + port.postMessage(message); + }) + .catch(e => { + port.postMessage('clients.matchAll() rejected: ' + e); + })); +}; diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/controlled-frame-postMessage.html b/test/fixtures/wpt/service-workers/service-worker/resources/controlled-frame-postMessage.html new file mode 100644 index 000000000000..c4428e88a3da --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/controlled-frame-postMessage.html @@ -0,0 +1,39 @@ + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/controlled-worker-late-postMessage.js b/test/fixtures/wpt/service-workers/service-worker/resources/controlled-worker-late-postMessage.js new file mode 100644 index 000000000000..41d2db43b1fe --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/controlled-worker-late-postMessage.js @@ -0,0 +1,6 @@ +setTimeout(() => { + navigator.serviceWorker.onmessage = e => self.postMessage(e.data); +}, 500); +setTimeout(() => { + self.postMessage("No message received"); +}, 5000); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/controlled-worker-postMessage.js b/test/fixtures/wpt/service-workers/service-worker/resources/controlled-worker-postMessage.js new file mode 100644 index 000000000000..628dc65db11c --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/controlled-worker-postMessage.js @@ -0,0 +1,4 @@ +navigator.serviceWorker.onmessage = e => self.postMessage(e.data); +setTimeout(() => { + self.postMessage("No message received"); +}, 5000); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/cors-approved.txt b/test/fixtures/wpt/service-workers/service-worker/resources/cors-approved.txt new file mode 100644 index 000000000000..1cd89bb14d60 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/cors-approved.txt @@ -0,0 +1 @@ +plaintext diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/cors-approved.txt.headers b/test/fixtures/wpt/service-workers/service-worker/resources/cors-approved.txt.headers new file mode 100644 index 000000000000..f7985fd9bd52 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/cors-approved.txt.headers @@ -0,0 +1,3 @@ +Content-Type: text/plain +Access-Control-Allow-Origin: * + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/cors-denied.txt b/test/fixtures/wpt/service-workers/service-worker/resources/cors-denied.txt new file mode 100644 index 000000000000..ff333bd97da4 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/cors-denied.txt @@ -0,0 +1,2 @@ +this file is served without Access-Control-Allow-Origin headers so it should not +be readable from cross-origin. diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/create-blob-url-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/create-blob-url-worker.js new file mode 100644 index 000000000000..57e4882c24f7 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/create-blob-url-worker.js @@ -0,0 +1,22 @@ +const childWorkerScript = ` + self.onmessage = async (e) => { + const response = await fetch(e.data); + const text = await response.text(); + self.postMessage(text); + }; +`; +const blob = new Blob([childWorkerScript], { type: 'text/javascript' }); +const blobUrl = URL.createObjectURL(blob); +const childWorker = new Worker(blobUrl); + +// When a message comes from the parent frame, sends a resource url to the child +// worker. +self.onmessage = (e) => { + childWorker.postMessage(e.data); +}; + +// When a message comes from the child worker, sends a content of fetch() to the +// parent frame. +childWorker.onmessage = (e) => { + self.postMessage(e.data); +}; diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/create-out-of-scope-worker.html b/test/fixtures/wpt/service-workers/service-worker/resources/create-out-of-scope-worker.html new file mode 100644 index 000000000000..b51c45175094 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/create-out-of-scope-worker.html @@ -0,0 +1,19 @@ + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/css-sw-same-origin-substitution-iframe.sub.html b/test/fixtures/wpt/service-workers/service-worker/resources/css-sw-same-origin-substitution-iframe.sub.html new file mode 100644 index 000000000000..67e86e1ce6c3 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/css-sw-same-origin-substitution-iframe.sub.html @@ -0,0 +1,8 @@ + + +iframe: cross-origin CSS request, service worker substitutes a same-origin response + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/css-sw-same-origin-substitution-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/css-sw-same-origin-substitution-worker.js new file mode 100644 index 000000000000..eab5c9ff268b --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/css-sw-same-origin-substitution-worker.js @@ -0,0 +1,14 @@ +importScripts('test-helpers.sub.js'); + +const BASE_PATH = base_path(); + +self.addEventListener('fetch', event => { + const url = new URL(event.request.url); + // The iframe requests this cross-origin stylesheet; substitute a same-origin + // response (a real same-origin fetch => a cross-origin -> same-origin internal + // redirect on the page's channel). + if (url.pathname.endsWith('/css-sw-substitute-marker.css')) { + event.respondWith(fetch( + BASE_PATH + 'fetch-request-css-cross-origin-mime-check-same.css')); + } +}); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/direct.css b/test/fixtures/wpt/service-workers/service-worker/resources/direct.css new file mode 100644 index 000000000000..c812213f5307 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/direct.css @@ -0,0 +1,3 @@ +body { + width: 100%; +} diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/direct.html b/test/fixtures/wpt/service-workers/service-worker/resources/direct.html new file mode 100644 index 000000000000..e98d70207afa --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/direct.html @@ -0,0 +1,5 @@ + +Direct + + Here's a direct html from network. + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/direct.js b/test/fixtures/wpt/service-workers/service-worker/resources/direct.js new file mode 100644 index 000000000000..ed6f0e5f980a --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/direct.js @@ -0,0 +1 @@ +window.router_condition_request_destination_script = true; diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/direct.txt b/test/fixtures/wpt/service-workers/service-worker/resources/direct.txt new file mode 100644 index 000000000000..f3d9861c137b --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/direct.txt @@ -0,0 +1 @@ +Network diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/echo-message-to-source-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/echo-message-to-source-worker.js new file mode 100644 index 000000000000..bbbd35fb4f60 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/echo-message-to-source-worker.js @@ -0,0 +1,3 @@ +addEventListener('message', evt => { + evt.source.postMessage(evt.data); +}); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/embed-and-object-are-not-intercepted-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/embed-and-object-are-not-intercepted-worker.js new file mode 100644 index 000000000000..ffcdb7512888 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/embed-and-object-are-not-intercepted-worker.js @@ -0,0 +1,14 @@ +// This worker intercepts a request for EMBED/OBJECT and responds with a +// response that indicates that interception occurred. The tests expect +// that interception does not occur. +self.addEventListener('fetch', e => { + if (e.request.url.indexOf('embedded-content-from-server.html') != -1) { + e.respondWith(fetch('embedded-content-from-service-worker.html')); + return; + } + + if (e.request.url.indexOf('green.png') != -1) { + e.respondWith(Promise.reject('network error to show interception occurred')); + return; + } + }); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/embed-image-is-not-intercepted-iframe.html b/test/fixtures/wpt/service-workers/service-worker/resources/embed-image-is-not-intercepted-iframe.html new file mode 100644 index 000000000000..7b8b257203a2 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/embed-image-is-not-intercepted-iframe.html @@ -0,0 +1,21 @@ + + +iframe for embed-and-object-are-not-intercepted test + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/embed-is-not-intercepted-iframe.html b/test/fixtures/wpt/service-workers/service-worker/resources/embed-is-not-intercepted-iframe.html new file mode 100644 index 000000000000..39149915cc57 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/embed-is-not-intercepted-iframe.html @@ -0,0 +1,17 @@ + + +iframe for embed-and-object-are-not-intercepted test + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/embed-navigation-is-not-intercepted-iframe.html b/test/fixtures/wpt/service-workers/service-worker/resources/embed-navigation-is-not-intercepted-iframe.html new file mode 100644 index 000000000000..5e86f67735f7 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/embed-navigation-is-not-intercepted-iframe.html @@ -0,0 +1,23 @@ + + +iframe for embed-and-object-are-not-intercepted test + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/embedded-content-from-server.html b/test/fixtures/wpt/service-workers/service-worker/resources/embedded-content-from-server.html new file mode 100644 index 000000000000..ff50a9c75269 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/embedded-content-from-server.html @@ -0,0 +1,6 @@ + + +embed for embed-and-object-are-not-intercepted test + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/embedded-content-from-service-worker.html b/test/fixtures/wpt/service-workers/service-worker/resources/embedded-content-from-service-worker.html new file mode 100644 index 000000000000..2e2b9236082d --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/embedded-content-from-service-worker.html @@ -0,0 +1,7 @@ + + +embed for embed-and-object-are-not-intercepted test + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/empty-but-slow-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/empty-but-slow-worker.js new file mode 100644 index 000000000000..92abac7a384d --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/empty-but-slow-worker.js @@ -0,0 +1,8 @@ +addEventListener('fetch', evt => { + if (evt.request.url.endsWith('slow')) { + // Performance.now() might be a bit better here, but Date.now() has + // better compat in workers right now. + let start = Date.now(); + while(Date.now() - start < 2000); + } +}); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/empty-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/empty-worker.js new file mode 100644 index 000000000000..49ceb2648a93 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/empty-worker.js @@ -0,0 +1 @@ +// Do nothing. diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/empty.h2.js b/test/fixtures/wpt/service-workers/service-worker/resources/empty.h2.js new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/empty.html b/test/fixtures/wpt/service-workers/service-worker/resources/empty.html new file mode 100644 index 000000000000..6feb11946b80 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/empty.html @@ -0,0 +1,6 @@ + + + +hello world + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/empty.js b/test/fixtures/wpt/service-workers/service-worker/resources/empty.js new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/enable-client-message-queue.html b/test/fixtures/wpt/service-workers/service-worker/resources/enable-client-message-queue.html new file mode 100644 index 000000000000..512bd14bc67d --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/enable-client-message-queue.html @@ -0,0 +1,39 @@ + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/end-to-end-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/end-to-end-worker.js new file mode 100644 index 000000000000..d45a50556a93 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/end-to-end-worker.js @@ -0,0 +1,7 @@ +onmessage = function(e) { + var message = e.data; + if (typeof message === 'object' && 'port' in message) { + var response = 'Ack for: ' + message.from; + message.port.postMessage(response); + } +}; diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/events-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/events-worker.js new file mode 100644 index 000000000000..80a2188677ba --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/events-worker.js @@ -0,0 +1,12 @@ +var eventsSeen = []; + +function handler(event) { eventsSeen.push(event.type); } + +['activate', 'install'].forEach(function(type) { + self.addEventListener(type, handler); + }); + +onmessage = function(e) { + var message = e.data; + message.port.postMessage({events: eventsSeen}); +}; diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/extendable-event-async-waituntil.js b/test/fixtures/wpt/service-workers/service-worker/resources/extendable-event-async-waituntil.js new file mode 100644 index 000000000000..8a975b0d2e9b --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/extendable-event-async-waituntil.js @@ -0,0 +1,210 @@ +// This worker calls waitUntil() and respondWith() asynchronously and +// reports back to the test whether they threw. +// +// These test cases are confusing. Bear in mind that the event is active +// (calling waitUntil() is allowed) if: +// * The pending promise count is not 0, or +// * The event dispatch flag is set. + +// Controlled by 'init'/'done' messages. +var resolveLockPromise; +var port; + +self.addEventListener('message', function(event) { + var waitPromise; + var resolveTestPromise; + + switch (event.data.step) { + case 'init': + event.waitUntil(new Promise((res) => { resolveLockPromise = res; })); + port = event.data.port; + break; + case 'done': + resolveLockPromise(); + break; + + // Throws because waitUntil() is called in a task after event dispatch + // finishes. + case 'no-current-extension-different-task': + async_task_waituntil(event).then(reportResultExpecting('InvalidStateError')); + break; + + // OK because waitUntil() is called in a microtask that runs after the + // event handler runs, while the event dispatch flag is still set. + case 'no-current-extension-different-microtask': + async_microtask_waituntil(event).then(reportResultExpecting('OK')); + break; + + // OK because the second waitUntil() is called while the first waitUntil() + // promise is still pending. + case 'current-extension-different-task': + event.waitUntil(new Promise((res) => { resolveTestPromise = res; })); + async_task_waituntil(event).then(reportResultExpecting('OK')).then(resolveTestPromise); + break; + + // OK because all promises involved resolve "immediately", so the second + // waitUntil() is called during the microtask checkpoint at the end of + // event dispatching, when the event dispatch flag is still set. + case 'during-event-dispatch-current-extension-expired-same-microtask-turn': + waitPromise = Promise.resolve(); + event.waitUntil(waitPromise); + waitPromise.then(() => { return sync_waituntil(event); }) + .then(reportResultExpecting('OK')) + break; + + // OK for the same reason as above. + case 'during-event-dispatch-current-extension-expired-same-microtask-turn-extra': + waitPromise = Promise.resolve(); + event.waitUntil(waitPromise); + waitPromise.then(() => { return async_microtask_waituntil(event); }) + .then(reportResultExpecting('OK')) + break; + + + // OK because the pending promise count is decremented in a microtask + // queued upon fulfillment of the first waitUntil() promise, so the second + // waitUntil() is called while the pending promise count is still + // positive. + case 'after-event-dispatch-current-extension-expired-same-microtask-turn': + waitPromise = makeNewTaskPromise(); + event.waitUntil(waitPromise); + waitPromise.then(() => { return sync_waituntil(event); }) + .then(reportResultExpecting('OK')) + break; + + // Throws because the second waitUntil() is called after the pending + // promise count was decremented to 0. + case 'after-event-dispatch-current-extension-expired-same-microtask-turn-extra': + waitPromise = makeNewTaskPromise(); + event.waitUntil(waitPromise); + waitPromise.then(() => { return async_microtask_waituntil(event); }) + .then(reportResultExpecting('InvalidStateError')) + break; + + // Throws because the second waitUntil() is called in a new task, after + // first waitUntil() promise settled and the event dispatch flag is unset. + case 'current-extension-expired-different-task': + event.waitUntil(Promise.resolve()); + async_task_waituntil(event).then(reportResultExpecting('InvalidStateError')); + break; + + case 'script-extendable-event': + self.dispatchEvent(new ExtendableEvent('nontrustedevent')); + break; + } + + event.source.postMessage('ACK'); + }); + +self.addEventListener('fetch', function(event) { + const path = new URL(event.request.url).pathname; + const step = path.substring(path.lastIndexOf('/') + 1); + let response; + switch (step) { + // OK because waitUntil() is called while the respondWith() promise is still + // unsettled, so the pending promise count is positive. + case 'pending-respondwith-async-waituntil': + var resolveFetch; + response = new Promise((res) => { resolveFetch = res; }); + event.respondWith(response); + async_task_waituntil(event) + .then(reportResultExpecting('OK')) + .then(() => { resolveFetch(new Response('OK')); }); + break; + + // OK because all promises involved resolve "immediately", so waitUntil() is + // called during the microtask checkpoint at the end of event dispatching, + // when the event dispatch flag is still set. + case 'during-event-dispatch-respondwith-microtask-sync-waituntil': + response = Promise.resolve(new Response('RESP')); + event.respondWith(response); + response.then(() => { return sync_waituntil(event); }) + .then(reportResultExpecting('OK')); + break; + + // OK because all promises involved resolve "immediately", so waitUntil() is + // called during the microtask checkpoint at the end of event dispatching, + // when the event dispatch flag is still set. + case 'during-event-dispatch-respondwith-microtask-async-waituntil': + response = Promise.resolve(new Response('RESP')); + event.respondWith(response); + response.then(() => { return async_microtask_waituntil(event); }) + .then(reportResultExpecting('OK')); + break; + + // OK because the pending promise count is decremented in a microtask queued + // upon fulfillment of the respondWith() promise, so waitUntil() is called + // while the pending promise count is still positive. + case 'after-event-dispatch-respondwith-microtask-sync-waituntil': + response = makeNewTaskPromise().then(() => {return new Response('RESP');}); + event.respondWith(response); + response.then(() => { return sync_waituntil(event); }) + .then(reportResultExpecting('OK')); + break; + + + // Throws because waitUntil() is called after the pending promise count was + // decremented to 0. + case 'after-event-dispatch-respondwith-microtask-async-waituntil': + response = makeNewTaskPromise().then(() => {return new Response('RESP');}); + event.respondWith(response); + response.then(() => { return async_microtask_waituntil(event); }) + .then(reportResultExpecting('InvalidStateError')) + break; + } +}); + +self.addEventListener('nontrustedevent', function(event) { + sync_waituntil(event).then(reportResultExpecting('InvalidStateError')); + }); + +function reportResultExpecting(expectedResult) { + return function (result) { + port.postMessage({result : result, expected: expectedResult}); + return result; + }; +} + +function sync_waituntil(event) { + return new Promise((res, rej) => { + try { + event.waitUntil(Promise.resolve()); + res('OK'); + } catch (error) { + res(error.name); + } + }); +} + +function async_microtask_waituntil(event) { + return new Promise((res, rej) => { + Promise.resolve().then(() => { + try { + event.waitUntil(Promise.resolve()); + res('OK'); + } catch (error) { + res(error.name); + } + }); + }); +} + +function async_task_waituntil(event) { + return new Promise((res, rej) => { + setTimeout(() => { + try { + event.waitUntil(Promise.resolve()); + res('OK'); + } catch (error) { + res(error.name); + } + }, 0); + }); +} + +// Returns a promise that settles in a separate task. +function makeNewTaskPromise() { + return new Promise(resolve => { + setTimeout(resolve, 0); + }); +} diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/extendable-event-waituntil.js b/test/fixtures/wpt/service-workers/service-worker/resources/extendable-event-waituntil.js new file mode 100644 index 000000000000..20a9eb023f62 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/extendable-event-waituntil.js @@ -0,0 +1,87 @@ +var pendingPorts = []; +var portResolves = []; + +onmessage = function(e) { + var message = e.data; + if ('port' in message) { + var resolve = self.portResolves.shift(); + if (resolve) + resolve(message.port); + else + self.pendingPorts.push(message.port); + } +}; + +function fulfillPromise() { + return new Promise(function(resolve) { + // Make sure the oninstall/onactivate callback returns first. + Promise.resolve().then(function() { + var port = self.pendingPorts.shift(); + if (port) + resolve(port); + else + self.portResolves.push(resolve); + }); + }).then(function(port) { + port.postMessage('SYNC'); + return new Promise(function(resolve) { + port.onmessage = function(e) { + if (e.data == 'ACK') + resolve(); + }; + }); + }); +} + +function rejectPromise() { + return new Promise(function(resolve, reject) { + // Make sure the oninstall/onactivate callback returns first. + Promise.resolve().then(reject); + }); +} + +function stripScopeName(url) { + return url.split('/').slice(-1)[0]; +} + +oninstall = function(e) { + switch (stripScopeName(self.location.href)) { + case 'install-fulfilled': + e.waitUntil(fulfillPromise()); + break; + case 'install-rejected': + e.waitUntil(rejectPromise()); + break; + case 'install-multiple-fulfilled': + e.waitUntil(fulfillPromise()); + e.waitUntil(fulfillPromise()); + break; + case 'install-reject-precedence': + // Three "extend lifetime promises" are needed to verify that the user + // agent waits for all promises to settle even in the event of rejection. + // The first promise is fulfilled on demand by the client, the second is + // immediately scheduled for rejection, and the third is fulfilled on + // demand by the client (but only after the first promise has been + // fulfilled). + // + // User agents which simply expose `Promise.all` semantics in this case + // (by entering the "redundant state" following the rejection of the + // second promise but prior to the fulfillment of the third) can be + // identified from the client context. + e.waitUntil(fulfillPromise()); + e.waitUntil(rejectPromise()); + e.waitUntil(fulfillPromise()); + break; + } +}; + +onactivate = function(e) { + switch (stripScopeName(self.location.href)) { + case 'activate-fulfilled': + e.waitUntil(fulfillPromise()); + break; + case 'activate-rejected': + e.waitUntil(rejectPromise()); + break; + } +}; diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fail-on-fetch-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/fail-on-fetch-worker.js new file mode 100644 index 000000000000..517f289fbc8e --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fail-on-fetch-worker.js @@ -0,0 +1,5 @@ +importScripts('worker-testharness.js'); + +this.addEventListener('fetch', function(event) { + event.respondWith(new Response('ERROR')); + }); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-access-control-login.html b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-access-control-login.html new file mode 100644 index 000000000000..ee296807ed14 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-access-control-login.html @@ -0,0 +1,16 @@ + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-canvas-tainting-double-write-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-canvas-tainting-double-write-worker.js new file mode 100644 index 000000000000..17723dcdda2f --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-canvas-tainting-double-write-worker.js @@ -0,0 +1,7 @@ +self.addEventListener('fetch', (event) => { + url = new URL(event.request.url); + if (url.search == '?PNGIMAGE') { + localUrl = new URL(url.pathname + url.search, self.location); + event.respondWith(fetch(localUrl)); + } +}); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-canvas-tainting-iframe.html b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-canvas-tainting-iframe.html new file mode 100644 index 000000000000..75d766c193a8 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-canvas-tainting-iframe.html @@ -0,0 +1,70 @@ + +iframe for fetch canvas tainting test + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-canvas-tainting-tests.js b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-canvas-tainting-tests.js new file mode 100644 index 000000000000..2aada3669eff --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-canvas-tainting-tests.js @@ -0,0 +1,241 @@ +// This is the main driver of the canvas tainting tests. +const NOT_TAINTED = 'NOT_TAINTED'; +const TAINTED = 'TAINTED'; +const LOAD_ERROR = 'LOAD_ERROR'; + +let frame; + +// Creates a single promise_test. +function canvas_taint_test(url, cross_origin, expected_result) { + promise_test(t => { + return frame.contentWindow.create_test_case_promise(url, cross_origin) + .then(result => { + assert_equals(result, expected_result); + }); + }, 'url "' + url + '" with crossOrigin "' + cross_origin + '" should be ' + + expected_result); +} + + +// Runs all the tests. The given |params| has these properties: +// * |resource_path|: the relative path to the (image/video) resource to test. +// * |cache|: when true, the service worker bounces responses into +// Cache Storage and back out before responding with them. +function do_canvas_tainting_tests(params) { + const host_info = get_host_info(); + let resource_path = params.resource_path; + if (params.cache) + resource_path += "&cache=true"; + const resource_url = host_info['HTTPS_ORIGIN'] + resource_path; + const remote_resource_url = host_info['HTTPS_REMOTE_ORIGIN'] + resource_path; + + // Set up the service worker and the frame. + promise_test(function(t) { + const SCOPE = 'resources/fetch-canvas-tainting-iframe.html'; + const SCRIPT = 'resources/fetch-rewrite-worker.js'; + const host_info = get_host_info(); + + // login_https() is needed because some test cases use credentials. + return login_https(t) + .then(function() { + return service_worker_unregister_and_register(t, SCRIPT, SCOPE); + }) + .then(function(registration) { + promise_test(() => { + if (frame) + frame.remove(); + return registration.unregister(); + }, 'restore global state'); + + return wait_for_state(t, registration.installing, 'activated'); + }) + .then(function() { return with_iframe(SCOPE); }) + .then(f => { + frame = f; + }); + }, 'initialize global state'); + + // Reject tests. Add '&reject' so the service worker responds with a rejected promise. + // A load error is expected. + canvas_taint_test(resource_url + '&reject', '', LOAD_ERROR); + canvas_taint_test(resource_url + '&reject', 'anonymous', LOAD_ERROR); + canvas_taint_test(resource_url + '&reject', 'use-credentials', LOAD_ERROR); + + // Fallback tests. Add '&ignore' so the service worker does not respond to the fetch + // request, and we fall back to network. + canvas_taint_test(resource_url + '&ignore', '', NOT_TAINTED); + canvas_taint_test(remote_resource_url + '&ignore', '', TAINTED); + canvas_taint_test(remote_resource_url + '&ignore', 'anonymous', LOAD_ERROR); + canvas_taint_test( + remote_resource_url + '&ACAOrigin=' + host_info['HTTPS_ORIGIN'] + + '&ignore', + 'anonymous', + NOT_TAINTED); + canvas_taint_test(remote_resource_url + '&ignore', 'use-credentials', LOAD_ERROR); + canvas_taint_test( + remote_resource_url + '&ACAOrigin=' + host_info['HTTPS_ORIGIN'] + + '&ignore', + 'use-credentials', + LOAD_ERROR); + canvas_taint_test( + remote_resource_url + '&ACAOrigin=' + host_info['HTTPS_ORIGIN'] + + '&ACACredentials=true&ignore', + 'use-credentials', + NOT_TAINTED); + + // Credential tests (with fallback). Add '&Auth' so the server requires authentication. + // Furthermore, add '&ignore' so the service worker falls back to network. + canvas_taint_test(resource_url + '&Auth&ignore', '', NOT_TAINTED); + canvas_taint_test(remote_resource_url + '&Auth&ignore', '', TAINTED); + canvas_taint_test( + remote_resource_url + '&Auth&ignore', 'anonymous', LOAD_ERROR); + canvas_taint_test( + remote_resource_url + '&Auth&ignore', + 'use-credentials', + LOAD_ERROR); + canvas_taint_test( + remote_resource_url + '&Auth&ACAOrigin=' + host_info['HTTPS_ORIGIN'] + + '&ignore', + 'use-credentials', + LOAD_ERROR); + canvas_taint_test( + remote_resource_url + '&Auth&ACAOrigin=' + host_info['HTTPS_ORIGIN'] + + '&ACACredentials=true&ignore', + 'use-credentials', + NOT_TAINTED); + + // In the following tests, the service worker provides a response. + // Add '&url' so the service worker responds with fetch(url). + // Add '&mode' to configure the fetch request options. + + // Basic response tests. Set &url to the original url. + canvas_taint_test( + resource_url + '&mode=same-origin&url=' + encodeURIComponent(resource_url), + '', + NOT_TAINTED); + canvas_taint_test( + resource_url + '&mode=same-origin&url=' + encodeURIComponent(resource_url), + 'anonymous', + NOT_TAINTED); + canvas_taint_test( + resource_url + '&mode=same-origin&url=' + encodeURIComponent(resource_url), + 'use-credentials', + NOT_TAINTED); + canvas_taint_test( + remote_resource_url + '&mode=same-origin&url=' + + encodeURIComponent(resource_url), + '', + NOT_TAINTED); + canvas_taint_test( + remote_resource_url + '&mode=same-origin&url=' + + encodeURIComponent(resource_url), + 'anonymous', + NOT_TAINTED); + canvas_taint_test( + remote_resource_url + '&mode=same-origin&url=' + + encodeURIComponent(resource_url), + 'use-credentials', + NOT_TAINTED); + + // Opaque response tests. Set &url to the cross-origin URL, and &mode to + // 'no-cors' so we expect an opaque response. + canvas_taint_test( + resource_url + + '&mode=no-cors&url=' + encodeURIComponent(remote_resource_url), + '', + TAINTED); + canvas_taint_test( + resource_url + + '&mode=no-cors&url=' + encodeURIComponent(remote_resource_url), + 'anonymous', + LOAD_ERROR); + canvas_taint_test( + resource_url + + '&mode=no-cors&url=' + encodeURIComponent(remote_resource_url), + 'use-credentials', + LOAD_ERROR); + canvas_taint_test( + remote_resource_url + + '&mode=no-cors&url=' + encodeURIComponent(remote_resource_url), + '', + TAINTED); + canvas_taint_test( + remote_resource_url + + '&mode=no-cors&url=' + encodeURIComponent(remote_resource_url), + 'anonymous', + LOAD_ERROR); + canvas_taint_test( + remote_resource_url + + '&mode=no-cors&url=' + encodeURIComponent(remote_resource_url), + 'use-credentials', + LOAD_ERROR); + + // CORS response tests. Set &url to the cross-origin URL, and &mode + // to 'cors' to attempt a CORS request. + canvas_taint_test( + resource_url + '&mode=cors&url=' + + encodeURIComponent(remote_resource_url + + '&ACAOrigin=' + host_info['HTTPS_ORIGIN']), + '', + LOAD_ERROR); // We expect LOAD_ERROR since the server doesn't respond + // with an Access-Control-Allow-Credentials header. + canvas_taint_test( + resource_url + '&mode=cors&credentials=same-origin&url=' + + encodeURIComponent(remote_resource_url + + '&ACAOrigin=' + host_info['HTTPS_ORIGIN']), + '', + NOT_TAINTED); + canvas_taint_test( + resource_url + '&mode=cors&url=' + + encodeURIComponent(remote_resource_url + + '&ACAOrigin=' + host_info['HTTPS_ORIGIN']), + 'anonymous', + NOT_TAINTED); + canvas_taint_test( + resource_url + '&mode=cors&url=' + + encodeURIComponent(remote_resource_url + + '&ACAOrigin=' + host_info['HTTPS_ORIGIN']), + 'use-credentials', + LOAD_ERROR); // We expect LOAD_ERROR since the server doesn't respond + // with an Access-Control-Allow-Credentials header. + canvas_taint_test( + resource_url + '&mode=cors&url=' + + encodeURIComponent( + remote_resource_url + + '&ACACredentials=true&ACAOrigin=' + host_info['HTTPS_ORIGIN']), + 'use-credentials', + NOT_TAINTED); + canvas_taint_test( + remote_resource_url + '&mode=cors&url=' + + encodeURIComponent(remote_resource_url + + '&ACAOrigin=' + host_info['HTTPS_ORIGIN']), + '', + LOAD_ERROR); // We expect LOAD_ERROR since the server doesn't respond + // with an Access-Control-Allow-Credentials header. + canvas_taint_test( + remote_resource_url + '&mode=cors&credentials=same-origin&url=' + + encodeURIComponent(remote_resource_url + + '&ACAOrigin=' + host_info['HTTPS_ORIGIN']), + '', + NOT_TAINTED); + canvas_taint_test( + remote_resource_url + '&mode=cors&url=' + + encodeURIComponent(remote_resource_url + + '&ACAOrigin=' + host_info['HTTPS_ORIGIN']), + 'anonymous', + NOT_TAINTED); + canvas_taint_test( + remote_resource_url + '&mode=cors&url=' + + encodeURIComponent(remote_resource_url + + '&ACAOrigin=' + host_info['HTTPS_ORIGIN']), + 'use-credentials', + LOAD_ERROR); // We expect LOAD_ERROR since the server doesn't respond + // with an Access-Control-Allow-Credentials header. + canvas_taint_test( + remote_resource_url + '&mode=cors&url=' + + encodeURIComponent( + remote_resource_url + + '&ACACredentials=true&ACAOrigin=' + host_info['HTTPS_ORIGIN']), + 'use-credentials', + NOT_TAINTED); +} diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-cors-exposed-header-names-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-cors-exposed-header-names-worker.js new file mode 100644 index 000000000000..145952a22cf0 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-cors-exposed-header-names-worker.js @@ -0,0 +1,3 @@ +self.addEventListener('fetch', (e) => { + e.respondWith(fetch(e.request)); + }); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-cors-xhr-iframe.html b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-cors-xhr-iframe.html new file mode 100644 index 000000000000..d88c5103d35b --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-cors-xhr-iframe.html @@ -0,0 +1,170 @@ + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-csp-iframe.html b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-csp-iframe.html new file mode 100644 index 000000000000..33bf0416d585 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-csp-iframe.html @@ -0,0 +1,16 @@ + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-csp-iframe.html.sub.headers b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-csp-iframe.html.sub.headers new file mode 100644 index 000000000000..5a1c7b941aca --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-csp-iframe.html.sub.headers @@ -0,0 +1 @@ +Content-Security-Policy: img-src https://{{host}}:{{ports[https][0]}}; connect-src 'unsafe-inline' 'self' diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-error-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-error-worker.js new file mode 100644 index 000000000000..788252cf3b3b --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-error-worker.js @@ -0,0 +1,22 @@ +importScripts("/resources/testharness.js"); + +function doTest(event) +{ + if (!event.request.url.includes("fetch-error-test")) + return; + + let counter = 0; + const stream = new ReadableStream({ pull: controller => { + switch (++counter) { + case 1: + controller.enqueue(new Uint8Array([1])); + return; + default: + // We asynchronously error the stream so that there is ample time to resolve the fetch promise and call text() on the response. + step_timeout(() => controller.error("Sorry"), 50); + } + }}); + event.respondWith(new Response(stream)); +} + +self.addEventListener("fetch", doTest); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-add-async-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-add-async-worker.js new file mode 100644 index 000000000000..a5a44a57c99c --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-add-async-worker.js @@ -0,0 +1,6 @@ +importScripts('/resources/testharness.js'); + +promise_test(async () => { + await new Promise(handler => { step_timeout(handler, 0); }); + self.addEventListener('fetch', () => {}); +}, 'fetch event added asynchronously does not throw'); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-after-navigation-within-page-iframe.html b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-after-navigation-within-page-iframe.html new file mode 100644 index 000000000000..bf8a6d5ce51f --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-after-navigation-within-page-iframe.html @@ -0,0 +1,22 @@ + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-async-respond-with-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-async-respond-with-worker.js new file mode 100644 index 000000000000..dc3f1a1e9856 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-async-respond-with-worker.js @@ -0,0 +1,66 @@ +// This worker attempts to call respondWith() asynchronously after the +// fetch event handler finished. It reports back to the test whether +// an exception was thrown. + +// These get reset at the start of a test case. +let reportResult; + +// The test page sends a message to tell us that a new test case is starting. +// We expect a fetch event after this. +self.addEventListener('message', (event) => { + // Ensure tests run mutually exclusive. + if (reportResult) { + event.source.postMessage('testAlreadyRunning'); + return; + } + + const resultPromise = new Promise((resolve) => { + reportResult = resolve; + // Tell the client that everything is initialized and that it's safe to + // proceed with the test without relying on the order of events (which some + // browsers like Chrome may not guarantee). + event.source.postMessage('messageHandlerInitialized'); + }); + + // Keep the worker alive until the test case finishes, and report + // back the result to the test page. + event.waitUntil(resultPromise.then(result => { + reportResult = null; + event.source.postMessage(result); + })); +}); + +// Calls respondWith() and reports back whether an exception occurred. +function tryRespondWith(event) { + try { + event.respondWith(new Response()); + reportResult({didThrow: false}); + } catch (error) { + reportResult({didThrow: true, error: error.name}); + } +} + +function respondWithInTask(event) { + setTimeout(() => { + tryRespondWith(event); + }, 0); +} + +function respondWithInMicrotask(event) { + Promise.resolve().then(() => { + tryRespondWith(event); + }); +} + +self.addEventListener('fetch', function(event) { + const path = new URL(event.request.url).pathname; + const test = path.substring(path.lastIndexOf('/') + 1); + + // If this is a test case, try respondWith() and report back to the test page + // the result. + if (test == 'respondWith-in-task') { + respondWithInTask(event); + } else if (test == 'respondWith-in-microtask') { + respondWithInMicrotask(event); + } +}); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-download-helpers.js b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-download-helpers.js new file mode 100644 index 000000000000..f9ad52daf81d --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-download-helpers.js @@ -0,0 +1,50 @@ +// Shared helpers for fetch-event-download-*.https.html tests. +// crbug.com/40410035. + +function uniqueChannelId() { + return 'download-' + Math.random().toString(36).slice(2); +} + +// Resolves with the first message posted to a BroadcastChannel of the given +// id, or rejects via the test's timeout if none arrives. +function nextChannelMessage(t, channelId) { + return new Promise((resolve) => { + const channel = new BroadcastChannel(channelId); + channel.addEventListener('message', (e) => { + channel.close(); + resolve(e.data); + }, {once: true}); + t.add_cleanup(() => channel.close()); + }); +} + +// Resolves true if a message arrived within `timeoutMs`, false otherwise. +function awaitChannelSilence(t, channelId, timeoutMs) { + return new Promise((resolve) => { + const channel = new BroadcastChannel(channelId); + let received = false; + channel.addEventListener('message', () => { + received = true; + channel.close(); + resolve(true); + }); + step_timeout(() => { + channel.close(); + resolve(received); + }, timeoutMs); + t.add_cleanup(() => channel.close()); + }); +} + +// Programmatically clicks an via testdriver so the click carries +// transient activation; without it Chromium's download path may suppress the +// fetch entirely. +async function clickDownloadAnchor(t, href) { + const a = document.createElement('a'); + a.href = href; + a.download = ''; + a.textContent = 'download'; + document.body.appendChild(a); + t.add_cleanup(() => a.remove()); + await test_driver.click(a); +} diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-download-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-download-worker.js new file mode 100644 index 000000000000..38d0f56dc302 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-download-worker.js @@ -0,0 +1,39 @@ +// Service worker for fetch-event-download-*.https.html. +// +// Echoes the FetchEvent it sees for download requests onto a BroadcastChannel +// named after the channel ID embedded in the request URL's `?channel=` query +// parameter, then optionally provides a response based on the `?mode=` param. +// +// Mode values: +// "respond" (default) — call event.respondWith(new Response("from-sw", ...)). +// "fallback" — observe the event but do not call respondWith, +// letting the request fall back to the network. + +self.addEventListener('fetch', (event) => { + const url = new URL(event.request.url); + const channelId = url.searchParams.get('channel'); + if (!channelId) { + return; + } + const mode = url.searchParams.get('mode') || 'respond'; + + const channel = new BroadcastChannel(channelId); + channel.postMessage({ + type: 'fetch', + url: event.request.url, + destination: event.request.destination, + method: event.request.method, + mode: event.request.mode, + referrer: event.request.referrer, + clientId: event.clientId, + resultingClientId: event.resultingClientId, + }); + + if (mode === 'fallback') { + return; + } + + event.respondWith(new Response('from-sw', { + headers: {'content-type': 'text/plain'}, + })); +}); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-handled-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-handled-worker.js new file mode 100644 index 000000000000..53ee1493743d --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-handled-worker.js @@ -0,0 +1,37 @@ +// This worker reports back the final state of FetchEvent.handled (RESOLVED or +// REJECTED) to the test. + +self.addEventListener('message', function(event) { + self.port = event.data.port; +}); + +self.addEventListener('fetch', function(event) { + try { + event.handled.then(() => { + self.port.postMessage('RESOLVED'); + }, () => { + self.port.postMessage('REJECTED'); + }); + } catch (e) { + self.port.postMessage('FAILED'); + return; + } + + const search = new URL(event.request.url).search; + switch (search) { + case '?respondWith-not-called': + break; + case '?respondWith-not-called-and-event-canceled': + event.preventDefault(); + break; + case '?respondWith-called-and-promise-resolved': + event.respondWith(Promise.resolve(new Response('body'))); + break; + case '?respondWith-called-and-promise-resolved-to-invalid-response': + event.respondWith(Promise.resolve('invalid response')); + break; + case '?respondWith-called-and-promise-rejected': + event.respondWith(Promise.reject(new Error('respondWith rejected'))); + break; + } +}); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-network-error-controllee-iframe.html b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-network-error-controllee-iframe.html new file mode 100644 index 000000000000..f6c1919bbcf6 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-network-error-controllee-iframe.html @@ -0,0 +1,60 @@ + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-network-error-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-network-error-worker.js new file mode 100644 index 000000000000..5bfe3a0bbd9c --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-network-error-worker.js @@ -0,0 +1,49 @@ +// Test that multiple fetch handlers do not confuse the implementation. +self.addEventListener('fetch', function(event) {}); + +self.addEventListener('fetch', function(event) { + var testcase = new URL(event.request.url).search; + switch (testcase) { + case '?reject': + event.respondWith(Promise.reject()); + break; + case '?prevent-default': + event.preventDefault(); + break; + case '?prevent-default-and-respond-with': + event.preventDefault(); + break; + case '?unused-body': + event.respondWith(new Response('body')); + break; + case '?used-body': + var res = new Response('body'); + res.text(); + event.respondWith(res); + break; + case '?unused-fetched-body': + event.respondWith(fetch('other.html').then(function(res){ + return res; + })); + break; + case '?used-fetched-body': + event.respondWith(fetch('other.html').then(function(res){ + res.text(); + return res; + })); + break; + case '?throw-exception': + throw('boom'); + break; + } + }); + +self.addEventListener('fetch', function(event) {}); + +self.addEventListener('fetch', function(event) { + var testcase = new URL(event.request.url).search; + if (testcase == '?prevent-default-and-respond-with') + event.respondWith(new Response('responding!')); + }); + +self.addEventListener('fetch', function(event) {}); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-network-fallback-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-network-fallback-worker.js new file mode 100644 index 000000000000..376bdbed05e1 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-network-fallback-worker.js @@ -0,0 +1,3 @@ +self.addEventListener('fetch', () => { + // Do nothing. +}); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-respond-with-argument-iframe.html b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-respond-with-argument-iframe.html new file mode 100644 index 000000000000..0ebd1ca81537 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-respond-with-argument-iframe.html @@ -0,0 +1,55 @@ + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-respond-with-argument-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-respond-with-argument-worker.js new file mode 100644 index 000000000000..712c4b73c9bc --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-respond-with-argument-worker.js @@ -0,0 +1,14 @@ +self.addEventListener('fetch', function(event) { + var testcase = new URL(event.request.url).search; + switch (testcase) { + case '?response-object': + event.respondWith(new Response('body')); + break; + case '?response-promise-object': + event.respondWith(Promise.resolve(new Response('body'))); + break; + case '?other-value': + event.respondWith(new Object()); + break; + } + }); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-respond-with-body-loaded-in-chunk-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-respond-with-body-loaded-in-chunk-worker.js new file mode 100644 index 000000000000..d3ba8a8df2e7 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-respond-with-body-loaded-in-chunk-worker.js @@ -0,0 +1,7 @@ +'use strict'; + +self.addEventListener('fetch', event => { + if (!event.request.url.match(/body-in-chunk$/)) + return; + event.respondWith(fetch("../../../fetch/api/resources/trickle.py?count=4&delay=50")); +}); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-respond-with-custom-response-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-respond-with-custom-response-worker.js new file mode 100644 index 000000000000..ff24aed1282c --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-respond-with-custom-response-worker.js @@ -0,0 +1,45 @@ +'use strict'; + +addEventListener('fetch', event => { + const url = new URL(event.request.url); + const type = url.searchParams.get('type'); + + if (!type) return; + + if (type === 'string') { + event.respondWith(new Response('PASS')); + } + else if (type === 'blob') { + event.respondWith( + new Response(new Blob(['PASS'])) + ); + } + else if (type === 'buffer-view') { + const encoder = new TextEncoder(); + event.respondWith( + new Response(encoder.encode('PASS')) + ); + } + else if (type === 'buffer') { + const encoder = new TextEncoder(); + event.respondWith( + new Response(encoder.encode('PASS').buffer) + ); + } + else if (type === 'form-data') { + const body = new FormData(); + body.set('result', 'PASS'); + event.respondWith( + new Response(body) + ); + } + else if (type === 'search-params') { + const body = new URLSearchParams(); + body.set('result', 'PASS'); + event.respondWith( + new Response(body, { + headers: { 'Content-Type': 'text/plain' } + }) + ); + } +}); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-respond-with-partial-stream-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-respond-with-partial-stream-worker.js new file mode 100644 index 000000000000..b7307f29f57f --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-respond-with-partial-stream-worker.js @@ -0,0 +1,28 @@ +let waitUntilResolve; + +let bodyController; + +self.addEventListener('message', evt => { + if (evt.data === 'done') { + bodyController.close(); + waitUntilResolve(); + } +}); + +self.addEventListener('fetch', evt => { + if (!evt.request.url.includes('partial-stream.txt')) { + return; + } + + evt.waitUntil(new Promise(resolve => waitUntilResolve = resolve)); + + let body = new ReadableStream({ + start: controller => { + let encoder = new TextEncoder(); + controller.enqueue(encoder.encode('partial-stream-content')); + bodyController = controller; + }, + }); + + evt.respondWith(new Response(body)); +}); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-respond-with-readable-stream-chunk-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-respond-with-readable-stream-chunk-worker.js new file mode 100644 index 000000000000..f954e3a18a5e --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-respond-with-readable-stream-chunk-worker.js @@ -0,0 +1,40 @@ +'use strict'; + +self.addEventListener('fetch', event => { + if (!event.request.url.match(/body-stream$/)) + return; + + var counter = 0; + const encoder = new TextEncoder(); + const stream = new ReadableStream({ pull: controller => { + switch (++counter) { + case 1: + controller.enqueue(encoder.encode('')); + return; + case 2: + controller.enqueue(encoder.encode('chunk #1')); + return; + case 3: + controller.enqueue(encoder.encode(' ')); + return; + case 4: + controller.enqueue(encoder.encode('chunk #2')); + return; + case 5: + controller.enqueue(encoder.encode(' ')); + return; + case 6: + controller.enqueue(encoder.encode('chunk #3')); + return; + case 7: + controller.enqueue(encoder.encode(' ')); + return; + case 8: + controller.enqueue(encoder.encode('chunk #4')); + return; + default: + controller.close(); + } + }}); + event.respondWith(new Response(stream)); +}); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-respond-with-readable-stream-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-respond-with-readable-stream-worker.js new file mode 100644 index 000000000000..056351322c69 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-respond-with-readable-stream-worker.js @@ -0,0 +1,81 @@ +'use strict'; +importScripts("/resources/testharness.js"); + +const map = new Map(); + +self.addEventListener('fetch', event => { + const url = new URL(event.request.url); + if (!url.searchParams.has('stream')) return; + + if (url.searchParams.has('observe-cancel')) { + const id = url.searchParams.get('id'); + if (id === undefined) { + event.respondWith(new Error('error')); + return; + } + event.waitUntil(new Promise(resolve => { + map.set(id, {label: 'pending', resolve}); + })); + + const stream = new ReadableStream({ + pull(c) { + if (url.searchParams.get('enqueue') === 'true') { + url.searchParams.delete('enqueue'); + c.enqueue(new Uint8Array([65])); + } + }, + cancel() { + map.get(id).label = 'cancelled'; + } + }); + event.respondWith(new Response(stream)); + return; + } + + if (url.searchParams.has('query-cancel')) { + const id = url.searchParams.get('id'); + if (id === undefined) { + event.respondWith(new Error('error')); + return; + } + const entry = map.get(id); + if (entry === undefined) { + event.respondWith(new Error('not found')); + return; + } + map.delete(id); + entry.resolve(); + event.respondWith(new Response(entry.label)); + return; + } + + if (url.searchParams.has('use-fetch-stream')) { + event.respondWith(async function() { + const response = await fetch('pass.txt'); + return new Response(response.body); + }()); + return; + } + + const delayEnqueue = url.searchParams.has('delay'); + + const stream = new ReadableStream({ + start(controller) { + const encoder = new TextEncoder(); + + const populate = () => { + controller.enqueue(encoder.encode('PASS')); + controller.close(); + } + + if (delayEnqueue) { + step_timeout(populate, 16); + } + else { + populate(); + } + } + }); + + event.respondWith(new Response(stream)); +}); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-respond-with-response-body-with-invalid-chunk-iframe.html b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-respond-with-response-body-with-invalid-chunk-iframe.html new file mode 100644 index 000000000000..d15454daa5be --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-respond-with-response-body-with-invalid-chunk-iframe.html @@ -0,0 +1,15 @@ + + +respond-with-response-body-with-invalid-chunk + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-respond-with-response-body-with-invalid-chunk-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-respond-with-response-body-with-invalid-chunk-worker.js new file mode 100644 index 000000000000..0254e24f94a2 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-respond-with-response-body-with-invalid-chunk-worker.js @@ -0,0 +1,12 @@ +'use strict'; + +self.addEventListener('fetch', event => { + if (!event.request.url.match(/body-stream-with-invalid-chunk$/)) + return; + const stream = new ReadableStream({start: controller => { + // The argument is intentionally a string, not a Uint8Array. + controller.enqueue('hello'); + }}); + const headers = { 'x-content-type-options': 'nosniff' }; + event.respondWith(new Response(stream, { headers })); + }); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-respond-with-stops-propagation-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-respond-with-stops-propagation-worker.js new file mode 100644 index 000000000000..18da049d69f4 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-respond-with-stops-propagation-worker.js @@ -0,0 +1,15 @@ +var result = null; + +self.addEventListener('message', function(event) { + event.data.port.postMessage(result); + }); + +self.addEventListener('fetch', function(event) { + if (!result) + result = 'PASS'; + event.respondWith(new Response()); + }); + +self.addEventListener('fetch', function(event) { + result = 'FAIL: fetch event propagated'; + }); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-test-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-test-worker.js new file mode 100644 index 000000000000..813f79d1b07b --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-test-worker.js @@ -0,0 +1,224 @@ +function handleHeaders(event) { + const headers = Array.from(event.request.headers); + event.respondWith(new Response(JSON.stringify(headers))); +} + +function handleString(event) { + event.respondWith(new Response('Test string')); +} + +function handleBlob(event) { + event.respondWith(new Response(new Blob(['Test blob']))); +} + +function handleReferrer(event) { + event.respondWith(new Response(new Blob( + ['Referrer: ' + event.request.referrer]))); +} + +function handleReferrerPolicy(event) { + event.respondWith(new Response(new Blob( + ['ReferrerPolicy: ' + event.request.referrerPolicy]))); +} + +function handleReferrerFull(event) { + event.respondWith(new Response(new Blob( + ['Referrer: ' + event.request.referrer + '\n' + + 'ReferrerPolicy: ' + event.request.referrerPolicy]))); +} + +function handleClientId(event) { + var body; + if (event.clientId !== "") { + body = 'Client ID Found: ' + event.clientId; + } else { + body = 'Client ID Not Found'; + } + event.respondWith(new Response(body)); +} + +function handleResultingClientId(event) { + var body; + if (event.resultingClientId !== "") { + body = 'Resulting Client ID Found: ' + event.resultingClientId; + } else { + body = 'Resulting Client ID Not Found'; + } + event.respondWith(new Response(body)); +} + +function handleNullBody(event) { + event.respondWith(new Response()); +} + +function handleFetch(event) { + event.respondWith(fetch('other.html')); +} + +function handleFormPost(event) { + event.respondWith(new Promise(function(resolve) { + event.request.text() + .then(function(result) { + resolve(new Response(event.request.method + ':' + + event.request.headers.get('Content-Type') + ':' + + result)); + }); + })); +} + +function handleMultipleRespondWith(event) { + var logForMultipleRespondWith = ''; + for (var i = 0; i < 3; ++i) { + logForMultipleRespondWith += '(' + i + ')'; + try { + event.respondWith(new Promise(function(resolve) { + setTimeout(function() { + resolve(new Response(logForMultipleRespondWith)); + }, 0); + })); + } catch (e) { + logForMultipleRespondWith += '[' + e.name + ']'; + } + } +} + +var lastResponseForUsedCheck = undefined; + +function handleUsedCheck(event) { + if (!lastResponseForUsedCheck) { + event.respondWith(fetch('other.html').then(function(response) { + lastResponseForUsedCheck = response; + return response; + })); + } else { + event.respondWith(new Response( + 'bodyUsed: ' + lastResponseForUsedCheck.bodyUsed)); + } +} +function handleFragmentCheck(event) { + var body; + if (event.request.url.indexOf('#') === -1) { + body = 'Fragment Not Found'; + } else { + body = 'Fragment Found :' + + event.request.url.substring(event.request.url.indexOf('#')); + } + event.respondWith(new Response(body)); +} +function handleCache(event) { + event.respondWith(new Response(event.request.cache)); +} +function handleEventSource(event) { + if (event.request.mode === 'navigate') { + return; + } + var data = { + mode: event.request.mode, + cache: event.request.cache, + credentials: event.request.credentials + }; + var body = 'data:' + JSON.stringify(data) + '\n\n'; + event.respondWith(new Response(body, { + headers: { 'Content-Type': 'text/event-stream' } + } + )); +} + +function handleIntegrity(event) { + event.respondWith(new Response(event.request.integrity)); +} + +function handleRequestBody(event) { + event.respondWith(event.request.text().then(text => { + return new Response(text); + })); +} + +function handleKeepalive(event) { + event.respondWith(new Response(event.request.keepalive)); +} + +function handleIsReloadNavigation(event) { + const request = event.request; + const body = + `method = ${request.method}, ` + + `isReloadNavigation = ${request.isReloadNavigation}`; + event.respondWith(new Response(body)); +} + +function handleIsHistoryNavigation(event) { + const request = event.request; + const body = + `method = ${request.method}, ` + + `isHistoryNavigation = ${request.isHistoryNavigation}`; + event.respondWith(new Response(body)); +} + +function handleUseAndIgnore(event) { + const request = event.request; + request.text(); + return; +} + +function handleCloneAndIgnore(event) { + const request = event.request; + request.clone().text(); + return; +} + +var handle_status_count = 0; +function handleStatus(event) { + handle_status_count++; + event.respondWith(async function() { + const res = await fetch(event.request); + const text = await res.text(); + return new Response(`${text}. Request was sent ${handle_status_count} times.`, + {"status": new URL(event.request.url).searchParams.get("status")}); + }()); +} + +self.addEventListener('fetch', function(event) { + var url = event.request.url; + var handlers = [ + { pattern: '?headers', fn: handleHeaders }, + { pattern: '?string', fn: handleString }, + { pattern: '?blob', fn: handleBlob }, + { pattern: '?referrerFull', fn: handleReferrerFull }, + { pattern: '?referrerPolicy', fn: handleReferrerPolicy }, + { pattern: '?referrer', fn: handleReferrer }, + { pattern: '?clientId', fn: handleClientId }, + { pattern: '?resultingClientId', fn: handleResultingClientId }, + { pattern: '?ignore', fn: function() {} }, + { pattern: '?null', fn: handleNullBody }, + { pattern: '?fetch', fn: handleFetch }, + { pattern: '?form-post', fn: handleFormPost }, + { pattern: '?multiple-respond-with', fn: handleMultipleRespondWith }, + { pattern: '?used-check', fn: handleUsedCheck }, + { pattern: '?fragment-check', fn: handleFragmentCheck }, + { pattern: '?cache', fn: handleCache }, + { pattern: '?eventsource', fn: handleEventSource }, + { pattern: '?integrity', fn: handleIntegrity }, + { pattern: '?request-body', fn: handleRequestBody }, + { pattern: '?keepalive', fn: handleKeepalive }, + { pattern: '?isReloadNavigation', fn: handleIsReloadNavigation }, + { pattern: '?isHistoryNavigation', fn: handleIsHistoryNavigation }, + { pattern: '?use-and-ignore', fn: handleUseAndIgnore }, + { pattern: '?clone-and-ignore', fn: handleCloneAndIgnore }, + { pattern: '?status', fn: handleStatus }, + ]; + + var handler = null; + for (var i = 0; i < handlers.length; ++i) { + if (url.indexOf(handlers[i].pattern) != -1) { + handler = handlers[i]; + break; + } + } + + if (handler) { + handler.fn(event); + } else { + event.respondWith(new Response(new Blob( + ['Service Worker got an unexpected request: ' + url]))); + } + }); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-within-sw-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-within-sw-worker.js new file mode 100644 index 000000000000..5903bab968dc --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-event-within-sw-worker.js @@ -0,0 +1,48 @@ +skipWaiting(); + +addEventListener('fetch', event => { + const url = new URL(event.request.url); + + if (url.origin != location.origin) return; + + if (url.pathname.endsWith('/sample.txt')) { + event.respondWith(new Response('intercepted')); + return; + } + + if (url.pathname.endsWith('/sample.txt-inner-fetch')) { + event.respondWith(fetch('sample.txt')); + return; + } + + if (url.pathname.endsWith('/sample.txt-inner-cache')) { + event.respondWith( + caches.open('test-inner-cache').then(cache => + cache.add('sample.txt').then(() => cache.match('sample.txt')) + ) + ); + return; + } + + if (url.pathname.endsWith('/show-notification')) { + // Copy the currect search string onto the icon url + const iconURL = new URL('notification_icon.py', location); + iconURL.search = url.search; + + event.respondWith( + registration.showNotification('test', { + icon: iconURL + }).then(() => registration.getNotifications()).then(notifications => { + for (const n of notifications) n.close(); + return new Response('done'); + }) + ); + return; + } + + if (url.pathname.endsWith('/notification_icon.py')) { + new BroadcastChannel('icon-request').postMessage('yay'); + event.respondWith(new Response('done')); + return; + } +}); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-header-visibility-iframe.html b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-header-visibility-iframe.html new file mode 100644 index 000000000000..0d9ab6ff9045 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-header-visibility-iframe.html @@ -0,0 +1,66 @@ + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-mixed-content-iframe-inscope-to-inscope.html b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-mixed-content-iframe-inscope-to-inscope.html new file mode 100644 index 000000000000..64a634e9db7b --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-mixed-content-iframe-inscope-to-inscope.html @@ -0,0 +1,71 @@ + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-mixed-content-iframe-inscope-to-outscope.html b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-mixed-content-iframe-inscope-to-outscope.html new file mode 100644 index 000000000000..be0b5c8f561d --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-mixed-content-iframe-inscope-to-outscope.html @@ -0,0 +1,80 @@ + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-mixed-content-iframe.html b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-mixed-content-iframe.html new file mode 100644 index 000000000000..2831c381b5e4 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-mixed-content-iframe.html @@ -0,0 +1,71 @@ + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-css-base-url-iframe.html b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-css-base-url-iframe.html new file mode 100644 index 000000000000..504e10435642 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-css-base-url-iframe.html @@ -0,0 +1,20 @@ + + +iframe for css base url test + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-css-base-url-style.css b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-css-base-url-style.css new file mode 100644 index 000000000000..f14fcaae7275 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-css-base-url-style.css @@ -0,0 +1 @@ +body { background-image: url("./sample.png");} diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-css-base-url-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-css-base-url-worker.js new file mode 100644 index 000000000000..f3d6a73bdde8 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-css-base-url-worker.js @@ -0,0 +1,45 @@ +let source; +let resolveDone; +let done = new Promise(resolve => resolveDone = resolve); + +// The page messages this worker to ask for the result. Keep the worker alive +// via waitUntil() until the result is sent. +self.addEventListener('message', event => { + source = event.data.port; + source.postMessage('pong'); + event.waitUntil(done); +}); + +self.addEventListener('fetch', event => { + const url = new URL(event.request.url); + + // For the CSS file, respond in a way that may change the response URL, + // depending on |url.search|. + const cssPath = 'request-url-path/fetch-request-css-base-url-style.css'; + if (url.pathname.indexOf(cssPath) != -1) { + // Respond with a different URL, deleting "request-url-path/". + if (url.search == '?fetch') { + event.respondWith(fetch('fetch-request-css-base-url-style.css?fetch')); + } + // Respond with new Response(). + else if (url.search == '?newResponse') { + const styleString = 'body { background-image: url("./sample.png");}'; + const headers = {'content-type': 'text/css'}; + event.respondWith(new Response(styleString, headers)); + } + } + + // The image request indicates what the base URL of the CSS was. Message the + // result back to the test page. + else if (url.pathname.indexOf('sample.png') != -1) { + // For some reason |source| is undefined here when running the test manually + // in Firefox. The test author experimented with both using Client + // (event.source) and MessagePort to try to get the test to pass, but + // failed. + source.postMessage({ + url: event.request.url, + referrer: event.request.referrer + }); + resolveDone(); + } +}); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-css-cross-origin-mime-check-cross.css b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-css-cross-origin-mime-check-cross.css new file mode 100644 index 000000000000..9a7545d07021 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-css-cross-origin-mime-check-cross.css @@ -0,0 +1 @@ +#crossOriginCss { color: blue; } diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-css-cross-origin-mime-check-cross.html b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-css-cross-origin-mime-check-cross.html new file mode 100644 index 000000000000..3211f78084d7 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-css-cross-origin-mime-check-cross.html @@ -0,0 +1 @@ +#crossOriginHtml { color: red; } diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-css-cross-origin-mime-check-iframe.html b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-css-cross-origin-mime-check-iframe.html new file mode 100644 index 000000000000..9a4adedb84d4 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-css-cross-origin-mime-check-iframe.html @@ -0,0 +1,17 @@ + + + + + + +

I should be blue

+

I should be blue

+

I should be blue

+

I should be blue

+

I should be blue

diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-css-cross-origin-mime-check-same.css b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-css-cross-origin-mime-check-same.css new file mode 100644 index 000000000000..55455bd5da58 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-css-cross-origin-mime-check-same.css @@ -0,0 +1 @@ +#sameOriginCss { color: blue; } diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-css-cross-origin-mime-check-same.html b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-css-cross-origin-mime-check-same.html new file mode 100644 index 000000000000..6fad4b9ff048 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-css-cross-origin-mime-check-same.html @@ -0,0 +1 @@ +#sameOriginHtml { color: blue; } diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-css-cross-origin-read-contents.html b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-css-cross-origin-read-contents.html new file mode 100644 index 000000000000..c902366b023a --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-css-cross-origin-read-contents.html @@ -0,0 +1,15 @@ + + +iframe: cross-origin CSS via service worker + + + + + + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-css-cross-origin-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-css-cross-origin-worker.js new file mode 100644 index 000000000000..a71e91216c10 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-css-cross-origin-worker.js @@ -0,0 +1,65 @@ +importScripts('/common/get-host-info.sub.js'); +importScripts('test-helpers.sub.js'); + +const HOST_INFO = get_host_info(); +const REMOTE_ORIGIN = HOST_INFO.HTTPS_REMOTE_ORIGIN; +const BASE_PATH = base_path(); +const CSS_FILE = 'fetch-request-css-cross-origin-mime-check-cross.css'; +const HTML_FILE = 'fetch-request-css-cross-origin-mime-check-cross.html'; + +function add_pipe_header(url_str, header) { + if (url_str.indexOf('?pipe=') == -1) { + url_str += '?pipe='; + } else { + url_str += '|'; + } + url_str += `header${header}`; + return url_str; +} + +self.addEventListener('fetch', function(event) { + const url = new URL(event.request.url); + + const use_mime = + (url.searchParams.get('mime') != 'no'); + const mime_header = '(Content-Type, text/css)'; + + const use_cors = + (url.searchParams.has('cors')); + const cors_header = '(Access-Control-Allow-Origin, *)'; + + const file = url.pathname.substring(url.pathname.lastIndexOf('/') + 1); + + // Respond with a cross-origin CSS resource, using CORS if desired. + if (file == 'cross-origin-css.css') { + let fetch_url = REMOTE_ORIGIN + BASE_PATH + CSS_FILE; + if (use_mime) + fetch_url = add_pipe_header(fetch_url, mime_header); + if (use_cors) + fetch_url = add_pipe_header(fetch_url, cors_header); + const mode = use_cors ? 'cors' : 'no-cors'; + event.respondWith(fetch(fetch_url, {'mode': mode})); + return; + } + + // Respond with a cross-origin CSS resource with an HTML name. This is only + // used in the MIME sniffing test, so MIME is never added. + if (file == 'cross-origin-html.css') { + const fetch_url = REMOTE_ORIGIN + BASE_PATH + HTML_FILE; + event.respondWith(fetch(fetch_url, {mode: 'no-cors'})); + return; + } + + // Respond with synthetic CSS. + if (file == 'synthetic.css') { + let headers = {}; + if (use_mime) { + headers['Content-Type'] = 'text/css'; + } + + event.respondWith(new Response("#synthetic { color: blue; }", {headers})); + return; + } + + // Otherwise, fallback to network. + }); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-fallback-iframe.html b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-fallback-iframe.html new file mode 100644 index 000000000000..d117d0f55ef3 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-fallback-iframe.html @@ -0,0 +1,32 @@ + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-fallback-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-fallback-worker.js new file mode 100644 index 000000000000..3b028b24bde4 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-fallback-worker.js @@ -0,0 +1,13 @@ +var requests = []; + +self.addEventListener('message', function(event) { + event.data.port.postMessage({requests: requests}); + requests = []; + }); + +self.addEventListener('fetch', function(event) { + requests.push({ + url: event.request.url, + mode: event.request.mode + }); + }); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-html-imports-iframe.html b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-html-imports-iframe.html new file mode 100644 index 000000000000..07a084257a8c --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-html-imports-iframe.html @@ -0,0 +1,13 @@ + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-html-imports-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-html-imports-worker.js new file mode 100644 index 000000000000..110727bd52cf --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-html-imports-worker.js @@ -0,0 +1,30 @@ +importScripts('/common/get-host-info.sub.js'); +var host_info = get_host_info(); + +self.addEventListener('fetch', function(event) { + var url = event.request.url; + if (url.indexOf('sample-dir') == -1) { + return; + } + var result = 'mode=' + event.request.mode + + ' credentials=' + event.request.credentials; + if (url == host_info.HTTPS_ORIGIN + '/sample-dir/same.html') { + event.respondWith(new Response( + result + + '' + + '')); + } else if (url == host_info.HTTPS_REMOTE_ORIGIN + '/sample-dir/other.html') { + event.respondWith(new Response( + result + + '' + + '')); + } else { + event.respondWith(new Response(result)); + } + }); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-no-freshness-headers-iframe.html b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-no-freshness-headers-iframe.html new file mode 100644 index 000000000000..e6e9380ba622 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-no-freshness-headers-iframe.html @@ -0,0 +1 @@ + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-no-freshness-headers-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-no-freshness-headers-worker.js new file mode 100644 index 000000000000..2bd59d739225 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-no-freshness-headers-worker.js @@ -0,0 +1,18 @@ +var requests = []; + +self.addEventListener('message', function(event) { + event.data.port.postMessage({requests: requests}); + }); + +self.addEventListener('fetch', function(event) { + var url = event.request.url; + var headers = []; + for (var header of event.request.headers) { + headers.push(header); + } + requests.push({ + url: url, + headers: headers + }); + event.respondWith(fetch(event.request)); + }); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-redirect-iframe.html b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-redirect-iframe.html new file mode 100644 index 000000000000..ffd76bfc4990 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-redirect-iframe.html @@ -0,0 +1,35 @@ + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-resources-iframe.https.html b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-resources-iframe.https.html new file mode 100644 index 000000000000..37fc491134d0 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-resources-iframe.https.html @@ -0,0 +1,126 @@ + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-resources-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-resources-worker.js new file mode 100644 index 000000000000..983cccb8db78 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-resources-worker.js @@ -0,0 +1,26 @@ +const requests = []; +let port = undefined; + +self.onmessage = e => { + const message = e.data; + if ('port' in message) { + port = message.port; + port.postMessage({ready: true}); + } +}; + +self.addEventListener('fetch', e => { + const url = e.request.url; + if (!url.includes('sample?test')) { + return; + } + port.postMessage({ + url: url, + mode: e.request.mode, + redirect: e.request.redirect, + credentials: e.request.credentials, + integrity: e.request.integrity, + destination: e.request.destination + }); + e.respondWith(Promise.reject()); +}); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-xhr-iframe.https.html b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-xhr-iframe.https.html new file mode 100644 index 000000000000..b3ddec1a701b --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-xhr-iframe.https.html @@ -0,0 +1,208 @@ + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-xhr-sync-error-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-xhr-sync-error-worker.js new file mode 100644 index 000000000000..b8d3db99bcc8 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-xhr-sync-error-worker.js @@ -0,0 +1,19 @@ +"use strict"; + +self.onfetch = event => { + if (event.request.url.endsWith("non-existent-stream-1.txt")) { + const rs1 = new ReadableStream(); + event.respondWith(new Response(rs1)); + rs1.cancel(1); + } else if (event.request.url.endsWith("non-existent-stream-2.txt")) { + const rs2 = new ReadableStream({ + start(controller) { controller.error(1) } + }); + event.respondWith(new Response(rs2)); + } else if (event.request.url.endsWith("non-existent-stream-3.txt")) { + const rs3 = new ReadableStream({ + pull(controller) { controller.error(1) } + }); + event.respondWith(new Response(rs3)); + } +}; diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-xhr-sync-iframe.html b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-xhr-sync-iframe.html new file mode 100644 index 000000000000..900762ffc6cc --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-xhr-sync-iframe.html @@ -0,0 +1,13 @@ + +Service Worker: Synchronous XHR is intercepted iframe + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-xhr-sync-on-worker-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-xhr-sync-on-worker-worker.js new file mode 100644 index 000000000000..0d24ffc1f333 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-xhr-sync-on-worker-worker.js @@ -0,0 +1,41 @@ +'use strict'; + +self.onfetch = function(event) { + if (event.request.url.indexOf('non-existent-file.txt') !== -1) { + event.respondWith(new Response('Response from service worker')); + } else if (event.request.url.indexOf('/iframe_page') !== -1) { + event.respondWith(new Response( + '\n' + + '', + { + headers: [['content-type', 'text/html']] + })); + } else if (event.request.url.indexOf('/worker_script') !== -1) { + event.respondWith(new Response( + 'self.onmessage = (msg) => {' + + ' const syncXhr = new XMLHttpRequest();' + + ' syncXhr.open(\'GET\', msg.data.url, false);' + + ' syncXhr.send();' + + ' self.postMessage({' + + ' status: syncXhr.status,' + + ' responseText: syncXhr.responseText' + + ' });' + + '}', + { + headers: [['content-type', 'application/javascript']] + })); + } +}; diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-xhr-sync-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-xhr-sync-worker.js new file mode 100644 index 000000000000..070e572f4004 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-xhr-sync-worker.js @@ -0,0 +1,7 @@ +'use strict'; + +self.onfetch = function(event) { + if (event.request.url.indexOf('non-existent-file.txt') !== -1) { + event.respondWith(new Response('Response from service worker')); + } +}; diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-xhr-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-xhr-worker.js new file mode 100644 index 000000000000..4e428374bc22 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-request-xhr-worker.js @@ -0,0 +1,22 @@ +self.addEventListener('fetch', function(event) { + var url = event.request.url; + if (url.indexOf('sample?test') == -1) { + return; + } + event.respondWith(new Promise(function(resolve) { + var headers = []; + for (var header of event.request.headers) { + headers.push(header); + } + event.request.text() + .then(function(result) { + resolve(new Response(JSON.stringify({ + method: event.request.method, + mode: event.request.mode, + credentials: event.request.credentials, + headers: headers, + body: result + }))); + }); + })); + }); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-response-taint-iframe.html b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-response-taint-iframe.html new file mode 100644 index 000000000000..5f09efe28dff --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-response-taint-iframe.html @@ -0,0 +1,2 @@ + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-response-xhr-iframe.https.html b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-response-xhr-iframe.https.html new file mode 100644 index 000000000000..c26eebee49d8 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-response-xhr-iframe.https.html @@ -0,0 +1,53 @@ + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-response-xhr-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-response-xhr-worker.js new file mode 100644 index 000000000000..0301b12c18a5 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-response-xhr-worker.js @@ -0,0 +1,12 @@ +self.addEventListener('fetch', function(event) { + var url = event.request.url; + if (url.indexOf('sample?test') == -1) { + return; + } + event.respondWith(new Promise(function(resolve) { + var headers = new Headers; + headers.append('foo', 'foo'); + headers.append('foo', 'bar'); + resolve(new Response('hello world', {'headers': headers})); + })); + }); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-response.html b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-response.html new file mode 100644 index 000000000000..6d27cf19e56f --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-response.html @@ -0,0 +1,29 @@ + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-response.js b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-response.js new file mode 100644 index 000000000000..775efc0bbd20 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-response.js @@ -0,0 +1,35 @@ +self.addEventListener('fetch', event => { + const path = event.request.url.match(/\/(?[^\/]+)$/); + switch (path?.groups?.name) { + case 'constructed': + event.respondWith(new Response(new Uint8Array([1, 2, 3]))); + break; + case 'forward': + event.respondWith(fetch('/common/text-plain.txt')); + break; + case 'stream': + event.respondWith((async() => { + const res = await fetch('/common/text-plain.txt'); + const body = await res.body; + const reader = await body.getReader(); + const stream = new ReadableStream({ + async start(controller) { + while (true) { + const {done, value} = await reader.read(); + if (done) + break; + + controller.enqueue(value); + } + controller.close(); + reader.releaseLock(); + } + }); + return new Response(stream); + })()); + break; + default: + event.respondWith(fetch(event.request)); + break; + } +}); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-rewrite-worker-referrer-policy.js b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-rewrite-worker-referrer-policy.js new file mode 100644 index 000000000000..64c99c95d86c --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-rewrite-worker-referrer-policy.js @@ -0,0 +1,4 @@ +// This script is intended to be served with the `Referrer-Policy` header as +// defined in the corresponding `.headers` file. + +importScripts('fetch-rewrite-worker.js'); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-rewrite-worker-referrer-policy.js.headers b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-rewrite-worker-referrer-policy.js.headers new file mode 100644 index 000000000000..5ae4265418e3 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-rewrite-worker-referrer-policy.js.headers @@ -0,0 +1,2 @@ +Content-Type: application/javascript +Referrer-Policy: origin diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-rewrite-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-rewrite-worker.js new file mode 100644 index 000000000000..20a80665270d --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-rewrite-worker.js @@ -0,0 +1,166 @@ +// By default, this worker responds to fetch events with +// respondWith(fetch(request)). Additionally, if the request has a &url +// parameter, it fetches the provided URL instead. Because it forwards fetch +// events to this other URL, it is called the "fetch rewrite" worker. +// +// The worker also looks for other params on the request to do more custom +// behavior, like falling back to network or throwing an error. + +function get_query_params(url) { + var search = (new URL(url)).search; + if (!search) { + return {}; + } + var ret = {}; + var params = search.substring(1).split('&'); + params.forEach(function(param) { + var element = param.split('='); + ret[decodeURIComponent(element[0])] = decodeURIComponent(element[1]); + }); + return ret; +} + +function get_request_init(base, params) { + var init = {}; + init['method'] = params['method'] || base['method']; + init['mode'] = params['mode'] || base['mode']; + if (init['mode'] == 'navigate') { + init['mode'] = 'same-origin'; + } + init['credentials'] = params['credentials'] || base['credentials']; + init['redirect'] = params['redirect-mode'] || base['redirect']; + return init; +} + +self.addEventListener('fetch', function(event) { + var params = get_query_params(event.request.url); + var init = get_request_init(event.request, params); + var url = params['url']; + if (params['ignore']) { + return; + } + if (params['throw']) { + throw new Error('boom'); + } + if (params['reject']) { + event.respondWith(new Promise(function(resolve, reject) { + reject(); + })); + return; + } + if (params['resolve-null']) { + event.respondWith(new Promise(function(resolve) { + resolve(null); + })); + return; + } + if (params['generate-png']) { + var binary = atob( + 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAA' + + 'RnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAAhSURBVDhPY3wro/Kf' + + 'gQLABKXJBqMGjBoAAqMGDLwBDAwAEsoCTFWunmQAAAAASUVORK5CYII='); + var array = new Uint8Array(binary.length); + for(var i = 0; i < binary.length; i++) { + array[i] = binary.charCodeAt(i); + }; + event.respondWith(new Response(new Blob([array], {type: 'image/png'}))); + return; + } + if (params['check-ua-header']) { + var ua = event.request.headers.get('User-Agent'); + if (ua) { + // We have a user agent! + event.respondWith(new Response(new Blob([ua]))); + } else { + // We don't have a user-agent! + event.respondWith(new Response(new Blob(["NO_UA"]))); + } + return; + } + if (params['check-accept-header']) { + var accept = event.request.headers.get('Accept'); + if (accept) { + event.respondWith(new Response(accept)); + } else { + event.respondWith(new Response('NO_ACCEPT')); + } + return; + } + event.respondWith(new Promise(function(resolve, reject) { + var request = event.request; + if (url) { + request = new Request(url, init); + } else if (params['change-request']) { + request = new Request(request, init); + } + const response_promise = params['navpreload'] ? event.preloadResponse + : fetch(request); + response_promise.then(function(response) { + var expectedType = params['expected_type']; + if (expectedType && response.type !== expectedType) { + // Resolve a JSON object with a failure instead of rejecting + // in order to distinguish this from a NetworkError, which + // may be expected even if the type is correct. + resolve(new Response(JSON.stringify({ + result: 'failure', + detail: 'got ' + response.type + ' Response.type instead of ' + + expectedType + }))); + } + + var expectedRedirected = params['expected_redirected']; + if (typeof expectedRedirected !== 'undefined') { + var expected_redirected = (expectedRedirected === 'true'); + if(response.redirected !== expected_redirected) { + // This is simply determining how to pass an error to the outer + // test case(fetch-request-redirect.https.html). + var execptedResolves = params['expected_resolves']; + if (execptedResolves === 'true') { + // Reject a JSON object with a failure since promise is expected + // to be resolved. + reject(new Response(JSON.stringify({ + result: 'failure', + detail: 'got '+ response.redirected + + ' Response.redirected instead of ' + + expectedRedirected + }))); + } else { + // Resolve a JSON object with a failure since promise is + // expected to be rejected. + resolve(new Response(JSON.stringify({ + result: 'failure', + detail: 'got '+ response.redirected + + ' Response.redirected instead of ' + + expectedRedirected + }))); + } + } + } + + if (params['clone']) { + response = response.clone(); + } + + // |cache| means to bounce responses through Cache Storage and back. + if (params['cache']) { + var cacheName = "cached-fetches-" + performance.now() + "-" + + event.request.url; + var cache; + var cachedResponse; + return self.caches.open(cacheName).then(function(opened) { + cache = opened; + return cache.put(request, response); + }).then(function() { + return cache.match(request); + }).then(function(cached) { + cachedResponse = cached; + return self.caches.delete(cacheName); + }).then(function() { + resolve(cachedResponse); + }); + } else { + resolve(response); + } + }, reject) + })); + }); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-rewrite-worker.js.headers b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-rewrite-worker.js.headers new file mode 100644 index 000000000000..123053b38c66 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-rewrite-worker.js.headers @@ -0,0 +1,2 @@ +Content-Type: text/javascript +Service-Worker-Allowed: / diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-variants-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-variants-worker.js new file mode 100644 index 000000000000..b950b9a18a6a --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-variants-worker.js @@ -0,0 +1,35 @@ +importScripts('/common/get-host-info.sub.js'); +importScripts('test-helpers.sub.js'); +importScripts('/resources/testharness.js'); + +const storedResponse = new Response(new Blob(['a simple text file'])) +const absolultePath = `${base_path()}/simple.txt` + +self.addEventListener('fetch', event => { + const search = new URLSearchParams(new URL(event.request.url).search.substr(1)) + const variant = search.get('variant') + const delay = search.get('delay') + if (!variant) + return + + switch (variant) { + case 'forward': + event.respondWith(fetch(event.request.url)) + break + case 'redirect': + event.respondWith(fetch(`/xhr/resources/redirect.py?location=${base_path()}/simple.txt`)) + break + case 'delay-before-fetch': + event.respondWith( + new Promise(resolve => { + step_timeout(() => fetch(event.request.url).then(resolve), delay) + })) + break + case 'delay-after-fetch': + event.respondWith(new Promise(resolve => { + fetch(event.request.url) + .then(response => step_timeout(() => resolve(response), delay)) + })) + break + } +}); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-waits-for-activate-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-waits-for-activate-worker.js new file mode 100644 index 000000000000..92a96ff88fb9 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-waits-for-activate-worker.js @@ -0,0 +1,31 @@ +var activatePromiseResolve; + +addEventListener('activate', function(evt) { + evt.waitUntil(new Promise(function(resolve) { + activatePromiseResolve = resolve; + })); +}); + +addEventListener('message', async function(evt) { + switch (evt.data) { + case 'CLAIM': + evt.waitUntil(new Promise(async resolve => { + await clients.claim(); + evt.source.postMessage('CLAIMED'); + resolve(); + })); + break; + case 'ACTIVATE': + if (typeof activatePromiseResolve !== 'function') { + throw new Error('Not activating!'); + } + activatePromiseResolve(); + break; + default: + throw new Error('Unknown message!'); + } +}); + +addEventListener('fetch', function(evt) { + evt.respondWith(new Response('Hello world')); +}); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/fetch-with-body-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-with-body-worker.js new file mode 100644 index 000000000000..bef899c1b000 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/fetch-with-body-worker.js @@ -0,0 +1,4 @@ +self.addEventListener("fetch", (event) => { + event.request.body; + event.respondWith(fetch(event.request)); +}); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/form-poster.html b/test/fixtures/wpt/service-workers/service-worker/resources/form-poster.html new file mode 100644 index 000000000000..cd11a30a5e85 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/form-poster.html @@ -0,0 +1,13 @@ + + + +
+ diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/frame-for-getregistrations.html b/test/fixtures/wpt/service-workers/service-worker/resources/frame-for-getregistrations.html new file mode 100644 index 000000000000..7fc35f18914c --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/frame-for-getregistrations.html @@ -0,0 +1,19 @@ + +Service Worker: frame for getRegistrations() + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/get-resultingClientId-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/get-resultingClientId-worker.js new file mode 100644 index 000000000000..f0e6c7becab6 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/get-resultingClientId-worker.js @@ -0,0 +1,107 @@ +// This worker expects a fetch event for a navigation and messages back the +// result of clients.get(event.resultingClientId). + +// Resolves when the test finishes. +let testFinishPromise; +let resolveTestFinishPromise; +let rejectTestFinishPromise; + +// Resolves to clients.get(event.resultingClientId) from the fetch event. +let getPromise; +let resolveGetPromise; +let rejectGetPromise; + +let resultingClientId; + +function startTest() { + testFinishPromise = new Promise((resolve, reject) => { + resolveTestFinishPromise = resolve; + rejectTestFinishPromise = reject; + }); + + getPromise = new Promise((resolve, reject) => { + resolveGetPromise = resolve; + rejectGetPromise = reject; + }); +} + +async function describeGetPromiseResult(promise) { + const result = {}; + + await promise.then( + (client) => { + result.promiseState = 'fulfilled'; + if (client === undefined) { + result.promiseValue = 'undefinedValue'; + } else if (client instanceof Client) { + result.promiseValue = 'client'; + result.client = { + id: client.id, + url: client.url + }; + } else { + result.promiseValue = 'unknown'; + } + }, + (error) => { + result.promiseState = 'rejected'; + }); + + return result; +} + +async function handleGetResultingClient(event) { + // Note that this message can arrive before |resultingClientId| is populated. + const result = await describeGetPromiseResult(getPromise); + // |resultingClientId| must be populated by now. + result.queriedId = resultingClientId; + event.source.postMessage(result); +}; + +async function handleGetClient(event) { + const id = event.data.id; + const result = await describeGetPromiseResult(self.clients.get(id)); + result.queriedId = id; + event.source.postMessage(result); +}; + +self.addEventListener('message', (event) => { + if (event.data.command == 'startTest') { + startTest(); + event.waitUntil(testFinishPromise); + event.source.postMessage('ok'); + return; + } + + if (event.data.command == 'finishTest') { + resolveTestFinishPromise(); + event.source.postMessage('ok'); + return; + } + + if (event.data.command == 'getResultingClient') { + event.waitUntil(handleGetResultingClient(event)); + return; + } + + if (event.data.command == 'getClient') { + event.waitUntil(handleGetClient(event)); + return; + } +}); + +async function handleFetch(event) { + try { + resultingClientId = event.resultingClientId; + const client = await self.clients.get(resultingClientId); + resolveGetPromise(client); + } catch (error) { + rejectGetPromise(error); + } +} + +self.addEventListener('fetch', (event) => { + if (event.request.mode != 'navigate') + return; + event.waitUntil(handleFetch(event)); +}); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/http-to-https-redirect-and-register-iframe.html b/test/fixtures/wpt/service-workers/service-worker/resources/http-to-https-redirect-and-register-iframe.html new file mode 100644 index 000000000000..bcab35364dff --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/http-to-https-redirect-and-register-iframe.html @@ -0,0 +1,25 @@ + +register, unregister, and report result to opener + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/iframe-with-fetch-variants.html b/test/fixtures/wpt/service-workers/service-worker/resources/iframe-with-fetch-variants.html new file mode 100644 index 000000000000..3a61d7bb890b --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/iframe-with-fetch-variants.html @@ -0,0 +1,14 @@ + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/iframe-with-image.html b/test/fixtures/wpt/service-workers/service-worker/resources/iframe-with-image.html new file mode 100644 index 000000000000..ce78840cb283 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/iframe-with-image.html @@ -0,0 +1,2 @@ + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/immutable-prototype-serviceworker.js b/test/fixtures/wpt/service-workers/service-worker/resources/immutable-prototype-serviceworker.js new file mode 100644 index 000000000000..d8a94ad46bef --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/immutable-prototype-serviceworker.js @@ -0,0 +1,19 @@ +function prototypeChain(global) { + let result = []; + while (global !== null) { + let thrown = false; + let next = Object.getPrototypeOf(global); + try { + Object.setPrototypeOf(global, {}); + result.push('mutable'); + } catch (e) { + result.push('immutable'); + } + global = next; + } + return result; +} + +self.onmessage = function(e) { + e.data.postMessage(prototypeChain(self)); +}; diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/import-echo-cookie-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/import-echo-cookie-worker.js new file mode 100644 index 000000000000..f5eac9508c9a --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/import-echo-cookie-worker.js @@ -0,0 +1 @@ +importScripts(`echo-cookie-worker.py${location.search}`); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/import-relative.xsl b/test/fixtures/wpt/service-workers/service-worker/resources/import-relative.xsl new file mode 100644 index 000000000000..063a62d03143 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/import-relative.xsl @@ -0,0 +1,5 @@ + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/import-scripts-404-after-update-plus-update-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/import-scripts-404-after-update-plus-update-worker.js new file mode 100644 index 000000000000..e9899d8e7274 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/import-scripts-404-after-update-plus-update-worker.js @@ -0,0 +1,8 @@ +// This worker imports a script that returns 200 on the first request and 404 +// on the second request, and a script that is updated every time when +// requesting it. +const params = new URLSearchParams(location.search); +const key = params.get('Key'); +const additional_key = params.get('AdditionalKey'); +importScripts(`update-worker.py?Key=${key}&Mode=not_found`, + `update-worker.py?Key=${additional_key}&Mode=normal`); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/import-scripts-404-after-update.js b/test/fixtures/wpt/service-workers/service-worker/resources/import-scripts-404-after-update.js new file mode 100644 index 000000000000..b569346035ac --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/import-scripts-404-after-update.js @@ -0,0 +1,6 @@ +// This worker imports a script that returns 200 on the first request and 404 +// on the second request. The resulting body also changes each time it is +// requested. +const params = new URLSearchParams(location.search); +const key = params.get('Key'); +importScripts(`update-worker.py?Key=${key}&Mode=not_found`); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/import-scripts-404.js b/test/fixtures/wpt/service-workers/service-worker/resources/import-scripts-404.js new file mode 100644 index 000000000000..19c7a4b8e561 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/import-scripts-404.js @@ -0,0 +1 @@ +importScripts('404.py'); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/import-scripts-cross-origin-worker.sub.js b/test/fixtures/wpt/service-workers/service-worker/resources/import-scripts-cross-origin-worker.sub.js new file mode 100644 index 000000000000..b432854db8bc --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/import-scripts-cross-origin-worker.sub.js @@ -0,0 +1 @@ +importScripts('https://{{domains[www1]}}:{{ports[https][0]}}/service-workers/service-worker/resources/import-scripts-version.py'); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/import-scripts-data-url-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/import-scripts-data-url-worker.js new file mode 100644 index 000000000000..fdabdafc6304 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/import-scripts-data-url-worker.js @@ -0,0 +1 @@ +importScripts('data:text/javascript,'); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/import-scripts-diff-resource-map-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/import-scripts-diff-resource-map-worker.js new file mode 100644 index 000000000000..0fdcb0fcf80a --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/import-scripts-diff-resource-map-worker.js @@ -0,0 +1,10 @@ +importScripts('/resources/testharness.js'); + +let echo1 = null; +let echo2 = null; +let arg1 = 'import-scripts-get.py?output=echo1&msg=test1'; +let arg2 = 'import-scripts-get.py?output=echo2&msg=test2'; + +importScripts(arg1, arg2); +assert_equals(echo1, 'test1'); +assert_equals(echo2, 'test2'); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/import-scripts-mime-types-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/import-scripts-mime-types-worker.js new file mode 100644 index 000000000000..7658eeace695 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/import-scripts-mime-types-worker.js @@ -0,0 +1,54 @@ +const badMimeTypes = [ + null, // no MIME type + 'text/plain', + // JSON is only valid for JSON module imports, never for classic + // importScripts(), even when the body is valid JavaScript. + 'application/json', + 'text/json', + 'application/manifest+json', +]; + +const validMimeTypes = [ + 'application/ecmascript', + 'application/javascript', + 'application/x-ecmascript', + 'application/x-javascript', + 'text/ecmascript', + 'text/javascript', + 'text/javascript1.0', + 'text/javascript1.1', + 'text/javascript1.2', + 'text/javascript1.3', + 'text/javascript1.4', + 'text/javascript1.5', + 'text/jscript', + 'text/livescript', + 'text/x-ecmascript', + 'text/x-javascript', +]; + +function importScriptsWithMimeType(mimeType) { + importScripts(`./mime-type-worker.py${mimeType ? '?mime=' + mimeType : ''}`); +} + +importScripts('/resources/testharness.js'); + +for (const mimeType of badMimeTypes) { + test(() => { + assert_throws_dom( + 'NetworkError', + () => { importScriptsWithMimeType(mimeType); }, + `importScripts with ${mimeType ? 'bad' : 'no'} MIME type ${mimeType || ''} throws NetworkError`, + ); + }, `Importing script with ${mimeType ? 'bad' : 'no'} MIME type ${mimeType || ''}`); +} + +for (const mimeType of validMimeTypes) { + test(() => { + try { + importScriptsWithMimeType(mimeType); + } catch { + assert_unreached(`importScripts with MIME type ${mimeType} should not throw`); + } + }, `Importing script with valid JavaScript MIME type ${mimeType}`); +} diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/import-scripts-redirect-import.js b/test/fixtures/wpt/service-workers/service-worker/resources/import-scripts-redirect-import.js new file mode 100644 index 000000000000..56c04f094602 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/import-scripts-redirect-import.js @@ -0,0 +1 @@ +// empty script diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/import-scripts-redirect-on-second-time-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/import-scripts-redirect-on-second-time-worker.js new file mode 100644 index 000000000000..f612ab8e6aa4 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/import-scripts-redirect-on-second-time-worker.js @@ -0,0 +1,7 @@ +// This worker imports a script that returns 200 on the first request and a +// redirect on the second request. The resulting body also changes each time it +// is requested. +const params = new URLSearchParams(location.search); +const key = params.get('Key'); +importScripts(`update-worker.py?Key=${key}&Mode=redirect&` + + `Redirect=update-worker.py?Key=${key}%26Mode=normal`); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/import-scripts-redirect-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/import-scripts-redirect-worker.js new file mode 100644 index 000000000000..d02a45349c24 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/import-scripts-redirect-worker.js @@ -0,0 +1 @@ +importScripts('redirect.py?Redirect=import-scripts-version.py'); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/import-scripts-resource-map-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/import-scripts-resource-map-worker.js new file mode 100644 index 000000000000..b3b9bc46a024 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/import-scripts-resource-map-worker.js @@ -0,0 +1,15 @@ +importScripts('/resources/testharness.js'); + +let version = null; +importScripts('import-scripts-version.py'); +// Once imported, the stored script should be loaded for subsequent importScripts. +const expected_version = version; + +version = null; +importScripts('import-scripts-version.py'); +assert_equals(expected_version, version, 'second import'); + +version = null; +importScripts('import-scripts-version.py', 'import-scripts-version.py', + 'import-scripts-version.py'); +assert_equals(expected_version, version, 'multiple imports'); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/import-scripts-updated-flag-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/import-scripts-updated-flag-worker.js new file mode 100644 index 000000000000..e01664662ef1 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/import-scripts-updated-flag-worker.js @@ -0,0 +1,31 @@ +importScripts('/resources/testharness.js'); + +let echo_output = null; + +// Tests importing a script that sets |echo_output| to the query string. +function test_import(str) { + echo_output = null; + importScripts('import-scripts-echo.py?msg=' + str); + assert_equals(echo_output, str); +} + +test_import('root'); +test_import('root-and-message'); + +self.addEventListener('install', () => { + test_import('install'); + test_import('install-and-message'); + }); + +self.addEventListener('message', e => { + var error = null; + echo_output = null; + + try { + importScripts('import-scripts-echo.py?msg=' + e.data); + } catch (e) { + error = e && e.name; + } + + e.source.postMessage({ error: error, value: echo_output }); + }); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/imported-classic-script.js b/test/fixtures/wpt/service-workers/service-worker/resources/imported-classic-script.js new file mode 100644 index 000000000000..5fc520405135 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/imported-classic-script.js @@ -0,0 +1 @@ +const imported = 'A classic script.'; diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/imported-module-script.js b/test/fixtures/wpt/service-workers/service-worker/resources/imported-module-script.js new file mode 100644 index 000000000000..56d196df040f --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/imported-module-script.js @@ -0,0 +1 @@ +export const imported = 'A module script.'; diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/imported-sw.js b/test/fixtures/wpt/service-workers/service-worker/resources/imported-sw.js new file mode 100644 index 000000000000..04a894d77f87 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/imported-sw.js @@ -0,0 +1,13 @@ +'use strict'; + +import {routerRules} from './router-rules.js'; + +const params = new URLSearchParams(location.search); +const key = params.get('imported-sw-router-key'); + +if (key) { + self.addEventListener('install', async e => { + await e.addRoutes(routerRules[key]); + self.skipWaiting(); + }); +} diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/indexeddb-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/indexeddb-worker.js new file mode 100644 index 000000000000..9add47683884 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/indexeddb-worker.js @@ -0,0 +1,57 @@ +self.addEventListener('message', function(e) { + var message = e.data; + if (message.action === 'create') { + e.waitUntil(deleteDB() + .then(doIndexedDBTest) + .then(function() { + message.port.postMessage({ type: 'created' }); + }) + .catch(function(reason) { + message.port.postMessage({ type: 'error', value: reason }); + })); + } else if (message.action === 'cleanup') { + e.waitUntil(deleteDB() + .then(function() { + message.port.postMessage({ type: 'done' }); + }) + .catch(function(reason) { + message.port.postMessage({ type: 'error', value: reason }); + })); + } + }); + +function deleteDB() { + return new Promise(function(resolve, reject) { + var delete_request = indexedDB.deleteDatabase('db'); + + delete_request.onsuccess = resolve; + delete_request.onerror = reject; + }); +} + +function doIndexedDBTest(port) { + return new Promise(function(resolve, reject) { + var open_request = indexedDB.open('db'); + + open_request.onerror = reject; + open_request.onupgradeneeded = function() { + var db = open_request.result; + db.createObjectStore('store'); + }; + open_request.onsuccess = function() { + var db = open_request.result; + var tx = db.transaction('store', 'readwrite'); + var store = tx.objectStore('store'); + store.put('value', 'key'); + + tx.onerror = function() { + db.close(); + reject(tx.error); + }; + tx.oncomplete = function() { + db.close(); + resolve(); + }; + }; + }); +} diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/install-event-type-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/install-event-type-worker.js new file mode 100644 index 000000000000..1c94ae21ea9d --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/install-event-type-worker.js @@ -0,0 +1,9 @@ +importScripts('worker-testharness.js'); + +self.oninstall = function(event) { + assert_true(event instanceof ExtendableEvent, 'instance of ExtendableEvent'); + assert_true(event instanceof InstallEvent, 'instance of InstallEvent'); + assert_equals(event.type, 'install', '`type` property value'); + assert_false(event.cancelable, '`cancelable` property value'); + assert_false(event.bubbles, '`bubbles` property value'); +}; diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/install-worker.html b/test/fixtures/wpt/service-workers/service-worker/resources/install-worker.html new file mode 100644 index 000000000000..ed20cd4dca6a --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/install-worker.html @@ -0,0 +1,22 @@ + + + +

Loading...

+ + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/intercepted-referrer-sw.js b/test/fixtures/wpt/service-workers/service-worker/resources/intercepted-referrer-sw.js new file mode 100644 index 000000000000..f0246c8dbe46 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/intercepted-referrer-sw.js @@ -0,0 +1,35 @@ +self.addEventListener('install', event => { + // Activate immediately to simplify the test. + event.waitUntil(self.skipWaiting()); +}); + +self.addEventListener('activate', event => { + // Make sure the very next navigation is controlled by this SW. + event.waitUntil(self.clients.claim()); +}); + +self.addEventListener('fetch', event => { + // Only handle top-level navigations within our scope. + if (event.request.mode === 'navigate') { + const html = ` + + SW Intercepted Page + +

SW-synthesized page

+

This page was served by a Service Worker via respondWith().

`; + + event.respondWith(new Response(html, { + headers: { 'Content-Type': 'text/html; charset=utf-8' } + })); + } + // Otherwise, fall through to network. +}); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/interface-requirements-worker.sub.js b/test/fixtures/wpt/service-workers/service-worker/resources/interface-requirements-worker.sub.js new file mode 100644 index 000000000000..a3f239b65481 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/interface-requirements-worker.sub.js @@ -0,0 +1,59 @@ +'use strict'; + +// This file checks additional interface requirements, on top of the basic IDL +// that is validated in service-workers/idlharness.any.js + +importScripts('/resources/testharness.js'); + +test(function() { + var req = new Request('http://{{host}}/', + {method: 'POST', + headers: [['Content-Type', 'Text/Html']]}); + assert_equals( + new ExtendableEvent('ExtendableEvent').type, + 'ExtendableEvent', 'Type of ExtendableEvent should be ExtendableEvent'); + assert_throws_js(TypeError, function() { + new FetchEvent('FetchEvent'); + }, 'FetchEvent constructor with one argument throws'); + assert_throws_js(TypeError, function() { + new FetchEvent('FetchEvent', {}); + }, 'FetchEvent constructor with empty init dict throws'); + assert_throws_js(TypeError, function() { + new FetchEvent('FetchEvent', {request: null}); + }, 'FetchEvent constructor with null request member throws'); + assert_equals( + new FetchEvent('FetchEvent', {request: req}).type, + 'FetchEvent', 'Type of FetchEvent should be FetchEvent'); + assert_equals( + new FetchEvent('FetchEvent', {request: req}).cancelable, + false, 'Default FetchEvent.cancelable should be false'); + assert_equals( + new FetchEvent('FetchEvent', {request: req}).bubbles, + false, 'Default FetchEvent.bubbles should be false'); + assert_equals( + new FetchEvent('FetchEvent', {request: req}).clientId, + '', 'Default FetchEvent.clientId should be the empty string'); + assert_equals( + new FetchEvent('FetchEvent', {request: req, cancelable: false}).cancelable, + false, 'FetchEvent.cancelable should be false'); + assert_equals( + new FetchEvent('FetchEvent', {request: req, clientId : 'test-client-id'}).clientId, 'test-client-id', + 'FetchEvent.clientId with option {clientId : "test-client-id"} should be "test-client-id"'); + assert_equals( + new FetchEvent('FetchEvent', {request : req}).request.url, + 'http://{{host}}/', + 'FetchEvent.request.url should return the value it was initialized to'); + assert_equals( + new FetchEvent('FetchEvent', {request : req}).isReload, + undefined, + 'FetchEvent.isReload should not exist'); + + }, 'Event constructors'); + +test(() => { + assert_false('XMLHttpRequest' in self); + }, 'xhr is not exposed'); + +test(() => { + assert_false('createObjectURL' in self.URL); + }, 'URL.createObjectURL is not exposed') diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/invalid-blobtype-iframe.https.html b/test/fixtures/wpt/service-workers/service-worker/resources/invalid-blobtype-iframe.https.html new file mode 100644 index 000000000000..04a9cb515e09 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/invalid-blobtype-iframe.https.html @@ -0,0 +1,28 @@ + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/invalid-blobtype-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/invalid-blobtype-worker.js new file mode 100644 index 000000000000..865dc30d4282 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/invalid-blobtype-worker.js @@ -0,0 +1,10 @@ +self.addEventListener('fetch', function(event) { + var url = event.request.url; + if (url.indexOf('sample?test') == -1) { + return; + } + event.respondWith(new Promise(function(resolve) { + // null byte in blob type + resolve(new Response(new Blob([],{type: 'a\0b'}))); + })); + }); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/invalid-header-iframe.https.html b/test/fixtures/wpt/service-workers/service-worker/resources/invalid-header-iframe.https.html new file mode 100644 index 000000000000..8f0e6baca175 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/invalid-header-iframe.https.html @@ -0,0 +1,25 @@ + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/invalid-header-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/invalid-header-worker.js new file mode 100644 index 000000000000..850874b8116d --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/invalid-header-worker.js @@ -0,0 +1,12 @@ +self.addEventListener('fetch', function(event) { + var url = event.request.url; + if (url.indexOf('sample?test') == -1) { + return; + } + event.respondWith(new Promise(function(resolve) { + var headers = new Headers; + headers.append('foo', 'foo'); + headers.append('foo', 'b\0r'); // header value with a null byte + resolve(new Response('hello world', {'headers': headers})); + })); + }); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/iso-latin1-header-iframe.html b/test/fixtures/wpt/service-workers/service-worker/resources/iso-latin1-header-iframe.html new file mode 100644 index 000000000000..cf2fa8d14f7c --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/iso-latin1-header-iframe.html @@ -0,0 +1,23 @@ + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/iso-latin1-header-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/iso-latin1-header-worker.js new file mode 100644 index 000000000000..d9ecca277b3f --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/iso-latin1-header-worker.js @@ -0,0 +1,12 @@ +self.addEventListener('fetch', function(event) { + var url = event.request.url; + if (url.indexOf('sample?test') == -1) { + return; + } + + event.respondWith(new Promise(function(resolve) { + var headers = new Headers; + headers.append('TEST', 'ßÀ¿'); // header value holds the Latin1 (ISO8859-1) string. + resolve(new Response('hello world', {'headers': headers})); + })); + }); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/load_worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/load_worker.js new file mode 100644 index 000000000000..18c673bebcab --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/load_worker.js @@ -0,0 +1,29 @@ +function run_test(data, sender) { + if (data === 'xhr') { + const xhr = new XMLHttpRequest(); + xhr.open('GET', 'synthesized-response.txt', true); + xhr.responseType = 'text'; + xhr.send(); + xhr.onload = evt => sender.postMessage(xhr.responseText); + xhr.onerror = () => sender.postMessage('XHR failed!'); + } else if (data === 'fetch') { + fetch('synthesized-response.txt') + .then(response => response.text()) + .then(data => sender.postMessage(data)) + .catch(error => sender.postMessage('Fetch failed!')); + } else if (data === 'importScripts') { + importScripts('synthesized-response.js'); + // |message| is provided by 'synthesized-response.js'; + sender.postMessage(message); + } else { + sender.postMessage('Unexpected message! ' + data); + } +} + +// Entry point for dedicated workers. +self.onmessage = evt => run_test(evt.data, self); + +// Entry point for shared workers. +self.onconnect = evt => { + evt.ports[0].onmessage = e => run_test(e.data, evt.ports[0]); +}; diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/loaded.html b/test/fixtures/wpt/service-workers/service-worker/resources/loaded.html new file mode 100644 index 000000000000..0cabce69f8e8 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/loaded.html @@ -0,0 +1,9 @@ + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/local-url-inherit-controller-frame.html b/test/fixtures/wpt/service-workers/service-worker/resources/local-url-inherit-controller-frame.html new file mode 100644 index 000000000000..e7214827a4cf --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/local-url-inherit-controller-frame.html @@ -0,0 +1,189 @@ + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/local-url-inherit-controller-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/local-url-inherit-controller-worker.js new file mode 100644 index 000000000000..4b7aad0f58a8 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/local-url-inherit-controller-worker.js @@ -0,0 +1,5 @@ +addEventListener('fetch', evt => { + if (evt.request.url.includes('sample')) { + evt.respondWith(new Response('intercepted')); + } +}); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/location-setter.html b/test/fixtures/wpt/service-workers/service-worker/resources/location-setter.html new file mode 100644 index 000000000000..f0ced06ec26d --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/location-setter.html @@ -0,0 +1,10 @@ + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/malformed-http-response.asis b/test/fixtures/wpt/service-workers/service-worker/resources/malformed-http-response.asis new file mode 100644 index 000000000000..bc3c68d46d53 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/malformed-http-response.asis @@ -0,0 +1 @@ +HAHAHA THIS IS NOT HTTP AND THE BROWSER SHOULD CONSIDER IT A NETWORK ERROR diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/message-vs-microtask.html b/test/fixtures/wpt/service-workers/service-worker/resources/message-vs-microtask.html new file mode 100644 index 000000000000..2c45c59a475a --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/message-vs-microtask.html @@ -0,0 +1,18 @@ + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/mime-sniffing-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/mime-sniffing-worker.js new file mode 100644 index 000000000000..5c34a7a49e87 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/mime-sniffing-worker.js @@ -0,0 +1,9 @@ +self.addEventListener('fetch', function(event) { + // Use an empty content-type value to force mime-sniffing. Note, this + // must be passed to the constructor since the mime-type of the Response + // is fixed and cannot be later changed. + var res = new Response('\n

test

', { + headers: { 'content-type': '' } + }); + event.respondWith(res); + }); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/missing.asis b/test/fixtures/wpt/service-workers/service-worker/resources/missing.asis new file mode 100644 index 000000000000..4846fe01d61a --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/missing.asis @@ -0,0 +1,4 @@ +HTTP/1.1 404 Not Found +Content-Type: text/javascript + +alert("hello"); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/module-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/module-worker.js new file mode 100644 index 000000000000..385fe7101503 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/module-worker.js @@ -0,0 +1 @@ +import * as module from './imported-module-script.js'; diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/multipart-image-iframe.html b/test/fixtures/wpt/service-workers/service-worker/resources/multipart-image-iframe.html new file mode 100644 index 000000000000..c59b95594ff5 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/multipart-image-iframe.html @@ -0,0 +1,19 @@ + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/multipart-image-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/multipart-image-worker.js new file mode 100644 index 000000000000..a38fe54d34fc --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/multipart-image-worker.js @@ -0,0 +1,21 @@ +importScripts('/common/get-host-info.sub.js'); +importScripts('test-helpers.sub.js'); + +const host_info = get_host_info(); + +const multipart_image_path = base_path() + 'multipart-image.py'; +const sameorigin_url = host_info['HTTPS_ORIGIN'] + multipart_image_path; +const cross_origin_url = host_info['HTTPS_REMOTE_ORIGIN'] + multipart_image_path; + +self.addEventListener('fetch', event => { + const url = event.request.url; + if (url.indexOf('cross-origin-multipart-image-with-no-cors') >= 0) { + event.respondWith(fetch(cross_origin_url, {mode: 'no-cors'})); + } else if (url.indexOf('cross-origin-multipart-image-with-cors-rejected') >= 0) { + event.respondWith(fetch(cross_origin_url, {mode: 'cors'})); + } else if (url.indexOf('cross-origin-multipart-image-with-cors-approved') >= 0) { + event.respondWith(fetch(cross_origin_url + '?approvecors', {mode: 'cors'})); + } else if (url.indexOf('same-origin-multipart-image') >= 0) { + event.respondWith(fetch(sameorigin_url)); + } +}); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/navigate-window-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/navigate-window-worker.js new file mode 100644 index 000000000000..f9617439fc60 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/navigate-window-worker.js @@ -0,0 +1,21 @@ +addEventListener('message', function(evt) { + if (evt.data.type === 'GET_CLIENTS') { + clients.matchAll(evt.data.opts).then(function(clientList) { + var resultList = clientList.map(function(c) { + return { url: c.url, frameType: c.frameType, id: c.id }; + }); + evt.source.postMessage({ type: 'success', detail: resultList }); + }).catch(function(err) { + evt.source.postMessage({ + type: 'failure', + detail: 'matchAll() rejected with "' + err + '"' + }); + }); + return; + } + + evt.source.postMessage({ + type: 'failure', + detail: 'Unexpected message type "' + evt.data.type + '"' + }); +}); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/navigation-redirect-body-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/navigation-redirect-body-worker.js new file mode 100644 index 000000000000..39f11baf8cb9 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/navigation-redirect-body-worker.js @@ -0,0 +1,11 @@ +self.addEventListener('fetch', function(event) { + event.respondWith( + fetch(event.request) + .then( + function(response) { + return response; + }, + function(error) { + return new Response('Error:' + error); + })); + }); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/navigation-redirect-other-origin.html b/test/fixtures/wpt/service-workers/service-worker/resources/navigation-redirect-other-origin.html new file mode 100644 index 000000000000..d82571d1a3c7 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/navigation-redirect-other-origin.html @@ -0,0 +1,89 @@ + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/navigation-redirect-to-http-iframe.html b/test/fixtures/wpt/service-workers/service-worker/resources/navigation-redirect-to-http-iframe.html new file mode 100644 index 000000000000..40e27c630d29 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/navigation-redirect-to-http-iframe.html @@ -0,0 +1,42 @@ + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/navigation-redirect-to-http-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/navigation-redirect-to-http-worker.js new file mode 100644 index 000000000000..6f2a8ae1d749 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/navigation-redirect-to-http-worker.js @@ -0,0 +1,22 @@ +importScripts('/resources/testharness.js'); + +self.addEventListener('fetch', function(event) { + event.respondWith(new Promise(function(resolve) { + Promise.resolve() + .then(function() { + assert_equals( + event.request.redirect, 'manual', + 'The redirect mode of navigation request must be manual.'); + return fetch(event.request); + }) + .then(function(response) { + assert_equals( + response.type, 'opaqueredirect', + 'The response type of 302 response must be opaqueredirect.'); + resolve(new Response('OK')); + }) + .catch(function(error) { + resolve(new Response('Failed in SW: ' + error)); + }); + })); + }); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/navigation-timing-worker-extended.js b/test/fixtures/wpt/service-workers/service-worker/resources/navigation-timing-worker-extended.js new file mode 100644 index 000000000000..79c54088ff60 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/navigation-timing-worker-extended.js @@ -0,0 +1,22 @@ +importScripts("/resources/testharness.js"); +const timings = {} + +const DELAY_ACTIVATION = 500 + +self.addEventListener('activate', event => { + event.waitUntil(new Promise(resolve => { + timings.activateWorkerStart = performance.now() + performance.timeOrigin; + + // This gives us enough time to ensure activation would delay fetch handling + step_timeout(resolve, DELAY_ACTIVATION); + }).then(() => timings.activateWorkerEnd = performance.now() + performance.timeOrigin)); +}) + +self.addEventListener('fetch', event => { + timings.handleFetchEvent = performance.now() + performance.timeOrigin; + event.respondWith(Promise.resolve(new Response(new Blob([` + + `])))); +}); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/navigation-timing-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/navigation-timing-worker.js new file mode 100644 index 000000000000..8539b40066dd --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/navigation-timing-worker.js @@ -0,0 +1,15 @@ +self.addEventListener('fetch', (event) => { + const url = event.request.url; + + // Network fallback. + if (url.indexOf('network-fallback') >= 0) { + return; + } + + // Don't intercept redirect. + if (url.indexOf('redirect.py') >= 0) { + return; + } + + event.respondWith(fetch(url)); +}); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/nested-blob-url-worker-created-from-worker.html b/test/fixtures/wpt/service-workers/service-worker/resources/nested-blob-url-worker-created-from-worker.html new file mode 100644 index 000000000000..fc048e288e90 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/nested-blob-url-worker-created-from-worker.html @@ -0,0 +1,16 @@ + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/nested-blob-url-workers.html b/test/fixtures/wpt/service-workers/service-worker/resources/nested-blob-url-workers.html new file mode 100644 index 000000000000..f0eafcd3e01c --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/nested-blob-url-workers.html @@ -0,0 +1,38 @@ + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/nested-iframe-parent.html b/test/fixtures/wpt/service-workers/service-worker/resources/nested-iframe-parent.html new file mode 100644 index 000000000000..115ab26e1221 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/nested-iframe-parent.html @@ -0,0 +1,5 @@ + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/nested-parent.html b/test/fixtures/wpt/service-workers/service-worker/resources/nested-parent.html new file mode 100644 index 000000000000..b4832d461d5c --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/nested-parent.html @@ -0,0 +1,18 @@ + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/nested-worker-created-from-blob-url-worker.html b/test/fixtures/wpt/service-workers/service-worker/resources/nested-worker-created-from-blob-url-worker.html new file mode 100644 index 000000000000..3fad2c9228ce --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/nested-worker-created-from-blob-url-worker.html @@ -0,0 +1,33 @@ + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/nested_load_worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/nested_load_worker.js new file mode 100644 index 000000000000..7296d8fe1a3a --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/nested_load_worker.js @@ -0,0 +1,23 @@ +// Entry point for dedicated workers. +self.onmessage = evt => { + try { + const worker = new Worker('load_worker.js'); + worker.onmessage = msg => self.postMessage(msg.data); + worker.postMessage(evt.data); + } catch (err) { + self.postMessage('Unexpected error! ' + err.message); + } +}; + +// Entry point for shared workers. +self.onconnect = evt => { + evt.ports[0].onmessage = e => { + try { + const worker = new Worker('load_worker.js'); + worker.onmessage = msg => evt.ports[0].postMessage(msg.data); + worker.postMessage(e.data); + } catch (err) { + evt.ports[0].postMessage('Unexpected error! ' + err.message); + } + }; +}; diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/no-dynamic-import.js b/test/fixtures/wpt/service-workers/service-worker/resources/no-dynamic-import.js new file mode 100644 index 000000000000..ecedd6c5d75c --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/no-dynamic-import.js @@ -0,0 +1,18 @@ +/** @type {[name: string, url: string][]} */ +const importUrlTests = [ + ["Module URL", "./basic-module.js"], + // In no-dynamic-import-in-module.any.js, this module is also statically imported + ["Another module URL", "./basic-module-2.js"], + [ + "Module data: URL", + "data:text/javascript;charset=utf-8," + + encodeURIComponent(`export default 'hello!';`), + ], +]; + +for (const [name, url] of importUrlTests) { + promise_test( + (t) => promise_rejects_js(t, TypeError, import(url), "Import must reject"), + name + ); +} diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/object-image-is-not-intercepted-iframe.html b/test/fixtures/wpt/service-workers/service-worker/resources/object-image-is-not-intercepted-iframe.html new file mode 100644 index 000000000000..5a20a58ab169 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/object-image-is-not-intercepted-iframe.html @@ -0,0 +1,21 @@ + + +iframe for embed-and-object-are-not-intercepted test + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/object-is-not-intercepted-iframe.html b/test/fixtures/wpt/service-workers/service-worker/resources/object-is-not-intercepted-iframe.html new file mode 100644 index 000000000000..0aeb81951ede --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/object-is-not-intercepted-iframe.html @@ -0,0 +1,18 @@ + + +iframe for embed-and-object-are-not-intercepted test + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/object-navigation-is-not-intercepted-iframe.html b/test/fixtures/wpt/service-workers/service-worker/resources/object-navigation-is-not-intercepted-iframe.html new file mode 100644 index 000000000000..5c8ab79a500a --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/object-navigation-is-not-intercepted-iframe.html @@ -0,0 +1,24 @@ + + +iframe for embed-and-object-are-not-intercepted test + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/onactivate-throw-error-from-nested-event-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/onactivate-throw-error-from-nested-event-worker.js new file mode 100644 index 000000000000..7c97014fd042 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/onactivate-throw-error-from-nested-event-worker.js @@ -0,0 +1,13 @@ +var max_nesting_level = 8; + +self.addEventListener('message', function(event) { + var level = event.data; + if (level < max_nesting_level) + dispatchEvent(new MessageEvent('message', { data: level + 1 })); + throw Error('error at level ' + level); + }); + +self.addEventListener('activate', function(event) { + dispatchEvent(new MessageEvent('message', { data: 1 })); + }); + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/onactivate-throw-error-then-cancel-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/onactivate-throw-error-then-cancel-worker.js new file mode 100644 index 000000000000..0bd9d318b241 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/onactivate-throw-error-then-cancel-worker.js @@ -0,0 +1,3 @@ +self.onerror = function(event) { return true; }; + +self.addEventListener('activate', function(event) { throw new Error(); }); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/onactivate-throw-error-then-prevent-default-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/onactivate-throw-error-then-prevent-default-worker.js new file mode 100644 index 000000000000..d56c95113917 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/onactivate-throw-error-then-prevent-default-worker.js @@ -0,0 +1,7 @@ +// Ensure we can handle multiple error handlers. One error handler +// calling preventDefault should cause the event to be treated as +// handled. +self.addEventListener('error', function(event) {}); +self.addEventListener('error', function(event) { event.preventDefault(); }); +self.addEventListener('error', function(event) {}); +self.addEventListener('activate', function(event) { throw new Error(); }); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/onactivate-throw-error-with-empty-onerror-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/onactivate-throw-error-with-empty-onerror-worker.js new file mode 100644 index 000000000000..eb12ae862c59 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/onactivate-throw-error-with-empty-onerror-worker.js @@ -0,0 +1,2 @@ +self.addEventListener('error', function(event) {}); +self.addEventListener('activate', function(event) { throw new Error(); }); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/onactivate-throw-error-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/onactivate-throw-error-worker.js new file mode 100644 index 000000000000..1e88ac5c4e78 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/onactivate-throw-error-worker.js @@ -0,0 +1,7 @@ +// Ensure we can handle multiple activate handlers. One handler throwing an +// error should cause the event dispatch to be treated as having unhandled +// errors. +self.addEventListener('activate', function(event) {}); +self.addEventListener('activate', function(event) {}); +self.addEventListener('activate', function(event) { throw new Error(); }); +self.addEventListener('activate', function(event) {}); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/onactivate-waituntil-forever.js b/test/fixtures/wpt/service-workers/service-worker/resources/onactivate-waituntil-forever.js new file mode 100644 index 000000000000..65b02b12b360 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/onactivate-waituntil-forever.js @@ -0,0 +1,8 @@ +'use strict'; + +self.addEventListener('activate', event => { + event.waitUntil(new Promise(() => { + // Use a promise that never resolves to prevent this service worker from + // advancing past the 'activating' state. + })); +}); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/onfetch-waituntil-forever.js b/test/fixtures/wpt/service-workers/service-worker/resources/onfetch-waituntil-forever.js new file mode 100644 index 000000000000..b905d555986e --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/onfetch-waituntil-forever.js @@ -0,0 +1,10 @@ +'use strict'; + +self.addEventListener('fetch', event => { + if (event.request.url.endsWith('waituntil-forever')) { + event.respondWith(new Promise(() => { + // Use a promise that never resolves to prevent this fetch from + // completing. + })); + } +}); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/oninstall-throw-error-from-nested-event-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/oninstall-throw-error-from-nested-event-worker.js new file mode 100644 index 000000000000..6729ab61a371 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/oninstall-throw-error-from-nested-event-worker.js @@ -0,0 +1,12 @@ +var max_nesting_level = 8; + +self.addEventListener('message', function(event) { + var level = event.data; + if (level < max_nesting_level) + dispatchEvent(new MessageEvent('message', { data: level + 1 })); + throw Error('error at level ' + level); + }); + +self.addEventListener('install', function(event) { + dispatchEvent(new MessageEvent('message', { data: 1 })); + }); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/oninstall-throw-error-then-cancel-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/oninstall-throw-error-then-cancel-worker.js new file mode 100644 index 000000000000..c2c499ab1a37 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/oninstall-throw-error-then-cancel-worker.js @@ -0,0 +1,3 @@ +self.onerror = function(event) { return true; }; + +self.addEventListener('install', function(event) { throw new Error(); }); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/oninstall-throw-error-then-prevent-default-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/oninstall-throw-error-then-prevent-default-worker.js new file mode 100644 index 000000000000..7667c2781d09 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/oninstall-throw-error-then-prevent-default-worker.js @@ -0,0 +1,7 @@ +// Ensure we can handle multiple error handlers. One error handler +// calling preventDefault should cause the event to be treated as +// handled. +self.addEventListener('error', function(event) {}); +self.addEventListener('error', function(event) { event.preventDefault(); }); +self.addEventListener('error', function(event) {}); +self.addEventListener('install', function(event) { throw new Error(); }); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/oninstall-throw-error-with-empty-onerror-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/oninstall-throw-error-with-empty-onerror-worker.js new file mode 100644 index 000000000000..8f56d1bf1491 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/oninstall-throw-error-with-empty-onerror-worker.js @@ -0,0 +1,2 @@ +self.addEventListener('error', function(event) {}); +self.addEventListener('install', function(event) { throw new Error(); }); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/oninstall-throw-error-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/oninstall-throw-error-worker.js new file mode 100644 index 000000000000..cc2f6d7e5e78 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/oninstall-throw-error-worker.js @@ -0,0 +1,7 @@ +// Ensure we can handle multiple install handlers. One handler throwing an +// error should cause the event dispatch to be treated as having unhandled +// errors. +self.addEventListener('install', function(event) {}); +self.addEventListener('install', function(event) {}); +self.addEventListener('install', function(event) { throw new Error(); }); +self.addEventListener('install', function(event) {}); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/oninstall-waituntil-forever.js b/test/fixtures/wpt/service-workers/service-worker/resources/oninstall-waituntil-forever.js new file mode 100644 index 000000000000..964483f2f427 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/oninstall-waituntil-forever.js @@ -0,0 +1,8 @@ +'use strict'; + +self.addEventListener('install', event => { + event.waitUntil(new Promise(() => { + // Use a promise that never resolves to prevent this service worker from + // advancing past the 'installing' state. + })); +}); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/oninstall-waituntil-throw-error-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/oninstall-waituntil-throw-error-worker.js new file mode 100644 index 000000000000..6cb8f6ede635 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/oninstall-waituntil-throw-error-worker.js @@ -0,0 +1,5 @@ +self.addEventListener('install', function(event) { + event.waitUntil(new Promise(function(aRequest, aResponse) { + throw new Error(); + })); +}); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/onparse-infiniteloop-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/onparse-infiniteloop-worker.js new file mode 100644 index 000000000000..6f439aee94d5 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/onparse-infiniteloop-worker.js @@ -0,0 +1,8 @@ +'use strict'; + +// Use an infinite loop to prevent this service worker from advancing past the +// 'parsed' state. +let i = 0; +while (true) { + ++i; +} diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/opaque-response-being-preloaded-xhr.html b/test/fixtures/wpt/service-workers/service-worker/resources/opaque-response-being-preloaded-xhr.html new file mode 100644 index 000000000000..9c6d8bd504a1 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/opaque-response-being-preloaded-xhr.html @@ -0,0 +1,33 @@ + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/opaque-response-preloaded-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/opaque-response-preloaded-worker.js new file mode 100644 index 000000000000..4fbe35df277e --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/opaque-response-preloaded-worker.js @@ -0,0 +1,12 @@ +importScripts('/common/get-host-info.sub.js'); + +var remoteUrl = get_host_info()['HTTPS_REMOTE_ORIGIN'] + + '/service-workers/service-worker/resources/sample.js' + +self.addEventListener('fetch', event => { + if (!event.request.url.match(/opaque-response\?from=/)) { + return; + } + + event.respondWith(fetch(remoteUrl, {mode: 'no-cors'})); + }); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/opaque-response-preloaded-xhr.html b/test/fixtures/wpt/service-workers/service-worker/resources/opaque-response-preloaded-xhr.html new file mode 100644 index 000000000000..f31ac9b5c4ce --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/opaque-response-preloaded-xhr.html @@ -0,0 +1,35 @@ + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/opaque-script-frame.html b/test/fixtures/wpt/service-workers/service-worker/resources/opaque-script-frame.html new file mode 100644 index 000000000000..a57aacec7c6f --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/opaque-script-frame.html @@ -0,0 +1,21 @@ + + + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/opaque-script-large.js b/test/fixtures/wpt/service-workers/service-worker/resources/opaque-script-large.js new file mode 100644 index 000000000000..7e1c598efc5c --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/opaque-script-large.js @@ -0,0 +1,41 @@ +function runScript() { + throw new Error("Intentional error."); +} + +function unused() { + // The following string is intended to be relatively large since some + // browsers trigger different code paths based on script size. + return "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a " + + "tortor ut orci bibendum blandit non quis diam. Aenean sit amet " + + "urna sit amet neque malesuada ultricies at vel nisi. Nunc et lacus " + + "est. Nam posuere erat enim, ac fringilla purus pellentesque " + + "cursus. Proin sodales eleifend lorem, eu semper massa scelerisque " + + "ac. Maecenas pharetra leo malesuada vulputate vulputate. Sed at " + + "efficitur odio. In rhoncus neque varius nibh efficitur gravida. " + + "Curabitur vitae dolor enim. Mauris semper lobortis libero sed " + + "congue. Donec felis ante, fringilla eget urna ut, finibus " + + "hendrerit lacus. Donec at interdum diam. Proin a neque vitae diam " + + "egestas euismod. Mauris posuere elementum lorem, eget convallis " + + "nisl elementum et. In ut leo ac neque dapibus pharetra quis ac " + + "velit. Integer pretium lectus non urna vulputate, in interdum mi " + + "lobortis. Sed laoreet ex et metus pharetra blandit. Curabitur " + + "sollicitudin non neque eu varius. Phasellus posuere congue arcu, " + + "in aliquam nunc fringilla a. Morbi id facilisis libero. Phasellus " + + "metus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. " + + "tortor ut orci bibendum blandit non quis diam. Aenean sit amet " + + "urna sit amet neque malesuada ultricies at vel nisi. Nunc et lacus " + + "est. Nam posuere erat enim, ac fringilla purus pellentesque " + + "cursus. Proin sodales eleifend lorem, eu semper massa scelerisque " + + "ac. Maecenas pharetra leo malesuada vulputate vulputate. Sed at " + + "efficitur odio. In rhoncus neque varius nibh efficitur gravida. " + + "Curabitur vitae dolor enim. Mauris semper lobortis libero sed " + + "congue. Donec felis ante, fringilla eget urna ut, finibus " + + "hendrerit lacus. Donec at interdum diam. Proin a neque vitae diam " + + "egestas euismod. Mauris posuere elementum lorem, eget convallis " + + "nisl elementum et. In ut leo ac neque dapibus pharetra quis ac " + + "velit. Integer pretium lectus non urna vulputate, in interdum mi " + + "lobortis. Sed laoreet ex et metus pharetra blandit. Curabitur " + + "sollicitudin non neque eu varius. Phasellus posuere congue arcu, " + + "in aliquam nunc fringilla a. Morbi id facilisis libero. Phasellus " + + "metus."; +} diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/opaque-script-small.js b/test/fixtures/wpt/service-workers/service-worker/resources/opaque-script-small.js new file mode 100644 index 000000000000..8b890985752f --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/opaque-script-small.js @@ -0,0 +1,3 @@ +function runScript() { + throw new Error("Intentional error."); +} diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/opaque-script-sw.js b/test/fixtures/wpt/service-workers/service-worker/resources/opaque-script-sw.js new file mode 100644 index 000000000000..4d882c617d8d --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/opaque-script-sw.js @@ -0,0 +1,37 @@ +importScripts('test-helpers.sub.js'); +importScripts('/common/get-host-info.sub.js'); + +const NAME = 'foo'; +const SAME_ORIGIN_BASE = new URL('./', self.location.href).href; +const CROSS_ORIGIN_BASE = new URL('./', + get_host_info().HTTPS_REMOTE_ORIGIN + base_path()).href; + +const urls = [ + `${SAME_ORIGIN_BASE}opaque-script-small.js`, + `${SAME_ORIGIN_BASE}opaque-script-large.js`, + `${CROSS_ORIGIN_BASE}opaque-script-small.js`, + `${CROSS_ORIGIN_BASE}opaque-script-large.js`, +]; + +self.addEventListener('install', evt => { + evt.waitUntil(async function() { + const c = await caches.open(NAME); + const promises = urls.map(async function(u) { + const r = await fetch(u, { mode: 'no-cors' }); + await c.put(u, r); + }); + await Promise.all(promises); + }()); +}); + +self.addEventListener('fetch', evt => { + const url = new URL(evt.request.url); + if (!url.pathname.includes('opaque-script-small.js') && + !url.pathname.includes('opaque-script-large.js')) { + return; + } + evt.respondWith(async function() { + const c = await caches.open(NAME); + return c.match(evt.request); + }()); +}); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/or-test/direct1.text b/test/fixtures/wpt/service-workers/service-worker/resources/or-test/direct1.text new file mode 100644 index 000000000000..f3d9861c137b --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/or-test/direct1.text @@ -0,0 +1 @@ +Network diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/or-test/direct1.text.headers b/test/fixtures/wpt/service-workers/service-worker/resources/or-test/direct1.text.headers new file mode 100644 index 000000000000..156209f9c81f --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/or-test/direct1.text.headers @@ -0,0 +1 @@ +Content-Type: text/html diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/or-test/direct2.text b/test/fixtures/wpt/service-workers/service-worker/resources/or-test/direct2.text new file mode 100644 index 000000000000..f3d9861c137b --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/or-test/direct2.text @@ -0,0 +1 @@ +Network diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/or-test/direct2.text.headers b/test/fixtures/wpt/service-workers/service-worker/resources/or-test/direct2.text.headers new file mode 100644 index 000000000000..156209f9c81f --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/or-test/direct2.text.headers @@ -0,0 +1 @@ +Content-Type: text/html diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/other.html b/test/fixtures/wpt/service-workers/service-worker/resources/other.html new file mode 100644 index 000000000000..b9f350438772 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/other.html @@ -0,0 +1,3 @@ + +Other +Here's an other html file. diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/override_assert_object_equals.js b/test/fixtures/wpt/service-workers/service-worker/resources/override_assert_object_equals.js new file mode 100644 index 000000000000..835046d472b2 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/override_assert_object_equals.js @@ -0,0 +1,58 @@ +// .body attribute of Request and Response object are experimental feture. It is +// enabled when --enable-experimental-web-platform-features flag is set. +// Touching this attribute can change the behavior of the objects. To avoid +// touching it while comparing the objects in LayoutTest, we overwrite +// assert_object_equals method. + +(function() { + var original_assert_object_equals = self.assert_object_equals; + function _brand(object) { + return Object.prototype.toString.call(object).match(/^\[object (.*)\]$/)[1]; + } + var assert_request_equals = function(actual, expected, prefix) { + if (typeof actual !== 'object') { + assert_equals(actual, expected, prefix); + return; + } + assert_true(actual instanceof Request, prefix); + assert_true(expected instanceof Request, prefix); + assert_equals(actual.bodyUsed, expected.bodyUsed, prefix + '.bodyUsed'); + assert_equals(actual.method, expected.method, prefix + '.method'); + assert_equals(actual.url, expected.url, prefix + '.url'); + original_assert_object_equals(actual.headers, expected.headers, + prefix + '.headers'); + assert_equals(actual.context, expected.context, prefix + '.context'); + assert_equals(actual.referrer, expected.referrer, prefix + '.referrer'); + assert_equals(actual.mode, expected.mode, prefix + '.mode'); + assert_equals(actual.credentials, expected.credentials, + prefix + '.credentials'); + assert_equals(actual.cache, expected.cache, prefix + '.cache'); + }; + var assert_response_equals = function(actual, expected, prefix) { + if (typeof actual !== 'object') { + assert_equals(actual, expected, prefix); + return; + } + assert_true(actual instanceof Response, prefix); + assert_true(expected instanceof Response, prefix); + assert_equals(actual.bodyUsed, expected.bodyUsed, prefix + '.bodyUsed'); + assert_equals(actual.type, expected.type, prefix + '.type'); + assert_equals(actual.url, expected.url, prefix + '.url'); + assert_equals(actual.status, expected.status, prefix + '.status'); + assert_equals(actual.statusText, expected.statusText, + prefix + '.statusText'); + original_assert_object_equals(actual.headers, expected.headers, + prefix + '.headers'); + }; + var assert_object_equals = function(actual, expected, description) { + var prefix = (description ? description + ': ' : '') + _brand(expected); + if (expected instanceof Request) { + assert_request_equals(actual, expected, prefix); + } else if (expected instanceof Response) { + assert_response_equals(actual, expected, prefix); + } else { + original_assert_object_equals(actual, expected, description); + } + }; + self.assert_object_equals = assert_object_equals; +})(); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/partitioned-cookies-3p-credentialless-frame.html b/test/fixtures/wpt/service-workers/service-worker/resources/partitioned-cookies-3p-credentialless-frame.html new file mode 100644 index 000000000000..25ddf601457c --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/partitioned-cookies-3p-credentialless-frame.html @@ -0,0 +1,114 @@ + + + + +Service Worker: Partitioned Cookies 3P Credentialless Iframe + + + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/partitioned-cookies-3p-frame.html b/test/fixtures/wpt/service-workers/service-worker/resources/partitioned-cookies-3p-frame.html new file mode 100644 index 000000000000..97f3a9c3df3e --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/partitioned-cookies-3p-frame.html @@ -0,0 +1,77 @@ + + + + +Service Worker: Partitioned Cookies 3P Iframe + + + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/partitioned-cookies-3p-sw.js b/test/fixtures/wpt/service-workers/service-worker/resources/partitioned-cookies-3p-sw.js new file mode 100644 index 000000000000..c9713b6c50c4 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/partitioned-cookies-3p-sw.js @@ -0,0 +1,3 @@ +// Import the code from the 1P partitioned worker. +// We use separate URLs for each worker script to keep their scopes unique. +importScripts('./partitioned-cookies-sw.js'); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/partitioned-cookies-3p-window.html b/test/fixtures/wpt/service-workers/service-worker/resources/partitioned-cookies-3p-window.html new file mode 100644 index 000000000000..40d38b3f79f3 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/partitioned-cookies-3p-window.html @@ -0,0 +1,35 @@ + + + + +Service Worker: Partitioned Cookies 3P Window + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/partitioned-cookies-sw.js b/test/fixtures/wpt/service-workers/service-worker/resources/partitioned-cookies-sw.js new file mode 100644 index 000000000000..767dbf443275 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/partitioned-cookies-sw.js @@ -0,0 +1,53 @@ +self.addEventListener('message', ev => ev.waitUntil(onMessage(ev))); + +async function onMessage(event) { + if (!event.data) + return; + switch (event.data.type) { + case 'test_message': + return onTestMessage(event); + case 'echo_cookies_http': + return onEchoCookiesHttp(event); + case 'echo_cookies_js': + return onEchoCookiesJs(event); + case 'echo_cookies_import': + return onEchoCookiesImport(event); + default: + return; + } +} + +// test_message just verifies that the message passing is working. +async function onTestMessage(event) { + event.source.postMessage({ok: true}); +} + +async function onEchoCookiesHttp(event) { + try { + const resp = await fetch( + `${self.origin}/cookies/resources/list.py`, {credentials: 'include'}); + const cookies = await resp.json(); + event.source.postMessage({ok: true, cookies: Object.keys(cookies)}); + } catch (err) { + event.source.postMessage({ok: false}); + } +} + +// echo_cookies returns the names of all of the cookies available to the worker. +async function onEchoCookiesJs(event) { + try { + const cookie_objects = await self.cookieStore.getAll(); + const cookies = cookie_objects.map(c => c.name); + event.source.postMessage({ok: true, cookies}); + } catch (err) { + event.source.postMessage({ok: false}); + } +} + +// Sets `self._cookies` variable, array of the names of cookies available to +// the request. +importScripts(`${self.origin}/cookies/resources/list-cookies-for-script.py`); + +function onEchoCookiesImport(event) { + event.source.postMessage({ok: true, cookies: self._cookies}); +} diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/partitioned-cookies-test-helpers.js b/test/fixtures/wpt/service-workers/service-worker/resources/partitioned-cookies-test-helpers.js new file mode 100644 index 000000000000..73f3b0bde069 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/partitioned-cookies-test-helpers.js @@ -0,0 +1,31 @@ +// Return a generator containing the worker's message. +// +// Usage: +// await navigator.serviceWorker.register(...) +// ... +// const nextMessage = worker_message_generator(); +// const msg_1 = await nextMessage(); +// const msg_2 = await nextMessage(); +// const msg_3 = await nextMessage(); +// +// Worker should have its own onmessage event listener that +// postMessages replies to the DOM. +function worker_message_generator() { + const buffer = []; + let resolve = null; + + navigator.serviceWorker.addEventListener('message', message => { + buffer.push(message.data); + if (resolve) { + resolve(); + } + }); + + return async function () { + if (buffer.length != 0) { + return buffer.shift(); + } + await new Promise(r => resolve = r); + return buffer.shift(); + } +} diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/partitioned-service-worker-iframe-claim.html b/test/fixtures/wpt/service-workers/service-worker/resources/partitioned-service-worker-iframe-claim.html new file mode 100644 index 000000000000..12b048ee04c7 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/partitioned-service-worker-iframe-claim.html @@ -0,0 +1,59 @@ + +Service Worker: 3P iframe for partitioned service workers + + + + + + + \ No newline at end of file diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/partitioned-service-worker-nested-iframe-child.html b/test/fixtures/wpt/service-workers/service-worker/resources/partitioned-service-worker-nested-iframe-child.html new file mode 100644 index 000000000000..d05fef48bf0e --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/partitioned-service-worker-nested-iframe-child.html @@ -0,0 +1,44 @@ + +Service Worker: Innermost nested iframe for partitioned service workers + + + + + +Innermost 1p iframe (A2) with 3p ancestor (A1-B-A2-A3): this iframe will +register a service worker when it loads and then add its own iframe (A3) that +will attempt to navigate to a url. ServiceWorker will intercept this navigation +and resolve the ServiceWorker's internal Promise. When +ThirdPartyStoragePartitioning is enabled, this iframe should be partitioned +from the main frame and should not share a ServiceWorker. + + \ No newline at end of file diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/partitioned-service-worker-nested-iframe-parent.html b/test/fixtures/wpt/service-workers/service-worker/resources/partitioned-service-worker-nested-iframe-parent.html new file mode 100644 index 000000000000..f748e2f78d91 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/partitioned-service-worker-nested-iframe-parent.html @@ -0,0 +1,30 @@ + +Service Worker: Middle nested iframe for partitioned service workers + + + + + +Middle of the nested iframes (3p ancestor or B in A1-B-A2). + + \ No newline at end of file diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/partitioned-service-worker-third-party-iframe-getRegistrations.html b/test/fixtures/wpt/service-workers/service-worker/resources/partitioned-service-worker-third-party-iframe-getRegistrations.html new file mode 100644 index 000000000000..747c05894602 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/partitioned-service-worker-third-party-iframe-getRegistrations.html @@ -0,0 +1,40 @@ + +Service Worker: 3P iframe for partitioned service workers + + + + + + This iframe will register a service worker when it loads and then will use + getRegistrations to get a handle to the SW. It will then postMessage to the + SW to retrieve the SW's ID. This iframe will then forward that message up, + eventually, to the test. + + \ No newline at end of file diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/partitioned-service-worker-third-party-iframe-matchAll.html b/test/fixtures/wpt/service-workers/service-worker/resources/partitioned-service-worker-third-party-iframe-matchAll.html new file mode 100644 index 000000000000..7a2c36693e1e --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/partitioned-service-worker-third-party-iframe-matchAll.html @@ -0,0 +1,27 @@ + +Service Worker: 3P iframe for partitioned service workers + + + + + + This iframe will register a service worker when it loads and then will use + getRegistrations to get a handle to the SW. It will then postMessage to the + SW to get the SW's clients via matchAll(). This iframe will then forward the + SW's response up, eventually, to the test. + + \ No newline at end of file diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/partitioned-service-worker-third-party-iframe.html b/test/fixtures/wpt/service-workers/service-worker/resources/partitioned-service-worker-third-party-iframe.html new file mode 100644 index 000000000000..1b7f671b3714 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/partitioned-service-worker-third-party-iframe.html @@ -0,0 +1,36 @@ + +Service Worker: 3P iframe for partitioned service workers + + + + + + +This iframe will register a service worker when it loads and then add its own +iframe that will attempt to navigate to a url that service worker will intercept +and use to resolve the service worker's internal Promise. + + \ No newline at end of file diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/partitioned-service-worker-third-party-window.html b/test/fixtures/wpt/service-workers/service-worker/resources/partitioned-service-worker-third-party-window.html new file mode 100644 index 000000000000..86384ce28087 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/partitioned-service-worker-third-party-window.html @@ -0,0 +1,41 @@ + +Service Worker: 3P window for partitioned service workers + + + + + +This page should be opened as a third-party window. It then loads an iframe +specified by the query parameter. Finally it forwards the postMessage from the +iframe up to the opener (the test). + + + \ No newline at end of file diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/partitioned-storage-sw.js b/test/fixtures/wpt/service-workers/service-worker/resources/partitioned-storage-sw.js new file mode 100644 index 000000000000..00f797981037 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/partitioned-storage-sw.js @@ -0,0 +1,81 @@ +// Holds the promise that the "resolve.fakehtml" call attempts to resolve. +// This is "the SW's promise" that other parts of the test refer to. +var promise; +// Stores the resolve funcution for the current promise. +var pending_resolve_func = null; +// Unique ID to determine which service worker is being used. +const ID = Math.random(); + +function callAndResetResolve() { + var local_resolve = pending_resolve_func; + pending_resolve_func = null; + local_resolve(); +} + +self.addEventListener('fetch', function(event) { + fetchEventHandler(event); +}) + +self.addEventListener('message', (event) => { + event.waitUntil(async function() { + if(!event.data) + return; + + if (event.data.type === "get-id") { + event.source.postMessage({ID: ID}); + } + else if(event.data.type === "get-match-all") { + clients.matchAll({includeUncontrolled: true}).then(clients_list => { + const url_list = clients_list.map(item => item.url); + event.source.postMessage({urls_list: url_list}); + }); + } + else if(event.data.type === "claim") { + await clients.claim(); + } + }()); +}); + +async function fetchEventHandler(event){ + var request_url = new URL(event.request.url); + var url_search = request_url.search.substr(1); + request_url.search = ""; + if ( request_url.href.endsWith('waitUntilResolved.fakehtml') ) { + + if (pending_resolve_func != null) { + // Respond with an error if there is already a pending promise + event.respondWith(Response.error()); + return; + } + + // Create the new promise. + promise = new Promise(function(resolve) { + pending_resolve_func = resolve; + }); + event.waitUntil(promise); + + event.respondWith(new Response(` + + Promise created by ${url_search} + + + `, {headers: {'Content-Type': 'text/html'}} + )); + + } + else if ( request_url.href.endsWith('resolve.fakehtml') ) { + var has_pending = !!pending_resolve_func; + event.respondWith(new Response(` + + Promise settled for ${url_search} + + + `, {headers: {'Content-Type': 'text/html'}})); + + if (has_pending) { + callAndResetResolve(); + } + } +} \ No newline at end of file diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/partitioned-utils.js b/test/fixtures/wpt/service-workers/service-worker/resources/partitioned-utils.js new file mode 100644 index 000000000000..22e90beaec77 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/partitioned-utils.js @@ -0,0 +1,110 @@ +// The resolve function for the current pending event listener's promise. +// It is nulled once the promise is resolved. +var message_event_promise_resolve = null; + +function messageEventHandler(evt) { + if (message_event_promise_resolve) { + local_resolve = message_event_promise_resolve; + message_event_promise_resolve = null; + local_resolve(evt.data); + } +} + +function makeMessagePromise() { + if (message_event_promise_resolve != null) { + // Do not create a new promise until the previous is settled. + return; + } + + return new Promise(resolve => { + message_event_promise_resolve = resolve; + }); +} + +// Loads a url for the frame type and then returns a promise for +// the data that was postMessage'd from the loaded frame. +// If the frame type is 'window' then `url` is encoded into the search param +// as the url the 3p window is meant to iframe. +function loadAndReturnSwData(t, url, frame_type) { + if (frame_type !== 'iframe' && frame_type !== 'window') { + return; + } + + const message_promise = makeMessagePromise(); + + // Create the iframe or window and then return the promise for data. + if ( frame_type === 'iframe' ) { + const frame = with_iframe(url, false); + t.add_cleanup(async () => { + const f = await frame; + f.remove(); + }); + } + else { + // 'window' case. + const search_param = new URLSearchParams(); + search_param.append('target', url); + + const third_party_window_url = new URL( + './resources/partitioned-service-worker-third-party-window.html' + + '?' + search_param, + get_host_info().HTTPS_NOTSAMESITE_ORIGIN + self.location.pathname); + + const w = window.open(third_party_window_url); + t.add_cleanup(() => w.close()); + } + + return message_promise; +} + +// Checks for an existing service worker registration. If not present, +// registers and maintains a service worker. Used in windows or iframes +// that will be partitioned from the main frame. +async function setupServiceWorker() { + + const script = './partitioned-storage-sw.js'; + const scope = './partitioned-'; + + var reg = await navigator.serviceWorker.register(script, { scope: scope }); + + // We should keep track if we installed a worker or not. If we did then we + // need to uninstall it. Otherwise we let the top level test uninstall it + // (If partitioning is not working). + var installed_a_worker = true; + await new Promise(resolve => { + // Check if a worker is already activated. + var worker = reg.active; + // If so, just resolve. + if ( worker ) { + installed_a_worker = false; + resolve(); + return; + } + + //Otherwise check if one is waiting. + worker = reg.waiting; + // If not waiting, grab the installing worker. + if ( !worker ) { + worker = reg.installing; + } + + // Resolve once it's activated. + worker.addEventListener('statechange', evt => { + if (worker.state === 'activated') { + resolve(); + } + }); + }); + + self.addEventListener('unload', async () => { + // If we didn't install a worker then that means the top level test did, and + // that test is therefore responsible for cleaning it up. + if ( !installed_a_worker ) { + return; + } + + await reg.unregister(); + }); + + return reg; +} \ No newline at end of file diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/pass-through-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/pass-through-worker.js new file mode 100644 index 000000000000..5eaf48d5887d --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/pass-through-worker.js @@ -0,0 +1,3 @@ +addEventListener('fetch', evt => { + evt.respondWith(fetch(evt.request)); +}); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/pass.txt b/test/fixtures/wpt/service-workers/service-worker/resources/pass.txt new file mode 100644 index 000000000000..7ef22e9a431a --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/pass.txt @@ -0,0 +1 @@ +PASS diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/performance-timeline-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/performance-timeline-worker.js new file mode 100644 index 000000000000..6c6dfcbd2811 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/performance-timeline-worker.js @@ -0,0 +1,62 @@ +importScripts('/resources/testharness.js'); + +promise_test(function(test) { + var durationMsec = 100; + // There are limits to our accuracy here. Timers may fire up to a + // millisecond early due to platform-dependent rounding. In addition + // the performance API introduces some rounding as well to prevent + // timing attacks. + var accuracy = 1.5; + return new Promise(function(resolve) { + performance.mark('startMark'); + setTimeout(resolve, durationMsec); + }).then(function() { + performance.mark('endMark'); + performance.measure('measure', 'startMark', 'endMark'); + var startMark = performance.getEntriesByName('startMark')[0]; + var endMark = performance.getEntriesByName('endMark')[0]; + var measure = performance.getEntriesByType('measure')[0]; + assert_equals(measure.startTime, startMark.startTime); + assert_approx_equals(endMark.startTime - startMark.startTime, + measure.duration, 0.001); + assert_greater_than(measure.duration, durationMsec - accuracy); + assert_equals(performance.getEntriesByType('mark').length, 2); + assert_equals(performance.getEntriesByType('measure').length, 1); + performance.clearMarks('startMark'); + performance.clearMeasures('measure'); + assert_equals(performance.getEntriesByType('mark').length, 1); + assert_equals(performance.getEntriesByType('measure').length, 0); + }); + }, 'User Timing'); + +promise_test(function(test) { + return fetch('sample.txt') + .then(function(resp) { + return resp.text(); + }) + .then(function(text) { + var expectedResources = ['testharness.js', 'sample.txt']; + assert_equals(performance.getEntriesByType('resource').length, expectedResources.length); + for (var i = 0; i < expectedResources.length; i++) { + var entry = performance.getEntriesByType('resource')[i]; + assert_true(entry.name.endsWith(expectedResources[i])); + assert_equals(entry.workerStart, 0); + assert_greater_than(entry.startTime, 0); + assert_greater_than(entry.responseEnd, entry.startTime); + } + return new Promise(function(resolve) { + performance.onresourcetimingbufferfull = _ => { + resolve('bufferfull'); + } + performance.setResourceTimingBufferSize(expectedResources.length); + fetch('sample.txt'); + }); + }) + .then(function(result) { + assert_equals(result, 'bufferfull'); + performance.clearResourceTimings(); + assert_equals(performance.getEntriesByType('resource').length, 0); + }) + }, 'Resource Timing'); + +done(); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/postmessage-blob-url.js b/test/fixtures/wpt/service-workers/service-worker/resources/postmessage-blob-url.js new file mode 100644 index 000000000000..9095194a4c03 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/postmessage-blob-url.js @@ -0,0 +1,5 @@ +self.onmessage = e => { + fetch(e.data) + .then(response => response.text()) + .then(text => e.source.postMessage('Worker reply:' + text)); +}; diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/postmessage-dictionary-transferables-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/postmessage-dictionary-transferables-worker.js new file mode 100644 index 000000000000..87a4500d754a --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/postmessage-dictionary-transferables-worker.js @@ -0,0 +1,24 @@ +var messageHandler = function(port, e) { + var text_decoder = new TextDecoder; + port.postMessage({ + content: text_decoder.decode(e.data), + byteLength: e.data.byteLength + }); + + // Send back the array buffer via Client.postMessage. + port.postMessage(e.data, {transfer: [e.data.buffer]}); + + port.postMessage({ + content: text_decoder.decode(e.data), + byteLength: e.data.byteLength + }); +}; + +self.addEventListener('message', e => { + if (e.ports[0]) { + // Wait for messages sent via MessagePort. + e.ports[0].onmessage = messageHandler.bind(null, e.ports[0]); + return; + } + messageHandler(e.source, e); + }); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/postmessage-echo-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/postmessage-echo-worker.js new file mode 100644 index 000000000000..f088ad127804 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/postmessage-echo-worker.js @@ -0,0 +1,3 @@ +self.addEventListener('message', event => { + event.source.postMessage(event.data); +}); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/postmessage-fetched-text.js b/test/fixtures/wpt/service-workers/service-worker/resources/postmessage-fetched-text.js new file mode 100644 index 000000000000..9fc67171d05d --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/postmessage-fetched-text.js @@ -0,0 +1,5 @@ +self.onmessage = async (e) => { + const response = await fetch(e.data); + const text = await response.text(); + self.postMessage(text); +}; diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/postmessage-msgport-to-client-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/postmessage-msgport-to-client-worker.js new file mode 100644 index 000000000000..7af935f4f8fc --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/postmessage-msgport-to-client-worker.js @@ -0,0 +1,19 @@ +self.onmessage = function(e) { + e.waitUntil(self.clients.matchAll().then(function(clients) { + clients.forEach(function(client) { + var messageChannel = new MessageChannel(); + messageChannel.port1.onmessage = + onMessageViaMessagePort.bind(null, messageChannel.port1); + client.postMessage(undefined, [messageChannel.port2]); + }); + })); +}; + +function onMessageViaMessagePort(port, e) { + var message = e.data; + if ('value' in message) { + port.postMessage({ack: 'Acking value: ' + message.value}); + } else if ('done' in message) { + port.postMessage({done: true}); + } +} diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/postmessage-on-load-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/postmessage-on-load-worker.js new file mode 100644 index 000000000000..c2b0bcb8bfb0 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/postmessage-on-load-worker.js @@ -0,0 +1,9 @@ +if ('DedicatedWorkerGlobalScope' in self && + self instanceof DedicatedWorkerGlobalScope) { + postMessage('dedicated worker script loaded'); +} else if ('SharedWorkerGlobalScope' in self && + self instanceof SharedWorkerGlobalScope) { + self.onconnect = evt => { + evt.ports[0].postMessage('shared worker script loaded'); + }; +} diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/postmessage-to-client-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/postmessage-to-client-worker.js new file mode 100644 index 000000000000..17913063583a --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/postmessage-to-client-worker.js @@ -0,0 +1,10 @@ +self.onmessage = function(e) { + e.waitUntil(self.clients.matchAll().then(function(clients) { + clients.forEach(function(client) { + client.postMessage('Sending message via clients'); + if (!Array.isArray(clients)) + client.postMessage('clients is not an array'); + client.postMessage('quit'); + }); + })); +}; diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/postmessage-transferables-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/postmessage-transferables-worker.js new file mode 100644 index 000000000000..d35c1c952b88 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/postmessage-transferables-worker.js @@ -0,0 +1,24 @@ +var messageHandler = function(port, e) { + var text_decoder = new TextDecoder; + port.postMessage({ + content: text_decoder.decode(e.data), + byteLength: e.data.byteLength + }); + + // Send back the array buffer via Client.postMessage. + port.postMessage(e.data, [e.data.buffer]); + + port.postMessage({ + content: text_decoder.decode(e.data), + byteLength: e.data.byteLength + }); +}; + +self.addEventListener('message', e => { + if (e.ports[0]) { + // Wait for messages sent via MessagePort. + e.ports[0].onmessage = messageHandler.bind(null, e.ports[0]); + return; + } + messageHandler(e.source, e); + }); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/postmessage-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/postmessage-worker.js new file mode 100644 index 000000000000..858cf04267c2 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/postmessage-worker.js @@ -0,0 +1,19 @@ +var port; + +// Exercise the 'onmessage' handler: +self.onmessage = function(e) { + var message = e.data; + if ('port' in message) { + port = message.port; + } +}; + +// And an event listener: +self.addEventListener('message', function(e) { + var message = e.data; + if ('value' in message) { + port.postMessage('Acking value: ' + message.value); + } else if ('done' in message) { + port.postMessage('quit'); + } + }); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/range-request-to-different-origins-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/range-request-to-different-origins-worker.js new file mode 100644 index 000000000000..cab605833905 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/range-request-to-different-origins-worker.js @@ -0,0 +1,40 @@ +// This worker is meant to test range requests where the responses come from +// multiple origins. It forwards the first request to a cross-origin URL +// (generating an opaque response). The server is expected to return a 206 +// Partial Content response. Then the worker lets subsequent range requests +// fall back to network (generating same-origin responses). The intent is to try +// to trick the browser into treating the resource as same-origin. +// +// It would also be interesting to do the reverse test where the first request +// goes to the same-origin URL, and subsequent range requests go cross-origin in +// 'no-cors' mode to receive opaque responses. But the service worker cannot do +// this, because in 'no-cors' mode the 'range' HTTP header is disallowed. + +importScripts('/common/get-host-info.sub.js') + +let initial = true; +function is_initial_request() { + const old = initial; + initial = false; + return old; +} + +self.addEventListener('fetch', e => { + const url = new URL(e.request.url); + if (url.search.indexOf('VIDEO') == -1) { + // Fall back for non-video. + return; + } + + // Make the first request go cross-origin. + if (is_initial_request()) { + const cross_origin_url = get_host_info().HTTPS_REMOTE_ORIGIN + + url.pathname + url.search; + const cross_origin_request = new Request(cross_origin_url, + {mode: 'no-cors', headers: e.request.headers}); + e.respondWith(fetch(cross_origin_request)); + return; + } + + // Fall back to same origin for subsequent range requests. + }); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/range-request-with-different-cors-modes-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/range-request-with-different-cors-modes-worker.js new file mode 100644 index 000000000000..7580b0b68a95 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/range-request-with-different-cors-modes-worker.js @@ -0,0 +1,60 @@ +// This worker is meant to test range requests where the responses are a mix of +// opaque ones and non-opaque ones. It forwards the first request to a +// cross-origin URL (generating an opaque response). The server is expected to +// return a 206 Partial Content response. Then the worker forwards subsequent +// range requests to that URL, with CORS sharing generating a non-opaque +// responses. The intent is to try to trick the browser into treating the +// resource as non-opaque. +// +// It would also be interesting to do the reverse test where the first request +// uses 'cors', and subsequent range requests use 'no-cors' mode. But the +// service worker cannot do this, because in 'no-cors' mode the 'range' HTTP +// header is disallowed. + +importScripts('/common/get-host-info.sub.js') + +let initial = true; +function is_initial_request() { + const old = initial; + initial = false; + return old; +} + +self.addEventListener('fetch', e => { + const url = new URL(e.request.url); + if (url.search.indexOf('VIDEO') == -1) { + // Fall back for non-video. + return; + } + + let cross_origin_url = get_host_info().HTTPS_REMOTE_ORIGIN + + url.pathname + url.search; + + // The first request is no-cors. + if (is_initial_request()) { + const init = { mode: 'no-cors', headers: e.request.headers }; + const cross_origin_request = new Request(cross_origin_url, init); + e.respondWith(fetch(cross_origin_request)); + return; + } + + // Subsequent range requests are cors. + + // Copy headers needed for range requests. + let my_headers = new Headers; + if (e.request.headers.get('accept')) + my_headers.append('accept', e.request.headers.get('accept')); + if (e.request.headers.get('range')) + my_headers.append('range', e.request.headers.get('range')); + + // Add &ACAOrigin to allow CORS. + cross_origin_url += '&ACAOrigin=' + get_host_info().HTTPS_ORIGIN; + // Add &ACAHeaders to allow range requests. + cross_origin_url += '&ACAHeaders=accept,range'; + + // Make the CORS request. + const init = { mode: 'cors', headers: my_headers }; + const cross_origin_request = new Request(cross_origin_url, init); + e.respondWith(fetch(cross_origin_request)); + }); + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/range-request-with-synth-head-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/range-request-with-synth-head-worker.js new file mode 100644 index 000000000000..6b6395aecaef --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/range-request-with-synth-head-worker.js @@ -0,0 +1,36 @@ +// This worker is meant to test range requests where the initial response +// synthesizes a 206 Partial Content response with leading bytes. +// Then the worker lets subsequent range requests fall back to network. + +let initial = true; +function is_initial_request() { + const old = initial; + initial = false; + return old; +} + +self.addEventListener('fetch', e => { + const url = new URL(e.request.url); + if (url.search.indexOf('VIDEO') == -1) { + // Fall back for non-video. + return; + } + + // Synthesize the response to the first request. + if (is_initial_request()) { + // Consistent with fetch-access-control.py?VIDEO + const init = { + status: 206, + headers: { + "Accept-Ranges": "bytes", + "Content-Type": "video/webm", + "Content-Range": "bytes 0-1/*", + "Content-Length": "2", + }, + }; + e.respondWith(new Response(new Uint8Array([0x1a, 0x45]), init)); + return; + } + + // Fall back for subsequent range requests. + }); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/redirect-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/redirect-worker.js new file mode 100644 index 000000000000..82e21fc26fdb --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/redirect-worker.js @@ -0,0 +1,145 @@ +// We store an empty response for each fetch event request we see +// in this Cache object so we can get the list of urls in the +// message event. +var cacheName = 'urls-' + self.registration.scope; + +var waitUntilPromiseList = []; + +// Sends the requests seen by this worker. The output is: +// { +// requestInfos: [ +// {url: url1, resultingClientId: id1}, +// {url: url2, resultingClientId: id2}, +// ] +// } +async function getRequestInfos(event) { + // Wait for fetch events to finish. + await Promise.all(waitUntilPromiseList); + waitUntilPromiseList = []; + + // Generate the message. + const cache = await caches.open(cacheName); + const requestList = await cache.keys(); + const requestInfos = []; + for (let i = 0; i < requestList.length; i++) { + const response = await cache.match(requestList[i]); + const body = await response.json(); + requestInfos[i] = { + url: requestList[i].url, + resultingClientId: body.resultingClientId + }; + } + await caches.delete(cacheName); + + event.data.port.postMessage({requestInfos}); +} + +// Sends the results of clients.get(id) from this worker. The +// input is: +// { +// actual_ids: {a: id1, b: id2, x: id3} +// } +// +// The output is: +// { +// clients: { +// a: {found: false}, +// b: {found: false}, +// x: { +// id: id3, +// url: url1, +// found: true +// } +// } +// } +async function getClients(event) { + // |actual_ids| is like: + // {a: id1, b: id2, x: id3} + const actual_ids = event.data.actual_ids; + const result = {} + for (let key of Object.keys(actual_ids)) { + const id = actual_ids[key]; + const client = await self.clients.get(id); + if (client === undefined) + result[key] = {found: false}; + else + result[key] = {found: true, url: client.url, id: client.id}; + } + event.data.port.postMessage({clients: result}); +} + +self.addEventListener('message', async function(event) { + if (event.data.command == 'getRequestInfos') { + event.waitUntil(getRequestInfos(event)); + return; + } + + if (event.data.command == 'getClients') { + event.waitUntil(getClients(event)); + return; + } +}); + +function get_query_params(url) { + var search = (new URL(url)).search; + if (!search) { + return {}; + } + var ret = {}; + var params = search.substring(1).split('&'); + params.forEach(function(param) { + var element = param.split('='); + ret[decodeURIComponent(element[0])] = decodeURIComponent(element[1]); + }); + return ret; +} + +self.addEventListener('fetch', function(event) { + var waitUntilPromise = caches.open(cacheName).then(function(cache) { + const responseBody = {}; + responseBody['resultingClientId'] = event.resultingClientId; + const headers = new Headers({'Content-Type': 'application/json'}); + const response = new Response(JSON.stringify(responseBody), {headers}); + return cache.put(event.request, response); + }); + event.waitUntil(waitUntilPromise); + + var params = get_query_params(event.request.url); + if (!params['sw']) { + // To avoid races, add the waitUntil() promise to our global list. + // If we get a message event before we finish here, it will wait + // these promises to complete before proceeding to read from the + // cache. + waitUntilPromiseList.push(waitUntilPromise); + return; + } + + event.respondWith(waitUntilPromise.then(async () => { + if (params['sw'] == 'gen') { + return Response.redirect(params['url']); + } else if (params['sw'] == 'gen-manual') { + // Note this differs from Response.redirect() in that relative URLs are + // preserved. + return new Response("", { + status: 301, + headers: {location: params['url']}, + }); + } else if (params['sw'] == 'fetch') { + return fetch(event.request); + } else if (params['sw'] == 'fetch-url') { + return fetch(params['url']); + } else if (params['sw'] == 'follow') { + return fetch(new Request(event.request.url, {redirect: 'follow'})); + } else if (params['sw'] == 'manual') { + return fetch(new Request(event.request.url, {redirect: 'manual'})); + } else if (params['sw'] == 'manualThroughCache') { + const url = event.request.url; + await caches.delete(url) + const cache = await self.caches.open(url); + const response = await fetch(new Request(url, {redirect: 'manual'})); + await cache.put(event.request, response); + return cache.match(url); + } + // unexpected... trigger an interception failure + })); + }); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/referer-iframe.html b/test/fixtures/wpt/service-workers/service-worker/resources/referer-iframe.html new file mode 100644 index 000000000000..295ff4567154 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/referer-iframe.html @@ -0,0 +1,39 @@ + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/referrer-policy-iframe.html b/test/fixtures/wpt/service-workers/service-worker/resources/referrer-policy-iframe.html new file mode 100644 index 000000000000..9ef3cd19a982 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/referrer-policy-iframe.html @@ -0,0 +1,32 @@ + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/register-closed-window-iframe.html b/test/fixtures/wpt/service-workers/service-worker/resources/register-closed-window-iframe.html new file mode 100644 index 000000000000..bd386574e2c5 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/register-closed-window-iframe.html @@ -0,0 +1,23 @@ + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/register-iframe.html b/test/fixtures/wpt/service-workers/service-worker/resources/register-iframe.html new file mode 100644 index 000000000000..f5a040e41d96 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/register-iframe.html @@ -0,0 +1,4 @@ + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/register-rewrite-worker.html b/test/fixtures/wpt/service-workers/service-worker/resources/register-rewrite-worker.html new file mode 100644 index 000000000000..bf06317ad9e3 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/register-rewrite-worker.html @@ -0,0 +1,32 @@ + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/register-static-router-iframe.html b/test/fixtures/wpt/service-workers/service-worker/resources/register-static-router-iframe.html new file mode 100644 index 000000000000..f23353af9cf9 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/register-static-router-iframe.html @@ -0,0 +1,35 @@ + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/registration-tests-mime-types.js b/test/fixtures/wpt/service-workers/service-worker/resources/registration-tests-mime-types.js new file mode 100644 index 000000000000..7a64cd91e411 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/registration-tests-mime-types.js @@ -0,0 +1,122 @@ +// Registration tests that mostly verify the MIME type. +// +// This file tests every MIME type so it necessarily starts many service +// workers, so it may be slow. +function registration_tests_mime_types(register_method) { + promise_test(function(t) { + var script = 'resources/mime-type-worker.py'; + var scope = 'resources/scope/no-mime-type-worker/'; + return promise_rejects_dom(t, + 'SecurityError', + register_method(script, {scope: scope}), + 'Registration of no MIME type script should fail.'); + }, 'Registering script with no MIME type'); + + promise_test(function(t) { + var script = 'resources/mime-type-worker.py?mime=text/plain'; + var scope = 'resources/scope/bad-mime-type-worker/'; + return promise_rejects_dom(t, + 'SecurityError', + register_method(script, {scope: scope}), + 'Registration of plain text script should fail.'); + }, 'Registering script with bad MIME type'); + + // The top-level service worker script must have a JavaScript MIME type. A + // JSON MIME type is only valid for imported (non-top-level) modules, so + // registering a top-level script served as JSON must fail even when the body + // happens to be valid JavaScript. + const jsonMimeTypes = [ + 'application/json', + 'text/json', + 'application/manifest+json', + ]; + + for (const jsonMimeType of jsonMimeTypes) { + promise_test(function(t) { + // Encode the MIME type so characters such as '+' survive the query + // string instead of being decoded to a space by the server. + var script = + `resources/mime-type-worker.py?mime=${encodeURIComponent(jsonMimeType)}`; + // Use a scope unique to each MIME type so the registrations don't + // interfere with one another. + var scope = `resources/scope/json-mime-type-worker/${jsonMimeType}`; + return promise_rejects_dom(t, + 'SecurityError', + register_method(script, {scope: scope}), + 'Registration of JSON MIME type script should fail.'); + }, `Registering script with JSON MIME type ${jsonMimeType}`); + } + + /** + * ServiceWorkerContainer.register() should throw a TypeError, according to + * step 17.1 of https://w3c.github.io/ServiceWorker/#importscripts + * + * "[17] If an uncaught runtime script error occurs during the above step, then: + * [17.1] Invoke Reject Job Promise with job and TypeError" + * + * (Where the "uncaught runtime script error" is thrown by an unsuccessful + * importScripts()) + */ + promise_test(function(t) { + var script = 'resources/import-mime-type-worker.py'; + var scope = 'resources/scope/no-mime-type-worker/'; + return promise_rejects_js(t, + TypeError, + register_method(script, {scope: scope}), + 'Registration of no MIME type imported script should fail.'); + }, 'Registering script that imports script with no MIME type'); + + promise_test(function(t) { + var script = 'resources/import-mime-type-worker.py?mime=text/plain'; + var scope = 'resources/scope/bad-mime-type-worker/'; + return promise_rejects_js(t, + TypeError, + register_method(script, {scope: scope}), + 'Registration of plain text imported script should fail.'); + }, 'Registering script that imports script with bad MIME type'); + + const validMimeTypes = [ + 'application/ecmascript', + 'application/javascript', + 'application/x-ecmascript', + 'application/x-javascript', + 'text/ecmascript', + 'text/javascript', + 'text/javascript1.0', + 'text/javascript1.1', + 'text/javascript1.2', + 'text/javascript1.3', + 'text/javascript1.4', + 'text/javascript1.5', + 'text/jscript', + 'text/livescript', + 'text/x-ecmascript', + 'text/x-javascript' + ]; + + for (const validMimeType of validMimeTypes) { + promise_test(() => { + var script = `resources/mime-type-worker.py?mime=${validMimeType}`; + var scope = 'resources/scope/good-mime-type-worker/'; + + return register_method(script, {scope}).then(registration => { + assert_true( + registration instanceof ServiceWorkerRegistration, + 'Successfully registered.'); + return registration.unregister(); + }); + }, `Registering script with good MIME type ${validMimeType}`); + + promise_test(() => { + var script = `resources/import-mime-type-worker.py?mime=${validMimeType}`; + var scope = 'resources/scope/good-mime-type-worker/'; + + return register_method(script, { scope }).then(registration => { + assert_true( + registration instanceof ServiceWorkerRegistration, + 'Successfully registered.'); + return registration.unregister(); + }); + }, `Registering script that imports script with good MIME type ${validMimeType}`); + } +} diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/registration-tests-scope.js b/test/fixtures/wpt/service-workers/service-worker/resources/registration-tests-scope.js new file mode 100644 index 000000000000..30c424b2b423 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/registration-tests-scope.js @@ -0,0 +1,120 @@ +// Registration tests that mostly exercise the scope option. +function registration_tests_scope(register_method) { + promise_test(function(t) { + var script = 'resources/empty-worker.js'; + var scope = 'resources/scope%2fencoded-slash-in-scope'; + return promise_rejects_js(t, + TypeError, + register_method(script, {scope: scope}), + 'URL-encoded slash in the scope should be rejected.'); + }, 'Scope including URL-encoded slash'); + + promise_test(function(t) { + var script = 'resources/empty-worker.js'; + var scope = 'resources/scope%5cencoded-slash-in-scope'; + return promise_rejects_js(t, + TypeError, + register_method(script, {scope: scope}), + 'URL-encoded backslash in the scope should be rejected.'); + }, 'Scope including URL-encoded backslash'); + + promise_test(function(t) { + var script = 'resources/empty-worker.js'; + var scope = 'data:text/html,'; + return promise_rejects_js(t, + TypeError, + register_method(script, {scope: scope}), + 'scope URL scheme is not "http" or "https"'); + }, 'Scope URL scheme is a data: URL'); + + promise_test(function(t) { + var script = 'resources/empty-worker.js'; + var scope = new URL('resources', location).href.replace('https:', 'ftp:'); + return promise_rejects_js(t, + TypeError, + register_method(script, {scope: scope}), + 'scope URL scheme is not "http" or "https"'); + }, 'Scope URL scheme is an ftp: URL'); + + promise_test(function(t) { + // URL-encoded full-width 'scope'. + var name = '%ef%bd%93%ef%bd%83%ef%bd%8f%ef%bd%90%ef%bd%85'; + var script = 'resources/empty-worker.js'; + var scope = 'resources/' + name + '/escaped-multibyte-character-scope'; + return register_method(script, {scope: scope}) + .then(function(registration) { + assert_equals( + registration.scope, + normalizeURL(scope), + 'URL-encoded multibyte characters should be available.'); + return registration.unregister(); + }); + }, 'Scope including URL-encoded multibyte characters'); + + promise_test(function(t) { + // Non-URL-encoded full-width "scope". + var name = String.fromCodePoint(0xff53, 0xff43, 0xff4f, 0xff50, 0xff45); + var script = 'resources/empty-worker.js'; + var scope = 'resources/' + name + '/non-escaped-multibyte-character-scope'; + return register_method(script, {scope: scope}) + .then(function(registration) { + assert_equals( + registration.scope, + normalizeURL(scope), + 'Non-URL-encoded multibyte characters should be available.'); + return registration.unregister(); + }); + }, 'Scope including non-escaped multibyte characters'); + + promise_test(function(t) { + var script = 'resources/empty-worker.js'; + var scope = 'resources/././scope/self-reference-in-scope'; + return register_method(script, {scope: scope}) + .then(function(registration) { + assert_equals( + registration.scope, + normalizeURL('resources/scope/self-reference-in-scope'), + 'Scope including self-reference should be normalized.'); + return registration.unregister(); + }); + }, 'Scope including self-reference'); + + promise_test(function(t) { + var script = 'resources/empty-worker.js'; + var scope = 'resources/../resources/scope/parent-reference-in-scope'; + return register_method(script, {scope: scope}) + .then(function(registration) { + assert_equals( + registration.scope, + normalizeURL('resources/scope/parent-reference-in-scope'), + 'Scope including parent-reference should be normalized.'); + return registration.unregister(); + }); + }, 'Scope including parent-reference'); + + promise_test(function(t) { + var script = 'resources/empty-worker.js'; + var scope = 'resources/scope////consecutive-slashes-in-scope'; + return register_method(script, {scope: scope}) + .then(function(registration) { + // Although consecutive slashes in the scope are not unified, the + // scope is under the script directory and registration should + // succeed. + assert_equals( + registration.scope, + normalizeURL(scope), + 'Should successfully be registered.'); + return registration.unregister(); + }) + }, 'Scope including consecutive slashes'); + + promise_test(function(t) { + var script = 'resources/empty-worker.js'; + var scope = 'filesystem:' + normalizeURL('resources/scope/filesystem-scope-url'); + return promise_rejects_js(t, + TypeError, + register_method(script, {scope: scope}), + 'Registering with the scope that has same-origin filesystem: URL ' + + 'should fail with TypeError.'); + }, 'Scope URL is same-origin filesystem: URL'); +} diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/registration-tests-script-url.js b/test/fixtures/wpt/service-workers/service-worker/resources/registration-tests-script-url.js new file mode 100644 index 000000000000..55cbe6fa9594 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/registration-tests-script-url.js @@ -0,0 +1,82 @@ +// Registration tests that mostly exercise the scriptURL parameter. +function registration_tests_script_url(register_method) { + promise_test(function(t) { + var script = 'resources%2fempty-worker.js'; + var scope = 'resources/scope/encoded-slash-in-script-url'; + return promise_rejects_js(t, + TypeError, + register_method(script, {scope: scope}), + 'URL-encoded slash in the script URL should be rejected.'); + }, 'Script URL including URL-encoded slash'); + + promise_test(function(t) { + var script = 'resources%2Fempty-worker.js'; + var scope = 'resources/scope/encoded-slash-in-script-url'; + return promise_rejects_js(t, + TypeError, + register_method(script, {scope: scope}), + 'URL-encoded slash in the script URL should be rejected.'); + }, 'Script URL including uppercase URL-encoded slash'); + + promise_test(function(t) { + var script = 'resources%5cempty-worker.js'; + var scope = 'resources/scope/encoded-slash-in-script-url'; + return promise_rejects_js(t, + TypeError, + register_method(script, {scope: scope}), + 'URL-encoded backslash in the script URL should be rejected.'); + }, 'Script URL including URL-encoded backslash'); + + promise_test(function(t) { + var script = 'resources%5Cempty-worker.js'; + var scope = 'resources/scope/encoded-slash-in-script-url'; + return promise_rejects_js(t, + TypeError, + register_method(script, {scope: scope}), + 'URL-encoded backslash in the script URL should be rejected.'); + }, 'Script URL including uppercase URL-encoded backslash'); + + promise_test(function(t) { + var script = 'data:application/javascript,'; + var scope = 'resources/scope/data-url-in-script-url'; + return promise_rejects_js(t, + TypeError, + register_method(script, {scope: scope}), + 'Data URLs should not be registered as service workers.'); + }, 'Script URL is a data URL'); + + promise_test(function(t) { + var script = 'data:application/javascript,'; + var scope = new URL('resources/scope/data-url-in-script-url', location); + return promise_rejects_js(t, + TypeError, + register_method(script, {scope: scope}), + 'Data URLs should not be registered as service workers.'); + }, 'Script URL is a data URL and scope URL is not relative'); + + promise_test(function(t) { + var script = 'resources/././empty-worker.js'; + var scope = 'resources/scope/parent-reference-in-script-url'; + return register_method(script, {scope: scope}) + .then(function(registration) { + assert_equals( + get_newest_worker(registration).scriptURL, + normalizeURL('resources/empty-worker.js'), + 'Script URL including self-reference should be normalized.'); + return registration.unregister(); + }); + }, 'Script URL including self-reference'); + + promise_test(function(t) { + var script = 'resources/../resources/empty-worker.js'; + var scope = 'resources/scope/parent-reference-in-script-url'; + return register_method(script, {scope: scope}) + .then(function(registration) { + assert_equals( + get_newest_worker(registration).scriptURL, + normalizeURL('resources/empty-worker.js'), + 'Script URL including parent-reference should be normalized.'); + return registration.unregister(); + }); + }, 'Script URL including parent-reference'); +} diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/registration-tests-script.js b/test/fixtures/wpt/service-workers/service-worker/resources/registration-tests-script.js new file mode 100644 index 000000000000..a74cab8e3ace --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/registration-tests-script.js @@ -0,0 +1,121 @@ +// Registration tests that mostly exercise the service worker script contents or +// response. +function registration_tests_script(register_method, type) { + promise_test(function(t) { + var script = 'resources/invalid-chunked-encoding.py'; + var scope = 'resources/scope/invalid-chunked-encoding/'; + return promise_rejects_js(t, + TypeError, + register_method(script, {scope: scope}), + 'Registration of invalid chunked encoding script should fail.'); + }, 'Registering invalid chunked encoding script'); + + promise_test(function(t) { + var script = 'resources/invalid-chunked-encoding-with-flush.py'; + var scope = 'resources/scope/invalid-chunked-encoding-with-flush/'; + return promise_rejects_js(t, + TypeError, + register_method(script, {scope: scope}), + 'Registration of invalid chunked encoding script should fail.'); + }, 'Registering invalid chunked encoding script with flush'); + + promise_test(function(t) { + var script = 'resources/malformed-worker.py?parse-error'; + var scope = 'resources/scope/parse-error'; + return promise_rejects_js(t, + TypeError, + register_method(script, {scope: scope}), + 'Registration of script including parse error should fail.'); + }, 'Registering script including parse error'); + + promise_test(function(t) { + var script = 'resources/malformed-worker.py?undefined-error'; + var scope = `resources/scope/undefined-error/${type}`; + return promise_rejects_js(t, + TypeError, + register_method(script, {scope: scope}), + 'Registration of script including undefined error should fail.'); + }, `Registering script including undefined error: ${type}`); + + promise_test(function(t) { + var script = 'resources/malformed-worker.py?uncaught-exception'; + var scope = `resources/scope/uncaught-exception/${type}`; + return promise_rejects_js(t, + TypeError, + register_method(script, {scope: scope}), + 'Registration of script including uncaught exception should fail.'); + }, `Registering script including uncaught exception: ${type}`); + + if (type === 'classic') { + promise_test(function(t) { + var script = 'resources/malformed-worker.py?import-malformed-script'; + var scope = 'resources/scope/import-malformed-script'; + return promise_rejects_js(t, + TypeError, + register_method(script, {scope: scope}), + 'Registration of script importing malformed script should fail.'); + }, 'Registering script importing malformed script'); + } + + if (type === 'module') { + promise_test(function(t) { + var script = 'resources/malformed-worker.py?top-level-await'; + var scope = 'resources/scope/top-level-await'; + return promise_rejects_js(t, + TypeError, + register_method(script, {scope: scope}), + 'Registration of script with top-level await should fail.'); + }, 'Registering script with top-level await'); + + promise_test(function(t) { + var script = 'resources/malformed-worker.py?instantiation-error'; + var scope = 'resources/scope/instantiation-error'; + return promise_rejects_js(t, + TypeError, + register_method(script, {scope: scope}), + 'Registration of script with module instantiation error should fail.'); + }, 'Registering script with module instantiation error'); + + promise_test(function(t) { + var script = 'resources/malformed-worker.py?instantiation-error-and-top-level-await'; + var scope = 'resources/scope/instantiation-error-and-top-level-await'; + return promise_rejects_js(t, + TypeError, + register_method(script, {scope: scope}), + 'Registration of script with module instantiation error and top-level await should fail.'); + }, 'Registering script with module instantiation error and top-level await'); + } + + promise_test(function(t) { + var script = 'resources/no-such-worker.js'; + var scope = 'resources/scope/no-such-worker'; + return promise_rejects_js(t, + TypeError, + register_method(script, {scope: scope}), + 'Registration of non-existent script should fail.'); + }, 'Registering non-existent script'); + + if (type === 'classic') { + promise_test(function(t) { + var script = 'resources/malformed-worker.py?import-no-such-script'; + var scope = 'resources/scope/import-no-such-script'; + return promise_rejects_js(t, + TypeError, + register_method(script, {scope: scope}), + 'Registration of script importing non-existent script should fail.'); + }, 'Registering script importing non-existent script'); + } + + promise_test(function(t) { + var script = 'resources/malformed-worker.py?caught-exception'; + var scope = 'resources/scope/caught-exception'; + return register_method(script, {scope: scope}) + .then(function(registration) { + assert_true( + registration instanceof ServiceWorkerRegistration, + 'Successfully registered.'); + return registration.unregister(); + }); + }, 'Registering script including caught exception'); + +} diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/registration-tests-security-error.js b/test/fixtures/wpt/service-workers/service-worker/resources/registration-tests-security-error.js new file mode 100644 index 000000000000..c45fbd45789a --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/registration-tests-security-error.js @@ -0,0 +1,78 @@ +// Registration tests that mostly exercise SecurityError cases. +function registration_tests_security_error(register_method) { + promise_test(function(t) { + var script = 'resources/registration-worker.js'; + var scope = 'resources'; + return promise_rejects_dom(t, + 'SecurityError', + register_method(script, {scope: scope}), + 'Registering same scope as the script directory without the last ' + + 'slash should fail with SecurityError.'); + }, 'Registering same scope as the script directory without the last slash'); + + promise_test(function(t) { + var script = 'resources/registration-worker.js'; + var scope = 'different-directory/'; + return promise_rejects_dom(t, + 'SecurityError', + register_method(script, {scope: scope}), + 'Registration scope outside the script directory should fail ' + + 'with SecurityError.'); + }, 'Registration scope outside the script directory'); + + promise_test(function(t) { + var script = 'resources/registration-worker.js'; + var scope = 'http://example.com/'; + return promise_rejects_dom(t, + 'SecurityError', + register_method(script, {scope: scope}), + 'Registration scope outside domain should fail with SecurityError.'); + }, 'Registering scope outside domain'); + + promise_test(function(t) { + var script = 'http://example.com/worker.js'; + var scope = 'http://example.com/scope/'; + return promise_rejects_dom(t, + 'SecurityError', + register_method(script, {scope: scope}), + 'Registration script outside domain should fail with SecurityError.'); + }, 'Registering script outside domain'); + + promise_test(function(t) { + var script = 'resources/redirect.py?Redirect=' + + encodeURIComponent('/resources/registration-worker.js'); + var scope = 'resources/scope/redirect/'; + return promise_rejects_dom(t, + 'SecurityError', + register_method(script, {scope: scope}), + 'Registration of redirected script should fail.'); + }, 'Registering redirected script'); + + promise_test(function(t) { + var script = 'resources/empty-worker.js'; + var scope = 'resources/../scope/parent-reference-in-scope'; + return promise_rejects_dom(t, + 'SecurityError', + register_method(script, {scope: scope}), + 'Scope not under the script directory should be rejected.'); + }, 'Scope including parent-reference and not under the script directory'); + + promise_test(function(t) { + var script = 'resources////empty-worker.js'; + var scope = 'resources/scope/consecutive-slashes-in-script-url'; + return promise_rejects_dom(t, + 'SecurityError', + register_method(script, {scope: scope}), + 'Consecutive slashes in the script url should not be unified.'); + }, 'Script URL including consecutive slashes'); + + promise_test(function(t) { + var script = 'filesystem:' + normalizeURL('resources/empty-worker.js'); + var scope = 'resources/scope/filesystem-script-url'; + return promise_rejects_js(t, + TypeError, + register_method(script, {scope: scope}), + 'Registering a script which has same-origin filesystem: URL should ' + + 'fail with TypeError.'); + }, 'Script URL is same-origin filesystem: URL'); +} diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/registration-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/registration-worker.js new file mode 100644 index 000000000000..44d1d2774a24 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/registration-worker.js @@ -0,0 +1 @@ +// empty for now diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/reject-install-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/reject-install-worker.js new file mode 100644 index 000000000000..41f07fd5db81 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/reject-install-worker.js @@ -0,0 +1,3 @@ +self.oninstall = function(event) { + event.waitUntil(Promise.reject()); +}; diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/reply-to-message.html b/test/fixtures/wpt/service-workers/service-worker/resources/reply-to-message.html new file mode 100644 index 000000000000..8a70e2ad933e --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/reply-to-message.html @@ -0,0 +1,7 @@ + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/request-end-to-end-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/request-end-to-end-worker.js new file mode 100644 index 000000000000..6bd2b72137e5 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/request-end-to-end-worker.js @@ -0,0 +1,34 @@ +'use strict'; + +onfetch = function(e) { + var headers = {}; + for (var header of e.request.headers) { + var key = header[0], value = header[1]; + headers[key] = value; + } + var append_header_error = ''; + try { + e.request.headers.append('Test-Header', 'TestValue'); + } catch (error) { + append_header_error = error.name; + } + + var request_construct_error = ''; + try { + new Request(e.request, {method: 'GET'}); + } catch (error) { + request_construct_error = error.name; + } + + e.respondWith(new Response(JSON.stringify({ + url: e.request.url, + method: e.request.method, + referrer: e.request.referrer, + headers: headers, + mode: e.request.mode, + credentials: e.request.credentials, + redirect: e.request.redirect, + append_header_error: append_header_error, + request_construct_error: request_construct_error + }))); +}; diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/resource-timing-iframe.sub.html b/test/fixtures/wpt/service-workers/service-worker/resources/resource-timing-iframe.sub.html new file mode 100644 index 000000000000..ec4c726331d6 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/resource-timing-iframe.sub.html @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/resource-timing-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/resource-timing-worker.js new file mode 100644 index 000000000000..b74e8cd6a236 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/resource-timing-worker.js @@ -0,0 +1,12 @@ +self.addEventListener('fetch', function(event) { + if (event.request.url.indexOf('sample.js') != -1) { + event.respondWith(new Promise(resolve => { + // Slightly delay the response so we ensure we get a non-zero + // duration. + setTimeout(_ => resolve(new Response('// Empty javascript')), 50); + })); + } + else if (event.request.url.indexOf('missing.jpg?SWRespondsWithFetch') != -1) { + event.respondWith(fetch('sample.txt?SWFetched')); + } +}); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/respond-then-throw-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/respond-then-throw-worker.js new file mode 100644 index 000000000000..adb48de69e72 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/respond-then-throw-worker.js @@ -0,0 +1,40 @@ +var syncport = null; + +self.addEventListener('message', function(e) { + if ('port' in e.data) { + if (syncport) { + syncport(e.data.port); + } else { + syncport = e.data.port; + } + } +}); + +function sync() { + return new Promise(function(resolve) { + if (syncport) { + resolve(syncport); + } else { + syncport = resolve; + } + }).then(function(port) { + port.postMessage('SYNC'); + return new Promise(function(resolve) { + port.onmessage = function(e) { + if (e.data === 'ACK') { + resolve(); + } + } + }); + }); +} + + +self.addEventListener('fetch', function(event) { + // In Firefox the result would depend on a race between fetch handling + // and exception handling code. On the assumption that this might be a common + // design error, we explicitly allow the exception to be handled first. + event.respondWith(sync().then(() => new Response('intercepted'))); + + throw("error"); + }); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/respond-with-body-accessed-response-iframe.html b/test/fixtures/wpt/service-workers/service-worker/resources/respond-with-body-accessed-response-iframe.html new file mode 100644 index 000000000000..7be314879499 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/respond-with-body-accessed-response-iframe.html @@ -0,0 +1,20 @@ + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/respond-with-body-accessed-response-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/respond-with-body-accessed-response-worker.js new file mode 100644 index 000000000000..c602109bc683 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/respond-with-body-accessed-response-worker.js @@ -0,0 +1,93 @@ +importScripts('/common/get-host-info.sub.js'); +importScripts('test-helpers.sub.js'); + +function getQueryParams(url) { + var search = (new URL(url)).search; + if (!search) { + return {}; + } + var ret = {}; + var params = search.substring(1).split('&'); + params.forEach(function(param) { + var element = param.split('='); + ret[decodeURIComponent(element[0])] = decodeURIComponent(element[1]); + }); + return ret; +} + +function createResponse(params) { + if (params['type'] == 'basic') { + return fetch('respond-with-body-accessed-response.jsonp'); + } + if (params['type'] == 'opaque') { + return fetch(get_host_info()['HTTPS_REMOTE_ORIGIN'] + base_path() + + 'respond-with-body-accessed-response.jsonp', + {mode: 'no-cors'}); + } + if (params['type'] == 'default') { + return Promise.resolve(new Response('callback(\'OK\');')); + } + + return Promise.reject(new Error('unexpected type :' + params['type'])); +} + +function cloneResponseIfNeeded(params, response) { + if (params['clone'] == '1') { + return response.clone(); + } else if (params['clone'] == '2') { + response.clone(); + return response; + } + return response; +} + +function passThroughCacheIfNeeded(params, request, response) { + return new Promise(function(resolve) { + if (params['passThroughCache'] == 'true') { + var cache_name = request.url; + var cache; + self.caches.delete(cache_name) + .then(function() { + return self.caches.open(cache_name); + }) + .then(function(c) { + cache = c; + return cache.put(request, response); + }) + .then(function() { + return cache.match(request.url); + }) + .then(function(res) { + // Touch .body here to test the behavior after touching it. + res.body; + resolve(res); + }); + } else { + resolve(response); + } + }) +} + +self.addEventListener('fetch', function(event) { + if (event.request.url.indexOf('TestRequest') == -1) { + return; + } + var params = getQueryParams(event.request.url); + event.respondWith( + createResponse(params) + .then(function(response) { + // Touch .body here to test the behavior after touching it. + response.body; + return cloneResponseIfNeeded(params, response); + }) + .then(function(response) { + // Touch .body here to test the behavior after touching it. + response.body; + return passThroughCacheIfNeeded(params, event.request, response); + }) + .then(function(response) { + // Touch .body here to test the behavior after touching it. + response.body; + return response; + })); + }); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/respond-with-body-accessed-response.jsonp b/test/fixtures/wpt/service-workers/service-worker/resources/respond-with-body-accessed-response.jsonp new file mode 100644 index 000000000000..b9c28f51f90a --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/respond-with-body-accessed-response.jsonp @@ -0,0 +1 @@ +callback('OK'); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/router-rules.js b/test/fixtures/wpt/service-workers/service-worker/resources/router-rules.js new file mode 100644 index 000000000000..27462b6c1d74 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/router-rules.js @@ -0,0 +1,148 @@ +const TEST_CACHE_NAME = 'v1'; +// https://w3c.github.io/ServiceWorker/#check-router-registration-limit-algorithm +const CONDITION_MAX_RECURSION_DEPTH = 10; +const CONDITION_MAX_COUNT = 1024; + +const routerRules = { + 'condition-urlpattern-constructed-source-network': [{ + condition: {urlPattern: new URLPattern({pathname: '/**/direct.txt'})}, + source: 'network' + }], + 'condition-urlpattern-not-source-network': [{ + condition: {not: {urlPattern: new URLPattern({pathname: '/**/not.txt'})}}, + source: 'network' + }], + 'condition-urlpattern-constructed-match-all-source-cache': [ + {condition: {urlPattern: new URLPattern({})}, source: 'cache'}, + ], + 'condition-urlpattern-urlpatterncompatible-source-network': [ + {condition: {urlPattern: {pathname: '/**/direct.txt'}}, source: 'network'}, + ], + 'condition-urlpattern-string-source-network': [ + {condition: {urlPattern: '/**/direct.txt'}, source: 'network'}, + ], + 'condition-urlpattern-string-source-cache': [ + {condition: {urlPattern: '/**/cache.txt'}, source: 'cache'}, + ], + 'condition-urlpattern-string-source-cache-with-name': [ + {condition: {urlPattern: '/**/cache.txt'}, source: {cacheName: TEST_CACHE_NAME}}, + ], + 'condition-urlpattern-constructed-ignore-case-source-network': [{ + condition: { + urlPattern: + new URLPattern({pathname: '/**/DiReCT.TxT'}, {ignoreCase: true}) + }, + source: 'network' + }], + 'condition-urlpattern-constructed-respect-case-source-network': [{ + condition: {urlPattern: new URLPattern({pathname: '/**/DiReCT.TxT'})}, + source: 'network' + }], + 'condition-request-source-network': + [{condition: {requestMode: 'no-cors'}, source: 'network'}], + 'condition-request-navigate-source-cache': + [{condition: {requestMode: 'navigate'}, source: 'cache'}], + 'condition-request-method-get-network': + [{condition: {requestMethod: 'GET'}, source: 'network'}], + 'condition-request-method-post-network': + [{condition: {requestMethod: 'POST'}, source: 'network'}], + 'condition-request-method-put-network': + [{condition: {requestMethod: 'PUT'}, source: 'network'}], + 'condition-request-method-delete-network': + [{condition: {requestMethod: 'DELETE'}, source: 'network'}], + 'condition-lack-of-condition': [{ + source: 'network' + }], + 'condition-lack-of-source': [{ + condition: {requestMode: 'no-cors'}, + }], + 'condition-invalid-bytestring-request-method': [{ + condition: {requestMethod: String.fromCodePoint(0x3042)}, + source: 'network' + }], + 'condition-invalid-http-request-method': [{ + condition: {requestMethod: '(GET|POST)'}, + source: 'network' + }], + 'condition-forbidden-request-method': [{ + condition: {requestMethod: 'connect'}, + source: 'network' + }], + 'condition-invalid-or-condition-depth': (() => { + const addOrCondition = (depth) => { + if (depth > CONDITION_MAX_RECURSION_DEPTH + 1) { + return {urlPattern: '/foo'}; + } + return { + or: [addOrCondition(depth + 1)] + }; + }; + return {condition: addOrCondition(1), source: 'network'}; + })(), + 'condition-invalid-not-condition-depth': (() => { + const generateNotCondition = (depth) => { + if (depth > CONDITION_MAX_RECURSION_DEPTH + 1) { + return { + urlPattern: '/**/example.txt', + }; + } + return {not: generateNotCondition(depth + 1)}; + }; + return {condition: generateNotCondition(1), source: 'network'}; + })(), + 'condition-invalid-router-size': [...Array(CONDITION_MAX_COUNT + 1)].map((val, i) => { + return { + condition: {urlPattern: `/foo-${i}`}, + source: 'network' + }; + }), + 'condition-request-destination-script-network': + [{condition: {requestDestination: 'script'}, source: 'network'}], + 'condition-or-source-network': [{ + condition: { + or: [ + { + or: [{urlPattern: '/**/or-test/direct1.*??*'}], + }, + {urlPattern: '/**/or-test/direct2.*??*'} + ] + }, + source: 'network' + }], + 'condition-request-source-fetch-event': + [{condition: {requestMode: 'no-cors'}, source: 'fetch-event'}], + 'condition-urlpattern-string-source-fetch-event': + [{condition: {urlPattern: '/**/*'}, source: 'fetch-event'}], + 'multiple-router-rules': [ + { + condition: { + urlPattern: '/**/direct.txt', + }, + source: 'network' + }, + {condition: {urlPattern: '/**/direct.html'}, source: 'network'} + ], + 'condition-urlpattern-string-source-race-network-and-fetch-handler': [ + { + condition: {urlPattern: '/**/direct.py'}, + source: 'race-network-and-fetch-handler' + }, + ], + 'multiple-conditions-network': { + condition: { + urlPattern: new URLPattern({search: 'test'}), + requestMode: 'cors', + requestMethod: 'post', + }, + source: 'network' + }, + 'multiple-conditions-with-destination-network' : { + condition: { + urlPattern: new URLPattern({search: 'test'}), + requestDestination: 'style' + }, + source: 'network' + } +}; + +export {routerRules, TEST_CACHE_NAME as cacheName}; diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/sample-worker-interceptor.js b/test/fixtures/wpt/service-workers/service-worker/resources/sample-worker-interceptor.js new file mode 100644 index 000000000000..c06f8dd77b79 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/sample-worker-interceptor.js @@ -0,0 +1,62 @@ +importScripts('/common/get-host-info.sub.js'); + +const text = 'worker loading intercepted by service worker'; +const dedicated_worker_script = `postMessage('${text}');`; +const shared_worker_script = + `onconnect = evt => evt.ports[0].postMessage('${text}');`; + +let source; +let resolveDone; +let done = new Promise(resolve => resolveDone = resolve); + +// The page messages this worker to ask for the result. Keep the worker alive +// via waitUntil() until the result is sent. +self.addEventListener('message', event => { + source = event.data.port; + source.postMessage({id: event.source.id}); + source.onmessage = resolveDone; + event.waitUntil(done); +}); + +self.onfetch = event => { + const url = event.request.url; + const destination = event.request.destination; + + if (source) + source.postMessage({clientId:event.clientId, resultingClientId: event.resultingClientId}); + + // Request handler for a synthesized response. + if (url.indexOf('synthesized') != -1) { + let script_headers = new Headers({ "Content-Type": "text/javascript" }); + if (destination === 'worker') + event.respondWith(new Response(dedicated_worker_script, { 'headers': script_headers })); + else if (destination === 'sharedworker') + event.respondWith(new Response(shared_worker_script, { 'headers': script_headers })); + else + event.respondWith(new Response('Unexpected request! ' + destination)); + return; + } + + // Request handler for a same-origin response. + if (url.indexOf('same-origin') != -1) { + event.respondWith(fetch('postmessage-on-load-worker.js')); + return; + } + + // Request handler for a cross-origin response. + if (url.indexOf('cors') != -1) { + const filename = 'postmessage-on-load-worker.js'; + const path = (new URL(filename, self.location)).pathname; + let new_url = get_host_info()['HTTPS_REMOTE_ORIGIN'] + path; + let mode; + if (url.indexOf('no-cors') != -1) { + // Test no-cors mode. + mode = 'no-cors'; + } else { + // Test cors mode. + new_url += '?pipe=header(Access-Control-Allow-Origin,*)'; + mode = 'cors'; + } + event.respondWith(fetch(new_url, { mode: mode })); + } +}; diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/sample.html b/test/fixtures/wpt/service-workers/service-worker/resources/sample.html new file mode 100644 index 000000000000..12a179980df2 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/sample.html @@ -0,0 +1,2 @@ + +Hello world diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/sample.js b/test/fixtures/wpt/service-workers/service-worker/resources/sample.js new file mode 100644 index 000000000000..b8889db05d08 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/sample.js @@ -0,0 +1 @@ +var hello = "world"; diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/sample.txt b/test/fixtures/wpt/service-workers/service-worker/resources/sample.txt new file mode 100644 index 000000000000..802992c4220d --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/sample.txt @@ -0,0 +1 @@ +Hello world diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/sandboxed-iframe-fetch-event-iframe.html b/test/fixtures/wpt/service-workers/service-worker/resources/sandboxed-iframe-fetch-event-iframe.html new file mode 100644 index 000000000000..239fa7330371 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/sandboxed-iframe-fetch-event-iframe.html @@ -0,0 +1,63 @@ + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/sandboxed-iframe-fetch-event-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/sandboxed-iframe-fetch-event-worker.js new file mode 100644 index 000000000000..4035a8b19b90 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/sandboxed-iframe-fetch-event-worker.js @@ -0,0 +1,20 @@ +var requests = []; + +self.addEventListener('message', function(event) { + event.waitUntil(self.clients.matchAll() + .then(function(clients) { + var client_urls = []; + for(var client of clients){ + client_urls.push(client.url); + } + client_urls = client_urls.sort(); + event.data.port.postMessage( + {clients: client_urls, requests: requests}); + requests = []; + })); + }); + +self.addEventListener('fetch', function(event) { + requests.push(event.request.url); + event.respondWith(fetch(event.request)); + }); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/sandboxed-iframe-navigator-serviceworker-iframe.html b/test/fixtures/wpt/service-workers/service-worker/resources/sandboxed-iframe-navigator-serviceworker-iframe.html new file mode 100644 index 000000000000..1d682e47ef5e --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/sandboxed-iframe-navigator-serviceworker-iframe.html @@ -0,0 +1,25 @@ + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/scope1/module-worker-importing-redirect-to-scope2.js b/test/fixtures/wpt/service-workers/service-worker/resources/scope1/module-worker-importing-redirect-to-scope2.js new file mode 100644 index 000000000000..ae681ba30e0b --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/scope1/module-worker-importing-redirect-to-scope2.js @@ -0,0 +1 @@ +import * as module from './redirect.py?Redirect=/service-workers/service-worker/resources/scope2/imported-module-script.js'; diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/scope1/module-worker-importing-scope2.js b/test/fixtures/wpt/service-workers/service-worker/resources/scope1/module-worker-importing-scope2.js new file mode 100644 index 000000000000..e28505249c28 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/scope1/module-worker-importing-scope2.js @@ -0,0 +1 @@ +import * as module from '../scope2/imported-module-script.js'; diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/scope2/imported-module-script.js b/test/fixtures/wpt/service-workers/service-worker/resources/scope2/imported-module-script.js new file mode 100644 index 000000000000..a18e704a3c58 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/scope2/imported-module-script.js @@ -0,0 +1,4 @@ +export const imported = 'A module script.'; +onmessage = msg => { + msg.source.postMessage('pong'); +}; diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/scope2/simple.txt b/test/fixtures/wpt/service-workers/service-worker/resources/scope2/simple.txt new file mode 100644 index 000000000000..cd876676e85e --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/scope2/simple.txt @@ -0,0 +1 @@ +a simple text file (scope2/) diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/secure-context-service-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/secure-context-service-worker.js new file mode 100644 index 000000000000..5ba99f075362 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/secure-context-service-worker.js @@ -0,0 +1,21 @@ +self.addEventListener('fetch', event => { + let url = new URL(event.request.url); + if (url.pathname.indexOf('sender.html') != -1) { + event.respondWith(new Response( + "", + { headers: { 'Content-Type': 'text/html'} } + )); + } else if (url.pathname.indexOf('report') != -1) { + self.clients.matchAll().then(clients => { + for (client of clients) { + client.postMessage(url.searchParams.get('result')); + } + }); + event.respondWith( + new Response( + '', + { headers: { 'Content-Type': 'text/html'} } + ) + ); + } +}); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/secure-context/sender.html b/test/fixtures/wpt/service-workers/service-worker/resources/secure-context/sender.html new file mode 100644 index 000000000000..05e58822a862 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/secure-context/sender.html @@ -0,0 +1 @@ + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/secure-context/window.html b/test/fixtures/wpt/service-workers/service-worker/resources/secure-context/window.html new file mode 100644 index 000000000000..071a507cb33e --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/secure-context/window.html @@ -0,0 +1,15 @@ + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/service-worker-interception-dynamic-import-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/service-worker-interception-dynamic-import-worker.js new file mode 100644 index 000000000000..680e07ff588c --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/service-worker-interception-dynamic-import-worker.js @@ -0,0 +1 @@ +import('./service-worker-interception-network-worker.js'); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/service-worker-interception-network-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/service-worker-interception-network-worker.js new file mode 100644 index 000000000000..5ff390010134 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/service-worker-interception-network-worker.js @@ -0,0 +1 @@ +postMessage('LOADED_FROM_NETWORK'); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/service-worker-interception-service-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/service-worker-interception-service-worker.js new file mode 100644 index 000000000000..6b43a3769637 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/service-worker-interception-service-worker.js @@ -0,0 +1,9 @@ +const kURL = '/service-worker-interception-network-worker.js'; +const kScript = 'postMessage("LOADED_FROM_SERVICE_WORKER")'; +const kHeaders = [['content-type', 'text/javascript']]; + +self.addEventListener('fetch', e => { + // Serve a generated response for kURL. + if (e.request.url.indexOf(kURL) != -1) + e.respondWith(new Response(kScript, { headers: kHeaders })); +}); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/service-worker-interception-static-import-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/service-worker-interception-static-import-worker.js new file mode 100644 index 000000000000..e570958701db --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/service-worker-interception-static-import-worker.js @@ -0,0 +1 @@ +import './service-worker-interception-network-worker.js'; diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/silence.oga b/test/fixtures/wpt/service-workers/service-worker/resources/silence.oga new file mode 100644 index 000000000000..af591880436a Binary files /dev/null and b/test/fixtures/wpt/service-workers/service-worker/resources/silence.oga differ diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/simple-intercept-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/simple-intercept-worker.js new file mode 100644 index 000000000000..f8b5f8c5cb77 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/simple-intercept-worker.js @@ -0,0 +1,5 @@ +self.onfetch = function(event) { + if (event.request.url.indexOf('simple') != -1) + event.respondWith( + new Response(new Blob(['intercepted by service worker']))); +}; diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/simple-intercept-worker.js.headers b/test/fixtures/wpt/service-workers/service-worker/resources/simple-intercept-worker.js.headers new file mode 100644 index 000000000000..a17a9a3a12ce --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/simple-intercept-worker.js.headers @@ -0,0 +1 @@ +Content-Type: application/javascript diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/simple-test-for-condition-main-resource.html b/test/fixtures/wpt/service-workers/service-worker/resources/simple-test-for-condition-main-resource.html new file mode 100644 index 000000000000..0c3e3e78707b --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/simple-test-for-condition-main-resource.html @@ -0,0 +1,3 @@ + +Simple +Here's a simple html file. diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/simple.csv b/test/fixtures/wpt/service-workers/service-worker/resources/simple.csv new file mode 100644 index 000000000000..ecbef786e738 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/simple.csv @@ -0,0 +1 @@ +matched,with,non-url,conditions diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/simple.html b/test/fixtures/wpt/service-workers/service-worker/resources/simple.html new file mode 100644 index 000000000000..0c3e3e78707b --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/simple.html @@ -0,0 +1,3 @@ + +Simple +Here's a simple html file. diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/simple.txt b/test/fixtures/wpt/service-workers/service-worker/resources/simple.txt new file mode 100644 index 000000000000..9e3cb91fb9b9 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/simple.txt @@ -0,0 +1 @@ +a simple text file diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/skip-waiting-installed-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/skip-waiting-installed-worker.js new file mode 100644 index 000000000000..6f7008bddcdf --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/skip-waiting-installed-worker.js @@ -0,0 +1,33 @@ +var saw_activate_event = false + +self.addEventListener('activate', function() { + saw_activate_event = true; + }); + +self.addEventListener('message', function(event) { + var port = event.data.port; + event.waitUntil(self.skipWaiting() + .then(function(result) { + if (result !== undefined) { + port.postMessage('FAIL: Promise should be resolved with undefined'); + return; + } + + if (!saw_activate_event) { + port.postMessage( + 'FAIL: Promise should be resolved after activate event is dispatched'); + return; + } + + if (self.registration.active.state !== 'activating') { + port.postMessage( + 'FAIL: Promise should be resolved before ServiceWorker#state is set to activated'); + return; + } + + port.postMessage('PASS'); + }) + .catch(function(e) { + port.postMessage('FAIL: unexpected exception: ' + e); + })); + }); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/skip-waiting-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/skip-waiting-worker.js new file mode 100644 index 000000000000..3fc1d1e237aa --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/skip-waiting-worker.js @@ -0,0 +1,21 @@ +importScripts('worker-testharness.js'); + +promise_test(function() { + return skipWaiting() + .then(function(result) { + assert_equals(result, undefined, + 'Promise should be resolved with undefined'); + }) + .then(function() { + var promises = []; + for (var i = 0; i < 8; ++i) + promises.push(self.skipWaiting()); + return Promise.all(promises); + }) + .then(function(results) { + results.forEach(function(r) { + assert_equals(r, undefined, + 'Promises should be resolved with undefined'); + }); + }); + }, 'skipWaiting'); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/square.png b/test/fixtures/wpt/service-workers/service-worker/resources/square.png new file mode 100644 index 000000000000..01c9666a8de9 Binary files /dev/null and b/test/fixtures/wpt/service-workers/service-worker/resources/square.png differ diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/square.png.sub.headers b/test/fixtures/wpt/service-workers/service-worker/resources/square.png.sub.headers new file mode 100644 index 000000000000..7341132745be --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/square.png.sub.headers @@ -0,0 +1,2 @@ +Content-Type: image/png +Access-Control-Allow-Origin: * diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/srcdoc-iframe-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/srcdoc-iframe-worker.js new file mode 100644 index 000000000000..548116c89ea8 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/srcdoc-iframe-worker.js @@ -0,0 +1,11 @@ +self.addEventListener('message', event => { + event.source.postMessage('passed'); +}); + +self.addEventListener('fetch', event => { + let url = new URL(event.request.url); + if (!url.searchParams.get('test_resource')) { + return; + } + event.respondWith(new Response('passed')); +}); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/srcdoc-iframe.html b/test/fixtures/wpt/service-workers/service-worker/resources/srcdoc-iframe.html new file mode 100644 index 000000000000..6407845c5adf --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/srcdoc-iframe.html @@ -0,0 +1,92 @@ + + + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/stalling-service-worker.js b/test/fixtures/wpt/service-workers/service-worker/resources/stalling-service-worker.js new file mode 100644 index 000000000000..fdf1e6cac04e --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/stalling-service-worker.js @@ -0,0 +1,54 @@ +async function post_message_to_client(role, message, ports) { + (await clients.matchAll()).forEach(client => { + if (new URL(client.url).searchParams.get('role') === role) { + client.postMessage(message, ports); + } + }); +} + +async function post_message_to_child(message, ports) { + await post_message_to_client('child', message, ports); +} + +function ping_message(data) { + return { type: 'ping', data }; +} + +self.onmessage = event => { + const message = ping_message(event.data); + post_message_to_child(message); + post_message_to_parent(message); +} + +async function post_message_to_parent(message, ports) { + await post_message_to_client('parent', message, ports); +} + +function fetch_message(key) { + return { type: 'fetch', key }; +} + +// Send a message to the parent along with a MessagePort to respond +// with. +function report_fetch_request(key) { + const channel = new MessageChannel(); + const reply = new Promise(resolve => { + channel.port1.onmessage = resolve; + }).then(event => event.data); + return post_message_to_parent(fetch_message(key), [channel.port2]).then(() => reply); +} + +function respond_with_script(script) { + return new Response(new Blob(script, { type: 'text/javascript' })); +} + +// Whenever a controlled document requests a URL with a 'key' search +// parameter we report the request to the parent frame and wait for +// a response. The content of the response is then used to respond to +// the fetch request. +addEventListener('fetch', event => { + let key = new URL(event.request.url).searchParams.get('key'); + if (key) { + event.respondWith(report_fetch_request(key).then(respond_with_script)); + } +}); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/static-router-helpers.sub.js b/test/fixtures/wpt/service-workers/service-worker/resources/static-router-helpers.sub.js new file mode 100644 index 000000000000..0ab1f1fae1dd --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/static-router-helpers.sub.js @@ -0,0 +1,82 @@ +// Helper functions for ServiceWorker static routing API. +// +// test-helpers.sub.js must be loaded before using this. + +// Get a dictionary of information recorded inside ServiceWorker. +// It includes: +// - request URL and mode. +// - errors. +// +// See: static-router-sw.js for details. +const get_info_from_worker = + async worker => { + const promise = new Promise(function(resolve) { + var channel = new MessageChannel(); + channel.port1.onmessage = function(msg) { resolve(msg); }; + worker.postMessage({port: channel.port2}, [channel.port2]); + }); + const message = await promise; + + return message.data; +} + +// Reset information stored inside ServiceWorker. +const reset_info_in_worker = + async worker => { + const promise = new Promise(function(resolve) { + var channel = new MessageChannel(); + channel.port1.onmessage = function(msg) { resolve(msg); }; + worker.postMessage({port: channel.port2, reset: true}, [channel.port2]); + }); + await promise; +} + +// This script's directory name. It is used for specifying test files. +const scriptDir = document.currentScript.src.match(/.*\//)[0]; + +// Register the ServiceWorker and wait until activated. +// {ruleKey} represents the key of routerRules defined in router-rules.js. +// {swScript} represents the service worker source URL. +// {swScope} represents the service worker resource scope. +const registerAndActivate = async (test, ruleKey, swScript, swScope) => { + if (!swScript) { + swScript = scriptDir + 'static-router-sw.js' + } + if (!swScope) { + swScope = scriptDir; + } + const swURL = `${swScript}?key=${ruleKey}`; + const reg = await service_worker_unregister_and_register( + test, swURL, swScope, { type: 'module' }); + add_completion_callback(() => reg.unregister()); + const worker = reg.installing; + await wait_for_state(test, worker, 'activated'); + + return worker; +}; + +// Create iframe with the given url. This automatically removes the iframe in a +// cleanup. +const createIframe = async (t, url) => { + const iframe = await with_iframe(url); + t.add_cleanup(() => iframe.remove()); + + return iframe; +}; + +// Register a service worker, then create an iframe at url. +function iframeTest(url, ruleKey, callback, name) { + return promise_test(async t => { + const worker = await registerAndActivate(t, ruleKey); + const iframe = await createIframe(t, url); + await callback(t, iframe.contentWindow, worker); + }, name); +}; + +function randomString() { + let result = ""; + for (let i = 0; i < 5; i++) { + result += String.fromCharCode(97 + Math.floor(Math.random() * 26)); + } + return result; +} diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/static-router-no-fetch-handler-sw.js b/test/fixtures/wpt/service-workers/service-worker/resources/static-router-no-fetch-handler-sw.js new file mode 100644 index 000000000000..1ba5fd7d463b --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/static-router-no-fetch-handler-sw.js @@ -0,0 +1,35 @@ +'use strict'; + +import {routerRules} from './router-rules.js'; +import { + recordError, + getRecords, + resetRecords } from './static-router-sw.sub.js'; + +self.addEventListener('install', async e => { + e.waitUntil(caches.open('v1').then( + cache => {cache.put('cache.txt', new Response('From cache'))})); + + const params = new URLSearchParams(location.search); + const key = params.get('key'); + try { + await e.addRoutes(routerRules[key]); + } catch (e) { + recordError(e); + } + self.skipWaiting(); +}); + +self.addEventListener('activate', e => { + e.waitUntil(clients.claim()); +}); + +self.addEventListener('message', function(event) { + if (event.data.reset) { + resetRecords(); + } + if (event.data.port) { + const {requests, errors} = getRecords(); + event.data.port.postMessage({requests, errors}); + } +}); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/static-router-race-network-and-fetch-handler-sw.js b/test/fixtures/wpt/service-workers/service-worker/resources/static-router-race-network-and-fetch-handler-sw.js new file mode 100644 index 000000000000..904ff0f46d8f --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/static-router-race-network-and-fetch-handler-sw.js @@ -0,0 +1,62 @@ +'use strict'; + +import {routerRules} from './router-rules.js'; +import { + recordRequest, + recordError, + getRecords, + resetRecords } from './static-router-sw.sub.js'; + +import './imported-sw.js'; + +self.addEventListener('install', async e => { + e.waitUntil(caches.open('v1').then( + cache => {cache.put('cache.txt', new Response('From cache'))})); + + const params = new URLSearchParams(location.search); + const key = params.get('key'); + try { + await e.addRoutes(routerRules[key]); + } catch (e) { + recordError(e); + } + self.skipWaiting(); +}); + +self.addEventListener('activate', e => { + e.waitUntil(clients.claim()); +}); + +self.addEventListener('fetch', async function(event) { + try { + recordRequest(event.request); + const url = new URL(event.request.url); + // Force slow response + if (url.searchParams.has('sw_slow')) { + const start = Date.now(); + while (true) { + if (Date.now() - start > 200) { + break; + } + } + } + const nonce = url.searchParams.get('nonce'); + event.respondWith(new Response(nonce)); + // Call `fetch(e.request)` but it's not consumed. + if (url.searchParams.has('call_fetch')) { + await fetch(event.request); + } + } catch (e) { + recordError(e) + } +}); + +self.addEventListener('message', function(event) { + if (event.data.reset) { + resetRecords(); + } + if (event.data.port) { + const {requests, errors} = getRecords(); + event.data.port.postMessage({requests, errors}); + } +}); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/static-router-sw.js b/test/fixtures/wpt/service-workers/service-worker/resources/static-router-sw.js new file mode 100644 index 000000000000..c0bd683f9182 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/static-router-sw.js @@ -0,0 +1,45 @@ +'use strict'; + +import {routerRules, cacheName} from './router-rules.js'; +import { + recordRequest, + recordError, + getRecords, + resetRecords } from './static-router-sw.sub.js'; + +import './imported-sw.js'; + +self.addEventListener('install', async e => { + e.waitUntil(caches.open(cacheName).then( + cache => {cache.put('cache.txt', new Response('From cache'))})); + + const params = new URLSearchParams(location.search); + const key = params.get('key'); + try { + await e.addRoutes(routerRules[key]); + } catch (e) { + recordError(e); + } + self.skipWaiting(); +}); + +self.addEventListener('activate', e => { + e.waitUntil(clients.claim()); +}); + +self.addEventListener('fetch', function(event) { + recordRequest(event.request); + const url = new URL(event.request.url); + const nonce = url.searchParams.get('nonce'); + event.respondWith(new Response(nonce)); +}); + +self.addEventListener('message', function(event) { + if (event.data.reset) { + resetRecords(); + } + if (event.data.port) { + const {requests, errors} = getRecords(); + event.data.port.postMessage({requests, errors}); + } +}); diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/static-router-sw.sub.js b/test/fixtures/wpt/service-workers/service-worker/resources/static-router-sw.sub.js new file mode 100644 index 000000000000..04f9c5533a48 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/static-router-sw.sub.js @@ -0,0 +1,29 @@ +let requests = []; +let errors = []; + +const recordRequest = req => { + requests.push({url: req.url, mode: req.mode, destination: req.destination}); +}; + +const recordError = (error) => { + errors.push(error); +}; + +const getRecords = () => { + return { + requests, + errors + }; +} + +const resetRecords = () => { + requests = []; + errors = []; +} + +export { + recordRequest, + recordError, + getRecords, + resetRecords +}; diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/subdir/blank.html b/test/fixtures/wpt/service-workers/service-worker/resources/subdir/blank.html new file mode 100644 index 000000000000..a3c3a4689a62 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/subdir/blank.html @@ -0,0 +1,2 @@ + +Empty doc diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/subdir/simple.txt b/test/fixtures/wpt/service-workers/service-worker/resources/subdir/simple.txt new file mode 100644 index 000000000000..86bcdd7dc56f --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/subdir/simple.txt @@ -0,0 +1 @@ +a simple text file (subdir/) diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/svg-target-reftest-001-frame.html b/test/fixtures/wpt/service-workers/service-worker/resources/svg-target-reftest-001-frame.html new file mode 100644 index 000000000000..59fb524049d8 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/svg-target-reftest-001-frame.html @@ -0,0 +1,3 @@ + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/resources/svg-target-reftest-001.html b/test/fixtures/wpt/service-workers/service-worker/resources/svg-target-reftest-001.html new file mode 100644 index 000000000000..9a93d3b37047 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/resources/svg-target-reftest-001.html @@ -0,0 +1,5 @@ + + +Green svg box reference file +

Pass if you see a green box below.

+ + + diff --git a/test/fixtures/wpt/workers/SharedWorker-exception-propagation.html b/test/fixtures/wpt/workers/SharedWorker-exception-propagation.html new file mode 100644 index 000000000000..5823a19a4bfa --- /dev/null +++ b/test/fixtures/wpt/workers/SharedWorker-exception-propagation.html @@ -0,0 +1,33 @@ + +Uncaught error in shared worker should not propagate to window + + + + + diff --git a/test/fixtures/wpt/workers/SharedWorker-exception.html b/test/fixtures/wpt/workers/SharedWorker-exception.html new file mode 100644 index 000000000000..28b858485727 --- /dev/null +++ b/test/fixtures/wpt/workers/SharedWorker-exception.html @@ -0,0 +1,22 @@ + +This test checks whether exceptions in SharedWorkers are logged to the parent document. An exception should be logged to the error console. + + + + diff --git a/test/fixtures/wpt/workers/SharedWorker-extendedLifetime-blob.html b/test/fixtures/wpt/workers/SharedWorker-extendedLifetime-blob.html new file mode 100644 index 000000000000..5a3945c59185 --- /dev/null +++ b/test/fixtures/wpt/workers/SharedWorker-extendedLifetime-blob.html @@ -0,0 +1,71 @@ + +SharedWorker extendedLifetime (Blob URL) + + + + + diff --git a/test/fixtures/wpt/workers/SharedWorker-extendedLifetime-data.html b/test/fixtures/wpt/workers/SharedWorker-extendedLifetime-data.html new file mode 100644 index 000000000000..96e45c4af50c --- /dev/null +++ b/test/fixtures/wpt/workers/SharedWorker-extendedLifetime-data.html @@ -0,0 +1,67 @@ + +SharedWorker extendedLifetime (Data URL) + + + + + diff --git a/test/fixtures/wpt/workers/SharedWorker-extendedLifetime-named-module.html b/test/fixtures/wpt/workers/SharedWorker-extendedLifetime-named-module.html new file mode 100644 index 000000000000..543c5b24933f --- /dev/null +++ b/test/fixtures/wpt/workers/SharedWorker-extendedLifetime-named-module.html @@ -0,0 +1,69 @@ + +SharedWorker extendedLifetime (Named and Module) + + + + + diff --git a/test/fixtures/wpt/workers/SharedWorker-extendedLifetime.html b/test/fixtures/wpt/workers/SharedWorker-extendedLifetime.html new file mode 100644 index 000000000000..a0fb0a007b7d --- /dev/null +++ b/test/fixtures/wpt/workers/SharedWorker-extendedLifetime.html @@ -0,0 +1,51 @@ + +SharedWorker extendedLifetime + + + + + diff --git a/test/fixtures/wpt/workers/SharedWorker-replace-EventHandler.any.js b/test/fixtures/wpt/workers/SharedWorker-replace-EventHandler.any.js new file mode 100644 index 000000000000..90c7d2d08d17 --- /dev/null +++ b/test/fixtures/wpt/workers/SharedWorker-replace-EventHandler.any.js @@ -0,0 +1,15 @@ +// META: global=sharedworker +// https://crbug.com/239669 +const t = async_test("Tests that repeatedly setting 'onerror' within a shared worker doesnt crash."); +onconnect = t.step_func_done((event) => { + function update() { + onerror = undefined; + } + try { + for (var i = 0; i < 8; ++i) { + update(); + } + } catch (ex) { + assert_unreached("FAIL: unexpected exception (" + ex + ") received while updating onerror event handler."); + } +}); diff --git a/test/fixtures/wpt/workers/SharedWorker-script-error.html b/test/fixtures/wpt/workers/SharedWorker-script-error.html new file mode 100644 index 000000000000..3c93cc038f27 --- /dev/null +++ b/test/fixtures/wpt/workers/SharedWorker-script-error.html @@ -0,0 +1,37 @@ + +Test SharedWorker script error handling functionality. + + + diff --git a/test/fixtures/wpt/workers/SharedWorker-simple.html b/test/fixtures/wpt/workers/SharedWorker-simple.html new file mode 100644 index 000000000000..7cd3f4f3be65 --- /dev/null +++ b/test/fixtures/wpt/workers/SharedWorker-simple.html @@ -0,0 +1,17 @@ + +Test simple shared worker construction case. + + + diff --git a/test/fixtures/wpt/workers/SharedWorkerPerformanceNow.html b/test/fixtures/wpt/workers/SharedWorkerPerformanceNow.html new file mode 100644 index 000000000000..be5b5e3488c6 --- /dev/null +++ b/test/fixtures/wpt/workers/SharedWorkerPerformanceNow.html @@ -0,0 +1,47 @@ + + + +window.performance.now in shared workers + + + + + + + diff --git a/test/fixtures/wpt/workers/SharedWorker_blobUrl.html b/test/fixtures/wpt/workers/SharedWorker_blobUrl.html new file mode 100644 index 000000000000..e5b1c673c060 --- /dev/null +++ b/test/fixtures/wpt/workers/SharedWorker_blobUrl.html @@ -0,0 +1,30 @@ + +Shared Worker: Blob URL passed over message port + + + + + + + diff --git a/test/fixtures/wpt/workers/SharedWorker_dataUrl.html b/test/fixtures/wpt/workers/SharedWorker_dataUrl.html new file mode 100644 index 000000000000..c1dec27d49f8 --- /dev/null +++ b/test/fixtures/wpt/workers/SharedWorker_dataUrl.html @@ -0,0 +1,63 @@ + +Shared Worker: Data URL cross-origin checks + + + + + + + diff --git a/test/fixtures/wpt/workers/WEB_FEATURES.yml b/test/fixtures/wpt/workers/WEB_FEATURES.yml new file mode 100644 index 000000000000..40ba4aa99ea0 --- /dev/null +++ b/test/fixtures/wpt/workers/WEB_FEATURES.yml @@ -0,0 +1,16 @@ +rules: +- WorkerNavigator-hardware-concurrency.any.js: [hardware-concurrency] +- WorkerGlobalScope_requestAnimationFrame.worker.js: [request-animation-frame-workers] +- WorkerGlobalScope_setInterval.htm: [setinterval] +- WorkerGlobalScope_setTimeout.htm: [settimeout] +- WorkerNavigator_userAgentData.http.html: [ua-client-hints] +- WorkerNavigator_userAgentData.https.html: [ua-client-hints] +- WorkerNavigator_onLine.htm: [online] +- Worker-postMessage-happens-in-parallel.https.html: [postmessage] +- postMessage_*: [postmessage] +- WorkerNavigator_userAgent.htm: [user-agent-sniffing] +- data-url-shared.html: [shared-workers] +- SharedWorker-*: [shared-workers] +- shared-worker-*: [shared-workers] +- "*.any.*": [] +- "*": [dedicated-workers] diff --git a/test/fixtures/wpt/workers/Worker-base64.any.js b/test/fixtures/wpt/workers/Worker-base64.any.js new file mode 100644 index 000000000000..6a46b477848c --- /dev/null +++ b/test/fixtures/wpt/workers/Worker-base64.any.js @@ -0,0 +1,5 @@ +// META: global=worker +test(() => { + assert_equals(typeof atob, 'function'); + assert_equals(typeof btoa, 'function'); +}, 'Tests that atob() / btoa() functions are exposed to workers'); diff --git a/test/fixtures/wpt/workers/Worker-call.worker.js b/test/fixtures/wpt/workers/Worker-call.worker.js new file mode 100644 index 000000000000..ba07498880cb --- /dev/null +++ b/test/fixtures/wpt/workers/Worker-call.worker.js @@ -0,0 +1,12 @@ +importScripts("/resources/testharness.js"); +test(() => { + try { + postMessage("SUCCESS: postMessage() called directly"); + postMessage.call(null, "SUCCESS: postMessage() invoked via postMessage.call()"); + var saved = postMessage; + saved("SUCCESS: postMessage() called via intermediate variable"); + } catch (ex) { + assert_unreached("FAIL: unexpected exception (" + ex + ") received while calling functions from the worker context."); + } +}, 'Test calling functions from WorkerContext.'); +done(); diff --git a/test/fixtures/wpt/workers/Worker-constructor-proto.any.js b/test/fixtures/wpt/workers/Worker-constructor-proto.any.js new file mode 100644 index 000000000000..297fe6c58b47 --- /dev/null +++ b/test/fixtures/wpt/workers/Worker-constructor-proto.any.js @@ -0,0 +1,7 @@ +//META: global=worker +test(() => { + const proto = {}; + assert_equals(String(Object.getPrototypeOf(WorkerLocation)).replace(/\n/g, " ").replace(/\s\s+/g, " "), "function () { [native code] }"); + Object.setPrototypeOf(WorkerLocation, proto); + assert_equals(Object.getPrototypeOf(WorkerLocation), proto); +}, 'Tests that setting the proto of a built in constructor is not reset.'); diff --git a/test/fixtures/wpt/workers/Worker-creation-happens-in-parallel.https.html b/test/fixtures/wpt/workers/Worker-creation-happens-in-parallel.https.html new file mode 100644 index 000000000000..887d95f3df68 --- /dev/null +++ b/test/fixtures/wpt/workers/Worker-creation-happens-in-parallel.https.html @@ -0,0 +1,18 @@ + +Test that creation of a "new Worker()" will occur in parallel to the main JS thread performing other computation, and can be joined with. + + + diff --git a/test/fixtures/wpt/workers/Worker-creation-happens-in-parallel.https.html.headers b/test/fixtures/wpt/workers/Worker-creation-happens-in-parallel.https.html.headers new file mode 100644 index 000000000000..4b06ac7cc63e --- /dev/null +++ b/test/fixtures/wpt/workers/Worker-creation-happens-in-parallel.https.html.headers @@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy:same-origin +Cross-Origin-Embedder-Policy:require-corp diff --git a/test/fixtures/wpt/workers/Worker-custom-event.any.js b/test/fixtures/wpt/workers/Worker-custom-event.any.js new file mode 100644 index 000000000000..d7e983aaddc5 --- /dev/null +++ b/test/fixtures/wpt/workers/Worker-custom-event.any.js @@ -0,0 +1,8 @@ +// META: global=worker +async_test(t => { + var target = self; + target.addEventListener('custom-event', t.step_func_done()); + + var event = new Event('custom-event'); + target.dispatchEvent(event); +}, 'Test CustomEvents on workers.'); diff --git a/test/fixtures/wpt/workers/Worker-formdata.any.js b/test/fixtures/wpt/workers/Worker-formdata.any.js new file mode 100644 index 000000000000..a07f194bd24e --- /dev/null +++ b/test/fixtures/wpt/workers/Worker-formdata.any.js @@ -0,0 +1,19 @@ +// META: global=dedicatedworker +test(() => { + assert_own_property(self, 'FormData'); + assert_equals(FormData.length, 0); + + var formData = new FormData(); + assert_not_equals(formData, null); + assert_own_property(FormData.prototype, 'append'); + formData.append('key', 'value'); + + var blob = new Blob([]); + assert_not_equals(blob, null); + formData.append('key', blob); + formData.append('key', blob, 'filename'); + + assert_throws_dom("DataCloneError", + function() { postMessage(formData) }, + "Trying to clone formdata inside a postMessage results in an exception." ); +},'Test FormData interface object'); diff --git a/test/fixtures/wpt/workers/Worker-location.sub.any.js b/test/fixtures/wpt/workers/Worker-location.sub.any.js new file mode 100644 index 000000000000..c05bb1750f71 --- /dev/null +++ b/test/fixtures/wpt/workers/Worker-location.sub.any.js @@ -0,0 +1,14 @@ +// META: global=dedicatedworker,sharedworker +test(() => { + assert_equals(String(WorkerLocation).replace(/\n/g, " ").replace(/\s\s+/g, " "), "function WorkerLocation() { [native code] }"); + assert_true(location instanceof Object); + assert_equals(location.href, 'http://{{host}}:{{ports[http][0]}}/workers/Worker-location.sub.any.worker.js'); + assert_equals(location.origin, "http://{{host}}:{{ports[http][0]}}"); + assert_equals(location.protocol, "http:"); + assert_equals(location.host, "{{host}}:{{ports[http][0]}}"); + assert_equals(location.hostname, "{{host}}"); + assert_equals(location.port, "{{ports[http][0]}}"); + assert_equals(location.pathname, "/workers/Worker-location.sub.any.worker.js"); + assert_equals(location.search, ""); + assert_equals(location.hash, ""); +}, 'Test WorkerLocation properties.'); diff --git a/test/fixtures/wpt/workers/Worker-messageport.html b/test/fixtures/wpt/workers/Worker-messageport.html new file mode 100644 index 000000000000..f7734b2543fc --- /dev/null +++ b/test/fixtures/wpt/workers/Worker-messageport.html @@ -0,0 +1,69 @@ + +Test that pages and workers can send MessagePorts to one another. + + + diff --git a/test/fixtures/wpt/workers/Worker-multi-port.html b/test/fixtures/wpt/workers/Worker-multi-port.html new file mode 100644 index 000000000000..587176e9fc10 --- /dev/null +++ b/test/fixtures/wpt/workers/Worker-multi-port.html @@ -0,0 +1,86 @@ + +Test sending multiple ports through Worker.postMessage. + + + diff --git a/test/fixtures/wpt/workers/Worker-nested-importScripts-error.html b/test/fixtures/wpt/workers/Worker-nested-importScripts-error.html new file mode 100644 index 000000000000..bd96c835df92 --- /dev/null +++ b/test/fixtures/wpt/workers/Worker-nested-importScripts-error.html @@ -0,0 +1,18 @@ + +This tests that errors from nested importScripts have the expected provenance. + + + diff --git a/test/fixtures/wpt/workers/Worker-postMessage-happens-in-parallel.https.html b/test/fixtures/wpt/workers/Worker-postMessage-happens-in-parallel.https.html new file mode 100644 index 000000000000..3b8683f79dcd --- /dev/null +++ b/test/fixtures/wpt/workers/Worker-postMessage-happens-in-parallel.https.html @@ -0,0 +1,20 @@ + +Test that calling "worker.postMessage()" will occur truly in parallel to the main JS thread performing other computation. + + + diff --git a/test/fixtures/wpt/workers/Worker-postMessage-happens-in-parallel.https.html.headers b/test/fixtures/wpt/workers/Worker-postMessage-happens-in-parallel.https.html.headers new file mode 100644 index 000000000000..4b06ac7cc63e --- /dev/null +++ b/test/fixtures/wpt/workers/Worker-postMessage-happens-in-parallel.https.html.headers @@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy:same-origin +Cross-Origin-Embedder-Policy:require-corp diff --git a/test/fixtures/wpt/workers/Worker-replace-event-handler.any.js b/test/fixtures/wpt/workers/Worker-replace-event-handler.any.js new file mode 100644 index 000000000000..ff7c764f2bdd --- /dev/null +++ b/test/fixtures/wpt/workers/Worker-replace-event-handler.any.js @@ -0,0 +1,11 @@ +// META: global=worker +// This is a regression test for a crash bug in Chrome: http://crbug.com/239669 +function update() { + onmessage = undefined; +} + +test(() => { + for (var i = 0; i < 8; ++i) { + update(); + } +}, "Tests that repeatedly setting 'onmessage' within a worker doesn't crash."); diff --git a/test/fixtures/wpt/workers/Worker-replace-global-constructor.any.js b/test/fixtures/wpt/workers/Worker-replace-global-constructor.any.js new file mode 100644 index 000000000000..d724c6c8ec6d --- /dev/null +++ b/test/fixtures/wpt/workers/Worker-replace-global-constructor.any.js @@ -0,0 +1,9 @@ +// META: global=worker +test(() => { + try { + self.MessageEvent = 'PASS'; + assert_equals(self.MessageEvent, 'PASS'); + } catch (ex) { + assert_unreached("FAIL: unexpected exception (" + ex + ") received while replacing global constructor MessageEvent."); + } +}, 'Test replacing global constructors in a worker context.'); diff --git a/test/fixtures/wpt/workers/Worker-replace-self.any.js b/test/fixtures/wpt/workers/Worker-replace-self.any.js new file mode 100644 index 000000000000..513fd4a257f4 --- /dev/null +++ b/test/fixtures/wpt/workers/Worker-replace-self.any.js @@ -0,0 +1,9 @@ +// META: global=worker +test(() => { + try { + self = 'PASS'; + assert_true(self instanceof WorkerGlobalScope); + } catch (ex) { + assert_unreached("FAIL: unexpected exception (" + ex + ") received while replacing self."); + } +}, 'Test that self is not replaceable.'); diff --git a/test/fixtures/wpt/workers/Worker-simultaneous-errors.html b/test/fixtures/wpt/workers/Worker-simultaneous-errors.html new file mode 100644 index 000000000000..4339f2e33436 --- /dev/null +++ b/test/fixtures/wpt/workers/Worker-simultaneous-errors.html @@ -0,0 +1,33 @@ + +Test simultaneous errors on workers. + + + diff --git a/test/fixtures/wpt/workers/Worker-structure-message.html b/test/fixtures/wpt/workers/Worker-structure-message.html new file mode 100644 index 000000000000..9eb12dc6c55b --- /dev/null +++ b/test/fixtures/wpt/workers/Worker-structure-message.html @@ -0,0 +1,27 @@ + +Test that pages and workers can send Structure Message to one another. + + + diff --git a/test/fixtures/wpt/workers/Worker-terminate-forever-during-evaluation.html b/test/fixtures/wpt/workers/Worker-terminate-forever-during-evaluation.html new file mode 100644 index 000000000000..ab66f29289f2 --- /dev/null +++ b/test/fixtures/wpt/workers/Worker-terminate-forever-during-evaluation.html @@ -0,0 +1,69 @@ + +Test Worker.terminate() for a worker that tries to run forever after top-level script evaluation is started. + + + diff --git a/test/fixtures/wpt/workers/Worker-terminate-forever.html b/test/fixtures/wpt/workers/Worker-terminate-forever.html new file mode 100644 index 000000000000..3528bb6246dd --- /dev/null +++ b/test/fixtures/wpt/workers/Worker-terminate-forever.html @@ -0,0 +1,11 @@ + +Test Worker.terminate() for a worker that tries to run forever. + + + diff --git a/test/fixtures/wpt/workers/Worker-termination-with-port-messages.html b/test/fixtures/wpt/workers/Worker-termination-with-port-messages.html new file mode 100644 index 000000000000..bc19784adae8 --- /dev/null +++ b/test/fixtures/wpt/workers/Worker-termination-with-port-messages.html @@ -0,0 +1,22 @@ + +This test terminates a worker when there are many undelivered MessagePort messages still waiting to be dispatched into the Worker Context. This causes termination of JS execution and test should not try to dispatch the remaining messages. Test succeeds if it does not hang or crash (if worker thread is running in the separate process, that process could hang or crash). + + + diff --git a/test/fixtures/wpt/workers/Worker-timeout-cancel-order.html b/test/fixtures/wpt/workers/Worker-timeout-cancel-order.html new file mode 100644 index 000000000000..78d930df783b --- /dev/null +++ b/test/fixtures/wpt/workers/Worker-timeout-cancel-order.html @@ -0,0 +1,17 @@ + +Test setTimeOut,cancelTimeout in Web Workers. + + + diff --git a/test/fixtures/wpt/workers/Worker-timeout-decreasing-order.html b/test/fixtures/wpt/workers/Worker-timeout-decreasing-order.html new file mode 100644 index 000000000000..f459461ec061 --- /dev/null +++ b/test/fixtures/wpt/workers/Worker-timeout-decreasing-order.html @@ -0,0 +1,23 @@ + +Test setTimeOut,fired in decreasing order in Web Workers. + + + diff --git a/test/fixtures/wpt/workers/Worker-timeout-increasing-order.html b/test/fixtures/wpt/workers/Worker-timeout-increasing-order.html new file mode 100644 index 000000000000..34b029466bb2 --- /dev/null +++ b/test/fixtures/wpt/workers/Worker-timeout-increasing-order.html @@ -0,0 +1,23 @@ + +Test setTimeOut,fired in increasing order in Web Workers. + + + diff --git a/test/fixtures/wpt/workers/WorkerGlobalScope-close.html b/test/fixtures/wpt/workers/WorkerGlobalScope-close.html new file mode 100644 index 000000000000..08ab1ca515c6 --- /dev/null +++ b/test/fixtures/wpt/workers/WorkerGlobalScope-close.html @@ -0,0 +1,81 @@ + +Test WorkerGlobalScope.close functionality. + + + diff --git a/test/fixtures/wpt/workers/WorkerGlobalScope_ErrorEvent_colno.htm b/test/fixtures/wpt/workers/WorkerGlobalScope_ErrorEvent_colno.htm new file mode 100644 index 000000000000..793d6c1807b2 --- /dev/null +++ b/test/fixtures/wpt/workers/WorkerGlobalScope_ErrorEvent_colno.htm @@ -0,0 +1,18 @@ + + WorkerGlobalScope onerror event handler argument: col + + +
+ diff --git a/test/fixtures/wpt/workers/WorkerGlobalScope_ErrorEvent_filename.htm b/test/fixtures/wpt/workers/WorkerGlobalScope_ErrorEvent_filename.htm new file mode 100644 index 000000000000..e165a23f418e --- /dev/null +++ b/test/fixtures/wpt/workers/WorkerGlobalScope_ErrorEvent_filename.htm @@ -0,0 +1,20 @@ + + WorkerGlobalScope onerror event handler argument: location + + +
+ diff --git a/test/fixtures/wpt/workers/WorkerGlobalScope_ErrorEvent_lineno.htm b/test/fixtures/wpt/workers/WorkerGlobalScope_ErrorEvent_lineno.htm new file mode 100644 index 000000000000..dfbc51467da5 --- /dev/null +++ b/test/fixtures/wpt/workers/WorkerGlobalScope_ErrorEvent_lineno.htm @@ -0,0 +1,18 @@ + + WorkerGlobalScope onerror event handler argument: line + + +
+ diff --git a/test/fixtures/wpt/workers/WorkerGlobalScope_ErrorEvent_message.htm b/test/fixtures/wpt/workers/WorkerGlobalScope_ErrorEvent_message.htm new file mode 100644 index 000000000000..27d4dda5114c --- /dev/null +++ b/test/fixtures/wpt/workers/WorkerGlobalScope_ErrorEvent_message.htm @@ -0,0 +1,20 @@ + + WorkerGlobalScope onerror event handler argument: message + + +
+ diff --git a/test/fixtures/wpt/workers/WorkerGlobalScope_importScripts.htm b/test/fixtures/wpt/workers/WorkerGlobalScope_importScripts.htm new file mode 100644 index 000000000000..1a3616df98bc --- /dev/null +++ b/test/fixtures/wpt/workers/WorkerGlobalScope_importScripts.htm @@ -0,0 +1,14 @@ + + WorkerGlobalScope API: importScripts() + + +
+ diff --git a/test/fixtures/wpt/workers/WorkerGlobalScope_importScripts_NetworkErr.htm b/test/fixtures/wpt/workers/WorkerGlobalScope_importScripts_NetworkErr.htm new file mode 100644 index 000000000000..36fe6e0b2d3a --- /dev/null +++ b/test/fixtures/wpt/workers/WorkerGlobalScope_importScripts_NetworkErr.htm @@ -0,0 +1,13 @@ + + importScripts() with non-existent script file + + +
+ diff --git a/test/fixtures/wpt/workers/WorkerGlobalScope_importScripts_NosniffErr.htm b/test/fixtures/wpt/workers/WorkerGlobalScope_importScripts_NosniffErr.htm new file mode 100644 index 000000000000..d99cecdc6a51 --- /dev/null +++ b/test/fixtures/wpt/workers/WorkerGlobalScope_importScripts_NosniffErr.htm @@ -0,0 +1,8 @@ + + importScripts() with nosniff X-Content-Type-Options + + +
+ diff --git a/test/fixtures/wpt/workers/WorkerGlobalScope_requestAnimationFrame.worker.js b/test/fixtures/wpt/workers/WorkerGlobalScope_requestAnimationFrame.worker.js new file mode 100644 index 000000000000..e1b0b9f15a69 --- /dev/null +++ b/test/fixtures/wpt/workers/WorkerGlobalScope_requestAnimationFrame.worker.js @@ -0,0 +1,19 @@ +importScripts("/resources/testharness.js"); + +async_test(t => { + const res = []; + requestAnimationFrame(t.step_func(dt => { + res.push(dt); + requestAnimationFrame(t.step_func(dt => { + res.push(dt); + requestAnimationFrame(t.step_func_done(dt => { + res.push(dt); + assert_equals(res.length, 3); + assert_less_than(res[0], res[1]); + assert_less_than(res[1], res[2]); + })); + })); + })); +}); + +done(); diff --git a/test/fixtures/wpt/workers/WorkerGlobalScope_setInterval.htm b/test/fixtures/wpt/workers/WorkerGlobalScope_setInterval.htm new file mode 100644 index 000000000000..4e147fbf60f1 --- /dev/null +++ b/test/fixtures/wpt/workers/WorkerGlobalScope_setInterval.htm @@ -0,0 +1,20 @@ + + WorkerGlobalScope API: setInterval() + + +
+ diff --git a/test/fixtures/wpt/workers/WorkerGlobalScope_setTimeout.htm b/test/fixtures/wpt/workers/WorkerGlobalScope_setTimeout.htm new file mode 100644 index 000000000000..89fdf3d740a8 --- /dev/null +++ b/test/fixtures/wpt/workers/WorkerGlobalScope_setTimeout.htm @@ -0,0 +1,20 @@ + + WorkerGlobalScope API: setTimeout() + + +
+ diff --git a/test/fixtures/wpt/workers/WorkerLocation-origin.sub.window.js b/test/fixtures/wpt/workers/WorkerLocation-origin.sub.window.js new file mode 100644 index 000000000000..7e808105dd79 --- /dev/null +++ b/test/fixtures/wpt/workers/WorkerLocation-origin.sub.window.js @@ -0,0 +1,11 @@ +async_test(t => { + const frame = document.createElement("iframe"), + asciiOrigin = location.protocol + "//{{domains[天気の良い日]}}:" + location.port, + path = new URL("support/WorkerLocation-origin.html", location).pathname; + frame.src = asciiOrigin + path; + self.onmessage = t.step_func_done(e => { + assert_equals(e.data.origin, asciiOrigin); + }); + document.body.appendChild(frame); + t.add_cleanup(() => frame.remove()); +}, "workerLocation.origin must use ASCII code points"); diff --git a/test/fixtures/wpt/workers/WorkerLocation.htm b/test/fixtures/wpt/workers/WorkerLocation.htm new file mode 100644 index 000000000000..a74f13a8b48b --- /dev/null +++ b/test/fixtures/wpt/workers/WorkerLocation.htm @@ -0,0 +1,15 @@ + + WorkerLocation object + + +
+ diff --git a/test/fixtures/wpt/workers/WorkerLocation_hash.htm b/test/fixtures/wpt/workers/WorkerLocation_hash.htm new file mode 100644 index 000000000000..74a424efc3c4 --- /dev/null +++ b/test/fixtures/wpt/workers/WorkerLocation_hash.htm @@ -0,0 +1,13 @@ + + WorkerLocation URL decomposition IDL attribute: hash + + +
+ diff --git a/test/fixtures/wpt/workers/WorkerLocation_hash_encoding.htm b/test/fixtures/wpt/workers/WorkerLocation_hash_encoding.htm new file mode 100644 index 000000000000..b2a171a092a6 --- /dev/null +++ b/test/fixtures/wpt/workers/WorkerLocation_hash_encoding.htm @@ -0,0 +1,13 @@ + + WorkerLocation.hash with url encoding string + + +
+ diff --git a/test/fixtures/wpt/workers/WorkerLocation_hash_nonexist.htm b/test/fixtures/wpt/workers/WorkerLocation_hash_nonexist.htm new file mode 100644 index 000000000000..2d898c075c38 --- /dev/null +++ b/test/fixtures/wpt/workers/WorkerLocation_hash_nonexist.htm @@ -0,0 +1,13 @@ + + WorkerLocation.hash with no <fragment> component + + +
+ diff --git a/test/fixtures/wpt/workers/WorkerLocation_host.htm b/test/fixtures/wpt/workers/WorkerLocation_host.htm new file mode 100644 index 000000000000..53286ddfc539 --- /dev/null +++ b/test/fixtures/wpt/workers/WorkerLocation_host.htm @@ -0,0 +1,13 @@ + + WorkerLocation URL decomposition IDL attribute: host + + +
+ diff --git a/test/fixtures/wpt/workers/WorkerLocation_hostname.htm b/test/fixtures/wpt/workers/WorkerLocation_hostname.htm new file mode 100644 index 000000000000..97250805c9f8 --- /dev/null +++ b/test/fixtures/wpt/workers/WorkerLocation_hostname.htm @@ -0,0 +1,13 @@ + + WorkerLocation URL decomposition IDL attribute: hostname + + +
+ diff --git a/test/fixtures/wpt/workers/WorkerLocation_href.htm b/test/fixtures/wpt/workers/WorkerLocation_href.htm new file mode 100644 index 000000000000..3ed1dbd4f519 --- /dev/null +++ b/test/fixtures/wpt/workers/WorkerLocation_href.htm @@ -0,0 +1,15 @@ + + WorkerLocation href attribute + + +
+ diff --git a/test/fixtures/wpt/workers/WorkerLocation_pathname.htm b/test/fixtures/wpt/workers/WorkerLocation_pathname.htm new file mode 100644 index 000000000000..346984511553 --- /dev/null +++ b/test/fixtures/wpt/workers/WorkerLocation_pathname.htm @@ -0,0 +1,15 @@ + + WorkerLocation URL decomposition IDL attribute: pathname + + +
+ diff --git a/test/fixtures/wpt/workers/WorkerLocation_port.htm b/test/fixtures/wpt/workers/WorkerLocation_port.htm new file mode 100644 index 000000000000..ef86cfacb615 --- /dev/null +++ b/test/fixtures/wpt/workers/WorkerLocation_port.htm @@ -0,0 +1,13 @@ + + WorkerLocation URL decomposition IDL attribute: port + + +
+ diff --git a/test/fixtures/wpt/workers/WorkerLocation_protocol.htm b/test/fixtures/wpt/workers/WorkerLocation_protocol.htm new file mode 100644 index 000000000000..f792dee51568 --- /dev/null +++ b/test/fixtures/wpt/workers/WorkerLocation_protocol.htm @@ -0,0 +1,13 @@ + + WorkerLocation URL decomposition IDL attribute: protocol + + +
+ diff --git a/test/fixtures/wpt/workers/WorkerLocation_search.htm b/test/fixtures/wpt/workers/WorkerLocation_search.htm new file mode 100644 index 000000000000..bc6add8768ae --- /dev/null +++ b/test/fixtures/wpt/workers/WorkerLocation_search.htm @@ -0,0 +1,13 @@ + + WorkerLocation URL decomposition IDL attribute: search + + +
+ diff --git a/test/fixtures/wpt/workers/WorkerLocation_search_empty.htm b/test/fixtures/wpt/workers/WorkerLocation_search_empty.htm new file mode 100644 index 000000000000..a32d4309128d --- /dev/null +++ b/test/fixtures/wpt/workers/WorkerLocation_search_empty.htm @@ -0,0 +1,13 @@ + + WorkerLocation.search with empty <query> + + +
+ diff --git a/test/fixtures/wpt/workers/WorkerLocation_search_fragment.htm b/test/fixtures/wpt/workers/WorkerLocation_search_fragment.htm new file mode 100644 index 000000000000..3ec4cffa6b5d --- /dev/null +++ b/test/fixtures/wpt/workers/WorkerLocation_search_fragment.htm @@ -0,0 +1,13 @@ + + WorkerLocation.search with <fragment> in <query> + + +
+ diff --git a/test/fixtures/wpt/workers/WorkerLocation_search_nonexist.htm b/test/fixtures/wpt/workers/WorkerLocation_search_nonexist.htm new file mode 100644 index 000000000000..9907e6473c2d --- /dev/null +++ b/test/fixtures/wpt/workers/WorkerLocation_search_nonexist.htm @@ -0,0 +1,13 @@ + + WorkerLocation.search with no <query> component + + +
+ diff --git a/test/fixtures/wpt/workers/WorkerNavigator-hardware-concurrency.any.js b/test/fixtures/wpt/workers/WorkerNavigator-hardware-concurrency.any.js new file mode 100644 index 000000000000..49db7503ffb1 --- /dev/null +++ b/test/fixtures/wpt/workers/WorkerNavigator-hardware-concurrency.any.js @@ -0,0 +1,4 @@ +// META: global=worker +test(() => { + assert_true(navigator.hardwareConcurrency > 0); +}, 'Test worker navigator hardware concurrency.'); diff --git a/test/fixtures/wpt/workers/WorkerNavigator.any.js b/test/fixtures/wpt/workers/WorkerNavigator.any.js new file mode 100644 index 000000000000..a9542af79aa3 --- /dev/null +++ b/test/fixtures/wpt/workers/WorkerNavigator.any.js @@ -0,0 +1,12 @@ +// META: global=worker +test(() => { + assert_equals(typeof navigator, "object"); + assert_true(navigator instanceof WorkerNavigator); + assert_equals(navigator.appName, "Netscape"); + assert_true(navigator.appVersion.indexOf('WebKit') != 0); + assert_equals(typeof navigator.platform, "string"); + assert_true(navigator.userAgent.indexOf('WebKit') != 0); + assert_equals(typeof navigator.onLine, "boolean"); + assert_equals(navigator.appCodeName, 'Mozilla'); + assert_equals(navigator.product, 'Gecko'); +}, "Testing Navigator properties on workers."); diff --git a/test/fixtures/wpt/workers/WorkerNavigator_appName.htm b/test/fixtures/wpt/workers/WorkerNavigator_appName.htm new file mode 100644 index 000000000000..832c46ff5e21 --- /dev/null +++ b/test/fixtures/wpt/workers/WorkerNavigator_appName.htm @@ -0,0 +1,13 @@ + + WorkerNavigator appName + + +
+ diff --git a/test/fixtures/wpt/workers/WorkerNavigator_appVersion.htm b/test/fixtures/wpt/workers/WorkerNavigator_appVersion.htm new file mode 100644 index 000000000000..7deaa4256af2 --- /dev/null +++ b/test/fixtures/wpt/workers/WorkerNavigator_appVersion.htm @@ -0,0 +1,13 @@ + + WorkerNavigator appVersion + + +
+ diff --git a/test/fixtures/wpt/workers/WorkerNavigator_onLine.htm b/test/fixtures/wpt/workers/WorkerNavigator_onLine.htm new file mode 100644 index 000000000000..f9e819b8aaba --- /dev/null +++ b/test/fixtures/wpt/workers/WorkerNavigator_onLine.htm @@ -0,0 +1,13 @@ + + WorkerNavigator.onLine + + +
+ diff --git a/test/fixtures/wpt/workers/WorkerNavigator_platform.htm b/test/fixtures/wpt/workers/WorkerNavigator_platform.htm new file mode 100644 index 000000000000..3a6de80eb96d --- /dev/null +++ b/test/fixtures/wpt/workers/WorkerNavigator_platform.htm @@ -0,0 +1,13 @@ + + WorkerNavigator.platform + + +
+ diff --git a/test/fixtures/wpt/workers/WorkerNavigator_userAgent.htm b/test/fixtures/wpt/workers/WorkerNavigator_userAgent.htm new file mode 100644 index 000000000000..8a34fb480ac5 --- /dev/null +++ b/test/fixtures/wpt/workers/WorkerNavigator_userAgent.htm @@ -0,0 +1,13 @@ + + WorkerNavigator.userAgent + + +
+ diff --git a/test/fixtures/wpt/workers/WorkerNavigator_userAgentData.http.html b/test/fixtures/wpt/workers/WorkerNavigator_userAgentData.http.html new file mode 100644 index 000000000000..4e8ca34eebcc --- /dev/null +++ b/test/fixtures/wpt/workers/WorkerNavigator_userAgentData.http.html @@ -0,0 +1,17 @@ + + WorkerNavigator.userAgentData + + + diff --git a/test/fixtures/wpt/workers/WorkerNavigator_userAgentData.https.html b/test/fixtures/wpt/workers/WorkerNavigator_userAgentData.https.html new file mode 100644 index 000000000000..8ca73df3e8cd --- /dev/null +++ b/test/fixtures/wpt/workers/WorkerNavigator_userAgentData.https.html @@ -0,0 +1,65 @@ + + WorkerNavigator.userAgentData + + + diff --git a/test/fixtures/wpt/workers/WorkerPerformanceNow.html b/test/fixtures/wpt/workers/WorkerPerformanceNow.html new file mode 100644 index 000000000000..286832fd9471 --- /dev/null +++ b/test/fixtures/wpt/workers/WorkerPerformanceNow.html @@ -0,0 +1,26 @@ + + + +performance.now in dedicated workers + + + + + + + diff --git a/test/fixtures/wpt/workers/Worker_ErrorEvent_bubbles_cancelable.htm b/test/fixtures/wpt/workers/Worker_ErrorEvent_bubbles_cancelable.htm new file mode 100644 index 000000000000..4619ee7b5312 --- /dev/null +++ b/test/fixtures/wpt/workers/Worker_ErrorEvent_bubbles_cancelable.htm @@ -0,0 +1,22 @@ + + +Web Workers: Worker ErrorEvent - bubbles, cancelable + + + +
+ diff --git a/test/fixtures/wpt/workers/Worker_ErrorEvent_error.htm b/test/fixtures/wpt/workers/Worker_ErrorEvent_error.htm new file mode 100644 index 000000000000..bb7cea12e040 --- /dev/null +++ b/test/fixtures/wpt/workers/Worker_ErrorEvent_error.htm @@ -0,0 +1,32 @@ + + + + + + diff --git a/test/fixtures/wpt/workers/Worker_ErrorEvent_filename.htm b/test/fixtures/wpt/workers/Worker_ErrorEvent_filename.htm new file mode 100644 index 000000000000..0faef6fea2a8 --- /dev/null +++ b/test/fixtures/wpt/workers/Worker_ErrorEvent_filename.htm @@ -0,0 +1,20 @@ + + AbstractWorker ErrorEvent.filename + + +
+ diff --git a/test/fixtures/wpt/workers/Worker_ErrorEvent_lineno.htm b/test/fixtures/wpt/workers/Worker_ErrorEvent_lineno.htm new file mode 100644 index 000000000000..ad98172960f6 --- /dev/null +++ b/test/fixtures/wpt/workers/Worker_ErrorEvent_lineno.htm @@ -0,0 +1,18 @@ + + AbstractWorker ErrorEvent.lineno + + +
+ diff --git a/test/fixtures/wpt/workers/Worker_ErrorEvent_message.htm b/test/fixtures/wpt/workers/Worker_ErrorEvent_message.htm new file mode 100644 index 000000000000..5602d9bc02d9 --- /dev/null +++ b/test/fixtures/wpt/workers/Worker_ErrorEvent_message.htm @@ -0,0 +1,19 @@ + + AbstractWorker ErrorEvent.message + + +
+ diff --git a/test/fixtures/wpt/workers/Worker_ErrorEvent_type.htm b/test/fixtures/wpt/workers/Worker_ErrorEvent_type.htm new file mode 100644 index 000000000000..3a0f85ad9b6b --- /dev/null +++ b/test/fixtures/wpt/workers/Worker_ErrorEvent_type.htm @@ -0,0 +1,19 @@ + + AbstractWorker ErrorEvent.type + + +
+ diff --git a/test/fixtures/wpt/workers/Worker_NosniffErr.htm b/test/fixtures/wpt/workers/Worker_NosniffErr.htm new file mode 100644 index 000000000000..11d4b7c290ad --- /dev/null +++ b/test/fixtures/wpt/workers/Worker_NosniffErr.htm @@ -0,0 +1,13 @@ + + Worker with nosniff X-Content-Type-Options header + + +
+ diff --git a/test/fixtures/wpt/workers/Worker_basic.htm b/test/fixtures/wpt/workers/Worker_basic.htm new file mode 100644 index 000000000000..d2b57b4918b0 --- /dev/null +++ b/test/fixtures/wpt/workers/Worker_basic.htm @@ -0,0 +1,31 @@ + + Web Workers Basic Tests + + +
+ diff --git a/test/fixtures/wpt/workers/Worker_cross_origin_security_err.htm b/test/fixtures/wpt/workers/Worker_cross_origin_security_err.htm new file mode 100644 index 000000000000..a3e49df79ad4 --- /dev/null +++ b/test/fixtures/wpt/workers/Worker_cross_origin_security_err.htm @@ -0,0 +1,21 @@ + +Worker cross-origin URL + + + +
+ diff --git a/test/fixtures/wpt/workers/Worker_dispatchEvent_ErrorEvent.htm b/test/fixtures/wpt/workers/Worker_dispatchEvent_ErrorEvent.htm new file mode 100644 index 000000000000..7ba56b89ecf1 --- /dev/null +++ b/test/fixtures/wpt/workers/Worker_dispatchEvent_ErrorEvent.htm @@ -0,0 +1,39 @@ + + ErrorEvent and Worker.dispatchEvent() + + +
+ diff --git a/test/fixtures/wpt/workers/Worker_script_mimetype.htm b/test/fixtures/wpt/workers/Worker_script_mimetype.htm new file mode 100644 index 000000000000..d2278d3717c2 --- /dev/null +++ b/test/fixtures/wpt/workers/Worker_script_mimetype.htm @@ -0,0 +1,42 @@ + +Worker constructor with wrong MIME type scripts + + + + + + diff --git a/test/fixtures/wpt/workers/Worker_terminate_event_queue.htm b/test/fixtures/wpt/workers/Worker_terminate_event_queue.htm new file mode 100644 index 000000000000..e4f106ad3a86 --- /dev/null +++ b/test/fixtures/wpt/workers/Worker_terminate_event_queue.htm @@ -0,0 +1,23 @@ + + AbstractWorker terminate(): clear event queue + + + +
+ diff --git a/test/fixtures/wpt/workers/abrupt-completion.html b/test/fixtures/wpt/workers/abrupt-completion.html new file mode 100644 index 000000000000..6c09ae4419cc --- /dev/null +++ b/test/fixtures/wpt/workers/abrupt-completion.html @@ -0,0 +1,63 @@ + + + + + + diff --git a/test/fixtures/wpt/workers/baseurl/alpha/WEB_FEATURES.yml b/test/fixtures/wpt/workers/baseurl/alpha/WEB_FEATURES.yml new file mode 100644 index 000000000000..2d1787baf9a1 --- /dev/null +++ b/test/fixtures/wpt/workers/baseurl/alpha/WEB_FEATURES.yml @@ -0,0 +1,3 @@ +rules: +- importScripts-in-sharedworker.html: [shared-workers] +- "*": [dedicated-workers] diff --git a/test/fixtures/wpt/workers/baseurl/alpha/import-in-moduleworker.html b/test/fixtures/wpt/workers/baseurl/alpha/import-in-moduleworker.html new file mode 100644 index 000000000000..2c75dec9ce76 --- /dev/null +++ b/test/fixtures/wpt/workers/baseurl/alpha/import-in-moduleworker.html @@ -0,0 +1,14 @@ + + +Base URL in module dedicated workers: import + + + diff --git a/test/fixtures/wpt/workers/baseurl/alpha/importScripts-in-sharedworker.html b/test/fixtures/wpt/workers/baseurl/alpha/importScripts-in-sharedworker.html new file mode 100644 index 000000000000..6a4111c6c052 --- /dev/null +++ b/test/fixtures/wpt/workers/baseurl/alpha/importScripts-in-sharedworker.html @@ -0,0 +1,8 @@ + + +Base URL in classic shared workers: importScripts + + + diff --git a/test/fixtures/wpt/workers/baseurl/alpha/importScripts-in-worker.html b/test/fixtures/wpt/workers/baseurl/alpha/importScripts-in-worker.html new file mode 100644 index 000000000000..55907bf4238d --- /dev/null +++ b/test/fixtures/wpt/workers/baseurl/alpha/importScripts-in-worker.html @@ -0,0 +1,8 @@ + + +Base URL in classic dedicated workers: importScripts + + + diff --git a/test/fixtures/wpt/workers/baseurl/alpha/worker-in-worker.html b/test/fixtures/wpt/workers/baseurl/alpha/worker-in-worker.html new file mode 100644 index 000000000000..284425ed3407 --- /dev/null +++ b/test/fixtures/wpt/workers/baseurl/alpha/worker-in-worker.html @@ -0,0 +1,14 @@ + + +Base URL in workers: new Worker() + + + diff --git a/test/fixtures/wpt/workers/baseurl/alpha/xhr-in-moduleworker.html b/test/fixtures/wpt/workers/baseurl/alpha/xhr-in-moduleworker.html new file mode 100644 index 000000000000..7597a1357d1d --- /dev/null +++ b/test/fixtures/wpt/workers/baseurl/alpha/xhr-in-moduleworker.html @@ -0,0 +1,14 @@ + + +Base URL in module dedicated workers: XHR + + + diff --git a/test/fixtures/wpt/workers/baseurl/alpha/xhr-in-sharedworker.html b/test/fixtures/wpt/workers/baseurl/alpha/xhr-in-sharedworker.html new file mode 100644 index 000000000000..43921b898dcd --- /dev/null +++ b/test/fixtures/wpt/workers/baseurl/alpha/xhr-in-sharedworker.html @@ -0,0 +1,8 @@ + + +Base URL in classic shared workers: XHR + + + diff --git a/test/fixtures/wpt/workers/baseurl/alpha/xhr-in-worker.html b/test/fixtures/wpt/workers/baseurl/alpha/xhr-in-worker.html new file mode 100644 index 000000000000..bc58b9b2dd18 --- /dev/null +++ b/test/fixtures/wpt/workers/baseurl/alpha/xhr-in-worker.html @@ -0,0 +1,8 @@ + + +Base URL in classic dedicated workers: XHR + + + diff --git a/test/fixtures/wpt/workers/baseurl/beta/script.js b/test/fixtures/wpt/workers/baseurl/beta/script.js new file mode 100644 index 000000000000..bef771ff9eba --- /dev/null +++ b/test/fixtures/wpt/workers/baseurl/beta/script.js @@ -0,0 +1 @@ +var result = 'beta/script.js'; diff --git a/test/fixtures/wpt/workers/baseurl/beta/subsharedworker.js b/test/fixtures/wpt/workers/baseurl/beta/subsharedworker.js new file mode 100644 index 000000000000..de6a8cacaf80 --- /dev/null +++ b/test/fixtures/wpt/workers/baseurl/beta/subsharedworker.js @@ -0,0 +1,3 @@ +onconnect = function(e) { + e.source.postMessage('beta'); +} diff --git a/test/fixtures/wpt/workers/baseurl/beta/subworker.js b/test/fixtures/wpt/workers/baseurl/beta/subworker.js new file mode 100644 index 000000000000..997cecd6ced2 --- /dev/null +++ b/test/fixtures/wpt/workers/baseurl/beta/subworker.js @@ -0,0 +1 @@ +postMessage("beta"); diff --git a/test/fixtures/wpt/workers/baseurl/beta/test.txt b/test/fixtures/wpt/workers/baseurl/beta/test.txt new file mode 100644 index 000000000000..65b2df87f7df --- /dev/null +++ b/test/fixtures/wpt/workers/baseurl/beta/test.txt @@ -0,0 +1 @@ +beta diff --git a/test/fixtures/wpt/workers/baseurl/gamma/import.js b/test/fixtures/wpt/workers/baseurl/gamma/import.js new file mode 100644 index 000000000000..1246913a84b7 --- /dev/null +++ b/test/fixtures/wpt/workers/baseurl/gamma/import.js @@ -0,0 +1,2 @@ +import r from "./script-module.js"; +postMessage(r); diff --git a/test/fixtures/wpt/workers/baseurl/gamma/importScripts.js b/test/fixtures/wpt/workers/baseurl/gamma/importScripts.js new file mode 100644 index 000000000000..13820380a83e --- /dev/null +++ b/test/fixtures/wpt/workers/baseurl/gamma/importScripts.js @@ -0,0 +1,6 @@ +importScripts('/resources/testharness.js'); +importScripts("script.js"); +test(() => { + assert_equals(result, "gamma/script.js"); +}); +done(); diff --git a/test/fixtures/wpt/workers/baseurl/gamma/script-module.js b/test/fixtures/wpt/workers/baseurl/gamma/script-module.js new file mode 100644 index 000000000000..88d5f82db3e3 --- /dev/null +++ b/test/fixtures/wpt/workers/baseurl/gamma/script-module.js @@ -0,0 +1 @@ +export default 'gamma/script-module.js'; diff --git a/test/fixtures/wpt/workers/baseurl/gamma/script.js b/test/fixtures/wpt/workers/baseurl/gamma/script.js new file mode 100644 index 000000000000..0f9ce8eacf4a --- /dev/null +++ b/test/fixtures/wpt/workers/baseurl/gamma/script.js @@ -0,0 +1 @@ +var result = 'gamma/script.js'; diff --git a/test/fixtures/wpt/workers/baseurl/gamma/subworker.js b/test/fixtures/wpt/workers/baseurl/gamma/subworker.js new file mode 100644 index 000000000000..44407358e612 --- /dev/null +++ b/test/fixtures/wpt/workers/baseurl/gamma/subworker.js @@ -0,0 +1 @@ +postMessage("gamma"); diff --git a/test/fixtures/wpt/workers/baseurl/gamma/test.txt b/test/fixtures/wpt/workers/baseurl/gamma/test.txt new file mode 100644 index 000000000000..af17f6cc87e4 --- /dev/null +++ b/test/fixtures/wpt/workers/baseurl/gamma/test.txt @@ -0,0 +1 @@ +gamma diff --git a/test/fixtures/wpt/workers/baseurl/gamma/worker.js b/test/fixtures/wpt/workers/baseurl/gamma/worker.js new file mode 100644 index 000000000000..8cfbcaef3129 --- /dev/null +++ b/test/fixtures/wpt/workers/baseurl/gamma/worker.js @@ -0,0 +1,4 @@ +var worker = new Worker("subworker.js"); +worker.onmessage = function(e) { + postMessage(e.data); +} diff --git a/test/fixtures/wpt/workers/baseurl/gamma/xhr-worker.js b/test/fixtures/wpt/workers/baseurl/gamma/xhr-worker.js new file mode 100644 index 000000000000..a9d77827d951 --- /dev/null +++ b/test/fixtures/wpt/workers/baseurl/gamma/xhr-worker.js @@ -0,0 +1,8 @@ +importScripts('/resources/testharness.js'); +test(t => { + var x = new XMLHttpRequest(); + x.open("GET", "test.txt", false); + x.send(); + assert_equals(x.response, "gamma\n"); +}); +done(); diff --git a/test/fixtures/wpt/workers/baseurl/gamma/xhr.js b/test/fixtures/wpt/workers/baseurl/gamma/xhr.js new file mode 100644 index 000000000000..70f331565aa6 --- /dev/null +++ b/test/fixtures/wpt/workers/baseurl/gamma/xhr.js @@ -0,0 +1,4 @@ +var x = new XMLHttpRequest(); +x.open("GET", "test.txt", false); +x.send(); +postMessage(x.response); diff --git a/test/fixtures/wpt/workers/constructors/SharedWorker/1 b/test/fixtures/wpt/workers/constructors/SharedWorker/1 new file mode 100644 index 000000000000..831434e63990 --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/SharedWorker/1 @@ -0,0 +1,3 @@ +onconnect = e => { + e.ports[0].postMessage(['1', self.name]); +}; diff --git a/test/fixtures/wpt/workers/constructors/SharedWorker/1.headers b/test/fixtures/wpt/workers/constructors/SharedWorker/1.headers new file mode 100644 index 000000000000..e7ec0d6699d0 --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/SharedWorker/1.headers @@ -0,0 +1 @@ +Content-Type: text/javascript diff --git a/test/fixtures/wpt/workers/constructors/SharedWorker/Infinity b/test/fixtures/wpt/workers/constructors/SharedWorker/Infinity new file mode 100644 index 000000000000..d4c921c5658e --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/SharedWorker/Infinity @@ -0,0 +1,3 @@ +onconnect = e => { + e.ports[0].postMessage(['Infinity', self.name]); +}; diff --git a/test/fixtures/wpt/workers/constructors/SharedWorker/Infinity-arguments.html b/test/fixtures/wpt/workers/constructors/SharedWorker/Infinity-arguments.html new file mode 100644 index 000000000000..b38e55dc6bae --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/SharedWorker/Infinity-arguments.html @@ -0,0 +1,13 @@ + +Infinity as arguments + + + diff --git a/test/fixtures/wpt/workers/constructors/SharedWorker/Infinity.headers b/test/fixtures/wpt/workers/constructors/SharedWorker/Infinity.headers new file mode 100644 index 000000000000..6805c323df5a --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/SharedWorker/Infinity.headers @@ -0,0 +1 @@ +Content-Type: text/javascript; charset=utf-8 diff --git a/test/fixtures/wpt/workers/constructors/SharedWorker/NaN b/test/fixtures/wpt/workers/constructors/SharedWorker/NaN new file mode 100644 index 000000000000..1d06329788c3 --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/SharedWorker/NaN @@ -0,0 +1,3 @@ +onconnect = e => { + e.ports[0].postMessage(['NaN', self.name]); +}; diff --git a/test/fixtures/wpt/workers/constructors/SharedWorker/NaN-arguments.html b/test/fixtures/wpt/workers/constructors/SharedWorker/NaN-arguments.html new file mode 100644 index 000000000000..8a4578a965a3 --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/SharedWorker/NaN-arguments.html @@ -0,0 +1,13 @@ + +NaN as arguments + + + diff --git a/test/fixtures/wpt/workers/constructors/SharedWorker/NaN.headers b/test/fixtures/wpt/workers/constructors/SharedWorker/NaN.headers new file mode 100644 index 000000000000..6805c323df5a --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/SharedWorker/NaN.headers @@ -0,0 +1 @@ +Content-Type: text/javascript; charset=utf-8 diff --git a/test/fixtures/wpt/workers/constructors/SharedWorker/SharedWorker-constructor.html b/test/fixtures/wpt/workers/constructors/SharedWorker/SharedWorker-constructor.html new file mode 100644 index 000000000000..7909eb536953 --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/SharedWorker/SharedWorker-constructor.html @@ -0,0 +1,28 @@ + +Test SharedWorker constructor functionality. + + + diff --git a/test/fixtures/wpt/workers/constructors/SharedWorker/URLMismatchError.htm b/test/fixtures/wpt/workers/constructors/SharedWorker/URLMismatchError.htm new file mode 100644 index 000000000000..683d201ad3a0 --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/SharedWorker/URLMismatchError.htm @@ -0,0 +1,31 @@ + + +Web Workers: SharedWorker - same name, different URL + + + + diff --git a/test/fixtures/wpt/workers/constructors/SharedWorker/WEB_FEATURES.yml b/test/fixtures/wpt/workers/constructors/SharedWorker/WEB_FEATURES.yml new file mode 100644 index 000000000000..73744331853b --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/SharedWorker/WEB_FEATURES.yml @@ -0,0 +1,2 @@ +rules: +- "**": [shared-workers] diff --git a/test/fixtures/wpt/workers/constructors/SharedWorker/connect-event.html b/test/fixtures/wpt/workers/constructors/SharedWorker/connect-event.html new file mode 100644 index 000000000000..0ab41d25c906 --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/SharedWorker/connect-event.html @@ -0,0 +1,14 @@ + +connect event + + + diff --git a/test/fixtures/wpt/workers/constructors/SharedWorker/connect-event.js b/test/fixtures/wpt/workers/constructors/SharedWorker/connect-event.js new file mode 100644 index 000000000000..2cf26a723e8e --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/SharedWorker/connect-event.js @@ -0,0 +1,3 @@ +onconnect = e => { + e.ports[0].postMessage([e.data === '', e instanceof MessageEvent, e.ports.length == 1]); +}; diff --git a/test/fixtures/wpt/workers/constructors/SharedWorker/dummy-name.html b/test/fixtures/wpt/workers/constructors/SharedWorker/dummy-name.html new file mode 100644 index 000000000000..25277042e21b --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/SharedWorker/dummy-name.html @@ -0,0 +1,10 @@ + +creating a dummy shared worker with name "foo" + + + + diff --git a/test/fixtures/wpt/workers/constructors/SharedWorker/dummy-shared-worker.html b/test/fixtures/wpt/workers/constructors/SharedWorker/dummy-shared-worker.html new file mode 100644 index 000000000000..59a449ad7d87 --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/SharedWorker/dummy-shared-worker.html @@ -0,0 +1,10 @@ + +creating a dummy shared worker + + + + diff --git a/test/fixtures/wpt/workers/constructors/SharedWorker/dummy-shared-worker.js b/test/fixtures/wpt/workers/constructors/SharedWorker/dummy-shared-worker.js new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/test/fixtures/wpt/workers/constructors/SharedWorker/empty-name.html b/test/fixtures/wpt/workers/constructors/SharedWorker/empty-name.html new file mode 100644 index 000000000000..94771d27c9eb --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/SharedWorker/empty-name.html @@ -0,0 +1,10 @@ + +creating a dummy shared worker with explicit name "" + + + + diff --git a/test/fixtures/wpt/workers/constructors/SharedWorker/empty.js b/test/fixtures/wpt/workers/constructors/SharedWorker/empty.js new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/test/fixtures/wpt/workers/constructors/SharedWorker/global-members.html b/test/fixtures/wpt/workers/constructors/SharedWorker/global-members.html new file mode 100644 index 000000000000..2da4fc1cee6e --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/SharedWorker/global-members.html @@ -0,0 +1,12 @@ + +members of SharedWorkerGlobalScope + + + diff --git a/test/fixtures/wpt/workers/constructors/SharedWorker/global-members.js b/test/fixtures/wpt/workers/constructors/SharedWorker/global-members.js new file mode 100644 index 000000000000..453da6aae514 --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/SharedWorker/global-members.js @@ -0,0 +1,9 @@ +const expected = 'self location close onerror importScripts navigator addEventListener removeEventListener dispatchEvent name onconnect setTimeout clearTimeout setInterval clearInterval'.split(' '); +let log = ''; +for (let i = 0; i < expected.length; ++i) { + if (!(expected[i] in self)) + log += expected[i] + ' did not exist\n'; +} +onconnect = e => { + e.ports[0].postMessage(log); +}; diff --git a/test/fixtures/wpt/workers/constructors/SharedWorker/interface-objects.html b/test/fixtures/wpt/workers/constructors/SharedWorker/interface-objects.html new file mode 100644 index 000000000000..a8f69981687a --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/SharedWorker/interface-objects.html @@ -0,0 +1,20 @@ + +expected interface objects/constructors + + + diff --git a/test/fixtures/wpt/workers/constructors/SharedWorker/interface-objects.js b/test/fixtures/wpt/workers/constructors/SharedWorker/interface-objects.js new file mode 100644 index 000000000000..2a7aaee687a4 --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/SharedWorker/interface-objects.js @@ -0,0 +1,13 @@ +let prt; +const handleCall = e => { + const log = []; + for (let i = 0; i < e.data.length; ++i) { + if (!(e.data[i] in self)) + log.push(e.data[i]); + } + prt.postMessage('These were missing: '+log.join(', ')); +}; +onconnect = e => { + prt = e.ports[0]; + prt.onmessage = handleCall; +}; diff --git a/test/fixtures/wpt/workers/constructors/SharedWorker/name.html b/test/fixtures/wpt/workers/constructors/SharedWorker/name.html new file mode 100644 index 000000000000..4531cb1b800b --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/SharedWorker/name.html @@ -0,0 +1,12 @@ + +self.name + + + diff --git a/test/fixtures/wpt/workers/constructors/SharedWorker/name.js b/test/fixtures/wpt/workers/constructors/SharedWorker/name.js new file mode 100644 index 000000000000..2bc2a4b18b50 --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/SharedWorker/name.js @@ -0,0 +1,3 @@ +onconnect = e => { + e.ports[0].postMessage(self.name); +}; diff --git a/test/fixtures/wpt/workers/constructors/SharedWorker/no-arguments-ctor.html b/test/fixtures/wpt/workers/constructors/SharedWorker/no-arguments-ctor.html new file mode 100644 index 000000000000..5a1231d7b596 --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/SharedWorker/no-arguments-ctor.html @@ -0,0 +1,13 @@ + +no arguments + + + + + diff --git a/test/fixtures/wpt/workers/constructors/SharedWorker/null b/test/fixtures/wpt/workers/constructors/SharedWorker/null new file mode 100644 index 000000000000..16f02d513161 --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/SharedWorker/null @@ -0,0 +1,3 @@ +onconnect = e => { + e.ports[0].postMessage(['null', self.name]); +}; diff --git a/test/fixtures/wpt/workers/constructors/SharedWorker/null-arguments.html b/test/fixtures/wpt/workers/constructors/SharedWorker/null-arguments.html new file mode 100644 index 000000000000..dd5e5773edbb --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/SharedWorker/null-arguments.html @@ -0,0 +1,13 @@ + +null as arguments + + + diff --git a/test/fixtures/wpt/workers/constructors/SharedWorker/null.headers b/test/fixtures/wpt/workers/constructors/SharedWorker/null.headers new file mode 100644 index 000000000000..e7ec0d6699d0 --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/SharedWorker/null.headers @@ -0,0 +1 @@ +Content-Type: text/javascript diff --git a/test/fixtures/wpt/workers/constructors/SharedWorker/number-arguments.html b/test/fixtures/wpt/workers/constructors/SharedWorker/number-arguments.html new file mode 100644 index 000000000000..8f90baa89854 --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/SharedWorker/number-arguments.html @@ -0,0 +1,13 @@ + +1 as arguments + + + diff --git a/test/fixtures/wpt/workers/constructors/SharedWorker/port-onmessage.html b/test/fixtures/wpt/workers/constructors/SharedWorker/port-onmessage.html new file mode 100644 index 000000000000..706420c5e4a3 --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/SharedWorker/port-onmessage.html @@ -0,0 +1,12 @@ + +worker.port.onmessage + + + diff --git a/test/fixtures/wpt/workers/constructors/SharedWorker/port-onmessage.js b/test/fixtures/wpt/workers/constructors/SharedWorker/port-onmessage.js new file mode 100644 index 000000000000..64ef84df15a3 --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/SharedWorker/port-onmessage.js @@ -0,0 +1,3 @@ +onconnect = e => { + e.ports[0].postMessage(true); +}; diff --git a/test/fixtures/wpt/workers/constructors/SharedWorker/port-properties.html b/test/fixtures/wpt/workers/constructors/SharedWorker/port-properties.html new file mode 100644 index 000000000000..e2a1d5b2a8f4 --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/SharedWorker/port-properties.html @@ -0,0 +1,19 @@ + +worker.port + + + + + diff --git a/test/fixtures/wpt/workers/constructors/SharedWorker/port-readonly.html b/test/fixtures/wpt/workers/constructors/SharedWorker/port-readonly.html new file mode 100644 index 000000000000..cfb5f3afa514 --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/SharedWorker/port-readonly.html @@ -0,0 +1,14 @@ + +setting worker.port + + + + + diff --git a/test/fixtures/wpt/workers/constructors/SharedWorker/same-origin.html b/test/fixtures/wpt/workers/constructors/SharedWorker/same-origin.html new file mode 100644 index 000000000000..4f1b62a6605b --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/SharedWorker/same-origin.html @@ -0,0 +1,62 @@ + +same-origin checks + + + + + diff --git a/test/fixtures/wpt/workers/constructors/SharedWorker/setting-port-members.html b/test/fixtures/wpt/workers/constructors/SharedWorker/setting-port-members.html new file mode 100644 index 000000000000..0c53474ff076 --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/SharedWorker/setting-port-members.html @@ -0,0 +1,53 @@ + +setting members of worker.port + + + diff --git a/test/fixtures/wpt/workers/constructors/SharedWorker/shared-worker.js b/test/fixtures/wpt/workers/constructors/SharedWorker/shared-worker.js new file mode 100644 index 000000000000..b6d18855da51 --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/SharedWorker/shared-worker.js @@ -0,0 +1,6 @@ +onconnect = e => { + const port = e.ports[0]; + port.onmessage = e => { + port.postMessage('ping'); + } +} diff --git a/test/fixtures/wpt/workers/constructors/SharedWorker/undefined b/test/fixtures/wpt/workers/constructors/SharedWorker/undefined new file mode 100644 index 000000000000..b8462f19118b --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/SharedWorker/undefined @@ -0,0 +1,3 @@ +onconnect = e => { + e.ports[0].postMessage(['undefined', self.name]); +}; diff --git a/test/fixtures/wpt/workers/constructors/SharedWorker/undefined-arguments.html b/test/fixtures/wpt/workers/constructors/SharedWorker/undefined-arguments.html new file mode 100644 index 000000000000..cd4c86e84ab1 --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/SharedWorker/undefined-arguments.html @@ -0,0 +1,13 @@ + +undefined as arguments + + + diff --git a/test/fixtures/wpt/workers/constructors/SharedWorker/undefined.headers b/test/fixtures/wpt/workers/constructors/SharedWorker/undefined.headers new file mode 100644 index 000000000000..e7ec0d6699d0 --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/SharedWorker/undefined.headers @@ -0,0 +1 @@ +Content-Type: text/javascript diff --git a/test/fixtures/wpt/workers/constructors/SharedWorker/unexpected-global-properties.html b/test/fixtures/wpt/workers/constructors/SharedWorker/unexpected-global-properties.html new file mode 100644 index 000000000000..522d31ff56bf --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/SharedWorker/unexpected-global-properties.html @@ -0,0 +1,12 @@ + +unexpected members/interface objects/constructors + + + diff --git a/test/fixtures/wpt/workers/constructors/SharedWorker/unexpected-global-properties.js b/test/fixtures/wpt/workers/constructors/SharedWorker/unexpected-global-properties.js new file mode 100644 index 000000000000..0af893582142 --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/SharedWorker/unexpected-global-properties.js @@ -0,0 +1,9 @@ +const unexpected = 'open print stop getComputedStyle getSelection releaseEvents captureEvents alert confirm prompt addEventStream removeEventStream back forward attachEvent detachEvent navigate DOMParser XMLSerializer XPathEvaluator XSLTProcessor opera Image Option frames Audio SVGUnitTypes SVGZoomAndPan java netscape sun Packages ByteArray closed defaultStatus document event frameElement history innerHeight innerWidth opener outerHeight outerWidth pageXOffset pageYOffset parent screen screenLeft screenTop screenX screenY status top window length'.split(' '); // iterated window in opera and removed expected ones +let log = ''; +for (let i = 0; i < unexpected.length; ++i) { + if (unexpected[i] in self) + log += unexpected[i] + ' '; +} +onconnect = e => { + e.ports[0].postMessage(log); +}; diff --git a/test/fixtures/wpt/workers/constructors/SharedWorker/unresolvable-url.html b/test/fixtures/wpt/workers/constructors/SharedWorker/unresolvable-url.html new file mode 100644 index 000000000000..c68968d77dd9 --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/SharedWorker/unresolvable-url.html @@ -0,0 +1,12 @@ + +resolving broken url + + + + diff --git a/test/fixtures/wpt/workers/constructors/Worker/1 b/test/fixtures/wpt/workers/constructors/Worker/1 new file mode 100644 index 000000000000..ea0b7c8f4ccb --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/Worker/1 @@ -0,0 +1 @@ +postMessage('1'); diff --git a/test/fixtures/wpt/workers/constructors/Worker/1.headers b/test/fixtures/wpt/workers/constructors/Worker/1.headers new file mode 100644 index 000000000000..e7ec0d6699d0 --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/Worker/1.headers @@ -0,0 +1 @@ +Content-Type: text/javascript diff --git a/test/fixtures/wpt/workers/constructors/Worker/AbstractWorker.onerror.html b/test/fixtures/wpt/workers/constructors/Worker/AbstractWorker.onerror.html new file mode 100644 index 000000000000..b27f278bff8e --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/Worker/AbstractWorker.onerror.html @@ -0,0 +1,37 @@ + +AbstractWorker.onerror + + + + + +
+ \ No newline at end of file diff --git a/test/fixtures/wpt/workers/constructors/Worker/AbstractWorker.onerror.js b/test/fixtures/wpt/workers/constructors/Worker/AbstractWorker.onerror.js new file mode 100644 index 000000000000..1594decd3709 --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/Worker/AbstractWorker.onerror.js @@ -0,0 +1,5 @@ +// Throw a runtime error, the UA must report the error for that script. +// https://html.spec.whatwg.org/#runtime-script-errors-2 +for (;;) + throw new Error("error from onerror.js"); +postMessage(1); // shouldn't do anything since the script doesn't compile diff --git a/test/fixtures/wpt/workers/constructors/Worker/Blob-url.html b/test/fixtures/wpt/workers/constructors/Worker/Blob-url.html new file mode 100644 index 000000000000..168fc91ae1d0 --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/Worker/Blob-url.html @@ -0,0 +1,21 @@ + + +Web Workers: Worker - Blob url + + + +
+ diff --git a/test/fixtures/wpt/workers/constructors/Worker/DedicatedWorkerGlobalScope-members.worker.js b/test/fixtures/wpt/workers/constructors/Worker/DedicatedWorkerGlobalScope-members.worker.js new file mode 100644 index 000000000000..2ef466ccdc30 --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/Worker/DedicatedWorkerGlobalScope-members.worker.js @@ -0,0 +1,18 @@ +importScripts("/resources/testharness.js"); + +var expected = [ + 'postMessage', 'onmessage', /* DedicatedWorkerGlobalScope */ + 'self', 'location', 'close', 'onerror', 'onoffline', 'ononline', /* WorkerGlobalScope */ + 'addEventListener', 'removeEventListener', 'dispatchEvent', /* EventListener */ + 'importScripts', 'navigator', /* WorkerUtils */ + 'setTimeout', 'clearTimeout', 'setInterval', 'clearInterval', /* WindowTimers */ + 'btoa', 'atob' /* WindowBase64 */ +]; +for (var i = 0; i < expected.length; ++i) { + var property = expected[i]; + test(function() { + assert_true(property in self); + }, "existence of " + property); +} + +done(); diff --git a/test/fixtures/wpt/workers/constructors/Worker/WEB_FEATURES.yml b/test/fixtures/wpt/workers/constructors/Worker/WEB_FEATURES.yml new file mode 100644 index 000000000000..a489fa783e57 --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/Worker/WEB_FEATURES.yml @@ -0,0 +1,3 @@ +rules: +- use-base-url.html: [base] +- "*": [dedicated-workers] diff --git a/test/fixtures/wpt/workers/constructors/Worker/Worker-constructor.html b/test/fixtures/wpt/workers/constructors/Worker/Worker-constructor.html new file mode 100644 index 000000000000..6d6843b77b69 --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/Worker/Worker-constructor.html @@ -0,0 +1,60 @@ + +Test Worker constructor functionality. + + + diff --git a/test/fixtures/wpt/workers/constructors/Worker/constructor-utf16-bom.html b/test/fixtures/wpt/workers/constructors/Worker/constructor-utf16-bom.html new file mode 100644 index 000000000000..0e423922feaf --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/Worker/constructor-utf16-bom.html @@ -0,0 +1,21 @@ + + +Worker constructor: UTF-16 BOM should trigger error + + + \ No newline at end of file diff --git a/test/fixtures/wpt/workers/constructors/Worker/ctor-1.html b/test/fixtures/wpt/workers/constructors/Worker/ctor-1.html new file mode 100644 index 000000000000..bd865261fc6e --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/Worker/ctor-1.html @@ -0,0 +1,23 @@ + + +1 as argument + + + + +
+ + diff --git a/test/fixtures/wpt/workers/constructors/Worker/ctor-null.html b/test/fixtures/wpt/workers/constructors/Worker/ctor-null.html new file mode 100644 index 000000000000..94ab71aeff62 --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/Worker/ctor-null.html @@ -0,0 +1,23 @@ + + +null as argument + + + + +
+ + diff --git a/test/fixtures/wpt/workers/constructors/Worker/ctor-undefined.html b/test/fixtures/wpt/workers/constructors/Worker/ctor-undefined.html new file mode 100644 index 000000000000..2d9eb6e65637 --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/Worker/ctor-undefined.html @@ -0,0 +1,23 @@ + + +undefined as argument + + + + +
+ + diff --git a/test/fixtures/wpt/workers/constructors/Worker/expected-self-properties.worker.js b/test/fixtures/wpt/workers/constructors/Worker/expected-self-properties.worker.js new file mode 100644 index 000000000000..72edf495eb67 --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/Worker/expected-self-properties.worker.js @@ -0,0 +1,11 @@ +importScripts("/resources/testharness.js"); + +var expected = ['XMLHttpRequest', 'WebSocket', 'EventSource', 'MessageChannel', 'Worker']; +for (var i = 0; i < expected.length; ++i) { + var property = expected[i]; + test(function() { + assert_true(property in self); + }, "existence of " + property); +} + +done(); diff --git a/test/fixtures/wpt/workers/constructors/Worker/null b/test/fixtures/wpt/workers/constructors/Worker/null new file mode 100644 index 000000000000..6d079b514cf5 --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/Worker/null @@ -0,0 +1 @@ +postMessage('null'); diff --git a/test/fixtures/wpt/workers/constructors/Worker/null.headers b/test/fixtures/wpt/workers/constructors/Worker/null.headers new file mode 100644 index 000000000000..e7ec0d6699d0 --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/Worker/null.headers @@ -0,0 +1 @@ +Content-Type: text/javascript diff --git a/test/fixtures/wpt/workers/constructors/Worker/same-origin.html b/test/fixtures/wpt/workers/constructors/Worker/same-origin.html new file mode 100644 index 000000000000..56dbfe3b3f3a --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/Worker/same-origin.html @@ -0,0 +1,65 @@ + + +same-origin checks; the script is in a script element + + + + +
+ diff --git a/test/fixtures/wpt/workers/constructors/Worker/sample_worker/worker.js b/test/fixtures/wpt/workers/constructors/Worker/sample_worker/worker.js new file mode 100644 index 000000000000..19bbea58e767 --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/Worker/sample_worker/worker.js @@ -0,0 +1 @@ +onmessage = function(event) { postMessage(event.data); } diff --git a/test/fixtures/wpt/workers/constructors/Worker/script-utf16be.js b/test/fixtures/wpt/workers/constructors/Worker/script-utf16be.js new file mode 100644 index 000000000000..fa15f44bd0a6 Binary files /dev/null and b/test/fixtures/wpt/workers/constructors/Worker/script-utf16be.js differ diff --git a/test/fixtures/wpt/workers/constructors/Worker/script-utf16le.js b/test/fixtures/wpt/workers/constructors/Worker/script-utf16le.js new file mode 100644 index 000000000000..6253e4ceac25 Binary files /dev/null and b/test/fixtures/wpt/workers/constructors/Worker/script-utf16le.js differ diff --git a/test/fixtures/wpt/workers/constructors/Worker/terminate.html b/test/fixtures/wpt/workers/constructors/Worker/terminate.html new file mode 100644 index 000000000000..b9af76e2fb1b --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/Worker/terminate.html @@ -0,0 +1,34 @@ + +terminate() + + + +
+ \ No newline at end of file diff --git a/test/fixtures/wpt/workers/constructors/Worker/terminate.js b/test/fixtures/wpt/workers/constructors/Worker/terminate.js new file mode 100644 index 000000000000..e6349c3320ee --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/Worker/terminate.js @@ -0,0 +1,4 @@ +(function f() { + postMessage(1); + setTimeout(f, 0); +})(); \ No newline at end of file diff --git a/test/fixtures/wpt/workers/constructors/Worker/undefined b/test/fixtures/wpt/workers/constructors/Worker/undefined new file mode 100644 index 000000000000..bc7f482e94ad --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/Worker/undefined @@ -0,0 +1 @@ +postMessage('undefined'); diff --git a/test/fixtures/wpt/workers/constructors/Worker/undefined.headers b/test/fixtures/wpt/workers/constructors/Worker/undefined.headers new file mode 100644 index 000000000000..e7ec0d6699d0 --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/Worker/undefined.headers @@ -0,0 +1 @@ +Content-Type: text/javascript diff --git a/test/fixtures/wpt/workers/constructors/Worker/unexpected-self-properties.worker.js b/test/fixtures/wpt/workers/constructors/Worker/unexpected-self-properties.worker.js new file mode 100644 index 000000000000..acdd0eb303b4 --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/Worker/unexpected-self-properties.worker.js @@ -0,0 +1,11 @@ +importScripts("/resources/testharness.js"); + +var unexpected = ['open', 'print', 'stop', 'getComputedStyle', 'getSelection', 'releaseEvents', 'captureEvents', 'alert', 'confirm', 'prompt', 'addEventStream', 'removeEventStream', 'back', 'forward', 'attachEvent', 'detachEvent', 'navigate', 'DOMParser', 'XMLSerializer', 'XPathEvaluator', 'XSLTProcessor', 'opera', 'Image', 'Option', 'frames', 'Audio', 'SVGUnitTypes', 'SVGZoomAndPan', 'java', 'netscape', 'sun', 'Packages', 'ByteArray', 'closed', 'defaultStatus', 'document', 'event', 'frameElement', 'history', 'innerHeight', 'innerWidth', 'opener', 'outerHeight', 'outerWidth', 'pageXOffset', 'pageYOffset', 'parent', 'screen', 'screenLeft', 'screenTop', 'screenX', 'screenY', 'status', 'top', 'window', 'length', 'SharedWorker']; // iterated window in opera and removed expected ones +for (var i = 0; i < unexpected.length; ++i) { + var property = unexpected[i]; + test(function() { + assert_false(property in self); + }, "existence of " + property); +} + +done(); diff --git a/test/fixtures/wpt/workers/constructors/Worker/use-base-url.html b/test/fixtures/wpt/workers/constructors/Worker/use-base-url.html new file mode 100644 index 000000000000..94ce2a71f142 --- /dev/null +++ b/test/fixtures/wpt/workers/constructors/Worker/use-base-url.html @@ -0,0 +1,18 @@ + + +Use the document base url when resolving worker URLs + + + + + diff --git a/test/fixtures/wpt/workers/data-url-shared-window.html b/test/fixtures/wpt/workers/data-url-shared-window.html new file mode 100644 index 000000000000..7459f592861b --- /dev/null +++ b/test/fixtures/wpt/workers/data-url-shared-window.html @@ -0,0 +1,25 @@ + + +data URL shared worker + + + + + diff --git a/test/fixtures/wpt/workers/data-url-shared.html b/test/fixtures/wpt/workers/data-url-shared.html new file mode 100644 index 000000000000..aae76d46cd7a --- /dev/null +++ b/test/fixtures/wpt/workers/data-url-shared.html @@ -0,0 +1,78 @@ + +data URL shared workers + + + + diff --git a/test/fixtures/wpt/workers/data-url.html b/test/fixtures/wpt/workers/data-url.html new file mode 100644 index 000000000000..f8fe65e520c4 --- /dev/null +++ b/test/fixtures/wpt/workers/data-url.html @@ -0,0 +1,67 @@ + +data URL dedicated workers + + + diff --git a/test/fixtures/wpt/workers/dedicated-worker-from-blob-url.window.js b/test/fixtures/wpt/workers/dedicated-worker-from-blob-url.window.js new file mode 100644 index 000000000000..61a1c06c246a --- /dev/null +++ b/test/fixtures/wpt/workers/dedicated-worker-from-blob-url.window.js @@ -0,0 +1,47 @@ +function message_from_port(port) { + return new Promise((resolve, reject) => { + port.onmessage = e => resolve(e.data); + port.onerror = e => reject(e); + }); +} + +promise_test(async t => { + const run_result = 'worker_OK'; + const blob_contents = 'self.postMessage("' + run_result + '");'; + const blob = new Blob([blob_contents]); + const url = URL.createObjectURL(blob); + + const worker = new Worker(url); + const reply = await message_from_port(worker); + assert_equals(reply, run_result); +}, 'Creating a dedicated worker from a blob URL works.'); + +promise_test(async t => { + const run_result = 'worker_OK'; + const blob_contents = 'self.postMessage("' + run_result + '");'; + const blob = new Blob([blob_contents]); + const url = URL.createObjectURL(blob); + + const worker = new Worker(url); + URL.revokeObjectURL(url); + const reply = await message_from_port(worker); + assert_equals(reply, run_result); +}, 'Creating a dedicated worker from a blob URL works immediately before revoking.'); + +promise_test(async t => { + const run_result = false; + const blob_contents = ` +let constructedRequest = false; +try { + new Request("./file.js"); + constructedRequest = true; +} catch (e) {} +self.postMessage(constructedRequest); +`; + const blob = new Blob([blob_contents]); + const url = URL.createObjectURL(blob); + + const worker = new Worker(url); + const reply = await message_from_port(worker); + assert_equals(reply, run_result, "Should not be able to resolve request with relative file path in blob"); +}, 'Blob URLs should not resolve relative to document base URL.'); diff --git a/test/fixtures/wpt/workers/dedicated-worker-in-data-url-context.window.js b/test/fixtures/wpt/workers/dedicated-worker-in-data-url-context.window.js new file mode 100644 index 000000000000..124914012dbb --- /dev/null +++ b/test/fixtures/wpt/workers/dedicated-worker-in-data-url-context.window.js @@ -0,0 +1,111 @@ +// META: title=data URL dedicated worker in data URL context +// META: script=/service-workers/service-worker/resources/test-helpers.sub.js +const mimeType = 'application/javascript'; + +// Tests creating a dedicated worker in a data URL iframe. +promise_test(async t => { + const nestedWorkerScriptURL = + new URL('/workers/support/post-message-on-load-worker.js', location.href); + + // This code will be executed in a data URL iframe. The iframe tries to create + // a dedicated worker from |nestedWorkerScriptURL|, but that should result in + // a failure. This is because the data URL iframe has an opaque origin, and + // script fetch is handled as a cross-origin request. + const frameCode = ` + + `; + + const p = new Promise(r => window.onmessage = e => r(e.data)); + const frame = await with_iframe(`data:text/html;base64,${btoa(frameCode)}`); + const result = await p; + assert_equals(result, 'PASS'); +}, 'Create a dedicated worker in a data url frame'); + +// Tests creating a dedicated worker in a data URL dedicated worker (i.e., +// nested dedicated worker). +promise_test(async t => { + const nestedWorkerScriptURL = + new URL('/workers/support/post-message-on-load-worker.js', location.href); + + // This code will be executed in a data URL dedicated worker. The worker tries + // to create a nested dedicated worker from |nestedWorkerScriptURL|, but that + // should result in a failure. This is because the data URL dedicated worker + // has an opaque origin, and script fetch is handled as a cross-origin + // request. + const workerCode = ` + try { + const worker = new Worker('${nestedWorkerScriptURL}'); + worker.onmessage = + e => postMessage('Worker construction unexpectedly succeeded'); + worker.onerror = e => postMessage('PASS'); + } catch (e) { + // Cross-origin request should asynchronously fail during worker script + // fetch because its request mode is 'same-origin'. + postMessage('Worker construction unexpectedly synchronously failed'); + } + `; + + const result = await new Promise((resolve, reject) => { + const worker = new Worker(`data:${mimeType};base64,${btoa(workerCode)}`); + worker.onmessage = e => resolve(e.data); + worker.onerror = e => reject(e.message); + }); + assert_equals(result, 'PASS'); +}, 'Create a dedicated worker in a data url dedicated worker'); + +// Tests creating a data URL dedicated worker in a data URL iframe. +promise_test(async t => { + // This code will be executed in a data URL iframe. The iframe tries to create + // a data URL dedicated worker. Fetching a data URL from the data URL iframe + // whose origin is opaque is allowed, so the worker construction should + // succeed. The iframe posts the result to the parent frame. + const frameCode = ` + + `; + + const p = new Promise(r => window.onmessage = e => r(e.data)); + const frame = await with_iframe(`data:text/html;base64,${btoa(frameCode)}`); + const result = await p; + assert_equals(result, 'PASS'); +}, 'Create a data url dedicated worker in a data url frame'); + +// Tests creating a data URL dedicated worker in a data URL dedicated worker +// (i.e., nested dedicated worker). +promise_test(async t => { + // This code will be executed in a data URL dedicated worker. The worker tries + // to create a nested data URL dedicated worker. Fetching a data URL from the + // data URL dedicated worker is allowed, so the worker construction should + // succeed. The worker posts the result to the parent frame. + const workerCode = ` + const worker = new Worker('data:${mimeType},postMessage("PASS");'); + worker.onmessage = e => postMessage(e.data); + worker.onerror = e => postMessage('FAIL: ' + e.message); + `; + + const result = await new Promise((resolve, reject) => { + const worker = new Worker(`data:${mimeType};base64,${btoa(workerCode)}`); + worker.onmessage = e => resolve(e.data); + worker.onerror = e => reject(e.message); + }); + assert_equals(result, 'PASS'); +}, 'Create a data url dedicated worker in a data url dedicated worker'); diff --git a/test/fixtures/wpt/workers/dedicated-worker-parse-error-failure.html b/test/fixtures/wpt/workers/dedicated-worker-parse-error-failure.html new file mode 100644 index 000000000000..ed475dab105f --- /dev/null +++ b/test/fixtures/wpt/workers/dedicated-worker-parse-error-failure.html @@ -0,0 +1,27 @@ + +DedicatedWorker: parse error failure + + + + + diff --git a/test/fixtures/wpt/workers/dedicated-worker-runtime-error-is-not-parse-error.html b/test/fixtures/wpt/workers/dedicated-worker-runtime-error-is-not-parse-error.html new file mode 100644 index 000000000000..94e470c5dc0d --- /dev/null +++ b/test/fixtures/wpt/workers/dedicated-worker-runtime-error-is-not-parse-error.html @@ -0,0 +1,36 @@ + +DedicatedWorker: runtime errors are not parse errors + + + diff --git a/test/fixtures/wpt/workers/examples/fetch_tests_from_worker.html b/test/fixtures/wpt/workers/examples/fetch_tests_from_worker.html new file mode 100644 index 000000000000..5ac765c7eeae --- /dev/null +++ b/test/fixtures/wpt/workers/examples/fetch_tests_from_worker.html @@ -0,0 +1,21 @@ + + + + + diff --git a/test/fixtures/wpt/workers/examples/fetch_tests_from_worker.js b/test/fixtures/wpt/workers/examples/fetch_tests_from_worker.js new file mode 100644 index 000000000000..01ba12a622f3 --- /dev/null +++ b/test/fixtures/wpt/workers/examples/fetch_tests_from_worker.js @@ -0,0 +1,28 @@ +// This file is an example of a hand-written test using +// fetch_tests_from_worker(). +// Unlike *.any.js or *.worker.js tests, fetch_tests_from_worker.html/js files +// are manually written and no generated glue code are involved. + +// fetch_tests_from_worker() requires testharness.js both on the parent +// document and on the worker. +importScripts("/resources/testharness.js"); + +// ============================================================================ + +// Test body. +test(() => { + assert_equals(1, 1, "1 == 1"); + }, + "Test that should pass" +); + +// ============================================================================ + +// `done()` is always needed at the bottom for dedicated workers and shared +// workers, even if you write `async_test()` or `promise_test()`. +// `async_test()` and `promise_test()` called before this `done()` +// will continue and assertions/failures after this `done()` are not ignored. +// See +// https://web-platform-tests.org/writing-tests/testharness-api.html#determining-when-all-tests-are-complete +// for details. +done(); diff --git a/test/fixtures/wpt/workers/examples/general.any.js b/test/fixtures/wpt/workers/examples/general.any.js new file mode 100644 index 000000000000..cb5d61eafbec --- /dev/null +++ b/test/fixtures/wpt/workers/examples/general.any.js @@ -0,0 +1,34 @@ +// META: global=worker + +// See +// https://web-platform-tests.org/writing-tests/testharness.html#multi-global-tests +// for how to specify in which global scopes to run this tests, +// how to specify additional scripts needed, etc. + +// testharness.js is imported (via importScripts()) by generated glue code by +// WPT server. +// See ClassicWorkerHandler in +// https://github.com/web-platform-tests/wpt/blob/master/tools/serve/serve.py. + +// ============================================================================ + +// Test body. +// .any.js tests are always testharness.js-based. +test(() => { + assert_equals(1, 1, "1 == 1"); + }, + "Test that should pass" +); + +test(() => { + // This file is "general.any.js" but the worker top-level script is + // "general.any.worker.js", which is generated by the WPT server. + assert_equals(location.pathname, "/workers/examples/general.any.worker.js"); + }, + "Worker top-level script is a generated script." +); + +// done() is NOT needed in .any.js tests, as it is called by generated +// glue code by the WPT server. +// See ClassicWorkerHandler in +// https://github.com/web-platform-tests/wpt/blob/master/tools/serve/serve.py. diff --git a/test/fixtures/wpt/workers/examples/general.worker.js b/test/fixtures/wpt/workers/examples/general.worker.js new file mode 100644 index 000000000000..aeca236781bf --- /dev/null +++ b/test/fixtures/wpt/workers/examples/general.worker.js @@ -0,0 +1,35 @@ +// This file is an example of a test using *.worker.js mechanism. +// The parent document that calls fetch_tests_from_worker() is auto-generated +// but there are no generated code in the worker side. + +// fetch_tests_from_worker() requires testharness.js both on the parent +// document and on the worker. +importScripts("/resources/testharness.js"); + +// ============================================================================ + +// Test body. +test(() => { + assert_equals(1, 1, "1 == 1"); + }, + "Test that should pass" +); + +test(() => { + // This file is "general.worker.js" and this file itself is the worker + // top-level script (which is different from the .any.js case). + assert_equals(location.pathname, "/workers/examples/general.worker.js"); + }, + "Worker top-level script is the .worker.js file itself." +); + +// ============================================================================ + +// `done()` is always needed at the bottom for dedicated workers and shared +// workers, even if you write `async_test()` or `promise_test()`. +// `async_test()` and `promise_test()` called before this `done()` +// will continue and assertions/failures after this `done()` are not ignored. +// See +// https://web-platform-tests.org/writing-tests/testharness-api.html#determining-when-all-tests-are-complete +// for details. +done(); diff --git a/test/fixtures/wpt/workers/examples/onconnect.any.js b/test/fixtures/wpt/workers/examples/onconnect.any.js new file mode 100644 index 000000000000..d43a9921833d --- /dev/null +++ b/test/fixtures/wpt/workers/examples/onconnect.any.js @@ -0,0 +1,4 @@ +// META: global=sharedworker +const t = async_test("onconnect is called"); +onconnect = t.step_func_done((event) => { +}); diff --git a/test/fixtures/wpt/workers/importscripts_mime.any.js b/test/fixtures/wpt/workers/importscripts_mime.any.js new file mode 100644 index 000000000000..bfdfc191fd3e --- /dev/null +++ b/test/fixtures/wpt/workers/importscripts_mime.any.js @@ -0,0 +1,52 @@ +// META: global=worker +// +// Tentative test for https://github.com/whatwg/html/issues/3255 + +let test_cases = [ + // Supported mimetypes: + ["text/javascript", true], + ["application/javascript", true], + ["text/ecmascript", true], + + // Blocked mimetpyes: + ["image/png", false], + ["text/csv", false], + ["video/mpeg", false], + + // Legacy mimetypes: + ["text/html", false], + ["text/plain", false], + ["application/xml", false], + ["application/octet-stream", false], + + // Potato mimetypes: + ["text/potato", false], + ["potato/text", false], + ["aaa/aaa", false], + ["zzz/zzz", false], + + // Parameterized mime types: + ["text/javascript; charset=utf-8", true], + ["text/javascript;charset=utf-8", true], + ["text/javascript;bla;bla", true], + ["text/csv; charset=utf-8", false], + ["text/csv;charset=utf-8", false], + ["text/csv;bla;bla", false], + + // Funky capitalization: + ["Text/html", false], + ["text/Html", false], + ["TeXt/HtMl", false], + ["TEXT/HTML", false], +]; + +for (const [mimeType, isScriptType] of test_cases) { + test(t => { + let import_url = "/workers/support/imported_script.py?mime=" + mimeType; + if (isScriptType) { + assert_equals(undefined, importScripts(import_url)); + } else { + assert_throws_dom("NetworkError", _ => { importScripts(import_url) }) + } + }, "importScripts() requires scripty MIME types: " + mimeType + " is " + (isScriptType ? "allowed" : "blocked") + "."); +} diff --git a/test/fixtures/wpt/workers/importscripts_mime_local.any.js b/test/fixtures/wpt/workers/importscripts_mime_local.any.js new file mode 100644 index 000000000000..62d690d8af0e --- /dev/null +++ b/test/fixtures/wpt/workers/importscripts_mime_local.any.js @@ -0,0 +1,66 @@ +// META: global=dedicatedworker,sharedworker +// +// Tests for https://github.com/whatwg/html/issues/8869 + +importScripts("/resources/testharness.js"); + +let test_cases = [ + // Supported mimetypes: + ["text/javascript", true], + ["application/javascript", true], + ["text/ecmascript", true], + + // Blocked mimetpyes: + ["image/png", false], + ["text/csv", false], + ["video/mpeg", false], + + // Legacy mimetypes: + ["text/html", false], + ["text/plain", false], + ["application/xml", false], + ["application/octet-stream", false], + + // Potato mimetypes: + ["text/potato", false], + ["potato/text", false], + ["aaa/aaa", false], + ["zzz/zzz", false], + + // Parameterized mime types: + ["text/javascript; charset=utf-8", true], + ["text/javascript;charset=utf-8", true], + ["text/javascript;bla;bla", true], + ["text/csv; charset=utf-8", false], + ["text/csv;charset=utf-8", false], + ["text/csv;bla;bla", false], + + // Funky capitalization: + ["Text/html", false], + ["text/Html", false], + ["TeXt/HtMl", false], + ["TEXT/HTML", false], +]; + +for (const [mimeType, isScriptType] of test_cases) { + test(t => { + let import_url = `data:${ mimeType },`; + if (isScriptType) { + assert_equals(undefined, importScripts(import_url)); + } else { + assert_throws_dom("NetworkError", _ => { importScripts(import_url) }) + } + }, "importScripts() requires scripty MIME types for data: URLs: " + mimeType + " is " + (isScriptType ? "allowed" : "blocked") + "."); +} + +for (const [mimeType, isScriptType] of test_cases) { + test(t => { + let import_url = URL.createObjectURL(new Blob([""], { type: mimeType })); + if (isScriptType) { + assert_equals(undefined, importScripts(import_url)); + } else { + assert_throws_dom("NetworkError", _ => { importScripts(import_url) }) + } + }, "importScripts() requires scripty MIME types for blob: URLs: " + mimeType + " is " + (isScriptType ? "allowed" : "blocked") + "."); +} +done(); diff --git a/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/EventTarget.worker.js b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/EventTarget.worker.js new file mode 100644 index 000000000000..954c46c07eca --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/EventTarget.worker.js @@ -0,0 +1,23 @@ +importScripts("/resources/testharness.js"); + +test(function(t) { + var i = 0; + addEventListener("message", function listener(evt) { + t.step(function() { + ++i; + removeEventListener("message", listener, true); + }); + }, true); + self.dispatchEvent(new Event("message")); + self.dispatchEvent(new Event("message")); + assert_equals(i, 1); +}, "removeEventListener"); + +test(function() { + addEventListener("message", this.step_func(function(evt) { + assert_equals(evt.target, self); + }), true); + self.dispatchEvent(new Event("message")); +}, "target"); + +done(); diff --git a/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/WEB_FEATURES.yml b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/WEB_FEATURES.yml new file mode 100644 index 000000000000..b4d9c5323522 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/WEB_FEATURES.yml @@ -0,0 +1,2 @@ +rules: +- "*": [dedicated-workers] diff --git a/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/onmessage.worker.js b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/onmessage.worker.js new file mode 100644 index 000000000000..6f285caac385 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/onmessage.worker.js @@ -0,0 +1,40 @@ +importScripts("/resources/testharness.js"); + +test(function() { + self.onmessage = 1; + assert_equals(self.onmessage, null, + "attribute should return null after being set to a primitive"); +}, "Setting onmessage to 1"); + +test(function() { + var object = { + handleEvent: this.unreached_func() + }; + self.onmessage = object; + assert_equals(self.onmessage, object, + "attribute should return the object it was set to."); + + self.dispatchEvent(new Event("message")); +}, "Setting onmessage to an object"); + +test(function() { + var triggered = false; + var f = function(e) { triggered = true; }; + self.onmessage = f; + assert_equals(self.onmessage, f, + "attribute should return the function it was set to."); + + self.dispatchEvent(new Event("message")); + assert_true(triggered, "event handler should have been triggered"); +}, "Setting onmessage to a function"); + + +test(function() { + assert_not_equals(self.onmessage, null, + "attribute should not return null after being set to a function"); + self.onmessage = 1; + assert_equals(self.onmessage, null, + "attribute should return null after being set to a primitive"); +}, "Setting onmessage to 1 (again)"); + +done(); diff --git a/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/WEB_FEATURES.yml b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/WEB_FEATURES.yml new file mode 100644 index 000000000000..6eea69ad8a80 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/WEB_FEATURES.yml @@ -0,0 +1,2 @@ +rules: +- "**": [postmessage] diff --git a/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/event-ports-dedicated.html b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/event-ports-dedicated.html new file mode 100644 index 000000000000..be89478786b6 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/event-ports-dedicated.html @@ -0,0 +1,15 @@ + +e.ports in dedicated worker + + +
+ \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/event-ports-dedicated.js b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/event-ports-dedicated.js new file mode 100644 index 000000000000..c5cc9f8d9f58 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/event-ports-dedicated.js @@ -0,0 +1,3 @@ +onmessage = function(e) { + postMessage(e.ports instanceof Array && e.ports.length === 0); +} \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/imagedata-cloned-canvas-in-array.html b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/imagedata-cloned-canvas-in-array.html new file mode 100644 index 000000000000..7c019a999348 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/imagedata-cloned-canvas-in-array.html @@ -0,0 +1,22 @@ + +posting an imagedata (from a cloned canvas) in an array + + +
+ \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/imagedata-cloned-canvas-in-array.js b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/imagedata-cloned-canvas-in-array.js new file mode 100644 index 000000000000..76eaee366c78 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/imagedata-cloned-canvas-in-array.js @@ -0,0 +1,10 @@ +onmessage = function(e) { + function processPixels(imagedata) { + var pixeldata = imagedata.data; + for (var i = 0; i < pixeldata.length; i = i+4) { + pixeldata[i] = 128; + } + postMessage(imagedata); + } + processPixels(e.data[0]); +} \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/message-event.html b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/message-event.html new file mode 100644 index 000000000000..91ec632685f3 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/message-event.html @@ -0,0 +1,23 @@ + + +'message' event properties + + + +
+ diff --git a/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/message-event.js b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/message-event.js new file mode 100644 index 000000000000..54a250005e8d --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/message-event.js @@ -0,0 +1 @@ +postMessage("test"); diff --git a/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/return-value.worker.js b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/return-value.worker.js new file mode 100644 index 000000000000..521251699a08 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/return-value.worker.js @@ -0,0 +1,8 @@ +importScripts("/resources/testharness.js"); + +test(function() { + var rv = postMessage(1); + assert_equals(rv, undefined); +}, "return value of postMessage"); + +done(); diff --git a/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/second-argument-dictionary.html b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/second-argument-dictionary.html new file mode 100644 index 000000000000..1749644908f2 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/second-argument-dictionary.html @@ -0,0 +1,16 @@ + +Using dictionary as postMessage's second argument + + +
+ \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/second-argument-dictionary.js b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/second-argument-dictionary.js new file mode 100644 index 000000000000..0cb80f8faeb1 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/second-argument-dictionary.js @@ -0,0 +1,7 @@ +onmessage = (event) => { + try { + postMessage(event.data, {transfer: [event.data]}); + } catch(e) { + postMessage(''+e); + } +} \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/second-argument-null-in-array.html b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/second-argument-null-in-array.html new file mode 100644 index 000000000000..8db06b411642 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/second-argument-null-in-array.html @@ -0,0 +1,14 @@ + +Using [null] in postMessage's second argument + + +
+ \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/second-argument-null-in-array.js b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/second-argument-null-in-array.js new file mode 100644 index 000000000000..95a094234b7f --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/second-argument-null-in-array.js @@ -0,0 +1,5 @@ +try { + postMessage(false, [null]); +} catch(e) { + postMessage(e instanceof TypeError); +} \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/second-argument-null.html b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/second-argument-null.html new file mode 100644 index 000000000000..68d9caabc50e --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/second-argument-null.html @@ -0,0 +1,14 @@ + +Using null in postMessage's second argument + + +
+ \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/second-argument-null.js b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/second-argument-null.js new file mode 100644 index 000000000000..6f6f9e799ff1 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/second-argument-null.js @@ -0,0 +1,5 @@ +try { + postMessage(1, null); +} catch(e) { + postMessage(e instanceof TypeError); +} \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/second-argument-undefined.html b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/second-argument-undefined.html new file mode 100644 index 000000000000..c7dcb3c5c0f3 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/second-argument-undefined.html @@ -0,0 +1,14 @@ + +Using undefined in postMessage's second argument + + +
+ \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/second-argument-undefined.js b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/second-argument-undefined.js new file mode 100644 index 000000000000..6f11443c4a88 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/second-argument-undefined.js @@ -0,0 +1,5 @@ +try { + postMessage(1, undefined); +} catch(e) { + postMessage(''+e); +} \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/setting-postMessage.html b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/setting-postMessage.html new file mode 100644 index 000000000000..5b3e014e1e08 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/setting-postMessage.html @@ -0,0 +1,14 @@ + +setting postMessage + + +
+ \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/setting-postMessage.js b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/setting-postMessage.js new file mode 100644 index 000000000000..5426ebde0d4c --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/setting-postMessage.js @@ -0,0 +1,3 @@ +var x = postMessage; +postMessage = 1; +x(postMessage == 1); \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/structured-clone-imagedata.html b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/structured-clone-imagedata.html new file mode 100644 index 000000000000..c7fbb0f9560d --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/structured-clone-imagedata.html @@ -0,0 +1,18 @@ + +structured clone of ImageData + + +
+ \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/structured-clone-imagedata.js b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/structured-clone-imagedata.js new file mode 100644 index 000000000000..04cd7eea5ba8 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/structured-clone-imagedata.js @@ -0,0 +1,5 @@ +onmessage = function(e) { + var imagedata = e.data; + imagedata.data[0] = 128; + postMessage(imagedata); +} \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/structured-clone-message.html b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/structured-clone-message.html new file mode 100644 index 000000000000..edf4fb7e0e5c --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/structured-clone-message.html @@ -0,0 +1,38 @@ + +structured clone of message + + +
+ \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/structured-clone-message.js b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/structured-clone-message.js new file mode 100644 index 000000000000..db456e1fbaec --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/DedicatedWorkerGlobalScope/postMessage/structured-clone-message.js @@ -0,0 +1,14 @@ +var err = new Error('foo'); +var date = new Date(); +// commented out bits are either tested elsewhere or not supported yet. or uncloneable. +var tests = [undefined, null, false, true, 1, NaN, Infinity, 'foo', date, /foo/, /* ImageData, File, FileData, FileList,*/ null/*self*/, + [undefined, null, false, true, 1, NaN, Infinity, 'foo', /*date, /foo/,*/ null/*self*/, /*[], {},*/ null/*err*/], + {a:undefined, b:null, c:false, d:true, e:1, f:NaN, g:Infinity, h:'foo', /*i:date, j:/foo/,*/ k:null/*self*/, /*l:[], m:{},*/ n:null/*err*/}, + null/*err*/]; +for (var i = 0; i < tests.length; ++i) { + try { + postMessage(tests[i]); + } catch(e) { + postMessage(''+e); + } +} \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/SharedWorkerGlobalScope/WEB_FEATURES.yml b/test/fixtures/wpt/workers/interfaces/SharedWorkerGlobalScope/WEB_FEATURES.yml new file mode 100644 index 000000000000..73744331853b --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/SharedWorkerGlobalScope/WEB_FEATURES.yml @@ -0,0 +1,2 @@ +rules: +- "**": [shared-workers] diff --git a/test/fixtures/wpt/workers/interfaces/SharedWorkerGlobalScope/name/getting.html b/test/fixtures/wpt/workers/interfaces/SharedWorkerGlobalScope/name/getting.html new file mode 100644 index 000000000000..c3a52d12e8a3 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/SharedWorkerGlobalScope/name/getting.html @@ -0,0 +1,17 @@ + +getting name + + +
+ diff --git a/test/fixtures/wpt/workers/interfaces/SharedWorkerGlobalScope/name/getting.js b/test/fixtures/wpt/workers/interfaces/SharedWorkerGlobalScope/name/getting.js new file mode 100644 index 000000000000..acf89ca6f678 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/SharedWorkerGlobalScope/name/getting.js @@ -0,0 +1,9 @@ +addEventListener('connect', function(e) { + var passed; + switch (location.hash) { + case '#1': passed = name == ''; break; + case '#2': passed = name == 'a'; break; + case '#3': passed = name == '0'; break; + } + e.ports[0].postMessage(passed); +}, false); diff --git a/test/fixtures/wpt/workers/interfaces/SharedWorkerGlobalScope/name/setting.html b/test/fixtures/wpt/workers/interfaces/SharedWorkerGlobalScope/name/setting.html new file mode 100644 index 000000000000..ddd856971019 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/SharedWorkerGlobalScope/name/setting.html @@ -0,0 +1,15 @@ + +setting name + + +
+ diff --git a/test/fixtures/wpt/workers/interfaces/SharedWorkerGlobalScope/name/setting.js b/test/fixtures/wpt/workers/interfaces/SharedWorkerGlobalScope/name/setting.js new file mode 100644 index 000000000000..c705e9c40a6d --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/SharedWorkerGlobalScope/name/setting.js @@ -0,0 +1,4 @@ +addEventListener('connect', function(e) { + name = 1; + e.ports[0].postMessage(name); +}, false); diff --git a/test/fixtures/wpt/workers/interfaces/SharedWorkerGlobalScope/onconnect.html b/test/fixtures/wpt/workers/interfaces/SharedWorkerGlobalScope/onconnect.html new file mode 100644 index 000000000000..8a0f103d40e1 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/SharedWorkerGlobalScope/onconnect.html @@ -0,0 +1,14 @@ + +onconnect + + +
+ diff --git a/test/fixtures/wpt/workers/interfaces/SharedWorkerGlobalScope/onconnect.js b/test/fixtures/wpt/workers/interfaces/SharedWorkerGlobalScope/onconnect.js new file mode 100644 index 000000000000..34a2be51fc47 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/SharedWorkerGlobalScope/onconnect.js @@ -0,0 +1,19 @@ +var results = []; +try { + self.onconnect = 1; + results.push(String(onconnect)); +} catch(e) { + results.push(''+e); +} +try { + self.onconnect = {handleEvent:function(){}}; + results.push(String(onconnect)); +} catch(e) { + results.push(''+e); +} +var f = function(e) { + results.push(e.data); + e.ports[0].postMessage(results); +}; +onconnect = f; +results.push(typeof onconnect); diff --git a/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/close/WEB_FEATURES.yml b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/close/WEB_FEATURES.yml new file mode 100644 index 000000000000..bb8d27860d8d --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/close/WEB_FEATURES.yml @@ -0,0 +1,4 @@ +rules: +- setInterval.html: [setinterval] +- setTimeout.html: [settimeout] +- "*": [dedicated-workers] diff --git a/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/close/incoming-message.html b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/close/incoming-message.html new file mode 100644 index 000000000000..0905d07661da --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/close/incoming-message.html @@ -0,0 +1,18 @@ + +close() and incoming message + + +
+ \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/close/incoming-message.js b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/close/incoming-message.js new file mode 100644 index 000000000000..b4f7e7fc0555 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/close/incoming-message.js @@ -0,0 +1,5 @@ +onmessage = function(e) { + postMessage(1); + throw new Error(); +} +close(); \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/close/sending-messages.html b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/close/sending-messages.html new file mode 100644 index 000000000000..da7da66d25b8 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/close/sending-messages.html @@ -0,0 +1,18 @@ + +close() and sending messages + + +
+ \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/close/sending-messages.js b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/close/sending-messages.js new file mode 100644 index 000000000000..2e0a89828880 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/close/sending-messages.js @@ -0,0 +1,3 @@ +postMessage(1); +close(); +postMessage(2); \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/close/setInterval.html b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/close/setInterval.html new file mode 100644 index 000000000000..2f0ba176d494 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/close/setInterval.html @@ -0,0 +1,17 @@ + +close() and setInterval + + +
+ \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/close/setInterval.js b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/close/setInterval.js new file mode 100644 index 000000000000..d165d20eab47 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/close/setInterval.js @@ -0,0 +1,11 @@ +var interval1 = setInterval(function() { + clearInterval(interval1); + postMessage(1); + throw new Error(); +}, 10); +close(); +var interval2 = setInterval(function() { + clearInterval(interval2); + postMessage(1); + throw new Error(); +}, 10); \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/close/setTimeout.html b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/close/setTimeout.html new file mode 100644 index 000000000000..2bddc0947f63 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/close/setTimeout.html @@ -0,0 +1,17 @@ + +close() and setTimeout + + +
+ \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/close/setTimeout.js b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/close/setTimeout.js new file mode 100644 index 000000000000..55eecb05570f --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/close/setTimeout.js @@ -0,0 +1,7 @@ +function x() { + postMessage(1); + throw new Error(); +} +setTimeout(x, 0); +close(); +setTimeout(x, 0); \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/location/WEB_FEATURES.yml b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/location/WEB_FEATURES.yml new file mode 100644 index 000000000000..05c5abb31004 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/location/WEB_FEATURES.yml @@ -0,0 +1,3 @@ +rules: +- redirect-sharedworker.html: [shared-workers] +- "*": [dedicated-workers] diff --git a/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/location/members.html b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/location/members.html new file mode 100644 index 000000000000..3da6b7484d89 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/location/members.html @@ -0,0 +1,22 @@ + +members of WorkerLocation + + +
+ \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/location/members.js b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/location/members.js new file mode 100644 index 000000000000..37235eac8319 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/location/members.js @@ -0,0 +1,3 @@ +postMessage([null, location.href, location.protocol, location.host, + location.hostname, location.port, location.pathname, + location.search, location.hash]); \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/location/post-location-members.js b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/location/post-location-members.js new file mode 100644 index 000000000000..e850b76b6e5f --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/location/post-location-members.js @@ -0,0 +1,8 @@ +postMessage([location.href, + location.protocol, + location.host, + location.hostname, + location.port, + location.pathname, + location.search, + location.hash]); \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/location/redirect-module.html b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/location/redirect-module.html new file mode 100644 index 000000000000..b1a14be8f751 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/location/redirect-module.html @@ -0,0 +1,20 @@ + +WorkerLocation with redirects: module dedicated workers + + +
+ diff --git a/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/location/redirect-sharedworker.html b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/location/redirect-sharedworker.html new file mode 100644 index 000000000000..978a99ac8c4e --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/location/redirect-sharedworker.html @@ -0,0 +1,9 @@ + +WorkerLocation with redirects: classic shared workers + + +
+ diff --git a/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/location/redirect.html b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/location/redirect.html new file mode 100644 index 000000000000..98a0e5476027 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/location/redirect.html @@ -0,0 +1,28 @@ + + +WorkerLocation with redirects: classic dedicated workers + + +
+ + + + diff --git a/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/location/redirect.js b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/location/redirect.js new file mode 100644 index 000000000000..2db48544a2d7 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/location/redirect.js @@ -0,0 +1,7 @@ +importScripts('/resources/testharness.js'); +test(t => { + assert_equals(location.pathname, '/workers/interfaces/WorkerGlobalScope/location/redirect.js'); + assert_equals(location.search, '?a'); + assert_equals(location.hash, ''); +}); +done(); diff --git a/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/location/returns-same-object.any.js b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/location/returns-same-object.any.js new file mode 100644 index 000000000000..dd3560f040cd --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/location/returns-same-object.any.js @@ -0,0 +1,5 @@ +// META: global=worker + +test(function() { + assert_equals(location, location); +}, 'location === location'); diff --git a/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/location/setting-members.html b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/location/setting-members.html new file mode 100644 index 000000000000..7ea79b689704 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/location/setting-members.html @@ -0,0 +1,23 @@ + +setting members of WorkerLocation + + +
+ \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/location/setting-members.js b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/location/setting-members.js new file mode 100644 index 000000000000..4c5c8a35ae88 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/location/setting-members.js @@ -0,0 +1,13 @@ +var exceptions = []; +try { location.href = 1; } catch(e) { exceptions.push('href'); } +try { location.protocol = 1; } catch(e) { exceptions.push('protocol'); } +try { location.host = 1; } catch(e) { exceptions.push('host'); } +try { location.hostname = 1; } catch(e) { exceptions.push('hostname');} +try { location.port = 1; } catch(e) { exceptions.push('port'); } +try { location.pathname = 1; } catch(e) { exceptions.push('pathname'); } +try { location.search = 1; } catch(e) { exceptions.push('search'); } +try { location.hash = 1; } catch(e) { exceptions.push('hash'); } + +postMessage([null, location.href, location.protocol, location.host, + location.hostname, location.port, location.pathname, + location.search, location.hash, exceptions]); \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/location/worker-separate-file.html b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/location/worker-separate-file.html new file mode 100644 index 000000000000..ac8e64dcc886 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/location/worker-separate-file.html @@ -0,0 +1,28 @@ + + +location with a worker in separate file + + +
+ + + diff --git a/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/onerror/WEB_FEATURES.yml b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/onerror/WEB_FEATURES.yml new file mode 100644 index 000000000000..b16862ba1c01 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/onerror/WEB_FEATURES.yml @@ -0,0 +1,2 @@ +rules: +- "**": [dedicated-workers] diff --git a/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/onerror/exception-in-onerror.html b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/onerror/exception-in-onerror.html new file mode 100644 index 000000000000..5f3999db66a7 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/onerror/exception-in-onerror.html @@ -0,0 +1,91 @@ + + + + diff --git a/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/onerror/handled.html b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/onerror/handled.html new file mode 100644 index 000000000000..7d4b03c6cd35 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/onerror/handled.html @@ -0,0 +1,22 @@ + +onerror, "handled" + + +
+ \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/onerror/handled.js b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/onerror/handled.js new file mode 100644 index 000000000000..e58fa4a51521 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/onerror/handled.js @@ -0,0 +1,8 @@ +onerror = function(a, b, c, d) { + postMessage([a, b, c, d]); + return true; // the error is "handled" +} +function x() { + y(); +} +x(); \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/onerror/message-classic-DOMException.html b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/onerror/message-classic-DOMException.html new file mode 100644 index 000000000000..df8c85147509 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/onerror/message-classic-DOMException.html @@ -0,0 +1,7 @@ + + + + + diff --git a/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/onerror/message-classic-Error.html b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/onerror/message-classic-Error.html new file mode 100644 index 000000000000..e026b6ebf09f --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/onerror/message-classic-Error.html @@ -0,0 +1,7 @@ + + + + + diff --git a/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/onerror/message-helper.js b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/onerror/message-helper.js new file mode 100644 index 000000000000..6271329b0314 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/onerror/message-helper.js @@ -0,0 +1,61 @@ +// The error's `message` values in Worker error event handlers are tested. +// While not explicitly specified in the HTML spec, we expect some information +// about thrown errors (e.g. original message, the string "TypeError", etc.) +// to appear in the `message`. + +function prepareHandler(t, error, expectedCount) { + let count = 0; + return t.step_func(e => { + e.preventDefault(); + + assert_regexp_match( + e.message, + /Throw in/, + 'e.message should contain the message of the thrown error'); + + if (error === 'DOMException-TypeError') { + assert_regexp_match(e.message, /TypeError/); + } + + ++count; + if (count >= expectedCount) { + t.done(); + } + }); +} + +function expectErrors(worker, error, expectedCount, title) { + async_test(t => { + worker.addEventListener('error', + prepareHandler(t, error, expectedCount)); + }, title+ ': listener'); + async_test(t => { + worker.onerror = prepareHandler(t, error, expectedCount); + }, title + ': handler'); +} + +function runTest(type, error) { + for (const location of ['toplevel', + 'setTimeout-function', + 'setTimeout-string', + 'onmessage', + 'onerror']) { + const worker = new Worker( + 'throw.js?throw-in-' + location + '&error=' + error, + {type}); + let expectedCount = 1; + if (location === 'onmessage') { + // This makes the worker's message handler to throw an error. + worker.postMessage('foo'); + } + if (location === 'onerror') { + // This makes the worker's message handler to throw an error, + // AND worker's error handler to throw another error. + // Therefore we expect two errors here. + worker.postMessage('foo'); + expectedCount = 2; + } + expectErrors(worker, error, expectedCount, + 'Throw ' + error + ' in ' + location + ': ' + type); + } +} diff --git a/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/onerror/message-module-DOMException.html b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/onerror/message-module-DOMException.html new file mode 100644 index 000000000000..8ed873bc3227 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/onerror/message-module-DOMException.html @@ -0,0 +1,7 @@ + + + + + diff --git a/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/onerror/message-module-Error.html b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/onerror/message-module-Error.html new file mode 100644 index 000000000000..046ff969d6bd --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/onerror/message-module-Error.html @@ -0,0 +1,7 @@ + + + + + diff --git a/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/onerror/not-handled.html b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/onerror/not-handled.html new file mode 100644 index 000000000000..11d03d728b15 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/onerror/not-handled.html @@ -0,0 +1,28 @@ + +onerror, "not handled" + + +
+ diff --git a/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/onerror/not-handled.js b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/onerror/not-handled.js new file mode 100644 index 000000000000..c3254b0ba7e1 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/onerror/not-handled.js @@ -0,0 +1,7 @@ +onerror = function(a, b, c, d) { + return false; // the error is "not handled" +} +function x() { + y(); +} +x(); \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/onerror/propagate-to-window-onerror.html b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/onerror/propagate-to-window-onerror.html new file mode 100644 index 000000000000..b3be77267971 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/onerror/propagate-to-window-onerror.html @@ -0,0 +1,21 @@ + +onerror, "not handled" with only window.onerror defined + + +
+ \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/onerror/propagate-to-window-onerror.js b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/onerror/propagate-to-window-onerror.js new file mode 100644 index 000000000000..0daf488d6f52 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/onerror/propagate-to-window-onerror.js @@ -0,0 +1,4 @@ +function x() { + y(); +} +x(); \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/onerror/throw.js b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/onerror/throw.js new file mode 100644 index 000000000000..704098a6d868 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/onerror/throw.js @@ -0,0 +1,34 @@ +const params = new URL(self.location.href).searchParams; + +self.createError = (message) => { + if (params.get('error') === 'DOMException-TypeError') { + return new DOMException(message, 'TypeError'); + } else { + return new Error(message); + } +}; + +onerror = function() { + if (params.has('throw-in-onerror')) { + throw createError('Throw in error handler'); + } + return false; +}; +onmessage = function() { + throw createError('Throw in message handler'); + return false; +}; + +if (params.has('throw-in-toplevel')) { + throw createError('Throw in toplevel'); +} + +// We don't use step_timeout() here, because we have to test the behavior of +// setTimeout() without wrappers. +if (params.has('throw-in-setTimeout-function')) { + setTimeout(() => { throw createError('Throw in setTimeout function') }, 0); +} + +if (params.has('throw-in-setTimeout-string')) { + setTimeout("throw createError('Throw in setTimeout string')", 0); +} diff --git a/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/self.any.js b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/self.any.js new file mode 100644 index 000000000000..64b4ee2faefb --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerGlobalScope/self.any.js @@ -0,0 +1,19 @@ +// META: global=worker + +test(function() { + assert_equals(self, self); +}, 'self === self'); + +test(function() { + assert_true(self instanceof WorkerGlobalScope); +}, 'self instanceof WorkerGlobalScope'); + +test(function() { + assert_true('self' in self); +}, '\'self\' in self'); + +test(function() { + var x = self; + self = 1; + assert_equals(self, x); +}, 'self = 1'); diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/WindowTimers/001.html b/test/fixtures/wpt/workers/interfaces/WorkerUtils/WindowTimers/001.html new file mode 100644 index 000000000000..9fe5e2b1bc7b --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/WindowTimers/001.html @@ -0,0 +1,14 @@ + +setTimeout + + +
+ \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/WindowTimers/001.js b/test/fixtures/wpt/workers/interfaces/WorkerUtils/WindowTimers/001.js new file mode 100644 index 000000000000..bd5b7c4071c2 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/WindowTimers/001.js @@ -0,0 +1 @@ +setTimeout(function() { postMessage(1) }, 10); \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/WindowTimers/002.html b/test/fixtures/wpt/workers/interfaces/WorkerUtils/WindowTimers/002.html new file mode 100644 index 000000000000..1a10b3d0bb8d --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/WindowTimers/002.html @@ -0,0 +1,13 @@ + +clearTimeout + + +
+ \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/WindowTimers/002.js b/test/fixtures/wpt/workers/interfaces/WorkerUtils/WindowTimers/002.js new file mode 100644 index 000000000000..a96c08844202 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/WindowTimers/002.js @@ -0,0 +1,2 @@ +var t = setTimeout(function() { postMessage(1); }, 10); +clearTimeout(t); \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/WindowTimers/003.html b/test/fixtures/wpt/workers/interfaces/WorkerUtils/WindowTimers/003.html new file mode 100644 index 000000000000..119d109b5fd2 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/WindowTimers/003.html @@ -0,0 +1,14 @@ + +setInterval + + +
+ \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/WindowTimers/003.js b/test/fixtures/wpt/workers/interfaces/WorkerUtils/WindowTimers/003.js new file mode 100644 index 000000000000..e64e4e2179f0 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/WindowTimers/003.js @@ -0,0 +1 @@ +setInterval(function() { postMessage(1); }, 10); \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/WindowTimers/004.html b/test/fixtures/wpt/workers/interfaces/WorkerUtils/WindowTimers/004.html new file mode 100644 index 000000000000..83d7bf915fb6 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/WindowTimers/004.html @@ -0,0 +1,13 @@ + +clearInterval + + +
+ \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/WindowTimers/004.js b/test/fixtures/wpt/workers/interfaces/WorkerUtils/WindowTimers/004.js new file mode 100644 index 000000000000..e80d79a8e51b --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/WindowTimers/004.js @@ -0,0 +1,4 @@ +var t = setInterval(function() { + postMessage(1); +}, 10); +clearInterval(t); \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/WindowTimers/005.html b/test/fixtures/wpt/workers/interfaces/WorkerUtils/WindowTimers/005.html new file mode 100644 index 000000000000..2a181d55d0d9 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/WindowTimers/005.html @@ -0,0 +1,14 @@ + +setInterval when closing + + +
+ \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/WindowTimers/005.js b/test/fixtures/wpt/workers/interfaces/WorkerUtils/WindowTimers/005.js new file mode 100644 index 000000000000..125c224e7bcf --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/WindowTimers/005.js @@ -0,0 +1,3 @@ +self.close(); +var t = setInterval(function() {}, 10); +postMessage(t); \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/WindowTimers/WEB_FEATURES.yml b/test/fixtures/wpt/workers/interfaces/WorkerUtils/WindowTimers/WEB_FEATURES.yml new file mode 100644 index 000000000000..54493da00f91 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/WindowTimers/WEB_FEATURES.yml @@ -0,0 +1,6 @@ +rules: +- 003.html: [setinterval] +- 004.html: [setinterval] +- 005.html: [setinterval] +- 001.html: [settimeout] +- 002.html: [settimeout] diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/001.worker.js b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/001.worker.js new file mode 100644 index 000000000000..aa86c8ef1779 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/001.worker.js @@ -0,0 +1,7 @@ +importScripts("/resources/testharness.js"); + +test(function() { + importScripts(); +}); + +done(); diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/002.worker.js b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/002.worker.js new file mode 100644 index 000000000000..1cacee5ccb5e --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/002.worker.js @@ -0,0 +1,11 @@ +importScripts("/resources/testharness.js"); + +test(function() { + var ran = false; + assert_throws_dom("SyntaxError", function() { + importScripts('data:text/javascript,ran=true','http://foo bar'); + }); + assert_false(ran, 'first argument to importScripts ran'); +}); + +done(); diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/003.html b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/003.html new file mode 100644 index 000000000000..5dcd08aa1546 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/003.html @@ -0,0 +1,14 @@ + +importScripts running scripts + + +
+ \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/003.js b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/003.js new file mode 100644 index 000000000000..6e378ef20fff --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/003.js @@ -0,0 +1,8 @@ +var x = 'a'; +try { + importScripts('data:text/javascript,x+="b"', + 'data:text/javascript,x+="c"'); +} catch(e) { + x += "d" +} +postMessage(x); \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/004.html b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/004.html new file mode 100644 index 000000000000..62537e088814 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/004.html @@ -0,0 +1,15 @@ + +importScripts broken script + + +
+ \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/004.js b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/004.js new file mode 100644 index 000000000000..98040d0d48df --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/004.js @@ -0,0 +1,13 @@ +var x = ''; +var exception; +try { + importScripts('data:text/javascript,x+="first script successful. "', + 'data:text/javascript,x+="FAIL (second script). "; for(;) break;', // doesn't compile + 'data:text/javascript,x+="FAIL (third script)"'); +} catch(ex) { + if (ex instanceof SyntaxError) + exception = true; + else + exception = String(ex); +} +postMessage([x, exception]); \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/005.html b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/005.html new file mode 100644 index 000000000000..7ebbc1be5594 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/005.html @@ -0,0 +1,15 @@ + +importScripts separate scripts + + +
+ \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/005.js b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/005.js new file mode 100644 index 000000000000..18c534efa9c9 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/005.js @@ -0,0 +1,9 @@ +var x; +var y; +try { + importScripts('data:text/javascript,x={', + 'data:text/javascript,}'); +} catch(e) { + y = true; +} +postMessage([x, y]); \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/006.html b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/006.html new file mode 100644 index 000000000000..aec2fb148330 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/006.html @@ -0,0 +1,17 @@ + +importScripts uncaught exception + + + +
+ \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/006.js b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/006.js new file mode 100644 index 000000000000..fc170f790c74 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/006.js @@ -0,0 +1,11 @@ +var x; +var y; +var z; +try { + importScripts('data:text/javascript,x=1', + 'data:text/javascript,throw 2', + 'data:text/javascript,z=3'); +} catch(e) { + y = e; +} +postMessage([x, y, z]); \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/007.html b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/007.html new file mode 100644 index 000000000000..37e888365f70 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/007.html @@ -0,0 +1,17 @@ + +postMessage in importScripts + + +
+ \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/007.js b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/007.js new file mode 100644 index 000000000000..dc85216f3df7 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/007.js @@ -0,0 +1,2 @@ +importScripts('data:text/javascript,postMessage(1)'); +postMessage(2); \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/008.html b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/008.html new file mode 100644 index 000000000000..f72b79939c07 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/008.html @@ -0,0 +1,14 @@ + +variables and functions crossing importScripts boundary + + +
+ \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/008.js b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/008.js new file mode 100644 index 000000000000..c957fcd63538 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/008.js @@ -0,0 +1,3 @@ +var log = postMessage; +importScripts('data:text/javascript,function run() { log(true) }'); +run(); \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/009.html b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/009.html new file mode 100644 index 000000000000..e0eb5488c2e7 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/009.html @@ -0,0 +1,20 @@ + +variables and functions crossing importScripts boundary, take 2 + + +
+ \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/009.js b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/009.js new file mode 100644 index 000000000000..4b86f8c30308 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/009.js @@ -0,0 +1,3 @@ +var log = postMessage; +importScripts('data:text/javascript,function run() { for(var i = 0; i < 1000; ++i) { if (i == 500) log(true); } return 1; }'); +postMessage(run()); \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/010.html b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/010.html new file mode 100644 index 000000000000..a6db49c4be94 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/010.html @@ -0,0 +1,17 @@ + +importScripts(undefined) + + +
+ \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/010.js b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/010.js new file mode 100644 index 000000000000..4ec4a3b8c753 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/010.js @@ -0,0 +1,11 @@ +// prevent recursion +if ('beenThere' in self) { + throw 'undefined stringified to the empty string'; +} +beenThere = true; +try { + importScripts(undefined); + postMessage(got); +} catch(ex) { + postMessage(String(ex)); +} \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/011.html b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/011.html new file mode 100644 index 000000000000..1bfb23349756 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/011.html @@ -0,0 +1,17 @@ + +importScripts(null) + + +
+ \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/011.js b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/011.js new file mode 100644 index 000000000000..bd6fed5c0a37 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/011.js @@ -0,0 +1,11 @@ +// prevent recursion +if ('beenThere' in self) { + throw 'null stringified to the empty string'; +} +beenThere = true; +try { + importScripts(null); + postMessage(got); +} catch(ex) { + postMessage(String(ex)); +} \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/012.html b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/012.html new file mode 100644 index 000000000000..ab0778d0c71f --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/012.html @@ -0,0 +1,17 @@ + +importScripts(1) + + +
+ \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/012.js b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/012.js new file mode 100644 index 000000000000..f4c887f7df4a --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/012.js @@ -0,0 +1,11 @@ +// prevent recursion +if ('beenThere' in self) { + throw '1 stringified to the empty string'; +} +beenThere = true; +try { + importScripts(1); + postMessage(got); +} catch(ex) { + postMessage(String(ex)); +} \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/1 b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/1 new file mode 100644 index 000000000000..18cea4ff0f4b --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/1 @@ -0,0 +1 @@ +var got = '1'; \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/1.headers b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/1.headers new file mode 100644 index 000000000000..a17a9a3a12ce --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/1.headers @@ -0,0 +1 @@ +Content-Type: application/javascript diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/WEB_FEATURES.yml b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/WEB_FEATURES.yml new file mode 100644 index 000000000000..4ab206cd6d13 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/WEB_FEATURES.yml @@ -0,0 +1,3 @@ +rules: +- "*.any.js": [] +- "*": [dedicated-workers] diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/blob-url.worker.js b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/blob-url.worker.js new file mode 100644 index 000000000000..71603bf314f2 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/blob-url.worker.js @@ -0,0 +1,40 @@ +importScripts("/resources/testharness.js"); + +function objectUrlFromScript(script) { + const blob = new Blob([script], { type: "text/javascript" }); + return URL.createObjectURL(blob); +} + +test((t) => { + self.run = false; + const blobScriptUrl = objectUrlFromScript(`self.run = true;`); + t.add_cleanup(() => URL.revokeObjectURL(blobScriptUrl)); + + importScripts(blobScriptUrl); + assert_true(self.run); +}, "Blob URLs work on importScripts"); + +test(() => { + self.run = false; + const blobScriptUrl = objectUrlFromScript(`self.run = true;`); + + URL.revokeObjectURL(blobScriptUrl); + + assert_throws_dom("NetworkError", () => { + importScripts(blobScriptUrl); + }); + assert_false(self.run); +}, "A revoked blob URL will fail"); + +test(() => { + self.run = false; + const runScriptUrl = objectUrlFromScript(`self.run = true;`); + const revokeScriptUrl = objectUrlFromScript( + `URL.revokeObjectURL(${JSON.stringify(runScriptUrl)});` + ); + + importScripts(revokeScriptUrl, runScriptUrl); + assert_true(self.run); +}, "Revoking a blob URL in an earlier script will not fail"); + +done(); diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/catch.sub.any.js b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/catch.sub.any.js new file mode 100644 index 000000000000..52da60be91f6 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/catch.sub.any.js @@ -0,0 +1,47 @@ +// META: global=worker + +const crossOrigin = "https://{{hosts[alt][]}}:{{ports[https][0]}}"; +const redirectToCrossOrigin = "/common/redirect.py?location=" + crossOrigin; + +test(function() { + assert_throws_js(SyntaxError, function() { + importScripts("/workers/modules/resources/syntax-error.js"); + }); +}, "Same-origin syntax error"); + +test(function() { + assert_throws_js(Error, function() { + importScripts("/workers/modules/resources/throw.js"); + }); +}, "Same-origin throw"); + +// https://html.spec.whatwg.org/C/#run-a-classic-script +// Step 8.2. If rethrow errors is true and script's muted errors is true, then: +// Step 8.2.2. Throw a "NetworkError" DOMException. +test(function() { + assert_throws_dom("NetworkError", function() { + importScripts(crossOrigin + + "/workers/modules/resources/syntax-error.js"); + }); +}, "Cross-origin syntax error"); + +test(function() { + assert_throws_dom("NetworkError", function() { + importScripts(crossOrigin + + "/workers/modules/resources/throw.js"); + }); +}, "Cross-origin throw"); + +test(function() { + assert_throws_dom("NetworkError", function() { + importScripts(redirectToCrossOrigin + + "/workers/modules/resources/syntax-error.js"); + }); +}, "Redirect-to-cross-origin syntax error"); + +test(function() { + assert_throws_dom("NetworkError", function() { + importScripts(redirectToCrossOrigin + + "/workers/modules/resources/throw.js"); + }); +}, "Redirect-to-Cross-origin throw"); diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/null b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/null new file mode 100644 index 000000000000..8e54b66c50ec --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/null @@ -0,0 +1 @@ +var got = 'null'; \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/null.headers b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/null.headers new file mode 100644 index 000000000000..a17a9a3a12ce --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/null.headers @@ -0,0 +1 @@ +Content-Type: application/javascript diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-cross-origin.sub.any.js b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-cross-origin.sub.any.js new file mode 100644 index 000000000000..4fd8914856b5 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-cross-origin.sub.any.js @@ -0,0 +1,8 @@ +// META: global=dedicatedworker,sharedworker +// META: script=report-error-helper.js +const crossOrigin = "https://{{hosts[alt][]}}:{{ports[https][0]}}"; +runTest( + crossOrigin + "/workers/modules/resources/syntax-error.js", + false, + "NetworkError" +); diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-helper.js b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-helper.js new file mode 100644 index 000000000000..7fc6d0dd64bc --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-helper.js @@ -0,0 +1,80 @@ +setup({ allow_uncaught_exception:true }); + +// For SyntaxError, the line in doImportScripts() is expected to be reported +// as `e.lineno` etc. below. +// doImportScripts() is introduced here to prevent the line number from being +// affected by changes in runTest(), use of setTimeout(), etc. +function doImportScripts(url) { + importScripts(url); +} + +const t0 = async_test("WorkerGlobalScope error event: error"); +const t1 = async_test("WorkerGlobalScope error event: message"); +const t2 = async_test("WorkerGlobalScope error event: filename"); +const t3 = async_test("WorkerGlobalScope error event: lineno"); + +function runTest(importScriptUrl, shouldUseSetTimeout, expected) { + self.addEventListener("error", e => { + if (expected === "NetworkError") { + t0.step_func_done(() => { + assert_equals(e.error.constructor, DOMException, + "e.error should be a DOMException") + assert_equals(e.error.name, "NetworkError"); + })(); + + t1.step_func_done(() => { + assert_not_equals(e.message, "Script error.", + "e.message should not be muted to 'Script error.'"); + })(); + + // filename, lineno etc. should NOT point to the location within + // `syntax-error.js` (otherwise parse errors to be muted are + // leaked to JavaScript). + // we expect they point to the caller of `importScripts()`, + // while this is not explicitly stated in the spec. + t2.step_func_done(() => { + assert_equals(e.filename, self.location.origin + + '/workers/interfaces/WorkerUtils/importScripts/report-error-helper.js'); + })(); + t3.step_func_done(() => { + assert_equals(e.lineno, 8); + })(); + // We don't check `e.colno` for now, because browsers set different + // `colno` values. + } else if (expected === "SyntaxError") { + t0.step_func_done(() => { + assert_equals(e.error.constructor, SyntaxError); + assert_equals(e.error.name, "SyntaxError"); + })(); + + t1.step_func_done(() => { + assert_not_equals(e.message, "Script error.", + "e.message should not be muted to 'Script error.'"); + })(); + + // filename, lineno etc. are expected to point to the location within + // `syntax-error.js` because it is same-origin, + // while this is not explicitly stated in the spec. + t2.step_func_done(() => { + assert_equals(e.filename, self.location.origin + + '/workers/modules/resources/syntax-error.js'); + })(); + t3.step_func_done(() => { + assert_equals(e.lineno, 1); + })(); + // We don't check `e.colno` for now, because browsers set different + // `colno` values. + } + + // Because importScripts() throws, we call done() here. + done(); + }); + + if (shouldUseSetTimeout) { + setTimeout( + () => doImportScripts(importScriptUrl), + 0); + } else { + doImportScripts(importScriptUrl); + } +} diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-redirect-to-cross-origin.sub.any.js b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-redirect-to-cross-origin.sub.any.js new file mode 100644 index 000000000000..2b9600973fb8 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-redirect-to-cross-origin.sub.any.js @@ -0,0 +1,9 @@ +// META: global=dedicatedworker,sharedworker +// META: script=report-error-helper.js +const crossOrigin = "https://{{hosts[alt][]}}:{{ports[https][0]}}"; +runTest( + "/common/redirect.py?location=" + crossOrigin + + "/workers/modules/resources/syntax-error.js", + false, + "NetworkError" +); diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-same-origin.sub.any.js b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-same-origin.sub.any.js new file mode 100644 index 000000000000..f7de416e1170 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-same-origin.sub.any.js @@ -0,0 +1,7 @@ +// META: global=dedicatedworker,sharedworker +// META: script=report-error-helper.js +runTest( + "/workers/modules/resources/syntax-error.js", + false, + "SyntaxError" +); diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-cross-origin.sub.any.js b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-cross-origin.sub.any.js new file mode 100644 index 000000000000..a1bbef7bc45a --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-cross-origin.sub.any.js @@ -0,0 +1,8 @@ +// META: global=dedicatedworker,sharedworker +// META: script=report-error-helper.js +const crossOrigin = "https://{{hosts[alt][]}}:{{ports[https][0]}}"; +runTest( + crossOrigin + "/workers/modules/resources/syntax-error.js", + true, + "NetworkError" +); diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-redirect-to-cross-origin.sub.any.js b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-redirect-to-cross-origin.sub.any.js new file mode 100644 index 000000000000..2755b337d3da --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-redirect-to-cross-origin.sub.any.js @@ -0,0 +1,9 @@ +// META: global=dedicatedworker,sharedworker +// META: script=report-error-helper.js +const crossOrigin = "https://{{hosts[alt][]}}:{{ports[https][0]}}"; +runTest( + "/common/redirect.py?location=" + crossOrigin + + "/workers/modules/resources/syntax-error.js", + true, + "NetworkError" +); diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-same-origin.sub.any.js b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-same-origin.sub.any.js new file mode 100644 index 000000000000..c4f70ebec973 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/report-error-setTimeout-same-origin.sub.any.js @@ -0,0 +1,7 @@ +// META: global=dedicatedworker,sharedworker +// META: script=report-error-helper.js +runTest( + "/workers/modules/resources/syntax-error.js", + true, + "SyntaxError" +); diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/undefined b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/undefined new file mode 100644 index 000000000000..f99ba4be744c --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/undefined @@ -0,0 +1 @@ +var got = 'undefined'; \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/undefined.headers b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/undefined.headers new file mode 100644 index 000000000000..a17a9a3a12ce --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/importScripts/undefined.headers @@ -0,0 +1 @@ +Content-Type: application/javascript diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/navigator/002.html b/test/fixtures/wpt/workers/interfaces/WorkerUtils/navigator/002.html new file mode 100644 index 000000000000..4c76e2b69908 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/navigator/002.html @@ -0,0 +1,14 @@ + +navigator.appName + + +
+ \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/navigator/002.js b/test/fixtures/wpt/workers/interfaces/WorkerUtils/navigator/002.js new file mode 100644 index 000000000000..a5af348ef107 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/navigator/002.js @@ -0,0 +1 @@ +postMessage(navigator.appName); \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/navigator/003.html b/test/fixtures/wpt/workers/interfaces/WorkerUtils/navigator/003.html new file mode 100644 index 000000000000..86ab5aee4896 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/navigator/003.html @@ -0,0 +1,14 @@ + +navigator.appVersion + + +
+ \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/navigator/003.js b/test/fixtures/wpt/workers/interfaces/WorkerUtils/navigator/003.js new file mode 100644 index 000000000000..ff92f8aadb8d --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/navigator/003.js @@ -0,0 +1 @@ +postMessage(navigator.appVersion); \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/navigator/004.html b/test/fixtures/wpt/workers/interfaces/WorkerUtils/navigator/004.html new file mode 100644 index 000000000000..93eee0095712 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/navigator/004.html @@ -0,0 +1,14 @@ + +navigator.platform + + +
+ \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/navigator/004.js b/test/fixtures/wpt/workers/interfaces/WorkerUtils/navigator/004.js new file mode 100644 index 000000000000..c1b575e43c99 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/navigator/004.js @@ -0,0 +1 @@ +postMessage(navigator.platform); \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/navigator/005.html b/test/fixtures/wpt/workers/interfaces/WorkerUtils/navigator/005.html new file mode 100644 index 000000000000..ad2899e62ead --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/navigator/005.html @@ -0,0 +1,14 @@ + +navigator.userAgent + + +
+ \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/navigator/005.js b/test/fixtures/wpt/workers/interfaces/WorkerUtils/navigator/005.js new file mode 100644 index 000000000000..d62252d39b21 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/navigator/005.js @@ -0,0 +1 @@ +postMessage(navigator.userAgent); \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/navigator/006.html b/test/fixtures/wpt/workers/interfaces/WorkerUtils/navigator/006.html new file mode 100644 index 000000000000..e0f7386af31c --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/navigator/006.html @@ -0,0 +1,14 @@ + +navigator.onLine + + +
+ \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/navigator/006.js b/test/fixtures/wpt/workers/interfaces/WorkerUtils/navigator/006.js new file mode 100644 index 000000000000..325fd0fbdec3 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/navigator/006.js @@ -0,0 +1 @@ +postMessage(navigator.onLine); \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/navigator/007.html b/test/fixtures/wpt/workers/interfaces/WorkerUtils/navigator/007.html new file mode 100644 index 000000000000..8f9d38dd857a --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/navigator/007.html @@ -0,0 +1,14 @@ + +readonlyness of members of Navigator + + +
+ \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/navigator/007.js b/test/fixtures/wpt/workers/interfaces/WorkerUtils/navigator/007.js new file mode 100644 index 000000000000..38849bc8abc6 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/navigator/007.js @@ -0,0 +1,11 @@ +var log = []; +var neverEncounteredValue = "This is not the value you are looking for."; +for (x in navigator) { + // skip functions, as they are writable + if (typeof navigator[x] === 'function') continue; + // this should silently fail and not throw per webidl + navigator[x] = neverEncounteredValue; + if (navigator[x] === neverEncounteredValue) + log.push(x); +} +postMessage(log.join(', ')); \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/navigator/008.worker.js b/test/fixtures/wpt/workers/interfaces/WorkerUtils/navigator/008.worker.js new file mode 100644 index 000000000000..e539d85d763d --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/navigator/008.worker.js @@ -0,0 +1,12 @@ +"use strict"; +importScripts("/resources/testharness.js"); +test(function () { + for (const x in navigator) { + // skip functions, as they are settable + if (typeof navigator[x] === "function") continue; + assert_throws_js(TypeError, () => { + navigator[x] = ""; + }, `navigator.${x} is read-only`); + } +}, "navigator properties are read-only"); +done(); diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/navigator/WEB_FEATURES.yml b/test/fixtures/wpt/workers/interfaces/WorkerUtils/navigator/WEB_FEATURES.yml new file mode 100644 index 000000000000..6a7232bd7f27 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/navigator/WEB_FEATURES.yml @@ -0,0 +1,5 @@ +rules: +- 006.html: [online, dedicated-workers] +- 005.html: [user-agent-sniffing] +- language.html: [language, dedicated-workers] +- "*": [dedicated-workers] diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/navigator/language.html b/test/fixtures/wpt/workers/interfaces/WorkerUtils/navigator/language.html new file mode 100644 index 000000000000..535ab3a7cb98 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/navigator/language.html @@ -0,0 +1,14 @@ + +navigator.language + + +
+ \ No newline at end of file diff --git a/test/fixtures/wpt/workers/interfaces/WorkerUtils/navigator/language.js b/test/fixtures/wpt/workers/interfaces/WorkerUtils/navigator/language.js new file mode 100644 index 000000000000..e94ba4dfcf16 --- /dev/null +++ b/test/fixtures/wpt/workers/interfaces/WorkerUtils/navigator/language.js @@ -0,0 +1 @@ +postMessage(navigator.language); \ No newline at end of file diff --git a/test/fixtures/wpt/workers/modules/WEB_FEATURES.yml b/test/fixtures/wpt/workers/modules/WEB_FEATURES.yml new file mode 100644 index 000000000000..6399a3a20323 --- /dev/null +++ b/test/fixtures/wpt/workers/modules/WEB_FEATURES.yml @@ -0,0 +1,3 @@ +rules: +- dedicated-worker-*: [js-modules-workers] +- shared-worker-*: [js-modules-shared-workers] diff --git a/test/fixtures/wpt/workers/modules/dedicated-worker-import-blob-url.any.js b/test/fixtures/wpt/workers/modules/dedicated-worker-import-blob-url.any.js new file mode 100644 index 000000000000..e5d79add7366 --- /dev/null +++ b/test/fixtures/wpt/workers/modules/dedicated-worker-import-blob-url.any.js @@ -0,0 +1,26 @@ +// META: script=/workers/modules/resources/import-test-cases.js + +// Imports |testCase.scriptURL| on a dedicated worker loaded from a blob URL, +// and waits until the list of imported modules is sent from the worker. Passes +// if the list is equal to |testCase.expectation|. +function import_blob_url_test(testCase) { + promise_test(async () => { + const importURL = new URL(testCase.scriptURL, location.href); + const blob = new Blob([`import "${importURL}";`], + { type: 'text/javascript' }); + const blobURL = URL.createObjectURL(blob); + const worker = new Worker(blobURL, { type: 'module'}); + worker.postMessage('Send message for tests from main script.'); + const msgEvent = await new Promise((resolve, reject) => { + worker.onmessage = resolve; + worker.onerror = error => { + const msg = error instanceof ErrorEvent ? error.message + : 'unknown error'; + reject(msg); + }; + }); + assert_array_equals(msgEvent.data, testCase.expectation); + }, testCase.description); +} + +testCases.forEach(import_blob_url_test); diff --git a/test/fixtures/wpt/workers/modules/dedicated-worker-import-csp.html b/test/fixtures/wpt/workers/modules/dedicated-worker-import-csp.html new file mode 100644 index 000000000000..6e0051aa14ed --- /dev/null +++ b/test/fixtures/wpt/workers/modules/dedicated-worker-import-csp.html @@ -0,0 +1,138 @@ + +DedicatedWorker: CSP for ES Modules + + + diff --git a/test/fixtures/wpt/workers/modules/dedicated-worker-import-data-url-cross-origin.html b/test/fixtures/wpt/workers/modules/dedicated-worker-import-data-url-cross-origin.html new file mode 100644 index 000000000000..2f790a06a5cd --- /dev/null +++ b/test/fixtures/wpt/workers/modules/dedicated-worker-import-data-url-cross-origin.html @@ -0,0 +1,45 @@ + +DedicatedWorker: ES modules for data URL workers + + + diff --git a/test/fixtures/wpt/workers/modules/dedicated-worker-import-data-url.any.js b/test/fixtures/wpt/workers/modules/dedicated-worker-import-data-url.any.js new file mode 100644 index 000000000000..b837ad67da62 --- /dev/null +++ b/test/fixtures/wpt/workers/modules/dedicated-worker-import-data-url.any.js @@ -0,0 +1,25 @@ +// META: script=/workers/modules/resources/import-test-cases.js + +// Imports |testCase.scriptURL| on a dedicated worker loaded from a data URL, +// and waits until the list of imported modules is sent from the worker. Passes +// if the list is equal to |testCase.expectation|. +function import_data_url_test(testCase) { + promise_test(async () => { + // The Access-Control-Allow-Origin header is necessary because a worker + // loaded from a data URL has a null origin and import() on the worker + // without the header is blocked. + const importURL = new URL(testCase.scriptURL, location.href) + + '?pipe=header(Access-Control-Allow-Origin, *)'; + const dataURL = `data:text/javascript,import "${importURL}";`; + + const worker = new Worker(dataURL, { type: 'module'}); + worker.postMessage('Send message for tests from main script.'); + const msgEvent = await new Promise((resolve, reject) =>{ + worker.onmessage = resolve; + worker.onerror = reject; + }).catch(e => assert_true(false)); + assert_array_equals(msgEvent.data, testCase.expectation); + }, testCase.description); +} + +testCases.forEach(import_data_url_test); diff --git a/test/fixtures/wpt/workers/modules/dedicated-worker-import-failure.html b/test/fixtures/wpt/workers/modules/dedicated-worker-import-failure.html new file mode 100644 index 000000000000..8c6beb35d36d --- /dev/null +++ b/test/fixtures/wpt/workers/modules/dedicated-worker-import-failure.html @@ -0,0 +1,57 @@ + +DedicatedWorker: import failure + + + + diff --git a/test/fixtures/wpt/workers/modules/dedicated-worker-import-meta.html b/test/fixtures/wpt/workers/modules/dedicated-worker-import-meta.html new file mode 100644 index 000000000000..97a5da870f8d --- /dev/null +++ b/test/fixtures/wpt/workers/modules/dedicated-worker-import-meta.html @@ -0,0 +1,59 @@ + +DedicatedWorker: import.meta + + + diff --git a/test/fixtures/wpt/workers/modules/dedicated-worker-import-referrer.html b/test/fixtures/wpt/workers/modules/dedicated-worker-import-referrer.html new file mode 100644 index 000000000000..855df6219436 --- /dev/null +++ b/test/fixtures/wpt/workers/modules/dedicated-worker-import-referrer.html @@ -0,0 +1,244 @@ + +DedicatedWorker: Referrer + + + + diff --git a/test/fixtures/wpt/workers/modules/dedicated-worker-import.any.js b/test/fixtures/wpt/workers/modules/dedicated-worker-import.any.js new file mode 100644 index 000000000000..d5bb6cccbe21 --- /dev/null +++ b/test/fixtures/wpt/workers/modules/dedicated-worker-import.any.js @@ -0,0 +1,22 @@ +// META: script=/workers/modules/resources/import-test-cases.js + +// Starts a dedicated worker for |testCase.scriptURL| and waits until the list +// of imported modules is sent from the worker. Passes if the list is equal to +// |testCase.expectation|. +function import_test(testCase) { + promise_test(async () => { + const worker = new Worker(testCase.scriptURL, { type: 'module' }); + worker.postMessage('Send message for tests from main script.'); + const msgEvent = await new Promise((resolve, reject) => { + worker.onmessage = resolve; + worker.onerror = error => { + const msg = error instanceof ErrorEvent ? error.message + : 'unknown error'; + reject(msg); + }; + }); + assert_array_equals(msgEvent.data, testCase.expectation); + }, testCase.description); +} + +testCases.forEach(import_test); diff --git a/test/fixtures/wpt/workers/modules/dedicated-worker-options-credentials.html b/test/fixtures/wpt/workers/modules/dedicated-worker-options-credentials.html new file mode 100644 index 000000000000..94916d7ff5d6 --- /dev/null +++ b/test/fixtures/wpt/workers/modules/dedicated-worker-options-credentials.html @@ -0,0 +1,304 @@ + +DedicatedWorker: WorkerOptions 'credentials' + + + + + diff --git a/test/fixtures/wpt/workers/modules/dedicated-worker-options-credentials.html.headers b/test/fixtures/wpt/workers/modules/dedicated-worker-options-credentials.html.headers new file mode 100644 index 000000000000..8da851ab7363 --- /dev/null +++ b/test/fixtures/wpt/workers/modules/dedicated-worker-options-credentials.html.headers @@ -0,0 +1,2 @@ +Set-Cookie: COOKIE_NAME=1 +Access-Control-Allow-Credentials: true diff --git a/test/fixtures/wpt/workers/modules/dedicated-worker-options-type.html b/test/fixtures/wpt/workers/modules/dedicated-worker-options-type.html new file mode 100644 index 000000000000..bb37a18f2cc9 --- /dev/null +++ b/test/fixtures/wpt/workers/modules/dedicated-worker-options-type.html @@ -0,0 +1,46 @@ + +DedicatedWorker: WorkerOptions 'type' + + + diff --git a/test/fixtures/wpt/workers/modules/dedicated-worker-parse-error-failure.html b/test/fixtures/wpt/workers/modules/dedicated-worker-parse-error-failure.html new file mode 100644 index 000000000000..343bfe289f30 --- /dev/null +++ b/test/fixtures/wpt/workers/modules/dedicated-worker-parse-error-failure.html @@ -0,0 +1,51 @@ + +DedicatedWorker: parse error failure + + + + + diff --git a/test/fixtures/wpt/workers/modules/resources/dynamic-import-and-then-static-import-worker.js b/test/fixtures/wpt/workers/modules/resources/dynamic-import-and-then-static-import-worker.js new file mode 100644 index 000000000000..527702f55117 --- /dev/null +++ b/test/fixtures/wpt/workers/modules/resources/dynamic-import-and-then-static-import-worker.js @@ -0,0 +1,32 @@ +// This script is meant to be imported by a module worker. It receives a +// message from the worker and responds with the list of imported modules. +const sourcePromise = new Promise(resolve => { + if ('DedicatedWorkerGlobalScope' in self && + self instanceof DedicatedWorkerGlobalScope) { + self.onmessage = e => { + resolve(e.target); + }; + } else if ( + 'SharedWorkerGlobalScope' in self && + self instanceof SharedWorkerGlobalScope) { + self.onconnect = e => { + resolve(e.ports[0]); + }; + } else if ( + 'ServiceWorkerGlobalScope' in self && + self instanceof ServiceWorkerGlobalScope) { + self.onmessage = e => { + resolve(e.source); + }; + } +}); + +const importedModulesPromise = + import('./export-on-static-import-script.js') + .then(module => module.importedModules) + .catch(error => `Failed to do dynamic import: ${error}`); + +Promise.all([sourcePromise, importedModulesPromise]).then(results => { + const [source, importedModules] = results; + source.postMessage(importedModules); +}); diff --git a/test/fixtures/wpt/workers/modules/resources/dynamic-import-data-url-block-cross-origin.js b/test/fixtures/wpt/workers/modules/resources/dynamic-import-data-url-block-cross-origin.js new file mode 100644 index 000000000000..caa15319c55c --- /dev/null +++ b/test/fixtures/wpt/workers/modules/resources/dynamic-import-data-url-block-cross-origin.js @@ -0,0 +1,24 @@ +const sourcePromise = new Promise(resolve => { + if ('DedicatedWorkerGlobalScope' in self && + self instanceof DedicatedWorkerGlobalScope) { + self.onmessage = e => { + resolve(e.target); + }; + } else if ( + 'SharedWorkerGlobalScope' in self && + self instanceof SharedWorkerGlobalScope) { + self.onconnect = e => { + resolve(e.ports[0]); + }; + } +}); + +const importedModulesPromise = + import("data:text/javascript, export const importedModules = ['export-block-cross-origin.js'];") + .then(module => module.importedModules) + .catch(() => ['ERROR']); + +Promise.all([sourcePromise, importedModulesPromise]).then(results => { + const [source, importedModules] = results; + source.postMessage(importedModules); +}); diff --git a/test/fixtures/wpt/workers/modules/resources/dynamic-import-given-url-worker.js b/test/fixtures/wpt/workers/modules/resources/dynamic-import-given-url-worker.js new file mode 100644 index 000000000000..55102759352c --- /dev/null +++ b/test/fixtures/wpt/workers/modules/resources/dynamic-import-given-url-worker.js @@ -0,0 +1,21 @@ +// This worker dynamically imports the script URL sent by postMessage(), and +// sends back an error name if the dynamic import fails. +if ('DedicatedWorkerGlobalScope' in self && + self instanceof DedicatedWorkerGlobalScope) { + self.onmessage = msg_event => { + import(msg_event.data) + .then(module => postMessage(module.meta_url)) + .catch(e => postMessage(e.name)); + }; +} else if ( + 'SharedWorkerGlobalScope' in self && + self instanceof SharedWorkerGlobalScope) { + self.onconnect = connect_event => { + const port = connect_event.ports[0]; + port.onmessage = msg_event => { + import(msg_event.data) + .then(module => port.postMessage(module.meta_url)) + .catch(e => port.postMessage(e.name)); + }; + }; +} diff --git a/test/fixtures/wpt/workers/modules/resources/dynamic-import-remote-origin-credentials-checker-worker.sub.js b/test/fixtures/wpt/workers/modules/resources/dynamic-import-remote-origin-credentials-checker-worker.sub.js new file mode 100644 index 000000000000..3cfbe7c6e4ca --- /dev/null +++ b/test/fixtures/wpt/workers/modules/resources/dynamic-import-remote-origin-credentials-checker-worker.sub.js @@ -0,0 +1,15 @@ +// Import a remote origin script. +const import_url = + 'http://{{domains[www1]}}:{{ports[http][0]}}/workers/modules/resources/export-credentials.py'; +if ('DedicatedWorkerGlobalScope' in self && + self instanceof DedicatedWorkerGlobalScope) { + import(import_url) + .then(module => postMessage(module.cookie)); +} else if ( + 'SharedWorkerGlobalScope' in self && + self instanceof SharedWorkerGlobalScope) { + onconnect = e => { + import(import_url) + .then(module => e.ports[0].postMessage(module.cookie)); + }; +} diff --git a/test/fixtures/wpt/workers/modules/resources/dynamic-import-remote-origin-referrer-checker-worker.sub.js b/test/fixtures/wpt/workers/modules/resources/dynamic-import-remote-origin-referrer-checker-worker.sub.js new file mode 100644 index 000000000000..014a3467e86c --- /dev/null +++ b/test/fixtures/wpt/workers/modules/resources/dynamic-import-remote-origin-referrer-checker-worker.sub.js @@ -0,0 +1,16 @@ +// Import a remote origin script. +const import_url = 'https://{{hosts[alt][]}}:{{ports[https][0]}}/workers/modules/resources/export-referrer-checker.py'; +if ('DedicatedWorkerGlobalScope' in self && + self instanceof DedicatedWorkerGlobalScope) { + import(import_url) + .then(module => postMessage(module.referrer)) + .catch(error => postMessage(`Import failed: ${error}`)); +} else if ( + 'SharedWorkerGlobalScope' in self && + self instanceof SharedWorkerGlobalScope) { + onconnect = e => { + import(import_url) + .then(module => e.ports[0].postMessage(module.referrer)) + .catch(error => e.ports[0].postMessage(`Import failed: ${error}`)); + }; +} diff --git a/test/fixtures/wpt/workers/modules/resources/dynamic-import-remote-origin-script-worker.sub.js b/test/fixtures/wpt/workers/modules/resources/dynamic-import-remote-origin-script-worker.sub.js new file mode 100644 index 000000000000..7ed65438904a --- /dev/null +++ b/test/fixtures/wpt/workers/modules/resources/dynamic-import-remote-origin-script-worker.sub.js @@ -0,0 +1,17 @@ +// Import a remote origin script. +const importUrl = + 'https://{{domains[www1]}}:{{ports[https][0]}}/workers/modules/resources/export-on-load-script.js'; +if ('DedicatedWorkerGlobalScope' in self && + self instanceof DedicatedWorkerGlobalScope) { + import(importUrl) + .then(module => postMessage(module.importedModules)) + .catch(e => postMessage(['ERROR'])); +} else if ( + 'SharedWorkerGlobalScope' in self && + self instanceof SharedWorkerGlobalScope) { + onconnect = e => { + import(importUrl) + .then(module => e.ports[0].postMessage(module.importedModules)) + .catch(error => e.ports[0].postMessage(['ERROR'])); + }; +} diff --git a/test/fixtures/wpt/workers/modules/resources/dynamic-import-same-origin-credentials-checker-worker.js b/test/fixtures/wpt/workers/modules/resources/dynamic-import-same-origin-credentials-checker-worker.js new file mode 100644 index 000000000000..24dbd551280f --- /dev/null +++ b/test/fixtures/wpt/workers/modules/resources/dynamic-import-same-origin-credentials-checker-worker.js @@ -0,0 +1,13 @@ +const import_url = './export-credentials.py'; +if ('DedicatedWorkerGlobalScope' in self && + self instanceof DedicatedWorkerGlobalScope) { + import(import_url) + .then(module => postMessage(module.cookie)); +} else if ( + 'SharedWorkerGlobalScope' in self && + self instanceof SharedWorkerGlobalScope) { + onconnect = e => { + import(import_url) + .then(module => e.ports[0].postMessage(module.cookie)); + }; +} diff --git a/test/fixtures/wpt/workers/modules/resources/dynamic-import-same-origin-referrer-checker-worker.js b/test/fixtures/wpt/workers/modules/resources/dynamic-import-same-origin-referrer-checker-worker.js new file mode 100644 index 000000000000..56f8a6ffe822 --- /dev/null +++ b/test/fixtures/wpt/workers/modules/resources/dynamic-import-same-origin-referrer-checker-worker.js @@ -0,0 +1,15 @@ +const import_url = './export-referrer-checker.py'; +if ('DedicatedWorkerGlobalScope' in self && + self instanceof DedicatedWorkerGlobalScope) { + import(import_url) + .then(module => postMessage(module.referrer)) + .catch(error => postMessage(`Import failed: ${error}`)); +} else if ( + 'SharedWorkerGlobalScope' in self && + self instanceof SharedWorkerGlobalScope) { + onconnect = e => { + import(import_url) + .then(module => e.ports[0].postMessage(module.referrer)) + .catch(error => e.ports[0].postMessage(`Import failed: ${error}`)); + }; +} diff --git a/test/fixtures/wpt/workers/modules/resources/dynamic-import-script-block-cross-origin.js b/test/fixtures/wpt/workers/modules/resources/dynamic-import-script-block-cross-origin.js new file mode 100644 index 000000000000..52ec53066359 --- /dev/null +++ b/test/fixtures/wpt/workers/modules/resources/dynamic-import-script-block-cross-origin.js @@ -0,0 +1,24 @@ +const sourcePromise = new Promise(resolve => { + if ('DedicatedWorkerGlobalScope' in self && + self instanceof DedicatedWorkerGlobalScope) { + self.onmessage = e => { + resolve(e.target); + }; + } else if ( + 'SharedWorkerGlobalScope' in self && + self instanceof SharedWorkerGlobalScope) { + self.onconnect = e => { + resolve(e.ports[0]); + }; + } +}); + +const importedModulesPromise = + import('./export-block-cross-origin.js') + .then(module => module.importedModules) + .catch(() => ['ERROR']); + +Promise.all([sourcePromise, importedModulesPromise]).then(results => { + const [source, importedModules] = results; + source.postMessage(importedModules); +}); diff --git a/test/fixtures/wpt/workers/modules/resources/dynamic-import-worker.js b/test/fixtures/wpt/workers/modules/resources/dynamic-import-worker.js new file mode 100644 index 000000000000..2e756fe055e9 --- /dev/null +++ b/test/fixtures/wpt/workers/modules/resources/dynamic-import-worker.js @@ -0,0 +1,32 @@ +// This script is meant to be imported by a module worker. It receives a +// message from the worker and responds with the list of imported modules. +const sourcePromise = new Promise(resolve => { + if ('DedicatedWorkerGlobalScope' in self && + self instanceof DedicatedWorkerGlobalScope) { + self.onmessage = e => { + resolve(e.target); + }; + } else if ( + 'SharedWorkerGlobalScope' in self && + self instanceof SharedWorkerGlobalScope) { + self.onconnect = e => { + resolve(e.ports[0]); + }; + } else if ( + 'ServiceWorkerGlobalScope' in self && + self instanceof ServiceWorkerGlobalScope) { + self.onmessage = e => { + resolve(e.source); + }; + } +}); + +const importedModulesPromise = + import('./export-on-load-script.js') + .then(module => module.importedModules) + .catch(error => `Failed to do dynamic import: ${error}`); + +Promise.all([sourcePromise, importedModulesPromise]).then(results => { + const [source, importedModules] = results; + source.postMessage(importedModules); +}); diff --git a/test/fixtures/wpt/workers/modules/resources/empty-worker.js b/test/fixtures/wpt/workers/modules/resources/empty-worker.js new file mode 100644 index 000000000000..49ceb2648a93 --- /dev/null +++ b/test/fixtures/wpt/workers/modules/resources/empty-worker.js @@ -0,0 +1 @@ +// Do nothing. diff --git a/test/fixtures/wpt/workers/modules/resources/eval-dynamic-import-worker.js b/test/fixtures/wpt/workers/modules/resources/eval-dynamic-import-worker.js new file mode 100644 index 000000000000..60080d4292a8 --- /dev/null +++ b/test/fixtures/wpt/workers/modules/resources/eval-dynamic-import-worker.js @@ -0,0 +1,29 @@ +// This script is meant to be imported by a module worker. It receives a +// message from the worker and responds with the list of imported modules. +const code = 'const sourcePromise = new Promise(resolve => {' + + ' if (\'DedicatedWorkerGlobalScope\' in self &&' + + ' self instanceof DedicatedWorkerGlobalScope) {' + + ' self.onmessage = e => {' + + ' resolve(e.target);' + + ' };' + + ' } else if (\'SharedWorkerGlobalScope\' in self &&' + + ' self instanceof SharedWorkerGlobalScope) {' + + ' self.onconnect = e => {' + + ' resolve(e.ports[0]);' + + ' };' + + ' } else if (\'ServiceWorkerGlobalScope\' in self &&' + + ' self instanceof ServiceWorkerGlobalScope) {' + + ' self.onmessage = e => {' + + ' resolve(e.source);' + + ' };' + + ' }' + + '});' + + 'const importedModulesPromise =' + + ' import(\'./export-on-load-script.js\')' + + ' .then(module => module.importedModules)' + + ' .catch(error => `Failed to do dynamic import: ${error}`);' + + 'Promise.all([sourcePromise, importedModulesPromise]).then(results => {' + + ' const [source, importedModules] = results;' + + ' source.postMessage(importedModules);' + + '});'; +eval(code); diff --git a/test/fixtures/wpt/workers/modules/resources/export-block-cross-origin.js b/test/fixtures/wpt/workers/modules/resources/export-block-cross-origin.js new file mode 100644 index 000000000000..a4b513d280e9 --- /dev/null +++ b/test/fixtures/wpt/workers/modules/resources/export-block-cross-origin.js @@ -0,0 +1 @@ +export const importedModules = ['export-block-cross-origin.js']; diff --git a/test/fixtures/wpt/workers/modules/resources/export-on-dynamic-import-script.js b/test/fixtures/wpt/workers/modules/resources/export-on-dynamic-import-script.js new file mode 100644 index 000000000000..bab7cb48d249 --- /dev/null +++ b/test/fixtures/wpt/workers/modules/resources/export-on-dynamic-import-script.js @@ -0,0 +1,8 @@ +// Export the list of imported modules. It's available after the |ready| promise +// is resolved. +export let importedModules = ['export-on-dynamic-import-script.js']; +export let ready = import('./export-on-load-script.js') + .then(module => { + Array.prototype.push.apply(importedModules, module.importedModules); + return importedModules; + }); diff --git a/test/fixtures/wpt/workers/modules/resources/export-on-dynamic-import-script.js.headers b/test/fixtures/wpt/workers/modules/resources/export-on-dynamic-import-script.js.headers new file mode 100644 index 000000000000..cb762eff8068 --- /dev/null +++ b/test/fixtures/wpt/workers/modules/resources/export-on-dynamic-import-script.js.headers @@ -0,0 +1 @@ +Access-Control-Allow-Origin: * diff --git a/test/fixtures/wpt/workers/modules/resources/export-on-load-script.js b/test/fixtures/wpt/workers/modules/resources/export-on-load-script.js new file mode 100644 index 000000000000..7d1b122c3225 --- /dev/null +++ b/test/fixtures/wpt/workers/modules/resources/export-on-load-script.js @@ -0,0 +1 @@ +export const importedModules = ['export-on-load-script.js']; diff --git a/test/fixtures/wpt/workers/modules/resources/export-on-load-script.js.headers b/test/fixtures/wpt/workers/modules/resources/export-on-load-script.js.headers new file mode 100644 index 000000000000..cb762eff8068 --- /dev/null +++ b/test/fixtures/wpt/workers/modules/resources/export-on-load-script.js.headers @@ -0,0 +1 @@ +Access-Control-Allow-Origin: * diff --git a/test/fixtures/wpt/workers/modules/resources/export-on-static-import-script.js b/test/fixtures/wpt/workers/modules/resources/export-on-static-import-script.js new file mode 100644 index 000000000000..3f7174eef0be --- /dev/null +++ b/test/fixtures/wpt/workers/modules/resources/export-on-static-import-script.js @@ -0,0 +1,3 @@ +import * as module from './export-on-load-script.js'; +const filename = 'export-on-static-import-script.js'; +export const importedModules = [filename].concat(module.importedModules); diff --git a/test/fixtures/wpt/workers/modules/resources/export-on-static-import-script.js.headers b/test/fixtures/wpt/workers/modules/resources/export-on-static-import-script.js.headers new file mode 100644 index 000000000000..cb762eff8068 --- /dev/null +++ b/test/fixtures/wpt/workers/modules/resources/export-on-static-import-script.js.headers @@ -0,0 +1 @@ +Access-Control-Allow-Origin: * diff --git a/test/fixtures/wpt/workers/modules/resources/import-meta-url-export.js b/test/fixtures/wpt/workers/modules/resources/import-meta-url-export.js new file mode 100644 index 000000000000..5287b2e9e849 --- /dev/null +++ b/test/fixtures/wpt/workers/modules/resources/import-meta-url-export.js @@ -0,0 +1 @@ +export const meta_url = import.meta.url; diff --git a/test/fixtures/wpt/workers/modules/resources/import-meta-url-worker.js b/test/fixtures/wpt/workers/modules/resources/import-meta-url-worker.js new file mode 100644 index 000000000000..7887836a6cc1 --- /dev/null +++ b/test/fixtures/wpt/workers/modules/resources/import-meta-url-worker.js @@ -0,0 +1,10 @@ +if ('DedicatedWorkerGlobalScope' in self && + self instanceof DedicatedWorkerGlobalScope) { + postMessage(import.meta.url); +} else if ( + 'SharedWorkerGlobalScope' in self && + self instanceof SharedWorkerGlobalScope) { + self.onconnect = e => { + e.ports[0].postMessage(import.meta.url); + }; +} diff --git a/test/fixtures/wpt/workers/modules/resources/import-scripts-worker.js b/test/fixtures/wpt/workers/modules/resources/import-scripts-worker.js new file mode 100644 index 000000000000..d85f573ffe3a --- /dev/null +++ b/test/fixtures/wpt/workers/modules/resources/import-scripts-worker.js @@ -0,0 +1,33 @@ +try { + importScripts('empty-worker.js'); + if ('DedicatedWorkerGlobalScope' in self && + self instanceof DedicatedWorkerGlobalScope) { + postMessage('LOADED'); + } else if ( + 'SharedWorkerGlobalScope' in self && + self instanceof SharedWorkerGlobalScope) { + onconnect = e => { + e.ports[0].postMessage('LOADED'); + }; + } +} catch (e) { + // Post a message instead of propagating an ErrorEvent to the page because + // propagated event loses an error name. + // + // Step 1. "Let notHandled be the result of firing an event named error at the + // Worker object associated with the worker, using ErrorEvent, with the + // cancelable attribute initialized to true, the message, filename, lineno, + // and colno attributes initialized appropriately, and the error attribute + // initialized to null." + // https://html.spec.whatwg.org/multipage/workers.html#runtime-script-errors-2 + if ('DedicatedWorkerGlobalScope' in self && + self instanceof DedicatedWorkerGlobalScope) { + postMessage(e.name); + } else if ( + 'SharedWorkerGlobalScope' in self && + self instanceof SharedWorkerGlobalScope) { + onconnect = connectEvent => { + connectEvent.ports[0].postMessage(e.name); + }; + } +} diff --git a/test/fixtures/wpt/workers/modules/resources/import-test-cases.js b/test/fixtures/wpt/workers/modules/resources/import-test-cases.js new file mode 100644 index 000000000000..8ad89e8fda11 --- /dev/null +++ b/test/fixtures/wpt/workers/modules/resources/import-test-cases.js @@ -0,0 +1,59 @@ +const testCases = [ + { + scriptURL: '/workers/modules/resources/static-import-worker.js', + expectation: ['export-on-load-script.js'], + description: 'Static import.' + }, + { + scriptURL: '/workers/modules/resources/static-import-remote-origin-script-worker.sub.js', + expectation: ['export-on-load-script.js'], + description: 'Static import (cross-origin).' + }, + { + scriptURL: '/workers/modules/resources/static-import-redirect-worker.js', + expectation: ['export-on-load-script.js'], + description: 'Static import (redirect).' + }, + { + scriptURL: '/workers/modules/resources/nested-static-import-worker.js', + expectation: [ + 'export-on-static-import-script.js', + 'export-on-load-script.js' + ], + description: 'Nested static import.' + }, + { + scriptURL: '/workers/modules/resources/static-import-and-then-dynamic-import-worker.js', + expectation: [ + 'export-on-dynamic-import-script.js', + 'export-on-load-script.js' + ], + description: 'Static import and then dynamic import.' + }, + { + scriptURL: '/workers/modules/resources/dynamic-import-worker.js', + expectation: ['export-on-load-script.js'], + description: 'Dynamic import.' + }, + { + scriptURL: '/workers/modules/resources/nested-dynamic-import-worker.js', + expectation: [ + 'export-on-dynamic-import-script.js', + 'export-on-load-script.js' + ], + description: 'Nested dynamic import.' + }, + { + scriptURL: '/workers/modules/resources/dynamic-import-and-then-static-import-worker.js', + expectation: [ + 'export-on-static-import-script.js', + 'export-on-load-script.js' + ], + description: 'Dynamic import and then static import.' + }, + { + scriptURL: '/workers/modules/resources/eval-dynamic-import-worker.js', + expectation: ['export-on-load-script.js'], + description: 'eval(import()).' + } +]; diff --git a/test/fixtures/wpt/workers/modules/resources/nested-dynamic-import-worker.js b/test/fixtures/wpt/workers/modules/resources/nested-dynamic-import-worker.js new file mode 100644 index 000000000000..00da43c5f078 --- /dev/null +++ b/test/fixtures/wpt/workers/modules/resources/nested-dynamic-import-worker.js @@ -0,0 +1,34 @@ +// This script is meant to be imported by a module worker. It receives a +// message from the worker and responds with the list of imported modules. + +const sourcePromise = new Promise(resolve => { + if ('DedicatedWorkerGlobalScope' in self && + self instanceof DedicatedWorkerGlobalScope) { + self.onmessage = e => { + resolve(e.target); + }; + } else if ( + 'SharedWorkerGlobalScope' in self && + self instanceof SharedWorkerGlobalScope) { + self.onconnect = e => { + resolve(e.ports[0]); + }; + } else if ( + 'ServiceWorkerGlobalScope' in self && + self instanceof ServiceWorkerGlobalScope) { + self.onmessage = e => { + resolve(e.source); + }; + } +}); + +const importedModulesPromise = + import('./export-on-dynamic-import-script.js') + .then(module => module.ready) + .then(importedModules => importedModules) + .catch(error => `Failed to do dynamic import: ${error}`); + +Promise.all([sourcePromise, importedModulesPromise]).then(results => { + const [source, importedModules] = results; + source.postMessage(importedModules); +}); diff --git a/test/fixtures/wpt/workers/modules/resources/nested-static-import-worker.js b/test/fixtures/wpt/workers/modules/resources/nested-static-import-worker.js new file mode 100644 index 000000000000..c3a9ff0b799d --- /dev/null +++ b/test/fixtures/wpt/workers/modules/resources/nested-static-import-worker.js @@ -0,0 +1,21 @@ +// This script is meant to be imported by a module worker. It receives a +// message from the worker and responds with the list of imported modules. +import * as module from './export-on-static-import-script.js'; +if ('DedicatedWorkerGlobalScope' in self && + self instanceof DedicatedWorkerGlobalScope) { + self.onmessage = e => { + e.target.postMessage(module.importedModules); + }; +} else if ( + 'SharedWorkerGlobalScope' in self && + self instanceof SharedWorkerGlobalScope) { + self.onconnect = e => { + e.ports[0].postMessage(module.importedModules); + }; +} else if ( + 'ServiceWorkerGlobalScope' in self && + self instanceof ServiceWorkerGlobalScope) { + self.onmessage = e => { + e.source.postMessage(module.importedModules); + }; +} diff --git a/test/fixtures/wpt/workers/modules/resources/new-shared-worker-window.html b/test/fixtures/wpt/workers/modules/resources/new-shared-worker-window.html new file mode 100644 index 000000000000..84564fd7b6e5 --- /dev/null +++ b/test/fixtures/wpt/workers/modules/resources/new-shared-worker-window.html @@ -0,0 +1,19 @@ + +SharedWorker: new SharedWorker() + + + diff --git a/test/fixtures/wpt/workers/modules/resources/new-worker-window.html b/test/fixtures/wpt/workers/modules/resources/new-worker-window.html new file mode 100644 index 000000000000..32a89fae0ecd --- /dev/null +++ b/test/fixtures/wpt/workers/modules/resources/new-worker-window.html @@ -0,0 +1,19 @@ + +DedicatedWorker: new Worker() + + + diff --git a/test/fixtures/wpt/workers/modules/resources/post-message-on-load-worker.js b/test/fixtures/wpt/workers/modules/resources/post-message-on-load-worker.js new file mode 100644 index 000000000000..e1c547ab6a4d --- /dev/null +++ b/test/fixtures/wpt/workers/modules/resources/post-message-on-load-worker.js @@ -0,0 +1,10 @@ +if ('DedicatedWorkerGlobalScope' in self && + self instanceof DedicatedWorkerGlobalScope) { + postMessage('LOADED'); +} else if ( + 'SharedWorkerGlobalScope' in self && + self instanceof SharedWorkerGlobalScope) { + self.onconnect = e => { + e.ports[0].postMessage('LOADED'); + }; +} diff --git a/test/fixtures/wpt/workers/modules/resources/static-import-and-then-dynamic-import-worker.js b/test/fixtures/wpt/workers/modules/resources/static-import-and-then-dynamic-import-worker.js new file mode 100644 index 000000000000..2d857a2e90a1 --- /dev/null +++ b/test/fixtures/wpt/workers/modules/resources/static-import-and-then-dynamic-import-worker.js @@ -0,0 +1,34 @@ +// This script is meant to be imported by a module worker. It receives a +// message from the worker and responds with the list of imported modules. +import * as module from './export-on-dynamic-import-script.js'; + +const sourcePromise = new Promise(resolve => { + if ('DedicatedWorkerGlobalScope' in self && + self instanceof DedicatedWorkerGlobalScope) { + self.onmessage = e => { + resolve(e.target); + }; + } else if ( + 'SharedWorkerGlobalScope' in self && + self instanceof SharedWorkerGlobalScope) { + self.onconnect = e => { + resolve(e.ports[0]); + }; + } else if ( + 'ServiceWorkerGlobalScope' in self && + self instanceof ServiceWorkerGlobalScope) { + self.onmessage = e => { + resolve(e.source); + }; + } +}); + +export let importedModules = ['export-on-dynamic-import-script.js']; +const importedModulesPromise = module.ready + .then(importedModules => importedModules) + .catch(error => `Failed to do dynamic import: ${error}`); + +Promise.all([sourcePromise, importedModulesPromise]).then(results => { + const [source, importedModules] = results; + source.postMessage(importedModules); +}); diff --git a/test/fixtures/wpt/workers/modules/resources/static-import-data-url-block-cross-origin.js b/test/fixtures/wpt/workers/modules/resources/static-import-data-url-block-cross-origin.js new file mode 100644 index 000000000000..833348d66cce --- /dev/null +++ b/test/fixtures/wpt/workers/modules/resources/static-import-data-url-block-cross-origin.js @@ -0,0 +1,14 @@ +import * as module from "data:text/javascript, export const importedModules = ['export-block-cross-origin.js'];"; + +if ('DedicatedWorkerGlobalScope' in self && + self instanceof DedicatedWorkerGlobalScope) { + self.onmessage = e => { + e.target.postMessage(module.importedModules); + }; +} else if ( + 'SharedWorkerGlobalScope' in self && + self instanceof SharedWorkerGlobalScope) { + self.onconnect = e => { + e.ports[0].postMessage(module.importedModules); + }; +} diff --git a/test/fixtures/wpt/workers/modules/resources/static-import-non-existent-script-worker.js b/test/fixtures/wpt/workers/modules/resources/static-import-non-existent-script-worker.js new file mode 100644 index 000000000000..16f70e9daf49 --- /dev/null +++ b/test/fixtures/wpt/workers/modules/resources/static-import-non-existent-script-worker.js @@ -0,0 +1 @@ +import './non-existent-script.js'; diff --git a/test/fixtures/wpt/workers/modules/resources/static-import-redirect-worker.js b/test/fixtures/wpt/workers/modules/resources/static-import-redirect-worker.js new file mode 100644 index 000000000000..8434c1a34e28 --- /dev/null +++ b/test/fixtures/wpt/workers/modules/resources/static-import-redirect-worker.js @@ -0,0 +1,21 @@ +// This script is meant to be imported by a module worker. It receives a +// message from the worker and responds with the list of imported modules. +import * as module from './redirect.py?location=/workers/modules/resources/export-on-load-script.js'; +if ('DedicatedWorkerGlobalScope' in self && + self instanceof DedicatedWorkerGlobalScope) { + self.onmessage = e => { + e.target.postMessage(module.importedModules); + }; +} else if ( + 'SharedWorkerGlobalScope' in self && + self instanceof SharedWorkerGlobalScope) { + self.onconnect = e => { + e.ports[0].postMessage(module.importedModules); + }; +} else if ( + 'ServiceWorkerGlobalScope' in self && + self instanceof ServiceWorkerGlobalScope) { + self.onmessage = e => { + e.source.postMessage(module.importedModules); + }; +} diff --git a/test/fixtures/wpt/workers/modules/resources/static-import-remote-origin-credentials-checker-worker.sub.js b/test/fixtures/wpt/workers/modules/resources/static-import-remote-origin-credentials-checker-worker.sub.js new file mode 100644 index 000000000000..c543cb496160 --- /dev/null +++ b/test/fixtures/wpt/workers/modules/resources/static-import-remote-origin-credentials-checker-worker.sub.js @@ -0,0 +1,12 @@ +// Import a remote origin script. +import * as module from 'http://{{domains[www1]}}:{{ports[http][0]}}/workers/modules/resources/export-credentials.py'; +if ('DedicatedWorkerGlobalScope' in self && + self instanceof DedicatedWorkerGlobalScope) { + postMessage(module.cookie); +} else if ( + 'SharedWorkerGlobalScope' in self && + self instanceof SharedWorkerGlobalScope) { + onconnect = e => { + e.ports[0].postMessage(module.cookie); + }; +} diff --git a/test/fixtures/wpt/workers/modules/resources/static-import-remote-origin-referrer-checker-worker.sub.js b/test/fixtures/wpt/workers/modules/resources/static-import-remote-origin-referrer-checker-worker.sub.js new file mode 100644 index 000000000000..c1f8340f36d7 --- /dev/null +++ b/test/fixtures/wpt/workers/modules/resources/static-import-remote-origin-referrer-checker-worker.sub.js @@ -0,0 +1,12 @@ +// Import a remote origin script. +import * as module from 'https://{{hosts[alt][]}}:{{ports[https][0]}}/workers/modules/resources/export-referrer-checker.py'; +if ('DedicatedWorkerGlobalScope' in self && + self instanceof DedicatedWorkerGlobalScope) { + postMessage(module.referrer); +} else if ( + 'SharedWorkerGlobalScope' in self && + self instanceof SharedWorkerGlobalScope) { + onconnect = e => { + e.ports[0].postMessage(module.referrer); + }; +} diff --git a/test/fixtures/wpt/workers/modules/resources/static-import-remote-origin-script-worker.sub.js b/test/fixtures/wpt/workers/modules/resources/static-import-remote-origin-script-worker.sub.js new file mode 100644 index 000000000000..6432dd5d80d0 --- /dev/null +++ b/test/fixtures/wpt/workers/modules/resources/static-import-remote-origin-script-worker.sub.js @@ -0,0 +1,20 @@ +// Import a remote origin script. +import * as module from 'https://{{domains[www1]}}:{{ports[https][0]}}/workers/modules/resources/export-on-load-script.py'; +if ('DedicatedWorkerGlobalScope' in self && + self instanceof DedicatedWorkerGlobalScope) { + self.onmessage = e => { + e.target.postMessage(module.importedModules); + }; +} else if ( + 'SharedWorkerGlobalScope' in self && + self instanceof SharedWorkerGlobalScope) { + self.onconnect = e => { + e.ports[0].postMessage(module.importedModules); + }; +} else if ( + 'ServiceWorkerGlobalScope' in self && + self instanceof ServiceWorkerGlobalScope) { + self.onmessage = e => { + e.source.postMessage(module.importedModules); + }; +} diff --git a/test/fixtures/wpt/workers/modules/resources/static-import-same-origin-credentials-checker-worker.js b/test/fixtures/wpt/workers/modules/resources/static-import-same-origin-credentials-checker-worker.js new file mode 100644 index 000000000000..e83dc92070ff --- /dev/null +++ b/test/fixtures/wpt/workers/modules/resources/static-import-same-origin-credentials-checker-worker.js @@ -0,0 +1,11 @@ +import * as module from './export-credentials.py'; +if ('DedicatedWorkerGlobalScope' in self && + self instanceof DedicatedWorkerGlobalScope) { + postMessage(module.cookie); +} else if ( + 'SharedWorkerGlobalScope' in self && + self instanceof SharedWorkerGlobalScope) { + onconnect = e => { + e.ports[0].postMessage(module.cookie); + }; +} diff --git a/test/fixtures/wpt/workers/modules/resources/static-import-same-origin-referrer-checker-worker.js b/test/fixtures/wpt/workers/modules/resources/static-import-same-origin-referrer-checker-worker.js new file mode 100644 index 000000000000..ffcab9e45fdf --- /dev/null +++ b/test/fixtures/wpt/workers/modules/resources/static-import-same-origin-referrer-checker-worker.js @@ -0,0 +1,11 @@ +import * as module from './export-referrer-checker.py'; +if ('DedicatedWorkerGlobalScope' in self && + self instanceof DedicatedWorkerGlobalScope) { + postMessage(module.referrer); +} else if ( + 'SharedWorkerGlobalScope' in self && + self instanceof SharedWorkerGlobalScope) { + onconnect = e => { + e.ports[0].postMessage(module.referrer); + }; +} diff --git a/test/fixtures/wpt/workers/modules/resources/static-import-script-block-cross-origin.js b/test/fixtures/wpt/workers/modules/resources/static-import-script-block-cross-origin.js new file mode 100644 index 000000000000..82be8e7ce72e --- /dev/null +++ b/test/fixtures/wpt/workers/modules/resources/static-import-script-block-cross-origin.js @@ -0,0 +1,14 @@ +import * as module from './export-block-cross-origin.js'; + +if ('DedicatedWorkerGlobalScope' in self && + self instanceof DedicatedWorkerGlobalScope) { + self.onmessage = e => { + e.target.postMessage(module.importedModules); + }; +} else if ( + 'SharedWorkerGlobalScope' in self && + self instanceof SharedWorkerGlobalScope) { + self.onconnect = e => { + e.ports[0].postMessage(module.importedModules); + }; +} diff --git a/test/fixtures/wpt/workers/modules/resources/static-import-syntax-error.js b/test/fixtures/wpt/workers/modules/resources/static-import-syntax-error.js new file mode 100644 index 000000000000..3a20e792c455 --- /dev/null +++ b/test/fixtures/wpt/workers/modules/resources/static-import-syntax-error.js @@ -0,0 +1 @@ +import * as module from './syntax-error.js'; diff --git a/test/fixtures/wpt/workers/modules/resources/static-import-worker.js b/test/fixtures/wpt/workers/modules/resources/static-import-worker.js new file mode 100644 index 000000000000..19a347999d38 --- /dev/null +++ b/test/fixtures/wpt/workers/modules/resources/static-import-worker.js @@ -0,0 +1,21 @@ +// This script is meant to be imported by a module worker. It receives a +// message from the worker and responds with the list of imported modules. +import * as module from './export-on-load-script.js'; +if ('DedicatedWorkerGlobalScope' in self && + self instanceof DedicatedWorkerGlobalScope) { + self.onmessage = e => { + e.target.postMessage(module.importedModules); + }; +} else if ( + 'SharedWorkerGlobalScope' in self && + self instanceof SharedWorkerGlobalScope) { + self.onconnect = e => { + e.ports[0].postMessage(module.importedModules); + }; +} else if ( + 'ServiceWorkerGlobalScope' in self && + self instanceof ServiceWorkerGlobalScope) { + self.onmessage = e => { + e.source.postMessage(module.importedModules); + }; +} diff --git a/test/fixtures/wpt/workers/modules/resources/syntax-error.js b/test/fixtures/wpt/workers/modules/resources/syntax-error.js new file mode 100644 index 000000000000..8c5c4df671bc --- /dev/null +++ b/test/fixtures/wpt/workers/modules/resources/syntax-error.js @@ -0,0 +1 @@ +1 + ; diff --git a/test/fixtures/wpt/workers/modules/resources/throw.js b/test/fixtures/wpt/workers/modules/resources/throw.js new file mode 100644 index 000000000000..3d876d43d930 --- /dev/null +++ b/test/fixtures/wpt/workers/modules/resources/throw.js @@ -0,0 +1 @@ +throw new Error('custom message'); diff --git a/test/fixtures/wpt/workers/modules/shared-worker-import-blob-url.window.js b/test/fixtures/wpt/workers/modules/shared-worker-import-blob-url.window.js new file mode 100644 index 000000000000..a79d5725ad87 --- /dev/null +++ b/test/fixtures/wpt/workers/modules/shared-worker-import-blob-url.window.js @@ -0,0 +1,26 @@ +// META: script=/workers/modules/resources/import-test-cases.js + +// Imports |testCase.scriptURL| on a shared worker loaded from a blob URL, +// and waits until the list of imported modules is sent from the worker. Passes +// if the list is equal to |testCase.expectation|. +function import_blob_url_test(testCase) { + promise_test(async () => { + const importURL = new URL(testCase.scriptURL, location.href); + const blob = + new Blob([`import "${importURL}";`], {type: 'text/javascript'}); + const blobURL = URL.createObjectURL(blob); + const worker = new SharedWorker(blobURL, {type: 'module'}); + worker.port.postMessage('Send message for tests from main script.'); + const msgEvent = await new Promise((resolve, reject) => { + worker.port.onmessage = resolve; + worker.onerror = error => { + const msg = error instanceof ErrorEvent ? error.message + : 'unknown error'; + reject(msg); + }; + }); + assert_array_equals(msgEvent.data, testCase.expectation); + }, testCase.description); +} + +testCases.forEach(import_blob_url_test); diff --git a/test/fixtures/wpt/workers/modules/shared-worker-import-csp.html b/test/fixtures/wpt/workers/modules/shared-worker-import-csp.html new file mode 100644 index 000000000000..c7ca37557a1d --- /dev/null +++ b/test/fixtures/wpt/workers/modules/shared-worker-import-csp.html @@ -0,0 +1,128 @@ + +SharedWorker: CSP for ES Modules + + + + diff --git a/test/fixtures/wpt/workers/modules/shared-worker-import-data-url-cross-origin.html b/test/fixtures/wpt/workers/modules/shared-worker-import-data-url-cross-origin.html new file mode 100644 index 000000000000..06724a2b9ea5 --- /dev/null +++ b/test/fixtures/wpt/workers/modules/shared-worker-import-data-url-cross-origin.html @@ -0,0 +1,46 @@ + +SharedWorker: ES modules for data URL workers + + + diff --git a/test/fixtures/wpt/workers/modules/shared-worker-import-data-url.window.js b/test/fixtures/wpt/workers/modules/shared-worker-import-data-url.window.js new file mode 100644 index 000000000000..5c77f6d93661 --- /dev/null +++ b/test/fixtures/wpt/workers/modules/shared-worker-import-data-url.window.js @@ -0,0 +1,25 @@ +// META: script=/workers/modules/resources/import-test-cases.js + +// Imports |testCase.scriptURL| on a shared worker loaded from a data URL, +// and waits until the list of imported modules is sent from the worker. Passes +// if the list is equal to |testCase.expectation|. +function import_data_url_test(testCase) { + promise_test(async () => { + // The Access-Control-Allow-Origin header is necessary because a worker + // loaded from a data URL has a null origin and import() on the worker + // without the header is blocked. + const importURL = new URL(testCase.scriptURL, location.href) + + '?pipe=header(Access-Control-Allow-Origin, *)'; + const dataURL = `data:text/javascript,import "${importURL}";`; + + const worker = new SharedWorker(dataURL, { type: 'module'}); + worker.port.postMessage('Send message for tests from main script.'); + const msgEvent = await new Promise((resolve, reject) =>{ + worker.port.onmessage = resolve; + worker.onerror = reject; + }).catch(e => assert_true(false)); + assert_array_equals(msgEvent.data, testCase.expectation); + }, testCase.description); +} + +testCases.forEach(import_data_url_test); diff --git a/test/fixtures/wpt/workers/modules/shared-worker-import-failure.html b/test/fixtures/wpt/workers/modules/shared-worker-import-failure.html new file mode 100644 index 000000000000..c9d166c4fe78 --- /dev/null +++ b/test/fixtures/wpt/workers/modules/shared-worker-import-failure.html @@ -0,0 +1,70 @@ + +SharedWorker: import failure + + + + diff --git a/test/fixtures/wpt/workers/modules/shared-worker-import-meta.html b/test/fixtures/wpt/workers/modules/shared-worker-import-meta.html new file mode 100644 index 000000000000..e8e9b51f6a50 --- /dev/null +++ b/test/fixtures/wpt/workers/modules/shared-worker-import-meta.html @@ -0,0 +1,49 @@ + +SharedWorker: import.meta + + + diff --git a/test/fixtures/wpt/workers/modules/shared-worker-import-referrer.html b/test/fixtures/wpt/workers/modules/shared-worker-import-referrer.html new file mode 100644 index 000000000000..1096fd2ad872 --- /dev/null +++ b/test/fixtures/wpt/workers/modules/shared-worker-import-referrer.html @@ -0,0 +1,259 @@ + +SharedWorker: Referrer + + + + diff --git a/test/fixtures/wpt/workers/modules/shared-worker-import.window.js b/test/fixtures/wpt/workers/modules/shared-worker-import.window.js new file mode 100644 index 000000000000..5be49ec12598 --- /dev/null +++ b/test/fixtures/wpt/workers/modules/shared-worker-import.window.js @@ -0,0 +1,22 @@ +// META: script=/workers/modules/resources/import-test-cases.js + +// Starts a shared worker for |testCase.scriptURL| and waits until the list +// of imported modules is sent from the worker. Passes if the list is equal to +// |testCase.expectation|. +function import_test(testCase) { + promise_test(async () => { + const worker = new SharedWorker(testCase.scriptURL, {type: 'module'}); + worker.port.postMessage('Send message for tests from main script.'); + const msgEvent = await new Promise((resolve, reject) => { + worker.port.onmessage = resolve; + worker.onerror = error => { + const msg = error instanceof ErrorEvent ? error.message + : 'unknown error'; + reject(msg); + }; + }); + assert_array_equals(msgEvent.data, testCase.expectation); + }, testCase.description); +} + +testCases.forEach(import_test); diff --git a/test/fixtures/wpt/workers/modules/shared-worker-options-credentials.html b/test/fixtures/wpt/workers/modules/shared-worker-options-credentials.html new file mode 100644 index 000000000000..221dd01a376f --- /dev/null +++ b/test/fixtures/wpt/workers/modules/shared-worker-options-credentials.html @@ -0,0 +1,309 @@ + +SharedWorker: WorkerOptions 'credentials' + + + + + diff --git a/test/fixtures/wpt/workers/modules/shared-worker-options-credentials.html.headers b/test/fixtures/wpt/workers/modules/shared-worker-options-credentials.html.headers new file mode 100644 index 000000000000..8da851ab7363 --- /dev/null +++ b/test/fixtures/wpt/workers/modules/shared-worker-options-credentials.html.headers @@ -0,0 +1,2 @@ +Set-Cookie: COOKIE_NAME=1 +Access-Control-Allow-Credentials: true diff --git a/test/fixtures/wpt/workers/modules/shared-worker-options-type.html b/test/fixtures/wpt/workers/modules/shared-worker-options-type.html new file mode 100644 index 000000000000..f62eeeb76b9f --- /dev/null +++ b/test/fixtures/wpt/workers/modules/shared-worker-options-type.html @@ -0,0 +1,48 @@ + +SharedWorker: WorkerOptions 'type' + + + diff --git a/test/fixtures/wpt/workers/modules/shared-worker-parse-error-failure.html b/test/fixtures/wpt/workers/modules/shared-worker-parse-error-failure.html new file mode 100644 index 000000000000..f197d81e36ac --- /dev/null +++ b/test/fixtures/wpt/workers/modules/shared-worker-parse-error-failure.html @@ -0,0 +1,53 @@ + +SharedWorker: parse error failure + + + + diff --git a/test/fixtures/wpt/workers/multi-globals/WEB_FEATURES.yml b/test/fixtures/wpt/workers/multi-globals/WEB_FEATURES.yml new file mode 100644 index 000000000000..b16862ba1c01 --- /dev/null +++ b/test/fixtures/wpt/workers/multi-globals/WEB_FEATURES.yml @@ -0,0 +1,2 @@ +rules: +- "**": [dedicated-workers] diff --git a/test/fixtures/wpt/workers/multi-globals/current/current.html b/test/fixtures/wpt/workers/multi-globals/current/current.html new file mode 100644 index 000000000000..e6261f83883f --- /dev/null +++ b/test/fixtures/wpt/workers/multi-globals/current/current.html @@ -0,0 +1,3 @@ + + +Current page diff --git a/test/fixtures/wpt/workers/multi-globals/current/worker.js b/test/fixtures/wpt/workers/multi-globals/current/worker.js new file mode 100644 index 000000000000..44103842a40d --- /dev/null +++ b/test/fixtures/wpt/workers/multi-globals/current/worker.js @@ -0,0 +1 @@ +postMessage('current'); diff --git a/test/fixtures/wpt/workers/multi-globals/incumbent/incumbent.html b/test/fixtures/wpt/workers/multi-globals/incumbent/incumbent.html new file mode 100644 index 000000000000..d8bd1ae2c0f2 --- /dev/null +++ b/test/fixtures/wpt/workers/multi-globals/incumbent/incumbent.html @@ -0,0 +1,14 @@ + + +Incumbent page + + + + diff --git a/test/fixtures/wpt/workers/multi-globals/incumbent/worker.js b/test/fixtures/wpt/workers/multi-globals/incumbent/worker.js new file mode 100644 index 000000000000..03f02a869086 --- /dev/null +++ b/test/fixtures/wpt/workers/multi-globals/incumbent/worker.js @@ -0,0 +1 @@ +postMessage('incumbent'); diff --git a/test/fixtures/wpt/workers/multi-globals/url-parsing.html b/test/fixtures/wpt/workers/multi-globals/url-parsing.html new file mode 100644 index 000000000000..27bbc0cb50fe --- /dev/null +++ b/test/fixtures/wpt/workers/multi-globals/url-parsing.html @@ -0,0 +1,20 @@ + + +Multiple globals for Worker constructor: parsing scriptURL + + + + + + + + diff --git a/test/fixtures/wpt/workers/multi-globals/worker.js b/test/fixtures/wpt/workers/multi-globals/worker.js new file mode 100644 index 000000000000..fcc521e31370 --- /dev/null +++ b/test/fixtures/wpt/workers/multi-globals/worker.js @@ -0,0 +1 @@ +postMessage('entry'); diff --git a/test/fixtures/wpt/workers/name-property.html b/test/fixtures/wpt/workers/name-property.html new file mode 100644 index 000000000000..ccc2a9de3a9c --- /dev/null +++ b/test/fixtures/wpt/workers/name-property.html @@ -0,0 +1,30 @@ + + +Test the name property of shared and dedicated workers via the name constructor option + + + + + + + + diff --git a/test/fixtures/wpt/workers/nested_worker.worker.js b/test/fixtures/wpt/workers/nested_worker.worker.js new file mode 100644 index 000000000000..005b3c2f3039 --- /dev/null +++ b/test/fixtures/wpt/workers/nested_worker.worker.js @@ -0,0 +1,11 @@ +importScripts("/resources/testharness.js"); + +async_test(function() { + var worker1 = new Worker("support/WorkerBasic.js"); + worker1.postMessage("ping"); + worker1.onmessage = this.step_func_done(function(evt) { + assert_equals(evt.data, "Pass"); + worker1.terminate(); + }); +}, "Nested worker"); +done(); diff --git a/test/fixtures/wpt/workers/nested_worker_close_from_parent_worker.html b/test/fixtures/wpt/workers/nested_worker_close_from_parent_worker.html new file mode 100644 index 000000000000..57c98517cbd3 --- /dev/null +++ b/test/fixtures/wpt/workers/nested_worker_close_from_parent_worker.html @@ -0,0 +1,15 @@ + + +Test terminating a nested workers by calling terminate() from its parent worker + + + diff --git a/test/fixtures/wpt/workers/nested_worker_close_self.worker.js b/test/fixtures/wpt/workers/nested_worker_close_self.worker.js new file mode 100644 index 000000000000..73c87f405508 --- /dev/null +++ b/test/fixtures/wpt/workers/nested_worker_close_self.worker.js @@ -0,0 +1,12 @@ +importScripts("/resources/testharness.js"); + +async_test(function() { + if (!self.Worker) + done(); + const worker = new Worker("support/WorkerClose.js"); + worker.onmessage = this.step_func_done(function(e) { + assert_equals(e.data, "close"); + done(); + }); + worker.postMessage("close"); +}, "Nested work that closes itself"); diff --git a/test/fixtures/wpt/workers/nested_worker_importScripts.worker.js b/test/fixtures/wpt/workers/nested_worker_importScripts.worker.js new file mode 100644 index 000000000000..a671ee4e1e93 --- /dev/null +++ b/test/fixtures/wpt/workers/nested_worker_importScripts.worker.js @@ -0,0 +1,11 @@ +importScripts("/resources/testharness.js"); + +async_test(function() { + const worker = new Worker("support/ImportScripts.js"); + worker.postMessage("ping"); + worker.onmessage = this.step_func_done(function(evt) { + assert_equals(evt.data, "Pass"); + worker.terminate(); + }); +}, "Nested worker that calls importScripts()"); +done(); diff --git a/test/fixtures/wpt/workers/nested_worker_sync_xhr.worker.js b/test/fixtures/wpt/workers/nested_worker_sync_xhr.worker.js new file mode 100644 index 000000000000..609ecc49e16d --- /dev/null +++ b/test/fixtures/wpt/workers/nested_worker_sync_xhr.worker.js @@ -0,0 +1,11 @@ +importScripts("/resources/testharness.js"); + +async_test(function() { + const worker = new Worker("support/sync_xhr.js"); + worker.postMessage("ping"); + worker.onmessage = this.step_func_done(function(evt) { + assert_equals(evt.data, "Pass"); + worker.terminate(); + }); +}, "Nested worker that issues a sync XHR"); +done(); diff --git a/test/fixtures/wpt/workers/nested_worker_terminate_from_document.html b/test/fixtures/wpt/workers/nested_worker_terminate_from_document.html new file mode 100644 index 000000000000..10849b3f6ce8 --- /dev/null +++ b/test/fixtures/wpt/workers/nested_worker_terminate_from_document.html @@ -0,0 +1,14 @@ + + +Test terminating a chain of nested workers by calling terminate() from the owning document + + + diff --git a/test/fixtures/wpt/workers/non-automated/WEB_FEATURES.yml b/test/fixtures/wpt/workers/non-automated/WEB_FEATURES.yml new file mode 100644 index 000000000000..182aad016868 --- /dev/null +++ b/test/fixtures/wpt/workers/non-automated/WEB_FEATURES.yml @@ -0,0 +1,2 @@ +rules: +- navigator-onLine.html: [online] diff --git a/test/fixtures/wpt/workers/non-automated/infinite-nested.html b/test/fixtures/wpt/workers/non-automated/infinite-nested.html new file mode 100644 index 000000000000..3ff3edb35348 --- /dev/null +++ b/test/fixtures/wpt/workers/non-automated/infinite-nested.html @@ -0,0 +1,12 @@ + +infinite nested workers +

There number below should be increasing (ideally never-ending).

+
0
+ \ No newline at end of file diff --git a/test/fixtures/wpt/workers/non-automated/infinite-nested.js b/test/fixtures/wpt/workers/non-automated/infinite-nested.js new file mode 100644 index 000000000000..137dd0a2e281 --- /dev/null +++ b/test/fixtures/wpt/workers/non-automated/infinite-nested.js @@ -0,0 +1,5 @@ +postMessage(1); +var w = new Worker('infinite-nested.js'); +w.onmessage = function(e) { + postMessage(e.data); +} \ No newline at end of file diff --git a/test/fixtures/wpt/workers/non-automated/infinite-sibling-and-nested.html b/test/fixtures/wpt/workers/non-automated/infinite-sibling-and-nested.html new file mode 100644 index 000000000000..463546cc969f --- /dev/null +++ b/test/fixtures/wpt/workers/non-automated/infinite-sibling-and-nested.html @@ -0,0 +1,12 @@ + +infinite sibling and nested workers +

The number below should be increasing (ideally never-ending).

+
0
+ diff --git a/test/fixtures/wpt/workers/non-automated/infinite-sibling-and-nested.js b/test/fixtures/wpt/workers/non-automated/infinite-sibling-and-nested.js new file mode 100644 index 000000000000..cf7b794a414d --- /dev/null +++ b/test/fixtures/wpt/workers/non-automated/infinite-sibling-and-nested.js @@ -0,0 +1,8 @@ +function createWorker() { + var worker = new Worker('infinite-nested.js?' + Math.random()); + worker.onmessage = function(e) { + postMessage(e.data); + createWorker(); + } +} +createWorker(); \ No newline at end of file diff --git a/test/fixtures/wpt/workers/non-automated/infinite-sibling.html b/test/fixtures/wpt/workers/non-automated/infinite-sibling.html new file mode 100644 index 000000000000..edcb8d707227 --- /dev/null +++ b/test/fixtures/wpt/workers/non-automated/infinite-sibling.html @@ -0,0 +1,12 @@ + +infinite sibling workers +

The number below should be increasing (ideally never-ending).

+
0
+ diff --git a/test/fixtures/wpt/workers/non-automated/infinite-sibling.js b/test/fixtures/wpt/workers/non-automated/infinite-sibling.js new file mode 100644 index 000000000000..6424f7009324 --- /dev/null +++ b/test/fixtures/wpt/workers/non-automated/infinite-sibling.js @@ -0,0 +1,8 @@ +function createWorker() { + var worker = new Worker('post-a-1.js?' + Math.random()); + worker.onmessage = function(e) { + postMessage(e.data); + createWorker(); + } +} +createWorker(); \ No newline at end of file diff --git a/test/fixtures/wpt/workers/non-automated/navigator-onLine.html b/test/fixtures/wpt/workers/non-automated/navigator-onLine.html new file mode 100644 index 000000000000..5f2746b54633 --- /dev/null +++ b/test/fixtures/wpt/workers/non-automated/navigator-onLine.html @@ -0,0 +1,29 @@ + +navigator.onLine in dedicated worker +
Log:
+
+ +

As you go online and offline, the log should be filled with the correct status of navigator.onLine.

+

\ No newline at end of file diff --git a/test/fixtures/wpt/workers/non-automated/navigator-onLine.js b/test/fixtures/wpt/workers/non-automated/navigator-onLine.js new file mode 100644 index 000000000000..592b286bb352 --- /dev/null +++ b/test/fixtures/wpt/workers/non-automated/navigator-onLine.js @@ -0,0 +1,11 @@ +if ('onmessage' in self) { // dedicated worker + onmessage = function(e) { + postMessage(navigator.onLine); + } +} else { // shared worker + onconnect = function(e) { + e.ports[0].onmessage = function(e) { + this.postMessage(navigator.onLine); + } + } +} \ No newline at end of file diff --git a/test/fixtures/wpt/workers/non-automated/post-a-1.js b/test/fixtures/wpt/workers/non-automated/post-a-1.js new file mode 100644 index 000000000000..2318c2e267db --- /dev/null +++ b/test/fixtures/wpt/workers/non-automated/post-a-1.js @@ -0,0 +1 @@ +postMessage(1); \ No newline at end of file diff --git a/test/fixtures/wpt/workers/opaque-origin.html b/test/fixtures/wpt/workers/opaque-origin.html new file mode 100644 index 000000000000..83574b456fec --- /dev/null +++ b/test/fixtures/wpt/workers/opaque-origin.html @@ -0,0 +1,17 @@ + + + + + + + + diff --git a/test/fixtures/wpt/workers/postMessage_DataCloneErr.htm b/test/fixtures/wpt/workers/postMessage_DataCloneErr.htm new file mode 100644 index 000000000000..24093ce4e3e5 --- /dev/null +++ b/test/fixtures/wpt/workers/postMessage_DataCloneErr.htm @@ -0,0 +1,13 @@ + + postMessage() with WorkerNavigator + + +
+ diff --git a/test/fixtures/wpt/workers/postMessage_block.https.html b/test/fixtures/wpt/workers/postMessage_block.https.html new file mode 100644 index 000000000000..c3e69f6193f0 --- /dev/null +++ b/test/fixtures/wpt/workers/postMessage_block.https.html @@ -0,0 +1,18 @@ + + + + + + + diff --git a/test/fixtures/wpt/workers/postMessage_block.https.html.headers b/test/fixtures/wpt/workers/postMessage_block.https.html.headers new file mode 100644 index 000000000000..63b60e490f47 --- /dev/null +++ b/test/fixtures/wpt/workers/postMessage_block.https.html.headers @@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp diff --git a/test/fixtures/wpt/workers/postMessage_clone_port.htm b/test/fixtures/wpt/workers/postMessage_clone_port.htm new file mode 100644 index 000000000000..b1d7b84e3c09 --- /dev/null +++ b/test/fixtures/wpt/workers/postMessage_clone_port.htm @@ -0,0 +1,22 @@ + + postMessage(): clone a port + + +
+ diff --git a/test/fixtures/wpt/workers/postMessage_clone_port_error.htm b/test/fixtures/wpt/workers/postMessage_clone_port_error.htm new file mode 100644 index 000000000000..3558987476bd --- /dev/null +++ b/test/fixtures/wpt/workers/postMessage_clone_port_error.htm @@ -0,0 +1,14 @@ + + postMessage(): cloning source port + + +
+ diff --git a/test/fixtures/wpt/workers/postMessage_event_properties.htm b/test/fixtures/wpt/workers/postMessage_event_properties.htm new file mode 100644 index 000000000000..8122413de40d --- /dev/null +++ b/test/fixtures/wpt/workers/postMessage_event_properties.htm @@ -0,0 +1,24 @@ + + postMessage(): MessageEvent properties + + +
+ diff --git a/test/fixtures/wpt/workers/postMessage_ports_readonly_array.htm b/test/fixtures/wpt/workers/postMessage_ports_readonly_array.htm new file mode 100644 index 000000000000..bd833ede9361 --- /dev/null +++ b/test/fixtures/wpt/workers/postMessage_ports_readonly_array.htm @@ -0,0 +1,22 @@ + + postMessage(): read-only ports array + + +
+ diff --git a/test/fixtures/wpt/workers/postMessage_target_source.htm b/test/fixtures/wpt/workers/postMessage_target_source.htm new file mode 100644 index 000000000000..7d684916dde2 --- /dev/null +++ b/test/fixtures/wpt/workers/postMessage_target_source.htm @@ -0,0 +1,18 @@ + + postMessage(): target port and source port + + +
+ diff --git a/test/fixtures/wpt/workers/resources/shared-worker-memory.js b/test/fixtures/wpt/workers/resources/shared-worker-memory.js new file mode 100644 index 000000000000..b1504f38c504 --- /dev/null +++ b/test/fixtures/wpt/workers/resources/shared-worker-memory.js @@ -0,0 +1,30 @@ +'use strict'; + +let stored_data = null; + +function processMessage(e) { + function respond(data) { + e.currentTarget.postMessage(Object.assign(data, {reqid: e.data.reqid})); + } + + switch (e.data.op) { + case 'load': { + respond({ack: 'load', status: 'OK', data: stored_data}); + break; + } + case 'store': { + try { + stored_data = e.data.data + } catch (err) { + respond({ack: 'store', status: 'ERROR', error: err.name}); + return; + } + respond({ack: 'store', status: 'OK'}); + break; + } + } +} + +self.addEventListener('connect', e => { + e.ports[0].onmessage = processMessage; +}); diff --git a/test/fixtures/wpt/workers/resources/worker-url-encoding.js b/test/fixtures/wpt/workers/resources/worker-url-encoding.js new file mode 100644 index 000000000000..444a19db4e2d --- /dev/null +++ b/test/fixtures/wpt/workers/resources/worker-url-encoding.js @@ -0,0 +1 @@ +postMessage(location.search); \ No newline at end of file diff --git a/test/fixtures/wpt/workers/same-origin-check.sub.html b/test/fixtures/wpt/workers/same-origin-check.sub.html new file mode 100644 index 000000000000..7af021b8dbb7 --- /dev/null +++ b/test/fixtures/wpt/workers/same-origin-check.sub.html @@ -0,0 +1,56 @@ + + + + diff --git a/test/fixtures/wpt/workers/same-site-cookies/first-party.all.tentative.https.window.js b/test/fixtures/wpt/workers/same-site-cookies/first-party.all.tentative.https.window.js new file mode 100644 index 000000000000..ac6030e65403 --- /dev/null +++ b/test/fixtures/wpt/workers/same-site-cookies/first-party.all.tentative.https.window.js @@ -0,0 +1,29 @@ +// META: script=/resources/testdriver.js +// META: script=/resources/testdriver-vendor.js +// META: script=/workers/same-site-cookies/resources/util.js + +'use strict'; + +// Here's the set-up for this test: +// Step 1 (window) Set cookies. +// Step 2 (window) Set up listener for cookie message and start worker. +// Step 3 (redirect) Redirect to worker script. +// Step 4 (worker) Send cookie message to window. +// Step 5 (window) Receive cookie message and cleanup. + +async_test(t => { + // Step 1 + const cookie_set_window = window.open("/workers/same-site-cookies/resources/set_cookies.py"); + cookie_set_window.onload = t.step_func(_ => { + // Step 2 + const worker = new SharedWorker("/workers/same-site-cookies/resources/worker_redirect.py", {sameSiteCookies: "all"}); + worker.port.onmessage = t.step_func(e => { + // Step 5 + getCookieNames().then(t.step_func((cookies) => { + assert_equals(e.data + cookies, "ReadOnLoad:StrictLaxNone,ReadOnFetch:StrictLaxNone,SetOnRedirectLoad:StrictLaxNone,SetOnLoad:StrictLaxNone,SetOnRedirectFetch:StrictLaxNone,SetOnFetch:StrictLaxNone", "Worker should get/set all cookies"); + cookie_set_window.close(); + t.done(); + })); + }); + }); +}, "Check SharedWorker sameSiteCookies option all for first-party"); diff --git a/test/fixtures/wpt/workers/same-site-cookies/first-party.default.tentative.https.window.js b/test/fixtures/wpt/workers/same-site-cookies/first-party.default.tentative.https.window.js new file mode 100644 index 000000000000..2c64ff628f5b --- /dev/null +++ b/test/fixtures/wpt/workers/same-site-cookies/first-party.default.tentative.https.window.js @@ -0,0 +1,29 @@ +// META: script=/resources/testdriver.js +// META: script=/resources/testdriver-vendor.js +// META: script=/workers/same-site-cookies/resources/util.js + +'use strict'; + +// Here's the set-up for this test: +// Step 1 (window) Set cookies. +// Step 2 (window) Set up listener for cookie message and start worker. +// Step 3 (redirect) Redirect to worker script. +// Step 4 (worker) Send cookie message to window. +// Step 5 (window) Receive cookie message and cleanup. + +async_test(t => { + // Step 1 + const cookie_set_window = window.open("/workers/same-site-cookies/resources/set_cookies.py"); + cookie_set_window.onload = t.step_func(_ => { + // Step 2 + const worker = new SharedWorker("/workers/same-site-cookies/resources/worker_redirect.py"); + worker.port.onmessage = t.step_func(e => { + // Step 5 + getCookieNames().then(t.step_func((cookies) => { + assert_equals(e.data + cookies, "ReadOnLoad:StrictLaxNone,ReadOnFetch:StrictLaxNone,SetOnRedirectLoad:StrictLaxNone,SetOnLoad:StrictLaxNone,SetOnRedirectFetch:StrictLaxNone,SetOnFetch:StrictLaxNone", "Worker should get/set all cookies"); + cookie_set_window.close(); + t.done(); + })); + }); + }); +}, "Check SharedWorker sameSiteCookies option default for first-party"); diff --git a/test/fixtures/wpt/workers/same-site-cookies/first-party.none.tentative.https.window.js b/test/fixtures/wpt/workers/same-site-cookies/first-party.none.tentative.https.window.js new file mode 100644 index 000000000000..76a8b1d8bcb5 --- /dev/null +++ b/test/fixtures/wpt/workers/same-site-cookies/first-party.none.tentative.https.window.js @@ -0,0 +1,29 @@ +// META: script=/resources/testdriver.js +// META: script=/resources/testdriver-vendor.js +// META: script=/workers/same-site-cookies/resources/util.js + +'use strict'; + +// Here's the set-up for this test: +// Step 1 (window) Set cookies. +// Step 2 (window) Set up listener for cookie message and start worker. +// Step 3 (redirect) Redirect to worker script. +// Step 4 (worker) Send cookie message to window. +// Step 5 (window) Receive cookie message and cleanup. + +async_test(t => { + // Step 1 + const cookie_set_window = window.open("/workers/same-site-cookies/resources/set_cookies.py"); + cookie_set_window.onload = t.step_func(_ => { + // Step 2 + const worker = new SharedWorker("/workers/same-site-cookies/resources/worker_redirect.py", {sameSiteCookies: "none"}); + worker.port.onmessage = t.step_func(e => { + // Step 5 + getCookieNames().then(t.step_func((cookies) => { + assert_equals(e.data + cookies, "ReadOnLoad:None,ReadOnFetch:None,SetOnRedirectLoad:None,SetOnLoad:None,SetOnRedirectFetch:None,SetOnFetch:None", "Worker should get/set SameSite=None cookies only"); + cookie_set_window.close(); + t.done(); + })); + }); + }); +}, "Check SharedWorker sameSiteCookies option none for first-party"); diff --git a/test/fixtures/wpt/workers/same-site-cookies/resources/iframe-iframe.html b/test/fixtures/wpt/workers/same-site-cookies/resources/iframe-iframe.html new file mode 100644 index 000000000000..efd4f3a65468 --- /dev/null +++ b/test/fixtures/wpt/workers/same-site-cookies/resources/iframe-iframe.html @@ -0,0 +1,31 @@ + + + + + + + diff --git a/test/fixtures/wpt/workers/same-site-cookies/resources/iframe.sub.html b/test/fixtures/wpt/workers/same-site-cookies/resources/iframe.sub.html new file mode 100644 index 000000000000..c4724d01d2f5 --- /dev/null +++ b/test/fixtures/wpt/workers/same-site-cookies/resources/iframe.sub.html @@ -0,0 +1,14 @@ + + + + + + + diff --git a/test/fixtures/wpt/workers/same-site-cookies/resources/util.js b/test/fixtures/wpt/workers/same-site-cookies/resources/util.js new file mode 100644 index 000000000000..67d9ee5c06bf --- /dev/null +++ b/test/fixtures/wpt/workers/same-site-cookies/resources/util.js @@ -0,0 +1,46 @@ +async function getCookieNames() { + const cookies = await test_driver.get_all_cookies(); + const cookie_names = {}; + cookies.forEach((element) => cookie_names[element["name"]] = true); + let message = ",SetOnRedirectLoad:"; + if (cookie_names.hasOwnProperty("samesite_strict_set_on_redirect_load")) { + message += "Strict"; + } + if (cookie_names.hasOwnProperty("samesite_lax_set_on_redirect_load")) { + message += "Lax"; + } + if (cookie_names.hasOwnProperty("samesite_none_set_on_redirect_load")) { + message += "None"; + } + message += ",SetOnLoad:"; + if (cookie_names.hasOwnProperty("samesite_strict_set_on_load")) { + message += "Strict"; + } + if (cookie_names.hasOwnProperty("samesite_lax_set_on_load")) { + message += "Lax"; + } + if (cookie_names.hasOwnProperty("samesite_none_set_on_load")) { + message += "None"; + } + message += ",SetOnRedirectFetch:"; + if (cookie_names.hasOwnProperty("samesite_strict_set_on_redirect_fetch")) { + message += "Strict"; + } + if (cookie_names.hasOwnProperty("samesite_lax_set_on_redirect_fetch")) { + message += "Lax"; + } + if (cookie_names.hasOwnProperty("samesite_none_set_on_redirect_fetch")) { + message += "None"; + } + message += ",SetOnFetch:"; + if (cookie_names.hasOwnProperty("samesite_strict_set_on_fetch")) { + message += "Strict"; + } + if (cookie_names.hasOwnProperty("samesite_lax_set_on_fetch")) { + message += "Lax"; + } + if (cookie_names.hasOwnProperty("samesite_none_set_on_fetch")) { + message += "None"; + } + return message; +} diff --git a/test/fixtures/wpt/workers/same-site-cookies/third-party.all.tentative.sub.https.window.js b/test/fixtures/wpt/workers/same-site-cookies/third-party.all.tentative.sub.https.window.js new file mode 100644 index 000000000000..21b53819d93f --- /dev/null +++ b/test/fixtures/wpt/workers/same-site-cookies/third-party.all.tentative.sub.https.window.js @@ -0,0 +1,32 @@ +// META: script=/resources/testdriver.js +// META: script=/resources/testdriver-vendor.js +// META: script=/workers/same-site-cookies/resources/util.js + +'use strict'; + +// Here's the set-up for this test: +// Step 1 (window) Set cookies. +// Step 2 (top-frame) Set up listener for "DidNotStart" message and open cross-site iframe. +// Step 3 (sub-frame) Open iframe same-site to top-frame. +// Step 4 (sub-sub-frame) Set up listener for message and start worker. +// Step 5 (redirect) Skipped. +// Step 6 (worker) Skipped. +// Step 7 (sub-sub-frame) Worker failed to start and window messages "DidNotStart". +// Step 8 (top-frame) Receive "DidNotStart" message and cleanup. + +async_test(t => { + // Step 1 + const cookie_set_window = window.open("/workers/same-site-cookies/resources/set_cookies.py"); + cookie_set_window.onload = t.step_func(_ => { + // Step 2 + window.addEventListener("message", t.step_func(e => { + // Step 8 + assert_equals(e.data, "DidNotStart", "Worker should not have started"); + cookie_set_window.close(); + t.done(); + })); + let iframe = document.createElement("iframe"); + iframe.src = "https://{{hosts[alt][]}}:{{ports[https][0]}}/workers/same-site-cookies/resources/iframe.sub.html?type=all"; + document.body.appendChild(iframe); + }); +}, "Check SharedWorker sameSiteCookies option all for third-party"); diff --git a/test/fixtures/wpt/workers/same-site-cookies/third-party.default.tentative.sub.https.window.js b/test/fixtures/wpt/workers/same-site-cookies/third-party.default.tentative.sub.https.window.js new file mode 100644 index 000000000000..bf499c1992c9 --- /dev/null +++ b/test/fixtures/wpt/workers/same-site-cookies/third-party.default.tentative.sub.https.window.js @@ -0,0 +1,34 @@ +// META: script=/resources/testdriver.js +// META: script=/resources/testdriver-vendor.js +// META: script=/workers/same-site-cookies/resources/util.js + +'use strict'; + +// Here's the set-up for this test: +// Step 1 (window) Set cookies. +// Step 2 (top-frame) Set up listener for cookie message and open cross-site iframe. +// Step 3 (sub-frame) Open iframe same-site to top-frame. +// Step 4 (sub-sub-frame) Set up listener for message and start worker. +// Step 5 (redirect) Redirect to worker script. +// Step 6 (worker) Send cookie message to iframe. +// Step 7 (sub-sub-frame) Receive message and pass on to window. +// Step 8 (top-frame) Receive cookie message and cleanup. + +async_test(t => { + // Step 1 + const cookie_set_window = window.open("/workers/same-site-cookies/resources/set_cookies.py"); + cookie_set_window.onload = t.step_func(_ => { + // Step 2 + window.addEventListener("message", t.step_func(e => { + // Step 8 + getCookieNames().then(t.step_func((cookies) => { + assert_equals(e.data + cookies, "ReadOnLoad:None,ReadOnFetch:None,SetOnRedirectLoad:None,SetOnLoad:None,SetOnRedirectFetch:None,SetOnFetch:None", "Worker should get/set SameSite=None cookies only"); + cookie_set_window.close(); + t.done(); + })); + })); + let iframe = document.createElement("iframe"); + iframe.src = "https://{{hosts[alt][]}}:{{ports[https][0]}}/workers/same-site-cookies/resources/iframe.sub.html?type=default"; + document.body.appendChild(iframe); + }); +}, "Check SharedWorker sameSiteCookies option default for third-party"); diff --git a/test/fixtures/wpt/workers/same-site-cookies/third-party.none.tentative.sub.https.window.js b/test/fixtures/wpt/workers/same-site-cookies/third-party.none.tentative.sub.https.window.js new file mode 100644 index 000000000000..f00e585f7783 --- /dev/null +++ b/test/fixtures/wpt/workers/same-site-cookies/third-party.none.tentative.sub.https.window.js @@ -0,0 +1,34 @@ +// META: script=/resources/testdriver.js +// META: script=/resources/testdriver-vendor.js +// META: script=/workers/same-site-cookies/resources/util.js + +'use strict'; + +// Here's the set-up for this test: +// Step 1 (window) Set cookies. +// Step 2 (top-frame) Set up listener for cookie message and open cross-site iframe. +// Step 3 (sub-frame) Open iframe same-site to top-frame. +// Step 4 (sub-sub-frame) Set up listener for message and start worker. +// Step 5 (redirect) Redirect to worker script. +// Step 6 (worker) Send cookie message to iframe. +// Step 7 (sub-sub-frame) Receive message and pass on to window. +// Step 8 (top-frame) Receive cookie message and cleanup. + +async_test(t => { + // Step 1 + const cookie_set_window = window.open("/workers/same-site-cookies/resources/set_cookies.py"); + cookie_set_window.onload = t.step_func(_ => { + // Step 2 + window.addEventListener("message", t.step_func(e => { + // Step 8 + getCookieNames().then(t.step_func((cookies) => { + assert_equals(e.data + cookies, "ReadOnLoad:None,ReadOnFetch:None,SetOnRedirectLoad:None,SetOnLoad:None,SetOnRedirectFetch:None,SetOnFetch:None", "Worker should get/set SameSite=None cookies only"); + cookie_set_window.close(); + t.done(); + })); + })); + let iframe = document.createElement("iframe"); + iframe.src = "https://{{hosts[alt][]}}:{{ports[https][0]}}/workers/same-site-cookies/resources/iframe.sub.html?type=none"; + document.body.appendChild(iframe); + }); +}, "Check SharedWorker sameSiteCookies option none for third-party"); diff --git a/test/fixtures/wpt/workers/semantics/encodings/001.html b/test/fixtures/wpt/workers/semantics/encodings/001.html new file mode 100644 index 000000000000..05ee5e006b45 --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/encodings/001.html @@ -0,0 +1,14 @@ + +encoding, dedicated worker + + +
+ \ No newline at end of file diff --git a/test/fixtures/wpt/workers/semantics/encodings/001.js b/test/fixtures/wpt/workers/semantics/encodings/001.js new file mode 100644 index 000000000000..03bc557c33c4 --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/encodings/001.js @@ -0,0 +1 @@ +postMessage('å'); \ No newline at end of file diff --git a/test/fixtures/wpt/workers/semantics/encodings/001.js.headers b/test/fixtures/wpt/workers/semantics/encodings/001.js.headers new file mode 100644 index 000000000000..5614aaa7f0f5 --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/encodings/001.js.headers @@ -0,0 +1 @@ +Content-Type: text/javascript; charset=windows-1252 diff --git a/test/fixtures/wpt/workers/semantics/encodings/002.html b/test/fixtures/wpt/workers/semantics/encodings/002.html new file mode 100644 index 000000000000..fecbffc18da7 --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/encodings/002.html @@ -0,0 +1,14 @@ + +encoding, shared worker + + +
+ diff --git a/test/fixtures/wpt/workers/semantics/encodings/002.js b/test/fixtures/wpt/workers/semantics/encodings/002.js new file mode 100644 index 000000000000..9dde7bbda921 --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/encodings/002.js @@ -0,0 +1,3 @@ +onconnect = function(e) { + e.ports[0].postMessage('å'); +} \ No newline at end of file diff --git a/test/fixtures/wpt/workers/semantics/encodings/002.js.headers b/test/fixtures/wpt/workers/semantics/encodings/002.js.headers new file mode 100644 index 000000000000..5614aaa7f0f5 --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/encodings/002.js.headers @@ -0,0 +1 @@ +Content-Type: text/javascript; charset=windows-1252 diff --git a/test/fixtures/wpt/workers/semantics/encodings/003.html b/test/fixtures/wpt/workers/semantics/encodings/003.html new file mode 100644 index 000000000000..095320e4d147 --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/encodings/003.html @@ -0,0 +1,14 @@ + +URL encoding, dedicated worker + + +
+ \ No newline at end of file diff --git a/test/fixtures/wpt/workers/semantics/encodings/003.js b/test/fixtures/wpt/workers/semantics/encodings/003.js new file mode 100644 index 000000000000..35bda8bba88b --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/encodings/003.js @@ -0,0 +1,5 @@ +var xhr = new XMLHttpRequest(); +xhr.open('GET', '003-1.py?x=å', false); +xhr.send(); +var passed = xhr.responseText == 'PASS'; +postMessage(passed); \ No newline at end of file diff --git a/test/fixtures/wpt/workers/semantics/encodings/004.html b/test/fixtures/wpt/workers/semantics/encodings/004.html new file mode 100644 index 000000000000..cd556b8190e7 --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/encodings/004.html @@ -0,0 +1,14 @@ + +URL encoding, shared worker + + +
+ \ No newline at end of file diff --git a/test/fixtures/wpt/workers/semantics/encodings/004.js b/test/fixtures/wpt/workers/semantics/encodings/004.js new file mode 100644 index 000000000000..5146929a73b5 --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/encodings/004.js @@ -0,0 +1,7 @@ +onconnect = function(e) { + var xhr = new XMLHttpRequest(); + xhr.open('GET', '003-1.py?x=å', false); + xhr.send(); + var passed = xhr.responseText == 'PASS'; + e.ports[0].postMessage(passed); +} \ No newline at end of file diff --git a/test/fixtures/wpt/workers/semantics/encodings/004.worker.js b/test/fixtures/wpt/workers/semantics/encodings/004.worker.js new file mode 100644 index 000000000000..28489a572be1 --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/encodings/004.worker.js @@ -0,0 +1,5 @@ +importScripts("/resources/testharness.js"); +test(function() { + assert_equals("�", "\ufffd"); +}, "Decoding invalid utf-8"); +done(); diff --git a/test/fixtures/wpt/workers/semantics/encodings/WEB_FEATURES.yml b/test/fixtures/wpt/workers/semantics/encodings/WEB_FEATURES.yml new file mode 100644 index 000000000000..082be9e2a20c --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/encodings/WEB_FEATURES.yml @@ -0,0 +1,4 @@ +rules: +- 002.html: [shared-workers] +- 004.html: [shared-workers] +- "*": [dedicated-workers] diff --git a/test/fixtures/wpt/workers/semantics/interface-objects/001.worker.js b/test/fixtures/wpt/workers/semantics/interface-objects/001.worker.js new file mode 100644 index 000000000000..a95da5638f52 --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/interface-objects/001.worker.js @@ -0,0 +1,82 @@ +importScripts("/resources/testharness.js"); +var expected = [ + // https://html.spec.whatwg.org/ + "WorkerGlobalScope", + "DedicatedWorkerGlobalScope", + "Worker", + "MessagePort", + "MessageEvent", + "WorkerNavigator", + "MessageChannel", + "WorkerLocation", + "ImageData", + "ImageBitmap", + "CanvasGradient", + "CanvasPattern", + "TextMetrics", + "Path2D", + "PromiseRejectionEvent", + "EventSource", + "BroadcastChannel", + // https://websockets.spec.whatwg.org/ + "WebSocket", + "CloseEvent", + // https://tc39.github.io/ecma262/ + "ArrayBuffer", + "Int8Array", + "Uint8Array", + "Uint8ClampedArray", + "Int16Array", + "Uint16Array", + "Int32Array", + "Uint32Array", + "Float16Array", + "Float32Array", + "Float64Array", + "DataView", + // https://xhr.spec.whatwg.org/ + "XMLHttpRequestEventTarget", + "XMLHttpRequestUpload", + "XMLHttpRequest", + "ProgressEvent", + "FormData", + // https://url.spec.whatwg.org/ + "URL", + "URLSearchParams", + // https://w3c.github.io/FileAPI/ + "File", + "Blob", + "FileList", + "FileReader", + "FileReaderSync", + // https://dom.spec.whatwg.org/ + "EventTarget", + "ErrorEvent", + "Event", + "CustomEvent", + // https://webidl.spec.whatwg.org/ + "DOMException", + // https://streams.spec.whatwg.org/ + "ReadableStream", + "WritableStream", + "ByteLengthQueuingStrategy", + "CountQueuingStrategy", + // http://w3c.github.io/IndexedDB/ + "IDBRequest", + "IDBOpenDBRequest", + "IDBVersionChangeEvent", + "IDBFactory", + "IDBDatabase", + "IDBObjectStore", + "IDBIndex", + "IDBKeyRange", + "IDBCursor", + "IDBCursorWithValue", + "IDBTransaction", +]; +for (var i = 0; i < expected.length; ++i) { + test(function () { + assert_own_property(self, expected[i]); + }, "The " + expected[i] + " interface object should be exposed."); +} +done(); diff --git a/test/fixtures/wpt/workers/semantics/interface-objects/002.worker.js b/test/fixtures/wpt/workers/semantics/interface-objects/002.worker.js new file mode 100644 index 000000000000..9c8dc6746e07 --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/interface-objects/002.worker.js @@ -0,0 +1,45 @@ +importScripts("/resources/testharness.js"); +var unexpected = [ + // https://html.spec.whatwg.org/ + "SharedWorker", + "CanvasPath", + "SharedWorkerGlobalScope", + "AbstractView", + "AbstractWorker", + "ApplicationCache", + "Location", + "Navigator", + "Audio", + "HTMLCanvasElement", + "Path", + "CanvasProxy", + "CanvasRenderingContext2D", + "DrawingStyle", + "BeforeUnloadEvent", + "PopStateEvent", + "HashChangeEvent", + "PageTransitionEvent", + // https://dom.spec.whatwg.org/ + "DOMImplementation", + // http://w3c.github.io/IndexedDB/ + "IDBEnvironment", + // https://www.w3.org/TR/2010/NOTE-webdatabase-20101118/ + "Database", + // https://w3c.github.io/uievents/ + "UIEvent", + "FocusEvent", + "MouseEvent", + "WheelEvent", + "InputEvent", + "KeyboardEvent", + "CompositionEvent", + // https://w3c.github.io/webvtt/ + "VTTCue", + "VTTRegion", +]; +for (var i = 0; i < unexpected.length; ++i) { + test(function () { + assert_false(unexpected[i] in self); + }, "The " + unexpected[i] + " interface object should not be exposed."); +} +done(); diff --git a/test/fixtures/wpt/workers/semantics/interface-objects/003.any.js b/test/fixtures/wpt/workers/semantics/interface-objects/003.any.js new file mode 100644 index 000000000000..9dcc024ab7b3 --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/interface-objects/003.any.js @@ -0,0 +1,82 @@ +// META: global=sharedworker + +var expected = [ + // https://html.spec.whatwg.org/ + "WorkerGlobalScope", + "SharedWorkerGlobalScope", + "Worker", + "MessagePort", + "MessageEvent", + "WorkerNavigator", + "MessageChannel", + "WorkerLocation", + "ImageData", + "ImageBitmap", + "CanvasGradient", + "CanvasPattern", + "Path2D", + "PromiseRejectionEvent", + "EventSource", + "BroadcastChannel", + // https://websockets.spec.whatwg.org/ + "WebSocket", + "CloseEvent", + // https://tc39.github.io/ecma262/ + "ArrayBuffer", + "Int8Array", + "Uint8Array", + "Uint8ClampedArray", + "Int16Array", + "Uint16Array", + "Int32Array", + "Uint32Array", + "Float16Array", + "Float32Array", + "Float64Array", + "DataView", + // https://xhr.spec.whatwg.org/ + "XMLHttpRequestEventTarget", + "XMLHttpRequestUpload", + "XMLHttpRequest", + "ProgressEvent", + "FormData", + // https://url.spec.whatwg.org/ + "URL", + "URLSearchParams", + // https://w3c.github.io/FileAPI/ + "File", + "Blob", + "FileList", + "FileReader", + "FileReaderSync", + // https://dom.spec.whatwg.org/ + "EventTarget", + "ErrorEvent", + "Event", + "CustomEvent", + // https://webidl.spec.whatwg.org/ + "DOMException", + // https://streams.spec.whatwg.org/ + "ReadableStream", + "WritableStream", + "ByteLengthQueuingStrategy", + "CountQueuingStrategy", + // http://w3c.github.io/IndexedDB/ + "IDBRequest", + "IDBOpenDBRequest", + "IDBVersionChangeEvent", + "IDBFactory", + "IDBDatabase", + "IDBObjectStore", + "IDBIndex", + "IDBKeyRange", + "IDBCursor", + "IDBCursorWithValue", + "IDBTransaction", +]; + +for (var i = 0; i < expected.length; ++i) { + test(function() { + assert_true(expected[i] in self); + }, "The " + expected[i] + " interface object should be exposed"); +} diff --git a/test/fixtures/wpt/workers/semantics/interface-objects/004.any.js b/test/fixtures/wpt/workers/semantics/interface-objects/004.any.js new file mode 100644 index 000000000000..1b0b93b5df0f --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/interface-objects/004.any.js @@ -0,0 +1,41 @@ +// META: global=sharedworker + +var unexpected = [ + // https://html.spec.whatwg.org/ + "ApplicationCache", + "SharedWorker", + "CanvasPath", + "DedicatedWorkerGlobalScope", + "AbstractView", + "AbstractWorker", + "Location", + "Navigator", + "DOMImplementation", + "Audio", + "HTMLCanvasElement", + "Path", + "CanvasProxy", + "CanvasRenderingContext2D", + "DrawingStyle", + "PopStateEvent", + "HashChangeEvent", + "PageTransitionEvent", + // http://w3c.github.io/IndexedDB/ + "IDBEnvironment", + // https://www.w3.org/TR/2010/NOTE-webdatabase-20101118/ + "Database", + // https://w3c.github.io/uievents/ + "UIEvent", + "FocusEvent", + "MouseEvent", + "WheelEvent", + "InputEvent", + "KeyboardEvent", + "CompositionEvent", +]; + +for (var i = 0; i < unexpected.length; ++i) { + test(function() { + assert_false(unexpected[i] in self); + }, "The " + unexpected[i] + " interface object should not be exposed"); +} diff --git a/test/fixtures/wpt/workers/semantics/interface-objects/WEB_FEATURES.yml b/test/fixtures/wpt/workers/semantics/interface-objects/WEB_FEATURES.yml new file mode 100644 index 000000000000..601723d1a665 --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/interface-objects/WEB_FEATURES.yml @@ -0,0 +1,7 @@ +rules: +# These "any.js" tests are limited to the SharedWorker context via the "META" +# configuration. +- 003.any.js: [shared-workers] +- 004.any.js: [shared-workers] +- 001.worker.js: [dedicated-workers] +- 002.worker.js: [dedicated-workers] diff --git a/test/fixtures/wpt/workers/semantics/multiple-workers/001.html b/test/fixtures/wpt/workers/semantics/multiple-workers/001.html new file mode 100644 index 000000000000..f9e2bbeabab1 --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/multiple-workers/001.html @@ -0,0 +1,23 @@ + +dedicated and shared worker in same page + + +
+ \ No newline at end of file diff --git a/test/fixtures/wpt/workers/semantics/multiple-workers/001.js b/test/fixtures/wpt/workers/semantics/multiple-workers/001.js new file mode 100644 index 000000000000..6d51169dea0e --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/multiple-workers/001.js @@ -0,0 +1,11 @@ +if ('onmessage' in self) { // dedicated worker + onmessage = function(e) { + postMessage(e.data); + } +} else { // shared worker + onconnect = function(e) { + e.ports[0].onmessage = function(e) { + this.postMessage(e.data); + } + } +} \ No newline at end of file diff --git a/test/fixtures/wpt/workers/semantics/multiple-workers/002.html b/test/fixtures/wpt/workers/semantics/multiple-workers/002.html new file mode 100644 index 000000000000..aa01e361d806 --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/multiple-workers/002.html @@ -0,0 +1,21 @@ + +creating 3 sibling dedicated workers + + +
+ \ No newline at end of file diff --git a/test/fixtures/wpt/workers/semantics/multiple-workers/002.js b/test/fixtures/wpt/workers/semantics/multiple-workers/002.js new file mode 100644 index 000000000000..2318c2e267db --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/multiple-workers/002.js @@ -0,0 +1 @@ +postMessage(1); \ No newline at end of file diff --git a/test/fixtures/wpt/workers/semantics/multiple-workers/003.html b/test/fixtures/wpt/workers/semantics/multiple-workers/003.html new file mode 100644 index 000000000000..f6e03c75f782 --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/multiple-workers/003.html @@ -0,0 +1,16 @@ + +creating 3 nested dedicated workers + + + +
+ diff --git a/test/fixtures/wpt/workers/semantics/multiple-workers/003.js b/test/fixtures/wpt/workers/semantics/multiple-workers/003.js new file mode 100644 index 000000000000..14a5a614b3d8 --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/multiple-workers/003.js @@ -0,0 +1,13 @@ +if (location.hash == '#1') { + var w2 = new Worker('003.js#2'); + w2.onmessage = function(e) { + postMessage('1'+e.data); + } +} else if (location.hash == '#2') { + var w3 = new Worker('003.js#3'); + w3.onmessage = function(e) { + postMessage('2'+e.data); + } +} else { + postMessage('3'); +} diff --git a/test/fixtures/wpt/workers/semantics/multiple-workers/004-1.html b/test/fixtures/wpt/workers/semantics/multiple-workers/004-1.html new file mode 100644 index 000000000000..eac038c5beef --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/multiple-workers/004-1.html @@ -0,0 +1,7 @@ + + + diff --git a/test/fixtures/wpt/workers/semantics/multiple-workers/004-2.js b/test/fixtures/wpt/workers/semantics/multiple-workers/004-2.js new file mode 100644 index 000000000000..e59cd6927e34 --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/multiple-workers/004-2.js @@ -0,0 +1,6 @@ +var port; +onconnect = function(e) { + if (!port) + port = e.ports[0]; + port.postMessage(1); +} \ No newline at end of file diff --git a/test/fixtures/wpt/workers/semantics/multiple-workers/004.html b/test/fixtures/wpt/workers/semantics/multiple-workers/004.html new file mode 100644 index 000000000000..552cc8a63340 --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/multiple-workers/004.html @@ -0,0 +1,37 @@ + +shared worker with multiple documents + + + +
+ + + diff --git a/test/fixtures/wpt/workers/semantics/multiple-workers/008-1.html b/test/fixtures/wpt/workers/semantics/multiple-workers/008-1.html new file mode 100644 index 000000000000..d19d7fa3369a --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/multiple-workers/008-1.html @@ -0,0 +1,8 @@ + +008-1 + \ No newline at end of file diff --git a/test/fixtures/wpt/workers/semantics/multiple-workers/008.html b/test/fixtures/wpt/workers/semantics/multiple-workers/008.html new file mode 100644 index 000000000000..ee38d80866e8 --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/multiple-workers/008.html @@ -0,0 +1,19 @@ + +messagechannel in shared worker + + +
+ + \ No newline at end of file diff --git a/test/fixtures/wpt/workers/semantics/multiple-workers/008.js b/test/fixtures/wpt/workers/semantics/multiple-workers/008.js new file mode 100644 index 000000000000..92593ebb865f --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/multiple-workers/008.js @@ -0,0 +1,6 @@ +var channel = new MessageChannel(); +var i = 0; +onconnect = function(e) { + i++; + e.ports[0].postMessage(1, [channel['port' + i]]); +} \ No newline at end of file diff --git a/test/fixtures/wpt/workers/semantics/multiple-workers/WEB_FEATURES.yml b/test/fixtures/wpt/workers/semantics/multiple-workers/WEB_FEATURES.yml new file mode 100644 index 000000000000..e3386cc09310 --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/multiple-workers/WEB_FEATURES.yml @@ -0,0 +1,4 @@ +rules: +- 004.html: [shared-workers] +- 008.html: [shared-workers] +- "*": [dedicated-workers] diff --git a/test/fixtures/wpt/workers/semantics/multiple-workers/exposure.any.js b/test/fixtures/wpt/workers/semantics/multiple-workers/exposure.any.js new file mode 100644 index 000000000000..7e226a7333fb --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/multiple-workers/exposure.any.js @@ -0,0 +1,11 @@ +// META: global=window,worker + +test(() => { + const assert = "ServiceWorkerGlobalScope" in globalThis ? assert_equals : assert_not_equals; + assert(globalThis.Worker, undefined); +}, "Worker exposure"); + +test(() => { + const assert = globalThis.GLOBAL.isWindow() ? assert_not_equals : assert_equals; + assert(globalThis.SharedWorker, undefined); +}, "SharedWorker exposure"); diff --git a/test/fixtures/wpt/workers/semantics/navigation/001-1.html b/test/fixtures/wpt/workers/semantics/navigation/001-1.html new file mode 100644 index 000000000000..c259c2c839f8 --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/navigation/001-1.html @@ -0,0 +1,15 @@ + +001-1 + +link \ No newline at end of file diff --git a/test/fixtures/wpt/workers/semantics/navigation/001-1.js b/test/fixtures/wpt/workers/semantics/navigation/001-1.js new file mode 100644 index 000000000000..f62c365e3221 --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/navigation/001-1.js @@ -0,0 +1 @@ +setInterval(function() { postMessage(new Date()) }, 10) \ No newline at end of file diff --git a/test/fixtures/wpt/workers/semantics/navigation/001.html b/test/fixtures/wpt/workers/semantics/navigation/001.html new file mode 100644 index 000000000000..f31c2590e58e --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/navigation/001.html @@ -0,0 +1,39 @@ + + +navigating + + +
+ + + + + diff --git a/test/fixtures/wpt/workers/semantics/navigation/002.html b/test/fixtures/wpt/workers/semantics/navigation/002.html new file mode 100644 index 000000000000..8ea98ef2d44a --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/navigation/002.html @@ -0,0 +1,38 @@ + + +navigating 2 + + +
+ + + + + diff --git a/test/fixtures/wpt/workers/semantics/navigation/WEB_FEATURES.yml b/test/fixtures/wpt/workers/semantics/navigation/WEB_FEATURES.yml new file mode 100644 index 000000000000..b16862ba1c01 --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/navigation/WEB_FEATURES.yml @@ -0,0 +1,2 @@ +rules: +- "**": [dedicated-workers] diff --git a/test/fixtures/wpt/workers/semantics/reporting-errors/001.html b/test/fixtures/wpt/workers/semantics/reporting-errors/001.html new file mode 100644 index 000000000000..d8b17289fe24 --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/reporting-errors/001.html @@ -0,0 +1,17 @@ + +shared worker, not handled + + +
+ diff --git a/test/fixtures/wpt/workers/semantics/reporting-errors/001.js b/test/fixtures/wpt/workers/semantics/reporting-errors/001.js new file mode 100644 index 000000000000..5736666cc3b6 --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/reporting-errors/001.js @@ -0,0 +1,28 @@ +var port; +var timeout; +onerror = function(a,b,c,d,e) { + // will return undefined, thus the error is "not handled" + // so error should be reported to the user, but this test doesn't check + // that. + // just make sure that this method is invoked with five arguments + clearTimeout(timeout); + var log = ''; + if (arguments.length != 5) + log += 'got ' + arguments.length + ' arguments, expected 5. '; + if (typeof a != 'string') + log += 'first argument wasn\'t a string. '; + if (b != location.href) + log += 'second argument was ' + b + ', expected ' + location.href + '. '; + if (typeof c != 'number') + log += 'third argument wasn\'t a number. '; + if (typeof d != 'number') + log += 'fourth argument wasn\'t a number. '; + if (e != 42) + log += 'fifth argument wasn\'t the thrown exception. '; + port.postMessage(log); +} +onconnect = function (e) { + port = e.ports[0]; + timeout = setTimeout(function() { port.postMessage('self.onerror was not invoked'); }, 250); + throw 42; // will "report the error" +} diff --git a/test/fixtures/wpt/workers/semantics/reporting-errors/002.html b/test/fixtures/wpt/workers/semantics/reporting-errors/002.html new file mode 100644 index 000000000000..4b322a5f07d1 --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/reporting-errors/002.html @@ -0,0 +1,17 @@ + +shared worker, addEventListener + + +
+ diff --git a/test/fixtures/wpt/workers/semantics/reporting-errors/002.js b/test/fixtures/wpt/workers/semantics/reporting-errors/002.js new file mode 100644 index 000000000000..ff96922634ff --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/reporting-errors/002.js @@ -0,0 +1,34 @@ +var port; +var timeout; +addEventListener('error', function(e) { + // event is not canceled, thus the error is "not handled" + // so error should be reported to the user, but this test doesn't check + // that. + // just make sure that this event has the right properties + clearTimeout(timeout); + var log = ''; + if (!self.ErrorEvent || Object.getPrototypeOf(e) != ErrorEvent.prototype) + log += 'event should be an ErrorEvent. '; + if (e.bubbles) + log += 'event should not bubble. '; + if (!e.cancelable) + log += 'event should be cancelable. '; + if (!e.isTrusted) + log += 'event should be trusted. '; + if (typeof e.message != 'string') + log += 'message wasn\'t a string. '; + if (e.filename != location.href) + log += 'filename was ' + e.filename + ', expected ' + location.href + '. '; + if (typeof e.lineno != 'number') + log += 'lineno wasn\'t a number. '; + if (typeof e.colno != 'number') + log += 'colno argument wasn\'t a number. '; + if (e.error != 42) + log += 'fifth argument wasn\'t the thrown exception. '; + port.postMessage(log); +}, false); +onconnect = function (e) { + port = e.ports[0]; + timeout = setTimeout(function() { port.postMessage('No error event fired'); }, 250); + throw 42; // will "report the error" +} diff --git a/test/fixtures/wpt/workers/semantics/reporting-errors/003.html b/test/fixtures/wpt/workers/semantics/reporting-errors/003.html new file mode 100644 index 000000000000..8ea59b810616 --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/reporting-errors/003.html @@ -0,0 +1,23 @@ + +shared worker, no error event on worker or port + + +
+ diff --git a/test/fixtures/wpt/workers/semantics/reporting-errors/003.js b/test/fixtures/wpt/workers/semantics/reporting-errors/003.js new file mode 100644 index 000000000000..8a3390bb2490 --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/reporting-errors/003.js @@ -0,0 +1,8 @@ +onconnect = function (e) { + setTimeout(function() { e.ports[0].postMessage(''); }, 250); + y(); // will "report the error" + // onerror is null so it'll be "not handled", and the error should be + // reported to the user, although we don't test that here + // make sure we don't fire an error event on the message port or the + // SharedWorker object +} diff --git a/test/fixtures/wpt/workers/semantics/reporting-errors/004-1.html b/test/fixtures/wpt/workers/semantics/reporting-errors/004-1.html new file mode 100644 index 000000000000..326e1399ec5f --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/reporting-errors/004-1.html @@ -0,0 +1,18 @@ + + diff --git a/test/fixtures/wpt/workers/semantics/reporting-errors/004.html b/test/fixtures/wpt/workers/semantics/reporting-errors/004.html new file mode 100644 index 000000000000..8516e52c6fe2 --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/reporting-errors/004.html @@ -0,0 +1,26 @@ + +shared worker in two documents and window.onerror + + +
+ diff --git a/test/fixtures/wpt/workers/semantics/reporting-errors/004.js b/test/fixtures/wpt/workers/semantics/reporting-errors/004.js new file mode 100644 index 000000000000..a68d2ab01def --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/reporting-errors/004.js @@ -0,0 +1,6 @@ +var i = 0; +onconnect = function (e) { + i++; + setTimeout(function() { e.ports[0].postMessage(i); }, 250); + y(); // will "report the error" +} diff --git a/test/fixtures/wpt/workers/semantics/reporting-errors/WEB_FEATURES.yml b/test/fixtures/wpt/workers/semantics/reporting-errors/WEB_FEATURES.yml new file mode 100644 index 000000000000..73744331853b --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/reporting-errors/WEB_FEATURES.yml @@ -0,0 +1,2 @@ +rules: +- "**": [shared-workers] diff --git a/test/fixtures/wpt/workers/semantics/run-a-worker/001.html b/test/fixtures/wpt/workers/semantics/run-a-worker/001.html new file mode 100644 index 000000000000..71e48c277114 --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/run-a-worker/001.html @@ -0,0 +1,14 @@ + +worker global scope, dedicated worker + + +
+ \ No newline at end of file diff --git a/test/fixtures/wpt/workers/semantics/run-a-worker/001.js b/test/fixtures/wpt/workers/semantics/run-a-worker/001.js new file mode 100644 index 000000000000..33ed47f1b442 --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/run-a-worker/001.js @@ -0,0 +1 @@ +postMessage(this === self); \ No newline at end of file diff --git a/test/fixtures/wpt/workers/semantics/run-a-worker/002.html b/test/fixtures/wpt/workers/semantics/run-a-worker/002.html new file mode 100644 index 000000000000..9487d886a67d --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/run-a-worker/002.html @@ -0,0 +1,14 @@ + +worker global scope, shared worker + + +
+ \ No newline at end of file diff --git a/test/fixtures/wpt/workers/semantics/run-a-worker/002.js b/test/fixtures/wpt/workers/semantics/run-a-worker/002.js new file mode 100644 index 000000000000..627272aaefa3 --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/run-a-worker/002.js @@ -0,0 +1,4 @@ +var passed = this === self; +onconnect = function(e) { + e.ports[0].postMessage(passed); +} \ No newline at end of file diff --git a/test/fixtures/wpt/workers/semantics/run-a-worker/003.html b/test/fixtures/wpt/workers/semantics/run-a-worker/003.html new file mode 100644 index 000000000000..e96c176f20ab --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/run-a-worker/003.html @@ -0,0 +1,15 @@ + +handling for 404 response + + + diff --git a/test/fixtures/wpt/workers/semantics/run-a-worker/WEB_FEATURES.yml b/test/fixtures/wpt/workers/semantics/run-a-worker/WEB_FEATURES.yml new file mode 100644 index 000000000000..fb5bc3756c1e --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/run-a-worker/WEB_FEATURES.yml @@ -0,0 +1,3 @@ +rules: +- 002.html: [shared-workers] +- "*": [dedicated-workers] diff --git a/test/fixtures/wpt/workers/semantics/structured-clone/dedicated.html b/test/fixtures/wpt/workers/semantics/structured-clone/dedicated.html new file mode 100644 index 000000000000..16b6be56f147 --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/structured-clone/dedicated.html @@ -0,0 +1,33 @@ + +structured clone to dedicated worker + + + + + + +
+ diff --git a/test/fixtures/wpt/workers/semantics/structured-clone/shared.html b/test/fixtures/wpt/workers/semantics/structured-clone/shared.html new file mode 100644 index 000000000000..eb85499fe283 --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/structured-clone/shared.html @@ -0,0 +1,37 @@ + +structured clone to shared worker + + + + + + +
+ diff --git a/test/fixtures/wpt/workers/semantics/xhr/001-1.xml b/test/fixtures/wpt/workers/semantics/xhr/001-1.xml new file mode 100644 index 000000000000..5d735bdf6199 --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/xhr/001-1.xml @@ -0,0 +1 @@ +foo \ No newline at end of file diff --git a/test/fixtures/wpt/workers/semantics/xhr/001.html b/test/fixtures/wpt/workers/semantics/xhr/001.html new file mode 100644 index 000000000000..da59f5ac2d16 --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/xhr/001.html @@ -0,0 +1,16 @@ + +async XMLHttpRequest in dedicated worker + + +
+ + \ No newline at end of file diff --git a/test/fixtures/wpt/workers/semantics/xhr/001.js b/test/fixtures/wpt/workers/semantics/xhr/001.js new file mode 100644 index 000000000000..1cbe98ba470b --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/xhr/001.js @@ -0,0 +1,13 @@ +var xhr = new XMLHttpRequest(); +var log = ''; +xhr.onreadystatechange = function(e) { + if (this.readyState == 4) { + if (this.responseXML != null) + log += 'responseXML was not null. '; + if (this.responseText != 'foo') + log += 'responseText was ' + this.responseText + ', expected foo. '; + postMessage(log); + } +} +xhr.open('GET', '001-1.xml', true); +xhr.send(); \ No newline at end of file diff --git a/test/fixtures/wpt/workers/semantics/xhr/002.html b/test/fixtures/wpt/workers/semantics/xhr/002.html new file mode 100644 index 000000000000..60c0e161cc8e --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/xhr/002.html @@ -0,0 +1,16 @@ + +sync XMLHttpRequest in dedicated worker + + +
+ + \ No newline at end of file diff --git a/test/fixtures/wpt/workers/semantics/xhr/002.js b/test/fixtures/wpt/workers/semantics/xhr/002.js new file mode 100644 index 000000000000..68d7e91d451e --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/xhr/002.js @@ -0,0 +1,9 @@ +var xhr = new XMLHttpRequest(); +var log = ''; +xhr.open('GET', '001-1.xml', false); +xhr.send(); +if (xhr.responseXML != null) + log += 'responseXML was not null. '; +if (xhr.responseText != 'foo') + log += 'responseText was ' + this.responseText + ', expected foo. '; +postMessage(log); \ No newline at end of file diff --git a/test/fixtures/wpt/workers/semantics/xhr/003.html b/test/fixtures/wpt/workers/semantics/xhr/003.html new file mode 100644 index 000000000000..e3ce36b82cfc --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/xhr/003.html @@ -0,0 +1,16 @@ + +async XMLHttpRequest in shared worker + + +
+ + diff --git a/test/fixtures/wpt/workers/semantics/xhr/003.js b/test/fixtures/wpt/workers/semantics/xhr/003.js new file mode 100644 index 000000000000..1a9c5a7ee816 --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/xhr/003.js @@ -0,0 +1,17 @@ +onconnect = function(e) { + var xhr = new XMLHttpRequest(); + var log = ''; + var port = e.ports[0]; + var postMessage = port.postMessage; + xhr.onreadystatechange = function(e) { + if (this.readyState == 4) { + if (this.responseXML != null) + log += 'responseXML was not null. '; + if (this.responseText && this.responseText != 'foo') + log += 'responseText was ' + this.responseText + ', expected foo. '; + postMessage.call(port, log); + } + } + xhr.open('GET', '001-1.xml', true); + xhr.send(); +} diff --git a/test/fixtures/wpt/workers/semantics/xhr/004.html b/test/fixtures/wpt/workers/semantics/xhr/004.html new file mode 100644 index 000000000000..d11e3dbc1b92 --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/xhr/004.html @@ -0,0 +1,16 @@ + +sync XMLHttpRequest in shared worker + + +
+ + diff --git a/test/fixtures/wpt/workers/semantics/xhr/004.js b/test/fixtures/wpt/workers/semantics/xhr/004.js new file mode 100644 index 000000000000..1741c8d36a0e --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/xhr/004.js @@ -0,0 +1,11 @@ +onconnect = function(e) { + var xhr = new XMLHttpRequest(); + var log = ''; + xhr.open('GET', '001-1.xml', false); + xhr.send(); + if (xhr.responseXML != null) + log += 'responseXML was not null. '; + if (xhr.responseText != 'foo') + log += 'responseText was ' + xhr.responseText + ', expected foo. '; + e.ports[0].postMessage(log); +} diff --git a/test/fixtures/wpt/workers/semantics/xhr/005.html b/test/fixtures/wpt/workers/semantics/xhr/005.html new file mode 100644 index 000000000000..84abdb0c4264 --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/xhr/005.html @@ -0,0 +1,21 @@ + +base url, dedicated worker + + +
+ + + diff --git a/test/fixtures/wpt/workers/semantics/xhr/006.html b/test/fixtures/wpt/workers/semantics/xhr/006.html new file mode 100644 index 000000000000..7411b4baef3a --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/xhr/006.html @@ -0,0 +1,21 @@ + +base url, shared worker + + +
+ + + diff --git a/test/fixtures/wpt/workers/semantics/xhr/WEB_FEATURES.yml b/test/fixtures/wpt/workers/semantics/xhr/WEB_FEATURES.yml new file mode 100644 index 000000000000..233f18fee3cf --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/xhr/WEB_FEATURES.yml @@ -0,0 +1,7 @@ +rules: +- 003.html: [shared-workers] +- 004.html: [shared-workers] +- 006.html: [shared-workers] +- 001.html: [dedicated-workers] +- 002.html: [dedicated-workers] +- 005.html: [dedicated-workers] diff --git a/test/fixtures/wpt/workers/semantics/xhr/support/001-1.xml b/test/fixtures/wpt/workers/semantics/xhr/support/001-1.xml new file mode 100644 index 000000000000..ecea58a93574 --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/xhr/support/001-1.xml @@ -0,0 +1 @@ +bar \ No newline at end of file diff --git a/test/fixtures/wpt/workers/semantics/xhr/support/005-1.js b/test/fixtures/wpt/workers/semantics/xhr/support/005-1.js new file mode 100644 index 000000000000..45f6519a2104 --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/xhr/support/005-1.js @@ -0,0 +1,5 @@ +var xhr = new XMLHttpRequest(); +xhr.open('GET', '001-1.xml', false); +xhr.send(); +var passed = xhr.responseText == 'bar'; +postMessage(passed); \ No newline at end of file diff --git a/test/fixtures/wpt/workers/semantics/xhr/support/006-1.js b/test/fixtures/wpt/workers/semantics/xhr/support/006-1.js new file mode 100644 index 000000000000..d446781eb7c1 --- /dev/null +++ b/test/fixtures/wpt/workers/semantics/xhr/support/006-1.js @@ -0,0 +1,7 @@ +onconnect = function(e) { + var xhr = new XMLHttpRequest(); + xhr.open('GET', '001-1.xml', false); + xhr.send(); + var passed = xhr.responseText == 'bar'; + e.ports[0].postMessage(passed); +} \ No newline at end of file diff --git a/test/fixtures/wpt/workers/shared-worker-from-blob-url.window.js b/test/fixtures/wpt/workers/shared-worker-from-blob-url.window.js new file mode 100644 index 000000000000..d3c6d4fe47f2 --- /dev/null +++ b/test/fixtures/wpt/workers/shared-worker-from-blob-url.window.js @@ -0,0 +1,73 @@ +function message_from_port(port) { + return new Promise(resolve => { + port.onmessage = e => resolve(e.data); + }); +} + +promise_test(async t => { + const run_result = 'worker_OK_'; + const blob_contents = + 'self.counter = 0; self.onconnect = e => {++self.counter;' + + 'e.source.postMessage("' + run_result + '" + self.counter); };'; + const blob = new Blob([blob_contents]); + const url = URL.createObjectURL(blob); + + const worker1 = new SharedWorker(url); + const reply1 = await message_from_port(worker1.port); + assert_equals(reply1, run_result + '1'); + const worker2 = new SharedWorker(url); + const reply2 = await message_from_port(worker2.port); + assert_equals(reply2, run_result + '2'); +}, 'Creating a shared worker from a blob URL works.'); + +promise_test(async t => { + const run_result = 'worker_OK'; + const blob_contents = + 'self.onconnect = e => { e.source.postMessage("' + run_result + '"); };'; + const blob = new Blob([blob_contents]); + const url = URL.createObjectURL(blob); + + const worker = new SharedWorker(url); + URL.revokeObjectURL(url); + + const reply = await message_from_port(worker.port); + assert_equals(reply, run_result); +}, 'Creating a shared worker from a blob URL works immediately before revoking.'); + +promise_test(async t => { + const run_result = 'worker_OK_'; + const blob_contents = + 'self.counter = 0; self.onconnect = e => {++self.counter;' + + 'e.source.postMessage("' + run_result + '" + self.counter); };'; + const blob = new Blob([blob_contents]); + const url = URL.createObjectURL(blob); + + const worker1 = new SharedWorker(url); + URL.revokeObjectURL(url); + + const reply1 = await message_from_port(worker1.port); + assert_equals(reply1, run_result + '1'); + const worker2 = new SharedWorker(url); + const reply2 = await message_from_port(worker2.port); + assert_equals(reply2, run_result + '2'); +}, 'Connecting to a shared worker on a revoked blob URL works.'); + +promise_test(async t => { + const run_result = false; + const blob_contents = ` +let constructedRequest = false; +try { + new Request("./file.js"); + constructedRequest = true; +} catch (e) {} +self.onconnect = e => { + e.source.postMessage(constructedRequest); +}; +`; + const blob = new Blob([blob_contents]); + const url = URL.createObjectURL(blob); + + const worker = new SharedWorker(url); + const reply = await message_from_port(worker.port); + assert_equals(reply, run_result, "Should not be able to resolve request with relative file path in blob"); +}, 'Blob URLs should not resolve relative to document base URL.'); diff --git a/test/fixtures/wpt/workers/shared-worker-in-data-url-context.window.js b/test/fixtures/wpt/workers/shared-worker-in-data-url-context.window.js new file mode 100644 index 000000000000..b768c815d08d --- /dev/null +++ b/test/fixtures/wpt/workers/shared-worker-in-data-url-context.window.js @@ -0,0 +1,65 @@ +// META: title=data URL shared worker in data URL context +// META: script=/service-workers/service-worker/resources/test-helpers.sub.js +const mimeType = 'application/javascript'; + +// Tests creating a data URL shared worker in a data URL iframe. +promise_test(async t => { + const nestedWorkerScriptURL = + new URL('/workers/support/post-message-on-load-worker.js', location.href); + + // This code will be executed in a data URL iframe. The iframe tries to create + // a shared worker from |nestedWorkerScriptURL|, but that should result in a + // failure. This is because the data URL iframe has an opaque origin, and + // script fetch is handled as a cross-origin request. + const frameCode = ` + + `; + + const p = new Promise(r => window.onmessage = e => r(e.data)); + const frame = await with_iframe(`data:text/html;base64,${btoa(frameCode)}`); + const result = await p; + assert_equals(result, 'PASS'); +}, 'Create a shared worker in a data url frame'); + +// Tests creating a data URL shared worker in a data URL iframe. +promise_test(async t => { + const workerCode = `onconnect = e => e.ports[0].postMessage("PASS");`; + + // This code will be executed in a data URL iframe. The iframe tries to create + // a data URL shared worker. Fetching a data URL from the data URL shared + // worker is allowed, so the worker construction should succeed. The worker + // posts the result to the parent frame. + const frameCode = ` + + `; + + const p = new Promise(r => window.onmessage = e => r(e.data)); + const frame = await with_iframe(`data:text/html;base64,${btoa(frameCode)}`); + const result = await p; + assert_equals(result, 'PASS'); +}, 'Create a data url shared worker in a data url frame'); diff --git a/test/fixtures/wpt/workers/shared-worker-name-via-options.html b/test/fixtures/wpt/workers/shared-worker-name-via-options.html new file mode 100644 index 000000000000..1914d66db748 --- /dev/null +++ b/test/fixtures/wpt/workers/shared-worker-name-via-options.html @@ -0,0 +1,38 @@ + + +Test the name property of shared workers mixing constructor options and constructor strings + + + + + + + + diff --git a/test/fixtures/wpt/workers/shared-worker-options-mismatch.html b/test/fixtures/wpt/workers/shared-worker-options-mismatch.html new file mode 100644 index 000000000000..f4cf6c4192d8 --- /dev/null +++ b/test/fixtures/wpt/workers/shared-worker-options-mismatch.html @@ -0,0 +1,81 @@ + +SharedWorker: type or credentials mismatch failure + + + diff --git a/test/fixtures/wpt/workers/shared-worker-parse-error-failure.html b/test/fixtures/wpt/workers/shared-worker-parse-error-failure.html new file mode 100644 index 000000000000..3f1b4c5d85f4 --- /dev/null +++ b/test/fixtures/wpt/workers/shared-worker-parse-error-failure.html @@ -0,0 +1,26 @@ + +SharedWorker: parse error failure + + + + diff --git a/test/fixtures/wpt/workers/shared-worker-partitioned-cookies.tentative.https.html b/test/fixtures/wpt/workers/shared-worker-partitioned-cookies.tentative.https.html new file mode 100644 index 000000000000..f17a96449796 --- /dev/null +++ b/test/fixtures/wpt/workers/shared-worker-partitioned-cookies.tentative.https.html @@ -0,0 +1,62 @@ + + + + +SharedWorker: Partitioned Cookies + + + + + + + + + + diff --git a/test/fixtures/wpt/workers/shared-worker-partitioned.tentative.html b/test/fixtures/wpt/workers/shared-worker-partitioned.tentative.html new file mode 100644 index 000000000000..0be8479fa9b0 --- /dev/null +++ b/test/fixtures/wpt/workers/shared-worker-partitioned.tentative.html @@ -0,0 +1,30 @@ + + +Test partitioning of shared workers + + + + + + + \ No newline at end of file diff --git a/test/fixtures/wpt/workers/shared-worker-runtime-error-is-not-parse-error.html b/test/fixtures/wpt/workers/shared-worker-runtime-error-is-not-parse-error.html new file mode 100644 index 000000000000..da7872f3f709 --- /dev/null +++ b/test/fixtures/wpt/workers/shared-worker-runtime-error-is-not-parse-error.html @@ -0,0 +1,36 @@ + +SharedWorker: runtime errors are not parse errors + + + diff --git a/test/fixtures/wpt/workers/support/ErrorEvent-error.js b/test/fixtures/wpt/workers/support/ErrorEvent-error.js new file mode 100644 index 000000000000..930b54c0d588 --- /dev/null +++ b/test/fixtures/wpt/workers/support/ErrorEvent-error.js @@ -0,0 +1,9 @@ +onerror = function(message, location, line, col, error) { + postMessage({ source: "onerror", value: error }); +} + +addEventListener("error", function(e) { + postMessage({ source: "event listener", value: e.error }); +}); + +throw "hello"; diff --git a/test/fixtures/wpt/workers/support/ErrorEvent.js b/test/fixtures/wpt/workers/support/ErrorEvent.js new file mode 100644 index 000000000000..22ea6d4fb515 --- /dev/null +++ b/test/fixtures/wpt/workers/support/ErrorEvent.js @@ -0,0 +1,10 @@ +onmessage = function(evt) +{ + throw(new Error(evt.data)); +} + +onerror = function(message, location, line, col) +{ + postMessage( {"message": message, "filename": location, "lineno": line, "colno": col} ); + return false; // "not handled" so the error propagates up to the Worker object +} diff --git a/test/fixtures/wpt/workers/support/ImportScripts.js b/test/fixtures/wpt/workers/support/ImportScripts.js new file mode 100644 index 000000000000..7f2a2bcb552e --- /dev/null +++ b/test/fixtures/wpt/workers/support/ImportScripts.js @@ -0,0 +1,9 @@ +try +{ + importScripts("WorkerBasic.js"); +} +catch(ex) +{ + result = "Fail"; + postMessage(result); +} diff --git a/test/fixtures/wpt/workers/support/ImportScriptsNetworkErr.js b/test/fixtures/wpt/workers/support/ImportScriptsNetworkErr.js new file mode 100644 index 000000000000..8179c8b10013 --- /dev/null +++ b/test/fixtures/wpt/workers/support/ImportScriptsNetworkErr.js @@ -0,0 +1,15 @@ +var result = "Fail"; + +try +{ + importScripts("NonExistentFile.js"); +} +catch(ex) +{ + if (ex.code != null && ex.code == ex.NETWORK_ERR) + { + result = "Pass"; + } +} + +postMessage(result); \ No newline at end of file diff --git a/test/fixtures/wpt/workers/support/ImportScriptsNosniffErr.js b/test/fixtures/wpt/workers/support/ImportScriptsNosniffErr.js new file mode 100644 index 000000000000..22dc9c1ba57c --- /dev/null +++ b/test/fixtures/wpt/workers/support/ImportScriptsNosniffErr.js @@ -0,0 +1,9 @@ +importScripts('/resources/testharness.js'); + +test(t => { + assert_throws_dom('NetworkError', () => { + importScripts("nosiniff-error-worker.py"); + }); +}, "importScripts throws on 'nosniff' violation"); + +done(); diff --git a/test/fixtures/wpt/workers/support/SharedWorker-common.js b/test/fixtures/wpt/workers/support/SharedWorker-common.js new file mode 100644 index 000000000000..1c1dac39714b --- /dev/null +++ b/test/fixtures/wpt/workers/support/SharedWorker-common.js @@ -0,0 +1,32 @@ +function generateError() +{ + // Generate an exception by accessing an undefined variable. + foo.bar = 0; +} + +onconnect = function(event) { + event.ports[0].onmessage = function(evt) { handleMessage(evt, event.ports[0]); }; +}; + +function handleMessage(event, port) { + self.port = port; + if (event.data == "ping") + port.postMessage("PASS: Received ping message"); + else if (event.data == "close") + close(); + else if (event.data == "done") + port.postMessage("DONE"); + else if (event.data == "throw") + generateError(); + else if (event.data == "testingNameAttribute") + port.postMessage(self.name); + else if (/eval.+/.test(event.data)) { + try { + port.postMessage(event.data.substr(5) + ": " + eval(event.data.substr(5))); + } catch (ex) { + port.postMessage(event.data.substr(5) + ": " + ex); + } + } + else + port.postMessage("FAILURE: Received unknown message: " + event.data); +} diff --git a/test/fixtures/wpt/workers/support/SharedWorker-create-common.js b/test/fixtures/wpt/workers/support/SharedWorker-create-common.js new file mode 100644 index 000000000000..1d06174f12d8 --- /dev/null +++ b/test/fixtures/wpt/workers/support/SharedWorker-create-common.js @@ -0,0 +1,8 @@ +// Make a SharedWorker that has the same external interface as a DedicatedWorker, to use in shared test code. +function createWorker() +{ + var worker = new SharedWorker('support/SharedWorker-common.js', 'name'); + worker.port.onmessage = function(evt) { worker.onmessage(evt); }; + worker.postMessage = function(msg, port) { worker.port.postMessage(msg, port); }; + return worker; +} diff --git a/test/fixtures/wpt/workers/support/SharedWorker-script-error.js b/test/fixtures/wpt/workers/support/SharedWorker-script-error.js new file mode 100644 index 000000000000..0e78949d97bd --- /dev/null +++ b/test/fixtures/wpt/workers/support/SharedWorker-script-error.js @@ -0,0 +1,22 @@ +onconnect = function(event) { + event.ports[0].onmessage = function(evt) { handleMessage(evt, event.ports[0]); }; +}; + +function handleMessage(event, port) { + if (event.data == "unhandledError") { + // Generate an unhandled error. + onerror = null; + setTimeout(function() { + port.postMessage("SUCCESS: unhandled error generated"); + }, 100); + generateError(); // Undefined function call + } else if (event.data == "handledError") { + onerror = function() { + port.postMessage("SUCCESS: error handled via onerror"); + return true; + }; + generateError(); // Undefined function call + } else { + port.postMessage("FAIL: Got unexpected message: " + event.data); + } +}; diff --git a/test/fixtures/wpt/workers/support/Timer.js b/test/fixtures/wpt/workers/support/Timer.js new file mode 100644 index 000000000000..a86a224dbb41 --- /dev/null +++ b/test/fixtures/wpt/workers/support/Timer.js @@ -0,0 +1,50 @@ +var count = 0; +var id; + +onmessage = function(evt) +{ + try + { + switch(evt.data) + { + case "TimeoutHandler": + count = 0; + id = setTimeout("TimeoutHandler()", 10); + postMessage('hello'); + break; + case "IntervalHandler": + count = 0; + id = setInterval("IntervalHandler()", 10); + postMessage('hello'); + break; + } + } + catch(ex) + { + postMessage("Fail"); + } +} + +function TimeoutHandler() +{ + count++; + postMessage("worker"); + + id = setTimeout("TimeoutHandler()", 10); + + if (count >= 2) + { + clearTimeout(id); + } +} + +function IntervalHandler() +{ + count++; + postMessage("worker"); + + if (count >= 2) + { + clearInterval(id); + } +} diff --git a/test/fixtures/wpt/workers/support/Worker-common.js b/test/fixtures/wpt/workers/support/Worker-common.js new file mode 100644 index 000000000000..55188fe913c5 --- /dev/null +++ b/test/fixtures/wpt/workers/support/Worker-common.js @@ -0,0 +1,16 @@ +onmessage = function(evt) +{ + if (evt.data == "ping") + postMessage("pong"); + else if (evt.data == "freeze") + while (1) {} + else if (evt.data == "close") + close(); + else if (/eval.+/.test(evt.data)) { + try { + postMessage(evt.data.substr(5) + ": " + eval(evt.data.substr(5))); + } catch (ex) { + postMessage(evt.data.substr(5) + ": " + ex); + } + } +} diff --git a/test/fixtures/wpt/workers/support/Worker-create-common.js b/test/fixtures/wpt/workers/support/Worker-create-common.js new file mode 100644 index 000000000000..f0b8efe46bd8 --- /dev/null +++ b/test/fixtures/wpt/workers/support/Worker-create-common.js @@ -0,0 +1,4 @@ +function createWorker() +{ + return new Worker('support/Worker-common.js'); +} diff --git a/test/fixtures/wpt/workers/support/Worker-creation-happens-in-parallel.js b/test/fixtures/wpt/workers/support/Worker-creation-happens-in-parallel.js new file mode 100644 index 000000000000..1e68302a0fc4 --- /dev/null +++ b/test/fixtures/wpt/workers/support/Worker-creation-happens-in-parallel.js @@ -0,0 +1,3 @@ +onmessage = (e) => { + e.data[0] = 1; +} diff --git a/test/fixtures/wpt/workers/support/Worker-creation-happens-in-parallel.js.headers b/test/fixtures/wpt/workers/support/Worker-creation-happens-in-parallel.js.headers new file mode 100644 index 000000000000..8249c49c340f --- /dev/null +++ b/test/fixtures/wpt/workers/support/Worker-creation-happens-in-parallel.js.headers @@ -0,0 +1 @@ +Cross-Origin-Embedder-Policy:require-corp diff --git a/test/fixtures/wpt/workers/support/Worker-messageport.js b/test/fixtures/wpt/workers/support/Worker-messageport.js new file mode 100644 index 000000000000..1e01b0a52b58 --- /dev/null +++ b/test/fixtures/wpt/workers/support/Worker-messageport.js @@ -0,0 +1,40 @@ +onmessage = function(evt) { + if (evt.data == "port") { + if (evt.ports) { + postMessage("PASS: Received message port"); + evt.ports[0].onmessage = pingBack; + evt.ports[0].start(); + } else { + postMessage("FAIL: Did not receive expected MessagePort"); + } + } else if (evt.data == "noport") { + if (!evt.ports || evt.ports.length) { + postMessage("FAIL: Received message port or null ports array"); + } else { + postMessage("PASS: evt.ports = [] as expected"); + } + } else if (evt.data == "spam") { + for (var i = 0 ; i < 1000 ; i++) { + evt.ports[0].postMessage(i); + } + postMessage("spamDone"); + } else if (evt.data == "getport") { + var channel = new MessageChannel(); + postMessage("port", [channel.port1]); + channel.port2.onmessage = pingBack; + channel.port2.start(); + } else { + postMessage("Unknown message:" + evt.data); + } + +} + +function pingBack(evt) { + // Make sure we got the expected data and send a return message over + // the port. + if (evt.data == "ping") { + evt.target.postMessage("pong"); + } else { + postMessage("FAIL: unknown message: " + evt.data); + } +} diff --git a/test/fixtures/wpt/workers/support/Worker-postMessage-happens-in-parallel.js b/test/fixtures/wpt/workers/support/Worker-postMessage-happens-in-parallel.js new file mode 100644 index 000000000000..48b4c34fe3a6 --- /dev/null +++ b/test/fixtures/wpt/workers/support/Worker-postMessage-happens-in-parallel.js @@ -0,0 +1,7 @@ +onmessage = (e) => { + if (e.data == 'init') { + postMessage(0); + } else { + e.data[0] = 1; + } +} diff --git a/test/fixtures/wpt/workers/support/Worker-postMessage-happens-in-parallel.js.headers b/test/fixtures/wpt/workers/support/Worker-postMessage-happens-in-parallel.js.headers new file mode 100644 index 000000000000..8249c49c340f --- /dev/null +++ b/test/fixtures/wpt/workers/support/Worker-postMessage-happens-in-parallel.js.headers @@ -0,0 +1 @@ +Cross-Origin-Embedder-Policy:require-corp diff --git a/test/fixtures/wpt/workers/support/Worker-run-forever-during-dynamic-import.js b/test/fixtures/wpt/workers/support/Worker-run-forever-during-dynamic-import.js new file mode 100644 index 000000000000..62840bd5b4ff --- /dev/null +++ b/test/fixtures/wpt/workers/support/Worker-run-forever-during-dynamic-import.js @@ -0,0 +1,3 @@ +import('./Worker-run-forever.js') + .then(r => postMessage('resolved: ' + r)) + .catch(e => postMessage('rejected: ' + e)); diff --git a/test/fixtures/wpt/workers/support/Worker-run-forever-during-importScripts.js b/test/fixtures/wpt/workers/support/Worker-run-forever-during-importScripts.js new file mode 100644 index 000000000000..6a3083f38215 --- /dev/null +++ b/test/fixtures/wpt/workers/support/Worker-run-forever-during-importScripts.js @@ -0,0 +1,4 @@ +importScripts('Worker-run-forever.js'); + +// This is not expected to run. +postMessage('after importScripts()'); diff --git a/test/fixtures/wpt/workers/support/Worker-run-forever-during-nested-importScripts.js b/test/fixtures/wpt/workers/support/Worker-run-forever-during-nested-importScripts.js new file mode 100644 index 000000000000..aae86a0b0553 --- /dev/null +++ b/test/fixtures/wpt/workers/support/Worker-run-forever-during-nested-importScripts.js @@ -0,0 +1 @@ +importScripts('Worker-run-forever-during-importScripts.js'); diff --git a/test/fixtures/wpt/workers/support/Worker-run-forever-during-top-level-await.js b/test/fixtures/wpt/workers/support/Worker-run-forever-during-top-level-await.js new file mode 100644 index 000000000000..a1c8b32b6197 --- /dev/null +++ b/test/fixtures/wpt/workers/support/Worker-run-forever-during-top-level-await.js @@ -0,0 +1,4 @@ +await 1; +postMessage('start'); +onerror = () => postMessage('onerror'); +while(1); diff --git a/test/fixtures/wpt/workers/support/Worker-run-forever.js b/test/fixtures/wpt/workers/support/Worker-run-forever.js new file mode 100644 index 000000000000..2d822d407f4c --- /dev/null +++ b/test/fixtures/wpt/workers/support/Worker-run-forever.js @@ -0,0 +1,3 @@ +postMessage('start'); +onerror = () => postMessage('onerror'); +while(1); diff --git a/test/fixtures/wpt/workers/support/Worker-structure-message.js b/test/fixtures/wpt/workers/support/Worker-structure-message.js new file mode 100644 index 000000000000..81cd98243b4d --- /dev/null +++ b/test/fixtures/wpt/workers/support/Worker-structure-message.js @@ -0,0 +1,15 @@ +self.onmessage = function(evt) { + if (evt.data.operation == 'find-edges' && + ArrayBuffer.prototype.isPrototypeOf(evt.data.input) && + evt.data.input.byteLength == 20 && + evt.data.threshold == 0.6) { + self.postMessage("PASS: Worker receives correct structure message."); + self.postMessage({ + operation: evt.data.operation, + input: evt.data.input, + threshold: evt.data.threshold + }); + } + else + self.postMessage("FAIL: Worker receives error structure message."); +} diff --git a/test/fixtures/wpt/workers/support/Worker-termination-with-port-messages.js b/test/fixtures/wpt/workers/support/Worker-termination-with-port-messages.js new file mode 100644 index 000000000000..a827db357e23 --- /dev/null +++ b/test/fixtures/wpt/workers/support/Worker-termination-with-port-messages.js @@ -0,0 +1,10 @@ +function echo(evt) +{ + evt.target.postMessage(evt.data); +} + +onmessage = function(evt) +{ + evt.ports[0].onmessage = echo; + evt.ports[0].start(); +} diff --git a/test/fixtures/wpt/workers/support/Worker-thread-multi-port.js b/test/fixtures/wpt/workers/support/Worker-thread-multi-port.js new file mode 100644 index 000000000000..2ce7cae596b5 --- /dev/null +++ b/test/fixtures/wpt/workers/support/Worker-thread-multi-port.js @@ -0,0 +1,43 @@ +onmessage = function(event) { + if (event.data == "noport") { + if (event.ports && !event.ports.length) + testPassed("event.ports is non-null and zero length when no port sent"); + else + testFailed("event.ports is null or non-zero length when no port sent"); + } else if (event.data == "zero ports") { + if (event.ports && !event.ports.length) + testPassed("event.ports is non-null and zero length when empty array sent"); + else + testFailed("event.ports is null or non-zero length when empty array sent"); + } else if (event.data == "two ports") { + if (!event.ports) { + testFailed("event.ports should be non-null when ports sent"); + return; + } + if (event.ports.length == 2) + testPassed("event.ports contains two ports when two ports sent"); + else + testFailed("event.ports contained " + event.ports.length + " when two ports sent"); + } else if (event.data == "failed ports") { + if (event.ports.length == 2) + testPassed("event.ports contains two ports when two ports re-sent after error"); + else + testFailed("event.ports contained " + event.ports.length + " when two ports re-sent after error"); + } else if (event.data == "noargs") { + try { + postMessage(); + testFailed("postMessage() did not throw"); + } catch (e) { + testPassed("postMessage() threw exception: " + e); + } + } else + testFailed("Received unexpected message: " + event.data); +}; + +function testPassed(msg) { + postMessage("PASS"+msg); +} + +function testFailed(msg) { + postMessage("FAIL"+msg); +} diff --git a/test/fixtures/wpt/workers/support/Worker-timeout-cancel-order.js b/test/fixtures/wpt/workers/support/Worker-timeout-cancel-order.js new file mode 100644 index 000000000000..afc66cf6a0b4 --- /dev/null +++ b/test/fixtures/wpt/workers/support/Worker-timeout-cancel-order.js @@ -0,0 +1,7 @@ +// The test will create 2 timeouts and cancel the first one. If only the second +// timeout executes then the test passes. +self.addEventListener('message', function(e) { + var t1 = setTimeout(function () { postMessage(1); }, 5); + setTimeout(function () { postMessage(2); }, 10); + clearTimeout(t1); +}, false); diff --git a/test/fixtures/wpt/workers/support/Worker-timeout-decreasing-order.js b/test/fixtures/wpt/workers/support/Worker-timeout-decreasing-order.js new file mode 100644 index 000000000000..b93dd5dc771a --- /dev/null +++ b/test/fixtures/wpt/workers/support/Worker-timeout-decreasing-order.js @@ -0,0 +1,7 @@ +// The test will create 3 timeouts with their intervals decreasing. +// If the timeouts execute in order then the test is PASS. +self.addEventListener('message', function(e) { + setTimeout(function () { postMessage(3); }, 15); + setTimeout(function () { postMessage(2); }, 10); + setTimeout(function () { postMessage(1); }, 5); +}, false); diff --git a/test/fixtures/wpt/workers/support/Worker-timeout-increasing-order.js b/test/fixtures/wpt/workers/support/Worker-timeout-increasing-order.js new file mode 100644 index 000000000000..42f81daa29c0 --- /dev/null +++ b/test/fixtures/wpt/workers/support/Worker-timeout-increasing-order.js @@ -0,0 +1,7 @@ +// The test will create 3 timeouts with their intervals increasing. +// If the timeouts execute in order then the test is PASS. +self.addEventListener('message', function(e) { + setTimeout(function () { postMessage(1); }, 5); + setTimeout(function () { postMessage(2); }, 10); + setTimeout(function () { postMessage(3); }, 15); +}, false); diff --git a/test/fixtures/wpt/workers/support/WorkerBasic.js b/test/fixtures/wpt/workers/support/WorkerBasic.js new file mode 100644 index 000000000000..6bb6d32b1419 --- /dev/null +++ b/test/fixtures/wpt/workers/support/WorkerBasic.js @@ -0,0 +1,7 @@ +var result = "Fail"; + +onmessage = function(evt) +{ + result = "Pass"; + postMessage(result); +} \ No newline at end of file diff --git a/test/fixtures/wpt/workers/support/WorkerClose.js b/test/fixtures/wpt/workers/support/WorkerClose.js new file mode 100644 index 000000000000..81f99993d81e --- /dev/null +++ b/test/fixtures/wpt/workers/support/WorkerClose.js @@ -0,0 +1,5 @@ +onmessage = function(evt) +{ + postMessage(evt.data); + self.close(); +} \ No newline at end of file diff --git a/test/fixtures/wpt/workers/support/WorkerDataCloneErr.js b/test/fixtures/wpt/workers/support/WorkerDataCloneErr.js new file mode 100644 index 000000000000..b7e8b0ae1676 --- /dev/null +++ b/test/fixtures/wpt/workers/support/WorkerDataCloneErr.js @@ -0,0 +1,15 @@ +var result = "Fail"; + +try +{ + postMessage(navigator); +} +catch(ex) +{ + if(ex.code != null && ex.code == ex.DATA_CLONE_ERR) + { + result = "Pass"; + } +} + +postMessage(result); \ No newline at end of file diff --git a/test/fixtures/wpt/workers/support/WorkerFetchURL.js b/test/fixtures/wpt/workers/support/WorkerFetchURL.js new file mode 100644 index 000000000000..4ad700bcce46 --- /dev/null +++ b/test/fixtures/wpt/workers/support/WorkerFetchURL.js @@ -0,0 +1,8 @@ +onconnect = e => { + let port = e.ports[0]; + port.onmessage = (e) => { + fetch(e.data) + .then(response => response.text()) + .then(text => port.postMessage('Worker reply:' + text)); + }; +} diff --git a/test/fixtures/wpt/workers/support/WorkerGlobalScope-close.js b/test/fixtures/wpt/workers/support/WorkerGlobalScope-close.js new file mode 100644 index 000000000000..e2b1c0a2fddf --- /dev/null +++ b/test/fixtures/wpt/workers/support/WorkerGlobalScope-close.js @@ -0,0 +1,43 @@ +// Check to see if the worker handles pending events. Messages after close() will not be sent to the parent page, so we use exceptions instead to report failures after close(). +onmessage = function(evt) +{ + if (evt.data == "closeWithPendingEvents") { + // Set a timer to generate an event - minimum timeout is 1ms. + setTimeout(function() { + postMessage("pending event processed"); + throw "should not be executed"; + }, 1); + var start = new Date().getTime(); + // Loop for 10 ms so the timer is ready to fire + while (new Date().getTime() - start < 100) + ; + // Now close - timer should not fire + close(); + } else if (evt.data == "typeofClose") { + postMessage("typeof close: " + (typeof close)); + } else if (evt.data == "close") { + close(); + postMessage("Should be delivered"); + } else if (evt.data == "ping") { + postMessage("pong"); + } else if (evt.data == "throw") { + throw "should never be executed"; + } else if (evt.data == "closeWithError") { + close(); + nonExistentFunction(); // Undefined function - throws exception + } else if (evt.data == "close_post_loop") { + close(); + postMessage("closed"); + while(true) {} // Should loop forever. + } else if (evt.data == "take_port") { + messagePort = evt.ports[0]; + messagePort.onmessage = function(event) { + close(); + postMessage("echo_" + event.data); + } + } else if (evt.data == "start_port") { + messagePort.start(); + } else { + postMessage("FAIL: Unknown message type: " + evt.data); + } +} diff --git a/test/fixtures/wpt/workers/support/WorkerLocation-origin.html b/test/fixtures/wpt/workers/support/WorkerLocation-origin.html new file mode 100644 index 000000000000..3d948030a79e --- /dev/null +++ b/test/fixtures/wpt/workers/support/WorkerLocation-origin.html @@ -0,0 +1,6 @@ + diff --git a/test/fixtures/wpt/workers/support/WorkerLocation.js b/test/fixtures/wpt/workers/support/WorkerLocation.js new file mode 100644 index 000000000000..901e21542a05 --- /dev/null +++ b/test/fixtures/wpt/workers/support/WorkerLocation.js @@ -0,0 +1,13 @@ +var obj = new Object(); +obj.location = location.toString(); +obj.href = location.href; +obj.origin = location.origin; +obj.protocol = location.protocol; +obj.host = location.host; +obj.hostname = location.hostname; +obj.port = location.port; +obj.pathname = location.pathname; +obj.search = location.search; +obj.hash = location.hash; + +postMessage(obj); diff --git a/test/fixtures/wpt/workers/support/WorkerNavigator.js b/test/fixtures/wpt/workers/support/WorkerNavigator.js new file mode 100644 index 000000000000..4258384ac444 --- /dev/null +++ b/test/fixtures/wpt/workers/support/WorkerNavigator.js @@ -0,0 +1,27 @@ +(async () => { + const obj = new Object(); + obj.appName = navigator.appName; + obj.appVersion = navigator.appVersion; + obj.platform = navigator.platform; + obj.userAgent = navigator.userAgent; + obj.onLine = navigator.onLine; + if (navigator.userAgentData) { + obj.brands = navigator.userAgentData.brands; + obj.mobile = navigator.userAgentData.mobile; + obj.platform = navigator.userAgentData.platform; + const highEntropyValues = await navigator.userAgentData.getHighEntropyValues([ + "architecture", "bitness", "fullVersionList", "model", + "platformVersion", "uaFullVersion", "wow64", "formFactors", + ]); + obj.architecture = highEntropyValues.architecture; + obj.bitness = highEntropyValues.bitness; + obj.fullVersionList = highEntropyValues.fullVersionList; + obj.model = highEntropyValues.model; + obj.platformVersion = highEntropyValues.platformVersion; + obj.uaFullVersion = highEntropyValues.uaFullVersion; + obj.wow64 = highEntropyValues.wow64; + obj.formFactors = highEntropyValues.formFactors; + obj.NavigatorUADataExposed = (typeof self.NavigatorUAData != "undefined"); + } + postMessage(obj); +})(); diff --git a/test/fixtures/wpt/workers/support/WorkerSendingPerformanceNow.js b/test/fixtures/wpt/workers/support/WorkerSendingPerformanceNow.js new file mode 100644 index 000000000000..ac12190efe3a --- /dev/null +++ b/test/fixtures/wpt/workers/support/WorkerSendingPerformanceNow.js @@ -0,0 +1,22 @@ +function calcResponse() { + const response = [ + typeof(workerStart), + typeof(performance), + typeof(performance.now), + performance.now() + ]; + return response; +} + +self.onmessage = function(event) { + postMessage(calcResponse()); + self.close(); +} + +self.addEventListener("connect", function(event) { + const port = event.ports[0]; + port.onmessage = function(event) { + port.postMessage(calcResponse()); + port.close(); + }; +}); diff --git a/test/fixtures/wpt/workers/support/WorkerTerminate.js b/test/fixtures/wpt/workers/support/WorkerTerminate.js new file mode 100644 index 000000000000..7c99e7ec5605 --- /dev/null +++ b/test/fixtures/wpt/workers/support/WorkerTerminate.js @@ -0,0 +1,10 @@ +onmessage = function(evt) +{ + for (var i=0; true; i++) + { + if (i%1000 == 0) + { + postMessage(i); + } + } +} diff --git a/test/fixtures/wpt/workers/support/WorkerText.txt b/test/fixtures/wpt/workers/support/WorkerText.txt new file mode 100644 index 000000000000..e4eeb5391da6 --- /dev/null +++ b/test/fixtures/wpt/workers/support/WorkerText.txt @@ -0,0 +1,2 @@ +var result = "Pass"; +postMessage(result); diff --git a/test/fixtures/wpt/workers/support/abrupt-completion.js b/test/fixtures/wpt/workers/support/abrupt-completion.js new file mode 100644 index 000000000000..f0884cc1d26a --- /dev/null +++ b/test/fixtures/wpt/workers/support/abrupt-completion.js @@ -0,0 +1,21 @@ +const isSharedWorker = + "SharedWorkerGlobalScope" in self && self instanceof SharedWorkerGlobalScope; + +function setMessageHandler(response) { + onmessage = e => { + e.ports[0].postMessage(response); + }; + + if (isSharedWorker) { + onconnect = e => { + e.ports[0].onmessage = onmessage; + }; + } +} + +setMessageHandler("handler-before-throw"); + +throw new Error("uncaught-exception"); + +// This should never be called because of the uncaught exception above. +setMessageHandler("handler-after-throw"); diff --git a/test/fixtures/wpt/workers/support/check-error-arguments.js b/test/fixtures/wpt/workers/support/check-error-arguments.js new file mode 100644 index 000000000000..64441f9225ec --- /dev/null +++ b/test/fixtures/wpt/workers/support/check-error-arguments.js @@ -0,0 +1,4 @@ +window.checkErrorArguments = args => { + assert_equals(args.length, 1); + assert_equals(args[0].constructor, Event); +}; diff --git a/test/fixtures/wpt/workers/support/empty-worker.js b/test/fixtures/wpt/workers/support/empty-worker.js new file mode 100644 index 000000000000..49ceb2648a93 --- /dev/null +++ b/test/fixtures/wpt/workers/support/empty-worker.js @@ -0,0 +1 @@ +// Do nothing. diff --git a/test/fixtures/wpt/workers/support/eval-syntax-error.js b/test/fixtures/wpt/workers/support/eval-syntax-error.js new file mode 100644 index 000000000000..0c1610aa4037 --- /dev/null +++ b/test/fixtures/wpt/workers/support/eval-syntax-error.js @@ -0,0 +1 @@ +eval('1 + ;'); diff --git a/test/fixtures/wpt/workers/support/iframe-sw-shared-name.html b/test/fixtures/wpt/workers/support/iframe-sw-shared-name.html new file mode 100644 index 000000000000..c1c7a536e13e --- /dev/null +++ b/test/fixtures/wpt/workers/support/iframe-sw-shared-name.html @@ -0,0 +1,19 @@ + +Iframe for cross-origin Shared Worker + + + + + + diff --git a/test/fixtures/wpt/workers/support/iframe_sw_dataUrl.html b/test/fixtures/wpt/workers/support/iframe_sw_dataUrl.html new file mode 100644 index 000000000000..0fb0ec228079 --- /dev/null +++ b/test/fixtures/wpt/workers/support/iframe_sw_dataUrl.html @@ -0,0 +1,13 @@ + +Iframe for Shared Worker: Data URL cross-origin checks + + + + diff --git a/test/fixtures/wpt/workers/support/importScripts-1.js b/test/fixtures/wpt/workers/support/importScripts-1.js new file mode 100644 index 000000000000..8869a4fbcafc --- /dev/null +++ b/test/fixtures/wpt/workers/support/importScripts-1.js @@ -0,0 +1 @@ +importScripts("importScripts-2.js"); diff --git a/test/fixtures/wpt/workers/support/importScripts-2.js b/test/fixtures/wpt/workers/support/importScripts-2.js new file mode 100644 index 000000000000..7f3f1116e76c --- /dev/null +++ b/test/fixtures/wpt/workers/support/importScripts-2.js @@ -0,0 +1 @@ +importScripts("importScripts-3.js"); diff --git a/test/fixtures/wpt/workers/support/importScripts-3.js b/test/fixtures/wpt/workers/support/importScripts-3.js new file mode 100644 index 000000000000..2d103a0411fe --- /dev/null +++ b/test/fixtures/wpt/workers/support/importScripts-3.js @@ -0,0 +1 @@ +importScripts("invalidScript.js"); diff --git a/test/fixtures/wpt/workers/support/invalidScript.js b/test/fixtures/wpt/workers/support/invalidScript.js new file mode 100644 index 000000000000..8655d4d1f18c --- /dev/null +++ b/test/fixtures/wpt/workers/support/invalidScript.js @@ -0,0 +1 @@ +SELECT * FROM TABLE; // an invalid script. diff --git a/test/fixtures/wpt/workers/support/json-parse-error.js b/test/fixtures/wpt/workers/support/json-parse-error.js new file mode 100644 index 000000000000..ac0c175e21b3 --- /dev/null +++ b/test/fixtures/wpt/workers/support/json-parse-error.js @@ -0,0 +1 @@ +JSON.parse('!'); diff --git a/test/fixtures/wpt/workers/support/name-as-accidental-global.js b/test/fixtures/wpt/workers/support/name-as-accidental-global.js new file mode 100644 index 000000000000..f2c39ea715aa --- /dev/null +++ b/test/fixtures/wpt/workers/support/name-as-accidental-global.js @@ -0,0 +1,9 @@ +"use strict"; +importScripts("/resources/testharness.js"); + +var name = "something else"; + +// This just makes the test name not "Untitled" +test(() => { }, `Declaring name as an accidental global must not cause a harness error for ${self.constructor.name}`); + +done(); diff --git a/test/fixtures/wpt/workers/support/name.js b/test/fixtures/wpt/workers/support/name.js new file mode 100644 index 000000000000..970578e425a3 --- /dev/null +++ b/test/fixtures/wpt/workers/support/name.js @@ -0,0 +1,18 @@ +"use strict"; +importScripts("/resources/testharness.js"); + +test(() => { + assert_true(self.hasOwnProperty("name"), "property exists on the global"); + assert_equals(self.name, "my name"); +}, `name property value for ${self.constructor.name}`); + +test(() => { + self.name = "something new"; + const propDesc = Object.getOwnPropertyDescriptor(self, "name"); + assert_equals(propDesc.value, "something new", "value"); + assert_true(propDesc.configurable, "configurable"); + assert_true(propDesc.writable, "writable"); + assert_true(propDesc.enumerable, "enumerable"); +}, `name property is replaceable for ${self.constructor.name}`); + +done(); diff --git a/test/fixtures/wpt/workers/support/parent_of_nested_worker.js b/test/fixtures/wpt/workers/support/parent_of_nested_worker.js new file mode 100644 index 000000000000..1f14334290a3 --- /dev/null +++ b/test/fixtures/wpt/workers/support/parent_of_nested_worker.js @@ -0,0 +1,14 @@ +try { + var worker = new Worker("WorkerBasic.js"); + worker.onmessage = function(e) { + if (e.data == "Pass") { + postMessage("Pass"); + } else if (e.data == "close") { + close(); + postMessage("Pass"); + } + }; + worker.postMessage("start"); +} catch (e) { + postMessage("Fail: " + e); +} diff --git a/test/fixtures/wpt/workers/support/post-message-on-load-worker.js b/test/fixtures/wpt/workers/support/post-message-on-load-worker.js new file mode 100644 index 000000000000..e1c547ab6a4d --- /dev/null +++ b/test/fixtures/wpt/workers/support/post-message-on-load-worker.js @@ -0,0 +1,10 @@ +if ('DedicatedWorkerGlobalScope' in self && + self instanceof DedicatedWorkerGlobalScope) { + postMessage('LOADED'); +} else if ( + 'SharedWorkerGlobalScope' in self && + self instanceof SharedWorkerGlobalScope) { + self.onconnect = e => { + e.ports[0].postMessage('LOADED'); + }; +} diff --git a/test/fixtures/wpt/workers/support/postMessage_block_worker.js b/test/fixtures/wpt/workers/support/postMessage_block_worker.js new file mode 100644 index 000000000000..0c7bcacccaf8 --- /dev/null +++ b/test/fixtures/wpt/workers/support/postMessage_block_worker.js @@ -0,0 +1,2 @@ +onmessage = e => Atomics.store(e.data, 0, 1); +postMessage('ready'); diff --git a/test/fixtures/wpt/workers/support/postMessage_block_worker.js.headers b/test/fixtures/wpt/workers/support/postMessage_block_worker.js.headers new file mode 100644 index 000000000000..6604450991a1 --- /dev/null +++ b/test/fixtures/wpt/workers/support/postMessage_block_worker.js.headers @@ -0,0 +1 @@ +Cross-Origin-Embedder-Policy: require-corp diff --git a/test/fixtures/wpt/workers/support/sandboxed-tests.html b/test/fixtures/wpt/workers/support/sandboxed-tests.html new file mode 100644 index 000000000000..811c925f56f1 --- /dev/null +++ b/test/fixtures/wpt/workers/support/sandboxed-tests.html @@ -0,0 +1,67 @@ + + + + + diff --git a/test/fixtures/wpt/workers/support/shared-name.js b/test/fixtures/wpt/workers/support/shared-name.js new file mode 100644 index 000000000000..f00448271922 --- /dev/null +++ b/test/fixtures/wpt/workers/support/shared-name.js @@ -0,0 +1,8 @@ +"use strict"; + +self.counter = 0; + +self.onconnect = e => { + ++self.counter; + e.source.postMessage({ counter: self.counter, name: self.name }); +}; diff --git a/test/fixtures/wpt/workers/support/shared-worker-echo-cookies.js b/test/fixtures/wpt/workers/support/shared-worker-echo-cookies.js new file mode 100644 index 000000000000..34dcbc9d260b --- /dev/null +++ b/test/fixtures/wpt/workers/support/shared-worker-echo-cookies.js @@ -0,0 +1,40 @@ +let port; + +self.onconnect = e => { + port = e.ports[0]; + port.addEventListener('message', onMessage); + port.start(); +}; + +async function onMessage(e) { + switch (e.data.type) { + case 'test_message': + port.postMessage({ok: true}); + return; + case 'echo_cookies_http': + return onEchoCookiesHttp(e); + case 'echo_cookies_import': + return onEchoCookiesImport(); + default: + throw new Error('Unexpected message type ' + e.data.type); + } +} + +async function onEchoCookiesHttp(e) { + try { + const resp = await fetch( + `${self.origin}/cookies/resources/list.py`, {credentials: 'include'}); + const cookies = await resp.json(); + port.postMessage({ok: true, cookies: Object.keys(cookies)}); + } catch (err) { + port.postMessage({ok: false}); + } +} + +// Sets `self._cookies` variable, array of the names of cookies available to +// the request. +importScripts(`${self.origin}/cookies/resources/list-cookies-for-script.py`); + +function onEchoCookiesImport() { + port.postMessage({ok: true, cookies: self._cookies}); +} diff --git a/test/fixtures/wpt/workers/support/shared-worker-eval-syntax-error.js b/test/fixtures/wpt/workers/support/shared-worker-eval-syntax-error.js new file mode 100644 index 000000000000..9911bf3cd526 --- /dev/null +++ b/test/fixtures/wpt/workers/support/shared-worker-eval-syntax-error.js @@ -0,0 +1,9 @@ +let errorFired = false; +onerror = () => { + errorFired = true; + return false; +}; +onconnect = e => { + e.ports[0].postMessage(errorFired ? "onerror-fired" : "no-error"); +}; +eval('1 + ;'); diff --git a/test/fixtures/wpt/workers/support/shared-worker-json-parse-error.js b/test/fixtures/wpt/workers/support/shared-worker-json-parse-error.js new file mode 100644 index 000000000000..f4bfd43e1891 --- /dev/null +++ b/test/fixtures/wpt/workers/support/shared-worker-json-parse-error.js @@ -0,0 +1,9 @@ +let errorFired = false; +onerror = () => { + errorFired = true; + return false; +}; +onconnect = e => { + e.ports[0].postMessage(errorFired ? "onerror-fired" : "no-error"); +}; +JSON.parse('!'); diff --git a/test/fixtures/wpt/workers/support/shared-worker-partitioned-cookies-3p-frame.html b/test/fixtures/wpt/workers/support/shared-worker-partitioned-cookies-3p-frame.html new file mode 100644 index 000000000000..45c01c8937a1 --- /dev/null +++ b/test/fixtures/wpt/workers/support/shared-worker-partitioned-cookies-3p-frame.html @@ -0,0 +1,43 @@ + + + + +Service Worker: Partitioned Cookies 3P Iframe + + + + + + + diff --git a/test/fixtures/wpt/workers/support/shared-worker-partitioned-cookies-3p-window.html b/test/fixtures/wpt/workers/support/shared-worker-partitioned-cookies-3p-window.html new file mode 100644 index 000000000000..e37e0a2cc6b6 --- /dev/null +++ b/test/fixtures/wpt/workers/support/shared-worker-partitioned-cookies-3p-window.html @@ -0,0 +1,26 @@ + + + + +SharedWorker: Partitioned Cookies 3P Window + + + + + + diff --git a/test/fixtures/wpt/workers/support/shared-worker-partitioned-cookies-helper.js b/test/fixtures/wpt/workers/support/shared-worker-partitioned-cookies-helper.js new file mode 100644 index 000000000000..e54d3848ae13 --- /dev/null +++ b/test/fixtures/wpt/workers/support/shared-worker-partitioned-cookies-helper.js @@ -0,0 +1,28 @@ +// Return a generator containing the worker's message. +// +// Usage: +// const worker = new SharedWorker(...); +// const nextMessage = worker_message_generator(worker); +// const msg_1 = await nextMessage(); +// const msg_2 = await nextMessage(); +// const msg_3 = await nextMessage(); +function worker_message_generator(shared_worker) { + const buffer = []; + let resolve = null; + + shared_worker.port.onmessage = message => { + buffer.push(message.data); + if (resolve) { + resolve(); + } + } + shared_worker.port.start(); + + return async function() { + if (buffer.length != 0) { + return buffer.shift(); + } + await new Promise(r => resolve = r); + return buffer.shift(); + } +} diff --git a/test/fixtures/wpt/workers/support/sync_xhr.js b/test/fixtures/wpt/workers/support/sync_xhr.js new file mode 100644 index 000000000000..5de747653738 --- /dev/null +++ b/test/fixtures/wpt/workers/support/sync_xhr.js @@ -0,0 +1,13 @@ +try +{ + const request = new XMLHttpRequest(); + request.open("GET", "sync_xhr_target.xml", false); + request.send(); + result = request.responseText == "sometext\n" ? "Pass" : "Fail"; + postMessage(result); +} +catch(ex) +{ + result = "Fail"; + postMessage(result); +} diff --git a/test/fixtures/wpt/workers/support/sync_xhr_target.xml b/test/fixtures/wpt/workers/support/sync_xhr_target.xml new file mode 100644 index 000000000000..d31a8c5eb463 --- /dev/null +++ b/test/fixtures/wpt/workers/support/sync_xhr_target.xml @@ -0,0 +1 @@ +sometext diff --git a/test/fixtures/wpt/workers/support/throw-on-message-Worker.js b/test/fixtures/wpt/workers/support/throw-on-message-Worker.js new file mode 100644 index 000000000000..3648f1f47853 --- /dev/null +++ b/test/fixtures/wpt/workers/support/throw-on-message-Worker.js @@ -0,0 +1,11 @@ +self.onerror = function(evt) { + postMessage('error'); + return true; +} + +self.onmessage = function(evt) { + if (evt.data === "first") + throw Error(); + else + postMessage(evt.data); +} diff --git a/test/fixtures/wpt/workers/support/window-sw-shared-name.html b/test/fixtures/wpt/workers/support/window-sw-shared-name.html new file mode 100644 index 000000000000..4a0704f9e4be --- /dev/null +++ b/test/fixtures/wpt/workers/support/window-sw-shared-name.html @@ -0,0 +1,22 @@ + +Window for cross-origin iframe with Shared Worker + + + + + + diff --git a/test/fixtures/wpt/workers/support/worker-request-animation-frame.js b/test/fixtures/wpt/workers/support/worker-request-animation-frame.js new file mode 100644 index 000000000000..b73781244ebd --- /dev/null +++ b/test/fixtures/wpt/workers/support/worker-request-animation-frame.js @@ -0,0 +1,6 @@ +self.onmessage = function(event) { + requestAnimationFrame(time => { + postMessage(time); + self.close(); + }); +} diff --git a/test/fixtures/wpt/workers/worker-performance.worker.js b/test/fixtures/wpt/workers/worker-performance.worker.js new file mode 100644 index 000000000000..c913b2e73750 --- /dev/null +++ b/test/fixtures/wpt/workers/worker-performance.worker.js @@ -0,0 +1,129 @@ +"use strict"; + +// Tests that most of the functionality of the window.performance object is available in web workers. + +importScripts("/resources/testharness.js"); + +function verifyEntry (entry, name, type, duration, assertName) { + assert_equals(entry.name, name, assertName + " has the right name"); + assert_equals(entry.entryType, type, assertName + " has the right type"); + assert_equals(entry.duration, duration, assertName + "has the right duration"); +} + +var start; +test(function testPerformanceNow () { + start = performance.now(); +}, "Can use performance.now in workers"); + +test(function testPerformanceMark () { + while (performance.now() == start) { } + performance.mark("mark1"); + // Stall the minimum amount of time to ensure the marks are separate + var now = performance.now(); + while (performance.now() == now) { } + performance.mark("mark2"); +}, "Can use performance.mark in workers"); + +test(function testPerformanceMeasure () { + performance.measure("measure1", "mark1", "mark2"); +}, "Can use performance.measure in workers"); + +test(function testPerformanceGetEntriesByName () { + var mark1s = performance.getEntriesByName("mark1"); + assert_equals(mark1s.length, 1, "getEntriesByName gave correct number of entries"); + verifyEntry(mark1s[0], "mark1", "mark", 0, "Entry got by name"); +}, "Can use performance.getEntriesByName in workers"); + +var marks; +var measures; +test(function testPerformanceGetEntriesByType () { + marks = performance.getEntriesByType("mark"); + assert_equals(marks.length, 2, "getEntriesByType gave correct number of entries"); + verifyEntry(marks[0], "mark1", "mark", 0, "First mark entry"); + verifyEntry(marks[1], "mark2", "mark", 0, "Second mark entry"); + measures = performance.getEntriesByType("measure"); + assert_equals(measures.length, 1, "getEntriesByType(\"measure\") gave correct number of entries"); + verifyEntry(measures[0], "measure1", "measure", marks[1].startTime - marks[0].startTime, "Measure entry"); +}, "Can use performance.getEntriesByType in workers"); + +test(function testPerformanceEntryOrder () { + assert_greater_than(marks[0].startTime, start, "First mark startTime is after a time before it"); + assert_greater_than(marks[1].startTime, marks[0].startTime, "Second mark startTime is after first mark startTime"); + assert_equals(measures[0].startTime, marks[0].startTime, "measure's startTime is the first mark's startTime"); +}, "Performance marks and measures seem to be working correctly in workers"); + +test(function testPerformanceClearing () { + performance.clearMarks(); + assert_equals(performance.getEntriesByType("mark").length, 0, "clearMarks cleared the marks"); + performance.clearMeasures(); + assert_equals(performance.getEntriesByType("measure").length, 0, "clearMeasures cleared the measures"); +}, "Can use clearMarks and clearMeasures in workers"); + +test(function testPerformanceResourceTiming () { // Resource timing + var start = performance.now(); + var xhr = new XMLHttpRequest(); + // Do a synchronous request and add a little artificial delay + xhr.open("GET", "/resources/testharness.js?pipe=trickle(d0.25)", false); + xhr.send(); + // The browser might or might not have added a resource performance entry for the importScripts() above; we're only interested in xmlhttprequest entries + var entries = performance.getEntriesByType("resource").filter(entry => entry.initiatorType == "xmlhttprequest"); + assert_equals(entries.length, 1, "getEntriesByType(\"resource\") returns one entry with initiatorType of xmlhttprequest"); + assert_true(!!entries[0].name.match(/\/resources\/testharness.js/), "Resource entry has loaded url as its name"); + assert_equals(entries[0].entryType, "resource", "Resource entry has correct entryType"); + assert_equals(entries[0].initiatorType, "xmlhttprequest", "Resource entry has correct initiatorType"); + var currentTimestamp = start; + var currentTimestampName = "a time before it"; + [ + "startTime", "fetchStart", "requestStart", "responseStart", "responseEnd" + ].forEach((name) => { + var timestamp = entries[0][name]; + // We want to skip over values that are 0 because of TAO securty rescritions + // Or else this test will fail. This can happen for "requestStart", "responseStart". + if (timestamp != 0) { + assert_greater_than_equal(timestamp, currentTimestamp, "Resource entry " + name + " is after " + currentTimestampName); + currentTimestamp = timestamp; + currentTimestampName = name; + } + }); + assert_greater_than(entries[0].responseEnd, entries[0].startTime, "The resource request should have taken at least some time"); + // We requested a delay of 250ms, but it could be a little bit less, and could be significantly more. + assert_greater_than(entries[0].responseEnd - entries[0].responseStart, 230, "Resource timing numbers reflect reality somewhat"); +}, "Resource timing seems to work in workers"); + +test(function testPerformanceClearResourceTimings () { + performance.clearResourceTimings(); + assert_equals(performance.getEntriesByType("resource").length, 0, "clearResourceTimings cleared the resource timings"); +}, "performance.clearResourceTimings in workers"); + +test(function testPerformanceSetResourceTimingBufferSize () { + performance.setResourceTimingBufferSize(0); + var xhr = new XMLHttpRequest(); + xhr.open("GET", "/resources/testharness.js", false); // synchronous request + xhr.send(); + assert_equals(performance.getEntriesByType("resource").length, 0, "setResourceTimingBufferSize(0) prevents resource entries from being added"); +}, "performance.setResourceTimingBufferSize in workers"); + +test(function testPerformanceHasNoTiming () { + assert_equals(typeof(performance.timing), "undefined", "performance.timing is undefined"); +}, "performance.timing is not available in workers"); + +test(function testPerformanceHasNoNavigation () { + assert_equals(typeof(performance.navigation), "undefined", "performance.navigation is undefined"); +}, "performance.navigation is not available in workers"); + +test(function testPerformanceHasToJSON () { + assert_equals(typeof(performance.toJSON), "function", "performance.toJSON is a function"); +}, "performance.toJSON is available in workers"); + +test(function testPerformanceNoNavigationEntries () { + assert_equals(performance.getEntriesByType("navigation").length, 0, "getEntriesByType(\"navigation\") returns nothing"); + assert_equals(performance.getEntriesByName("document", "navigation").length, 0, "getEntriesByName(\"document\", \"navigation\") returns nothing"); + assert_equals(performance.getEntriesByName("document").length, 0, "getEntriesByName(\"document\") returns nothing"); + var hasNavigation = performance.getEntries().some((e,i,a) => { + return e.entryType == "navigation"; + }); + assert_false(hasNavigation, "getEntries should return no navigation entries."); + +}, "There are no navigation type performance entries in workers"); + +done(); diff --git a/test/fixtures/wpt/workers/worker-request-animation-frame.html b/test/fixtures/wpt/workers/worker-request-animation-frame.html new file mode 100644 index 000000000000..2d65bc2c4610 --- /dev/null +++ b/test/fixtures/wpt/workers/worker-request-animation-frame.html @@ -0,0 +1,27 @@ + + + +raf time in dedicated workers + + + + + diff --git a/test/fixtures/wpt/workers/worker-url-encoding.html b/test/fixtures/wpt/workers/worker-url-encoding.html new file mode 100644 index 000000000000..56357a68603e --- /dev/null +++ b/test/fixtures/wpt/workers/worker-url-encoding.html @@ -0,0 +1,14 @@ + + +Worker URL is parsed using document encoding + + + \ No newline at end of file diff --git a/test/parallel/test-common-wpt-any.js b/test/parallel/test-common-wpt-any.js new file mode 100644 index 000000000000..d496c8859711 --- /dev/null +++ b/test/parallel/test-common-wpt-any.js @@ -0,0 +1,118 @@ +'use strict'; + +require('../common'); +const assert = require('assert'); +const { + getUnexpectedPasses, + WPTTestSpec, +} = require('../common/wpt'); + +const specs = WPTTestSpec.from( + 'WebCryptoAPI', + 'getPublicKey.tentative.https.any.js', + [], +); + +assert.deepStrictEqual(specs.map((spec) => ({ + testPath: spec.getTestPath(), + isWebWorkerTest: spec.isWebWorkerTest(), +})), [ + { + testPath: 'WebCryptoAPI/getPublicKey.tentative.https.any.html', + isWebWorkerTest: false, + }, + { + testPath: 'WebCryptoAPI/getPublicKey.tentative.https.any.worker.html', + isWebWorkerTest: true, + }, +]); + +const variantSpecs = WPTTestSpec.from( + 'WebCryptoAPI', + 'derive_bits_keys/hkdf.https.any.js', + [], +); + +assert.strictEqual(variantSpecs.length, 8); +assert.deepStrictEqual( + variantSpecs.filter((spec) => spec.isWebWorkerTest()) + .map((spec) => spec.getTestPath()), + [ + 'WebCryptoAPI/derive_bits_keys/hkdf.https.any.worker.html?1-1000', + 'WebCryptoAPI/derive_bits_keys/hkdf.https.any.worker.html?1001-2000', + 'WebCryptoAPI/derive_bits_keys/hkdf.https.any.worker.html?2001-3000', + 'WebCryptoAPI/derive_bits_keys/hkdf.https.any.worker.html?3001-last', + ], +); + +const skippedSpecs = WPTTestSpec.from( + 'WebCryptoAPI', + 'getPublicKey.tentative.https.any.js', + [{ requires: [], skip: 'unsupported' }], +); +assert.deepStrictEqual( + skippedSpecs.map(({ skipReasons }) => skipReasons), + [['unsupported'], ['unsupported']], +); + +const skippedSubtestSpecs = WPTTestSpec.from( + 'WebCryptoAPI', + 'getPublicKey.tentative.https.any.js', + [{ requires: [], skipTests: [/getPublicKey method/] }], +); +assert.ok(skippedSubtestSpecs.every( + (spec) => spec.isSkippedTest('getPublicKey method is available'))); + +const scopedSpecs = WPTTestSpec.from( + 'WebCryptoAPI', + 'getPublicKey.tentative.https.any.js', + [], + (spec) => (spec.getStatusKey().endsWith('.any.worker.html') ? + [{ requires: [], skip: 'worker only' }] : []), +); +assert.deepStrictEqual( + scopedSpecs.map(({ skipReasons }) => skipReasons), + [[], ['worker only']], +); + +const sourceRule = { + key: 'getPublicKey.tentative.https.any.js', + requires: [], + fail: { expected: ['shared failure'] }, +}; +const workerRule = { + key: 'getPublicKey.tentative.https.any.worker.html', + requires: [], + fail: { expected: ['worker failure'] }, +}; +const expectedFailureSpecs = WPTTestSpec.from( + 'WebCryptoAPI', + 'getPublicKey.tentative.https.any.js', + [sourceRule], + (spec) => (spec.isWebWorkerTest() ? [workerRule] : []), +); +const expectedResults = { + 'getPublicKey.tentative.https.any.html': { + fail: { expected: ['shared failure'] }, + }, + 'getPublicKey.tentative.https.any.worker.html': { + fail: { expected: ['shared failure', 'worker failure'] }, + }, +}; + +assert.deepStrictEqual( + getUnexpectedPasses(expectedFailureSpecs, expectedResults), + [], +); +expectedResults['getPublicKey.tentative.https.any.worker.html'].fail.expected = + ['worker failure']; +assert.deepStrictEqual( + getUnexpectedPasses(expectedFailureSpecs, expectedResults), + ['getPublicKey.tentative.https.any.worker.html:shared failure'], +); +expectedResults['getPublicKey.tentative.https.any.worker.html'].fail.expected = + ['shared failure']; +assert.deepStrictEqual( + getUnexpectedPasses(expectedFailureSpecs, expectedResults), + ['getPublicKey.tentative.https.any.worker.html:worker failure'], +); diff --git a/test/parallel/test-common-wpt-webworker-error.js b/test/parallel/test-common-wpt-webworker-error.js new file mode 100644 index 000000000000..57cef3175466 --- /dev/null +++ b/test/parallel/test-common-wpt-webworker-error.js @@ -0,0 +1,66 @@ +'use strict'; + +const common = require('../common'); +const fixtures = require('../common/fixtures'); +const assert = require('assert'); +const fs = require('fs'); +const path = require('path'); +const { Worker } = require('worker_threads'); + +const harnessPath = fixtures.path('wpt', 'resources', 'testharness.js'); +const worker = new Worker( + path.join(__dirname, '../common/wpt/worker.js'), + { + execArgv: ['--experimental-web-worker'], + workerData: { + testRelativePath: 'workers/error-after-result.any.js', + wptRunner: path.join(__dirname, '../common/wpt.js'), + wptPath: 'workers', + initScript: null, + harness: { + code: fs.readFileSync(harnessPath, 'utf8'), + filename: harnessPath, + }, + scriptsToRun: [], + webWorker: { + path: fixtures.path('web-worker', 'wpt-error-after-result.js'), + isAnyTest: true, + initScript: null, + variant: '', + scripts: [], + skippedTests: [], + }, + needsGc: false, + skippedTests: [], + }, + }, +); + +let sawResult = false; +const timeout = setTimeout(() => { + worker.terminate(); + assert.fail('WPT worker error was not reported'); +}, common.platformTimeout(1000)); + +worker.on('error', common.mustNotCall()); +worker.on('message', common.mustCall((message) => { + switch (message.type) { + case 'result': + assert.strictEqual(message.result.name, 'reported before error'); + assert.strictEqual(message.result.status, 0); + sawResult = true; + break; + case 'completion': + clearTimeout(timeout); + assert.ok(sawResult); + assert.strictEqual(message.status.status, 1); + assert.strictEqual( + message.status.message, + 'probe error after first result', + ); + worker.terminate(); + break; + default: + assert.fail(`Unexpected message type: ${message.type}`); + } +}, 2)); diff --git a/test/parallel/test-permission-allow-inspector.js b/test/parallel/test-permission-allow-inspector.js index 7d8b2aba8357..05022ff24044 100644 --- a/test/parallel/test-permission-allow-inspector.js +++ b/test/parallel/test-permission-allow-inspector.js @@ -38,7 +38,6 @@ session.connect(); }); assert.throws(() => { - // eslint-disable-next-line no-undef new Worker(` const child_process = require("node:child_process"); console.log(child_process.execSync("ls -l").toString()); diff --git a/test/parallel/test-worker-spec-differences.js b/test/parallel/test-worker-spec-differences.js new file mode 100644 index 000000000000..e6591f667e74 --- /dev/null +++ b/test/parallel/test-worker-spec-differences.js @@ -0,0 +1,62 @@ +// Flags: --experimental-web-worker +'use strict'; + +const common = require('../common'); +const fixtures = require('../common/fixtures'); +const assert = require('assert'); +const path = require('path'); + +function workerURL(name) { + return fixtures.fileURL('web-worker', name).href; +} + +// Asserts that `worker` posts exactly one message and terminates it. A worker +// is kept alive by its message port, so it never exits on its own. +function expectMessage(worker, check) { + worker.addEventListener('error', common.mustNotCall('worker failed')); + worker.addEventListener('message', common.mustCall(({ data }) => { + check(data); + worker.terminate(); + })); +} + +process.on('uncaughtException', common.mustNotCall( + 'worker errors must not be reported on the main thread')); + +// The only supported schemes are 'file:', 'blob:', and 'data:' +for (const unsupported of [ + 'https://nodejs.org/worker.js', + 'http://localhost/worker.js', + 'about:blank', + 'node:worker_threads', +]) { + assert.throws(() => new Worker(unsupported), { name: 'NotSupportedError' }); +} + +// Same as above, for `importScripts` +expectMessage(new Worker(workerURL('import-scheme.js')), + common.mustCall((data) => assert.strictEqual(data, 'NetworkError'))); + +// Rejection events are emitted on the process +expectMessage(new Worker(workerURL('no-events.js')), common.mustCall((data) => { + assert.deepStrictEqual(data.dispatched, []); + assert.strictEqual(data.processEvents, 1); +})); + +{ + // Calling close() immediately terminates the worker + const worker = new Worker(workerURL('close.js')); + worker.addEventListener('error', common.mustNotCall('worker failed')); + worker.addEventListener('message', common.mustCall(({ data }) => { + assert.strictEqual(data, 'before-close'); + }, 1)); +} + +{ + // Relative imports + const target = fixtures.path('web-worker', 'relative.js'); + const relative = + path.relative(process.cwd(), target).replaceAll(path.sep, '/'); + expectMessage(new Worker(relative.startsWith('.') ? relative : `./${relative}`), + common.mustCall((data) => assert.strictEqual(data, 'relative'))); +} diff --git a/test/wpt/README.md b/test/wpt/README.md index aba1b8617f90..bdd0b851fe31 100644 --- a/test/wpt/README.md +++ b/test/wpt/README.md @@ -201,6 +201,10 @@ that has not been ported to the Node.js runner. Use `fail` instead when the test can run but produces incorrect results due to an implementation bug or missing feature. +For a multi-global `.any.js` test, a source file key applies to every generated +test. Use a generated URL key such as `something.any.worker.html` to apply a +rule only to the dedicated worker test. + ### Skipping individual subtests To skip specific subtests within a file (rather than skipping the entire file), diff --git a/test/wpt/status/FileAPI/blob.cjs b/test/wpt/status/FileAPI/blob.cjs index bf40df1b8425..6f8599dc8b4e 100644 --- a/test/wpt/status/FileAPI/blob.cjs +++ b/test/wpt/status/FileAPI/blob.cjs @@ -33,7 +33,4 @@ module.exports = { ], }, }, - 'Blob-in-worker.worker.js': { - skip: 'Depends on Web Workers API', - }, }; diff --git a/test/wpt/status/dom/events.json b/test/wpt/status/dom/events.json index 8109e2372adf..f621431c9fc2 100644 --- a/test/wpt/status/dom/events.json +++ b/test/wpt/status/dom/events.json @@ -21,9 +21,6 @@ "event-global-set-before-handleEvent-lookup.window.js": { "skip": "window is not defined" }, - "event-global.worker.js": { - "skip": "importScripts is not defined" - }, "legacy-pre-activation-behavior.window.js": { "skip": "document is not defined" }, diff --git a/test/wpt/status/hr-time.cjs b/test/wpt/status/hr-time.cjs index c426eeeb8e92..35b82c87a1ea 100644 --- a/test/wpt/status/hr-time.cjs +++ b/test/wpt/status/hr-time.cjs @@ -19,7 +19,7 @@ module.exports = { }, } : {}), - 'idlharness.any.js': { + 'idlharness.any.html': { fail: { expected: [ 'Window interface: attribute performance', diff --git a/test/wpt/status/url.cjs b/test/wpt/status/url.cjs index d7cd8a8666b2..1ee0ce90071b 100644 --- a/test/wpt/status/url.cjs +++ b/test/wpt/status/url.cjs @@ -1,7 +1,7 @@ 'use strict'; module.exports = { - 'historical.any.js': { + 'historical.any.html': { 'fail': { 'expected': [ 'searchParams on location object', diff --git a/test/wpt/status/webidl.json b/test/wpt/status/webidl.json index 26a6e44f4841..73a89a373812 100644 --- a/test/wpt/status/webidl.json +++ b/test/wpt/status/webidl.json @@ -27,11 +27,24 @@ "Global object's setter throws when called on incompatible object", "Global object's operation throws when called on incompatible object", "Global object's getter works when called on null / undefined", - "Global object's setter works when called on null / undefined", + "Global object's setter works when called on null / undefined" + ] + } + }, + "ecmascript-binding/global-object-implicit-this-value.any.html": { + "fail": { + "expected": [ "ReferenceError: addEventListener is not defined" ] } }, + "ecmascript-binding/global-object-implicit-this-value.any.worker.html": { + "fail": { + "expected": [ + "Global object's operation works when called on null / undefined" + ] + } + }, "ecmascript-binding/legacy-factor-function-subclass.window.js": { "fail": { "expected": [ @@ -46,7 +59,7 @@ ] } }, - "ecmascript-binding/no-regexp-special-casing.any.js": { + "ecmascript-binding/no-regexp-special-casing.any.html": { "fail": { "expected": [ "Can be used as an object implementing a callback interface" diff --git a/test/wpt/status/workers.json b/test/wpt/status/workers.json new file mode 100644 index 000000000000..42234cd085df --- /dev/null +++ b/test/wpt/status/workers.json @@ -0,0 +1,161 @@ +{ + "SharedWorker-MessageEvent-source.any.js": { + "skip": "SharedWorker is not implemented" + }, + "SharedWorker-replace-EventHandler.any.js": { + "skip": "SharedWorker is not implemented" + }, + "Worker-location.sub.any.js": { + "skip": "Server substitution (.sub) is not supported" + }, + "WorkerLocation-origin.sub.window.js": { + "skip": "Needs a document and a WPT server" + }, + "constructors/Worker/AbstractWorker.onerror.js": { + "skip": "Not a test file; used as a worker script by .html tests" + }, + "constructors/Worker/expected-self-properties.worker.js": { + "fail": { + "note": "XMLHttpRequest and EventSource are not implemented", + "expected": [ + "existence of XMLHttpRequest", + "existence of EventSource" + ] + } + }, + "dedicated-worker-in-data-url-context.window.js": { + "skip": "Needs a document to create iframes" + }, + "examples/onconnect.any.js": { + "skip": "SharedWorker is not implemented" + }, + "importscripts_mime.any.js": { + "skip": "Needs a WPT server to serve scripts with arbitrary MIME types" + }, + "interfaces/WorkerUtils/importScripts/catch.sub.any.js": { + "skip": "Needs a WPT server; tests cross-origin importScripts()" + }, + "interfaces/WorkerUtils/importScripts/report-error-cross-origin.sub.any.js": { + "skip": "Needs a WPT server; tests cross-origin importScripts()" + }, + "interfaces/WorkerUtils/importScripts/report-error-redirect-to-cross-origin.sub.any.js": { + "skip": "Needs a WPT server; tests cross-origin importScripts()" + }, + "interfaces/WorkerUtils/importScripts/report-error-same-origin.sub.any.js": { + "skip": "Needs a WPT server; tests cross-origin importScripts()" + }, + "interfaces/WorkerUtils/importScripts/report-error-setTimeout-cross-origin.sub.any.js": { + "skip": "Needs a WPT server; tests cross-origin importScripts()" + }, + "interfaces/WorkerUtils/importScripts/report-error-setTimeout-redirect-to-cross-origin.sub.any.js": { + "skip": "Needs a WPT server; tests cross-origin importScripts()" + }, + "interfaces/WorkerUtils/importScripts/report-error-setTimeout-same-origin.sub.any.js": { + "skip": "Needs a WPT server; tests cross-origin importScripts()" + }, + "modules/dedicated-worker-import-blob-url.any.js": { + "skip": "Modules are imported from http(s): URLs served by a WPT server" + }, + "modules/dedicated-worker-import-data-url.any.js": { + "skip": "Modules are imported from http(s): URLs served by a WPT server" + }, + "modules/dedicated-worker-import.any.js": { + "fail": { + "note": "Needs a WPT server; tests cross-origin and redirected imports", + "expected": [ + "Static import (cross-origin).", + "Static import (redirect)." + ] + } + }, + "modules/resources/*.sub.js": { + "skip": "Not a test file; used as a worker script by other tests" + }, + "modules/shared-worker-import-blob-url.window.js": { + "skip": "SharedWorker is not implemented" + }, + "modules/shared-worker-import-data-url.window.js": { + "skip": "SharedWorker is not implemented" + }, + "modules/shared-worker-import.window.js": { + "skip": "SharedWorker is not implemented" + }, + "nested_worker_sync_xhr.worker.js": { + "skip": "XMLHttpRequest is not implemented" + }, + "same-site-cookies/first-party.all.tentative.https.window.js": { + "skip": "Needs a document and an https WPT server" + }, + "same-site-cookies/first-party.default.tentative.https.window.js": { + "skip": "Needs a document and an https WPT server" + }, + "same-site-cookies/first-party.none.tentative.https.window.js": { + "skip": "Needs a document and an https WPT server" + }, + "same-site-cookies/third-party.all.tentative.sub.https.window.js": { + "skip": "Needs a document and an https WPT server" + }, + "same-site-cookies/third-party.default.tentative.sub.https.window.js": { + "skip": "Needs a document and an https WPT server" + }, + "same-site-cookies/third-party.none.tentative.sub.https.window.js": { + "skip": "Needs a document and an https WPT server" + }, + "semantics/interface-objects/001.worker.js": { + "fail": { + "note": "Canvas, XHR, EventSource, PromiseRejectionEvent, ProgressEvent, the File API reader classes and IndexedDB are not implemented", + "expected": [ + "The ImageData interface object should be exposed.", + "The ImageBitmap interface object should be exposed.", + "The CanvasGradient interface object should be exposed.", + "The CanvasPattern interface object should be exposed.", + "The TextMetrics interface object should be exposed.", + "The Path2D interface object should be exposed.", + "The PromiseRejectionEvent interface object should be exposed.", + "The EventSource interface object should be exposed.", + "The XMLHttpRequestEventTarget interface object should be exposed.", + "The XMLHttpRequestUpload interface object should be exposed.", + "The XMLHttpRequest interface object should be exposed.", + "The ProgressEvent interface object should be exposed.", + "The FileList interface object should be exposed.", + "The FileReader interface object should be exposed.", + "The FileReaderSync interface object should be exposed.", + "The IDBRequest interface object should be exposed.", + "The IDBOpenDBRequest interface object should be exposed.", + "The IDBVersionChangeEvent interface object should be exposed.", + "The IDBFactory interface object should be exposed.", + "The IDBDatabase interface object should be exposed.", + "The IDBObjectStore interface object should be exposed.", + "The IDBIndex interface object should be exposed.", + "The IDBKeyRange interface object should be exposed.", + "The IDBCursor interface object should be exposed.", + "The IDBCursorWithValue interface object should be exposed.", + "The IDBTransaction interface object should be exposed." + ] + } + }, + "semantics/interface-objects/003.any.js": { + "skip": "SharedWorker is not implemented" + }, + "semantics/interface-objects/004.any.js": { + "skip": "SharedWorker is not implemented" + }, + "shared-worker-from-blob-url.window.js": { + "skip": "SharedWorker is not implemented" + }, + "shared-worker-in-data-url-context.window.js": { + "skip": "SharedWorker is not implemented" + }, + "worker-performance.worker.js": { + "fail": { + "note": "XMLHttpRequest is not implemented", + "expected": [ + "Resource timing seems to work in workers", + "performance.setResourceTimingBufferSize in workers" + ] + } + }, + "WorkerGlobalScope_requestAnimationFrame.worker.js": { + "skip": "requestAnimationFrame is not implemented in workers" + } +} diff --git a/test/wpt/test-hr-time.js b/test/wpt/test-hr-time.js index 9e7303d3e20c..13b35e3ac139 100644 --- a/test/wpt/test-hr-time.js +++ b/test/wpt/test-hr-time.js @@ -5,7 +5,9 @@ const { WPTRunner } = require('../common/wpt'); const runner = new WPTRunner('hr-time'); runner.setInitScript(` - self.GLOBAL.isWorker = () => false; + if (!globalThis.DedicatedWorkerGlobalScope) { + self.GLOBAL.isWorker = () => false; + } `); runner.pretendGlobalThisAs('Window'); diff --git a/test/wpt/test-workers.js b/test/wpt/test-workers.js new file mode 100644 index 000000000000..21ec86057b6e --- /dev/null +++ b/test/wpt/test-workers.js @@ -0,0 +1,9 @@ +'use strict'; + +require('../common'); +const { WPTRunner } = require('../common/wpt'); + +const runner = new WPTRunner('workers'); + +runner.pretendGlobalThisAs('Window'); +runner.runJsTests();