Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ServiceWorker: Add new WPT tests to make sure to update a registration with different script type and identical script content. #13755

Merged
merged 2 commits into from
Nov 13, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions service-workers/service-worker/resources/classic-worker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
importScripts('./imported-classic-script.js');
1 change: 1 addition & 0 deletions service-workers/service-worker/resources/module-worker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import * as module from './imported-module-script.js';
170 changes: 152 additions & 18 deletions service-workers/service-worker/update-registration-with-type.https.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,37 +7,39 @@
<script src="/resources/testharnessreport.js"></script>
<script src="resources/test-helpers.sub.js"></script>
<script>
// These tests check that a registration is updated correctly with
// different script type. At first Service Worker is register as
// The following two tests check that a registration is updated correctly
// with different script type. At first Service Worker is registered as
// classic script type, then it is re-registered as module script type,
// and vice versa. A main script is also updated at the same time.
promise_test(async t => {
const key = guid();
const script = `resources/update-registration-with-type.py?classic_first=1&key=${key}`;
const scope = 'resources/update-registration-with-type';
await service_worker_unregister(t, scope);
t.add_cleanup(() => service_worker_unregister(t, scope));

// Register with classic script type.
const firstRegistration = await navigator.serviceWorker.register(script, {
scope: scope,
type: 'classic'
});
firstRegistration.installing.postMessage(' ');
let msgEvent = await new Promise(resolve => {
navigator.serviceWorker.onmessage = resolve;
});
const firstWorker = firstRegistration.installing;
await wait_for_state(t, firstWorker, 'activated');
firstWorker.postMessage(' ');
let msgEvent = await new Promise(r => navigator.serviceWorker.onmessage = r);
assert_equals(msgEvent.data, 'A classic script.');

// Re-register with module script type.
const secondRegistration = await navigator.serviceWorker.register(script, {
scope: scope,
type: 'module'
});
secondRegistration.installing.postMessage(' ');
msgEvent = await new Promise(resolve => {
navigator.serviceWorker.onmessage = resolve;
});
const secondWorker = secondRegistration.installing;
secondWorker.postMessage(' ');
msgEvent = await new Promise(r => navigator.serviceWorker.onmessage = r);
assert_equals(msgEvent.data, 'A module script.');

assert_not_equals(firstWorker, secondWorker);
assert_equals(firstRegistration, secondRegistration);
}, 'Update the registration with a different script type (classic => module).');

Expand All @@ -46,29 +48,161 @@
const script = `resources/update-registration-with-type.py?classic_first=0&key=${key}`;
const scope = 'resources/update-registration-with-type';
await service_worker_unregister(t, scope);
t.add_cleanup(() => service_worker_unregister(t, scope));

// Register with module script type.
const firstRegistration = await navigator.serviceWorker.register(script, {
scope: scope,
type: 'module'
});
firstRegistration.installing.postMessage(' ');
let msgEvent = await new Promise(resolve => {
navigator.serviceWorker.onmessage = resolve;
});
const firstWorker = firstRegistration.installing;
await wait_for_state(t, firstWorker, 'activated');
firstWorker.postMessage(' ');
let msgEvent = await new Promise(r => navigator.serviceWorker.onmessage = r);
assert_equals(msgEvent.data, 'A module script.');

// Re-register with classic script type.
const secondRegistration = await navigator.serviceWorker.register(script, {
scope: scope,
type: 'classic'
});
secondRegistration.installing.postMessage(' ');
msgEvent = await new Promise(resolve => {
navigator.serviceWorker.onmessage = resolve;
});
const secondWorker = secondRegistration.installing;
secondWorker.postMessage(' ');
msgEvent = await new Promise(r => navigator.serviceWorker.onmessage = r);
assert_equals(msgEvent.data, 'A classic script.');

assert_not_equals(firstWorker, secondWorker);
assert_equals(firstRegistration, secondRegistration);
}, 'Update the registration with a different script type (module => classic).');

// The following two tests change the script type while keeping
// the script identical.
promise_test(async t => {
const script = 'resources/empty-worker.js';
const scope = 'resources/update-registration-with-type';
await service_worker_unregister(t, scope);
t.add_cleanup(() => service_worker_unregister(t, scope));

// Register with classic script type.
const firstRegistration = await navigator.serviceWorker.register(script, {
scope: scope,
type: 'classic'
});
const firstWorker = firstRegistration.installing;
await wait_for_state(t, firstWorker, 'activated');

// Re-register with module script type.
const secondRegistration = await navigator.serviceWorker.register(script, {
scope: scope,
type: 'module'
});
const secondWorker = secondRegistration.installing;

assert_not_equals(firstWorker, secondWorker);
assert_equals(firstRegistration, secondRegistration);
}, 'Update the registration with a different script type (classic => module) '
+ 'and with a same main script.');

promise_test(async t => {
const script = 'resources/empty-worker.js';
const scope = 'resources/update-registration-with-type';
await service_worker_unregister(t, scope);
t.add_cleanup(() => service_worker_unregister(t, scope));

// Register with module script type.
const firstRegistration = await navigator.serviceWorker.register(script, {
scope: scope,
type: 'module'
});
const firstWorker = firstRegistration.installing;
await wait_for_state(t, firstWorker, 'activated');

// Re-register with classic script type.
const secondRegistration = await navigator.serviceWorker.register(script, {
scope: scope,
type: 'classic'
});
const secondWorker = secondRegistration.installing;

assert_not_equals(firstWorker, secondWorker);
assert_equals(firstRegistration, secondRegistration);
}, 'Update the registration with a different script type (module => classic) '
+ 'and with a same main script.');

// This test checks that a registration is not updated with the same script
// type and the same main script.
promise_test(async t => {
const script = 'resources/empty-worker.js';
const scope = 'resources/update-registration-with-type';
await service_worker_unregister(t, scope);
t.add_cleanup(() => service_worker_unregister(t, scope));

// Register with module script type.
const firstRegistration = await navigator.serviceWorker.register(script, {
scope: scope,
type: 'module'
});
await wait_for_state(t, firstRegistration.installing, 'activated');

// Re-register with module script type.
const secondRegistration = await navigator.serviceWorker.register(script, {
scope: scope,
type: 'module'
});
assert_equals(secondRegistration.installing, null);

assert_equals(firstRegistration, secondRegistration);
}, 'Does not update the registration with the same script type and '
+ 'the same main script.');

// In the case (classic => module), a worker script contains importScripts()
// that is disallowed on module scripts, so the second registration is
// expected to fail script evaluation.
promise_test(async t => {
const script = 'resources/classic-worker.js';
const scope = 'resources/update-registration-with-type';
await service_worker_unregister(t, scope);
t.add_cleanup(() => service_worker_unregister(t, scope));

// Register with classic script type.
const firstRegistration = await navigator.serviceWorker.register(script, {
scope: scope,
type: 'classic'
});
assert_not_equals(firstRegistration.installing, null);
await wait_for_state(t, firstRegistration.installing, 'activated');

// Re-register with module script type and expect TypeError.
return promise_rejects(t, new TypeError, navigator.serviceWorker.register(script, {
scope: scope,
type: 'module'
}), 'Registering with invalid evaluation should be failed.');
}, 'Update the registration with a different script type (classic => module) '
+ 'and with a same main script. Expect evaluation failed.');

// In the case (module => classic), a worker script contains static-import
// that is disallowed on classic scripts, so the second registration is
// expected to fail script evaluation.
promise_test(async t => {
const script = 'resources/module-worker.js';
const scope = 'resources/update-registration-with-type';
await service_worker_unregister(t, scope);
t.add_cleanup(() => service_worker_unregister(t, scope));

// Register with module script type.
const firstRegistration = await navigator.serviceWorker.register(script, {
scope: scope,
type: 'module'
});
assert_not_equals(firstRegistration.installing, null);
await wait_for_state(t, firstRegistration.installing, 'activated');

// Re-register with classic script type and expect TypeError.
return promise_rejects(t, new TypeError, navigator.serviceWorker.register(script, {
scope: scope,
type: 'classic'
}), 'Registering with invalid evaluation should be failed.');
}, 'Update the registration with a different script type (module => classic) '
+ 'and with a same main script. Expect evaluation failed.');
</script>
</body>