| <!DOCTYPE html> |
| <meta charset="utf-8"> |
| <title>NavigationPreloadManager.getState</title> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <script src="../resources/test-helpers.sub.js"></script> |
| <script src="resources/helpers.js"></script> |
| <body> |
| <script> |
| function post_and_wait_for_reply(worker, message) { |
| return new Promise(resolve => { |
| navigator.serviceWorker.onmessage = e => { resolve(e.data); }; |
| worker.postMessage(message); |
| }); |
| } |
| |
| promise_test(t => { |
| const scope = '../resources/get-state'; |
| const script = '../resources/empty-worker.js'; |
| var np; |
| |
| return service_worker_unregister_and_register(t, script, scope) |
| .then(r => { |
| np = r.navigationPreload; |
| add_completion_callback(() => r.unregister()); |
| return wait_for_state(t, r.installing, 'activated'); |
| }) |
| .then(() => np.getState()) |
| .then(state => { |
| expect_navigation_preload_state(state, false, 'true', 'default state'); |
| return np.enable(); |
| }) |
| .then(result => { |
| assert_equals(result, undefined, |
| 'enable() should resolve to undefined'); |
| return np.getState(); |
| }) |
| .then(state => { |
| expect_navigation_preload_state(state, true, 'true', |
| 'state after enable()'); |
| return np.disable(); |
| }) |
| .then(result => { |
| assert_equals(result, undefined, |
| 'disable() should resolve to undefined'); |
| return np.getState(); |
| }) |
| .then(state => { |
| expect_navigation_preload_state(state, false, 'true', |
| 'state after disable()'); |
| return np.setHeaderValue('dreams that cannot be'); |
| }) |
| .then(result => { |
| assert_equals(result, undefined, |
| 'setHeaderValue() should resolve to undefined'); |
| return np.getState(); |
| }) |
| .then(state => { |
| expect_navigation_preload_state(state, false, 'dreams that cannot be', |
| 'state after setHeaderValue()'); |
| return np.setHeaderValue('').then(() => np.getState()); |
| }) |
| .then(state => { |
| expect_navigation_preload_state(state, false, '', |
| 'after setHeaderValue to empty string'); |
| return np.setHeaderValue(null).then(() => np.getState()); |
| }) |
| .then(state => { |
| expect_navigation_preload_state(state, false, 'null', |
| 'after setHeaderValue to null'); |
| return promise_rejects_js(t, |
| TypeError, |
| np.setHeaderValue('what\uDC00\uD800this'), |
| 'setHeaderValue() should throw if passed surrogates'); |
| }) |
| .then(() => { |
| return promise_rejects_js(t, |
| TypeError, |
| np.setHeaderValue('zer\0o'), |
| 'setHeaderValue() should throw if passed \\0'); |
| }) |
| .then(() => { |
| return promise_rejects_js(t, |
| TypeError, |
| np.setHeaderValue('\rcarriage'), |
| 'setHeaderValue() should throw if passed \\r'); |
| }) |
| .then(() => { |
| return promise_rejects_js(t, |
| TypeError, |
| np.setHeaderValue('newline\n'), |
| 'setHeaderValue() should throw if passed \\n'); |
| }) |
| .then(() => { |
| return promise_rejects_js(t, |
| TypeError, |
| np.setHeaderValue(), |
| 'setHeaderValue() should throw if passed undefined'); |
| }) |
| .then(() => np.enable().then(() => np.getState())) |
| .then(state => { |
| expect_navigation_preload_state(state, true, 'null', |
| 'enable() should not change header'); |
| }); |
| }, 'getState'); |
| |
| // This test sends commands to a worker to call enable()/disable()/getState(). |
| // It checks the results from the worker and verifies that they match the |
| // navigation preload state accessible from the page. |
| promise_test(t => { |
| const scope = 'resources/get-state-worker'; |
| const script = 'resources/get-state-worker.js'; |
| var worker; |
| var registration; |
| |
| return service_worker_unregister_and_register(t, script, scope) |
| .then(r => { |
| registration = r; |
| add_completion_callback(() => registration.unregister()); |
| worker = registration.installing; |
| return wait_for_state(t, worker, 'activated'); |
| }) |
| .then(() => { |
| // Call getState(). |
| return post_and_wait_for_reply(worker, 'getState'); |
| }) |
| .then(data => { |
| return Promise.all([data, registration.navigationPreload.getState()]); |
| }) |
| .then(states => { |
| expect_navigation_preload_state(states[0], false, 'true', |
| 'default state (from worker)'); |
| expect_navigation_preload_state(states[1], false, 'true', |
| 'default state (from page)'); |
| // Call enable() and then getState(). |
| return post_and_wait_for_reply(worker, 'enable'); |
| }) |
| .then(data => { |
| assert_equals(data, undefined, 'enable() should resolve to undefined'); |
| return Promise.all([ |
| post_and_wait_for_reply(worker, 'getState'), |
| registration.navigationPreload.getState() |
| ]); |
| }) |
| .then(states => { |
| expect_navigation_preload_state(states[0], true, 'true', |
| 'state after enable() (from worker)'); |
| expect_navigation_preload_state(states[1], true, 'true', |
| 'state after enable() (from page)'); |
| // Call disable() and then getState(). |
| return post_and_wait_for_reply(worker, 'disable'); |
| }) |
| .then(data => { |
| assert_equals(data, undefined, |
| '.disable() should resolve to undefined'); |
| return Promise.all([ |
| post_and_wait_for_reply(worker, 'getState'), |
| registration.navigationPreload.getState() |
| ]); |
| }) |
| .then(states => { |
| expect_navigation_preload_state(states[0], false, 'true', |
| 'state after disable() (from worker)'); |
| expect_navigation_preload_state(states[1], false, 'true', |
| 'state after disable() (from page)'); |
| return post_and_wait_for_reply(worker, 'setHeaderValue'); |
| }) |
| .then(data => { |
| assert_equals(data, undefined, |
| '.setHeaderValue() should resolve to undefined'); |
| return Promise.all([ |
| post_and_wait_for_reply(worker, 'getState'), |
| registration.navigationPreload.getState()]); |
| }) |
| .then(states => { |
| expect_navigation_preload_state( |
| states[0], false, 'insightful', |
| 'state after setHeaderValue() (from worker)'); |
| expect_navigation_preload_state( |
| states[1], false, 'insightful', |
| 'state after setHeaderValue() (from page)'); |
| }); |
| }, 'getState from a worker'); |
| |
| // This tests navigation preload API when there is no active worker. It calls |
| // the API from the main page and then from the worker itself. |
| promise_test(t => { |
| const scope = 'resources/wait-for-activate-worker'; |
| const script = 'resources/wait-for-activate-worker.js'; |
| var registration; |
| var np; |
| return service_worker_unregister_and_register(t, script, scope) |
| .then(r => { |
| registration = r; |
| np = registration.navigationPreload; |
| add_completion_callback(() => registration.unregister()); |
| return Promise.all([ |
| promise_rejects_dom( |
| t, 'InvalidStateError', np.enable(), |
| 'enable should reject if there is no active worker'), |
| promise_rejects_dom( |
| t, 'InvalidStateError', np.disable(), |
| 'disable should reject if there is no active worker'), |
| promise_rejects_dom( |
| t, 'InvalidStateError', np.setHeaderValue('umm'), |
| 'setHeaderValue should reject if there is no active worker')]); |
| }) |
| .then(() => np.getState()) |
| .then(state => { |
| expect_navigation_preload_state(state, false, 'true', |
| 'state before activation'); |
| return post_and_wait_for_reply(registration.installing, 'ping'); |
| }) |
| .then(result => assert_equals(result, 'PASS')); |
| }, 'no active worker'); |
| </script> |
| </body> |