summaryrefslogtreecommitdiffstats
path: root/browser/components/firefoxview/tests
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/firefoxview/tests')
-rw-r--r--browser/components/firefoxview/tests/browser/browser.toml8
-rw-r--r--browser/components/firefoxview/tests/browser/browser_firefoxview_dragDrop_pinned_tab.js102
-rw-r--r--browser/components/firefoxview/tests/browser/browser_firefoxview_paused.js99
-rw-r--r--browser/components/firefoxview/tests/browser/browser_firefoxview_search_telemetry.js5
-rw-r--r--browser/components/firefoxview/tests/browser/browser_firefoxview_tab.js6
-rw-r--r--browser/components/firefoxview/tests/browser/browser_history_firefoxview.js15
-rw-r--r--browser/components/firefoxview/tests/browser/browser_opentabs_cards.js10
-rw-r--r--browser/components/firefoxview/tests/browser/browser_opentabs_firefoxview.js4
-rw-r--r--browser/components/firefoxview/tests/browser/browser_opentabs_recency.js350
-rw-r--r--browser/components/firefoxview/tests/browser/browser_opentabs_tab_indicators.js10
-rw-r--r--browser/components/firefoxview/tests/browser/browser_recentlyclosed_firefoxview.js12
-rw-r--r--browser/components/firefoxview/tests/browser/browser_syncedtabs_errors_firefoxview.js272
-rw-r--r--browser/components/firefoxview/tests/browser/browser_syncedtabs_firefoxview.js7
-rw-r--r--browser/components/firefoxview/tests/browser/browser_tab_list_keyboard_navigation.js4
-rw-r--r--browser/components/firefoxview/tests/browser/browser_tab_on_close_warning.js2
-rw-r--r--browser/components/firefoxview/tests/chrome/test_fxview_tab_list.html5
16 files changed, 635 insertions, 276 deletions
diff --git a/browser/components/firefoxview/tests/browser/browser.toml b/browser/components/firefoxview/tests/browser/browser.toml
index 9f9c1c0176..db8b2ea25c 100644
--- a/browser/components/firefoxview/tests/browser/browser.toml
+++ b/browser/components/firefoxview/tests/browser/browser.toml
@@ -27,6 +27,8 @@ skip-if = ["true"] # Bug 1869605 and # Bug 1870296
["browser_firefoxview.js"]
+["browser_firefoxview_dragDrop_pinned_tab.js"]
+
["browser_firefoxview_general_telemetry.js"]
["browser_firefoxview_navigation.js"]
@@ -51,17 +53,15 @@ skip-if = ["true"] # Bug 1851453
["browser_opentabs_firefoxview.js"]
["browser_opentabs_more.js"]
-fail-if = ["a11y_checks"] # Bugs 1858041, 1854625, and 1872174 clicked Show all link is not accessible because it is "hidden" when clicked
skip-if = ["verify"] # Bug 1886017
["browser_opentabs_pinned_tabs.js"]
["browser_opentabs_recency.js"]
skip-if = [
- "os == 'win'",
- "os == 'mac' && verify",
+ "os == 'mac'",
"os == 'linux'"
-] # macos times out, see bug 1857293, skipped for windows, see bug 1858460, Bug 1875877 - frequent fails on linux.
+] # macos times out, see bug 1857293, Bug 1875877 - frequent fails on linux.
["browser_opentabs_search.js"]
fail-if = ["a11y_checks"] # Bug 1850591 clicked moz-page-nav-button button is not focusable
diff --git a/browser/components/firefoxview/tests/browser/browser_firefoxview_dragDrop_pinned_tab.js b/browser/components/firefoxview/tests/browser/browser_firefoxview_dragDrop_pinned_tab.js
new file mode 100644
index 0000000000..dd30d53030
--- /dev/null
+++ b/browser/components/firefoxview/tests/browser/browser_firefoxview_dragDrop_pinned_tab.js
@@ -0,0 +1,102 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function dragAndDrop(
+ tab1,
+ tab2,
+ initialWindow = window,
+ destWindow = window,
+ afterTab = true,
+ context
+) {
+ let rect = tab2.getBoundingClientRect();
+ let event = {
+ ctrlKey: false,
+ altKey: false,
+ clientX: rect.left + rect.width / 2 + 10 * (afterTab ? 1 : -1),
+ clientY: rect.top + rect.height / 2,
+ };
+
+ if (destWindow != initialWindow) {
+ // Make sure that both tab1 and tab2 are visible
+ initialWindow.focus();
+ initialWindow.moveTo(rect.left, rect.top + rect.height * 3);
+ }
+
+ EventUtils.synthesizeDrop(
+ tab1,
+ tab2,
+ null,
+ "move",
+ initialWindow,
+ destWindow,
+ event
+ );
+
+ // Ensure dnd suppression is cleared.
+ EventUtils.synthesizeMouseAtCenter(tab2, { type: "mouseup" }, context);
+}
+
+add_task(async function () {
+ await BrowserTestUtils.openNewForegroundTab(gBrowser, URLs[0]);
+ await BrowserTestUtils.openNewForegroundTab(gBrowser, URLs[1]);
+ await withFirefoxView({}, async browser => {
+ const { document } = browser.contentWindow;
+ let win1 = browser.ownerGlobal;
+ await navigateToViewAndWait(document, "opentabs");
+
+ let openTabs = document.querySelector("view-opentabs[name=opentabs]");
+ await openTabs.updateComplete;
+ await TestUtils.waitForCondition(
+ () => openTabs.viewCards[0].tabList.rowEls.length
+ );
+ await openTabs.openTabsTarget.readyWindowsPromise;
+ let card = openTabs.viewCards[0];
+ let tabRows = card.tabList.rowEls;
+ let tabChangeRaised;
+
+ // Pin first two tabs
+ for (var i = 0; i < 2; i++) {
+ tabChangeRaised = BrowserTestUtils.waitForEvent(
+ NonPrivateTabs,
+ "TabChange"
+ );
+ let currentTabEl = tabRows[i];
+ let currentTab = currentTabEl.tabElement;
+ info(`Pinning tab ${i + 1} with label: ${currentTab.label}`);
+ win1.gBrowser.pinTab(currentTab);
+ await tabChangeRaised;
+ await openTabs.updateComplete;
+ tabRows = card.tabList.rowEls;
+ currentTabEl = tabRows[i];
+
+ await TestUtils.waitForCondition(
+ () => currentTabEl.indicators.includes("pinned"),
+ `Tab ${i + 1} is pinned.`
+ );
+ }
+
+ info(`First two tabs are pinned.`);
+
+ let win2 = await BrowserTestUtils.openNewBrowserWindow();
+
+ await openTabs.updateComplete;
+ await TestUtils.waitForCondition(
+ () => openTabs.viewCards.length === 2,
+ "Two windows are shown for Open Tabs in in Fx View."
+ );
+
+ let pinnedTab = win1.gBrowser.visibleTabs[0];
+ let newWindowTab = win2.gBrowser.visibleTabs[0];
+
+ dragAndDrop(newWindowTab, pinnedTab, win2, win1, true, content);
+
+ await switchToFxViewTab();
+ await openTabs.updateComplete;
+ await TestUtils.waitForCondition(
+ () => openTabs.viewCards.length === 1,
+ "One window is shown for Open Tabs in in Fx View."
+ );
+ });
+ cleanupTabs();
+});
diff --git a/browser/components/firefoxview/tests/browser/browser_firefoxview_paused.js b/browser/components/firefoxview/tests/browser/browser_firefoxview_paused.js
index e61b48b472..52dfce962d 100644
--- a/browser/components/firefoxview/tests/browser/browser_firefoxview_paused.js
+++ b/browser/components/firefoxview/tests/browser/browser_firefoxview_paused.js
@@ -191,42 +191,6 @@ async function checkFxRenderCalls(browser, elements, selectedView) {
sandbox.restore();
}
-function dragAndDrop(
- tab1,
- tab2,
- initialWindow = window,
- destWindow = window,
- afterTab = true,
- context
-) {
- let rect = tab2.getBoundingClientRect();
- let event = {
- ctrlKey: false,
- altKey: false,
- clientX: rect.left + rect.width / 2 + 10 * (afterTab ? 1 : -1),
- clientY: rect.top + rect.height / 2,
- };
-
- if (destWindow != initialWindow) {
- // Make sure that both tab1 and tab2 are visible
- initialWindow.focus();
- initialWindow.moveTo(rect.left, rect.top + rect.height * 3);
- }
-
- EventUtils.synthesizeDrop(
- tab1,
- tab2,
- null,
- "move",
- initialWindow,
- destWindow,
- event
- );
-
- // Ensure dnd suppression is cleared.
- EventUtils.synthesizeMouseAtCenter(tab2, { type: "mouseup" }, context);
-}
-
add_task(async function test_recentbrowsing() {
await setupOpenAndClosedTabs();
@@ -438,66 +402,3 @@ add_task(async function test_recentlyclosed() {
});
await BrowserTestUtils.removeTab(TestTabs.tab2);
});
-
-add_task(async function test_drag_drop_pinned_tab() {
- await setupOpenAndClosedTabs();
- await withFirefoxView({}, async browser => {
- const { document } = browser.contentWindow;
- let win1 = browser.ownerGlobal;
- await navigateToViewAndWait(document, "opentabs");
-
- let openTabs = document.querySelector("view-opentabs[name=opentabs]");
- await openTabs.updateComplete;
- await TestUtils.waitForCondition(
- () => openTabs.viewCards[0].tabList.rowEls.length
- );
- await openTabs.openTabsTarget.readyWindowsPromise;
- let card = openTabs.viewCards[0];
- let tabRows = card.tabList.rowEls;
- let tabChangeRaised;
-
- // Pin first two tabs
- for (var i = 0; i < 2; i++) {
- tabChangeRaised = BrowserTestUtils.waitForEvent(
- NonPrivateTabs,
- "TabChange"
- );
- let currentTabEl = tabRows[i];
- let currentTab = currentTabEl.tabElement;
- info(`Pinning tab ${i + 1} with label: ${currentTab.label}`);
- win1.gBrowser.pinTab(currentTab);
- await tabChangeRaised;
- await openTabs.updateComplete;
- tabRows = card.tabList.rowEls;
- currentTabEl = tabRows[i];
-
- await TestUtils.waitForCondition(
- () => currentTabEl.indicators.includes("pinned"),
- `Tab ${i + 1} is pinned.`
- );
- }
-
- info(`First two tabs are pinned.`);
-
- let win2 = await BrowserTestUtils.openNewBrowserWindow();
-
- await openTabs.updateComplete;
- await TestUtils.waitForCondition(
- () => openTabs.viewCards.length === 2,
- "Two windows are shown for Open Tabs in in Fx View."
- );
-
- let pinnedTab = win1.gBrowser.visibleTabs[0];
- let newWindowTab = win2.gBrowser.visibleTabs[0];
-
- dragAndDrop(newWindowTab, pinnedTab, win2, win1, true, content);
-
- await switchToFxViewTab();
- await openTabs.updateComplete;
- await TestUtils.waitForCondition(
- () => openTabs.viewCards.length === 1,
- "One window is shown for Open Tabs in in Fx View."
- );
- });
- cleanupTabs();
-});
diff --git a/browser/components/firefoxview/tests/browser/browser_firefoxview_search_telemetry.js b/browser/components/firefoxview/tests/browser/browser_firefoxview_search_telemetry.js
index c76a11d3ad..e1aa58ae49 100644
--- a/browser/components/firefoxview/tests/browser/browser_firefoxview_search_telemetry.js
+++ b/browser/components/firefoxview/tests/browser/browser_firefoxview_search_telemetry.js
@@ -537,7 +537,7 @@ add_task(async function test_cumulative_searches_history_telemetry() {
() =>
history.fullyUpdated &&
history?.lists[0].rowEls?.length === 1 &&
- history?.searchQuery,
+ history?.controller?.searchQuery,
"Expected search results are not shown yet."
);
@@ -605,7 +605,8 @@ add_task(async function test_cumulative_searches_syncedtabs_telemetry() {
);
await TestUtils.waitForCondition(
() =>
- syncedTabs.tabLists[0].rowEls.length === 1 && syncedTabs?.searchQuery,
+ syncedTabs.tabLists[0].rowEls.length === 1 &&
+ syncedTabs.controller.searchQuery,
"Expected search results are not shown yet."
);
diff --git a/browser/components/firefoxview/tests/browser/browser_firefoxview_tab.js b/browser/components/firefoxview/tests/browser/browser_firefoxview_tab.js
index 037729ea7d..b556649d52 100644
--- a/browser/components/firefoxview/tests/browser/browser_firefoxview_tab.js
+++ b/browser/components/firefoxview/tests/browser/browser_firefoxview_tab.js
@@ -78,7 +78,7 @@ add_task(async function aria_attributes() {
"true",
'Firefox View button should have `aria-pressed="true"` upon selecting it'
);
- win.BrowserOpenTab();
+ win.BrowserCommands.openTab();
is(
win.FirefoxViewHandler.button.getAttribute("aria-pressed"),
"false",
@@ -118,8 +118,8 @@ add_task(async function homepage_new_tab() {
win.gBrowser.tabContainer,
"TabOpen"
);
- win.BrowserHome();
- info("Waiting for BrowserHome() to open a new tab");
+ win.BrowserCommands.home();
+ info("Waiting for BrowserCommands.home() to open a new tab");
await newTabOpened;
assertFirefoxViewTab(win);
ok(
diff --git a/browser/components/firefoxview/tests/browser/browser_history_firefoxview.js b/browser/components/firefoxview/tests/browser/browser_history_firefoxview.js
index c4c096acff..847ce4d9fd 100644
--- a/browser/components/firefoxview/tests/browser/browser_history_firefoxview.js
+++ b/browser/components/firefoxview/tests/browser/browser_history_firefoxview.js
@@ -58,14 +58,14 @@ function isElInViewport(element) {
async function historyComponentReady(historyComponent, expectedHistoryItems) {
await TestUtils.waitForCondition(
() =>
- [...historyComponent.allHistoryItems.values()].reduce(
+ [...historyComponent.controller.allHistoryItems.values()].reduce(
(acc, { length }) => acc + length,
0
) === expectedHistoryItems,
"History component ready"
);
- let expected = historyComponent.historyMapByDate.length;
+ let expected = historyComponent.controller.historyMapByDate.length;
let actual = historyComponent.cards.length;
is(expected, actual, `Total number of cards should be ${expected}`);
@@ -242,7 +242,8 @@ add_task(async function test_list_ordering() {
await TestUtils.waitForCondition(() => historyComponent.fullyUpdated);
await sortHistoryTelemetry(sortHistoryEvent);
- let expectedNumOfCards = historyComponent.historyMapBySite.length;
+ let expectedNumOfCards =
+ historyComponent.controller.historyMapBySite.length;
info(`Total number of cards should be ${expectedNumOfCards}`);
await BrowserTestUtils.waitForMutationCondition(
@@ -345,7 +346,7 @@ add_task(async function test_empty_states() {
"Import history banner is shown"
);
let importHistoryCloseButton =
- historyComponent.cards[0].querySelector("button.close");
+ historyComponent.cards[0].querySelector("moz-button.close");
importHistoryCloseButton.click();
await TestUtils.waitForCondition(() => historyComponent.fullyUpdated);
ok(
@@ -484,7 +485,7 @@ add_task(async function test_search_history() {
{ childList: true, subtree: true },
() =>
historyComponent.cards.length ===
- historyComponent.historyMapByDate.length
+ historyComponent.controller.historyMapByDate.length
);
searchTextbox.blur();
@@ -513,7 +514,7 @@ add_task(async function test_search_history() {
{ childList: true, subtree: true },
() =>
historyComponent.cards.length ===
- historyComponent.historyMapByDate.length
+ historyComponent.controller.historyMapByDate.length
);
});
});
@@ -528,7 +529,7 @@ add_task(async function test_persist_collapse_card_after_view_change() {
historyComponent.profileAge = 8;
await TestUtils.waitForCondition(
() =>
- [...historyComponent.allHistoryItems.values()].reduce(
+ [...historyComponent.controller.allHistoryItems.values()].reduce(
(acc, { length }) => acc + length,
0
) === 4
diff --git a/browser/components/firefoxview/tests/browser/browser_opentabs_cards.js b/browser/components/firefoxview/tests/browser/browser_opentabs_cards.js
index d4de3ae5a9..5fdcf89d70 100644
--- a/browser/components/firefoxview/tests/browser/browser_opentabs_cards.js
+++ b/browser/components/firefoxview/tests/browser/browser_opentabs_cards.js
@@ -203,13 +203,15 @@ add_task(async function open_tab_new_window() {
const cards = getOpenTabsCards(openTabs);
const originalWinRows = await getTabRowsForCard(cards[1]);
const [row] = originalWinRows;
+
+ // We hide date/time and URL columns in tab rows when there are multiple window cards for spacial reasons
ok(
- row.shadowRoot.getElementById("fxview-tab-row-url").hidden,
- "The URL is hidden, since we have two windows."
+ !row.shadowRoot.getElementById("fxview-tab-row-url"),
+ "The URL span element isn't found within the tab row as expected, since we have two open windows."
);
ok(
- row.shadowRoot.getElementById("fxview-tab-row-date").hidden,
- "The date is hidden, since we have two windows."
+ !row.shadowRoot.getElementById("fxview-tab-row-date"),
+ "The date span element isn't found within the tab row as expected, since we have two open windows."
);
info("Select a tab from the original window.");
tabChangeRaised = BrowserTestUtils.waitForEvent(
diff --git a/browser/components/firefoxview/tests/browser/browser_opentabs_firefoxview.js b/browser/components/firefoxview/tests/browser/browser_opentabs_firefoxview.js
index 955c2363d7..2c415e7aa2 100644
--- a/browser/components/firefoxview/tests/browser/browser_opentabs_firefoxview.js
+++ b/browser/components/firefoxview/tests/browser/browser_opentabs_firefoxview.js
@@ -131,7 +131,7 @@ async function moreMenuSetup() {
}
add_task(async function test_close_open_tab() {
- await withFirefoxView({}, async browser => {
+ await withFirefoxView({}, async () => {
const [cards, rows] = await moreMenuSetup();
const firstTab = rows[0];
const tertiaryButtonEl = firstTab.tertiaryButtonEl;
@@ -321,7 +321,7 @@ add_task(async function test_send_device_submenu() {
.stub(gSync, "getSendTabTargets")
.callsFake(() => fxaDevicesWithCommands);
- await withFirefoxView({}, async browser => {
+ await withFirefoxView({}, async () => {
// TEST_URL1 is our only tab, left over from previous test
Assert.deepEqual(
getVisibleTabURLs(),
diff --git a/browser/components/firefoxview/tests/browser/browser_opentabs_recency.js b/browser/components/firefoxview/tests/browser/browser_opentabs_recency.js
index ee3f9981e1..fc10ef2eb0 100644
--- a/browser/components/firefoxview/tests/browser/browser_opentabs_recency.js
+++ b/browser/components/firefoxview/tests/browser/browser_opentabs_recency.js
@@ -2,23 +2,30 @@
* http://creativecommons.org/publicdomain/zero/1.0/ */
/*
- This test checks the recent-browsing view of open tabs in about:firefoxview next
+ This test checks that the recent-browsing view of open tabs in about:firefoxview
presents the correct tab data in the correct order.
*/
+SimpleTest.requestCompleteLog();
+
+const { ObjectUtils } = ChromeUtils.importESModule(
+ "resource://gre/modules/ObjectUtils.sys.mjs"
+);
+let origBrowserState;
const tabURL1 = "data:,Tab1";
const tabURL2 = "data:,Tab2";
const tabURL3 = "data:,Tab3";
const tabURL4 = "data:,Tab4";
-let gInitialTab;
-let gInitialTabURL;
-
add_setup(function () {
- gInitialTab = gBrowser.selectedTab;
- gInitialTabURL = tabUrl(gInitialTab);
+ origBrowserState = SessionStore.getBrowserState();
});
+async function cleanup() {
+ await switchToWindow(window);
+ await SessionStoreTestUtils.promiseBrowserState(origBrowserState);
+}
+
function tabUrl(tab) {
return tab.linkedBrowser.currentURI?.spec;
}
@@ -37,6 +44,12 @@ async function minimizeWindow(win) {
ok(win.document.hidden, "Top level window should be hidden");
}
+function getAllSelectedTabURLs() {
+ return BrowserWindowTracker.orderedWindows.map(win =>
+ tabUrl(win.gBrowser.selectedTab)
+ );
+}
+
async function restoreWindow(win) {
ok(win.document.hidden, "Top level window should be hidden");
let promiseSizeModeChange = BrowserTestUtils.waitForEvent(
@@ -93,86 +106,91 @@ async function restoreWindow(win) {
ok(!win.document.hidden, "Top level window should be visible");
}
-async function prepareOpenTabs(urls, win = window) {
- const reusableTabURLs = ["about:newtab", "about:blank"];
- const gBrowser = win.gBrowser;
-
- for (let url of urls) {
- if (
- gBrowser.visibleTabs.length == 1 &&
- reusableTabURLs.includes(gBrowser.selectedBrowser.currentURI.spec)
- ) {
- // we'll load into this tab rather than opening a new one
- info(
- `Loading ${url} into blank tab: ${gBrowser.selectedBrowser.currentURI.spec}`
- );
- BrowserTestUtils.startLoadingURIString(gBrowser.selectedBrowser, url);
- await BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser, null, url);
- } else {
- info(`Loading ${url} into new tab`);
- await BrowserTestUtils.openNewForegroundTab(gBrowser, url);
- }
- await new Promise(res => win.requestAnimationFrame(res));
+async function prepareOpenWindowsAndTabs(windowsData) {
+ // windowsData selected tab URL should be unique so we can map tab URL to window
+ const browserState = {
+ windows: windowsData.map((winData, index) => {
+ const tabs = winData.tabs.map(url => ({
+ entries: [{ url, triggeringPrincipal_base64 }],
+ }));
+ return {
+ tabs,
+ selected: winData.selectedIndex + 1,
+ zIndex: index + 1,
+ };
+ }),
+ };
+ await SessionStoreTestUtils.promiseBrowserState(browserState);
+ await NonPrivateTabs.readyWindowsPromise;
+ const selectedTabURLOrder = browserState.windows.map(winData => {
+ return winData.tabs[winData.selected - 1].entries[0].url;
+ });
+ const windowByTabURL = new Map();
+ for (let win of BrowserWindowTracker.orderedWindows) {
+ windowByTabURL.set(tabUrl(win.gBrowser.selectedTab), win);
}
- Assert.equal(
- gBrowser.visibleTabs.length,
- urls.length,
- `Prepared ${urls.length} tabs as expected`
- );
- Assert.equal(
- tabUrl(gBrowser.selectedTab),
- urls[urls.length - 1],
- "The selectedTab is the last of the URLs given as expected"
+ is(
+ windowByTabURL.size,
+ windowsData.length,
+ "The tab URL to window mapping includes an entry for each window"
);
-}
-
-async function cleanup(...windowsToClose) {
- await Promise.all(
- windowsToClose.map(win => BrowserTestUtils.closeWindow(win))
+ info(
+ `After promiseBrowserState, selected tab order is: ${Array.from(
+ windowByTabURL.keys()
+ )}`
);
- while (gBrowser.visibleTabs.length > 1) {
- await SessionStoreTestUtils.closeTab(gBrowser.tabs.at(-1));
- }
- if (gBrowser.selectedBrowser.currentURI.spec !== gInitialTabURL) {
- BrowserTestUtils.startLoadingURIString(
- gBrowser.selectedBrowser,
- gInitialTabURL
- );
- await BrowserTestUtils.browserLoaded(
- gBrowser.selectedBrowser,
- null,
- gInitialTabURL
- );
+ // Make any corrections to the window order by selecting each in reverse order
+ for (let url of selectedTabURLOrder.toReversed()) {
+ await switchToWindow(windowByTabURL.get(url));
}
+ // Verify windows are in the expected order
+ Assert.deepEqual(
+ getAllSelectedTabURLs(),
+ selectedTabURLOrder,
+ "The windows and their selected tabs are in the expected order"
+ );
+ Assert.deepEqual(
+ BrowserWindowTracker.orderedWindows.map(win =>
+ win.gBrowser.visibleTabs.map(tab => tabUrl(tab))
+ ),
+ windowsData.map(winData => winData.tabs),
+ "We opened all the tabs in each window"
+ );
}
-function getOpenTabsComponent(browser) {
+function getRecentOpenTabsComponent(browser) {
return browser.contentDocument.querySelector(
"view-recentbrowsing view-opentabs"
);
}
-async function checkTabList(browser, expected) {
- const tabsView = getOpenTabsComponent(browser);
+async function checkRecentTabList(browser, expected) {
+ const tabsView = getRecentOpenTabsComponent(browser);
const [openTabsCard] = getOpenTabsCards(tabsView);
await openTabsCard.updateComplete;
const tabListRows = await getTabRowsForCard(openTabsCard);
Assert.ok(tabListRows, "Found the tab list element");
let actual = Array.from(tabListRows).map(row => row.url);
- Assert.deepEqual(
- actual,
- expected,
- "Tab list has items with URLs in the expected order"
+ await BrowserTestUtils.waitForCondition(
+ () => ObjectUtils.deepEqual(actual, expected),
+ "Waiting for tab list to hvae items with URLs in the expected order"
);
}
add_task(async function test_single_window_tabs() {
- await prepareOpenTabs([tabURL1, tabURL2]);
+ const testData = [
+ {
+ tabs: [tabURL1, tabURL2],
+ selectedIndex: 1, // the 2nd tab should be selected
+ },
+ ];
+ await prepareOpenWindowsAndTabs(testData);
+
await openFirefoxViewTab(window).then(async viewTab => {
const browser = viewTab.linkedBrowser;
- await checkTabList(browser, [tabURL2, tabURL1]);
+ await checkRecentTabList(browser, [tabURL2, tabURL1]);
// switch to the first tab
let promiseHidden = BrowserTestUtils.waitForEvent(
@@ -192,25 +210,62 @@ add_task(async function test_single_window_tabs() {
// and check the results in the open tabs section of Recent Browsing
await openFirefoxViewTab(window).then(async viewTab => {
const browser = viewTab.linkedBrowser;
- await checkTabList(browser, [tabURL1, tabURL2]);
+ await checkRecentTabList(browser, [tabURL1, tabURL2]);
});
await cleanup();
});
add_task(async function test_multiple_window_tabs() {
const fxViewURL = getFirefoxViewURL();
- const win1 = window;
+ const testData = [
+ {
+ // this window should be active after restore
+ tabs: [tabURL1, tabURL2],
+ selectedIndex: 0, // tabURL1 should be selected
+ },
+ {
+ tabs: [tabURL3, tabURL4],
+ selectedIndex: 0, // tabURL3 should be selected
+ },
+ ];
+ await prepareOpenWindowsAndTabs(testData);
+
+ Assert.deepEqual(
+ getAllSelectedTabURLs(),
+ [tabURL1, tabURL3],
+ "The windows and their selected tabs are in the expected order"
+ );
let tabChangeRaised;
- await prepareOpenTabs([tabURL1, tabURL2]);
- const win2 = await BrowserTestUtils.openNewBrowserWindow();
- await prepareOpenTabs([tabURL3, tabURL4], win2);
+ const [win1, win2] = BrowserWindowTracker.orderedWindows;
+
+ info(`Switch to window 1's 2nd tab: ${tabUrl(win1.gBrowser.visibleTabs[1])}`);
+ await BrowserTestUtils.switchTab(gBrowser, win1.gBrowser.visibleTabs[1]);
+ await switchToWindow(win2);
+
+ Assert.deepEqual(
+ getAllSelectedTabURLs(),
+ [tabURL3, tabURL2],
+ `Window 2 has selected the ${tabURL3} tab, window 1 has ${tabURL2}`
+ );
+ info(`Switch to window 2's 2nd tab: ${tabUrl(win2.gBrowser.visibleTabs[1])}`);
+ tabChangeRaised = BrowserTestUtils.waitForEvent(
+ NonPrivateTabs,
+ "TabRecencyChange"
+ );
+ await BrowserTestUtils.switchTab(win2.gBrowser, win2.gBrowser.visibleTabs[1]);
+ await tabChangeRaised;
+ Assert.deepEqual(
+ getAllSelectedTabURLs(),
+ [tabURL4, tabURL2],
+ `window 2 has selected the ${tabURL4} tab, ${tabURL2} remains selected in window 1`
+ );
// to avoid confusing the results by activating different windows,
// check fxview in the current window - which is win2
info("Switching to fxview tab in win2");
await openFirefoxViewTab(win2).then(async viewTab => {
const browser = viewTab.linkedBrowser;
- await checkTabList(browser, [tabURL4, tabURL3, tabURL2, tabURL1]);
+ await checkRecentTabList(browser, [tabURL4, tabURL3, tabURL2, tabURL1]);
Assert.equal(
tabUrl(win2.gBrowser.selectedTab),
@@ -218,7 +273,7 @@ add_task(async function test_multiple_window_tabs() {
`The selected tab in window 2 is ${fxViewURL}`
);
- info("Switching to first tab (tab3) in win2");
+ info("Switching to first tab in win2");
tabChangeRaised = BrowserTestUtils.waitForEvent(
NonPrivateTabs,
"TabRecencyChange"
@@ -231,20 +286,20 @@ add_task(async function test_multiple_window_tabs() {
win2.gBrowser,
win2.gBrowser.visibleTabs[0]
);
- Assert.equal(
- tabUrl(win2.gBrowser.selectedTab),
- tabURL3,
- `The selected tab in window 2 is ${tabURL3}`
- );
await tabChangeRaised;
await promiseHidden;
+ Assert.deepEqual(
+ getAllSelectedTabURLs(),
+ [tabURL3, tabURL2],
+ `window 2 has switched to ${tabURL3}, ${tabURL2} remains selected in window 1`
+ );
});
info("Opening fxview in win2 to confirm tab3 is most recent");
await openFirefoxViewTab(win2).then(async viewTab => {
const browser = viewTab.linkedBrowser;
info("Check result of selecting 1ist tab in window 2");
- await checkTabList(browser, [tabURL3, tabURL4, tabURL2, tabURL1]);
+ await checkRecentTabList(browser, [tabURL3, tabURL4, tabURL2, tabURL1]);
});
info("Focusing win1, where tab2 should be selected");
@@ -254,10 +309,10 @@ add_task(async function test_multiple_window_tabs() {
);
await switchToWindow(win1);
await tabChangeRaised;
- Assert.equal(
- tabUrl(win1.gBrowser.selectedTab),
- tabURL2,
- `The selected tab in window 1 is ${tabURL2}`
+ Assert.deepEqual(
+ getAllSelectedTabURLs(),
+ [tabURL2, fxViewURL],
+ `The selected tab in window 1 is ${tabURL2}, ${fxViewURL} remains selected in window 2`
);
info("Opening fxview in win1 to confirm tab2 is most recent");
@@ -266,7 +321,7 @@ add_task(async function test_multiple_window_tabs() {
info(
"In fxview, check result of activating window 1, where tab 2 is selected"
);
- await checkTabList(browser, [tabURL2, tabURL3, tabURL4, tabURL1]);
+ await checkRecentTabList(browser, [tabURL2, tabURL3, tabURL4, tabURL1]);
let promiseHidden = BrowserTestUtils.waitForEvent(
browser.contentDocument,
@@ -284,45 +339,50 @@ add_task(async function test_multiple_window_tabs() {
await promiseHidden;
await tabChangeRaised;
});
+ Assert.deepEqual(
+ getAllSelectedTabURLs(),
+ [tabURL1, fxViewURL],
+ `The selected tab in window 1 is ${tabURL1}, ${fxViewURL} remains selected in window 2`
+ );
// check result in the fxview in the 1st window
info("Opening fxview in win1 to confirm tab1 is most recent");
await openFirefoxViewTab(win1).then(async viewTab => {
const browser = viewTab.linkedBrowser;
info("Check result of selecting 1st tab in win1");
- await checkTabList(browser, [tabURL1, tabURL2, tabURL3, tabURL4]);
+ await checkRecentTabList(browser, [tabURL1, tabURL2, tabURL3, tabURL4]);
});
- await cleanup(win2);
+ await cleanup();
});
add_task(async function test_windows_activation() {
- const win1 = window;
- await prepareOpenTabs([tabURL1], win1);
- let fxViewTab;
- let tabChangeRaised;
- info("switch to firefox-view and leave it selected");
- await openFirefoxViewTab(win1).then(tab => (fxViewTab = tab));
+ // use Session restore to batch-open windows and tabs
+ const testData = [
+ {
+ // this window should be active after restore
+ tabs: [tabURL1],
+ selectedIndex: 0, // tabURL1 should be selected
+ },
+ {
+ tabs: [tabURL2],
+ selectedIndex: 0, // tabURL2 should be selected
+ },
+ {
+ tabs: [tabURL3],
+ selectedIndex: 0, // tabURL3 should be selected
+ },
+ ];
+ await prepareOpenWindowsAndTabs(testData);
- const win2 = await BrowserTestUtils.openNewBrowserWindow();
- await switchToWindow(win2);
- await prepareOpenTabs([tabURL2], win2);
-
- const win3 = await BrowserTestUtils.openNewBrowserWindow();
- await switchToWindow(win3);
- await prepareOpenTabs([tabURL3], win3);
-
- tabChangeRaised = BrowserTestUtils.waitForEvent(
- NonPrivateTabs,
- "TabRecencyChange"
- );
- info("Switching back to win 1");
- await switchToWindow(win1);
- info("Waiting for tabChangeRaised to resolve");
- await tabChangeRaised;
+ let tabChangeRaised;
+ const [win1, win2] = BrowserWindowTracker.orderedWindows;
- const browser = fxViewTab.linkedBrowser;
- await checkTabList(browser, [tabURL3, tabURL2, tabURL1]);
+ info("switch to firefox-view and leave it selected");
+ await openFirefoxViewTab(win1).then(async viewTab => {
+ const browser = viewTab.linkedBrowser;
+ await checkRecentTabList(browser, [tabURL1, tabURL2, tabURL3]);
+ });
info("switch to win2 and confirm its selected tab becomes most recent");
tabChangeRaised = BrowserTestUtils.waitForEvent(
@@ -331,24 +391,52 @@ add_task(async function test_windows_activation() {
);
await switchToWindow(win2);
await tabChangeRaised;
- await checkTabList(browser, [tabURL2, tabURL3, tabURL1]);
- await cleanup(win2, win3);
+ await openFirefoxViewTab(win1).then(async viewTab => {
+ await checkRecentTabList(viewTab.linkedBrowser, [
+ tabURL2,
+ tabURL1,
+ tabURL3,
+ ]);
+ });
+ await cleanup();
});
add_task(async function test_minimize_restore_windows() {
- const win1 = window;
- let tabChangeRaised;
- await prepareOpenTabs([tabURL1, tabURL2]);
- const win2 = await BrowserTestUtils.openNewBrowserWindow();
- await prepareOpenTabs([tabURL3, tabURL4], win2);
- await NonPrivateTabs.readyWindowsPromise;
+ const fxViewURL = getFirefoxViewURL();
+ const testData = [
+ {
+ // this window should be active after restore
+ tabs: [tabURL1, tabURL2],
+ selectedIndex: 1, // tabURL2 should be selected
+ },
+ {
+ tabs: [tabURL3, tabURL4],
+ selectedIndex: 0, // tabURL3 should be selected
+ },
+ ];
+ await prepareOpenWindowsAndTabs(testData);
+ const [win1, win2] = BrowserWindowTracker.orderedWindows;
+
+ // switch to the last (tabURL4) tab in window 2
+ await switchToWindow(win2);
+ let tabChangeRaised = BrowserTestUtils.waitForEvent(
+ NonPrivateTabs,
+ "TabRecencyChange"
+ );
+ await BrowserTestUtils.switchTab(win2.gBrowser, win2.gBrowser.visibleTabs[1]);
+ await tabChangeRaised;
+ Assert.deepEqual(
+ getAllSelectedTabURLs(),
+ [tabURL4, tabURL2],
+ "The windows and their selected tabs are in the expected order"
+ );
// to avoid confusing the results by activating different windows,
// check fxview in the current window - which is win2
info("Opening fxview in win2 to confirm tab4 is most recent");
await openFirefoxViewTab(win2).then(async viewTab => {
const browser = viewTab.linkedBrowser;
- await checkTabList(browser, [tabURL4, tabURL3, tabURL2, tabURL1]);
+ await checkRecentTabList(browser, [tabURL4, tabURL3, tabURL2, tabURL1]);
let promiseHidden = BrowserTestUtils.waitForEvent(
browser.contentDocument,
@@ -366,6 +454,11 @@ add_task(async function test_minimize_restore_windows() {
await promiseHidden;
await tabChangeRaised;
});
+ Assert.deepEqual(
+ getAllSelectedTabURLs(),
+ [tabURL3, tabURL2],
+ `Window 2 has ${tabURL3} selected, window 1 remains at ${tabURL2}`
+ );
// then minimize the window, focusing the 1st window
info("Minimizing win2, leaving tab 3 selected");
@@ -378,32 +471,41 @@ add_task(async function test_minimize_restore_windows() {
await switchToWindow(win1);
await tabChangeRaised;
- Assert.equal(
- tabUrl(win1.gBrowser.selectedTab),
- tabURL2,
- `The selected tab in window 1 is ${tabURL2}`
+ Assert.deepEqual(
+ getAllSelectedTabURLs(),
+ [tabURL2, tabURL3],
+ `Window 1 has ${tabURL2} selected, window 2 remains at ${tabURL3}`
);
info("Opening fxview in win1 to confirm tab2 is most recent");
await openFirefoxViewTab(win1).then(async viewTab => {
const browser = viewTab.linkedBrowser;
- await checkTabList(browser, [tabURL2, tabURL3, tabURL4, tabURL1]);
+ await checkRecentTabList(browser, [tabURL2, tabURL3, tabURL4, tabURL1]);
info(
"Restoring win2 and focusing it - which should make its selected tab most recent"
);
tabChangeRaised = BrowserTestUtils.waitForEvent(
NonPrivateTabs,
- "TabRecencyChange"
+ "TabRecencyChange",
+ false,
+ event => event.detail.sourceEvents?.includes("activate")
);
await restoreWindow(win2);
await switchToWindow(win2);
+ // make sure we wait for the activate event from OpenTabs.
await tabChangeRaised;
+ Assert.deepEqual(
+ getAllSelectedTabURLs(),
+ [tabURL3, fxViewURL],
+ `Window 2 was restored and has ${tabURL3} selected, window 1 remains at ${fxViewURL}`
+ );
+
info(
"Checking tab order in fxview in win1, to confirm tab3 is most recent"
);
- await checkTabList(browser, [tabURL3, tabURL2, tabURL4, tabURL1]);
+ await checkRecentTabList(browser, [tabURL3, tabURL2, tabURL4, tabURL1]);
});
-
- await cleanup(win2);
+ info("test done, waiting for cleanup");
+ await cleanup();
});
diff --git a/browser/components/firefoxview/tests/browser/browser_opentabs_tab_indicators.js b/browser/components/firefoxview/tests/browser/browser_opentabs_tab_indicators.js
index 78fab976ed..4403a8e36a 100644
--- a/browser/components/firefoxview/tests/browser/browser_opentabs_tab_indicators.js
+++ b/browser/components/firefoxview/tests/browser/browser_opentabs_tab_indicators.js
@@ -94,12 +94,16 @@ add_task(async function test_container_indicator() {
await TestUtils.waitForCondition(
() =>
Array.from(openTabs.viewCards[0].tabList.rowEls).some(rowEl => {
- containerTabElem = rowEl;
- return rowEl.containerObj;
+ let hasContainerObj;
+ if (rowEl.containerObj?.icon) {
+ containerTabElem = rowEl;
+ hasContainerObj = rowEl.containerObj;
+ }
+
+ return hasContainerObj;
}),
"The container tab element isn't marked in Fx View."
);
-
ok(
containerTabElem.shadowRoot
.querySelector(".fxview-tab-row-container-indicator")
diff --git a/browser/components/firefoxview/tests/browser/browser_recentlyclosed_firefoxview.js b/browser/components/firefoxview/tests/browser/browser_recentlyclosed_firefoxview.js
index fcfcf20562..85879667bb 100644
--- a/browser/components/firefoxview/tests/browser/browser_recentlyclosed_firefoxview.js
+++ b/browser/components/firefoxview/tests/browser/browser_recentlyclosed_firefoxview.js
@@ -372,6 +372,12 @@ add_task(async function test_dismiss_tab() {
info("calling dismiss_tab on the top, most-recently closed tab");
let closedTabItem = listItems[0];
+ // the most recently closed tab was in window 3 which got closed
+ // so we expect a sourceClosedId on the item element
+ ok(
+ !isNaN(closedTabItem.sourceClosedId),
+ "Item has a sourceClosedId property"
+ );
// dismiss the first tab and verify the list is correctly updated
await dismiss_tab(closedTabItem);
@@ -390,6 +396,12 @@ add_task(async function test_dismiss_tab() {
// dismiss the last tab and verify the list is correctly updated
closedTabItem = listItems[listItems.length - 1];
+ ok(
+ isNaN(closedTabItem.sourceClosedId),
+ "Item does not have a sourceClosedId property"
+ );
+ ok(closedTabItem.sourceWindowId, "Item has a sourceWindowId property");
+
await dismiss_tab(closedTabItem);
await listElem.getUpdateComplete;
diff --git a/browser/components/firefoxview/tests/browser/browser_syncedtabs_errors_firefoxview.js b/browser/components/firefoxview/tests/browser/browser_syncedtabs_errors_firefoxview.js
index 86e4d9cdee..a644b39fc6 100644
--- a/browser/components/firefoxview/tests/browser/browser_syncedtabs_errors_firefoxview.js
+++ b/browser/components/firefoxview/tests/browser/browser_syncedtabs_errors_firefoxview.js
@@ -69,19 +69,23 @@ add_task(async function test_network_offline() {
"view-syncedtabs:not([slot=syncedtabs])"
);
await TestUtils.waitForCondition(() => syncedTabsComponent.fullyUpdated);
- await BrowserTestUtils.waitForMutationCondition(
- syncedTabsComponent.shadowRoot.querySelector(".cards-container"),
- { childList: true },
- () => syncedTabsComponent.shadowRoot.innerHTML.includes("network-offline")
+ await TestUtils.waitForCondition(
+ () =>
+ syncedTabsComponent.emptyState.shadowRoot.textContent.includes(
+ "Check your internet connection"
+ ),
+ "The expected network offline error message is displayed."
);
- let emptyState =
- syncedTabsComponent.shadowRoot.querySelector("fxview-empty-state");
ok(
- emptyState.getAttribute("headerlabel").includes("network-offline"),
+ syncedTabsComponent.emptyState
+ .getAttribute("headerlabel")
+ .includes("network-offline"),
"Network offline message is shown"
);
- emptyState.querySelector("button[data-action='network-offline']").click();
+ syncedTabsComponent.emptyState
+ .querySelector("button[data-action='network-offline']")
+ .click();
await BrowserTestUtils.waitForCondition(
() => TabsSetupFlowManager.tryToClearError.calledOnce
@@ -92,10 +96,10 @@ add_task(async function test_network_offline() {
"TabsSetupFlowManager.tryToClearError() was called once"
);
- emptyState =
- syncedTabsComponent.shadowRoot.querySelector("fxview-empty-state");
ok(
- emptyState.getAttribute("headerlabel").includes("network-offline"),
+ syncedTabsComponent.emptyState
+ .getAttribute("headerlabel")
+ .includes("network-offline"),
"Network offline message is still shown"
);
@@ -121,16 +125,18 @@ add_task(async function test_sync_error() {
"view-syncedtabs:not([slot=syncedtabs])"
);
await TestUtils.waitForCondition(() => syncedTabsComponent.fullyUpdated);
- await BrowserTestUtils.waitForMutationCondition(
- syncedTabsComponent.shadowRoot.querySelector(".cards-container"),
- { childList: true },
- () => syncedTabsComponent.shadowRoot.innerHTML.includes("sync-error")
+ await TestUtils.waitForCondition(
+ () =>
+ syncedTabsComponent.emptyState.shadowRoot.textContent.includes(
+ "having trouble syncing"
+ ),
+ "Sync error message is shown."
);
- let emptyState =
- syncedTabsComponent.shadowRoot.querySelector("fxview-empty-state");
ok(
- emptyState.getAttribute("headerlabel").includes("sync-error"),
+ syncedTabsComponent.emptyState
+ .getAttribute("headerlabel")
+ .includes("sync-error"),
"Correct message should show when there's a sync service error"
);
@@ -139,3 +145,233 @@ add_task(async function test_sync_error() {
});
await tearDown(sandbox);
});
+
+add_task(async function test_sync_disabled_by_policy() {
+ await SpecialPowers.pushPrefEnv({
+ set: [["identity.fxaccounts.enabled", false]],
+ });
+ await withFirefoxView({}, async browser => {
+ const { document } = browser.contentWindow;
+ const recentBrowsingSyncedTabs = document.querySelector(
+ "view-syncedtabs[slot=syncedtabs]"
+ );
+ const syncedtabsPageNavButton = document.querySelector(
+ "moz-page-nav-button[view='syncedtabs']"
+ );
+
+ ok(
+ BrowserTestUtils.isHidden(recentBrowsingSyncedTabs),
+ "Synced tabs should not be visible from recent browsing."
+ );
+ ok(
+ BrowserTestUtils.isHidden(syncedtabsPageNavButton),
+ "Synced tabs nav button should not be visible."
+ );
+
+ document.location.assign(`${getFirefoxViewURL()}#syncedtabs`);
+ await TestUtils.waitForTick();
+ is(
+ document.querySelector("moz-page-nav").currentView,
+ "recentbrowsing",
+ "Should not be able to navigate to synced tabs."
+ );
+ });
+ await tearDown();
+});
+
+add_task(async function test_sync_error_signed_out() {
+ // sync error should not show if user is not signed in
+ let sandbox = await setupWithDesktopDevices(UIState.STATUS_NOT_CONFIGURED);
+ await withFirefoxView({}, async browser => {
+ const { document } = browser.contentWindow;
+ await navigateToViewAndWait(document, "syncedtabs");
+ Services.obs.notifyObservers(null, UIState.ON_UPDATE);
+ Services.obs.notifyObservers(null, "weave:service:sync:error");
+
+ let syncedTabsComponent = document.querySelector(
+ "view-syncedtabs:not([slot=syncedtabs])"
+ );
+ await TestUtils.waitForCondition(
+ () => syncedTabsComponent.fullyUpdated,
+ "The synced tabs component has finished updating."
+ );
+ await TestUtils.waitForCondition(
+ () =>
+ syncedTabsComponent.emptyState.shadowRoot.textContent.includes(
+ "sign in to your account"
+ ),
+ "Sign in header is shown."
+ );
+
+ ok(
+ syncedTabsComponent.emptyState
+ .getAttribute("headerlabel")
+ .includes("signin-header"),
+ "Sign in message is shown"
+ );
+ });
+ await tearDown(sandbox);
+});
+
+add_task(async function test_sync_disconnected_error() {
+ // it's possible for fxa to be enabled but sync not enabled.
+ const sandbox = setupSyncFxAMocks({
+ state: UIState.STATUS_SIGNED_IN,
+ syncEnabled: false,
+ });
+ await withFirefoxView({}, async browser => {
+ const { document } = browser.contentWindow;
+ await navigateToViewAndWait(document, "syncedtabs");
+
+ // triggered when user disconnects sync in about:preferences
+ Services.obs.notifyObservers(null, UIState.ON_UPDATE);
+
+ let syncedTabsComponent = document.querySelector(
+ "view-syncedtabs:not([slot=syncedtabs])"
+ );
+ info("Waiting for the synced tabs error step to be visible");
+ await TestUtils.waitForCondition(
+ () => syncedTabsComponent.fullyUpdated,
+ "The synced tabs component has finished updating."
+ );
+ await TestUtils.waitForCondition(
+ () =>
+ syncedTabsComponent.emptyState.shadowRoot.textContent.includes(
+ "allow syncing"
+ ),
+ "The expected synced tabs empty state header is shown."
+ );
+
+ info(
+ "Waiting for a mutation condition to ensure the right syncing error message"
+ );
+ ok(
+ syncedTabsComponent.emptyState
+ .getAttribute("headerlabel")
+ .includes("sync-disconnected-header"),
+ "Correct message should show when sync's been disconnected error"
+ );
+
+ let preferencesTabPromise = BrowserTestUtils.waitForNewTab(
+ browser.getTabBrowser(),
+ "about:preferences?action=choose-what-to-sync#sync",
+ true
+ );
+ let emptyStateButton = syncedTabsComponent.emptyState.querySelector(
+ "button[data-action='sync-disconnected']"
+ );
+ EventUtils.synthesizeMouseAtCenter(emptyStateButton, {}, content);
+ let preferencesTab = await preferencesTabPromise;
+ await BrowserTestUtils.removeTab(preferencesTab);
+ });
+ await tearDown(sandbox);
+});
+
+add_task(async function test_password_change_disconnect_error() {
+ // When the user changes their password on another device, we get into a state
+ // where the user is signed out but sync is still enabled.
+ const sandbox = setupSyncFxAMocks({
+ state: UIState.STATUS_LOGIN_FAILED,
+ syncEnabled: true,
+ });
+ await withFirefoxView({}, async browser => {
+ const { document } = browser.contentWindow;
+ await navigateToViewAndWait(document, "syncedtabs");
+
+ // triggered by the user changing fxa password on another device
+ Services.obs.notifyObservers(null, UIState.ON_UPDATE);
+
+ let syncedTabsComponent = document.querySelector(
+ "view-syncedtabs:not([slot=syncedtabs])"
+ );
+ await TestUtils.waitForCondition(
+ () => syncedTabsComponent.fullyUpdated,
+ "The synced tabs component has finished updating."
+ );
+ await TestUtils.waitForCondition(
+ () =>
+ syncedTabsComponent.emptyState.shadowRoot.textContent.includes(
+ "sign in to your account"
+ ),
+ "The expected synced tabs empty state header is shown."
+ );
+
+ ok(
+ syncedTabsComponent.emptyState
+ .getAttribute("headerlabel")
+ .includes("signin-header"),
+ "Sign in message is shown"
+ );
+ });
+ await tearDown(sandbox);
+});
+
+add_task(async function test_multiple_errors() {
+ let sandbox = await setupWithDesktopDevices();
+ await withFirefoxView({}, async browser => {
+ const { document } = browser.contentWindow;
+ await navigateToViewAndWait(document, "syncedtabs");
+ // Simulate conditions in which both the locked password and sync error
+ // messages could be shown
+ LoginTestUtils.primaryPassword.enable();
+ Services.obs.notifyObservers(null, UIState.ON_UPDATE);
+ Services.obs.notifyObservers(null, "weave:service:sync:error");
+
+ let syncedTabsComponent = document.querySelector(
+ "view-syncedtabs:not([slot=syncedtabs])"
+ );
+ await TestUtils.waitForCondition(
+ () => syncedTabsComponent.fullyUpdated,
+ "The synced tabs component has finished updating."
+ );
+ info("Waiting for the primary password error message to be shown");
+ await TestUtils.waitForCondition(
+ () =>
+ syncedTabsComponent.emptyState.shadowRoot.textContent.includes(
+ "enter the Primary Password"
+ ),
+ "The expected synced tabs empty state header is shown."
+ );
+
+ ok(
+ syncedTabsComponent.emptyState
+ .getAttribute("headerlabel")
+ .includes("password-locked-header"),
+ "Password locked message is shown"
+ );
+
+ const errorLink = syncedTabsComponent.emptyState.shadowRoot.querySelector(
+ "a[data-l10n-name=syncedtab-password-locked-link]"
+ );
+ ok(
+ errorLink && BrowserTestUtils.isVisible(errorLink),
+ "Error link is visible"
+ );
+
+ // Clear the primary password error message
+ LoginTestUtils.primaryPassword.disable();
+ Services.obs.notifyObservers(null, UIState.ON_UPDATE);
+
+ info("Waiting for the sync error message to be shown");
+ await TestUtils.waitForCondition(
+ () => syncedTabsComponent.fullyUpdated,
+ "The synced tabs component has finished updating."
+ );
+ await TestUtils.waitForCondition(
+ () =>
+ syncedTabsComponent.emptyState.shadowRoot.textContent.includes(
+ "having trouble syncing"
+ ),
+ "The expected synced tabs empty state header is shown."
+ );
+
+ ok(
+ errorLink && BrowserTestUtils.isHidden(errorLink),
+ "Error link is now hidden"
+ );
+
+ // Clear the sync error
+ Services.obs.notifyObservers(null, "weave:service:sync:finish");
+ });
+ await tearDown(sandbox);
+});
diff --git a/browser/components/firefoxview/tests/browser/browser_syncedtabs_firefoxview.js b/browser/components/firefoxview/tests/browser/browser_syncedtabs_firefoxview.js
index 11f135cd52..1bf387f578 100644
--- a/browser/components/firefoxview/tests/browser/browser_syncedtabs_firefoxview.js
+++ b/browser/components/firefoxview/tests/browser/browser_syncedtabs_firefoxview.js
@@ -276,9 +276,12 @@ add_task(async function test_tabs() {
});
await withFirefoxView({ openNewWindow: true }, async browser => {
+ // Notify observers while in recent browsing. Once synced tabs is selected,
+ // it should have the updated data.
+ Services.obs.notifyObservers(null, UIState.ON_UPDATE);
+
const { document } = browser.contentWindow;
await navigateToViewAndWait(document, "syncedtabs");
- Services.obs.notifyObservers(null, UIState.ON_UPDATE);
let syncedTabsComponent = document.querySelector(
"view-syncedtabs:not([slot=syncedtabs])"
@@ -309,7 +312,7 @@ add_task(async function test_tabs() {
);
ok(tabRow1[1].shadowRoot.textContent.includes, "Sandboxes - Sinon.JS");
is(tabRow1.length, 2, "Correct number of rows are displayed.");
- let tabRow2 = tabLists[1].shadowRoot.querySelectorAll("fxview-tab-row");
+ let tabRow2 = tabLists[1].rowEls;
is(tabRow2.length, 2, "Correct number of rows are dispayed.");
ok(tabRow1[0].shadowRoot.textContent.includes, "The Guardian");
ok(tabRow1[1].shadowRoot.textContent.includes, "The Times");
diff --git a/browser/components/firefoxview/tests/browser/browser_tab_list_keyboard_navigation.js b/browser/components/firefoxview/tests/browser/browser_tab_list_keyboard_navigation.js
index d83c1056e0..270c3b6809 100644
--- a/browser/components/firefoxview/tests/browser/browser_tab_list_keyboard_navigation.js
+++ b/browser/components/firefoxview/tests/browser/browser_tab_list_keyboard_navigation.js
@@ -93,7 +93,7 @@ add_task(async function test_focus_moves_after_unmute() {
);
// Unmute using keyboard
- card.tabList.currentActiveElementId = mutedTab.focusMediaButton();
+ mutedTab.focusMediaButton();
isActiveElement(mutedTab.mediaButtonEl);
info("The media button has focus.");
@@ -124,7 +124,7 @@ add_task(async function test_focus_moves_after_unmute() {
);
mutedTab = card.tabList.rowEls[0];
- card.tabList.currentActiveElementId = mutedTab.focusLink();
+ mutedTab.focusLink();
isActiveElement(mutedTab.mainEl);
info("The 'main' element has focus.");
diff --git a/browser/components/firefoxview/tests/browser/browser_tab_on_close_warning.js b/browser/components/firefoxview/tests/browser/browser_tab_on_close_warning.js
index 9980980c29..a63a55163a 100644
--- a/browser/components/firefoxview/tests/browser/browser_tab_on_close_warning.js
+++ b/browser/components/firefoxview/tests/browser/browser_tab_on_close_warning.js
@@ -31,7 +31,7 @@ add_task(
info("Opening Firefox View tab...");
await openFirefoxViewTab(win);
info("Trigger warnAboutClosingWindow()");
- win.BrowserTryToCloseWindow();
+ win.BrowserCommands.tryToCloseWindow();
await BrowserTestUtils.closeWindow(win);
ok(!dialogObserver.wasOpened, "Dialog was not opened");
dialogObserver.cleanup();
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 e48f776592..52ddc277c7 100644
--- a/browser/components/firefoxview/tests/chrome/test_fxview_tab_list.html
+++ b/browser/components/firefoxview/tests/chrome/test_fxview_tab_list.html
@@ -11,11 +11,6 @@
<script type="module" src="chrome://browser/content/firefoxview/fxview-tab-list.mjs"></script>
</head>
<body>
- <style>
- fxview-tab-list.history::part(secondary-button) {
- background-image: url("chrome://global/skin/icons/more.svg");
- }
- </style>
<p id="display"></p>
<div id="content" style="max-width: 750px">
<fxview-tab-list class="history" .dateTimeFormat="relative" .hasPopup="menu">