tor-browser

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

browser_document_command_paste_contextmenu_ext.js (11442B)


      1 /* -*- Mode: JavaScript; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 "use strict";
      8 
      9 const kContentFileUrl = kBaseUrlForContent + "simple_page_ext.html";
     10 
     11 async function promiseExecCommandPasteFromExtension(aBrowser, aExtension) {
     12  await SpecialPowers.spawn(aBrowser, [], async () => {
     13    content.document.notifyUserGestureActivation();
     14  });
     15 
     16  aExtension.sendMessage("paste");
     17  return await aExtension.awaitMessage("result");
     18 }
     19 
     20 async function execCommandPasteFromExtensionWithoutResult(
     21  aBrowser,
     22  aExtension
     23 ) {
     24  await SpecialPowers.spawn(aBrowser, [], async () => {
     25    content.document.notifyUserGestureActivation();
     26  });
     27 
     28  aExtension.sendMessage("pasteWithoutResult");
     29 }
     30 
     31 add_setup(async function () {
     32  await SpecialPowers.pushPrefEnv({
     33    set: [
     34      ["test.events.async.enabled", true],
     35      // Disable the paste contextmenu delay to make the test run faster.
     36      ["security.dialog_enable_delay", 0],
     37    ],
     38  });
     39 });
     40 
     41 kPasteCommandTests.forEach(test => {
     42  describe(test.description, () => {
     43    const contentScript = function () {
     44      browser.test.onMessage.addListener(async aMsg => {
     45        if (aMsg === "paste") {
     46          let clipboardData = null;
     47          document.addEventListener(
     48            "paste",
     49            e => {
     50              clipboardData = e.clipboardData.getData("text/plain");
     51            },
     52            { once: true }
     53          );
     54 
     55          const execCommandResult = document.execCommand("paste");
     56          browser.test.sendMessage("result", {
     57            execCommandResult,
     58            clipboardData,
     59          });
     60        } else if (aMsg === "pasteWithoutResult") {
     61          setTimeout(() => {
     62            document.execCommand("paste");
     63          }, 0);
     64        }
     65      });
     66    };
     67    const extensionData = {
     68      manifest: {
     69        content_scripts: [
     70          {
     71            js: ["contentscript.js"],
     72            matches: ["https://example.com/*"],
     73          },
     74        ],
     75      },
     76      files: {
     77        "contentscript.js": contentScript,
     78      },
     79    };
     80 
     81    it("Accepting paste contextmenu", async () => {
     82      info(`Randomized text to avoid overlappings with other tests`);
     83      const clipboardText = await promiseWritingRandomTextToClipboard();
     84 
     85      info(`Load and start the extension`);
     86      const extension = ExtensionTestUtils.loadExtension(extensionData);
     87      await extension.startup();
     88 
     89      await BrowserTestUtils.withNewTab(
     90        kContentFileUrl,
     91        async function (aBrowser) {
     92          if (test.setupFn) {
     93            info(`Setup`);
     94            await test.setupFn(aBrowser);
     95          }
     96 
     97          const pasteButtonIsShown = promisePasteButtonIsShown();
     98 
     99          info(`Trigger execCommand("paste") from extension`);
    100          const pasteCommandResult = promiseExecCommandPasteFromExtension(
    101            aBrowser,
    102            extension
    103          );
    104 
    105          info(`Wait for paste context menu is shown`);
    106          await pasteButtonIsShown;
    107 
    108          info(`Click paste context menu`);
    109          const pasteButtonIsHidden = promisePasteButtonIsHidden();
    110          await promiseClickPasteButton();
    111          await pasteButtonIsHidden;
    112 
    113          const { execCommandResult, clipboardData } = await pasteCommandResult;
    114          ok(execCommandResult, `execCommand("paste") should be succeed`);
    115          is(clipboardData, clipboardText, `Check clipboard data`);
    116 
    117          if (test.additionalCheckFunc) {
    118            info(`Additional checks`);
    119            await test.additionalCheckFunc(aBrowser, clipboardText);
    120          }
    121        }
    122      );
    123 
    124      info(`Unload extension`);
    125      await extension.unload();
    126    });
    127 
    128    it("Dismissing paste contextmenu", async () => {
    129      info(`Randomized text to avoid overlappings with other tests`);
    130      await promiseWritingRandomTextToClipboard();
    131 
    132      info(`Load and start the extension`);
    133      const extension = ExtensionTestUtils.loadExtension(extensionData);
    134      await extension.startup();
    135 
    136      await BrowserTestUtils.withNewTab(
    137        kContentFileUrl,
    138        async function (aBrowser) {
    139          if (test.setupFn) {
    140            info(`Setup`);
    141            await test.setupFn(aBrowser);
    142          }
    143 
    144          const pasteButtonIsShown = promisePasteButtonIsShown();
    145 
    146          info(`Trigger execCommand("paste") from extension`);
    147          const pasteCommandResult = promiseExecCommandPasteFromExtension(
    148            aBrowser,
    149            extension
    150          );
    151 
    152          info(`Wait for paste context menu is shown`);
    153          await pasteButtonIsShown;
    154 
    155          info(`Dismiss paste context menu`);
    156          const pasteButtonIsHidden = promisePasteButtonIsHidden();
    157          await promiseDismissPasteButton();
    158          await pasteButtonIsHidden;
    159 
    160          const { execCommandResult, clipboardData } = await pasteCommandResult;
    161          ok(!execCommandResult, `execCommand("paste") should not be succeed`);
    162          is(clipboardData, null, `Check clipboard data`);
    163 
    164          if (test.additionalCheckFunc) {
    165            info(`Additional checks`);
    166            await test.additionalCheckFunc(aBrowser, "");
    167          }
    168        }
    169      );
    170 
    171      info(`Unload extension`);
    172      await extension.unload();
    173    });
    174 
    175    it("Tab close", async () => {
    176      info(`Randomized text to avoid overlappings with other tests`);
    177      await promiseWritingRandomTextToClipboard();
    178 
    179      info(`Load and start the extension`);
    180      const extension = ExtensionTestUtils.loadExtension(extensionData);
    181      await extension.startup();
    182 
    183      let pasteButtonIsHidden;
    184      await BrowserTestUtils.withNewTab(
    185        kContentFileUrl,
    186        async function (aBrowser) {
    187          if (test.setupFn) {
    188            info(`Setup`);
    189            await test.setupFn(aBrowser);
    190          }
    191 
    192          const pasteButtonIsShown = promisePasteButtonIsShown();
    193 
    194          info(`Trigger execCommand("paste") from extension`);
    195          execCommandPasteFromExtensionWithoutResult(aBrowser, extension);
    196 
    197          info(`Wait for paste context menu is shown`);
    198          await pasteButtonIsShown;
    199 
    200          pasteButtonIsHidden = promisePasteButtonIsHidden();
    201          info("Close tab");
    202        }
    203      );
    204 
    205      await pasteButtonIsHidden;
    206 
    207      info(`Unload extension`);
    208      await extension.unload();
    209    });
    210 
    211    it("Tab switch", async () => {
    212      info(`Randomized text to avoid overlappings with other tests`);
    213      await promiseWritingRandomTextToClipboard();
    214 
    215      info(`Load and start the extension`);
    216      const extension = ExtensionTestUtils.loadExtension(extensionData);
    217      await extension.startup();
    218 
    219      await BrowserTestUtils.withNewTab(
    220        kContentFileUrl,
    221        async function (aBrowser) {
    222          if (test.setupFn) {
    223            info(`Setup`);
    224            await test.setupFn(aBrowser);
    225          }
    226 
    227          const pasteButtonIsShown = promisePasteButtonIsShown();
    228 
    229          info(`Trigger execCommand("paste") from extension`);
    230          execCommandPasteFromExtensionWithoutResult(aBrowser, extension);
    231 
    232          info(`Wait for paste context menu is shown`);
    233          await pasteButtonIsShown;
    234 
    235          info("Switch tab");
    236          let pasteButtonIsHidden = promisePasteButtonIsHidden();
    237          let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser);
    238 
    239          info(`Wait for paste context menu is hidden`);
    240          await pasteButtonIsHidden;
    241 
    242          BrowserTestUtils.removeTab(tab);
    243        }
    244      );
    245 
    246      info(`Unload extension`);
    247      await extension.unload();
    248    });
    249 
    250    it("Window switch", async () => {
    251      info(`Randomized text to avoid overlappings with other tests`);
    252      await promiseWritingRandomTextToClipboard();
    253 
    254      info(`Load and start the extension`);
    255      const extension = ExtensionTestUtils.loadExtension(extensionData);
    256      await extension.startup();
    257 
    258      await BrowserTestUtils.withNewTab(
    259        kContentFileUrl,
    260        async function (aBrowser) {
    261          if (test.setupFn) {
    262            info(`Setup`);
    263            await test.setupFn(aBrowser);
    264          }
    265 
    266          const pasteButtonIsShown = promisePasteButtonIsShown();
    267 
    268          info(`Trigger execCommand("paste") from extension`);
    269          execCommandPasteFromExtensionWithoutResult(aBrowser, extension);
    270 
    271          info(`Wait for paste context menu is shown`);
    272          await pasteButtonIsShown;
    273 
    274          info("Switch browser window");
    275          let pasteButtonIsHidden = promisePasteButtonIsHidden();
    276          let newWin = await BrowserTestUtils.openNewBrowserWindow();
    277 
    278          info(`Wait for paste context menu is hidden`);
    279          await pasteButtonIsHidden;
    280 
    281          await BrowserTestUtils.closeWindow(newWin);
    282        }
    283      );
    284 
    285      info(`Unload extension`);
    286      await extension.unload();
    287    });
    288 
    289    it("Tab navigate", async () => {
    290      info(`Randomized text to avoid overlappings with other tests`);
    291      await promiseWritingRandomTextToClipboard();
    292 
    293      info(`Load and start the extension`);
    294      const extension = ExtensionTestUtils.loadExtension(extensionData);
    295      await extension.startup();
    296 
    297      await BrowserTestUtils.withNewTab(
    298        kContentFileUrl,
    299        async function (aBrowser) {
    300          if (test.setupFn) {
    301            info(`Setup`);
    302            await test.setupFn(aBrowser);
    303          }
    304 
    305          const pasteButtonIsShown = promisePasteButtonIsShown();
    306 
    307          info(`Trigger execCommand("paste") from extension`);
    308          execCommandPasteFromExtensionWithoutResult(aBrowser, extension);
    309 
    310          info(`Wait for paste context menu is shown`);
    311          await pasteButtonIsShown;
    312 
    313          info("Navigate tab");
    314          let pasteButtonIsHidden = promisePasteButtonIsHidden();
    315          aBrowser.loadURI(Services.io.newURI("https://example.com/"), {
    316            triggeringPrincipal:
    317              Services.scriptSecurityManager.getSystemPrincipal(),
    318          });
    319 
    320          info(`Wait for paste context menu is hidden`);
    321          await pasteButtonIsHidden;
    322        }
    323      );
    324 
    325      info(`Unload extension`);
    326      await extension.unload();
    327    });
    328 
    329    it("Tab reload", async () => {
    330      info(`Randomized text to avoid overlappings with other tests`);
    331      await promiseWritingRandomTextToClipboard();
    332 
    333      info(`Load and start the extension`);
    334      const extension = ExtensionTestUtils.loadExtension(extensionData);
    335      await extension.startup();
    336 
    337      await BrowserTestUtils.withNewTab(
    338        kContentFileUrl,
    339        async function (aBrowser) {
    340          if (test.setupFn) {
    341            info(`Setup`);
    342            await test.setupFn(aBrowser);
    343          }
    344 
    345          const pasteButtonIsShown = promisePasteButtonIsShown();
    346 
    347          info(`Trigger execCommand("paste") from extension`);
    348          execCommandPasteFromExtensionWithoutResult(aBrowser, extension);
    349 
    350          info(`Wait for paste context menu is shown`);
    351          await pasteButtonIsShown;
    352 
    353          info("Reload tab");
    354          let pasteButtonIsHidden = promisePasteButtonIsHidden();
    355          await BrowserTestUtils.reloadTab(gBrowser.selectedTab);
    356 
    357          info(`Wait for paste context menu is hidden`);
    358          await pasteButtonIsHidden;
    359        }
    360      );
    361 
    362      info(`Unload extension`);
    363      await extension.unload();
    364    });
    365  });
    366 });