summaryrefslogtreecommitdiffstats
path: root/browser/components/firefoxview/tests
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-12 05:43:14 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-12 05:43:14 +0000
commit8dd16259287f58f9273002717ec4d27e97127719 (patch)
tree3863e62a53829a84037444beab3abd4ed9dfc7d0 /browser/components/firefoxview/tests
parentReleasing progress-linux version 126.0.1-1~progress7.99u1. (diff)
downloadfirefox-8dd16259287f58f9273002717ec4d27e97127719.tar.xz
firefox-8dd16259287f58f9273002717ec4d27e97127719.zip
Merging upstream version 127.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'browser/components/firefoxview/tests')
-rw-r--r--browser/components/firefoxview/tests/browser/browser.toml3
-rw-r--r--browser/components/firefoxview/tests/browser/browser_firefoxview.js39
-rw-r--r--browser/components/firefoxview/tests/browser/browser_firefoxview_virtual_list.js4
-rw-r--r--browser/components/firefoxview/tests/browser/browser_history_firefoxview.js83
-rw-r--r--browser/components/firefoxview/tests/browser/browser_notification_dot.js392
-rw-r--r--browser/components/firefoxview/tests/browser/browser_syncedtabs_firefoxview.js160
-rw-r--r--browser/components/firefoxview/tests/chrome/test_fxview_tab_list.html21
7 files changed, 279 insertions, 423 deletions
diff --git a/browser/components/firefoxview/tests/browser/browser.toml b/browser/components/firefoxview/tests/browser/browser.toml
index db8b2ea25c..c9036286d7 100644
--- a/browser/components/firefoxview/tests/browser/browser.toml
+++ b/browser/components/firefoxview/tests/browser/browser.toml
@@ -43,9 +43,6 @@ skip-if = ["true"] # Bug 1869605 and # Bug 1870296
["browser_history_firefoxview.js"]
-["browser_notification_dot.js"]
-skip-if = ["true"] # Bug 1851453
-
["browser_opentabs_cards.js"]
["browser_opentabs_changes.js"]
diff --git a/browser/components/firefoxview/tests/browser/browser_firefoxview.js b/browser/components/firefoxview/tests/browser/browser_firefoxview.js
index 1a51d61f42..00083d7c91 100644
--- a/browser/components/firefoxview/tests/browser/browser_firefoxview.js
+++ b/browser/components/firefoxview/tests/browser/browser_firefoxview.js
@@ -31,20 +31,47 @@ add_task(async function test_aria_roles() {
);
let recentlyClosedEmptyState = recentlyClosedComponent.emptyState;
let descriptionEls = recentlyClosedEmptyState.descriptionEls;
+ const recentlyClosedCard = SpecialPowers.wrap(
+ recentlyClosedEmptyState
+ ).openOrClosedShadowRoot.querySelector("card-container");
is(
- descriptionEls[1].querySelector("a").getAttribute("aria-details"),
- "card-container",
- "The link within the recently closed empty state has the expected 'aria-details' attribute."
+ recentlyClosedCard.getAttribute("aria-labelledby"),
+ "header",
+ "The recently closed empty state container has the expected 'aria-labelledby' attribute."
+ );
+ is(
+ recentlyClosedCard.getAttribute("aria-describedby"),
+ "description",
+ "The recently closed empty state container has the expected 'aria-describedby' attribute."
+ );
+ is(
+ recentlyClosedCard.getAttribute("role"),
+ "group",
+ "The recently closed empty state container has the expected 'role' attribute."
);
let syncedTabsComponent = document.querySelector(
"view-syncedtabs[slot=syncedtabs]"
);
let syncedTabsEmptyState = syncedTabsComponent.emptyState;
+ const syncedCard =
+ SpecialPowers.wrap(
+ syncedTabsEmptyState
+ ).openOrClosedShadowRoot.querySelector("card-container");
+ is(
+ syncedCard.getAttribute("aria-labelledby"),
+ "header",
+ "The synced tabs empty state container has the expected 'aria-labelledby' attribute."
+ );
+ is(
+ syncedCard.getAttribute("aria-describedby"),
+ "description",
+ "The synced tabs empty state container has the expected 'aria-describedby' attribute."
+ );
is(
- syncedTabsEmptyState.querySelector("button").getAttribute("aria-details"),
- "empty-container",
- "The button within the synced tabs empty state has the expected 'aria-details' attribute."
+ syncedCard.getAttribute("role"),
+ "group",
+ "The synced tabs empty state container has the expected 'role' attribute."
);
// Test keyboard navigation from card-container summary
diff --git a/browser/components/firefoxview/tests/browser/browser_firefoxview_virtual_list.js b/browser/components/firefoxview/tests/browser/browser_firefoxview_virtual_list.js
index bf53796ef7..e9502079d9 100644
--- a/browser/components/firefoxview/tests/browser/browser_firefoxview_virtual_list.js
+++ b/browser/components/firefoxview/tests/browser/browser_firefoxview_virtual_list.js
@@ -32,7 +32,9 @@ add_task(async function test_max_render_count_on_win_resize() {
await navigateToViewAndWait(document, "history");
let historyComponent = document.querySelector("view-history");
- let tabList = historyComponent.lists[0];
+ let tabList = await TestUtils.waitForCondition(
+ () => historyComponent.lists[0]
+ );
let rootVirtualList = tabList.rootVirtualListEl;
const initialHeight = window.outerHeight;
diff --git a/browser/components/firefoxview/tests/browser/browser_history_firefoxview.js b/browser/components/firefoxview/tests/browser/browser_history_firefoxview.js
index 847ce4d9fd..0bbc009eab 100644
--- a/browser/components/firefoxview/tests/browser/browser_history_firefoxview.js
+++ b/browser/components/firefoxview/tests/browser/browser_history_firefoxview.js
@@ -57,15 +57,11 @@ function isElInViewport(element) {
async function historyComponentReady(historyComponent, expectedHistoryItems) {
await TestUtils.waitForCondition(
- () =>
- [...historyComponent.controller.allHistoryItems.values()].reduce(
- (acc, { length }) => acc + length,
- 0
- ) === expectedHistoryItems,
+ () => historyComponent.controller.totalVisitsCount === expectedHistoryItems,
"History component ready"
);
- let expected = historyComponent.controller.historyMapByDate.length;
+ let expected = historyComponent.controller.historyVisits.length;
let actual = historyComponent.cards.length;
is(expected, actual, `Total number of cards should be ${expected}`);
@@ -242,8 +238,7 @@ add_task(async function test_list_ordering() {
await TestUtils.waitForCondition(() => historyComponent.fullyUpdated);
await sortHistoryTelemetry(sortHistoryEvent);
- let expectedNumOfCards =
- historyComponent.controller.historyMapBySite.length;
+ let expectedNumOfCards = historyComponent.controller.historyVisits.length;
info(`Total number of cards should be ${expectedNumOfCards}`);
await BrowserTestUtils.waitForMutationCondition(
@@ -475,7 +470,7 @@ add_task(async function test_search_history() {
EventUtils.sendString("Bogus Query", content);
await TestUtils.waitForCondition(() => {
const tabList = historyComponent.lists[0];
- return tabList?.shadowRoot.querySelector("fxview-empty-state");
+ return tabList?.emptyState;
}, "There are no matching search results.");
info("Clear the search query.");
@@ -485,7 +480,7 @@ add_task(async function test_search_history() {
{ childList: true, subtree: true },
() =>
historyComponent.cards.length ===
- historyComponent.controller.historyMapByDate.length
+ historyComponent.controller.historyVisits.length
);
searchTextbox.blur();
@@ -494,7 +489,7 @@ add_task(async function test_search_history() {
EventUtils.sendString("Bogus Query", content);
await TestUtils.waitForCondition(() => {
const tabList = historyComponent.lists[0];
- return tabList?.shadowRoot.querySelector("fxview-empty-state");
+ return tabList?.emptyState;
}, "There are no matching search results.");
info("Clear the search query with keyboard.");
@@ -514,11 +509,69 @@ add_task(async function test_search_history() {
{ childList: true, subtree: true },
() =>
historyComponent.cards.length ===
- historyComponent.controller.historyMapByDate.length
+ historyComponent.controller.historyVisits.length
);
});
});
+add_task(async function test_search_ignores_stale_queries() {
+ await PlacesUtils.history.clear();
+ const historyEntries = createHistoryEntries();
+ await PlacesUtils.history.insertMany(historyEntries);
+
+ let bogusQueryInProgress = false;
+ const searchDeferred = Promise.withResolvers();
+ const realDatabase = await PlacesUtils.promiseLargeCacheDBConnection();
+ const mockDatabase = {
+ executeCached: async (sql, options) => {
+ if (options.query === "Bogus Query") {
+ bogusQueryInProgress = true;
+ await searchDeferred.promise;
+ }
+ return realDatabase.executeCached(sql, options);
+ },
+ interrupt: () => searchDeferred.reject(),
+ };
+ const stub = sinon
+ .stub(PlacesUtils, "promiseLargeCacheDBConnection")
+ .resolves(mockDatabase);
+
+ await withFirefoxView({}, async browser => {
+ const { document } = browser.contentWindow;
+ await navigateToViewAndWait(document, "history");
+ const historyComponent = document.querySelector("view-history");
+ historyComponent.profileAge = 8;
+ await historyComponentReady(historyComponent, historyEntries.length);
+ const searchTextbox = await TestUtils.waitForCondition(
+ () => historyComponent.searchTextbox,
+ "The search textbox is displayed."
+ );
+
+ info("Input a bogus search query.");
+ EventUtils.synthesizeMouseAtCenter(searchTextbox, {}, content);
+ EventUtils.sendString("Bogus Query", content);
+ await TestUtils.waitForCondition(() => bogusQueryInProgress);
+
+ info("Clear the bogus query.");
+ EventUtils.synthesizeMouseAtCenter(searchTextbox.clearButton, {}, content);
+ await searchTextbox.updateComplete;
+
+ info("Input a real search query.");
+ EventUtils.synthesizeMouseAtCenter(searchTextbox, {}, content);
+ EventUtils.sendString("Example Domain 1", content);
+ await TestUtils.waitForCondition(() => {
+ const { rowEls } = historyComponent.lists[0];
+ return rowEls.length === 1 && rowEls[0].mainEl.href === URLs[1];
+ }, "There is one matching search result.");
+ searchDeferred.resolve();
+ await TestUtils.waitForTick();
+ const tabList = historyComponent.lists[0];
+ ok(!tabList.emptyState, "Empty state should not be shown.");
+ });
+
+ stub.restore();
+});
+
add_task(async function test_persist_collapse_card_after_view_change() {
await PlacesUtils.history.clear();
await addHistoryItems(today);
@@ -528,11 +581,7 @@ add_task(async function test_persist_collapse_card_after_view_change() {
const historyComponent = document.querySelector("view-history");
historyComponent.profileAge = 8;
await TestUtils.waitForCondition(
- () =>
- [...historyComponent.controller.allHistoryItems.values()].reduce(
- (acc, { length }) => acc + length,
- 0
- ) === 4
+ () => historyComponent.controller.totalVisitsCount === 4
);
let firstHistoryCard = historyComponent.cards[0];
ok(
diff --git a/browser/components/firefoxview/tests/browser/browser_notification_dot.js b/browser/components/firefoxview/tests/browser/browser_notification_dot.js
deleted file mode 100644
index 0fa747d40f..0000000000
--- a/browser/components/firefoxview/tests/browser/browser_notification_dot.js
+++ /dev/null
@@ -1,392 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-const tabsList1 = syncedTabsData1[0].tabs;
-const tabsList2 = syncedTabsData1[1].tabs;
-const BADGE_TOP_RIGHT = "75% 25%";
-
-const { SyncedTabs } = ChromeUtils.importESModule(
- "resource://services-sync/SyncedTabs.sys.mjs"
-);
-
-function setupRecentDeviceListMocks() {
- const sandbox = sinon.createSandbox();
- sandbox.stub(fxAccounts.device, "recentDeviceList").get(() => [
- {
- id: 1,
- name: "My desktop",
- isCurrentDevice: true,
- type: "desktop",
- tabs: [],
- },
- {
- id: 2,
- name: "My iphone",
- type: "mobile",
- tabs: [],
- },
- ]);
-
- sandbox.stub(UIState, "get").returns({
- status: UIState.STATUS_SIGNED_IN,
- syncEnabled: true,
- });
-
- return sandbox;
-}
-
-function waitForWindowActive(win, active) {
- info("Waiting for window activation");
- return Promise.all([
- BrowserTestUtils.waitForEvent(win, active ? "focus" : "blur"),
- BrowserTestUtils.waitForEvent(win, active ? "activate" : "deactivate"),
- ]);
-}
-
-async function waitForNotificationBadgeToBeShowing(fxViewButton) {
- info("Waiting for attention attribute to be set");
- await BrowserTestUtils.waitForMutationCondition(
- fxViewButton,
- { attributes: true },
- () => fxViewButton.hasAttribute("attention")
- );
- return fxViewButton.hasAttribute("attention");
-}
-
-async function waitForNotificationBadgeToBeHidden(fxViewButton) {
- info("Waiting for attention attribute to be removed");
- await BrowserTestUtils.waitForMutationCondition(
- fxViewButton,
- { attributes: true },
- () => !fxViewButton.hasAttribute("attention")
- );
- return !fxViewButton.hasAttribute("attention");
-}
-
-async function clickFirefoxViewButton(win) {
- await BrowserTestUtils.synthesizeMouseAtCenter(
- "#firefox-view-button",
- { type: "mousedown" },
- win.browsingContext
- );
-}
-
-function getBackgroundPositionForElement(ele) {
- let style = ele.ownerGlobal.getComputedStyle(ele);
- return style.getPropertyValue("background-position");
-}
-
-let previousFetchTime = 0;
-
-async function resetSyncedTabsLastFetched() {
- Services.prefs.clearUserPref("services.sync.lastTabFetch");
- previousFetchTime = 0;
- await TestUtils.waitForTick();
-}
-
-async function initTabSync() {
- let recentFetchTime = Math.floor(Date.now() / 1000);
- // ensure we don't try to set the pref with the same value, which will not produce
- // the expected pref change effects
- while (recentFetchTime == previousFetchTime) {
- await TestUtils.waitForTick();
- recentFetchTime = Math.floor(Date.now() / 1000);
- }
- Assert.greater(
- recentFetchTime,
- previousFetchTime,
- "The new lastTabFetch value is greater than the previous"
- );
-
- info("initTabSync, updating lastFetch:" + recentFetchTime);
- Services.prefs.setIntPref("services.sync.lastTabFetch", recentFetchTime);
- previousFetchTime = recentFetchTime;
- await TestUtils.waitForTick();
-}
-
-add_setup(async function () {
- await resetSyncedTabsLastFetched();
- await SpecialPowers.pushPrefEnv({
- set: [["browser.tabs.firefox-view.notify-for-tabs", true]],
- });
-
- // Clear any synced tabs from previous tests
- FirefoxViewNotificationManager.syncedTabs = null;
- Services.obs.notifyObservers(
- null,
- "firefoxview-notification-dot-update",
- "false"
- );
-});
-
-/**
- * Test that the notification badge will show and hide in the correct cases
- */
-add_task(async function testNotificationDot() {
- const sandbox = setupRecentDeviceListMocks();
- const syncedTabsMock = sandbox.stub(SyncedTabs, "getRecentTabs");
- sandbox.spy(SyncedTabs, "syncTabs");
-
- let win = await BrowserTestUtils.openNewBrowserWindow();
- let fxViewBtn = win.document.getElementById("firefox-view-button");
- ok(fxViewBtn, "Got the Firefox View button");
-
- // Initiate a synced tabs update with new tabs
- syncedTabsMock.returns(tabsList1);
- await initTabSync();
-
- ok(
- BrowserTestUtils.isVisible(fxViewBtn),
- "The Firefox View button is showing"
- );
-
- info(
- "testNotificationDot, button is showing, badge should be initially hidden"
- );
- ok(
- await waitForNotificationBadgeToBeHidden(fxViewBtn),
- "The notification badge is not showing initially"
- );
-
- // Initiate a synced tabs update with new tabs
- syncedTabsMock.returns(tabsList2);
- await initTabSync();
-
- ok(
- await waitForNotificationBadgeToBeShowing(fxViewBtn),
- "The notification badge is showing after first tab sync"
- );
-
- // check that switching to the firefoxviewtab removes the badge
- await clickFirefoxViewButton(win);
-
- info(
- "testNotificationDot, after clicking the button, badge should become hidden"
- );
- ok(
- await waitForNotificationBadgeToBeHidden(fxViewBtn),
- "The notification badge is not showing after going to Firefox View"
- );
-
- await BrowserTestUtils.waitForCondition(() => {
- return SyncedTabs.syncTabs.calledOnce;
- });
-
- ok(SyncedTabs.syncTabs.calledOnce, "SyncedTabs.syncTabs() was called once");
-
- syncedTabsMock.returns(tabsList1);
- // Initiate a synced tabs update with new tabs
- await initTabSync();
-
- // The noti badge would show but we are on a Firefox View page so no need to show the noti badge
- info(
- "testNotificationDot, after updating the recent tabs, badge should be hidden"
- );
- ok(
- await waitForNotificationBadgeToBeHidden(fxViewBtn),
- "The notification badge is not showing after tab sync while Firefox View is focused"
- );
-
- let newTab = await BrowserTestUtils.openNewForegroundTab(win.gBrowser);
- syncedTabsMock.returns(tabsList2);
- await initTabSync();
-
- ok(
- await waitForNotificationBadgeToBeShowing(fxViewBtn),
- "The notification badge is showing after navigation to a new tab"
- );
-
- // check that switching back to the Firefox View tab removes the badge
- await clickFirefoxViewButton(win);
-
- info(
- "testNotificationDot, after switching back to fxview, badge should be hidden"
- );
- ok(
- await waitForNotificationBadgeToBeHidden(fxViewBtn),
- "The notification badge is not showing after focusing the Firefox View tab"
- );
-
- await BrowserTestUtils.switchTab(win.gBrowser, newTab);
-
- // Initiate a synced tabs update with no new tabs
- await initTabSync();
-
- info(
- "testNotificationDot, after switching back to fxview with no new tabs, badge should be hidden"
- );
- ok(
- await waitForNotificationBadgeToBeHidden(fxViewBtn),
- "The notification badge is not showing after a tab sync with the same tabs"
- );
-
- await BrowserTestUtils.closeWindow(win);
-
- sandbox.restore();
-});
-
-/**
- * Tests the notification badge with multiple windows
- */
-add_task(async function testNotificationDotOnMultipleWindows() {
- const sandbox = setupRecentDeviceListMocks();
-
- await resetSyncedTabsLastFetched();
- const syncedTabsMock = sandbox.stub(SyncedTabs, "getRecentTabs");
-
- // Create a new window
- let win1 = await BrowserTestUtils.openNewBrowserWindow();
- await win1.delayedStartupPromise;
- let fxViewBtn = win1.document.getElementById("firefox-view-button");
- ok(fxViewBtn, "Got the Firefox View button");
-
- syncedTabsMock.returns(tabsList1);
- // Initiate a synced tabs update
- await initTabSync();
-
- // Create another window
- let win2 = await BrowserTestUtils.openNewBrowserWindow();
- await win2.delayedStartupPromise;
- let fxViewBtn2 = win2.document.getElementById("firefox-view-button");
-
- await clickFirefoxViewButton(win2);
-
- // Make sure the badge doesn't show on any window
- info(
- "testNotificationDotOnMultipleWindows, badge is initially hidden on window 1"
- );
- ok(
- await waitForNotificationBadgeToBeHidden(fxViewBtn),
- "The notification badge is not showing in the inital window"
- );
- info(
- "testNotificationDotOnMultipleWindows, badge is initially hidden on window 2"
- );
- ok(
- await waitForNotificationBadgeToBeHidden(fxViewBtn2),
- "The notification badge is not showing in the second window"
- );
-
- // Minimize the window.
- win2.minimize();
-
- await TestUtils.waitForCondition(
- () => !win2.gBrowser.selectedBrowser.docShellIsActive,
- "Waiting for docshell to be marked as inactive after minimizing the window"
- );
-
- syncedTabsMock.returns(tabsList2);
- info("Initiate a synced tabs update with new tabs");
- await initTabSync();
-
- // The badge will show because the View tab is minimized
- // Make sure the badge shows on all windows
- info(
- "testNotificationDotOnMultipleWindows, after new synced tabs and minimized win2, badge is visible on window 1"
- );
- ok(
- await waitForNotificationBadgeToBeShowing(fxViewBtn),
- "The notification badge is showing in the initial window"
- );
- info(
- "testNotificationDotOnMultipleWindows, after new synced tabs and minimized win2, badge is visible on window 2"
- );
- ok(
- await waitForNotificationBadgeToBeShowing(fxViewBtn2),
- "The notification badge is showing in the second window"
- );
-
- win2.restore();
- await TestUtils.waitForCondition(
- () => win2.gBrowser.selectedBrowser.docShellIsActive,
- "Waiting for docshell to be marked as active after restoring the window"
- );
-
- await BrowserTestUtils.closeWindow(win1);
- await BrowserTestUtils.closeWindow(win2);
-
- sandbox.restore();
-});
-
-/**
- * Tests the notification badge is in the correct spot and that the badge shows when opening a new window
- * if another window is showing the badge
- */
-add_task(async function testNotificationDotLocation() {
- const sandbox = setupRecentDeviceListMocks();
- await resetSyncedTabsLastFetched();
- const syncedTabsMock = sandbox.stub(SyncedTabs, "getRecentTabs");
-
- syncedTabsMock.returns(tabsList1);
-
- let win1 = await BrowserTestUtils.openNewBrowserWindow();
- let fxViewBtn = win1.document.getElementById("firefox-view-button");
- ok(fxViewBtn, "Got the Firefox View button");
-
- // Initiate a synced tabs update
- await initTabSync();
- syncedTabsMock.returns(tabsList2);
- // Initiate another synced tabs update
- await initTabSync();
-
- ok(
- await waitForNotificationBadgeToBeShowing(fxViewBtn),
- "The notification badge is showing initially"
- );
-
- // Create a new window
- let win2 = await BrowserTestUtils.openNewBrowserWindow();
- await win2.delayedStartupPromise;
-
- // Make sure the badge is showing on the new window
- let fxViewBtn2 = win2.document.getElementById("firefox-view-button");
- ok(
- await waitForNotificationBadgeToBeShowing(fxViewBtn2),
- "The notification badge is showing in the second window after opening"
- );
-
- // Make sure the badge is below and center now
- isnot(
- getBackgroundPositionForElement(fxViewBtn),
- BADGE_TOP_RIGHT,
- "The notification badge is not showing in the top right in the initial window"
- );
- isnot(
- getBackgroundPositionForElement(fxViewBtn2),
- BADGE_TOP_RIGHT,
- "The notification badge is not showing in the top right in the second window"
- );
-
- CustomizableUI.addWidgetToArea(
- "firefox-view-button",
- CustomizableUI.AREA_NAVBAR
- );
-
- // Make sure both windows still have the notification badge
- ok(
- await waitForNotificationBadgeToBeShowing(fxViewBtn),
- "The notification badge is showing in the initial window"
- );
- ok(
- await waitForNotificationBadgeToBeShowing(fxViewBtn2),
- "The notification badge is showing in the second window"
- );
-
- // Make sure the badge is in the top right now
- is(
- getBackgroundPositionForElement(fxViewBtn),
- BADGE_TOP_RIGHT,
- "The notification badge is showing in the top right in the initial window"
- );
- is(
- getBackgroundPositionForElement(fxViewBtn2),
- BADGE_TOP_RIGHT,
- "The notification badge is showing in the top right in the second window"
- );
-
- CustomizableUI.reset();
- await BrowserTestUtils.closeWindow(win1);
- await BrowserTestUtils.closeWindow(win2);
-
- sandbox.restore();
-});
diff --git a/browser/components/firefoxview/tests/browser/browser_syncedtabs_firefoxview.js b/browser/components/firefoxview/tests/browser/browser_syncedtabs_firefoxview.js
index 1bf387f578..872efd37a0 100644
--- a/browser/components/firefoxview/tests/browser/browser_syncedtabs_firefoxview.js
+++ b/browser/components/firefoxview/tests/browser/browser_syncedtabs_firefoxview.js
@@ -13,6 +13,11 @@ add_setup(async function () {
registerCleanupFunction(async function () {
await tearDown(gSandbox);
});
+
+ // set tab sync false so we don't skip setup states
+ await SpecialPowers.pushPrefEnv({
+ set: [["services.sync.engine.tabs", false]],
+ });
});
async function promiseTabListsUpdated({ tabLists }) {
@@ -748,3 +753,158 @@ add_task(async function search_synced_tabs_recent_browsing() {
await SpecialPowers.popPrefEnv();
await tearDown(sandbox);
});
+
+add_task(async function test_mobile_connected() {
+ Services.prefs.setBoolPref("services.sync.engine.tabs", false);
+ const sandbox = setupMocks({
+ state: UIState.STATUS_SIGNED_IN,
+ fxaDevices: [
+ {
+ id: 1,
+ name: "This Device",
+ isCurrentDevice: true,
+ type: "desktop",
+ tabs: [],
+ },
+ {
+ id: 2,
+ name: "Other Device",
+ type: "mobile",
+ tabs: [],
+ },
+ ],
+ });
+ await withFirefoxView({}, async browser => {
+ const { document } = browser.contentWindow;
+ // ensure tab sync is false so we don't skip onto next step
+ ok(
+ !Services.prefs.getBoolPref("services.sync.engine.tabs", false),
+ "services.sync.engine.tabs is initially false"
+ );
+
+ Services.obs.notifyObservers(null, UIState.ON_UPDATE);
+ await navigateToViewAndWait(document, "syncedtabs");
+
+ is(fxAccounts.device.recentDeviceList?.length, 2, "2 devices connected");
+ ok(
+ fxAccounts.device.recentDeviceList?.some(
+ device => device.type == "mobile"
+ ),
+ "A connected device is type:mobile"
+ );
+ });
+ await tearDown(sandbox);
+ Services.prefs.setBoolPref("services.sync.engine.tabs", true);
+});
+
+add_task(async function test_tablet_connected() {
+ Services.prefs.setBoolPref("services.sync.engine.tabs", false);
+ const sandbox = setupMocks({
+ state: UIState.STATUS_SIGNED_IN,
+ fxaDevices: [
+ {
+ id: 1,
+ name: "This Device",
+ isCurrentDevice: true,
+ type: "desktop",
+ tabs: [],
+ },
+ {
+ id: 2,
+ name: "Other Device",
+ type: "tablet",
+ tabs: [],
+ },
+ ],
+ });
+ await withFirefoxView({}, async browser => {
+ const { document } = browser.contentWindow;
+ // ensure tab sync is false so we don't skip onto next step
+ ok(
+ !Services.prefs.getBoolPref("services.sync.engine.tabs", false),
+ "services.sync.engine.tabs is initially false"
+ );
+
+ Services.obs.notifyObservers(null, UIState.ON_UPDATE);
+ await navigateToViewAndWait(document, "syncedtabs");
+
+ is(fxAccounts.device.recentDeviceList?.length, 2, "2 devices connected");
+ ok(
+ fxAccounts.device.recentDeviceList?.some(
+ device => device.type == "tablet"
+ ),
+ "A connected device is type:tablet"
+ );
+ });
+ await tearDown(sandbox);
+ Services.prefs.setBoolPref("services.sync.engine.tabs", true);
+});
+
+add_task(async function test_tab_sync_enabled() {
+ const sandbox = setupMocks({
+ state: UIState.STATUS_SIGNED_IN,
+ fxaDevices: [
+ {
+ id: 1,
+ name: "This Device",
+ isCurrentDevice: true,
+ type: "desktop",
+ tabs: [],
+ },
+ {
+ id: 2,
+ name: "Other Device",
+ type: "mobile",
+ tabs: [],
+ },
+ ],
+ });
+ await withFirefoxView({}, async browser => {
+ const { document } = browser.contentWindow;
+ Services.obs.notifyObservers(null, UIState.ON_UPDATE);
+ let syncedTabsComponent = document.querySelector(
+ "view-syncedtabs:not([slot=syncedtabs])"
+ );
+
+ // test initial state, with the pref not enabled
+ await navigateToViewAndWait(document, "syncedtabs");
+ // test with the pref toggled on
+ Services.prefs.setBoolPref("services.sync.engine.tabs", true);
+ await TestUtils.waitForCondition(
+ () => syncedTabsComponent.fullyUpdated,
+ "Synced tabs component is fully updated."
+ );
+ ok(!syncedTabsComponent.emptyState, "No empty state is being displayed.");
+
+ // reset and test clicking the action button
+ Services.prefs.setBoolPref("services.sync.engine.tabs", false);
+ await TestUtils.waitForCondition(
+ () => syncedTabsComponent.fullyUpdated,
+ "Synced tabs component is fully updated."
+ );
+ await TestUtils.waitForCondition(
+ () => syncedTabsComponent.emptyState,
+ "The empty state is rendered."
+ );
+
+ const actionButton = syncedTabsComponent.emptyState?.querySelector(
+ "button[data-action=sync-tabs-disabled]"
+ );
+ EventUtils.synthesizeMouseAtCenter(actionButton, {}, browser.contentWindow);
+ await TestUtils.waitForCondition(
+ () => syncedTabsComponent.fullyUpdated,
+ "Synced tabs component is fully updated."
+ );
+ await TestUtils.waitForCondition(
+ () => !syncedTabsComponent.emptyState,
+ "The empty state is rendered."
+ );
+
+ ok(true, "The empty state is no longer displayed when sync is enabled");
+ ok(
+ Services.prefs.getBoolPref("services.sync.engine.tabs", false),
+ "tab sync pref should be enabled after button click"
+ );
+ });
+ await tearDown(sandbox);
+});
diff --git a/browser/components/firefoxview/tests/chrome/test_fxview_tab_list.html b/browser/components/firefoxview/tests/chrome/test_fxview_tab_list.html
index 52ddc277c7..abea8725ee 100644
--- a/browser/components/firefoxview/tests/chrome/test_fxview_tab_list.html
+++ b/browser/components/firefoxview/tests/chrome/test_fxview_tab_list.html
@@ -37,8 +37,8 @@
const { BrowserTestUtils } = ChromeUtils.importESModule(
"resource://testing-common/BrowserTestUtils.sys.mjs"
);
- const { FirefoxViewPlacesQuery } = ChromeUtils.importESModule(
- "resource:///modules/firefox-view-places-query.sys.mjs"
+ const { PlacesQuery } = ChromeUtils.importESModule(
+ "resource://gre/modules/PlacesQuery.sys.mjs"
);
const { PlacesUtils } = ChromeUtils.importESModule(
"resource://gre/modules/PlacesUtils.sys.mjs"
@@ -52,7 +52,7 @@
const fxviewTabList = document.querySelector("fxview-tab-list");
let tabItems = [];
- const placesQuery = new FirefoxViewPlacesQuery();
+ const placesQuery = new PlacesQuery();
const URLs = [
"http://mochi.test:8888/browser/",
@@ -106,7 +106,20 @@
});
await historyUpdated.promise;
- fxviewTabList.tabItems = [...history.values()].flat();
+ fxviewTabList.tabItems = Array.from(history.values()).flat().map(visit => ({
+ ...visit,
+ time: visit.date.getTime(),
+ title: visit.title || visit.url,
+ icon: `page-icon:${visit.url}`,
+ primaryL10nId: "fxviewtabrow-tabs-list-tab",
+ primaryL10nArgs: JSON.stringify({
+ targetURI: visit.url,
+ }),
+ secondaryL10nId: "fxviewtabrow-options-menu-button",
+ secondaryL10nArgs: JSON.stringify({
+ tabTitle: visit.title || visit.url,
+ }),
+ }));
await fxviewTabList.getUpdateComplete();
tabItems = Array.from(fxviewTabList.rowEls);