summaryrefslogtreecommitdiffstats
path: root/browser/components/firefoxview/tests/browser/browser_notification_dot.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/firefoxview/tests/browser/browser_notification_dot.js')
-rw-r--r--browser/components/firefoxview/tests/browser/browser_notification_dot.js389
1 files changed, 389 insertions, 0 deletions
diff --git a/browser/components/firefoxview/tests/browser/browser_notification_dot.js b/browser/components/firefoxview/tests/browser/browser_notification_dot.js
new file mode 100644
index 0000000000..01411ee260
--- /dev/null
+++ b/browser/components/firefoxview/tests/browser/browser_notification_dot.js
@@ -0,0 +1,389 @@
+/* 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",
+ },
+ {
+ id: 2,
+ name: "My iphone",
+ type: "mobile",
+ },
+ ]);
+
+ 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);
+ }
+ ok(
+ 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.is_visible(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();
+});