summaryrefslogtreecommitdiffstats
path: root/browser/components/extensions/test/browser/browser_ext_connect_and_move_tabs.js
blob: 50f5380ce6b68db180b8843b22ac20bd71ff904c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";

// Tests that the Port object created by browser.runtime.connect is not
// prematurely disconnected as the underlying message managers change when a
// tab is moved between windows.

function loadExtension() {
  return ExtensionTestUtils.loadExtension({
    manifest: {
      content_scripts: [
        {
          js: ["script.js"],
          matches: ["http://mochi.test/?discoTest"],
        },
      ],
    },
    background() {
      browser.runtime.onConnect.addListener(port => {
        port.onDisconnect.addListener(() => {
          browser.test.fail(
            "onDisconnect should not fire because the port is to be closed from this side"
          );
          browser.test.sendMessage("port_disconnected");
        });
        port.onMessage.addListener(async msg => {
          browser.test.assertEq("connect_from_script", msg, "expected message");
          // Move a tab to a new window and back. Regression test for bugzil.la/1448674
          let { windowId, id: tabId, index } = port.sender.tab;
          await browser.windows.create({ tabId });
          await browser.tabs.move(tabId, { index, windowId });
          await browser.windows.create({ tabId });
          await browser.tabs.move(tabId, { index, windowId });
          try {
            // When the port is unexpectedly disconnected, postMessage will throw an error.
            port.postMessage("ping");
          } catch (e) {
            browser.test.fail(`Error: ${e} :: ${e.stack}`);
            browser.test.sendMessage("port_ping_ponged_before_disconnect");
          }
        });

        browser.runtime.onMessage.addListener(async (msg, sender) => {
          if (msg == "disconnect-me") {
            port.disconnect();
            // Now port.onDisconnect should fire in the content script.
          } else if (msg == "close-tab") {
            await browser.tabs.remove(sender.tab.id);
            browser.test.sendMessage("closed_tab");
          }
        });
      });

      browser.test.onMessage.addListener(msg => {
        browser.test.assertEq("open_extension_tab", msg, "expected message");
        browser.tabs.create({ url: "tab.html" });
      });
    },

    files: {
      "tab.html": `
        <!DOCTYPE html><meta charset="utf-8">
        <script src="script.js"></script>
      `,
      "script.js": function () {
        let port = browser.runtime.connect();
        port.onMessage.addListener(msg => {
          browser.test.assertEq("ping", msg, "expected message");
          browser.test.sendMessage("port_ping_ponged_before_disconnect");
          port.onDisconnect.addListener(() => {
            browser.test.sendMessage("port_disconnected");
            browser.runtime.sendMessage("close-tab");
          });
          browser.runtime.sendMessage("disconnect-me");
        });
        port.postMessage("connect_from_script");
      },
    },
  });
}

add_task(async function contentscript_connect_and_move_tabs() {
  let extension = loadExtension();
  await extension.startup();
  await BrowserTestUtils.openNewForegroundTab(
    gBrowser,
    "http://mochi.test:8888/?discoTest"
  );
  await extension.awaitMessage("port_ping_ponged_before_disconnect");
  await extension.awaitMessage("port_disconnected");
  await extension.awaitMessage("closed_tab");
  await extension.unload();
});

add_task(async function extension_tab_connect_and_move_tabs() {
  let extension = loadExtension();
  await extension.startup();
  extension.sendMessage("open_extension_tab");
  await extension.awaitMessage("port_ping_ponged_before_disconnect");
  await extension.awaitMessage("port_disconnected");
  await extension.awaitMessage("closed_tab");
  await extension.unload();
});