tor-browser

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

redirects.html (4786B)


      1 <!doctype html>
      2 <title>TextFragment invoked on redirects</title>
      3 <meta charset=utf-8>
      4 <meta name="timeout" content="long">
      5 <link rel="help" href="https://wicg.github.io/ScrollToTextFragment/">
      6 <script src="/resources/testharness.js"></script>
      7 <script src="/resources/testharnessreport.js"></script>
      8 <script src="/resources/testdriver.js"></script>
      9 <script src="/resources/testdriver-vendor.js"></script>
     10 <script src="/common/get-host-info.sub.js"></script>
     11 <script src="/common/utils.js"></script>
     12 <script src="stash.js"></script>
     13 
     14 <!--See comment in scroll-to-text-fragment.html for why these tests have the
     15 structure they do. -->
     16 <script>
     17 // This test ensure correct operation of text-fragments through both HTTP and
     18 // client side redirects in various scenarios.
     19 
     20 // Constructs a URL to either redirect.py or the local client-redirect.html;
     21 // which will cause an HTTP or client based redirect, respectively, to
     22 // |to_url|. |type| provides a numeric 30x code to specify an HTTP redirect,
     23 // "location" for a write to window.location, or "meta" for a <meta> refresh.
     24 function buildRedirectUrl(to_url, type) {
     25  let dest = "";
     26  to_url = encodeURIComponent(to_url);
     27 
     28  if (typeof type == "number") {
     29    // If the type is a number, it's an HTTP response code, use redirect.py to
     30    // respond with an HTTP redirect.
     31    const code = type;
     32    dest = `${get_host_info().ORIGIN}/common/redirect.py?status=${code}&location=${to_url}`;
     33  } else if (type == 'meta' || type == 'location') {
     34    // Otherwise we're requesting a client-side redirect, either a <meta> tag
     35    // or window.location. Use the client-redirect file to bounce to the
     36    // destination.
     37    dest = `client-redirect.html?${type}&${to_url}`;
     38  }
     39  return dest;
     40 }
     41 
     42 // Turns |path| from a relative-to-this-file path into a full URL.
     43 function relativePathToFull(path) {
     44  const pathname = window.location.toString();
     45  const base_path = pathname.substring(0, pathname.lastIndexOf('/') + 1);
     46  return base_path + path;
     47 }
     48 
     49 const status_codes = [301, 302, 303, 307, 308];
     50 
     51 // Test that an HTTP redirect to a URL with a text fragment invokes the
     52 // fragment.
     53 for (let code of status_codes) {
     54  promise_test(t => new Promise((resolve, reject) => {
     55    let key = token();
     56 
     57    const abs_url = relativePathToFull(`redirects-target.html?key=${key}#:~:text=target`);
     58    const url = buildRedirectUrl(abs_url, code);
     59 
     60    test_driver.bless('Open a URL with a text fragment directive', () => {
     61      window.open(url, '_blank', 'noopener');
     62    });
     63 
     64    fetchResults(key, resolve, reject);
     65  }).then(data => {
     66    assert_equals(data.scrolled, true);
     67  }), `Text fragment works from HTTP ${code} redirect.`);
     68 }
     69 
     70 // Test that a URL with a text fragment that causes an HTTP redirect preserves
     71 // the fragment and invokes it on the destination page.
     72 for (let code of status_codes) {
     73  promise_test(t => new Promise((resolve, reject) => {
     74    let key = token();
     75 
     76    const abs_url = relativePathToFull(`redirects-target.html?key=${key}`);
     77    const url = buildRedirectUrl(abs_url, code) + "#:~:text=target";
     78 
     79    test_driver.bless('Open a URL with a text fragment directive', () => {
     80      window.open(url, '_blank', 'noopener');
     81    });
     82 
     83    fetchResults(key, resolve, reject);
     84  }).then(data => {
     85    assert_equals(data.scrolled, true);
     86  }), `Text fragment propagated through HTTP ${code} redirect.`);
     87 }
     88 
     89 // Test that client-side redirects (using script) to a URL with a text fragment
     90 // cause the text fragment to be invoked.
     91 for (let type of ['location', 'meta']) {
     92  promise_test(t => new Promise((resolve, reject) => {
     93    let key = token();
     94 
     95    const to_url = `redirects-target.html?key=${key}#:~:text=target`
     96    const url = buildRedirectUrl(to_url, type);
     97 
     98    test_driver.bless('Open a URL with a text fragment directive', () => {
     99      window.open(url, '_blank', 'noopener');
    100    });
    101 
    102    fetchResults(key, resolve, reject);
    103  }).then(data => {
    104    assert_equals(data.scrolled, true);
    105  }), `Text fragment works on client-side ${type} redirect.`);
    106 }
    107 
    108 // Test that client-side redirects (using script) to a URL with a text fragment
    109 // cause the text fragment to be invoked only the first time. A further
    110 // redirect without a user gesture is blocked.
    111 for (let type of ['location', 'meta']) {
    112  promise_test(t => new Promise((resolve, reject) => {
    113    let key = token();
    114 
    115    const to_url = `redirects-target.html?twice&key=${key}#:~:text=target`
    116    const url = buildRedirectUrl(to_url, type);
    117 
    118    test_driver.bless('Open a URL with a text fragment directive', () => {
    119      window.open(url, '_blank', 'noopener');
    120    });
    121 
    122    fetchResults(key, resolve, reject);
    123  }).then(data => {
    124    assert_equals(data.scrolled, false);
    125  }), `One text fragment per user gesture allowed in client-side ${type} redirect.`);
    126 }
    127 </script>