diff options
Diffstat (limited to 'browser/components/firefoxview/tests/browser/browser_syncedtabs_firefoxview.js')
-rw-r--r-- | browser/components/firefoxview/tests/browser/browser_syncedtabs_firefoxview.js | 747 |
1 files changed, 747 insertions, 0 deletions
diff --git a/browser/components/firefoxview/tests/browser/browser_syncedtabs_firefoxview.js b/browser/components/firefoxview/tests/browser/browser_syncedtabs_firefoxview.js new file mode 100644 index 0000000000..8a3c63985b --- /dev/null +++ b/browser/components/firefoxview/tests/browser/browser_syncedtabs_firefoxview.js @@ -0,0 +1,747 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +add_setup(async function () { + registerCleanupFunction(() => { + // reset internal state so it doesn't affect the next tests + TabsSetupFlowManager.resetInternalState(); + }); + + // gSync.init() is called in a requestIdleCallback. Force its initialization. + gSync.init(); + + registerCleanupFunction(async function () { + await tearDown(gSandbox); + }); +}); + +async function promiseTabListsUpdated({ tabLists }) { + for (const tabList of tabLists) { + await tabList.updateComplete; + } + await TestUtils.waitForTick(); +} + +add_task(async function test_unconfigured_initial_state() { + const sandbox = setupMocks({ + state: UIState.STATUS_NOT_CONFIGURED, + syncEnabled: false, + }); + await withFirefoxView({}, async browser => { + const { document } = browser.contentWindow; + await navigateToCategoryAndWait(document, "syncedtabs"); + Services.obs.notifyObservers(null, UIState.ON_UPDATE); + + let syncedTabsComponent = document.querySelector( + "view-syncedtabs:not([slot=syncedtabs])" + ); + + let emptyState = + syncedTabsComponent.shadowRoot.querySelector("fxview-empty-state"); + ok( + emptyState.getAttribute("headerlabel").includes("syncedtabs-signin"), + "Signin message is shown" + ); + + // Test telemetry for signing into Firefox Accounts. + await clearAllParentTelemetryEvents(); + EventUtils.synthesizeMouseAtCenter( + emptyState.querySelector(`button[data-action="sign-in"]`), + {}, + browser.contentWindow + ); + await TestUtils.waitForCondition( + () => + Services.telemetry.snapshotEvents( + Ci.nsITelemetry.DATASET_PRERELEASE_CHANNELS + ).parent?.length >= 1, + "Waiting for fxa_continue firefoxview telemetry event.", + 200, + 100 + ); + TelemetryTestUtils.assertEvents( + [["firefoxview_next", "fxa_continue", "sync"]], + { category: "firefoxview_next" }, + { clear: true, process: "parent" } + ); + await BrowserTestUtils.removeTab(browser.ownerGlobal.gBrowser.selectedTab); + }); + await tearDown(sandbox); +}); + +add_task(async function test_signed_in() { + const sandbox = setupMocks({ + state: UIState.STATUS_SIGNED_IN, + fxaDevices: [ + { + id: 1, + name: "This Device", + isCurrentDevice: true, + type: "desktop", + tabs: [], + }, + ], + }); + + await withFirefoxView({}, async browser => { + const { document } = browser.contentWindow; + await navigateToCategoryAndWait(document, "syncedtabs"); + Services.obs.notifyObservers(null, UIState.ON_UPDATE); + + let syncedTabsComponent = document.querySelector( + "view-syncedtabs:not([slot=syncedtabs])" + ); + await TestUtils.waitForCondition(() => syncedTabsComponent.fullyUpdated); + let emptyState = + syncedTabsComponent.shadowRoot.querySelector("fxview-empty-state"); + ok( + emptyState.getAttribute("headerlabel").includes("syncedtabs-adddevice"), + "Add device message is shown" + ); + + // Test telemetry for adding a device. + await clearAllParentTelemetryEvents(); + EventUtils.synthesizeMouseAtCenter( + emptyState.querySelector(`button[data-action="add-device"]`), + {}, + browser.contentWindow + ); + await TestUtils.waitForCondition( + () => + Services.telemetry.snapshotEvents( + Ci.nsITelemetry.DATASET_PRERELEASE_CHANNELS + ).parent?.length >= 1, + "Waiting for fxa_mobile firefoxview telemetry event.", + 200, + 100 + ); + TelemetryTestUtils.assertEvents( + [["firefoxview_next", "fxa_mobile", "sync"]], + { category: "firefoxview_next" }, + { clear: true, process: "parent" } + ); + await BrowserTestUtils.removeTab(browser.ownerGlobal.gBrowser.selectedTab); + }); + await tearDown(sandbox); +}); + +add_task(async function test_no_synced_tabs() { + 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: "desktop", + tabs: [], + }, + ], + }); + + await withFirefoxView({}, async browser => { + const { document } = browser.contentWindow; + await navigateToCategoryAndWait(document, "syncedtabs"); + Services.obs.notifyObservers(null, UIState.ON_UPDATE); + + let syncedTabsComponent = document.querySelector( + "view-syncedtabs:not([slot=syncedtabs])" + ); + await TestUtils.waitForCondition(() => syncedTabsComponent.fullyUpdated); + let emptyState = + syncedTabsComponent.shadowRoot.querySelector("fxview-empty-state"); + ok( + emptyState.getAttribute("headerlabel").includes("syncedtabs-synctabs"), + "Enable synced tabs message is shown" + ); + }); + await tearDown(sandbox); + Services.prefs.setBoolPref("services.sync.engine.tabs", true); +}); + +add_task(async function test_no_error_for_two_desktop() { + 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: "desktop", + tabs: [], + }, + ], + }); + + await withFirefoxView({}, async browser => { + const { document } = browser.contentWindow; + await navigateToCategoryAndWait(document, "syncedtabs"); + Services.obs.notifyObservers(null, UIState.ON_UPDATE); + + let syncedTabsComponent = document.querySelector( + "view-syncedtabs:not([slot=syncedtabs])" + ); + await TestUtils.waitForCondition(() => syncedTabsComponent.fullyUpdated); + let emptyState = + syncedTabsComponent.shadowRoot.querySelector("fxview-empty-state"); + is(emptyState, null, "No empty state should be shown"); + let noTabs = syncedTabsComponent.shadowRoot.querySelectorAll(".notabs"); + is(noTabs.length, 1, "Should be 1 empty device"); + }); + await tearDown(sandbox); +}); + +add_task(async function test_empty_state() { + const sandbox = setupMocks({ + state: UIState.STATUS_SIGNED_IN, + fxaDevices: [ + { + id: 1, + name: "This Device", + isCurrentDevice: true, + type: "desktop", + tabs: [], + }, + { + id: 2, + name: "Other Desktop", + type: "desktop", + tabs: [], + }, + { + id: 3, + name: "Other Mobile", + type: "phone", + tabs: [], + }, + ], + }); + + await withFirefoxView({ openNewWindow: true }, async browser => { + const { document } = browser.contentWindow; + await navigateToCategoryAndWait(document, "syncedtabs"); + Services.obs.notifyObservers(null, UIState.ON_UPDATE); + + let syncedTabsComponent = document.querySelector( + "view-syncedtabs:not([slot=syncedtabs])" + ); + await TestUtils.waitForCondition(() => syncedTabsComponent.fullyUpdated); + let noTabs = syncedTabsComponent.shadowRoot.querySelectorAll(".notabs"); + is(noTabs.length, 2, "Should be 2 empty devices"); + + let headers = + syncedTabsComponent.shadowRoot.querySelectorAll("h3[slot=header]"); + ok( + headers[0].textContent.includes("Other Desktop"), + "Text is correct (Desktop)" + ); + ok(headers[0].innerHTML.includes("icon desktop"), "Icon should be desktop"); + ok( + headers[1].textContent.includes("Other Mobile"), + "Text is correct (Mobile)" + ); + ok(headers[1].innerHTML.includes("icon phone"), "Icon should be phone"); + }); + await tearDown(sandbox); +}); + +add_task(async function test_tabs() { + TabsSetupFlowManager.resetInternalState(); + + const sandbox = setupRecentDeviceListMocks(); + const syncedTabsMock = sandbox.stub(SyncedTabs, "getRecentTabs"); + let mockTabs1 = getMockTabData(syncedTabsData1); + let getRecentTabsResult = mockTabs1; + syncedTabsMock.callsFake(() => { + info( + `Stubbed SyncedTabs.getRecentTabs returning a promise that resolves to ${getRecentTabsResult.length} tabs\n` + ); + return Promise.resolve(getRecentTabsResult); + }); + sandbox.stub(SyncedTabs, "getTabClients").callsFake(() => { + return Promise.resolve(syncedTabsData1); + }); + + await withFirefoxView({ openNewWindow: true }, async browser => { + const { document } = browser.contentWindow; + await navigateToCategoryAndWait(document, "syncedtabs"); + Services.obs.notifyObservers(null, UIState.ON_UPDATE); + + let syncedTabsComponent = document.querySelector( + "view-syncedtabs:not([slot=syncedtabs])" + ); + await TestUtils.waitForCondition(() => syncedTabsComponent.fullyUpdated); + + let headers = + syncedTabsComponent.shadowRoot.querySelectorAll("h3[slot=header]"); + ok( + headers[0].textContent.includes("My desktop"), + "Text is correct (My desktop)" + ); + ok(headers[0].innerHTML.includes("icon desktop"), "Icon should be desktop"); + ok( + headers[1].textContent.includes("My iphone"), + "Text is correct (My iphone)" + ); + ok(headers[1].innerHTML.includes("icon phone"), "Icon should be phone"); + + let tabLists = syncedTabsComponent.tabLists; + await TestUtils.waitForCondition(() => { + return tabLists[0].rowEls.length; + }); + let tabRow1 = tabLists[0].rowEls; + ok( + tabRow1[0].shadowRoot.textContent.includes, + "Internet for people, not profits - Mozilla" + ); + 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"); + 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"); + + // Test telemetry for opening a tab. + await clearAllParentTelemetryEvents(); + EventUtils.synthesizeMouseAtCenter(tabRow1[0], {}, browser.contentWindow); + await TestUtils.waitForCondition( + () => + Services.telemetry.snapshotEvents( + Ci.nsITelemetry.DATASET_PRERELEASE_CHANNELS + ).parent?.length >= 1, + "Waiting for synced_tabs firefoxview telemetry event.", + 200, + 100 + ); + TelemetryTestUtils.assertEvents( + [ + [ + "firefoxview_next", + "synced_tabs", + "tabs", + null, + { page: "syncedtabs" }, + ], + ], + { category: "firefoxview_next" }, + { clear: true, process: "parent" } + ); + }); + await tearDown(sandbox); +}); + +add_task(async function test_empty_desktop_same_name() { + const sandbox = setupMocks({ + state: UIState.STATUS_SIGNED_IN, + fxaDevices: [ + { + id: 1, + name: "A Device", + isCurrentDevice: true, + type: "desktop", + tabs: [], + }, + { + id: 2, + name: "A Device", + type: "desktop", + tabs: [], + }, + ], + }); + + await withFirefoxView({ openNewWindow: true }, async browser => { + const { document } = browser.contentWindow; + await navigateToCategoryAndWait(document, "syncedtabs"); + Services.obs.notifyObservers(null, UIState.ON_UPDATE); + + let syncedTabsComponent = document.querySelector( + "view-syncedtabs:not([slot=syncedtabs])" + ); + await TestUtils.waitForCondition(() => syncedTabsComponent.fullyUpdated); + let noTabs = syncedTabsComponent.shadowRoot.querySelectorAll(".notabs"); + is(noTabs.length, 1, "Should be 1 empty devices"); + + let headers = + syncedTabsComponent.shadowRoot.querySelectorAll("h3[slot=header]"); + ok( + headers[0].textContent.includes("A Device"), + "Text is correct (Desktop)" + ); + }); + await tearDown(sandbox); +}); + +add_task(async function test_empty_desktop_same_name_three() { + const sandbox = setupMocks({ + state: UIState.STATUS_SIGNED_IN, + fxaDevices: [ + { + id: 1, + name: "A Device", + isCurrentDevice: true, + type: "desktop", + tabs: [], + }, + { + id: 2, + name: "A Device", + type: "desktop", + tabs: [], + }, + { + id: 3, + name: "A Device", + type: "desktop", + tabs: [], + }, + ], + }); + + await withFirefoxView({ openNewWindow: true }, async browser => { + const { document } = browser.contentWindow; + await navigateToCategoryAndWait(document, "syncedtabs"); + Services.obs.notifyObservers(null, UIState.ON_UPDATE); + + let syncedTabsComponent = document.querySelector( + "view-syncedtabs:not([slot=syncedtabs])" + ); + await TestUtils.waitForCondition(() => syncedTabsComponent.fullyUpdated); + let noTabs = syncedTabsComponent.shadowRoot.querySelectorAll(".notabs"); + is(noTabs.length, 2, "Should be 2 empty devices"); + + let headers = + syncedTabsComponent.shadowRoot.querySelectorAll("h3[slot=header]"); + ok( + headers[0].textContent.includes("A Device"), + "Text is correct (Desktop)" + ); + ok( + headers[1].textContent.includes("A Device"), + "Text is correct (Desktop)" + ); + }); + await tearDown(sandbox); +}); + +add_task(async function search_synced_tabs() { + TabsSetupFlowManager.resetInternalState(); + + const sandbox = setupRecentDeviceListMocks(); + const syncedTabsMock = sandbox.stub(SyncedTabs, "getRecentTabs"); + let mockTabs1 = getMockTabData(syncedTabsData1); + let getRecentTabsResult = mockTabs1; + syncedTabsMock.callsFake(() => { + info( + `Stubbed SyncedTabs.getRecentTabs returning a promise that resolves to ${getRecentTabsResult.length} tabs\n` + ); + return Promise.resolve(getRecentTabsResult); + }); + sandbox.stub(SyncedTabs, "getTabClients").callsFake(() => { + return Promise.resolve(syncedTabsData1); + }); + await SpecialPowers.pushPrefEnv({ + set: [["browser.firefox-view.search.enabled", true]], + }); + + await withFirefoxView({}, async browser => { + const { document } = browser.contentWindow; + await navigateToCategoryAndWait(document, "syncedtabs"); + Services.obs.notifyObservers(null, UIState.ON_UPDATE); + + let syncedTabsComponent = document.querySelector( + "view-syncedtabs:not([slot=syncedtabs])" + ); + await TestUtils.waitForCondition(() => syncedTabsComponent.fullyUpdated); + + is(syncedTabsComponent.cardEls.length, 2, "There are two device cards."); + await TestUtils.waitForCondition( + () => + syncedTabsComponent.cardEls[0].querySelector("fxview-tab-list") && + syncedTabsComponent.cardEls[0].querySelector("fxview-tab-list").rowEls + .length && + syncedTabsComponent.cardEls[1].querySelector("fxview-tab-list") && + syncedTabsComponent.cardEls[1].querySelector("fxview-tab-list").rowEls + .length, + "The tab list has loaded for the first two cards." + ); + let deviceOneTabs = + syncedTabsComponent.cardEls[0].querySelector("fxview-tab-list").rowEls; + let deviceTwoTabs = + syncedTabsComponent.cardEls[1].querySelector("fxview-tab-list").rowEls; + + info("Input a search query."); + EventUtils.synthesizeMouseAtCenter( + syncedTabsComponent.searchTextbox, + {}, + content + ); + EventUtils.sendString("Mozilla", content); + await TestUtils.waitForCondition( + () => syncedTabsComponent.fullyUpdated, + "Synced Tabs component is done updating." + ); + await TestUtils.waitForCondition( + () => + syncedTabsComponent.cardEls[0].querySelector("fxview-tab-list") && + syncedTabsComponent.cardEls[0].querySelector("fxview-tab-list").rowEls + .length, + "The tab list has loaded for the first card." + ); + await TestUtils.waitForCondition( + () => + syncedTabsComponent.cardEls[0].querySelector("fxview-tab-list").rowEls + .length === 1, + "There is one matching search result for the first device." + ); + await TestUtils.waitForCondition( + () => !syncedTabsComponent.cardEls[1].querySelector("fxview-tab-list"), + "There are no matching search results for the second device." + ); + + info("Clear the search query."); + EventUtils.synthesizeMouseAtCenter( + syncedTabsComponent.searchTextbox.clearButton, + {}, + content + ); + await TestUtils.waitForCondition( + () => syncedTabsComponent.fullyUpdated, + "Synced Tabs component is done updating." + ); + await TestUtils.waitForCondition( + () => + syncedTabsComponent.cardEls[0].querySelector("fxview-tab-list") && + syncedTabsComponent.cardEls[0].querySelector("fxview-tab-list").rowEls + .length && + syncedTabsComponent.cardEls[1].querySelector("fxview-tab-list") && + syncedTabsComponent.cardEls[1].querySelector("fxview-tab-list").rowEls + .length, + "The tab list has loaded for the first two cards." + ); + deviceOneTabs = + syncedTabsComponent.cardEls[0].querySelector("fxview-tab-list").rowEls; + deviceTwoTabs = + syncedTabsComponent.cardEls[1].querySelector("fxview-tab-list").rowEls; + await TestUtils.waitForCondition( + () => + syncedTabsComponent.cardEls[0].querySelector("fxview-tab-list").rowEls + .length === deviceOneTabs.length, + "The original device's list is restored." + ); + await TestUtils.waitForCondition( + () => + syncedTabsComponent.cardEls[1].querySelector("fxview-tab-list").rowEls + .length === deviceTwoTabs.length, + "The new devices's list is restored." + ); + syncedTabsComponent.searchTextbox.blur(); + + info("Input a search query with keyboard."); + EventUtils.synthesizeKey("f", { accelKey: true }, content); + EventUtils.sendString("Mozilla", content); + await TestUtils.waitForCondition( + () => syncedTabsComponent.fullyUpdated, + "Synced Tabs component is done updating." + ); + await TestUtils.waitForCondition( + () => + syncedTabsComponent.cardEls[0].querySelector("fxview-tab-list") && + syncedTabsComponent.cardEls[0].querySelector("fxview-tab-list").rowEls + .length, + "The tab list has loaded for the first card." + ); + await TestUtils.waitForCondition(() => { + return ( + syncedTabsComponent.cardEls[0].querySelector("fxview-tab-list").rowEls + .length === 1 + ); + }, "There is one matching search result for the first device."); + await TestUtils.waitForCondition( + () => !syncedTabsComponent.cardEls[1].querySelector("fxview-tab-list"), + "There are no matching search results for the second device." + ); + + info("Clear the search query with keyboard."); + is( + syncedTabsComponent.shadowRoot.activeElement, + syncedTabsComponent.searchTextbox, + "Search input is focused" + ); + EventUtils.synthesizeKey("KEY_Tab", {}, content); + ok( + syncedTabsComponent.searchTextbox.clearButton.matches(":focus-visible"), + "Clear Search button is focused" + ); + EventUtils.synthesizeKey("KEY_Enter", {}, content); + await TestUtils.waitForCondition( + () => syncedTabsComponent.fullyUpdated, + "Synced Tabs component is done updating." + ); + await TestUtils.waitForCondition( + () => + syncedTabsComponent.cardEls[0].querySelector("fxview-tab-list") && + syncedTabsComponent.cardEls[0].querySelector("fxview-tab-list").rowEls + .length && + syncedTabsComponent.cardEls[1].querySelector("fxview-tab-list") && + syncedTabsComponent.cardEls[1].querySelector("fxview-tab-list").rowEls + .length, + "The tab list has loaded for the first two cards." + ); + deviceOneTabs = + syncedTabsComponent.cardEls[0].querySelector("fxview-tab-list").rowEls; + deviceTwoTabs = + syncedTabsComponent.cardEls[1].querySelector("fxview-tab-list").rowEls; + await TestUtils.waitForCondition( + () => + syncedTabsComponent.cardEls[0].querySelector("fxview-tab-list").rowEls + .length === deviceOneTabs.length, + "The original device's list is restored." + ); + await TestUtils.waitForCondition( + () => + syncedTabsComponent.cardEls[1].querySelector("fxview-tab-list").rowEls + .length === deviceTwoTabs.length, + "The new devices's list is restored." + ); + }); + await SpecialPowers.popPrefEnv(); + await tearDown(sandbox); +}); + +add_task(async function search_synced_tabs_recent_browsing() { + const NUMBER_OF_TABS = 6; + TabsSetupFlowManager.resetInternalState(); + const sandbox = setupRecentDeviceListMocks(); + const tabClients = [ + { + id: 1, + type: "client", + name: "My desktop", + clientType: "desktop", + tabs: Array(NUMBER_OF_TABS).fill({ + type: "tab", + title: "Internet for people, not profits - Mozilla", + url: "https://www.mozilla.org/", + icon: "https://www.mozilla.org/media/img/favicons/mozilla/favicon.d25d81d39065.ico", + client: 1, + }), + }, + { + id: 2, + type: "client", + name: "My iphone", + clientType: "phone", + tabs: [ + { + type: "tab", + title: "Mount Everest - Wikipedia", + url: "https://en.wikipedia.org/wiki/Mount_Everest", + icon: "https://www.wikipedia.org/static/favicon/wikipedia.ico", + client: 2, + }, + ], + }, + ]; + sandbox + .stub(SyncedTabs, "getRecentTabs") + .resolves(getMockTabData(tabClients)); + sandbox.stub(SyncedTabs, "getTabClients").resolves(tabClients); + + await SpecialPowers.pushPrefEnv({ + set: [["browser.firefox-view.search.enabled", true]], + }); + await withFirefoxView({}, async browser => { + const { document } = browser.contentWindow; + await navigateToCategoryAndWait(document, "recentbrowsing"); + Services.obs.notifyObservers(null, UIState.ON_UPDATE); + + const recentBrowsing = document.querySelector("view-recentbrowsing"); + const slot = recentBrowsing.querySelector("[slot='syncedtabs']"); + + // Test that all tab lists repopulate when clearing out searched terms (Bug 1869895 & Bug 1873212) + info("Input a search query"); + EventUtils.synthesizeMouseAtCenter( + recentBrowsing.searchTextbox, + {}, + content + ); + EventUtils.sendString("Mozilla", content); + await TestUtils.waitForCondition( + () => slot.fullyUpdated && slot.tabLists.length === 1, + "Synced Tabs component is done updating." + ); + await promiseTabListsUpdated(slot); + info("Scroll first card into view."); + slot.tabLists[0].scrollIntoView(); + await TestUtils.waitForCondition( + () => slot.tabLists[0].rowEls.length === 5, + "The first card is populated." + ); + EventUtils.synthesizeMouseAtCenter( + recentBrowsing.searchTextbox, + {}, + content + ); + EventUtils.synthesizeKey("KEY_Backspace", { repeat: 5 }); + await TestUtils.waitForCondition( + () => slot.fullyUpdated && slot.tabLists.length === 2, + "Synced Tabs component is done updating." + ); + await promiseTabListsUpdated(slot); + info("Scroll second card into view."); + slot.tabLists[1].scrollIntoView(); + await TestUtils.waitForCondition( + () => + slot.tabLists[0].rowEls.length === 5 && + slot.tabLists[1].rowEls.length === 1, + "Both cards are populated." + ); + info("Clear the search query."); + EventUtils.synthesizeKey("KEY_Backspace", { repeat: 2 }); + + info("Input a search query"); + EventUtils.synthesizeMouseAtCenter( + recentBrowsing.searchTextbox, + {}, + content + ); + EventUtils.sendString("Mozilla", content); + await TestUtils.waitForCondition( + () => slot.fullyUpdated && slot.tabLists.length === 2, + "Synced Tabs component is done updating." + ); + await promiseTabListsUpdated(slot); + await TestUtils.waitForCondition( + () => slot.tabLists[0].rowEls.length === 5, + "Not all search results are shown yet." + ); + + info("Click the Show All link."); + const showAllLink = await TestUtils.waitForCondition(() => + slot.shadowRoot.querySelector("[data-l10n-id='firefoxview-show-all']") + ); + is(showAllLink.role, "link", "The show all control is a link."); + EventUtils.synthesizeMouseAtCenter(showAllLink, {}, content); + await TestUtils.waitForCondition( + () => slot.tabLists[0].rowEls.length === NUMBER_OF_TABS, + "All search results are shown." + ); + ok(BrowserTestUtils.isHidden(showAllLink), "The show all link is hidden."); + }); + await SpecialPowers.popPrefEnv(); + await tearDown(sandbox); +}); |