-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[WPT] BFCache: service worker clients
This CL adds tests for BFCache + Clients.claim(), Clients.matchAll() and unregister(). Bug: 1107415, 1204228, w3c/ServiceWorker#1594 Change-Id: I73233cf917e31dd91b974823d5490d0190f0eade
- Loading branch information
1 parent
3fd50d5
commit 89b57ab
Showing
5 changed files
with
256 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
31 changes: 31 additions & 0 deletions
31
html/browsers/browsing-the-web/back-forward-cache/resources/service-worker.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
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', e => { | ||
if (e.request.url.match(/\/is-controlled/)) { | ||
e.respondWith(new Response('controlled')); | ||
} | ||
else if (e.request.url.match(/\/get-clients-matchall/)) { | ||
const options = { includeUncontrolled: true, type: 'all' }; | ||
e.respondWith( | ||
self.clients.matchAll(options) | ||
.then(clients => { | ||
const client_urls = []; | ||
clients.forEach(client => client_urls.push(client.url)); | ||
return new Response(JSON.stringify(client_urls)); | ||
}) | ||
); | ||
} | ||
}); |
97 changes: 97 additions & 0 deletions
97
html/browsers/browsing-the-web/back-forward-cache/service-worker-clients-claim.https.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
<!doctype html> | ||
<meta name="timeout" content="long"> | ||
<script src="/resources/testharness.js"></script> | ||
<script src="/resources/testharnessreport.js"></script> | ||
<script src="/common/utils.js"></script> | ||
<script src="/common/dispatcher/dispatcher.js"></script> | ||
<script src="resources/helper.sub.js"></script> | ||
<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script> | ||
<script> | ||
|
||
promise_test(async t => { | ||
const pageA = new RemoteContext(token()); | ||
const pageB = new RemoteContext(token()); | ||
|
||
const urlA = location.origin + executorPath + pageA.context_id + '&events=pagehide,pageshow,load'; | ||
const urlB = originCrossSite + executorPath + pageB.context_id; | ||
|
||
window.open(urlA, '_blank', 'noopener'); | ||
|
||
await pageA.execute_script(waitForPageShow); | ||
|
||
await pageA.execute_script( | ||
(url) => { | ||
navigator.serviceWorker.oncontrollerchange = | ||
() => recordEvent('controllerchange'); | ||
}); | ||
|
||
// Register a service worker after `pageA` is loaded to make `pageA` | ||
// uncontrolled at this time. | ||
const workerUrl = 'resources/service-worker.js?pipe=header(Service-Worker-Allowed,../)'; | ||
const registration = await service_worker_unregister_and_register(t, workerUrl, './'); | ||
t.add_cleanup(_ => registration.unregister()); | ||
await wait_for_state(t, registration.installing, 'activated'); | ||
|
||
await pageA.execute_script( | ||
(url) => { | ||
prepareNavigation(() => { location.href = url; }); | ||
}, | ||
[urlB]); | ||
|
||
await pageB.execute_script(waitForPageShow); | ||
|
||
// Call clients.claim() when `pageA` is in BFCache. | ||
await claim(t, registration.active); | ||
|
||
// `pageA` doesn't appear in matchAll() because it is in BFCache. | ||
const clients1 = await (await fetch('/get-clients-matchall')).json(); | ||
assert_true(clients1.indexOf(urlA) < 0, '1: matchAll() before back navigation'); | ||
|
||
await pageB.execute_script( | ||
() => { | ||
prepareNavigation(() => { history.back(); }); | ||
} | ||
); | ||
await pageA.execute_script(waitForPageShow); | ||
await assert_bfcached(pageA); | ||
|
||
// After back navigation, `pageA` appears in matchAll(), but not controlled. | ||
const clients2 = await (await fetch('/get-clients-matchall')).json(); | ||
const controlled2 = await pageA.execute_script( | ||
() => fetch('/is-controlled?claim-2').then(r => r.text())); | ||
assert_true(clients2.indexOf(urlA) >= 0, '2: matchAll() just after back navigation'); | ||
assert_not_equals(controlled2, 'controlled', | ||
'2: pageA should not be controlled just after back navigation'); | ||
assert_array_equals( | ||
await pageA.execute_script(() => getRecordedEvents()), | ||
[ | ||
'window.load', | ||
'window.pageshow', | ||
'window.pagehide.persisted', | ||
'window.pageshow.persisted', | ||
], | ||
'2: controllerchange should not be fired just after back navigation'); | ||
|
||
// Call clients.claim() again when `pageA` is not in BFCache. | ||
await claim(t, registration.active); | ||
|
||
// After claim(), `pageA` is controlled. | ||
const clients3 = await (await fetch('/get-clients-matchall')).json(); | ||
const controlled3 = await pageA.execute_script( | ||
() => fetch('/is-controlled?claim-3').then(r => r.text())); | ||
assert_true(clients3.indexOf(urlA) >= 0, '3: matchAll() after back navigation and claim()'); | ||
assert_equals(controlled3, 'controlled', | ||
'3: pageA should be controlled after back navigation and claim()'); | ||
assert_array_equals( | ||
await pageA.execute_script(() => getRecordedEvents()), | ||
[ | ||
'window.load', | ||
'window.pageshow', | ||
'window.pagehide.persisted', | ||
'window.pageshow.persisted', | ||
'controllerchange', | ||
], | ||
'3: controllerchange should be fired'); | ||
|
||
}, 'Serviceworker Clients.claim()'); | ||
</script> |
63 changes: 63 additions & 0 deletions
63
html/browsers/browsing-the-web/back-forward-cache/service-worker-clients-matchall.https.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
<!doctype html> | ||
<script src="/resources/testharness.js"></script> | ||
<script src="/resources/testharnessreport.js"></script> | ||
<script src="/common/utils.js"></script> | ||
<script src="/common/dispatcher/dispatcher.js"></script> | ||
<script src="resources/helper.sub.js"></script> | ||
<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script> | ||
<script> | ||
|
||
promise_test(async t => { | ||
const workerUrl = 'resources/service-worker.js?pipe=header(Service-Worker-Allowed,../)'; | ||
const registration = await service_worker_unregister_and_register(t, workerUrl, './'); | ||
t.add_cleanup(_ => registration.unregister()); | ||
await wait_for_state(t, registration.installing, 'activated'); | ||
claim(t, registration.active); | ||
|
||
const pageA = new RemoteContext(token()); | ||
const pageB = new RemoteContext(token()); | ||
|
||
const urlA = location.origin + executorPath + pageA.context_id; | ||
const urlB = originCrossSite + executorPath + pageB.context_id; | ||
|
||
window.open(urlA, '_blank', 'noopener'); | ||
|
||
await pageA.execute_script(waitForPageShow); | ||
|
||
const clients1 = await (await fetch('/get-clients-matchall')).json(); | ||
const controlled1 = await pageA.execute_script( | ||
() => fetch('/is-controlled?matchall-1').then(r => r.text())); | ||
|
||
await pageA.execute_script( | ||
(url) => prepareNavigation(() => { | ||
location.href = url; | ||
}), | ||
[urlB]); | ||
|
||
await pageB.execute_script(waitForPageShow); | ||
|
||
const clients2 = await (await fetch('/get-clients-matchall')).json(); | ||
|
||
await pageB.execute_script( | ||
() => { | ||
prepareNavigation(() => { history.back(); }); | ||
} | ||
); | ||
|
||
await pageA.execute_script(waitForPageShow); | ||
await assert_bfcached(pageA); | ||
|
||
const clients3 = await (await fetch('/get-clients-matchall')).json(); | ||
const controlled3 = await pageA.execute_script( | ||
() => fetch('/is-controlled?matchall-3').then(r => r.text())); | ||
|
||
assert_true(clients1.indexOf(urlA) >= 0, '1: matchAll() before navigation'); | ||
assert_true(clients2.indexOf(urlA) < 0, '2: matchAll() before back navigation'); | ||
assert_true(clients3.indexOf(urlA) >= 0, '3: matchAll() after back navigation'); | ||
|
||
assert_equals(controlled1, 'controlled', | ||
'pageA should be controlled before BFCached'); | ||
assert_equals(controlled3, 'controlled', | ||
'pageA should be controlled after restored'); | ||
}, 'Serviceworker Clients.matchAll()'); | ||
</script> |
52 changes: 52 additions & 0 deletions
52
html/browsers/browsing-the-web/back-forward-cache/service-worker-unregister.https.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
<!doctype html> | ||
<script src="/resources/testharness.js"></script> | ||
<script src="/resources/testharnessreport.js"></script> | ||
<script src="/common/utils.js"></script> | ||
<script src="/common/dispatcher/dispatcher.js"></script> | ||
<script src="resources/helper.sub.js"></script> | ||
<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script> | ||
<script> | ||
|
||
promise_test(async t => { | ||
const workerUrl = 'resources/service-worker.js?pipe=header(Service-Worker-Allowed,../)'; | ||
const registration = await service_worker_unregister_and_register(t, workerUrl, './'); | ||
t.add_cleanup(_ => registration.unregister()); | ||
await wait_for_state(t, registration.installing, 'activated'); | ||
await claim(t, registration.active); | ||
|
||
const pageA = new RemoteContext(token()); | ||
const pageB = new RemoteContext(token()); | ||
|
||
const urlA = location.origin + executorPath + pageA.context_id; | ||
const urlB = originCrossSite + executorPath + pageB.context_id; | ||
|
||
window.open(urlA, '_blank', 'noopener'); | ||
|
||
await pageA.execute_script(waitForPageShow); | ||
await pageA.execute_script( | ||
(url) => prepareNavigation(() => { | ||
location.href = url; | ||
}), | ||
[urlB]); | ||
|
||
await pageB.execute_script(waitForPageShow); | ||
|
||
await registration.unregister(); | ||
|
||
await pageB.execute_script( | ||
() => { | ||
prepareNavigation(() => { history.back(); }); | ||
} | ||
); | ||
|
||
await pageA.execute_script(waitForPageShow); | ||
await assert_bfcached(pageA); | ||
|
||
assert_equals( | ||
await pageA.execute_script( | ||
() => fetch('/is-controlled').then(r => r.text())), | ||
'controlled', | ||
'pageA should be still controlled'); | ||
|
||
}, 'Unregister service worker while a controlled page is in BFCache should not crash'); | ||
</script> |