1125 lines
30 KiB
JavaScript
1125 lines
30 KiB
JavaScript
/* Any copyright is dedicated to the Public Domain.
|
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
|
|
"use strict";
|
|
|
|
const { FX_RELAY_OAUTH_CLIENT_ID } = ChromeUtils.importESModule(
|
|
"resource://gre/modules/FxAccountsCommon.sys.mjs"
|
|
);
|
|
|
|
ChromeUtils.defineESModuleGetters(this, {
|
|
CustomizableUITestUtils:
|
|
"resource://testing-common/CustomizableUITestUtils.sys.mjs",
|
|
ExperimentAPI: "resource://nimbus/ExperimentAPI.sys.mjs",
|
|
ExperimentFakes: "resource://testing-common/NimbusTestUtils.sys.mjs",
|
|
});
|
|
|
|
let gCUITestUtils = new CustomizableUITestUtils(window);
|
|
|
|
add_setup(async function () {
|
|
// gSync.init() is called in a requestIdleCallback. Force its initialization.
|
|
gSync.init();
|
|
// This preference gets set the very first time that the FxA menu gets opened,
|
|
// which can cause a state write to occur, which can confuse this test, since
|
|
// when in the signed-out state, we need to set the state _before_ opening
|
|
// the FxA menu (since the panel cannot be opened) in the signed out state.
|
|
await SpecialPowers.pushPrefEnv({
|
|
set: [["identity.fxaccounts.toolbar.accessed", true]],
|
|
});
|
|
});
|
|
|
|
add_task(async function test_ui_state_notification_calls_updateAllUI() {
|
|
let called = false;
|
|
let updateAllUI = gSync.updateAllUI;
|
|
gSync.updateAllUI = () => {
|
|
called = true;
|
|
};
|
|
|
|
Services.obs.notifyObservers(null, UIState.ON_UPDATE);
|
|
ok(called);
|
|
|
|
gSync.updateAllUI = updateAllUI;
|
|
});
|
|
|
|
add_task(async function test_navBar_button_visibility() {
|
|
const button = document.getElementById("fxa-toolbar-menu-button");
|
|
ok(button.closest("#nav-bar"), "button is in the #nav-bar");
|
|
|
|
const state = {
|
|
status: UIState.STATUS_NOT_CONFIGURED,
|
|
syncEnabled: true,
|
|
};
|
|
gSync.updateAllUI(state);
|
|
ok(
|
|
BrowserTestUtils.isVisible(button),
|
|
"Check button visibility with STATUS_NOT_CONFIGURED"
|
|
);
|
|
|
|
state.email = "foo@bar.com";
|
|
state.status = UIState.STATUS_NOT_VERIFIED;
|
|
gSync.updateAllUI(state);
|
|
ok(
|
|
BrowserTestUtils.isVisible(button),
|
|
"Check button visibility with STATUS_NOT_VERIFIED"
|
|
);
|
|
|
|
state.status = UIState.STATUS_LOGIN_FAILED;
|
|
gSync.updateAllUI(state);
|
|
ok(
|
|
BrowserTestUtils.isVisible(button),
|
|
"Check button visibility with STATUS_LOGIN_FAILED"
|
|
);
|
|
|
|
state.status = UIState.STATUS_SIGNED_IN;
|
|
gSync.updateAllUI(state);
|
|
ok(
|
|
BrowserTestUtils.isVisible(button),
|
|
"Check button visibility with STATUS_SIGNED_IN"
|
|
);
|
|
|
|
state.syncEnabled = false;
|
|
gSync.updateAllUI(state);
|
|
is(
|
|
BrowserTestUtils.isVisible(button),
|
|
true,
|
|
"Check button visibility when signed in, but sync disabled"
|
|
);
|
|
});
|
|
|
|
add_task(async function test_overflow_navBar_button_visibility() {
|
|
const button = document.getElementById("fxa-toolbar-menu-button");
|
|
|
|
let overflowPanel = document.getElementById("widget-overflow");
|
|
overflowPanel.setAttribute("animate", "false");
|
|
let navbar = document.getElementById(CustomizableUI.AREA_NAVBAR);
|
|
let originalWindowWidth = window.outerWidth;
|
|
|
|
registerCleanupFunction(function () {
|
|
overflowPanel.removeAttribute("animate");
|
|
window.resizeTo(originalWindowWidth, window.outerHeight);
|
|
return TestUtils.waitForCondition(
|
|
() => !navbar.hasAttribute("overflowing")
|
|
);
|
|
});
|
|
|
|
window.resizeTo(450, window.outerHeight);
|
|
|
|
await TestUtils.waitForCondition(() => navbar.hasAttribute("overflowing"));
|
|
ok(navbar.hasAttribute("overflowing"), "Should have an overflowing toolbar.");
|
|
|
|
let chevron = document.getElementById("nav-bar-overflow-button");
|
|
let shownPanelPromise = BrowserTestUtils.waitForEvent(
|
|
overflowPanel,
|
|
"popupshown"
|
|
);
|
|
chevron.click();
|
|
await shownPanelPromise;
|
|
|
|
ok(button, "fxa-toolbar-menu-button was found");
|
|
|
|
const state = {
|
|
status: UIState.STATUS_NOT_CONFIGURED,
|
|
syncEnabled: true,
|
|
};
|
|
gSync.updateAllUI(state);
|
|
|
|
ok(
|
|
BrowserTestUtils.isVisible(button),
|
|
"Button should still be visable even if user sync not configured"
|
|
);
|
|
|
|
let hidePanelPromise = BrowserTestUtils.waitForEvent(
|
|
overflowPanel,
|
|
"popuphidden"
|
|
);
|
|
chevron.click();
|
|
await hidePanelPromise;
|
|
});
|
|
|
|
add_task(async function setupForPanelTests() {
|
|
/* Proton hides the FxA toolbar button when in the nav-bar and unconfigured.
|
|
To test the panel in all states, we move it to the tabstrip toolbar where
|
|
it will always be visible.
|
|
*/
|
|
CustomizableUI.addWidgetToArea(
|
|
"fxa-toolbar-menu-button",
|
|
CustomizableUI.AREA_TABSTRIP
|
|
);
|
|
|
|
// make sure it gets put back at the end of the tests
|
|
registerCleanupFunction(() => {
|
|
CustomizableUI.addWidgetToArea(
|
|
"fxa-toolbar-menu-button",
|
|
CustomizableUI.AREA_NAVBAR
|
|
);
|
|
});
|
|
});
|
|
|
|
add_task(async function test_ui_state_signedin() {
|
|
await BrowserTestUtils.openNewForegroundTab(gBrowser, "https://example.com/");
|
|
|
|
const relativeDateAnchor = new Date();
|
|
let state = {
|
|
status: UIState.STATUS_SIGNED_IN,
|
|
syncEnabled: true,
|
|
email: "foo@bar.com",
|
|
displayName: "Foo Bar",
|
|
avatarURL: "https://foo.bar",
|
|
lastSync: new Date(),
|
|
syncing: false,
|
|
};
|
|
|
|
const origRelativeTimeFormat = gSync.relativeTimeFormat;
|
|
gSync.relativeTimeFormat = {
|
|
formatBestUnit(date) {
|
|
return origRelativeTimeFormat.formatBestUnit(date, {
|
|
now: relativeDateAnchor,
|
|
});
|
|
},
|
|
};
|
|
|
|
gSync.updateAllUI(state);
|
|
|
|
await openFxaPanel();
|
|
|
|
checkMenuBarItem("sync-syncnowitem");
|
|
checkPanelHeader();
|
|
ok(
|
|
BrowserTestUtils.isVisible(
|
|
document.getElementById("fxa-menu-header-title")
|
|
),
|
|
"expected toolbar to be visible after opening"
|
|
);
|
|
checkFxaToolbarButtonPanel({
|
|
headerTitle: "Manage account",
|
|
headerDescription: state.displayName,
|
|
enabledItems: [
|
|
"PanelUI-fxa-menu-sendtab-button",
|
|
"PanelUI-fxa-menu-connect-device-button",
|
|
"PanelUI-fxa-menu-syncnow-button",
|
|
"PanelUI-fxa-menu-sync-prefs-button",
|
|
"PanelUI-fxa-menu-account-signout-button",
|
|
],
|
|
disabledItems: [],
|
|
hiddenItems: ["PanelUI-fxa-menu-setup-sync-button"],
|
|
});
|
|
checkFxAAvatar("signedin");
|
|
gSync.relativeTimeFormat = origRelativeTimeFormat;
|
|
await closeFxaPanel();
|
|
|
|
await openMainPanel();
|
|
|
|
checkPanelUIStatusBar({
|
|
description: "Foo Bar",
|
|
titleHidden: true,
|
|
hideFxAText: true,
|
|
});
|
|
|
|
await closeTabAndMainPanel();
|
|
});
|
|
|
|
add_task(async function test_ui_state_syncing_panel_closed() {
|
|
let state = {
|
|
status: UIState.STATUS_SIGNED_IN,
|
|
syncEnabled: true,
|
|
email: "foo@bar.com",
|
|
displayName: "Foo Bar",
|
|
avatarURL: "https://foo.bar",
|
|
lastSync: new Date(),
|
|
syncing: true,
|
|
};
|
|
|
|
gSync.updateAllUI(state);
|
|
|
|
checkSyncNowButtons(true);
|
|
|
|
// Be good citizens and remove the "syncing" state.
|
|
gSync.updateAllUI({
|
|
status: UIState.STATUS_SIGNED_IN,
|
|
syncEnabled: true,
|
|
email: "foo@bar.com",
|
|
lastSync: new Date(),
|
|
syncing: false,
|
|
});
|
|
// Because we switch from syncing to non-syncing, and there's a timeout involved.
|
|
await promiseObserver("test:browser-sync:activity-stop");
|
|
});
|
|
|
|
add_task(async function test_ui_state_syncing_panel_open() {
|
|
await BrowserTestUtils.openNewForegroundTab(gBrowser, "https://example.com/");
|
|
|
|
let state = {
|
|
status: UIState.STATUS_SIGNED_IN,
|
|
syncEnabled: true,
|
|
email: "foo@bar.com",
|
|
displayName: "Foo Bar",
|
|
avatarURL: "https://foo.bar",
|
|
lastSync: new Date(),
|
|
syncing: false,
|
|
};
|
|
|
|
gSync.updateAllUI(state);
|
|
|
|
await openFxaPanel();
|
|
|
|
checkSyncNowButtons(false);
|
|
|
|
state = {
|
|
status: UIState.STATUS_SIGNED_IN,
|
|
syncEnabled: true,
|
|
email: "foo@bar.com",
|
|
displayName: "Foo Bar",
|
|
avatarURL: "https://foo.bar",
|
|
lastSync: new Date(),
|
|
syncing: true,
|
|
};
|
|
|
|
gSync.updateAllUI(state);
|
|
|
|
checkSyncNowButtons(true);
|
|
|
|
// Be good citizens and remove the "syncing" state.
|
|
gSync.updateAllUI({
|
|
status: UIState.STATUS_SIGNED_IN,
|
|
syncEnabled: true,
|
|
email: "foo@bar.com",
|
|
lastSync: new Date(),
|
|
syncing: false,
|
|
});
|
|
// Because we switch from syncing to non-syncing, and there's a timeout involved.
|
|
await promiseObserver("test:browser-sync:activity-stop");
|
|
|
|
await closeFxaPanel();
|
|
BrowserTestUtils.removeTab(gBrowser.selectedTab);
|
|
});
|
|
|
|
add_task(async function test_ui_state_panel_open_after_syncing() {
|
|
await BrowserTestUtils.openNewForegroundTab(gBrowser, "https://example.com/");
|
|
|
|
let state = {
|
|
status: UIState.STATUS_SIGNED_IN,
|
|
syncEnabled: true,
|
|
email: "foo@bar.com",
|
|
displayName: "Foo Bar",
|
|
avatarURL: "https://foo.bar",
|
|
lastSync: new Date(),
|
|
syncing: true,
|
|
};
|
|
|
|
gSync.updateAllUI(state);
|
|
|
|
await openFxaPanel();
|
|
|
|
checkSyncNowButtons(true);
|
|
|
|
// Be good citizens and remove the "syncing" state.
|
|
gSync.updateAllUI({
|
|
status: UIState.STATUS_SIGNED_IN,
|
|
syncEnabled: true,
|
|
email: "foo@bar.com",
|
|
lastSync: new Date(),
|
|
syncing: false,
|
|
});
|
|
// Because we switch from syncing to non-syncing, and there's a timeout involved.
|
|
await promiseObserver("test:browser-sync:activity-stop");
|
|
|
|
await closeFxaPanel();
|
|
BrowserTestUtils.removeTab(gBrowser.selectedTab);
|
|
});
|
|
|
|
add_task(async function test_ui_state_unconfigured() {
|
|
await BrowserTestUtils.openNewForegroundTab(gBrowser, "https://example.com/");
|
|
|
|
let state = {
|
|
status: UIState.STATUS_NOT_CONFIGURED,
|
|
};
|
|
|
|
gSync.updateAllUI(state);
|
|
|
|
checkMenuBarItem("sync-setup");
|
|
|
|
checkFxAAvatar("not_configured");
|
|
|
|
let signedOffLabel = gSync.fluentStrings.formatValueSync(
|
|
"appmenu-fxa-signed-in-label"
|
|
);
|
|
|
|
await openMainPanel();
|
|
|
|
checkPanelUIStatusBar({
|
|
description: signedOffLabel,
|
|
titleHidden: true,
|
|
hideFxAText: false,
|
|
});
|
|
await closeTabAndMainPanel();
|
|
});
|
|
|
|
add_task(async function test_ui_state_signed_in() {
|
|
await BrowserTestUtils.openNewForegroundTab(gBrowser, "https://example.com/");
|
|
|
|
let state = {
|
|
status: UIState.STATUS_SIGNED_IN,
|
|
syncEnabled: false,
|
|
email: "foo@bar.com",
|
|
displayName: "Foo Bar",
|
|
avatarURL: "https://foo.bar",
|
|
};
|
|
|
|
gSync.updateAllUI(state);
|
|
|
|
await openFxaPanel();
|
|
|
|
checkMenuBarItem("sync-enable");
|
|
checkPanelHeader();
|
|
checkFxaToolbarButtonPanel({
|
|
headerTitle: "Manage account",
|
|
headerDescription: "Foo Bar",
|
|
enabledItems: [
|
|
"PanelUI-fxa-menu-sendtab-button",
|
|
"PanelUI-fxa-menu-connect-device-button",
|
|
"PanelUI-fxa-menu-setup-sync-button",
|
|
"PanelUI-fxa-menu-account-signout-button",
|
|
],
|
|
disabledItems: [],
|
|
hiddenItems: [
|
|
"PanelUI-fxa-menu-syncnow-button",
|
|
"PanelUI-fxa-menu-sync-prefs-button",
|
|
],
|
|
});
|
|
checkFxAAvatar("signedin");
|
|
await closeFxaPanel();
|
|
|
|
await openMainPanel();
|
|
|
|
checkPanelUIStatusBar({
|
|
description: "Foo Bar",
|
|
titleHidden: true,
|
|
hideFxAText: true,
|
|
});
|
|
|
|
await closeTabAndMainPanel();
|
|
});
|
|
|
|
add_task(async function test_ui_state_signed_in_no_display_name() {
|
|
await BrowserTestUtils.openNewForegroundTab(gBrowser, "https://example.com/");
|
|
|
|
let state = {
|
|
status: UIState.STATUS_SIGNED_IN,
|
|
syncEnabled: false,
|
|
email: "foo@bar.com",
|
|
avatarURL: "https://foo.bar",
|
|
};
|
|
|
|
gSync.updateAllUI(state);
|
|
|
|
await openFxaPanel();
|
|
|
|
checkMenuBarItem("sync-enable");
|
|
checkPanelHeader();
|
|
checkFxaToolbarButtonPanel({
|
|
headerTitle: "Manage account",
|
|
headerDescription: "foo@bar.com",
|
|
enabledItems: [
|
|
"PanelUI-fxa-menu-sendtab-button",
|
|
"PanelUI-fxa-menu-connect-device-button",
|
|
"PanelUI-fxa-menu-setup-sync-button",
|
|
"PanelUI-fxa-menu-account-signout-button",
|
|
],
|
|
disabledItems: [],
|
|
hiddenItems: [
|
|
"PanelUI-fxa-menu-syncnow-button",
|
|
"PanelUI-fxa-menu-sync-prefs-button",
|
|
],
|
|
});
|
|
checkFxAAvatar("signedin");
|
|
await closeFxaPanel();
|
|
|
|
await openMainPanel();
|
|
|
|
checkPanelUIStatusBar({
|
|
description: "foo@bar.com",
|
|
titleHidden: true,
|
|
hideFxAText: true,
|
|
});
|
|
|
|
await closeTabAndMainPanel();
|
|
});
|
|
|
|
add_task(async function test_ui_state_unverified() {
|
|
await BrowserTestUtils.openNewForegroundTab(gBrowser, "https://example.com/");
|
|
|
|
let state = {
|
|
status: UIState.STATUS_NOT_VERIFIED,
|
|
email: "foo@bar.com",
|
|
syncing: false,
|
|
};
|
|
|
|
gSync.updateAllUI(state);
|
|
|
|
await openFxaPanel();
|
|
|
|
const expectedLabel = gSync.fluentStrings.formatValueSync(
|
|
"account-finish-account-setup"
|
|
);
|
|
|
|
checkMenuBarItem("sync-unverifieditem");
|
|
checkPanelHeader();
|
|
checkFxaToolbarButtonPanel({
|
|
headerTitle: expectedLabel,
|
|
headerDescription: state.email,
|
|
enabledItems: [
|
|
"PanelUI-fxa-menu-sendtab-button",
|
|
"PanelUI-fxa-menu-setup-sync-button",
|
|
"PanelUI-fxa-menu-account-signout-button",
|
|
],
|
|
disabledItems: ["PanelUI-fxa-menu-connect-device-button"],
|
|
hiddenItems: [
|
|
"PanelUI-fxa-menu-syncnow-button",
|
|
"PanelUI-fxa-menu-sync-prefs-button",
|
|
],
|
|
});
|
|
checkFxAAvatar("unverified");
|
|
await closeFxaPanel();
|
|
await openMainPanel();
|
|
|
|
checkPanelUIStatusBar({
|
|
description: state.email,
|
|
title: expectedLabel,
|
|
titleHidden: false,
|
|
hideFxAText: true,
|
|
});
|
|
|
|
await closeTabAndMainPanel();
|
|
});
|
|
|
|
add_task(async function test_ui_state_loginFailed() {
|
|
await BrowserTestUtils.openNewForegroundTab(gBrowser, "https://example.com/");
|
|
|
|
let state = {
|
|
status: UIState.STATUS_LOGIN_FAILED,
|
|
email: "foo@bar.com",
|
|
displayName: "Foo Bar",
|
|
};
|
|
|
|
gSync.updateAllUI(state);
|
|
|
|
await openFxaPanel();
|
|
|
|
const expectedLabel = gSync.fluentStrings.formatValueSync(
|
|
"account-disconnected2"
|
|
);
|
|
|
|
checkMenuBarItem("sync-reauthitem");
|
|
checkPanelHeader();
|
|
checkFxaToolbarButtonPanel({
|
|
headerTitle: expectedLabel,
|
|
headerDescription: state.displayName,
|
|
enabledItems: [
|
|
"PanelUI-fxa-menu-sendtab-button",
|
|
"PanelUI-fxa-menu-setup-sync-button",
|
|
"PanelUI-fxa-menu-account-signout-button",
|
|
],
|
|
disabledItems: ["PanelUI-fxa-menu-connect-device-button"],
|
|
hiddenItems: [
|
|
"PanelUI-fxa-menu-syncnow-button",
|
|
"PanelUI-fxa-menu-sync-prefs-button",
|
|
],
|
|
});
|
|
checkFxAAvatar("login-failed");
|
|
await closeFxaPanel();
|
|
await openMainPanel();
|
|
|
|
checkPanelUIStatusBar({
|
|
description: state.displayName,
|
|
title: expectedLabel,
|
|
titleHidden: false,
|
|
hideFxAText: true,
|
|
});
|
|
|
|
await closeTabAndMainPanel();
|
|
});
|
|
|
|
add_task(async function test_app_menu_fxa_disabled() {
|
|
const newWin = await BrowserTestUtils.openNewBrowserWindow();
|
|
|
|
Services.prefs.setBoolPref("identity.fxaccounts.enabled", true);
|
|
newWin.gSync.onFxaDisabled();
|
|
|
|
let menuButton = newWin.document.getElementById("PanelUI-menu-button");
|
|
menuButton.click();
|
|
await BrowserTestUtils.waitForEvent(newWin.PanelUI.mainView, "ViewShown");
|
|
|
|
[...newWin.document.querySelectorAll(".sync-ui-item")].forEach(
|
|
e => (e.hidden = false)
|
|
);
|
|
|
|
let hidden = BrowserTestUtils.waitForEvent(
|
|
newWin.document,
|
|
"popuphidden",
|
|
true
|
|
);
|
|
newWin.PanelUI.hide();
|
|
await hidden;
|
|
await BrowserTestUtils.closeWindow(newWin);
|
|
});
|
|
|
|
add_task(
|
|
// Can't open the history menu in tests on Mac.
|
|
() => AppConstants.platform != "mac",
|
|
async function test_history_menu_fxa_disabled() {
|
|
const newWin = await BrowserTestUtils.openNewBrowserWindow();
|
|
|
|
Services.prefs.setBoolPref("identity.fxaccounts.enabled", true);
|
|
newWin.gSync.onFxaDisabled();
|
|
|
|
const historyMenubarItem = window.document.getElementById("history-menu");
|
|
const historyMenu = window.document.getElementById("historyMenuPopup");
|
|
const syncedTabsItem = historyMenu.querySelector("#sync-tabs-menuitem");
|
|
const menuShown = BrowserTestUtils.waitForEvent(historyMenu, "popupshown");
|
|
historyMenubarItem.openMenu(true);
|
|
await menuShown;
|
|
|
|
Assert.equal(
|
|
syncedTabsItem.hidden,
|
|
true,
|
|
"Synced Tabs item should not be displayed when FxAccounts is disabled"
|
|
);
|
|
const menuHidden = BrowserTestUtils.waitForEvent(
|
|
historyMenu,
|
|
"popuphidden"
|
|
);
|
|
historyMenu.hidePopup();
|
|
await menuHidden;
|
|
await BrowserTestUtils.closeWindow(newWin);
|
|
}
|
|
);
|
|
|
|
// If the PXI experiment is enabled, we need to ensure we can see the CTAs when signed out
|
|
add_task(async function test_experiment_ui_state_unconfigured() {
|
|
await BrowserTestUtils.openNewForegroundTab(gBrowser, "https://example.com/");
|
|
|
|
// The experiment enables this bool, found in FeatureManifest.yaml
|
|
Services.prefs.setBoolPref(
|
|
"identity.fxaccounts.toolbar.pxiToolbarEnabled",
|
|
true
|
|
);
|
|
let state = {
|
|
status: UIState.STATUS_NOT_CONFIGURED,
|
|
};
|
|
|
|
gSync.updateAllUI(state);
|
|
|
|
checkMenuBarItem("sync-setup");
|
|
|
|
checkFxAAvatar("not_configured");
|
|
|
|
let expectedLabel = gSync.fluentStrings.formatValueSync(
|
|
"synced-tabs-fxa-sign-in"
|
|
);
|
|
|
|
let expectedDescriptionLabel = gSync.fluentStrings.formatValueSync(
|
|
"fxa-menu-sync-description"
|
|
);
|
|
|
|
await openMainPanel();
|
|
|
|
checkFxaToolbarButtonPanel({
|
|
headerTitle: expectedLabel,
|
|
headerDescription: expectedDescriptionLabel,
|
|
enabledItems: [
|
|
"PanelUI-fxa-cta-menu",
|
|
"PanelUI-fxa-menu-monitor-button",
|
|
"PanelUI-fxa-menu-relay-button",
|
|
"PanelUI-fxa-menu-vpn-button",
|
|
],
|
|
disabledItems: [],
|
|
hiddenItems: [
|
|
"PanelUI-fxa-menu-syncnow-button",
|
|
"PanelUI-fxa-menu-sync-prefs-button",
|
|
],
|
|
});
|
|
|
|
// Revert the pref at the end of the test
|
|
Services.prefs.setBoolPref(
|
|
"identity.fxaccounts.toolbar.pxiToolbarEnabled",
|
|
false
|
|
);
|
|
await closeTabAndMainPanel();
|
|
});
|
|
|
|
// Ensure we can see the regular signed in flow + the extra PXI CTAs when
|
|
// the experiment is enabled
|
|
add_task(async function test_experiment_ui_state_signedin() {
|
|
await BrowserTestUtils.openNewForegroundTab(gBrowser, "https://example.com/");
|
|
|
|
// The experiment enables this bool, found in FeatureManifest.yaml
|
|
Services.prefs.setBoolPref(
|
|
"identity.fxaccounts.toolbar.pxiToolbarEnabled",
|
|
true
|
|
);
|
|
|
|
const relativeDateAnchor = new Date();
|
|
let state = {
|
|
status: UIState.STATUS_SIGNED_IN,
|
|
syncEnabled: true,
|
|
email: "foo@bar.com",
|
|
displayName: "Foo Bar",
|
|
avatarURL: "https://foo.bar",
|
|
lastSync: new Date(),
|
|
syncing: false,
|
|
};
|
|
|
|
const origRelativeTimeFormat = gSync.relativeTimeFormat;
|
|
gSync.relativeTimeFormat = {
|
|
formatBestUnit(date) {
|
|
return origRelativeTimeFormat.formatBestUnit(date, {
|
|
now: relativeDateAnchor,
|
|
});
|
|
},
|
|
};
|
|
|
|
gSync.updateAllUI(state);
|
|
|
|
await openFxaPanel();
|
|
|
|
checkMenuBarItem("sync-syncnowitem");
|
|
checkPanelHeader();
|
|
ok(
|
|
BrowserTestUtils.isVisible(
|
|
document.getElementById("fxa-menu-header-title")
|
|
),
|
|
"expected toolbar to be visible after opening"
|
|
);
|
|
checkFxaToolbarButtonPanel({
|
|
headerTitle: "Manage account",
|
|
headerDescription: state.displayName,
|
|
enabledItems: [
|
|
"PanelUI-fxa-menu-sendtab-button",
|
|
"PanelUI-fxa-menu-connect-device-button",
|
|
"PanelUI-fxa-menu-syncnow-button",
|
|
"PanelUI-fxa-menu-sync-prefs-button",
|
|
"PanelUI-fxa-menu-account-signout-button",
|
|
"PanelUI-fxa-cta-menu",
|
|
"PanelUI-fxa-menu-monitor-button",
|
|
"PanelUI-fxa-menu-relay-button",
|
|
"PanelUI-fxa-menu-vpn-button",
|
|
],
|
|
disabledItems: [],
|
|
hiddenItems: ["PanelUI-fxa-menu-setup-sync-button"],
|
|
});
|
|
checkFxAAvatar("signedin");
|
|
gSync.relativeTimeFormat = origRelativeTimeFormat;
|
|
await closeFxaPanel();
|
|
|
|
await openMainPanel();
|
|
|
|
checkPanelUIStatusBar({
|
|
description: "Foo Bar",
|
|
titleHidden: true,
|
|
hideFxAText: true,
|
|
});
|
|
|
|
// Revert the pref at the end of the test
|
|
Services.prefs.setBoolPref(
|
|
"identity.fxaccounts.toolbar.pxiToolbarEnabled",
|
|
false
|
|
);
|
|
await closeTabAndMainPanel();
|
|
});
|
|
|
|
add_task(async function test_new_sync_setup_ui_exp_enabled() {
|
|
// Enroll in the experiment with the feature enabled
|
|
await ExperimentAPI.ready();
|
|
let doCleanup = await ExperimentFakes.enrollWithFeatureConfig({
|
|
featureId: NimbusFeatures.syncSetupFlow.featureId,
|
|
value: {
|
|
enabled: true,
|
|
},
|
|
});
|
|
|
|
let state = {
|
|
status: UIState.STATUS_SIGNED_IN,
|
|
syncEnabled: false,
|
|
email: "foo@bar.com",
|
|
displayName: "Foo Bar",
|
|
avatarURL: "https://foo.bar",
|
|
};
|
|
|
|
gSync.updateAllUI(state);
|
|
|
|
await openFxaPanel();
|
|
|
|
checkMenuBarItem("sync-enable");
|
|
checkPanelHeader();
|
|
|
|
checkFxaToolbarButtonPanel({
|
|
headerTitle: "Manage account",
|
|
headerDescription: "Foo Bar",
|
|
enabledItems: [
|
|
"PanelUI-fxa-menu-sendtab-button",
|
|
"PanelUI-fxa-menu-setup-sync-container", // New set-up element should be visible
|
|
"PanelUI-fxa-menu-account-signout-button",
|
|
],
|
|
disabledItems: [],
|
|
hiddenItems: [
|
|
"PanelUI-fxa-menu-syncnow-button",
|
|
"PanelUI-fxa-menu-sync-prefs-button",
|
|
"PanelUI-fxa-menu-connect-device-button", // CAD should also be hidden
|
|
"PanelUI-fxa-menu-setup-sync-button", // Old button should be hidden
|
|
],
|
|
});
|
|
|
|
await closeFxaPanel();
|
|
await doCleanup();
|
|
|
|
// We need to reset the panel back to hidden since in the code we flip between the old and new sync setup ids
|
|
// so subsequent tests will fail if checking this new container
|
|
let newSyncSetup = document.getElementById(
|
|
"PanelUI-fxa-menu-setup-sync-container"
|
|
);
|
|
newSyncSetup.setAttribute("hidden", true);
|
|
});
|
|
|
|
add_task(async function test_new_sync_setup_ui_no_exp() {
|
|
// Enroll in the experiment with the feature disabled
|
|
await ExperimentAPI.ready();
|
|
let doCleanup = await ExperimentFakes.enrollWithFeatureConfig({
|
|
featureId: NimbusFeatures.syncSetupFlow.featureId,
|
|
value: {
|
|
enabled: false,
|
|
},
|
|
});
|
|
|
|
let state = {
|
|
status: UIState.STATUS_SIGNED_IN,
|
|
syncEnabled: false,
|
|
email: "foo@bar.com",
|
|
displayName: "Foo Bar",
|
|
avatarURL: "https://foo.bar",
|
|
};
|
|
|
|
gSync.updateAllUI(state);
|
|
|
|
await openFxaPanel();
|
|
|
|
checkMenuBarItem("sync-enable");
|
|
checkPanelHeader();
|
|
|
|
checkFxaToolbarButtonPanel({
|
|
headerTitle: "Manage account",
|
|
headerDescription: "Foo Bar",
|
|
enabledItems: [
|
|
"PanelUI-fxa-menu-sendtab-button",
|
|
"PanelUI-fxa-menu-connect-device-button",
|
|
"PanelUI-fxa-menu-setup-sync-button", // Old setup button should be visible
|
|
"PanelUI-fxa-menu-account-signout-button",
|
|
],
|
|
disabledItems: [],
|
|
hiddenItems: [
|
|
"PanelUI-fxa-menu-syncnow-button",
|
|
"PanelUI-fxa-menu-sync-prefs-button",
|
|
"PanelUI-fxa-menu-setup-sync-container", // New setup container should be hidden
|
|
],
|
|
});
|
|
|
|
await doCleanup();
|
|
await closeFxaPanel();
|
|
});
|
|
|
|
// Ensure we can see the new "My services" section if the user has enabled relay on their account
|
|
add_task(async function test_ui_my_services_signedin() {
|
|
await BrowserTestUtils.openNewForegroundTab(gBrowser, "https://example.com/");
|
|
|
|
const relativeDateAnchor = new Date();
|
|
let state = {
|
|
status: UIState.STATUS_SIGNED_IN,
|
|
syncEnabled: true,
|
|
email: "foo@bar.com",
|
|
displayName: "Foo Bar",
|
|
avatarURL: "https://foo.bar",
|
|
lastSync: new Date(),
|
|
syncing: false,
|
|
};
|
|
|
|
const origRelativeTimeFormat = gSync.relativeTimeFormat;
|
|
gSync.relativeTimeFormat = {
|
|
formatBestUnit(date) {
|
|
return origRelativeTimeFormat.formatBestUnit(date, {
|
|
now: relativeDateAnchor,
|
|
});
|
|
},
|
|
};
|
|
|
|
gSync.updateAllUI(state);
|
|
|
|
// pretend that the user has relay enabled
|
|
gSync._attachedClients = [
|
|
{
|
|
id: FX_RELAY_OAUTH_CLIENT_ID,
|
|
},
|
|
];
|
|
|
|
await openFxaPanel();
|
|
|
|
checkMenuBarItem("sync-syncnowitem");
|
|
checkPanelHeader();
|
|
ok(
|
|
BrowserTestUtils.isVisible(
|
|
document.getElementById("fxa-menu-header-title")
|
|
),
|
|
"expected toolbar to be visible after opening"
|
|
);
|
|
checkFxaToolbarButtonPanel({
|
|
headerTitle: "Manage account",
|
|
headerDescription: state.displayName,
|
|
enabledItems: [
|
|
"PanelUI-fxa-menu-sendtab-button",
|
|
"PanelUI-fxa-menu-connect-device-button",
|
|
"PanelUI-fxa-menu-syncnow-button",
|
|
"PanelUI-fxa-menu-sync-prefs-button",
|
|
"PanelUI-fxa-menu-account-signout-button",
|
|
"PanelUI-fxa-cta-menu",
|
|
"PanelUI-fxa-menu-monitor-button",
|
|
"PanelUI-fxa-menu-vpn-button",
|
|
],
|
|
disabledItems: [],
|
|
hiddenItems: [
|
|
"PanelUI-fxa-menu-setup-sync-button",
|
|
"PanelUI-fxa-menu-relay-button", // the relay button in the "other protections" side should be hidden
|
|
],
|
|
});
|
|
checkFxAAvatar("signedin");
|
|
gSync.relativeTimeFormat = origRelativeTimeFormat;
|
|
await closeFxaPanel();
|
|
|
|
await openMainPanel();
|
|
|
|
checkPanelUIStatusBar({
|
|
description: "Foo Bar",
|
|
titleHidden: true,
|
|
hideFxAText: true,
|
|
});
|
|
|
|
// Revert the pref at the end of the test
|
|
Services.prefs.setBoolPref(
|
|
"identity.fxaccounts.toolbar.pxiToolbarEnabled",
|
|
false
|
|
);
|
|
await closeTabAndMainPanel();
|
|
});
|
|
|
|
function checkPanelUIStatusBar({
|
|
description,
|
|
title,
|
|
titleHidden,
|
|
hideFxAText,
|
|
}) {
|
|
checkAppMenuFxAText(hideFxAText);
|
|
let appMenuHeaderTitle = PanelMultiView.getViewNode(
|
|
document,
|
|
"appMenu-header-title"
|
|
);
|
|
let appMenuHeaderDescription = PanelMultiView.getViewNode(
|
|
document,
|
|
"appMenu-header-description"
|
|
);
|
|
is(
|
|
appMenuHeaderDescription.value,
|
|
description,
|
|
"app menu description has correct value"
|
|
);
|
|
is(appMenuHeaderTitle.hidden, titleHidden, "title has correct hidden status");
|
|
if (!titleHidden) {
|
|
is(appMenuHeaderTitle.value, title, "title has correct value");
|
|
}
|
|
}
|
|
|
|
function checkMenuBarItem(expectedShownItemId) {
|
|
checkItemsVisibilities(
|
|
[
|
|
"sync-setup",
|
|
"sync-enable",
|
|
"sync-syncnowitem",
|
|
"sync-reauthitem",
|
|
"sync-unverifieditem",
|
|
],
|
|
expectedShownItemId
|
|
);
|
|
}
|
|
|
|
function checkPanelHeader() {
|
|
let fxaPanelView = PanelMultiView.getViewNode(document, "PanelUI-fxa");
|
|
is(
|
|
fxaPanelView.getAttribute("title"),
|
|
gSync.fluentStrings.formatValueSync("appmenu-account-header"),
|
|
"Panel title is correct"
|
|
);
|
|
}
|
|
|
|
function checkSyncNowButtons(syncing, tooltip = null) {
|
|
const syncButtons = document.querySelectorAll(".syncNowBtn");
|
|
|
|
for (const syncButton of syncButtons) {
|
|
is(
|
|
syncButton.getAttribute("syncstatus"),
|
|
syncing ? "active" : null,
|
|
"button active has the right value"
|
|
);
|
|
if (tooltip) {
|
|
is(
|
|
syncButton.getAttribute("tooltiptext"),
|
|
tooltip,
|
|
"button tooltiptext is set to the right value"
|
|
);
|
|
}
|
|
}
|
|
|
|
const syncLabels = document.querySelectorAll(".syncnow-label");
|
|
|
|
for (const syncLabel of syncLabels) {
|
|
if (syncing) {
|
|
is(
|
|
syncLabel.getAttribute("data-l10n-id"),
|
|
syncLabel.getAttribute("syncing-data-l10n-id"),
|
|
"label is set to the right value"
|
|
);
|
|
} else {
|
|
is(
|
|
syncLabel.getAttribute("data-l10n-id"),
|
|
syncLabel.getAttribute("sync-now-data-l10n-id"),
|
|
"label is set to the right value"
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
async function checkFxaToolbarButtonPanel({
|
|
headerTitle,
|
|
headerDescription,
|
|
enabledItems,
|
|
disabledItems,
|
|
hiddenItems,
|
|
}) {
|
|
is(
|
|
document.getElementById("fxa-menu-header-title").value,
|
|
headerTitle,
|
|
"has correct title"
|
|
);
|
|
is(
|
|
document.getElementById("fxa-menu-header-description").value,
|
|
headerDescription,
|
|
"has correct description"
|
|
);
|
|
|
|
for (const id of enabledItems) {
|
|
const el = document.getElementById(id);
|
|
is(el.hasAttribute("disabled"), false, id + " is enabled");
|
|
}
|
|
|
|
for (const id of disabledItems) {
|
|
const el = document.getElementById(id);
|
|
is(el.getAttribute("disabled"), "true", id + " is disabled");
|
|
}
|
|
|
|
for (const id of hiddenItems) {
|
|
const el = document.getElementById(id);
|
|
is(el.getAttribute("hidden"), "true", id + " is hidden");
|
|
}
|
|
}
|
|
|
|
async function checkFxABadged() {
|
|
const button = document.getElementById("fxa-toolbar-menu-button");
|
|
await BrowserTestUtils.waitForCondition(() => {
|
|
return button.querySelector("label.feature-callout");
|
|
});
|
|
const badge = button.querySelector("label.feature-callout");
|
|
ok(badge, "expected feature-callout style badge");
|
|
ok(BrowserTestUtils.isVisible(badge), "expected the badge to be visible");
|
|
}
|
|
|
|
// fxaStatus is one of 'not_configured', 'unverified', 'login-failed', or 'signedin'.
|
|
function checkFxAAvatar(fxaStatus) {
|
|
// Unhide the panel so computed styles can be read
|
|
document.querySelector("#appMenu-popup").hidden = false;
|
|
|
|
const avatarContainers = [document.getElementById("fxa-avatar-image")];
|
|
for (const avatar of avatarContainers) {
|
|
const avatarURL = getComputedStyle(avatar).listStyleImage;
|
|
const expected = {
|
|
not_configured: 'url("chrome://browser/skin/fxa/avatar-empty.svg")',
|
|
unverified: 'url("chrome://browser/skin/fxa/avatar.svg")',
|
|
signedin: 'url("chrome://browser/skin/fxa/avatar.svg")',
|
|
"login-failed": 'url("chrome://browser/skin/fxa/avatar.svg")',
|
|
};
|
|
Assert.equal(
|
|
avatarURL,
|
|
expected[fxaStatus],
|
|
`expected avatar URL to be ${expected[fxaStatus]}, got ${avatarURL}`
|
|
);
|
|
}
|
|
}
|
|
|
|
function checkAppMenuFxAText(hideStatus) {
|
|
let fxaText = document.getElementById("appMenu-fxa-text");
|
|
let isHidden = fxaText.hidden || fxaText.style.visibility == "collapse";
|
|
Assert.equal(isHidden, hideStatus, "FxA text has correct hidden state");
|
|
}
|
|
|
|
// Only one item visible at a time.
|
|
function checkItemsVisibilities(itemsIds, expectedShownItemId) {
|
|
for (let id of itemsIds) {
|
|
if (id == expectedShownItemId) {
|
|
ok(
|
|
!document.getElementById(id).hidden,
|
|
"menuitem " + id + " should be visible"
|
|
);
|
|
} else {
|
|
ok(
|
|
document.getElementById(id).hidden,
|
|
"menuitem " + id + " should be hidden"
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
function promiseObserver(topic) {
|
|
return new Promise(resolve => {
|
|
let obs = (aSubject, aTopic) => {
|
|
Services.obs.removeObserver(obs, aTopic);
|
|
resolve(aSubject);
|
|
};
|
|
Services.obs.addObserver(obs, topic);
|
|
});
|
|
}
|
|
|
|
async function openTabAndFxaPanel() {
|
|
await BrowserTestUtils.openNewForegroundTab(gBrowser, "https://example.com/");
|
|
await openFxaPanel();
|
|
}
|
|
|
|
async function openFxaPanel() {
|
|
let fxaButton = document.getElementById("fxa-toolbar-menu-button");
|
|
fxaButton.click();
|
|
|
|
let fxaView = PanelMultiView.getViewNode(document, "PanelUI-fxa");
|
|
await BrowserTestUtils.waitForEvent(fxaView, "ViewShown");
|
|
}
|
|
|
|
async function closeFxaPanel() {
|
|
let fxaView = PanelMultiView.getViewNode(document, "PanelUI-fxa");
|
|
let hidden = BrowserTestUtils.waitForEvent(document, "popuphidden", true);
|
|
fxaView.closest("panel").hidePopup();
|
|
await hidden;
|
|
}
|
|
|
|
async function openMainPanel() {
|
|
let menuButton = document.getElementById("PanelUI-menu-button");
|
|
menuButton.click();
|
|
await BrowserTestUtils.waitForEvent(window.PanelUI.mainView, "ViewShown");
|
|
}
|
|
|
|
async function closeTabAndMainPanel() {
|
|
await gCUITestUtils.hideMainMenu();
|
|
|
|
BrowserTestUtils.removeTab(gBrowser.selectedTab);
|
|
}
|