tor-browser

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

storage-events.html (3626B)


      1 <!DOCTYPE HTML>
      2 <meta name="timeout" content="long">
      3 <script src="/resources/testharness.js"></script>
      4 <script src="/resources/testharnessreport.js"></script>
      5 <script src="/common/utils.js"></script>
      6 <script src="/common/dispatcher/dispatcher.js"></script>
      7 <script src="resources/helper.sub.js"></script>
      8 <script>
      9 // When localStorage (`key1`) is modified when a page (`pageA`) is in BFCache,
     10 // storage events should not be fired for the page after becoming active.
     11 // https://github.com/whatwg/storage/issues/119#issuecomment-1115844532
     12 promise_test(async t => {
     13  const pageA = new RemoteContext(token());
     14  const pageB = new RemoteContext(token());
     15  const pageC = new RemoteContext(token());
     16 
     17  const urlA = executorPath + pageA.context_id + '&events=pagehide,pageshow,load';
     18  const urlB = originCrossSite + executorPath + pageB.context_id;
     19  const urlC = executorPath + pageC.context_id + '&events=pagehide,pageshow,load';
     20 
     21  // localStorage key to set while pageA is in BFCache.
     22  const key1 = token();
     23  // localStorage key to set after pageA is restored from BFCache.
     24  const key2 = token();
     25 
     26  const startRecordingStorageEvent = (key1, key2) => {
     27    window.key1EventFired = new Promise(resolve => {
     28      window.addEventListener('storage', e => {
     29        if (e.key === key1) {
     30          recordEvent('storage1');
     31          resolve();
     32        }
     33      });
     34    });
     35    window.key2EventFired = new Promise(resolve => {
     36      window.addEventListener('storage', e => {
     37        if (e.key === key2) {
     38          recordEvent('storage2');
     39          resolve();
     40        }
     41      });
     42    });
     43  };
     44 
     45  window.open(urlA, '_blank', 'noopener');
     46  await pageA.execute_script(waitForPageShow);
     47  await pageA.execute_script(startRecordingStorageEvent, [key1, key2]);
     48 
     49  // Window C is an unrelated window kept open without navigation, to confirm
     50  // that storage events are fired as expected in non-BFCache-related scenario
     51  // and not blocked due to non-BFCache-related reasons.
     52  window.open(urlC, '_blank');
     53  await pageC.execute_script(waitForPageShow);
     54  await pageC.execute_script(startRecordingStorageEvent, [key1, key2]);
     55 
     56  // Navigate A to B.
     57  await pageA.execute_script((url) => {
     58    prepareNavigation(() => {
     59      location.href = url;
     60    });
     61  }, [urlB]);
     62  await pageB.execute_script(waitForPageShow);
     63 
     64  // Update `key1` while pageA is in BFCache.
     65  localStorage.setItem(key1, 'value');
     66 
     67  // Wait for a storage event is fired on PageC and a while,
     68  // to prevent race conditions between event processing
     69  // triggered by `setItem()` and the following operations.
     70  await pageC.execute_script(() => window.key1EventFired);
     71  await new Promise(resolve => t.step_timeout(resolve, 1000));
     72 
     73  // Back navigate to pageA, to be restored from BFCache.
     74  await pageB.execute_script(
     75    () => {
     76      prepareNavigation(() => { history.back(); });
     77    }
     78  );
     79  await pageA.execute_script(waitForPageShow);
     80  await assert_bfcached(pageA);
     81 
     82  // Update `key2` after pageA is restored from BFCache.
     83  localStorage.setItem(key2, 'value');
     84 
     85  // Wait for a storage event for `key2` is fired on PageA.
     86  await pageA.execute_script(() => window.key2EventFired);
     87 
     88  // Confirm that a storage event for `key1` is not fired on PageA.
     89  assert_array_equals(
     90    await pageA.execute_script(() => getRecordedEvents()),
     91    [
     92      'window.load',
     93      'window.pageshow',
     94      'window.pagehide.persisted',
     95      'window.pageshow.persisted',
     96      'storage2',
     97    ],
     98    'pageA should not receive storage events for updates while in BFCache');
     99 
    100 }, 'Storage events should not be fired for BFCached pages after becoming active');
    101 </script>