tor-browser

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

test_ext_tabs_executeScript_runAt.html (4313B)


      1 <!DOCTYPE HTML>
      2 <html>
      3 <head>
      4  <meta charset="utf-8">
      5  <title>Tabs executeScript runAt Test</title>
      6  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
      7  <script type="text/javascript" src="/tests/SimpleTest/ExtensionTestUtils.js"></script>
      8  <script type="text/javascript" src="head.js"></script>
      9  <link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
     10 </head>
     11 <body>
     12 
     13 <script type="text/javascript">
     14 "use strict";
     15 
     16 /**
     17 * These tests ensure that the runAt argument to tabs.executeScript delays
     18 * script execution until the document has reached the correct state.
     19 *
     20 * Since tests of this nature are especially race-prone, it relies on a
     21 * server-JS script to delay the completion of our test page's load cycle long
     22 * enough for us to attempt to load our scripts in the earlies phase we support.
     23 *
     24 * And since we can't actually rely on that timing, it retries any attempts that
     25 * fail to load as early as expected, but don't load at any illegal time.
     26 */
     27 
     28 add_task(async function testExecuteScript() {
     29  const win = window.open("about:blank");
     30 
     31  async function background(DEBUG) {
     32    let tab;
     33 
     34    const BASE = "http://mochi.test:8888/tests/mobile/shared/components/extensions/test/mochitest/";
     35    const URL = BASE + "file_slowed_document.sjs";
     36 
     37    const MAX_TRIES = 30;
     38 
     39    const onUpdatedPromise = (tabId, url, status) => {
     40      return new Promise(resolve => {
     41        browser.tabs.onUpdated.addListener(function listener(_, changed, tab) {
     42          if (tabId == tab.id && changed.status == status && tab.url == url) {
     43            browser.tabs.onUpdated.removeListener(listener);
     44            resolve();
     45          }
     46        });
     47      });
     48    };
     49 
     50    try {
     51      [tab] = await browser.tabs.query({active: true, currentWindow: true});
     52 
     53      let success = false;
     54      for (let tries = 0; !success && tries < MAX_TRIES; tries++) {
     55        const url = `${URL}?with-iframe&r=${Math.random()}`;
     56 
     57        const loadingPromise = onUpdatedPromise(tab.id, url, "loading");
     58        const completePromise = onUpdatedPromise(tab.id, url, "complete");
     59 
     60        // TODO: Test allFrames and frameId.
     61 
     62        await browser.tabs.update({url});
     63        await loadingPromise;
     64 
     65        const states = await Promise.all([
     66          // Send the executeScript requests in the reverse order that we expect
     67          // them to execute in, to avoid them passing only because of timing
     68          // races.
     69          browser.tabs.executeScript({
     70            code: "document.readyState",
     71            runAt: "document_idle",
     72          }),
     73          browser.tabs.executeScript({
     74            code: "document.readyState",
     75            runAt: "document_end",
     76          }),
     77          browser.tabs.executeScript({
     78            code: "document.readyState",
     79            runAt: "document_start",
     80          }),
     81        ].reverse());
     82 
     83        browser.test.log(`Got states: ${states}`);
     84 
     85        // Make sure that none of our scripts executed earlier than expected,
     86        // regardless of retries.
     87        browser.test.assertTrue(states[1] == "interactive" || states[1] == "complete",
     88                                `document_end state is valid: ${states[1]}`);
     89        browser.test.assertTrue(states[2] == "interactive" || states[2] == "complete",
     90                                `document_idle state is valid: ${states[2]}`);
     91 
     92        // If we have the earliest valid states for each script, we're done.
     93        // Otherwise, try again.
     94        success = ((states[0] == "loading" || DEBUG) &&
     95                   states[1] == "interactive" &&
     96                   (states[2] == "interactive" || states[2] == "complete"));
     97 
     98        await completePromise;
     99      }
    100 
    101      browser.test.assertTrue(success, "Got the earliest expected states at least once");
    102 
    103      browser.test.notifyPass("executeScript-runAt");
    104    } catch (e) {
    105      browser.test.fail(`Error: ${e} :: ${e.stack}`);
    106      browser.test.notifyFail("executeScript-runAt");
    107    }
    108  }
    109 
    110  const extension = ExtensionTestUtils.loadExtension({
    111    manifest: {
    112      "permissions": ["http://mochi.test/", "tabs"],
    113    },
    114    background: `(${background})(${AppConstants.DEBUG})`,
    115  });
    116 
    117  await extension.startup();
    118 
    119  await extension.awaitFinish("executeScript-runAt");
    120 
    121  await extension.unload();
    122 
    123  win.close();
    124 });
    125 </script>
    126 
    127 </body>
    128 </html>