| <!doctype html> |
| <meta charset=utf-8> |
| <title>Use Clear-Site-Data to immediately unregister service workers</title> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <script src="resources/test-helpers.sub.js"></script> |
| <script src="resources/unregister-immediately-helpers.js"></script> |
| <body> |
| <script> |
| 'use strict'; |
| |
| // These tests use the Clear-Site-Data network response header to immediately |
| // unregister a service worker registration with a worker whose state is |
| // 'installed', 'waiting', 'activating' or 'activated'. Immediately |
| // unregistering runs the "Clear Registration" algorithm without waiting for the |
| // active worker's controlled clients to unload. |
| |
| promise_test(async test => { |
| // This test keeps the the service worker in the 'activating' state by using a |
| // script with an activate event waitUntil() promise that never resolves. |
| const script_url = 'resources/onactivate-waituntil-forever.js'; |
| const scope_url = |
| 'resources/scope-for-unregister-immediately-with-waiting-worker'; |
| |
| const registration = await service_worker_unregister_and_register( |
| test, script_url, scope_url); |
| const service_worker = registration.installing; |
| |
| await wait_for_state(test, service_worker, 'activating'); |
| |
| // Clear-Site-Data must cause activation to fail. |
| await Promise.all([ |
| clear_site_data(), |
| wait_for_state(test, service_worker, 'redundant')]); |
| |
| await assert_no_registrations_exist(); |
| }, 'Clear-Site-Data must unregister a registration with a worker ' |
| + 'in the "activating" state.'); |
| |
| promise_test(async test => { |
| // Create an registration with two service workers: one activated and one |
| // installed. |
| const script_url = 'resources/update_shell.py'; |
| const scope_url = |
| 'resources/scope-for-unregister-immediately-with-with-update'; |
| |
| const registration = await service_worker_unregister_and_register( |
| test, script_url, scope_url); |
| const first_service_worker = registration.installing; |
| |
| await wait_for_state(test, first_service_worker, 'activated'); |
| registration.update(); |
| |
| const event_watcher = new EventWatcher(test, registration, 'updatefound'); |
| await event_watcher.wait_for('updatefound'); |
| |
| const second_service_worker = registration.installing; |
| await wait_for_state(test, second_service_worker, 'installed'); |
| |
| // Clear-Site-Data must clear both workers from the registration. |
| await Promise.all([ |
| clear_site_data(), |
| wait_for_state(test, first_service_worker, 'redundant'), |
| wait_for_state(test, second_service_worker, 'redundant')]); |
| |
| await assert_no_registrations_exist(); |
| }, 'Clear-Site-Data must unregister an activated registration with ' |
| + 'an update waiting.'); |
| |
| promise_test(async test => { |
| const script_url = 'resources/empty.js'; |
| const scope_url = |
| 'resources/blank.html?unregister-immediately-with-controlled-client'; |
| |
| const registration = await service_worker_unregister_and_register( |
| test, script_url, scope_url); |
| const service_worker = registration.installing; |
| |
| await wait_for_state(test, service_worker, 'activated'); |
| const frame = await add_controlled_iframe(test, scope_url); |
| const frame_registration = |
| await frame.contentWindow.navigator.serviceWorker.ready; |
| |
| const event_watcher = new EventWatcher( |
| test, frame.contentWindow.navigator.serviceWorker, 'controllerchange'); |
| |
| // Clear-Site-Data must remove the iframe's controller. |
| await Promise.all([ |
| clear_site_data(), |
| event_watcher.wait_for('controllerchange'), |
| wait_for_state(test, service_worker, 'redundant')]); |
| |
| assert_equals(frame.contentWindow.navigator.serviceWorker.controller, null); |
| await assert_no_registrations_exist(); |
| |
| // The ready promise must continue to resolve with the unregistered |
| // registration. |
| assert_equals(frame_registration, |
| await frame.contentWindow.navigator.serviceWorker.ready); |
| }, 'Clear-Site-Data must unregister an activated registration with controlled ' |
| + 'clients.'); |
| |
| promise_test(async test => { |
| const script_url = 'resources/empty.js'; |
| const scope_url = |
| 'resources/blank.html?unregister-immediately-while-waiting-to-clear'; |
| |
| const registration = await service_worker_unregister_and_register( |
| test, script_url, scope_url); |
| const service_worker = registration.installing; |
| |
| await wait_for_state(test, service_worker, 'activated'); |
| const frame = await add_controlled_iframe(test, scope_url); |
| |
| const event_watcher = new EventWatcher( |
| test, frame.contentWindow.navigator.serviceWorker, 'controllerchange'); |
| |
| // Unregister waits to clear the registration until no controlled clients |
| // exist. |
| await registration.unregister(); |
| |
| // Clear-Site-Data must clear the unregistered registration immediately. |
| await Promise.all([ |
| clear_site_data(), |
| event_watcher.wait_for('controllerchange'), |
| wait_for_state(test, service_worker, 'redundant')]); |
| |
| assert_equals(frame.contentWindow.navigator.serviceWorker.controller, null); |
| await assert_no_registrations_exist(); |
| }, 'Clear-Site-Data must clear an unregistered registration waiting for ' |
| + ' controlled clients to unload.'); |
| |
| </script> |
| </body> |