mirror of
https://github.com/servo/servo.git
synced 2025-08-21 21:35:32 +01:00
Update web-platform-tests to revision 2df7f9ff620cbdaa2928464892fb1dfb880fd6c6
This commit is contained in:
parent
97e3c5f3a9
commit
7ba3376dde
74 changed files with 1985 additions and 504 deletions
|
@ -1,6 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Service Worker: Navigation redirection</title>
|
||||
<meta name="timeout" content="long">
|
||||
<!-- empty variant tests document.location and intercepted URLs -->
|
||||
<meta name="variant" content="">
|
||||
<!-- client variant tests the Clients API (resultingClientId and Client.url) -->
|
||||
<meta name="variant" content="?client">
|
||||
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/common/get-host-info.sub.js"></script>
|
||||
|
@ -76,36 +81,208 @@ async function check_all_intercepted_urls(expected_urls) {
|
|||
assert_object_equals(urls, expected_urls, 'Intercepted URLs should match.');
|
||||
}
|
||||
|
||||
// Checks |clients| returned from a worker. Only the client matching
|
||||
// |expected_final_client_tag| should be found. Returns true if a client was
|
||||
// found. Note that the final client is not necessarily found by this worker,
|
||||
// if the client is cross-origin.
|
||||
//
|
||||
// |clients| is an object like:
|
||||
// {x: {found: true, id: id1, url: url1}, b: {found: false}}
|
||||
function check_clients(clients,
|
||||
expected_id,
|
||||
expected_url,
|
||||
expected_final_client_tag,
|
||||
worker_name) {
|
||||
let found = false;
|
||||
Object.keys(clients).forEach(key => {
|
||||
const info = clients[key];
|
||||
if (info.found) {
|
||||
assert_true(expected_final_client_tag,
|
||||
`${worker_name} client tag exists`);
|
||||
assert_equals(key, expected_final_client_tag,
|
||||
`${worker_name} client tag matches`);
|
||||
assert_equals(info.id, expected_id, `${worker_name} client id`);
|
||||
assert_equals(info.url, expected_url, `${worker_name} client url`);
|
||||
found = true;
|
||||
}
|
||||
});
|
||||
return found;
|
||||
}
|
||||
|
||||
function check_resulting_client_ids(infos, expected_infos, actual_ids, worker) {
|
||||
assert_equals(infos.length, expected_infos.length,
|
||||
`request length for ${worker}`);
|
||||
for (var i = 0; i < infos.length; i++) {
|
||||
const tag = expected_infos[i].resultingClientIdTag;
|
||||
const url = expected_infos[i].url;
|
||||
const actual_id = infos[i].resultingClientId;
|
||||
const expected_id = actual_ids[tag];
|
||||
assert_equals(typeof(actual_id), 'string',
|
||||
`resultingClientId for ${url} request to ${worker}`);
|
||||
if (expected_id) {
|
||||
assert_equals(requestInfos[0], expected_id,
|
||||
`resultingClientId for ${url} request to ${worker}`);
|
||||
} else {
|
||||
actual_ids[key] = actual_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Creates an iframe and navigates to |url|, which is expected to start a chain
|
||||
// of redirects.
|
||||
// - |expected_last_url| is the expected window.location after the
|
||||
// navigation.
|
||||
//
|
||||
// - |expected_request_infos| is the expected requests that the service workers
|
||||
// were dispatched fetch events for. The format is:
|
||||
// [
|
||||
// [{url: url1}, {url: url2}], // requests from workers[0],
|
||||
// [{url: url1}, // requests from workers[1],
|
||||
// [{url: url1}, {url: url2}] // requests from cross-origin worker
|
||||
// [
|
||||
// // Requests received by workers[0].
|
||||
// {url: url1, resultingClientIdTag: 'a'},
|
||||
// {url: url2, resultingClientIdTag: 'a'}
|
||||
// ],
|
||||
// [
|
||||
// // Requests received by workers[1].
|
||||
// {url: url3, resultingClientIdTag: 'a'}
|
||||
// ],
|
||||
// [
|
||||
// // Requests received by the cross-origin worker.
|
||||
// {url: url4, resultingClientIdTag: 'x'}
|
||||
// {url: url5, resultingClientIdTag: 'x'}
|
||||
// ]
|
||||
// ]
|
||||
// Here, |url| is |event.request.url| and |resultingClientIdTag| represents
|
||||
// |event.resultingClientId|. Since the actual client ids are not known
|
||||
// beforehand, the expectation isn't the literal expected value, but all equal
|
||||
// tags must map to the same actual id.
|
||||
//
|
||||
// - |expected_final_client_tag| is the resultingClientIdTag that is
|
||||
// expected to map to the created client's id. This is null if there
|
||||
// is no such tag, which can happen when the final request was a cross-origin
|
||||
// redirect to out-scope, so no worker received a fetch event whose
|
||||
// resultingClientId is the id of the resulting client.
|
||||
//
|
||||
// In the example above:
|
||||
// - workers[0] receives two requests with the same resultingClientId.
|
||||
// - workers[1] receives one request also with that resultingClientId.
|
||||
// - The cross-origin worker receives two requests with the same
|
||||
// resultingClientId which differs from the previous one.
|
||||
// - Assuming |expected_final_client_tag| is 'x', then the created
|
||||
// client has the id seen by the cross-origin worker above.
|
||||
function redirect_test(url,
|
||||
expected_last_url,
|
||||
expected_request_infos,
|
||||
expected_final_client_tag,
|
||||
test_name) {
|
||||
promise_test(async t => {
|
||||
const frame = await with_iframe(url);
|
||||
t.add_cleanup(() => { frame.remove(); });
|
||||
|
||||
const expected_intercepted_urls = expected_request_infos.map(requests => {
|
||||
return requests.map(info => {
|
||||
return info.url;
|
||||
});
|
||||
});
|
||||
await check_all_intercepted_urls(expected_intercepted_urls);
|
||||
const last_url = await send_to_iframe(frame, 'getLocation');
|
||||
assert_equals(last_url, expected_last_url, 'Last URL should match.');
|
||||
// Switch on variant.
|
||||
if (document.location.search == '?client') {
|
||||
return client_variant_test(url, expected_last_url, expected_request_infos,
|
||||
expected_final_client_tag, test_name);
|
||||
}
|
||||
|
||||
return default_variant_test(url, expected_last_url, expected_request_infos,
|
||||
frame, test_name);
|
||||
}, test_name);
|
||||
}
|
||||
|
||||
// The default variant tests the request interception chain and
|
||||
// resulting document.location.
|
||||
async function default_variant_test(url,
|
||||
expected_last_url,
|
||||
expected_request_infos,
|
||||
frame,
|
||||
test_name) {
|
||||
const expected_intercepted_urls = expected_request_infos.map(
|
||||
requests_for_worker => {
|
||||
return requests_for_worker.map(info => {
|
||||
return info.url;
|
||||
});
|
||||
});
|
||||
await check_all_intercepted_urls(expected_intercepted_urls);
|
||||
const last_url = await send_to_iframe(frame, 'getLocation');
|
||||
assert_equals(last_url, expected_last_url, 'Last URL should match.');
|
||||
}
|
||||
|
||||
// The "client" variant tests the Clients API using resultingClientId.
|
||||
async function client_variant_test(url,
|
||||
expected_last_url,
|
||||
expected_request_infos,
|
||||
expected_final_client_tag,
|
||||
test_name) {
|
||||
// Request infos is an array like:
|
||||
// [
|
||||
// [{url: url1, resultingClientIdTag: tag1}],
|
||||
// [{url: url2, resultingClientIdTag: tag2}],
|
||||
// [{url: url3: resultingClientIdTag: tag3}]
|
||||
// ]
|
||||
const requestInfos = await get_all_request_infos();
|
||||
|
||||
// We check the actual infos against the expected ones, and learn the
|
||||
// actual ids as we go.
|
||||
const actual_ids = {};
|
||||
check_resulting_client_ids(requestInfos[0],
|
||||
expected_request_infos[0],
|
||||
actual_ids,
|
||||
'worker0');
|
||||
check_resulting_client_ids(requestInfos[1],
|
||||
expected_request_infos[1],
|
||||
actual_ids,
|
||||
'worker1');
|
||||
check_resulting_client_ids(requestInfos[2],
|
||||
expected_request_infos[2],
|
||||
actual_ids,
|
||||
'crossOriginWorker');
|
||||
|
||||
// Now |actual_ids| maps tag to actual id:
|
||||
// {x: id1, b: id2, c: id3}
|
||||
// Ask each worker to try to resolve the actual ids to clients.
|
||||
// Only |expected_final_client_tag| should resolve to a client.
|
||||
const client_infos = await get_all_clients(actual_ids);
|
||||
|
||||
// Client infos is an object like:
|
||||
// {
|
||||
// worker0: {x: {found: true, id: id1, url: url1}, b: {found: false}},
|
||||
// worker1: {x: {found: true, id: id1, url: url1}},
|
||||
// crossOriginWorker: {x: {found: false}}, {b: {found: false}}
|
||||
// }
|
||||
//
|
||||
// Now check each client info. check_clients() verifies each info: only
|
||||
// |expected_final_client_tag| should ever be found and the found client
|
||||
// should have the expected url and id. A wrinkle is that not all workers
|
||||
// will find the client, if they are cross-origin to the client. This
|
||||
// means check_clients() trivially passes if no clients are found. So
|
||||
// additionally check that at least one worker found the client (|found|),
|
||||
// if that was expected (|expect_found|).
|
||||
let found = false;
|
||||
const expect_found = !!expected_final_client_tag;
|
||||
const expected_id = actual_ids[expected_final_client_tag];
|
||||
found = check_clients(client_infos.worker0,
|
||||
expected_id,
|
||||
expected_last_url,
|
||||
expected_final_client_tag,
|
||||
'worker0');
|
||||
found = check_clients(client_infos.worker1,
|
||||
expected_id,
|
||||
expected_last_url,
|
||||
expected_final_client_tag,
|
||||
'worker1') || found;
|
||||
found = check_clients(client_infos.crossOriginWorker,
|
||||
expected_id,
|
||||
expected_last_url,
|
||||
expected_final_client_tag,
|
||||
'crossOriginWorker') || found;
|
||||
assert_equals(found, expect_found, 'client found');
|
||||
|
||||
if (!expect_found) {
|
||||
// TODO(falken): Ask the other origin frame if it has a client of the
|
||||
// expected URL.
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener('message', on_message, false);
|
||||
|
||||
function on_message(e) {
|
||||
|
@ -129,6 +306,27 @@ function send_to_iframe(frame, message) {
|
|||
});
|
||||
}
|
||||
|
||||
async function get_all_clients(actual_ids) {
|
||||
const client_infos = {};
|
||||
client_infos['worker0'] = await get_clients(workers[0], actual_ids);
|
||||
client_infos['worker1'] = await get_clients(workers[1], actual_ids);
|
||||
client_infos['crossOriginWorker'] =
|
||||
await send_to_iframe(other_origin_frame,
|
||||
{command: 'get_clients', actual_ids});
|
||||
return client_infos;
|
||||
}
|
||||
|
||||
function get_clients(worker, actual_ids) {
|
||||
return new Promise(resolve => {
|
||||
var channel = new MessageChannel();
|
||||
channel.port1.onmessage = (msg) => {
|
||||
resolve(msg.data.clients);
|
||||
};
|
||||
worker.postMessage({command: 'getClients', actual_ids, port: channel.port2},
|
||||
[channel.port2]);
|
||||
});
|
||||
}
|
||||
|
||||
// Returns an array of the URLs that |worker| received fetch events for:
|
||||
// [url1, url2]
|
||||
async function get_intercepted_urls(worker) {
|
||||
|
@ -138,7 +336,10 @@ async function get_intercepted_urls(worker) {
|
|||
|
||||
// Returns the requests that |worker| received fetch events for. The return
|
||||
// value is an array of format:
|
||||
// [{url: url1}, {url: url2}]
|
||||
// [
|
||||
// {url: url1, resultingClientId: id},
|
||||
// {url: url2, resultingClientId: id}
|
||||
// ]
|
||||
function get_request_infos(worker) {
|
||||
return new Promise(resolve => {
|
||||
var channel = new MessageChannel();
|
||||
|
@ -150,6 +351,29 @@ function get_request_infos(worker) {
|
|||
});
|
||||
}
|
||||
|
||||
// Returns an array of the requests the workers received fetch events for:
|
||||
// [
|
||||
// // Requests from workers[0].
|
||||
// [
|
||||
// {url: url1, resultingClientIdTag: tag1},
|
||||
// {url: url2, resultingClientIdTag: tag1}
|
||||
// ],
|
||||
//
|
||||
// // Requests from workers[1].
|
||||
// [{url: url3, resultingClientIdTag: tag2}],
|
||||
//
|
||||
// // Requests from the cross-origin worker.
|
||||
// []
|
||||
// ]
|
||||
async function get_all_request_infos() {
|
||||
const request_infos = [];
|
||||
request_infos.push(await get_request_infos(workers[0]));
|
||||
request_infos.push(await get_request_infos(workers[1]));
|
||||
request_infos.push(await send_to_iframe(other_origin_frame,
|
||||
{command: 'get_request_infos'}));
|
||||
return request_infos;
|
||||
}
|
||||
|
||||
let url;
|
||||
let url1;
|
||||
let url2;
|
||||
|
@ -159,7 +383,8 @@ url = SCOPE1;
|
|||
redirect_test(
|
||||
OUT_SCOPE + 'url=' + encodeURIComponent(url),
|
||||
url,
|
||||
[[{url}], [], []],
|
||||
[[{url, resultingClientIdTag: 'x'}], [], []],
|
||||
'x',
|
||||
'Normal redirect to same-origin scope.');
|
||||
|
||||
|
||||
|
@ -167,30 +392,33 @@ url = SCOPE1 + '#ref';
|
|||
redirect_test(
|
||||
OUT_SCOPE + 'url=' + encodeURIComponent(SCOPE1) + '#ref',
|
||||
url,
|
||||
[[{url}], [], []],
|
||||
[[{url, resultingClientIdTag: 'x'}], [], []],
|
||||
'x',
|
||||
'Normal redirect to same-origin scope with a hash fragment.');
|
||||
|
||||
url = SCOPE1 + '#ref2';
|
||||
redirect_test(
|
||||
OUT_SCOPE + 'url=' + encodeURIComponent(url) + '#ref',
|
||||
url,
|
||||
[[{url}], [], []],
|
||||
[[{url, resultingClientIdTag: 'x'}], [], []],
|
||||
'x',
|
||||
'Normal redirect to same-origin scope with different hash fragments.');
|
||||
|
||||
url = OTHER_ORIGIN_SCOPE;
|
||||
redirect_test(
|
||||
OUT_SCOPE + 'url=' + encodeURIComponent(url),
|
||||
url,
|
||||
[[], [], [{url}]],
|
||||
[[], [], [{url, resultingClientIdTag: 'x'}]],
|
||||
'x',
|
||||
'Normal redirect to other-origin scope.');
|
||||
|
||||
|
||||
// SW fallbacked redirect. SW doesn't handle the fetch request.
|
||||
url = SCOPE1 + 'url=' + encodeURIComponent(OUT_SCOPE);
|
||||
redirect_test(
|
||||
url,
|
||||
OUT_SCOPE,
|
||||
[[{url}], [], []],
|
||||
[[{url, resultingClientIdTag: 'x'}], [], []],
|
||||
'x',
|
||||
'SW-fallbacked redirect to same-origin out-scope.');
|
||||
|
||||
url1 = SCOPE1 + 'url=' + encodeURIComponent(SCOPE1);
|
||||
|
@ -198,7 +426,15 @@ url2 = SCOPE1;
|
|||
redirect_test(
|
||||
url1,
|
||||
url2,
|
||||
[[{url: url1}, {url: url2}], [], []],
|
||||
[
|
||||
[
|
||||
{url: url1, resultingClientIdTag: 'x'},
|
||||
{url: url2, resultingClientIdTag: 'x'}
|
||||
],
|
||||
[],
|
||||
[]
|
||||
],
|
||||
'x',
|
||||
'SW-fallbacked redirect to same-origin same-scope.');
|
||||
|
||||
url1 = SCOPE1 + 'url=' + encodeURIComponent(SCOPE1) + '#ref';
|
||||
|
@ -206,7 +442,15 @@ url2 = SCOPE1 + '#ref';
|
|||
redirect_test(
|
||||
url1,
|
||||
url2,
|
||||
[[{url: url1}, {url: url2}], [], []],
|
||||
[
|
||||
[
|
||||
{url: url1, resultingClientIdTag: 'x'},
|
||||
{url: url2, resultingClientIdTag: 'x'}
|
||||
],
|
||||
[],
|
||||
[]
|
||||
],
|
||||
'x',
|
||||
'SW-fallbacked redirect to same-origin same-scope with a hash fragment.');
|
||||
|
||||
url1 = SCOPE1 + 'url=' + encodeURIComponent(SCOPE1 + '#ref2') + '#ref';
|
||||
|
@ -214,7 +458,15 @@ url2 = SCOPE1 + '#ref2';
|
|||
redirect_test(
|
||||
url1,
|
||||
url2,
|
||||
[[{url: url1}, {url: url2}], [], []],
|
||||
[
|
||||
[
|
||||
{url: url1, resultingClientIdTag: 'x'},
|
||||
{url: url2, resultingClientIdTag: 'x'}
|
||||
],
|
||||
[],
|
||||
[]
|
||||
],
|
||||
'x',
|
||||
'SW-fallbacked redirect to same-origin same-scope with different hash ' +
|
||||
'fragments.');
|
||||
|
||||
|
@ -223,7 +475,12 @@ url2 = SCOPE2;
|
|||
redirect_test(
|
||||
url1,
|
||||
url2,
|
||||
[[{url: url1}], [{url: url2}], []],
|
||||
[
|
||||
[{url: url1, resultingClientIdTag: 'x'}],
|
||||
[{url: url2, resultingClientIdTag: 'x'}],
|
||||
[]
|
||||
],
|
||||
'x',
|
||||
'SW-fallbacked redirect to same-origin other-scope.');
|
||||
|
||||
url1 = SCOPE1 + 'url=' + encodeURIComponent(OTHER_ORIGIN_OUT_SCOPE);
|
||||
|
@ -231,7 +488,8 @@ url2 = OTHER_ORIGIN_OUT_SCOPE;
|
|||
redirect_test(
|
||||
url1,
|
||||
url2,
|
||||
[[{url: url1}], [], []],
|
||||
[[{url: url1, resultingClientIdTag: 'a'}], [], []],
|
||||
'x',
|
||||
'SW-fallbacked redirect to other-origin out-scope.');
|
||||
|
||||
url1 = SCOPE1 + 'url=' + encodeURIComponent(OTHER_ORIGIN_SCOPE);
|
||||
|
@ -239,10 +497,32 @@ url2 = OTHER_ORIGIN_SCOPE;
|
|||
redirect_test(
|
||||
url1,
|
||||
url2,
|
||||
[[{url: url1}], [], [{url: url2}]],
|
||||
[
|
||||
[{url: url1, resultingClientIdTag: 'a'}],
|
||||
[],
|
||||
[{url: url2, resultingClientIdTag: 'x'}]
|
||||
],
|
||||
'x',
|
||||
'SW-fallbacked redirect to other-origin in-scope.');
|
||||
|
||||
|
||||
url3 = SCOPE1;
|
||||
url2 = OTHER_ORIGIN_SCOPE + 'url=' + encodeURIComponent(url3);
|
||||
url1 = SCOPE1 + 'url=' + encodeURIComponent(url2);
|
||||
redirect_test(
|
||||
url1,
|
||||
url3,
|
||||
[
|
||||
[
|
||||
{url: url1, resultingClientIdTag: 'a'},
|
||||
{url: url3, resultingClientIdTag: 'x'}
|
||||
],
|
||||
[],
|
||||
[{url: url2, resultingClientIdTag: 'b'}]
|
||||
],
|
||||
'x',
|
||||
'SW-fallbacked redirect to other-origin and back to same-origin.');
|
||||
|
||||
// SW generated redirect.
|
||||
// SW: event.respondWith(Response.redirect(params['url']));
|
||||
url1 = SCOPE1 + 'sw=gen&url=' + encodeURIComponent(OUT_SCOPE);
|
||||
|
@ -250,7 +530,8 @@ url2 = OUT_SCOPE;
|
|||
redirect_test(
|
||||
url1,
|
||||
url2,
|
||||
[[{url: url1}], [], []],
|
||||
[[{url: url1, resultingClientIdTag: 'a'}], [], []],
|
||||
null,
|
||||
'SW-generated redirect to same-origin out-scope.');
|
||||
|
||||
url1 = SCOPE1 + 'sw=gen&url=' + encodeURIComponent(OUT_SCOPE) + '#ref';
|
||||
|
@ -258,7 +539,8 @@ url2 = OUT_SCOPE + '#ref';
|
|||
redirect_test(
|
||||
url1,
|
||||
url2,
|
||||
[[{url: url1}], [], []],
|
||||
[[{url: url1, resultingClientIdTag: 'x'}], [], []],
|
||||
'x',
|
||||
'SW-generated redirect to same-origin out-scope with a hash fragment.');
|
||||
|
||||
url1 = SCOPE1 + 'sw=gen&url=' + encodeURIComponent(OUT_SCOPE + '#ref2') + '#ref';
|
||||
|
@ -266,7 +548,8 @@ url2 = OUT_SCOPE + '#ref2';
|
|||
redirect_test(
|
||||
url1,
|
||||
url2,
|
||||
[[{url: url1}], [], []],
|
||||
[[{url: url1, resultingClientIdTag: 'x'}], [], []],
|
||||
'x',
|
||||
'SW-generated redirect to same-origin out-scope with different hash ' +
|
||||
'fragments.');
|
||||
|
||||
|
@ -275,7 +558,15 @@ url2 = SCOPE1;
|
|||
redirect_test(
|
||||
url1,
|
||||
url2,
|
||||
[[{url: url1}, {url: url2}], [], []],
|
||||
[
|
||||
[
|
||||
{url: url1, resultingClientIdTag: 'x'},
|
||||
{url: url2, resultingClientIdTag: 'x'}
|
||||
],
|
||||
[],
|
||||
[]
|
||||
],
|
||||
'x',
|
||||
'SW-generated redirect to same-origin same-scope.');
|
||||
|
||||
url1 = SCOPE1 + 'sw=gen&url=' + encodeURIComponent(SCOPE2);
|
||||
|
@ -283,7 +574,12 @@ url2 = SCOPE2;
|
|||
redirect_test(
|
||||
url1,
|
||||
url2,
|
||||
[[{url: url1}], [{url: url2}], []],
|
||||
[
|
||||
[{url: url1, resultingClientIdTag: 'x'}],
|
||||
[{url: url2, resultingClientIdTag: 'x'}],
|
||||
[]
|
||||
],
|
||||
'x',
|
||||
'SW-generated redirect to same-origin other-scope.');
|
||||
|
||||
url1 = SCOPE1 + 'sw=gen&url=' + encodeURIComponent(OTHER_ORIGIN_OUT_SCOPE);
|
||||
|
@ -291,7 +587,8 @@ url2 = OTHER_ORIGIN_OUT_SCOPE;
|
|||
redirect_test(
|
||||
url1,
|
||||
url2,
|
||||
[[{url: url1}], [], []],
|
||||
[[{url: url1, resultingClientIdTag: 'a'}], [], []],
|
||||
null,
|
||||
'SW-generated redirect to other-origin out-scope.');
|
||||
|
||||
url1 = SCOPE1 + 'sw=gen&url=' + encodeURIComponent(OTHER_ORIGIN_SCOPE);
|
||||
|
@ -300,10 +597,11 @@ redirect_test(
|
|||
url1,
|
||||
url2,
|
||||
[
|
||||
[{url: url1}],
|
||||
[{url: url1, resultingClientIdTag: 'a'}],
|
||||
[],
|
||||
[{url: url2}]
|
||||
[{url: url2, resultingClientIdTag: 'x'}]
|
||||
],
|
||||
'x',
|
||||
'SW-generated redirect to other-origin in-scope.');
|
||||
|
||||
|
||||
|
@ -314,7 +612,8 @@ url2 = OUT_SCOPE;
|
|||
redirect_test(
|
||||
url1,
|
||||
url2,
|
||||
[[{url: url1}], [], []],
|
||||
[[{url: url1, resultingClientIdTag: 'x'}], [], []],
|
||||
'x',
|
||||
'SW-fetched redirect to same-origin out-scope.');
|
||||
|
||||
url1 = SCOPE1 + 'sw=fetch&url=' + encodeURIComponent(SCOPE1);
|
||||
|
@ -322,7 +621,15 @@ url2 = SCOPE1;
|
|||
redirect_test(
|
||||
url1,
|
||||
url2,
|
||||
[[{url: url1}, {url: url2}], [], []],
|
||||
[
|
||||
[
|
||||
{url: url1, resultingClientIdTag: 'x'},
|
||||
{url: url2, resultingClientIdTag: 'x'}
|
||||
],
|
||||
[],
|
||||
[]
|
||||
],
|
||||
'x',
|
||||
'SW-fetched redirect to same-origin same-scope.');
|
||||
|
||||
url1 = SCOPE1 + 'sw=fetch&url=' + encodeURIComponent(SCOPE2);
|
||||
|
@ -331,10 +638,11 @@ redirect_test(
|
|||
url1,
|
||||
url2,
|
||||
[
|
||||
[{url: url1}],
|
||||
[{url: url2}],
|
||||
[{url: url1, resultingClientIdTag: 'x'}],
|
||||
[{url: url2, resultingClientIdTag: 'x'}],
|
||||
[]
|
||||
],
|
||||
'x',
|
||||
'SW-fetched redirect to same-origin other-scope.');
|
||||
|
||||
url1 = SCOPE1 + 'sw=fetch&url=' + encodeURIComponent(OTHER_ORIGIN_OUT_SCOPE);
|
||||
|
@ -342,7 +650,8 @@ url2 = OTHER_ORIGIN_OUT_SCOPE;
|
|||
redirect_test(
|
||||
url1,
|
||||
url2,
|
||||
[[{url: url1}], [], []],
|
||||
[[{url: url1, resultingClientIdTag: 'a'}], [], []],
|
||||
null,
|
||||
'SW-fetched redirect to other-origin out-scope.');
|
||||
|
||||
url1 = SCOPE1 + 'sw=fetch&url=' + encodeURIComponent(OTHER_ORIGIN_SCOPE);
|
||||
|
@ -351,10 +660,11 @@ redirect_test(
|
|||
url1,
|
||||
url2,
|
||||
[
|
||||
[{url: url1}],
|
||||
[{url: url1, resultingClientIdTag: 'a'}],
|
||||
[],
|
||||
[{url: url2}]
|
||||
[{url: url2, resultingClientIdTag: 'x'}]
|
||||
],
|
||||
'x',
|
||||
'SW-fetched redirect to other-origin in-scope.');
|
||||
|
||||
|
||||
|
@ -366,7 +676,8 @@ url2 = OUT_SCOPE;
|
|||
redirect_test(
|
||||
url1,
|
||||
url2,
|
||||
[[{url: url1}], [], []],
|
||||
[[{url: url1, resultingClientIdTag: 'x'}], [], []],
|
||||
'x',
|
||||
'Redirect to same-origin out-scope with opaque redirect response.');
|
||||
|
||||
url1 = SCOPE1 + 'sw=manual&url=' + encodeURIComponent(SCOPE1);
|
||||
|
@ -374,7 +685,15 @@ url2 = SCOPE1;
|
|||
redirect_test(
|
||||
url1,
|
||||
url2,
|
||||
[[{url: url1}, {url: url2}], [], []],
|
||||
[
|
||||
[
|
||||
{url: url1, resultingClientIdTag: 'x'},
|
||||
{url: url2, resultingClientIdTag: 'x'}
|
||||
],
|
||||
[],
|
||||
[]
|
||||
],
|
||||
'x',
|
||||
'Redirect to same-origin same-scope with opaque redirect response.');
|
||||
|
||||
url1 = SCOPE1 + 'sw=manual&url=' + encodeURIComponent(SCOPE2);
|
||||
|
@ -382,7 +701,12 @@ url2 = SCOPE2;
|
|||
redirect_test(
|
||||
url1,
|
||||
url2,
|
||||
[[{url: url1}], [{url: url2}], []],
|
||||
[
|
||||
[{url: url1, resultingClientIdTag: 'x'}],
|
||||
[{url: url2, resultingClientIdTag: 'x'}],
|
||||
[]
|
||||
],
|
||||
'x',
|
||||
'Redirect to same-origin other-scope with opaque redirect response.');
|
||||
|
||||
url1 = SCOPE1 + 'sw=manual&url=' + encodeURIComponent(OTHER_ORIGIN_OUT_SCOPE);
|
||||
|
@ -390,7 +714,8 @@ url2 = OTHER_ORIGIN_OUT_SCOPE;
|
|||
redirect_test(
|
||||
url1,
|
||||
url2,
|
||||
[[{url: url1}], [], []],
|
||||
[[{url: url1, resultingClientIdTag: 'a'}], [], []],
|
||||
null,
|
||||
'Redirect to other-origin out-scope with opaque redirect response.');
|
||||
|
||||
url1 = SCOPE1 + 'sw=manual&url=' + encodeURIComponent(OTHER_ORIGIN_SCOPE);
|
||||
|
@ -398,12 +723,18 @@ url2 = OTHER_ORIGIN_SCOPE;
|
|||
redirect_test(
|
||||
url1,
|
||||
url2,
|
||||
[[{url: url1}], [], [{url: url2}]],
|
||||
[
|
||||
[{url: url1, resultingClientIdTag: 'a'}],
|
||||
[],
|
||||
[{url: url2, resultingClientIdTag: 'x'}]
|
||||
],
|
||||
'x',
|
||||
'Redirect to other-origin in-scope with opaque redirect response.');
|
||||
|
||||
url= SCOPE1 + 'sw=manual&noLocationRedirect';
|
||||
redirect_test(
|
||||
url, url, [[{url}], [], []],
|
||||
url, url, [[{url, resultingClientIdTag: 'x'}], [], []],
|
||||
'x',
|
||||
'No location redirect response.');
|
||||
|
||||
|
||||
|
@ -414,7 +745,8 @@ url2 = OUT_SCOPE;
|
|||
redirect_test(
|
||||
url1,
|
||||
url2,
|
||||
[[{url: url1}], [], []],
|
||||
[[{url: url1, resultingClientIdTag: 'x'}], [], []],
|
||||
'x',
|
||||
'Redirect to same-origin out-scope with opaque redirect response which ' +
|
||||
'is passed through Cache.');
|
||||
|
||||
|
@ -424,10 +756,14 @@ redirect_test(
|
|||
url1,
|
||||
url2,
|
||||
[
|
||||
[{url: url1}, {url: url2}],
|
||||
[
|
||||
{url: url1, resultingClientIdTag: 'x'},
|
||||
{url: url2, resultingClientIdTag: 'x'}
|
||||
],
|
||||
[],
|
||||
[]
|
||||
],
|
||||
'x',
|
||||
'Redirect to same-origin same-scope with opaque redirect response which ' +
|
||||
'is passed through Cache.');
|
||||
|
||||
|
@ -437,10 +773,11 @@ redirect_test(
|
|||
url1,
|
||||
url2,
|
||||
[
|
||||
[{url: url1}],
|
||||
[{url: url2}],
|
||||
[{url: url1, resultingClientIdTag: 'x'}],
|
||||
[{url: url2, resultingClientIdTag: 'x'}],
|
||||
[]
|
||||
],
|
||||
'x',
|
||||
'Redirect to same-origin other-scope with opaque redirect response which ' +
|
||||
'is passed through Cache.');
|
||||
|
||||
|
@ -450,7 +787,8 @@ url2 = OTHER_ORIGIN_OUT_SCOPE;
|
|||
redirect_test(
|
||||
url1,
|
||||
url2,
|
||||
[[{url: url1}], [], []],
|
||||
[[{url: url1, resultingClientIdTag: 'a'}], [], []],
|
||||
null,
|
||||
'Redirect to other-origin out-scope with opaque redirect response which ' +
|
||||
'is passed through Cache.');
|
||||
|
||||
|
@ -461,10 +799,11 @@ redirect_test(
|
|||
url1,
|
||||
url2,
|
||||
[
|
||||
[{url: url1}],
|
||||
[{url: url1, resultingClientIdTag: 'a'}],
|
||||
[],
|
||||
[{url: url2}],
|
||||
[{url: url2, resultingClientIdTag: 'x'}],
|
||||
],
|
||||
'x',
|
||||
'Redirect to other-origin in-scope with opaque redirect response which ' +
|
||||
'is passed through Cache.');
|
||||
|
||||
|
@ -472,7 +811,8 @@ url = SCOPE1 + 'sw=manualThroughCache&noLocationRedirect';
|
|||
redirect_test(
|
||||
url,
|
||||
url,
|
||||
[[{url}], [], []],
|
||||
[[{url, resultingClientIdTag: 'x'}], [], []],
|
||||
'x',
|
||||
'No location redirect response via Cache.');
|
||||
|
||||
// Clean up the test environment. This promise_test() needs to be the last one.
|
||||
|
|
|
@ -44,6 +44,20 @@ function get_request_infos(worker) {
|
|||
});
|
||||
}
|
||||
|
||||
function get_clients(worker, actual_ids) {
|
||||
return new Promise(function(resolve) {
|
||||
var channel = new MessageChannel();
|
||||
channel.port1.onmessage = (msg) => {
|
||||
resolve(msg.data.clients);
|
||||
};
|
||||
worker.postMessage({
|
||||
command: 'getClients',
|
||||
actual_ids,
|
||||
port: channel.port2
|
||||
}, [channel.port2]);
|
||||
});
|
||||
}
|
||||
|
||||
window.addEventListener('message', on_message, false);
|
||||
|
||||
function on_message(e) {
|
||||
|
@ -59,6 +73,11 @@ function on_message(e) {
|
|||
.then(function(data) {
|
||||
send_result(e.data.id, data);
|
||||
});
|
||||
} else if (command == 'get_clients') {
|
||||
get_clients(worker, e.data.message.actual_ids)
|
||||
.then(function(data) {
|
||||
send_result(e.data.id, data);
|
||||
});
|
||||
} else if (command == 'unregister') {
|
||||
registration.unregister()
|
||||
.then(function() {
|
||||
|
|
|
@ -5,6 +5,13 @@ 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);
|
||||
|
@ -15,8 +22,11 @@ async function getRequestInfos(event) {
|
|||
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);
|
||||
|
@ -24,13 +34,50 @@ async function getRequestInfos(event) {
|
|||
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;
|
||||
}
|
||||
|
||||
// TODO(falken): Add a getClientInfos command to test Clients API.
|
||||
if (event.data.command == 'getClients') {
|
||||
event.waitUntil(getClients(event));
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
function get_query_params(url) {
|
||||
|
@ -49,7 +96,11 @@ function get_query_params(url) {
|
|||
|
||||
self.addEventListener('fetch', function(event) {
|
||||
var waitUntilPromise = caches.open(cacheName).then(function(cache) {
|
||||
return cache.put(event.request, new Response());
|
||||
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);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue