tor-browser

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

browser_ext_messaging.js (6698B)


      1 /* Any copyright is dedicated to the Public Domain.
      2   http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 /* eslint-env webextensions */
      5 
      6 "use strict";
      7 
      8 const TEST_URL = "https://example.com/";
      9 
     10 // These allowed rejections are copied from
     11 // browser/components/extensions/test/browser/head.js.
     12 const { PromiseTestUtils } = ChromeUtils.importESModule(
     13  "resource://testing-common/PromiseTestUtils.sys.mjs"
     14 );
     15 PromiseTestUtils.allowMatchingRejectionsGlobally(
     16  /Message manager disconnected/
     17 );
     18 PromiseTestUtils.allowMatchingRejectionsGlobally(
     19  /Receiving end does not exist/
     20 );
     21 
     22 const extension = ExtensionTestUtils.loadExtension({
     23  manifest: {
     24    content_scripts: [
     25      {
     26        matches: [TEST_URL],
     27        js: ["content-script.js"],
     28        run_at: "document_start",
     29      },
     30    ],
     31  },
     32  background() {
     33    let currentPort;
     34 
     35    browser.runtime.onConnect.addListener(port => {
     36      currentPort = port;
     37      port.onDisconnect.addListener(() =>
     38        browser.test.sendMessage("port-disconnected")
     39      );
     40      port.onMessage.addListener(msg =>
     41        browser.test.sendMessage("port-message-received", msg)
     42      );
     43      browser.test.sendMessage("port-connected");
     44    });
     45 
     46    browser.test.onMessage.addListener(async msg => {
     47      if (msg !== "test:port-message-send") {
     48        browser.test.fail(`Unexpected test message received: ${msg}`);
     49      }
     50 
     51      currentPort.postMessage("ping");
     52    });
     53 
     54    browser.test.sendMessage("background:ready");
     55  },
     56  files: {
     57    "content-script.js": function contentScript() {
     58      const port = browser.runtime.connect();
     59      port.onMessage.addListener(msg => port.postMessage(`${msg}-pong`));
     60    },
     61  },
     62 });
     63 
     64 add_task(async function setup_first_test() {
     65  await extension.startup();
     66 
     67  await extension.awaitMessage("background:ready");
     68 });
     69 
     70 addRDMTaskWithPreAndPost(
     71  TEST_URL,
     72  async function pre_task() {
     73    await extension.awaitMessage("port-connected");
     74  },
     75  async function test_port_kept_connected_on_switch_to_RDB() {
     76    extension.sendMessage("test:port-message-send");
     77 
     78    is(
     79      await extension.awaitMessage("port-message-received"),
     80      "ping-pong",
     81      "Got the expected message back from the content script"
     82    );
     83  },
     84  async function post_task() {
     85    extension.sendMessage("test:port-message-send");
     86 
     87    is(
     88      await extension.awaitMessage("port-message-received"),
     89      "ping-pong",
     90      "Got the expected message back from the content script"
     91    );
     92  }
     93 );
     94 
     95 add_task(async function cleanup_first_test() {
     96  await extension.awaitMessage("port-disconnected");
     97 
     98  await extension.unload();
     99 });
    100 
    101 addRDMTask(TEST_URL, async function test_tab_sender() {
    102  const extension2 = ExtensionTestUtils.loadExtension({
    103    manifest: {
    104      permissions: ["tabs"],
    105 
    106      content_scripts: [
    107        {
    108          matches: [TEST_URL],
    109          js: ["content-script.js"],
    110          run_at: "document_start",
    111        },
    112      ],
    113    },
    114 
    115    async background() {
    116      const TEST_URL = "https://example.com/"; // eslint-disable-line no-shadow
    117 
    118      browser.test.log("Background script init");
    119 
    120      let extTab;
    121      const contentMessage = new Promise(resolve => {
    122        browser.test.log("Listen to content");
    123        const listener = async (msg, sender) => {
    124          browser.test.assertEq(
    125            msg,
    126            "hello-from-content",
    127            "Background script got hello-from-content message"
    128          );
    129 
    130          const tabs = await browser.tabs.query({
    131            currentWindow: true,
    132            active: true,
    133          });
    134          browser.test.assertEq(
    135            tabs.length,
    136            1,
    137            "One tab is active in the current window"
    138          );
    139          extTab = tabs[0];
    140          browser.test.log(`Tab: id ${extTab.id}, url ${extTab.url}`);
    141          browser.test.assertEq(extTab.url, TEST_URL, "Tab has the test URL");
    142 
    143          browser.test.assertTrue(!!sender, "Message has a sender");
    144          browser.test.assertTrue(!!sender.tab, "Message has a sender.tab");
    145          browser.test.assertEq(
    146            sender.tab.id,
    147            extTab.id,
    148            "Sender's tab ID matches the RDM tab ID"
    149          );
    150          browser.test.assertEq(
    151            sender.tab.url,
    152            extTab.url,
    153            "Sender's tab URL matches the RDM tab URL"
    154          );
    155 
    156          browser.runtime.onMessage.removeListener(listener);
    157          resolve();
    158        };
    159        browser.runtime.onMessage.addListener(listener);
    160      });
    161 
    162      // Wait for "resume" message so we know the content script is also ready.
    163      await new Promise(resolve => {
    164        browser.test.onMessage.addListener(resolve);
    165        browser.test.sendMessage("background-script-ready");
    166      });
    167 
    168      await contentMessage;
    169 
    170      browser.test.log("Send message from background to content");
    171      const contentSender = await browser.tabs.sendMessage(
    172        extTab.id,
    173        "hello-from-background"
    174      );
    175      browser.test.assertEq(
    176        contentSender.id,
    177        browser.runtime.id,
    178        "The sender ID in content matches this extension"
    179      );
    180 
    181      browser.test.notifyPass("rdm-messaging");
    182    },
    183 
    184    files: {
    185      "content-script.js": async function () {
    186        browser.test.log("Content script init");
    187 
    188        browser.test.log("Listen to background");
    189        browser.runtime.onMessage.addListener((msg, sender, respond) => {
    190          browser.test.assertEq(
    191            msg,
    192            "hello-from-background",
    193            "Content script got hello-from-background message"
    194          );
    195 
    196          browser.test.assertTrue(!!sender, "Message has a sender");
    197          browser.test.assertTrue(!!sender.id, "Message has a sender.id");
    198 
    199          const { id } = sender;
    200          respond({ id });
    201        });
    202 
    203        // Wait for "resume" message so we know the background script is also ready.
    204        await new Promise(resolve => {
    205          browser.test.onMessage.addListener(resolve);
    206          browser.test.sendMessage("content-script-ready");
    207        });
    208 
    209        browser.test.log("Send message from content to background");
    210        browser.runtime.sendMessage("hello-from-content");
    211      },
    212    },
    213  });
    214 
    215  const contentScriptReady = extension2.awaitMessage("content-script-ready");
    216  const backgroundScriptReady = extension2.awaitMessage(
    217    "background-script-ready"
    218  );
    219  const finish = extension2.awaitFinish("rdm-messaging");
    220 
    221  await extension2.startup();
    222 
    223  // It appears the background script and content script can loaded in either order, so
    224  // we'll wait for the both to listen before proceeding.
    225  await backgroundScriptReady;
    226  await contentScriptReady;
    227  extension2.sendMessage("resume");
    228 
    229  await finish;
    230  await extension2.unload();
    231 });