commit f839885524588fb02570370abeeb49c5a6d2d48b
parent b3818a61c95de0b5cfc61cf929d2a67f648be0e1
Author: Stephen Thompson <sthompson@mozilla.com>
Date: Mon, 1 Dec 2025 20:13:36 +0000
Bug 2002258 - moved tab notes menu browser test to tabnotes component r=dwalker,tabbrowser-reviewers
browser_tab_notes.js failed in beta simulation because `browser.tabs.notes.enabled` is `false` in beta and it appears the test was relying on the browser starting with it enabled.
I moved browser_tab_notes.js from tabbrowser to tabnotes so that I could ensure the tab notes pref is always enabled for testing purposes. I renamed browser_tab_notes to browser_tab_notes_menu in the process.
Differential Revision: https://phabricator.services.mozilla.com/D274047
Diffstat:
5 files changed, 200 insertions(+), 157 deletions(-)
diff --git a/browser/components/tabbrowser/test/browser/tabs/browser.toml b/browser/components/tabbrowser/test/browser/tabs/browser.toml
@@ -620,8 +620,6 @@ tags = "vertical-tabs"
["browser_tab_move_to_new_window_reload.js"]
tags = "vertical-tabs"
-["browser_tab_notes.js"]
-
["browser_tab_play.js"]
tags = "vertical-tabs"
diff --git a/browser/components/tabbrowser/test/browser/tabs/browser_tab_notes.js b/browser/components/tabbrowser/test/browser/tabs/browser_tab_notes.js
@@ -1,155 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const { TabNotes } = ChromeUtils.importESModule(
- "moz-src:///browser/components/tabnotes/TabNotes.sys.mjs"
-);
-
-registerCleanupFunction(() => {
- TabNotes.reset();
-});
-
-/**
- * Tab note menu tests
- */
-
-async function openTabNoteMenu(tab) {
- let tabContextMenu = await getContextMenu(tab, "tabContextMenu");
- let tabNotePanel = document.getElementById("tabNotePanel");
- let panelShown = BrowserTestUtils.waitForPopupEvent(tabNotePanel, "shown");
- tabContextMenu.activateItem(document.getElementById("context_addNote"));
- await panelShown;
- return tabNotePanel;
-}
-
-async function closeTabNoteMenu() {
- let tabNotePanel = document.getElementById("tabNotePanel");
- let menuHidden = BrowserTestUtils.waitForPopupEvent(tabNotePanel, "hidden");
- tabNotePanel.hidePopup();
- return menuHidden;
-}
-
-/**
- * Adds a tab, waits for it to load, and waits for the canonical URL to be
- * identified from the loaded contents of the tab. This ensures that the tab
- * meets the requirements to have a tab note.
- *
- * @param {string} [url="https://www.example.com"]
- * @returns {Promise<{tab: MozTabbrowserTab, canonicalUrl: string}>}
- */
-async function addTabWithCanonicalUrl(url = "https://www.example.com") {
- const { promise, resolve } = Promise.withResolvers();
- BrowserTestUtils.addTab(
- gBrowser,
- url,
- {
- skipAnimation: true,
- },
- tab => {
- BrowserTestUtils.waitForEvent(
- window,
- "CanonicalURL:Identified",
- false,
- e => e.target == tab.linkedBrowser
- ).then(e => {
- resolve({ tab, canonicalUrl: e.detail.canonicalUrl });
- });
- }
- );
- return promise;
-}
-
-add_task(async function test_openTabNotePanelFromContextMenu() {
- // open context menu with tab notes disabled
- await SpecialPowers.pushPrefEnv({
- set: [["browser.tabs.notes.enabled", false]],
- });
- let tab = await addTab("about:blank");
- let addNoteElement = document.getElementById("context_addNote");
- let tabContextMenu = await getContextMenu(tab, "tabContextMenu");
- Assert.ok(
- addNoteElement.hidden,
- "'Add Note' is hidden from context menu when pref disabled"
- );
- await closeContextMenu(tabContextMenu);
- await SpecialPowers.popPrefEnv();
-
- // open context menu with tab notes enabled
- await SpecialPowers.pushPrefEnv({
- set: [["browser.tabs.notes.enabled", true]],
- });
- tabContextMenu = await getContextMenu(tab, "tabContextMenu");
- Assert.ok(
- !addNoteElement.hidden,
- "'Add Note' is visible in context menu when pref enabled"
- );
- let tabNotePanel = document.getElementById("tabNotePanel");
-
- // open panel from context menu
- let panelShown = BrowserTestUtils.waitForPopupEvent(tabNotePanel, "shown");
- Assert.equal(tabNotePanel.state, "closed", "Tab note panel starts hidden");
- tabContextMenu.activateItem(addNoteElement);
- await panelShown;
- Assert.equal(
- tabNotePanel.state,
- "open",
- "Tab note panel appears after clicking context menu item"
- );
- await closeTabNoteMenu();
- BrowserTestUtils.removeTab(tab);
- await SpecialPowers.popPrefEnv();
-});
-
-add_task(async function test_dismissTabNotePanel() {
- await SpecialPowers.pushPrefEnv({
- set: [["browser.tabs.notes.enabled", true]],
- });
- // Dismiss panel by pressing Esc
- let tab = await addTab("about:blank");
- let tabNoteMenu = await openTabNoteMenu(tab);
- Assert.equal(tabNoteMenu.state, "open", "Tab note menu is open");
- EventUtils.synthesizeKey("KEY_Escape");
- await BrowserTestUtils.waitForPopupEvent(tabNoteMenu, "hidden");
- Assert.equal(
- tabNoteMenu.state,
- "closed",
- "Tab note menu closes after pressing Esc"
- );
-
- // Dismiss panel by clicking Cancel
- tabNoteMenu = await openTabNoteMenu(tab);
- Assert.equal(tabNoteMenu.state, "open", "Tab note menu is open");
- let menuHidden = BrowserTestUtils.waitForPopupEvent(tabNoteMenu, "hidden");
- let cancelButton = document.getElementById("tab-note-editor-button-cancel");
- cancelButton.click();
- await menuHidden;
- Assert.equal(
- tabNoteMenu.state,
- "closed",
- "Tab note menu closes after clicking cancel button"
- );
- BrowserTestUtils.removeTab(tab);
- await SpecialPowers.popPrefEnv();
-});
-
-add_task(async function test_saveTabNote() {
- await SpecialPowers.pushPrefEnv({
- set: [["browser.tabs.notes.enabled", true]],
- });
- let { tab, canonicalUrl } = await addTabWithCanonicalUrl();
- let tabNoteMenu = await openTabNoteMenu(tab);
- tabNoteMenu.querySelector("textarea").value = "Lorem ipsum dolor";
- let menuHidden = BrowserTestUtils.waitForPopupEvent(tabNoteMenu, "hidden");
- tabNoteMenu.querySelector("#tab-note-editor-button-save").click();
- await menuHidden;
-
- Assert.equal(TabNotes.get(canonicalUrl), "Lorem ipsum dolor");
-
- TabNotes.delete(canonicalUrl);
- BrowserTestUtils.removeTab(tab);
-
- await SpecialPowers.popPrefEnv();
-});
diff --git a/browser/components/tabnotes/moz.build b/browser/components/tabnotes/moz.build
@@ -25,3 +25,7 @@ EXTRA_COMPONENTS += [
XPCSHELL_TESTS_MANIFESTS += [
"test/unit/xpcshell.toml",
]
+
+BROWSER_CHROME_MANIFESTS += [
+ "test/browser/browser.toml",
+]
diff --git a/browser/components/tabnotes/test/browser/browser.toml b/browser/components/tabnotes/test/browser/browser.toml
@@ -0,0 +1,6 @@
+[DEFAULT]
+prefs = [
+ "browser.tabs.notes.enabled=true",
+]
+
+["browser_tab_notes_menu.js"]
diff --git a/browser/components/tabnotes/test/browser/browser_tab_notes_menu.js b/browser/components/tabnotes/test/browser/browser_tab_notes_menu.js
@@ -0,0 +1,190 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+const { TabNotes } = ChromeUtils.importESModule(
+ "moz-src:///browser/components/tabnotes/TabNotes.sys.mjs"
+);
+
+registerCleanupFunction(() => {
+ TabNotes.reset();
+});
+
+/**
+ * Tab note menu tests
+ */
+
+/**
+ * @param {Node} triggerNode
+ * @param {string} contextMenuId
+ * @returns {Promise<XULMenuElement|XULPopupElement>}
+ */
+async function getContextMenu(triggerNode, contextMenuId) {
+ let win = triggerNode.ownerGlobal;
+ triggerNode.scrollIntoView({ behavior: "instant" });
+ const contextMenu = win.document.getElementById(contextMenuId);
+ const contextMenuShown = BrowserTestUtils.waitForPopupEvent(
+ contextMenu,
+ "shown"
+ );
+
+ EventUtils.synthesizeMouseAtCenter(
+ triggerNode,
+ { type: "contextmenu", button: 2 },
+ win
+ );
+ await contextMenuShown;
+ return contextMenu;
+}
+
+/**
+ * @param {XULMenuElement|XULPopupElement} contextMenu
+ * @returns {Promise<void>}
+ */
+async function closeContextMenu(contextMenu) {
+ let menuHidden = BrowserTestUtils.waitForPopupEvent(contextMenu, "hidden");
+ contextMenu.hidePopup();
+ await menuHidden;
+}
+
+async function openTabNoteMenu(tab) {
+ let tabContextMenu = await getContextMenu(tab, "tabContextMenu");
+ let tabNotePanel = document.getElementById("tabNotePanel");
+ let panelShown = BrowserTestUtils.waitForPopupEvent(tabNotePanel, "shown");
+ tabContextMenu.activateItem(document.getElementById("context_addNote"));
+ await panelShown;
+ return tabNotePanel;
+}
+
+async function closeTabNoteMenu() {
+ let tabNotePanel = document.getElementById("tabNotePanel");
+ let menuHidden = BrowserTestUtils.waitForPopupEvent(tabNotePanel, "hidden");
+ tabNotePanel.hidePopup();
+ return menuHidden;
+}
+
+/**
+ * Adds a tab, waits for it to load, and waits for the canonical URL to be
+ * identified from the loaded contents of the tab. This ensures that the tab
+ * meets the requirements to have a tab note.
+ *
+ * @param {string} [url="https://www.example.com"]
+ * @returns {Promise<{tab: MozTabbrowserTab, canonicalUrl: string}>}
+ */
+async function addTabWithCanonicalUrl(url = "https://www.example.com") {
+ const { promise, resolve } = Promise.withResolvers();
+ BrowserTestUtils.addTab(
+ gBrowser,
+ url,
+ {
+ skipAnimation: true,
+ },
+ tab => {
+ BrowserTestUtils.waitForEvent(
+ window,
+ "CanonicalURL:Identified",
+ false,
+ e => e.target == tab.linkedBrowser
+ ).then(e => {
+ resolve({ tab, canonicalUrl: e.detail.canonicalUrl });
+ });
+ }
+ );
+ return promise;
+}
+
+add_task(async function test_openTabNotePanelFromContextMenu() {
+ // open context menu with tab notes disabled
+ await SpecialPowers.pushPrefEnv({
+ set: [["browser.tabs.notes.enabled", false]],
+ });
+ let tab = BrowserTestUtils.addTab(gBrowser, "https://www.example.com");
+ await BrowserTestUtils.browserLoaded(tab.linkedBrowser);
+ let addNoteElement = document.getElementById("context_addNote");
+ let tabContextMenu = await getContextMenu(tab, "tabContextMenu");
+ Assert.ok(
+ addNoteElement.hidden,
+ "'Add Note' is hidden from context menu when pref disabled"
+ );
+ await closeContextMenu(tabContextMenu);
+ await SpecialPowers.popPrefEnv();
+
+ // open context menu with tab notes enabled
+ await SpecialPowers.pushPrefEnv({
+ set: [["browser.tabs.notes.enabled", true]],
+ });
+ tabContextMenu = await getContextMenu(tab, "tabContextMenu");
+ Assert.ok(
+ !addNoteElement.hidden,
+ "'Add Note' is visible in context menu when pref enabled"
+ );
+ let tabNotePanel = document.getElementById("tabNotePanel");
+
+ // open panel from context menu
+ let panelShown = BrowserTestUtils.waitForPopupEvent(tabNotePanel, "shown");
+ Assert.equal(tabNotePanel.state, "closed", "Tab note panel starts hidden");
+ tabContextMenu.activateItem(addNoteElement);
+ await panelShown;
+ Assert.equal(
+ tabNotePanel.state,
+ "open",
+ "Tab note panel appears after clicking context menu item"
+ );
+ await closeTabNoteMenu();
+ BrowserTestUtils.removeTab(tab);
+ await SpecialPowers.popPrefEnv();
+});
+
+add_task(async function test_dismissTabNotePanel() {
+ await SpecialPowers.pushPrefEnv({
+ set: [["browser.tabs.notes.enabled", true]],
+ });
+ // Dismiss panel by pressing Esc
+ let tab = BrowserTestUtils.addTab(gBrowser, "https://www.example.com");
+ await BrowserTestUtils.browserLoaded(tab.linkedBrowser);
+ let tabNoteMenu = await openTabNoteMenu(tab);
+ Assert.equal(tabNoteMenu.state, "open", "Tab note menu is open");
+ EventUtils.synthesizeKey("KEY_Escape");
+ await BrowserTestUtils.waitForPopupEvent(tabNoteMenu, "hidden");
+ Assert.equal(
+ tabNoteMenu.state,
+ "closed",
+ "Tab note menu closes after pressing Esc"
+ );
+
+ // Dismiss panel by clicking Cancel
+ tabNoteMenu = await openTabNoteMenu(tab);
+ Assert.equal(tabNoteMenu.state, "open", "Tab note menu is open");
+ let menuHidden = BrowserTestUtils.waitForPopupEvent(tabNoteMenu, "hidden");
+ let cancelButton = document.getElementById("tab-note-editor-button-cancel");
+ cancelButton.click();
+ await menuHidden;
+ Assert.equal(
+ tabNoteMenu.state,
+ "closed",
+ "Tab note menu closes after clicking cancel button"
+ );
+ BrowserTestUtils.removeTab(tab);
+ await SpecialPowers.popPrefEnv();
+});
+
+add_task(async function test_saveTabNote() {
+ await SpecialPowers.pushPrefEnv({
+ set: [["browser.tabs.notes.enabled", true]],
+ });
+ let { tab, canonicalUrl } = await addTabWithCanonicalUrl();
+ let tabNoteMenu = await openTabNoteMenu(tab);
+ tabNoteMenu.querySelector("textarea").value = "Lorem ipsum dolor";
+ let menuHidden = BrowserTestUtils.waitForPopupEvent(tabNoteMenu, "hidden");
+ tabNoteMenu.querySelector("#tab-note-editor-button-save").click();
+ await menuHidden;
+
+ Assert.equal(TabNotes.get(canonicalUrl), "Lorem ipsum dolor");
+
+ TabNotes.delete(canonicalUrl);
+ BrowserTestUtils.removeTab(tab);
+
+ await SpecialPowers.popPrefEnv();
+});