From d236035b7224bc1faa8e793146f7d9e93c27b2e2 Mon Sep 17 00:00:00 2001 From: "Mr. M" Date: Sun, 11 May 2025 00:58:20 +0200 Subject: [PATCH] test: Added some tests for pinned tabs, b=(no-bug), c=tabs, tests --- src/zen/tabs/ZenPinnedTabManager.mjs | 15 +++ src/zen/tests/moz.build | 1 + src/zen/tests/pinned/browser.toml | 6 + .../tests/pinned/browser_pinned_changed.js | 37 +++++ .../tests/pinned/browser_pinned_created.js | 49 +++++++ .../tests/pinned/browser_pinned_edit_label.js | 42 ++++++ .../tests/pinned/browser_pinned_removed.js | 52 ++++++++ .../browser_pinned_reorder_changed_label.js | 126 ++++++++++++++++++ .../tests/pinned/browser_pinned_reordered.js | 97 ++++++++++++++ src/zen/tests/run.sh | 3 +- 10 files changed, 427 insertions(+), 1 deletion(-) create mode 100644 src/zen/tests/pinned/browser.toml create mode 100644 src/zen/tests/pinned/browser_pinned_changed.js create mode 100644 src/zen/tests/pinned/browser_pinned_created.js create mode 100644 src/zen/tests/pinned/browser_pinned_edit_label.js create mode 100644 src/zen/tests/pinned/browser_pinned_removed.js create mode 100644 src/zen/tests/pinned/browser_pinned_reorder_changed_label.js create mode 100644 src/zen/tests/pinned/browser_pinned_reordered.js diff --git a/src/zen/tabs/ZenPinnedTabManager.mjs b/src/zen/tabs/ZenPinnedTabManager.mjs index a9032d3a2..e2f6eb453 100644 --- a/src/zen/tabs/ZenPinnedTabManager.mjs +++ b/src/zen/tabs/ZenPinnedTabManager.mjs @@ -388,6 +388,11 @@ actualPin.title = tab.label; } await this.savePin(actualPin); + tab.dispatchEvent( + new CustomEvent('ZenPinnedTabMoved', { + detail: { tab }, + }) + ); } _onTabClick(e) { @@ -463,6 +468,11 @@ }); tab.setAttribute('zen-pin-id', uuid); + tab.dispatchEvent( + new CustomEvent('ZenPinnedTabCreated', { + detail: { tab }, + }) + ); // This is used while migrating old pins to new system - we don't want to refresh when migrating if (tab.getAttribute('zen-pinned-entry')) { @@ -497,6 +507,11 @@ } } await this._refreshPinnedTabs(); + tab.dispatchEvent( + new CustomEvent('ZenPinnedTabRemoved', { + detail: { tab }, + }) + ); } _initClosePinnedTabShortcut() { diff --git a/src/zen/tests/moz.build b/src/zen/tests/moz.build index 4bafc23c8..12d66a4c3 100644 --- a/src/zen/tests/moz.build +++ b/src/zen/tests/moz.build @@ -1,6 +1,7 @@ BROWSER_CHROME_MANIFESTS += [ "container_essentials/browser.toml", + "pinned/browser.toml", "urlbar/browser.toml", "workspaces/browser.toml", ] diff --git a/src/zen/tests/pinned/browser.toml b/src/zen/tests/pinned/browser.toml new file mode 100644 index 000000000..f07d4f83c --- /dev/null +++ b/src/zen/tests/pinned/browser.toml @@ -0,0 +1,6 @@ +["browser_pinned_changed.js"] +["browser_pinned_created.js"] +["browser_pinned_edit_label.js"] +["browser_pinned_removed.js"] +["browser_pinned_reorder_changed_label.js"] +["browser_pinned_reordered.js"] diff --git a/src/zen/tests/pinned/browser_pinned_changed.js b/src/zen/tests/pinned/browser_pinned_changed.js new file mode 100644 index 000000000..beee3a6f5 --- /dev/null +++ b/src/zen/tests/pinned/browser_pinned_changed.js @@ -0,0 +1,37 @@ +/* Any copyright is dedicated to the Public Domain. + https://creativecommons.org/publicdomain/zero/1.0/ */ + +'use strict'; + +add_task(async function test_Create_Pinned() { + let resolvePromise; + const promise = new Promise((resolve) => { + resolvePromise = resolve; + }); + + await BrowserTestUtils.withNewTab({ gBrowser, url: 'https://example.com/1' }, async (browser) => { + const tab = gBrowser.getTabForBrowser(browser); + tab.addEventListener( + 'ZenPinnedTabCreated', + async function (event) { + ok(tab.pinned, 'The tab should be pinned after calling gBrowser.pinTab()'); + + const pinTabID = tab.getAttribute('zen-pin-id'); + ok(pinTabID, 'The tab should have a zen-pin-id attribute after being pinned'); + + BrowserTestUtils.startLoadingURIString(browser, 'https://example.com/2'); + await BrowserTestUtils.browserLoaded(browser, false, 'https://example.com/2'); + setTimeout(() => { + ok( + tab.hasAttribute('zen-pinned-changed'), + 'The tab should have a zen-pinned-changed attribute after being pinned' + ); + resolvePromise(); + }, 0); + }, + { once: true } + ); + gBrowser.pinTab(tab); + await promise; + }); +}); diff --git a/src/zen/tests/pinned/browser_pinned_created.js b/src/zen/tests/pinned/browser_pinned_created.js new file mode 100644 index 000000000..c53234def --- /dev/null +++ b/src/zen/tests/pinned/browser_pinned_created.js @@ -0,0 +1,49 @@ +/* Any copyright is dedicated to the Public Domain. + https://creativecommons.org/publicdomain/zero/1.0/ */ + +'use strict'; + +add_task(async function test_Create_Pinned() { + let resolvePromise; + const promise = new Promise((resolve) => { + resolvePromise = resolve; + }); + + await BrowserTestUtils.openNewForegroundTab(window.gBrowser, 'https://example.com/', true); + + const newTab = gBrowser.selectedTab; + newTab.addEventListener( + 'ZenPinnedTabCreated', + async function (event) { + ok(newTab.pinned, 'The tab should be pinned after calling gBrowser.pinTab()'); + + const pinTabID = newTab.getAttribute('zen-pin-id'); + ok(pinTabID, 'The tab should have a zen-pin-id attribute after being pinned'); + + try { + const pins = await ZenPinnedTabsStorage.getPins(); + const pinObject = pins.find((pin) => pin.uuid === pinTabID); + ok(pinObject, 'The pin object should exist in the ZenPinnedTabsStorage'); + Assert.equal( + pinObject.url, + 'https://example.com/', + 'The pin object should have the correct URL' + ); + Assert.equal( + pinObject.workspaceUuid, + ZenWorkspaces.activeWorkspace, + 'The pin object should have the correct workspace UUID' + ); + } catch (error) { + ok(false, 'Error while checking the pin object in ZenPinnedTabsStorage: ' + error); + } + + resolvePromise(); + }, + { once: true } + ); + gBrowser.pinTab(newTab); + + await promise; + await BrowserTestUtils.removeTab(newTab); +}); diff --git a/src/zen/tests/pinned/browser_pinned_edit_label.js b/src/zen/tests/pinned/browser_pinned_edit_label.js new file mode 100644 index 000000000..e03cb7cb8 --- /dev/null +++ b/src/zen/tests/pinned/browser_pinned_edit_label.js @@ -0,0 +1,42 @@ +/* Any copyright is dedicated to the Public Domain. + https://creativecommons.org/publicdomain/zero/1.0/ */ + +'use strict'; + +add_task(async function test_Create_Pinned() { + let resolvePromise; + const promise = new Promise((resolve) => { + resolvePromise = resolve; + }); + + const customLabel = 'Test Label'; + + await BrowserTestUtils.withNewTab({ gBrowser, url: 'https://example.com/' }, async (browser) => { + const tab = gBrowser.getTabForBrowser(browser); + tab.addEventListener( + 'ZenPinnedTabCreated', + async function (event) { + ok(tab.pinned, 'The tab should be pinned after calling gBrowser.pinTab()'); + + const pinTabID = tab.getAttribute('zen-pin-id'); + ok(pinTabID, 'The tab should have a zen-pin-id attribute after being pinned'); + + await gZenPinnedTabManager.updatePinTitle(tab, customLabel, true); + + const pinnedTabs = await ZenPinnedTabsStorage.getPins(); + const pinObject = pinnedTabs.find((pin) => pin.uuid === pinTabID); + Assert.equal(pinObject.title, customLabel, 'The pin object should have the correct title'); + Assert.equal( + pinObject.url, + 'https://example.com/', + 'The pin object should have the correct URL' + ); + + resolvePromise(); + }, + { once: true } + ); + gBrowser.pinTab(tab); + await promise; + }); +}); diff --git a/src/zen/tests/pinned/browser_pinned_removed.js b/src/zen/tests/pinned/browser_pinned_removed.js new file mode 100644 index 000000000..4e4bc7959 --- /dev/null +++ b/src/zen/tests/pinned/browser_pinned_removed.js @@ -0,0 +1,52 @@ +/* Any copyright is dedicated to the Public Domain. + https://creativecommons.org/publicdomain/zero/1.0/ */ + +'use strict'; + +add_task(async function test_Remove_Pinned() { + let resolvePromise; + const promise = new Promise((resolve) => { + resolvePromise = resolve; + }); + + await BrowserTestUtils.openNewForegroundTab(window.gBrowser, 'https://example.com/', true); + + const newTab = gBrowser.selectedTab; + newTab.addEventListener( + 'ZenPinnedTabCreated', + async function (event) { + ok(newTab.pinned, 'The tab should be pinned after calling gBrowser.pinTab()'); + + const pinTabID = newTab.getAttribute('zen-pin-id'); + ok(pinTabID, 'The tab should have a zen-pin-id attribute after being pinned'); + + const pins = await ZenPinnedTabsStorage.getPins(); + const pinObject = pins.find((pin) => pin.uuid === pinTabID); + ok(pinObject, 'The pin object should exist in the ZenPinnedTabsStorage'); + newTab.addEventListener( + 'ZenPinnedTabRemoved', + async function (event) { + const pins = await ZenPinnedTabsStorage.getPins(); + const pinObject = pins.find((pin) => pin.uuid === pinTabID); + ok( + !pinObject, + 'The pin object should not exist in the ZenPinnedTabsStorage after removal' + ); + ok( + !newTab.hasAttribute('zen-pin-id'), + 'The tab should not have a zen-pin-id attribute after removal' + ); + ok(!newTab.pinned, 'The tab should not be pinned after removal'); + resolvePromise(); + }, + { once: true } + ); + gBrowser.unpinTab(newTab); + }, + { once: true } + ); + gBrowser.pinTab(newTab); + + await promise; + await BrowserTestUtils.removeTab(newTab); +}); diff --git a/src/zen/tests/pinned/browser_pinned_reorder_changed_label.js b/src/zen/tests/pinned/browser_pinned_reorder_changed_label.js new file mode 100644 index 000000000..10908c565 --- /dev/null +++ b/src/zen/tests/pinned/browser_pinned_reorder_changed_label.js @@ -0,0 +1,126 @@ +/* Any copyright is dedicated to the Public Domain. + https://creativecommons.org/publicdomain/zero/1.0/ */ + +'use strict'; + +add_task(async function test_Pinned_Reorder_Changed_Label() { + let resolvePromise; + const promise = new Promise((resolve) => { + resolvePromise = resolve; + }); + + const tabsToRemove = []; + for (let i = 0; i < 3; i++) { + await BrowserTestUtils.openNewForegroundTab(window.gBrowser, 'https://example.com/', true); + gBrowser.pinTab(gBrowser.selectedTab); + tabsToRemove.push(gBrowser.selectedTab); + } + + await BrowserTestUtils.openNewForegroundTab(window.gBrowser, 'https://example.com/', true); + tabsToRemove.push(gBrowser.selectedTab); + + const customLabel = 'Test Label'; + + const newTab = gBrowser.selectedTab; + newTab.addEventListener( + 'ZenPinnedTabCreated', + async function (event) { + ok(newTab.pinned, 'The tab should be pinned after calling gBrowser.pinTab()'); + + const pinTabID = newTab.getAttribute('zen-pin-id'); + ok(pinTabID, 'The tab should have a zen-pin-id attribute after being pinned'); + + await gZenPinnedTabManager.updatePinTitle(newTab, customLabel, true); + + const pins = await ZenPinnedTabsStorage.getPins(); + const pinObject = pins.find((pin) => pin.uuid === pinTabID); + + newTab.addEventListener( + 'ZenPinnedTabMoved', + async function (event) { + const pins = await ZenPinnedTabsStorage.getPins(); + const pinObject = pins.find((pin) => pin.uuid === pinTabID); + Assert.equal( + pinObject.title, + customLabel, + 'The pin object should have the correct title' + ); + Assert.equal( + pinObject.position, + 2, + 'The pin object should have the correct position after moving' + ); + resolvePromise(); + }, + { once: true } + ); + gBrowser.moveTabTo(newTab, { tabIndex: 2 }); + }, + { once: true } + ); + gBrowser.pinTab(newTab); + + await promise; + for (const tab of tabsToRemove) { + await BrowserTestUtils.removeTab(tab); + } +}); + +add_task(async function test_Pinned_Reorder_Changed_Label() { + let resolvePromise; + const promise = new Promise((resolve) => { + resolvePromise = resolve; + }); + + const tabsToRemove = []; + for (let i = 0; i < 3; i++) { + await BrowserTestUtils.openNewForegroundTab(window.gBrowser, 'https://example.com/', true); + gBrowser.pinTab(gBrowser.selectedTab); + tabsToRemove.push(gBrowser.selectedTab); + } + + await BrowserTestUtils.openNewForegroundTab(window.gBrowser, 'https://example.com/', true); + tabsToRemove.push(gBrowser.selectedTab); + + const customLabel = 'Test Label'; + + const newTab = gBrowser.selectedTab; + newTab.addEventListener( + 'ZenPinnedTabCreated', + async function (event) { + ok(newTab.pinned, 'The tab should be pinned after calling gBrowser.pinTab()'); + + const pinTabID = newTab.getAttribute('zen-pin-id'); + ok(pinTabID, 'The tab should have a zen-pin-id attribute after being pinned'); + + newTab.addEventListener( + 'ZenPinnedTabMoved', + async function (event) { + await gZenPinnedTabManager.updatePinTitle(newTab, customLabel, true); + const pins = await ZenPinnedTabsStorage.getPins(); + const pinObject = pins.find((pin) => pin.uuid === pinTabID); + Assert.equal( + pinObject.title, + customLabel, + 'The pin object should have the correct title' + ); + Assert.equal( + pinObject.position, + 1, + 'The pin object should have the correct position after moving' + ); + resolvePromise(); + }, + { once: true } + ); + gBrowser.moveTabTo(newTab, { tabIndex: 1 }); + }, + { once: true } + ); + gBrowser.pinTab(newTab); + + await promise; + for (const tab of tabsToRemove) { + await BrowserTestUtils.removeTab(tab); + } +}); diff --git a/src/zen/tests/pinned/browser_pinned_reordered.js b/src/zen/tests/pinned/browser_pinned_reordered.js new file mode 100644 index 000000000..6fc523b8b --- /dev/null +++ b/src/zen/tests/pinned/browser_pinned_reordered.js @@ -0,0 +1,97 @@ +/* Any copyright is dedicated to the Public Domain. + https://creativecommons.org/publicdomain/zero/1.0/ */ + +'use strict'; + +add_task(async function test_Create_Pinned() { + let resolvePromise; + const promise = new Promise((resolve) => { + resolvePromise = resolve; + }); + + const tabsToRemove = []; + for (let i = 0; i < 3; i++) { + await BrowserTestUtils.openNewForegroundTab(window.gBrowser, 'https://example.com/', true); + gBrowser.pinTab(gBrowser.selectedTab); + tabsToRemove.push(gBrowser.selectedTab); + } + + await BrowserTestUtils.openNewForegroundTab(window.gBrowser, 'https://example.com/', true); + tabsToRemove.push(gBrowser.selectedTab); + + const newTab = gBrowser.selectedTab; + newTab.addEventListener( + 'ZenPinnedTabCreated', + async function (event) { + ok(newTab.pinned, 'The tab should be pinned after calling gBrowser.pinTab()'); + + const pinTabID = newTab.getAttribute('zen-pin-id'); + ok(pinTabID, 'The tab should have a zen-pin-id attribute after being pinned'); + + const pins = await ZenPinnedTabsStorage.getPins(); + const pinObject = pins.find((pin) => pin.uuid === pinTabID); + const startIndex = pinObject.position; + Assert.greater(startIndex, 0, 'The pin object should have the correct start index'); + + resolvePromise(); + }, + { once: true } + ); + gBrowser.pinTab(newTab); + + await promise; + for (const tab of tabsToRemove) { + await BrowserTestUtils.removeTab(tab); + } +}); + +add_task(async function test_Create_Pinned() { + let resolvePromise; + const promise = new Promise((resolve) => { + resolvePromise = resolve; + }); + + const tabsToRemove = []; + for (let i = 0; i < 3; i++) { + await BrowserTestUtils.openNewForegroundTab(window.gBrowser, 'https://example.com/', true); + gBrowser.pinTab(gBrowser.selectedTab); + tabsToRemove.push(gBrowser.selectedTab); + } + + await BrowserTestUtils.openNewForegroundTab(window.gBrowser, 'https://example.com/', true); + tabsToRemove.push(gBrowser.selectedTab); + + const newTab = gBrowser.selectedTab; + newTab.addEventListener( + 'ZenPinnedTabCreated', + async function (event) { + ok(newTab.pinned, 'The tab should be pinned after calling gBrowser.pinTab()'); + + const pinTabID = newTab.getAttribute('zen-pin-id'); + ok(pinTabID, 'The tab should have a zen-pin-id attribute after being pinned'); + + newTab.addEventListener( + 'ZenPinnedTabMoved', + async function (event) { + const pins = await ZenPinnedTabsStorage.getPins(); + const pinObject = pins.find((pin) => pin.uuid === pinTabID); + Assert.equal( + pinObject.position, + 0, + 'The pin object should have the correct position after moving' + ); + resolvePromise(); + }, + { once: true } + ); + gBrowser.moveTabTo(newTab, { tabIndex: 0 }); + }, + { once: true } + ); + gBrowser.pinTab(newTab); + + await promise; + for (const tab of tabsToRemove) { + await BrowserTestUtils.removeTab(tab); + } +}); diff --git a/src/zen/tests/run.sh b/src/zen/tests/run.sh index 701984934..8c95a2dfd 100644 --- a/src/zen/tests/run.sh +++ b/src/zen/tests/run.sh @@ -12,5 +12,6 @@ cd ./engine ./mach mochitest $@ \ zen/tests/workspaces \ zen/tests/container_essentials \ - zen/tests/urlbar + zen/tests/urlbar \ + zen/tests/pinned cd ..