-
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
2c83d2e
commit c6fafad
Showing
5 changed files
with
245 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)); | ||
}) | ||
); | ||
} | ||
}); |
86 changes: 86 additions & 0 deletions
86
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,86 @@ | ||
<!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 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); | ||
|
||
const clients1 = await (await fetch('/get-clients-matchall')).json(); | ||
|
||
await pageB.execute_script( | ||
() => { | ||
prepareNavigation(() => { history.back(); }); | ||
} | ||
); | ||
await pageA.execute_script(waitForPageShow); | ||
await assert_bfcached(pageA); | ||
|
||
const clients2 = await (await fetch('/get-clients-matchall')).json(); | ||
assert_equals( | ||
await pageA.execute_script( | ||
() => fetch('/is-controlled?claim-2').then(r => r.text())), | ||
'controlled', | ||
'2: pageA should be controlled'); | ||
|
||
assert_array_equals( | ||
await pageA.execute_script(() => getRecordedEvents()), | ||
[ | ||
'window.load', | ||
'window.pageshow', | ||
'window.pagehide.persisted', | ||
'window.pageshow.persisted', | ||
'controllerchange', | ||
]); | ||
|
||
// Call clients.claim() again when `pageA` is not in BFCache. | ||
await claim(t, registration.active); | ||
|
||
assert_equals( | ||
await pageA.execute_script( | ||
() => fetch('/is-controlled?claim-3').then(r => r.text())), | ||
'controlled', | ||
'3: pageA should be controlled'); | ||
const clients3 = await (await fetch('/get-clients-matchall')).json(); | ||
|
||
assert_true(clients1.indexOf(urlA) < 0, '1: page should not be controlled when claim() is called while BFCached'); | ||
assert_true(clients2.indexOf(urlA) >= 0, '2: page should be controlled when claim() is called while BFCached and the page is restored'); | ||
assert_true(clients3.indexOf(urlA) >= 0, '3: page should be controlled when claim()ed after restored'); | ||
}, '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: Before navigation'); | ||
assert_true(clients2.indexOf(urlA) < 0, '2: Before back navigation'); | ||
assert_true(clients3.indexOf(urlA) >= 0, '3: 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> |