summaryrefslogtreecommitdiffstats
path: root/browser/base/content/test/pageActions/browser_PageActions_overflow.js
blob: 463dd336c48024076604e707a72a2c6df622ffa4 (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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
/* Any copyright is dedicated to the Public Domain.
 * https://creativecommons.org/publicdomain/zero/1.0/ */

"use strict";

add_task(async function test() {
  // We use an extension that shows a page action. We must add this additional
  // action because otherwise the meatball menu would not appear as an overflow
  // for a single action.
  let extension = ExtensionTestUtils.loadExtension({
    manifest: {
      name: "Test contextMenu",
      page_action: { show_matches: ["<all_urls>"] },
    },

    useAddonManager: "temporary",
  });

  await extension.startup();
  let actionId = ExtensionCommon.makeWidgetId(extension.id);

  let win = await BrowserTestUtils.openNewBrowserWindow();
  await SimpleTest.promiseFocus(win);
  Assert.greater(win.outerWidth, 700, "window is bigger than 700px");
  BrowserTestUtils.loadURIString(
    win.gBrowser,
    "data:text/html,<h1>A Page</h1>"
  );
  await BrowserTestUtils.browserLoaded(win.gBrowser.selectedBrowser);

  // The pageAction implementation enables the button at the next animation
  // frame, so before we look for the button we should wait one animation frame
  // as well.
  await promiseAnimationFrame(win);

  info("Check page action buttons are visible, the meatball button is not");
  let addonButton =
    win.BrowserPageActions.urlbarButtonNodeForActionID(actionId);
  Assert.ok(BrowserTestUtils.is_visible(addonButton));
  let starButton =
    win.BrowserPageActions.urlbarButtonNodeForActionID("bookmark");
  Assert.ok(BrowserTestUtils.is_visible(starButton));
  let meatballButton = win.document.getElementById("pageActionButton");
  Assert.ok(!BrowserTestUtils.is_visible(meatballButton));

  info(
    "Shrink the window, check page action buttons are not visible, the meatball menu is visible"
  );
  let originalOuterWidth = win.outerWidth;
  await promiseStableResize(500, win);
  Assert.ok(!BrowserTestUtils.is_visible(addonButton));
  Assert.ok(!BrowserTestUtils.is_visible(starButton));
  Assert.ok(BrowserTestUtils.is_visible(meatballButton));

  info(
    "Remove the extension, check the only page action button is visible, the meatball menu is not visible"
  );
  let promiseUninstalled = promiseAddonUninstalled(extension.id);
  await extension.unload();
  await promiseUninstalled;
  Assert.ok(BrowserTestUtils.is_visible(starButton));
  Assert.ok(!BrowserTestUtils.is_visible(meatballButton));
  Assert.deepEqual(
    win.BrowserPageActions.urlbarButtonNodeForActionID(actionId),
    null
  );

  await promiseStableResize(originalOuterWidth, win);
  await BrowserTestUtils.closeWindow(win);
});

add_task(async function bookmark() {
  // We use an extension that shows a page action. We must add this additional
  // action because otherwise the meatball menu would not appear as an overflow
  // for a single action.
  let extension = ExtensionTestUtils.loadExtension({
    manifest: {
      name: "Test contextMenu",
      page_action: { show_matches: ["<all_urls>"] },
    },

    useAddonManager: "temporary",
  });

  await extension.startup();
  const url = "data:text/html,<h1>A Page</h1>";
  let win = await BrowserTestUtils.openNewBrowserWindow();
  await SimpleTest.promiseFocus(win);
  BrowserTestUtils.loadURIString(win.gBrowser, url);
  await BrowserTestUtils.browserLoaded(win.gBrowser.selectedBrowser);

  // The pageAction implementation enables the button at the next animation
  // frame, so before we look for the button we should wait one animation frame
  // as well.
  await promiseAnimationFrame(win);

  info("Shrink the window if necessary, check the meatball menu is visible");
  let originalOuterWidth = win.outerWidth;
  await promiseStableResize(500, win);

  let meatballButton = win.document.getElementById("pageActionButton");
  Assert.ok(BrowserTestUtils.is_visible(meatballButton));

  // Open the panel.
  await promisePageActionPanelOpen(win);

  // The bookmark button should read "Bookmark Current Tab…" and not be starred.
  let bookmarkButton = win.document.getElementById("pageAction-panel-bookmark");
  await TestUtils.waitForCondition(
    () => bookmarkButton.label === "Bookmark Current Tab…"
  );
  Assert.ok(!bookmarkButton.hasAttribute("starred"));

  // Click the button.
  let hiddenPromise = promisePageActionPanelHidden(win);
  let showPromise = BrowserTestUtils.waitForPopupEvent(
    win.StarUI.panel,
    "shown"
  );
  EventUtils.synthesizeMouseAtCenter(bookmarkButton, {}, win);
  await hiddenPromise;
  await showPromise;
  win.StarUI.panel.hidePopup();

  // Open the panel again.
  await promisePageActionPanelOpen(win);

  // The bookmark button should now read "Edit This Bookmark…" and be starred.
  await TestUtils.waitForCondition(
    () => bookmarkButton.label === "Edit This Bookmark…"
  );
  Assert.ok(bookmarkButton.hasAttribute("starred"));
  Assert.equal(bookmarkButton.getAttribute("starred"), "true");

  // Click it again.
  hiddenPromise = promisePageActionPanelHidden(win);
  showPromise = BrowserTestUtils.waitForPopupEvent(win.StarUI.panel, "shown");
  EventUtils.synthesizeMouseAtCenter(bookmarkButton, {}, win);
  await hiddenPromise;
  await showPromise;

  let onItemRemovedPromise = PlacesTestUtils.waitForNotification(
    "bookmark-removed",
    events => events.some(event => event.url == url)
  );

  // Click the remove-bookmark button in the panel.
  win.StarUI._element("editBookmarkPanelRemoveButton").click();

  // Wait for the bookmark to be removed before continuing.
  await onItemRemovedPromise;

  // Open the panel again.
  await promisePageActionPanelOpen(win);

  // The bookmark button should read "Bookmark Current Tab…" and not be starred.
  await TestUtils.waitForCondition(
    () => bookmarkButton.label === "Bookmark Current Tab…"
  );
  Assert.ok(!bookmarkButton.hasAttribute("starred"));

  // Done.
  hiddenPromise = promisePageActionPanelHidden();
  win.BrowserPageActions.panelNode.hidePopup();
  await hiddenPromise;

  info("Remove the extension");
  let promiseUninstalled = promiseAddonUninstalled(extension.id);
  await extension.unload();
  await promiseUninstalled;

  await promiseStableResize(originalOuterWidth, win);
  await BrowserTestUtils.closeWindow(win);
});

add_task(async function test_disabledPageAction_hidden_in_protonOverflowMenu() {
  // Make sure the overflow menu urlbar button is visible (indipendently from
  // the current size of the Firefox window).
  BrowserPageActions.mainButtonNode.style.visibility = "visible";
  registerCleanupFunction(() => {
    BrowserPageActions.mainButtonNode.style.removeProperty("visibility");
  });

  const extension = ExtensionTestUtils.loadExtension({
    manifest: { page_action: {} },
    async background() {
      const { browser } = this;
      const [tab] = await browser.tabs.query({
        active: true,
        currentWindow: true,
      });
      browser.test.assertTrue(tab, "Got an active tab as expected");
      browser.test.onMessage.addListener(async msg => {
        switch (msg) {
          case "show-pageAction":
            await browser.pageAction.show(tab.id);
            break;
          case "hide-pageAction":
            await browser.pageAction.hide(tab.id);
            break;
          default:
            browser.test.fail(`Unexpected message received: ${msg}`);
        }
        browser.test.sendMessage(`${msg}:done`);
      });
    },
  });

  // eslint-disable-next-line @microsoft/sdl/no-insecure-url
  await BrowserTestUtils.withNewTab("http://example.com", async browser => {
    const win = browser.ownerGlobal;
    const promisePageActionPanelClosed = async () => {
      let popupHiddenPromise = promisePageActionPanelHidden(win);
      win.BrowserPageActions.panelNode.hidePopup();
      await popupHiddenPromise;
    };

    await extension.startup();
    const widgetId = ExtensionCommon.makeWidgetId(extension.id);

    info(
      "Show pageAction and verify it is visible in the urlbar overflow menu"
    );
    extension.sendMessage("show-pageAction");
    await extension.awaitMessage("show-pageAction:done");
    await promisePageActionPanelOpen(win);
    let pageActionNode =
      win.BrowserPageActions.panelButtonNodeForActionID(widgetId);
    ok(
      pageActionNode && BrowserTestUtils.is_visible(pageActionNode),
      "enabled pageAction should be visible in the urlbar overflow menu"
    );

    info("Hide pageAction and verify it is hidden in the urlbar overflow menu");
    extension.sendMessage("hide-pageAction");
    await extension.awaitMessage("hide-pageAction:done");

    await BrowserTestUtils.waitForCondition(
      () => !win.BrowserPageActions.panelButtonNodeForActionID(widgetId),
      "Wait for the disabled pageAction to be removed from the urlbar overflow menu"
    );

    await promisePageActionPanelClosed();

    info("Reopen the urlbar overflow menu");
    await promisePageActionPanelOpen(win);
    ok(
      !win.BrowserPageActions.panelButtonNodeForActionID(widgetId),
      "Disabled pageAction is still removed as expected"
    );

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

  await SpecialPowers.popPrefEnv();
});