tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ready.https.window.js (8159B)


      1 // META: title=Service Worker: navigator.serviceWorker.ready
      2 // META: script=resources/test-helpers.sub.js
      3 
      4 test(() => {
      5  assert_equals(
      6    navigator.serviceWorker.ready,
      7    navigator.serviceWorker.ready,
      8    'repeated access to ready without intervening registrations should return the same Promise object'
      9  );
     10 }, 'ready returns the same Promise object');
     11 
     12 promise_test(async t => {
     13  const frame = await with_iframe('resources/blank.html?uncontrolled');
     14  t.add_cleanup(() => frame.remove());
     15 
     16  const promise = frame.contentWindow.navigator.serviceWorker.ready;
     17 
     18  assert_equals(
     19    Object.getPrototypeOf(promise),
     20    frame.contentWindow.Promise.prototype,
     21    'the Promise should be in the context of the related document'
     22  );
     23 }, 'ready returns a Promise object in the context of the related document');
     24 
     25 promise_test(async t => {
     26  const url = 'resources/empty-worker.js';
     27  const scope = 'resources/blank.html?ready-controlled';
     28  const expectedURL = normalizeURL(url);
     29  const registration = await service_worker_unregister_and_register(t, url, scope);
     30  t.add_cleanup(() => registration.unregister());
     31 
     32  await wait_for_state(t, registration.installing, 'activated');
     33 
     34  const frame = await with_iframe(scope);
     35  t.add_cleanup(() => frame.remove());
     36 
     37  const readyReg = await frame.contentWindow.navigator.serviceWorker.ready;
     38 
     39  assert_equals(readyReg.installing, null, 'installing should be null');
     40  assert_equals(readyReg.waiting, null, 'waiting should be null');
     41  assert_equals(readyReg.active.scriptURL, expectedURL, 'active after ready should not be null');
     42  assert_equals(
     43    frame.contentWindow.navigator.serviceWorker.controller,
     44    readyReg.active,
     45    'the controller should be the active worker'
     46  );
     47  assert_in_array(
     48    readyReg.active.state,
     49    ['activating', 'activated'],
     50    '.ready should be resolved when the registration has an active worker'
     51  );
     52 }, 'ready on a controlled document');
     53 
     54 promise_test(async t => {
     55  const url = 'resources/empty-worker.js';
     56  const scope = 'resources/blank.html?ready-potential-controlled';
     57  const expected_url = normalizeURL(url);
     58  const frame = await with_iframe(scope);
     59  t.add_cleanup(() => frame.remove());
     60 
     61  const registration = await navigator.serviceWorker.register(url, { scope });
     62  t.add_cleanup(() => registration.unregister());
     63 
     64  const readyReg = await frame.contentWindow.navigator.serviceWorker.ready;
     65 
     66  assert_equals(readyReg.installing, null, 'installing should be null');
     67  assert_equals(readyReg.waiting, null, 'waiting should be null.')
     68  assert_equals(readyReg.active.scriptURL, expected_url, 'active after ready should not be null');
     69  assert_in_array(
     70    readyReg.active.state,
     71    ['activating', 'activated'],
     72    '.ready should be resolved when the registration has an active worker'
     73  );
     74  assert_equals(
     75    frame.contentWindow.navigator.serviceWorker.controller,
     76    null,
     77    'uncontrolled document should not have a controller'
     78  );
     79 }, 'ready on a potential controlled document');
     80 
     81 promise_test(async t => {
     82  const url = 'resources/empty-worker.js';
     83  const scope = 'resources/blank.html?ready-installing';
     84 
     85  await service_worker_unregister(t, scope);
     86 
     87  const frame = await with_iframe(scope);
     88  const promise = frame.contentWindow.navigator.serviceWorker.ready;
     89  navigator.serviceWorker.register(url, { scope });
     90  const registration = await promise;
     91 
     92  t.add_cleanup(async () => {
     93    await registration.unregister();
     94    frame.remove();
     95  });
     96 
     97  assert_equals(registration.installing, null, 'installing should be null');
     98  assert_equals(registration.waiting, null, 'waiting should be null');
     99  assert_not_equals(registration.active, null, 'active after ready should not be null');
    100  assert_in_array(
    101    registration.active.state,
    102    ['activating', 'activated'],
    103    '.ready should be resolved when the registration has an active worker'
    104  );
    105 }, 'ready on an iframe whose parent registers a new service worker');
    106 
    107 promise_test(async t => {
    108  const scope = 'resources/register-iframe.html';
    109  const frame = await with_iframe(scope);
    110 
    111  const registration = await frame.contentWindow.navigator.serviceWorker.ready;
    112 
    113  t.add_cleanup(async () => {
    114    await registration.unregister();
    115    frame.remove();
    116  });
    117 
    118  assert_equals(registration.installing, null, 'installing should be null');
    119  assert_equals(registration.waiting, null, 'waiting should be null');
    120  assert_not_equals(registration.active, null, 'active after ready should not be null');
    121  assert_in_array(
    122    registration.active.state,
    123    ['activating', 'activated'],
    124    '.ready should be resolved with "active worker"'
    125  );
    126 }, 'ready on an iframe that installs a new service worker');
    127 
    128 promise_test(async t => {
    129  const url = 'resources/empty-worker.js';
    130  const matchedScope = 'resources/blank.html?ready-after-match';
    131  const longerMatchedScope = 'resources/blank.html?ready-after-match-longer';
    132 
    133  await service_worker_unregister(t, matchedScope);
    134  await service_worker_unregister(t, longerMatchedScope);
    135 
    136  const frame = await with_iframe(longerMatchedScope);
    137  const registration = await navigator.serviceWorker.register(url, { scope: matchedScope });
    138 
    139  t.add_cleanup(async () => {
    140    await registration.unregister();
    141    frame.remove();
    142  });
    143 
    144  await wait_for_state(t, registration.installing, 'activated');
    145 
    146  const longerRegistration = await navigator.serviceWorker.register(url, { scope: longerMatchedScope });
    147 
    148  t.add_cleanup(() => longerRegistration.unregister());
    149 
    150  const readyReg = await frame.contentWindow.navigator.serviceWorker.ready;
    151 
    152  assert_equals(
    153    readyReg.scope,
    154    normalizeURL(longerMatchedScope),
    155    'longer matched registration should be returned'
    156  );
    157  assert_equals(
    158    frame.contentWindow.navigator.serviceWorker.controller,
    159    null,
    160    'controller should be null'
    161  );
    162 }, 'ready after a longer matched registration registered');
    163 
    164 promise_test(async t => {
    165  const url = 'resources/empty-worker.js';
    166  const matchedScope = 'resources/blank.html?ready-after-resolve';
    167  const longerMatchedScope = 'resources/blank.html?ready-after-resolve-longer';
    168  const registration = await service_worker_unregister_and_register(t, url, matchedScope);
    169  t.add_cleanup(() => registration.unregister());
    170 
    171  await wait_for_state(t, registration.installing, 'activated');
    172 
    173  const frame = await with_iframe(longerMatchedScope);
    174  t.add_cleanup(() => frame.remove());
    175 
    176  const readyReg1 = await frame.contentWindow.navigator.serviceWorker.ready;
    177 
    178  assert_equals(
    179    readyReg1.scope,
    180    normalizeURL(matchedScope),
    181    'matched registration should be returned'
    182  );
    183 
    184  const longerReg = await navigator.serviceWorker.register(url, { scope: longerMatchedScope });
    185  t.add_cleanup(() => longerReg.unregister());
    186 
    187  const readyReg2 = await frame.contentWindow.navigator.serviceWorker.ready;
    188 
    189  assert_equals(
    190    readyReg2.scope,
    191    normalizeURL(matchedScope),
    192    'ready should only be resolved once'
    193  );
    194 }, 'access ready after it has been resolved');
    195 
    196 promise_test(async t => {
    197  const url1 = 'resources/empty-worker.js';
    198  const url2 = url1 + '?2';
    199  const matchedScope = 'resources/blank.html?ready-after-unregister';
    200  const reg1 = await service_worker_unregister_and_register(t, url1, matchedScope);
    201  t.add_cleanup(() => reg1.unregister());
    202 
    203  await wait_for_state(t, reg1.installing, 'activating');
    204 
    205  const frame = await with_iframe(matchedScope);
    206  t.add_cleanup(() => frame.remove());
    207 
    208  await reg1.unregister();
    209 
    210  // Ready promise should be pending, waiting for a new registration to arrive
    211  const readyPromise = frame.contentWindow.navigator.serviceWorker.ready;
    212 
    213  const reg2 = await navigator.serviceWorker.register(url2, { scope: matchedScope });
    214  t.add_cleanup(() => reg2.unregister());
    215 
    216  const readyReg = await readyPromise;
    217 
    218  // Wait for registration update, since it comes from another global, the states are racy.
    219  await wait_for_state(t, reg2.installing || reg2.waiting || reg2.active, 'activated');
    220 
    221  assert_equals(readyReg.active.scriptURL, reg2.active.scriptURL, 'Resolves with the second registration');
    222  assert_not_equals(reg1, reg2, 'Registrations should be different');
    223 }, 'resolve ready after unregistering');