1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
|
<!DOCTYPE html>
<title>Service Worker: Navigate a Window</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/get-host-info.sub.js"></script>
<script src="resources/test-helpers.sub.js"></script>
<body>
<script>
var host_info = get_host_info();
var BASE_URL = host_info['HTTPS_ORIGIN'] + base_path();
function wait_for_message(msg) {
return new Promise(function(resolve, reject) {
window.addEventListener('message', function onMsg(evt) {
if (evt.data.type === msg) {
resolve();
}
});
});
}
function with_window(url) {
var win = window.open(url);
return wait_for_message('LOADED').then(_ => win);
}
function navigate_window(win, url) {
win.location = url;
return wait_for_message('LOADED').then(_ => win);
}
function reload_window(win) {
win.location.reload();
return wait_for_message('LOADED').then(_ => win);
}
function go_back(win) {
win.history.back();
return wait_for_message('PAGESHOW').then(_ => win);
}
function go_forward(win) {
win.history.forward();
return wait_for_message('PAGESHOW').then(_ => win);
}
function get_clients(win, sw, opts) {
return new Promise((resolve, reject) => {
win.navigator.serviceWorker.addEventListener('message', function onMsg(evt) {
win.navigator.serviceWorker.removeEventListener('message', onMsg);
if (evt.data.type === 'success') {
resolve(evt.data.detail);
} else {
reject(evt.data.detail);
}
});
sw.postMessage({ type: 'GET_CLIENTS', opts: (opts || {}) });
});
}
function validate_window(win, url, opts) {
return win.navigator.serviceWorker.getRegistration(url)
.then(reg => {
// In order to compare service worker instances we need to
// make sure the DOM object is owned by the same global; the
// opened window in this case.
assert_equals(win.navigator.serviceWorker.controller, reg.active,
'window should be controlled by service worker');
return get_clients(win, reg.active, opts);
})
.then(resultList => {
// We should always see our controlled window.
var expected = [
{ url: url, frameType: 'auxiliary' }
];
// If we are including uncontrolled windows, then we might see the
// test window itself and the test harness.
if (opts.includeUncontrolled) {
expected.push({ url: BASE_URL + 'navigate-window.https.html',
frameType: 'auxiliary' });
expected.push({ url: host_info['HTTPS_ORIGIN'] + '/testharness_runner.html',
frameType: 'top-level' });
}
assert_equals(resultList.length, expected.length,
'expected number of clients');
for (var i = 0; i < resultList.length; ++i) {
assert_equals(resultList[i].url, expected[i].url,
'client should have expected url');
assert_equals(resultList[i].frameType, expected[i].frameType,
' client should have expected frame type');
}
return win;
})
}
promise_test(function(t) {
var worker = BASE_URL + 'resources/navigate-window-worker.js';
var scope = BASE_URL + 'resources/loaded.html?navigate-window-controlled';
var url1 = scope + '&q=1';
var url2 = scope + '&q=2';
return service_worker_unregister_and_register(t, worker, scope)
.then(reg => wait_for_state(t, reg.installing, 'activated') )
.then(___ => with_window(url1))
.then(win => validate_window(win, url1, { includeUncontrolled: false }))
.then(win => navigate_window(win, url2))
.then(win => validate_window(win, url2, { includeUncontrolled: false }))
.then(win => go_back(win))
.then(win => validate_window(win, url1, { includeUncontrolled: false }))
.then(win => go_forward(win))
.then(win => validate_window(win, url2, { includeUncontrolled: false }))
.then(win => reload_window(win))
.then(win => validate_window(win, url2, { includeUncontrolled: false }))
.then(win => win.close())
.catch(unreached_rejection(t))
.then(___ => service_worker_unregister(t, scope))
}, 'Clients.matchAll() should not show an old window as controlled after ' +
'it navigates.');
promise_test(function(t) {
var worker = BASE_URL + 'resources/navigate-window-worker.js';
var scope = BASE_URL + 'resources/loaded.html?navigate-window-uncontrolled';
var url1 = scope + '&q=1';
var url2 = scope + '&q=2';
return service_worker_unregister_and_register(t, worker, scope)
.then(reg => wait_for_state(t, reg.installing, 'activated') )
.then(___ => with_window(url1))
.then(win => validate_window(win, url1, { includeUncontrolled: true }))
.then(win => navigate_window(win, url2))
.then(win => validate_window(win, url2, { includeUncontrolled: true }))
.then(win => go_back(win))
.then(win => validate_window(win, url1, { includeUncontrolled: true }))
.then(win => go_forward(win))
.then(win => validate_window(win, url2, { includeUncontrolled: true }))
.then(win => reload_window(win))
.then(win => validate_window(win, url2, { includeUncontrolled: true }))
.then(win => win.close())
.catch(unreached_rejection(t))
.then(___ => service_worker_unregister(t, scope))
}, 'Clients.matchAll() should not show an old window after it navigates.');
</script>
</body>
|