summaryrefslogtreecommitdiffstats
path: root/browser/components/extensions/test/browser/browser_ext_nontab_process_switch.js
blob: 56511d1a7d2343561c2b9cf5ac4889c0be0ca9ba (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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
"use strict";

add_task(async function process_switch_in_sidebars_popups() {
  await SpecialPowers.pushPrefEnv({
    set: [["extensions.content_web_accessible.enabled", true]],
  });

  let extension = ExtensionTestUtils.loadExtension({
    useAddonManager: "temporary", // To automatically show sidebar on load.
    manifest: {
      content_scripts: [
        {
          matches: ["http://example.com/*"],
          js: ["cs.js"],
        },
      ],

      sidebar_action: {
        default_panel: "page.html?sidebar",
      },
      browser_action: {
        default_popup: "page.html?popup",
        default_area: "navbar",
      },
      web_accessible_resources: ["page.html"],
    },
    files: {
      "page.html": `<!DOCTYPE html><meta charset=utf-8><script src=page.js></script>`,
      async "page.js"() {
        browser.test.sendMessage("extension_page", {
          place: location.search,
          pid: await SpecialPowers.spawnChrome([], () => {
            return windowGlobalParent.osPid;
          }),
        });
        if (!location.search.endsWith("_back")) {
          window.location.href = "http://example.com/" + location.search;
        }
      },

      async "cs.js"() {
        browser.test.sendMessage("content_script", {
          url: location.href,
          pid: await this.wrappedJSObject.SpecialPowers.spawnChrome([], () => {
            return windowGlobalParent.osPid;
          }),
        });
        if (location.search === "?popup") {
          window.location.href =
            browser.runtime.getURL("page.html") + "?popup_back";
        }
      },
    },
  });

  await extension.startup();

  let sidebar = await extension.awaitMessage("extension_page");
  is(sidebar.place, "?sidebar", "Message from the extension sidebar");

  let cs1 = await extension.awaitMessage("content_script");
  is(cs1.url, "http://example.com/?sidebar", "CS on example.com in sidebar");
  isnot(sidebar.pid, cs1.pid, "Navigating to example.com changed process");

  await clickBrowserAction(extension);
  let popup = await extension.awaitMessage("extension_page");
  is(popup.place, "?popup", "Message from the extension popup");

  let cs2 = await extension.awaitMessage("content_script");
  is(cs2.url, "http://example.com/?popup", "CS on example.com in popup");
  isnot(popup.pid, cs2.pid, "Navigating to example.com changed process");

  let popup2 = await extension.awaitMessage("extension_page");
  is(popup2.place, "?popup_back", "Back at extension page in popup");
  is(popup.pid, popup2.pid, "Same process as original popup page");

  is(sidebar.pid, popup.pid, "Sidebar and popup pages from the same process");

  // There's no guarantee that two (independent) pages from the same domain will
  // end up in the same process.

  await closeBrowserAction(extension);
  await extension.unload();
});

// Test that navigating the browserAction popup between extension pages doesn't keep the
// parser blocked (See Bug 1747813).
add_task(
  async function test_navigate_browserActionPopups_shouldnot_block_parser() {
    let extension = ExtensionTestUtils.loadExtension({
      manifest: {
        browser_action: {
          default_popup: "popup-1.html",
          default_area: "navbar",
        },
      },
      files: {
        "popup-1.html": `<!DOCTYPE html><meta charset=utf-8><script src=popup-1.js></script><h1>Popup 1</h1>`,
        "popup-2.html": `<!DOCTYPE html><meta charset=utf-8><script src=popup-2.js></script><h1>Popup 2</h1>`,

        "popup-1.js": function () {
          browser.test.onMessage.addListener(msg => {
            if (msg !== "navigate-popup") {
              browser.test.fail(`Unexpected test message "${msg}"`);
              return;
            }
            location.href = "/popup-2.html";
          });
          window.onload = () => browser.test.sendMessage("popup-page-1");
        },

        "popup-2.js": function () {
          window.onload = () => browser.test.sendMessage("popup-page-2");
        },
      },
    });

    // Make sure the mouse isn't hovering over the browserAction widget.
    EventUtils.synthesizeMouseAtCenter(
      gURLBar.textbox,
      { type: "mouseover" },
      window
    );

    await extension.startup();

    // Triggers popup preload (otherwise we wouldn't be blocking the parser for the browserAction popup
    // and the issue wouldn't be triggered, a real user on the contrary has a pretty high chance to trigger a
    // preload while hovering the browserAction popup before opening the popup with a click).
    let widget = getBrowserActionWidget(extension).forWindow(window);
    EventUtils.synthesizeMouseAtCenter(
      widget.node,
      { type: "mouseover" },
      window
    );
    await clickBrowserAction(extension);

    await extension.awaitMessage("popup-page-1");

    extension.sendMessage("navigate-popup");

    await extension.awaitMessage("popup-page-2");
    // If the bug is triggered (e.g. it did regress), the test will get stuck waiting for
    // the test message "popup-page-2" (which will never be sent because the extension page
    // script isn't executed while the parser is blocked).
    ok(
      true,
      "Extension browserAction popup successfully navigated to popup-page-2.html"
    );

    await closeBrowserAction(extension);
    await extension.unload();
  }
);