Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

/* Any copyright is dedicated to the Public Domain.
*/
const { AddonTestUtils } = ChromeUtils.importESModule(
);
const { AppMenuNotifications } = ChromeUtils.importESModule(
"resource://gre/modules/AppMenuNotifications.sys.mjs"
);
const DEFAULT_THEME_ID = "default-theme@mozilla.org";
function promisePostInstallNotificationShown() {
// The themes are unsigned, so we need to confirm we're okay with that first
// This is why we need to accept a prompt, and then continue to the prompt
// that is interesting to us (the post-install message)
const id = "theme-installed";
return new Promise(resolve => {
function popupshown() {
let notification = AppMenuNotifications.activeNotification;
if (!notification) {
return;
}
is(notification.id, id, `${id} notification shown`);
ok(window.PanelUI.isNotificationPanelOpen, "notification panel open");
window.PanelUI.notificationPanel.removeEventListener(
"popupshown",
popupshown
);
let popupnotificationID = window.PanelUI._getPopupId(notification);
let popupnotification = document.getElementById(popupnotificationID);
resolve(popupnotification);
}
window.PanelUI.notificationPanel.addEventListener("popupshown", popupshown);
});
}
async function installTheme(id, theme, { userInstalled = true } = {}) {
let install = await AddonManager.getInstallForFile(
theme,
"application/x-xpinstall"
);
const themeEnabled = AddonTestUtils.promiseAddonEvent(
"onEnabled",
addon => addon.id === id
);
if (userInstalled) {
// Mock a theme installed by a user.
AddonManager.installAddonFromAOM(
gBrowser.selectedBrowser,
document.documentURIObject,
install
);
} else {
// Mock a theme installed in the background (e.g. when it is being installed in the
// background by Firefox Sync).
install.install().then(themeAddon => themeAddon.enable());
}
return themeEnabled;
}
async function promisePostInstallShown() {
const panel = await promisePopupNotificationShown(
"addon-install-confirmation"
);
panel.button.click();
// Wait for post install pupup
let postInstallNotification = await promisePostInstallNotificationShown();
let okayButton = postInstallNotification.querySelector(
".popup-notification-primary-button"
);
let undoButton = postInstallNotification.querySelector(
".popup-notification-secondary-button"
);
return [okayButton, undoButton];
}
// Test that clicking the undo button on the post install notification reverts
// the theme
add_task(async function test_undoTheme() {
const RED_THEME_ID = "red@test.mozilla.org";
let redTheme = await AddonTestUtils.createTempWebExtensionFile({
manifest: {
version: "1.0",
name: "red theme",
browser_specific_settings: { gecko: { id: RED_THEME_ID } },
theme: {
colors: {
frame: "red",
},
},
},
});
const BLUE_THEME_ID = "blue@test.mozilla.org";
let blueTheme = await AddonTestUtils.createTempWebExtensionFile({
manifest: {
name: "blue theme",
version: "1.0",
browser_specific_settings: { gecko: { id: BLUE_THEME_ID } },
theme: {
colors: {
frame: "blue",
},
},
},
});
const GREEN_THEME_ID = "green@test.mozilla.org";
let greenTheme = await AddonTestUtils.createTempWebExtensionFile({
useAddonManager: "permanent",
manifest: {
name: "green theme",
version: "1.0",
browser_specific_settings: { gecko: { id: GREEN_THEME_ID } },
theme: {
colors: {
frame: "green",
},
},
},
});
// Install a new theme
let promiseThemeEnabled = installTheme(RED_THEME_ID, redTheme);
const [okayButton] = await promisePostInstallShown();
okayButton.click();
// Make sure the theme is fully enabled before checking the prefs
await promiseThemeEnabled;
Assert.strictEqual(
Services.prefs.getCharPref("extensions.activeThemeID"),
RED_THEME_ID,
"Expected red theme to be the active theme"
);
Assert.strictEqual(
(await AddonManager.getAddonByID(RED_THEME_ID)).previousActiveThemeID,
DEFAULT_THEME_ID,
"Expected previous active theme ID to be the default theme"
);
// After first theme is installed, trigger a second install but "undo" it
promiseThemeEnabled = installTheme(BLUE_THEME_ID, blueTheme);
const [, undoButton] = await promisePostInstallShown();
// At this point, the second (blue) theme is installed and we haven't
// reverted to the prevoius theme yet
// Make sure the theme is fully enabled before checking the prefs
await promiseThemeEnabled;
Assert.strictEqual(
Services.prefs.getCharPref("extensions.activeThemeID"),
BLUE_THEME_ID,
"Expected active theme before undo to be the blue theme"
);
Assert.strictEqual(
(await AddonManager.getAddonByID(BLUE_THEME_ID)).previousActiveThemeID,
RED_THEME_ID,
"Expected previous active theme ID before undo to be the red theme"
);
info(
"Install green theme without user interaction (mocks Firefox Sync installed theme)"
);
// Simulate a theme installed without using interaction (e.g. like it would
// be the case if Firefox Sync would be installing a theme as part of syncing
// the installed add-ons).
await installTheme(GREEN_THEME_ID, greenTheme, { userInstalled: false });
Assert.strictEqual(
Services.prefs.getCharPref("extensions.activeThemeID"),
GREEN_THEME_ID,
"Expected new active theme to be the green theme"
);
// Expect the previousActiveThemeID collected before to still be set to the
// theme id that was active when the blue theme was being installed.
Assert.strictEqual(
(await AddonManager.getAddonByID(BLUE_THEME_ID)).previousActiveThemeID,
RED_THEME_ID,
"Expected previous active theme ID before undo to still be the red theme"
);
info("Click theme undo button and expect the red theme to be re-enabled");
promiseThemeEnabled = AddonTestUtils.promiseAddonEvent(
"onEnabled",
addon => addon.id === RED_THEME_ID
);
undoButton.click();
// Make sure the theme is fully enabled before checking the prefs
await promiseThemeEnabled;
Assert.strictEqual(
RED_THEME_ID,
Services.prefs.getCharPref("extensions.activeThemeID"),
"Expected active theme after undo to be the red theme"
);
const redThemeAddon = await AddonManager.getAddonByID(RED_THEME_ID);
await redThemeAddon.uninstall();
});