summaryrefslogtreecommitdiffstats
path: root/devtools/startup/tests/browser/browser_shim_disable_devtools.js
blob: a9c3903d7888f0bb48f9f5e41f41d1f3e0ee4983 (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
155
156
157
158
159
160
161
162
163
164
165
/* Any copyright is dedicated to the Public Domain.
 http://creativecommons.org/publicdomain/zero/1.0/ */

"use strict";

/* eslint-env browser */

const { require } = ChromeUtils.importESModule(
  "resource://devtools/shared/loader/Loader.sys.mjs"
);

const { gDevTools } = require("devtools/client/framework/devtools");

async function simulateMenuOpen(menu) {
  return new Promise(resolve => {
    menu.addEventListener("popupshown", resolve, { once: true });
    menu.dispatchEvent(new MouseEvent("popupshowing"));
    menu.dispatchEvent(new MouseEvent("popupshown"));
  });
}

async function simulateMenuClosed(menu) {
  return new Promise(resolve => {
    menu.addEventListener("popuphidden", resolve, { once: true });
    menu.dispatchEvent(new MouseEvent("popuphiding"));
    menu.dispatchEvent(new MouseEvent("popuphidden"));
  });
}

/**
 * Test that the preference devtools.policy.disabled disables entry points for devtools.
 */
add_task(async function () {
  info(
    "Disable DevTools entry points (does not apply to the already created window"
  );
  await new Promise(resolve => {
    const options = { set: [["devtools.policy.disabled", true]] };
    SpecialPowers.pushPrefEnv(options, resolve);
  });

  // In DEV_EDITION the browser starts with the developer-button in the toolbar. This
  // applies to all new windows and forces creating keyboard shortcuts. The preference
  // tested should not change without restart, but for the needs of the test, remove the
  // developer-button from the UI before opening a new window.
  if (AppConstants.MOZ_DEV_EDITION) {
    CustomizableUI.removeWidgetFromArea("developer-button");
  }

  info(
    "Open a new window, all window-specific hooks for DevTools will be disabled."
  );
  const win = OpenBrowserWindow({ private: false });
  await waitForDelayedStartupFinished(win);

  info(
    "Open a new tab on the new window to ensure the focus is on the new window"
  );
  const tab = BrowserTestUtils.addTab(
    win.gBrowser,
    "data:text/html;charset=utf-8,<title>foo</title>"
  );
  await BrowserTestUtils.browserLoaded(win.gBrowser.getBrowserForTab(tab));

  info(
    "Synthesize a DevTools shortcut, the toolbox should not open on this new window."
  );
  synthesizeToggleToolboxKey(win);

  // There is no event to wait for here as this shortcut should have no effect.
  /* eslint-disable mozilla/no-arbitrary-setTimeout */
  await new Promise(r => setTimeout(r, 1000));

  is(gDevTools._toolboxesPerCommands.size, 0, "No toolbox has been opened");

  info("Open the context menu for the content page.");
  const contextMenu = win.document.getElementById("contentAreaContextMenu");
  const popupShownPromise = BrowserTestUtils.waitForEvent(
    contextMenu,
    "popupshown"
  );
  EventUtils.synthesizeMouseAtCenter(
    win.document.documentElement,
    { type: "contextmenu", button: 2 },
    win
  );
  await popupShownPromise;

  const inspectElementItem = contextMenu.querySelector(`#context-inspect`);
  ok(
    inspectElementItem.hidden,
    "The inspect element item is hidden in the context menu"
  );

  info("Close the context menu");
  const onContextMenuHidden = BrowserTestUtils.waitForEvent(
    contextMenu,
    "popuphidden"
  );
  contextMenu.hidePopup();
  await onContextMenuHidden;

  info("Open the menubar Tools menu");
  const toolsMenuPopup = win.document.getElementById("menu_ToolsPopup");
  const browserToolsMenu = win.document.getElementById("browserToolsMenu");
  ok(
    !browserToolsMenu.hidden,
    "The Browser Tools item of the tools menu is visible"
  );

  await simulateMenuOpen(toolsMenuPopup);
  const subMenu = win.document.getElementById("menuWebDeveloperPopup");

  info("Open the Browser Tools sub-menu");
  await simulateMenuOpen(subMenu);

  const visibleMenuItems = Array.from(
    subMenu.querySelectorAll("menuitem")
  ).filter(item => !item.hidden);

  const { menuitems } = require("devtools/client/menus");
  for (const devtoolsItem of menuitems) {
    ok(
      !visibleMenuItems.some(item => item.id === devtoolsItem.id),
      "DevTools menu item is not visible in the Browser Tools menu"
    );
  }

  info("Close out the menu popups");
  await simulateMenuClosed(subMenu);
  await simulateMenuClosed(toolsMenuPopup);

  win.gBrowser.removeTab(tab);

  info("Close the test window");
  const winClosed = BrowserTestUtils.windowClosed(win);
  win.BrowserCommands.tryToCloseWindow();
  await winClosed;
});

function waitForDelayedStartupFinished(win) {
  return new Promise(resolve => {
    Services.obs.addObserver(function observer(subject) {
      if (win == subject) {
        Services.obs.removeObserver(
          observer,
          "browser-delayed-startup-finished"
        );
        resolve();
      }
    }, "browser-delayed-startup-finished");
  });
}

/**
 * Helper to call the toggle devtools shortcut.
 */
function synthesizeToggleToolboxKey(win) {
  info("Trigger the toogle toolbox shortcut");
  if (Services.appinfo.OS == "Darwin") {
    EventUtils.synthesizeKey("i", { accelKey: true, altKey: true }, win);
  } else {
    EventUtils.synthesizeKey("i", { accelKey: true, shiftKey: true }, win);
  }
}