tor-browser

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

windowclient-navigate.https.html (5471B)


      1 <!DOCTYPE html>
      2 <title>Service Worker: WindowClient.navigate() tests</title>
      3 <meta name="timeout" content="long">
      4 <script src="/resources/testharness.js"></script>
      5 <script src="/resources/testharnessreport.js"></script>
      6 <script src="/common/get-host-info.sub.js"></script>
      7 <script src="resources/test-helpers.sub.js"></script>
      8 <body>
      9 <script>
     10 'use strict';
     11 
     12 const SCOPE = 'resources/blank.html';
     13 const SCRIPT_URL = 'resources/windowclient-navigate-worker.js';
     14 const CROSS_ORIGIN_URL =
     15  get_host_info()['HTTPS_REMOTE_ORIGIN'] + base_path() + 'resources/blank.html';
     16 
     17 navigateTest({
     18  description: 'normal',
     19  destUrl: 'blank.html?navigate',
     20  expected: normalizeURL(SCOPE) + '?navigate',
     21 });
     22 
     23 navigateTest({
     24  description: 'blank url',
     25  destUrl: '',
     26  expected: normalizeURL(SCRIPT_URL)
     27 });
     28 
     29 navigateTest({
     30  description: 'in scope but not controlled test on installing worker',
     31  destUrl: 'blank.html?navigate',
     32  expected: 'TypeError',
     33  waitState: 'installing',
     34 });
     35 
     36 navigateTest({
     37  description: 'in scope but not controlled test on active worker',
     38  destUrl: 'blank.html?navigate',
     39  expected: 'TypeError',
     40  controlled: false,
     41 });
     42 
     43 navigateTest({
     44  description: 'out of scope',
     45  srcUrl: '/common/blank.html',
     46  destUrl: 'blank.html?navigate',
     47  expected: 'TypeError',
     48 });
     49 
     50 navigateTest({
     51  description: 'cross origin url',
     52  destUrl: CROSS_ORIGIN_URL,
     53  expected: null
     54 });
     55 
     56 navigateTest({
     57  description: 'invalid url (http://[example.com])',
     58  destUrl: 'http://[example].com',
     59  expected: 'TypeError'
     60 });
     61 
     62 navigateTest({
     63  description: 'invalid url (view-source://example.com)',
     64  destUrl: 'view-source://example.com',
     65  expected: 'TypeError'
     66 });
     67 
     68 navigateTest({
     69  description: 'invalid url (file:///)',
     70  destUrl: 'file:///',
     71  expected: 'TypeError'
     72 });
     73 
     74 navigateTest({
     75  description: 'invalid url (about:blank)',
     76  destUrl: 'about:blank',
     77  expected: 'TypeError'
     78 });
     79 
     80 navigateTest({
     81  description: 'navigate on a top-level window client',
     82  destUrl: 'blank.html?navigate',
     83  srcUrl: 'resources/loaded.html',
     84  scope: 'resources/loaded.html',
     85  expected: normalizeURL(SCOPE) + '?navigate',
     86  frameType: 'top-level'
     87 });
     88 
     89 async function createFrame(t, parameters) {
     90  if (parameters.frameType === 'top-level') {
     91    // Wait for window.open is completed.
     92    await new Promise(resolve => {
     93      const win = window.open(parameters.srcUrl);
     94      t.add_cleanup(() => win.close());
     95      window.addEventListener('message', (e) => {
     96        if (e.data.type === 'LOADED') {
     97          resolve();
     98        }
     99      });
    100    });
    101  }
    102 
    103  if (parameters.frameType === 'nested') {
    104    const frame = await with_iframe(parameters.srcUrl);
    105    t.add_cleanup(() => frame.remove());
    106  }
    107 }
    108 
    109 function navigateTest(overrideParameters) {
    110  // default parameters
    111  const parameters = {
    112    description: null,
    113    srcUrl: SCOPE,
    114    destUrl: null,
    115    expected: null,
    116    waitState: 'activated',
    117    scope: SCOPE,
    118    controlled: true,
    119    // `frameType` can be 'nested' for an iframe WindowClient or 'top-level' for
    120    // a main frame WindowClient.
    121    frameType: 'nested'
    122  };
    123 
    124  for (const key in overrideParameters)
    125    parameters[key] = overrideParameters[key];
    126 
    127  promise_test(async function(t) {
    128    let pausedLifecyclePort;
    129    let scriptUrl = SCRIPT_URL;
    130 
    131    // For in-scope-but-not-controlled test on installing worker,
    132    // if the waitState is "installing", then append the query to scriptUrl.
    133    if (parameters.waitState === 'installing') {
    134      scriptUrl += '?' + parameters.waitState;
    135 
    136      navigator.serviceWorker.addEventListener('message', (event) => {
    137        if (event.data.port) {
    138          pausedLifecyclePort = event.data.port;
    139        }
    140      });
    141    }
    142 
    143    t.add_cleanup(() => {
    144      // Some tests require that the worker remain in a given lifecycle phase.
    145      // "Clean up" logic for these tests requires signaling the worker to
    146      // release the hold; this allows the worker to be properly discarded
    147      // prior to the execution of additional tests.
    148      if (pausedLifecyclePort) {
    149        // The value of the posted message is inconsequential. A string is
    150        // specified here solely to aid in test debugging.
    151        pausedLifecyclePort.postMessage('continue lifecycle');
    152      }
    153    });
    154 
    155    // Create a frame that is not controlled by a service worker.
    156    if (!parameters.controlled) {
    157      await createFrame(t, parameters);
    158    }
    159 
    160    const registration = await service_worker_unregister_and_register(
    161        t, scriptUrl, parameters.scope);
    162    const serviceWorker = registration.installing;
    163    await wait_for_state(t, serviceWorker, parameters.waitState);
    164    t.add_cleanup(() => registration.unregister());
    165 
    166    // Create a frame after a service worker is registered so that the frmae is
    167    // controlled by an active service worker.
    168    if (parameters.controlled) {
    169      await createFrame(t, parameters);
    170    }
    171 
    172    const response = await new Promise(resolve => {
    173      const channel = new MessageChannel();
    174      channel.port1.onmessage = t.step_func(resolve);
    175      serviceWorker.postMessage({
    176        port: channel.port2,
    177        url: parameters.destUrl,
    178        clientUrl: new URL(parameters.srcUrl, location).toString(),
    179        frameType: parameters.frameType,
    180        expected: parameters.expected,
    181        description: parameters.description,
    182      }, [channel.port2]);
    183    });
    184 
    185    assert_equals(response.data, null);
    186    await fetch_tests_from_worker(serviceWorker);
    187  }, parameters.description);
    188 }
    189 </script>
    190 </body>