1443 lines
43 KiB
JavaScript
1443 lines
43 KiB
JavaScript
/* eslint-env webextensions */
|
|
|
|
const PROXY_PREF = "network.proxy.type";
|
|
const HOMEPAGE_URL_PREF = "browser.startup.homepage";
|
|
const HOMEPAGE_OVERRIDE_KEY = "homepage_override";
|
|
const URL_OVERRIDES_TYPE = "url_overrides";
|
|
const NEW_TAB_KEY = "newTabURL";
|
|
const PREF_SETTING_TYPE = "prefs";
|
|
|
|
ChromeUtils.defineESModuleGetters(this, {
|
|
AboutNewTab: "resource:///modules/AboutNewTab.sys.mjs",
|
|
ExtensionSettingsStore:
|
|
"resource://gre/modules/ExtensionSettingsStore.sys.mjs",
|
|
});
|
|
|
|
XPCOMUtils.defineLazyPreferenceGetter(this, "proxyType", PROXY_PREF);
|
|
|
|
const { AddonTestUtils } = ChromeUtils.importESModule(
|
|
"resource://testing-common/AddonTestUtils.sys.mjs"
|
|
);
|
|
AddonTestUtils.initMochitest(this);
|
|
|
|
const { ExtensionPreferencesManager } = ChromeUtils.importESModule(
|
|
"resource://gre/modules/ExtensionPreferencesManager.sys.mjs"
|
|
);
|
|
|
|
const TEST_DIR = gTestPath.substr(0, gTestPath.lastIndexOf("/"));
|
|
const CHROME_URL_ROOT = TEST_DIR + "/";
|
|
const PERMISSIONS_URL =
|
|
"chrome://browser/content/preferences/dialogs/sitePermissions.xhtml";
|
|
let sitePermissionsDialog;
|
|
|
|
function getSupportsFile(path) {
|
|
let cr = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(
|
|
Ci.nsIChromeRegistry
|
|
);
|
|
let uri = Services.io.newURI(CHROME_URL_ROOT + path);
|
|
let fileurl = cr.convertChromeURL(uri);
|
|
return fileurl.QueryInterface(Ci.nsIFileURL);
|
|
}
|
|
|
|
function waitForMessageChange(
|
|
element,
|
|
cb,
|
|
opts = { attributes: true, attributeFilter: ["hidden"] }
|
|
) {
|
|
return waitForMutation(element, opts, cb);
|
|
}
|
|
|
|
function getElement(id, doc = gBrowser.contentDocument) {
|
|
return doc.getElementById(id);
|
|
}
|
|
|
|
function waitForMessageHidden(messageId, doc) {
|
|
return waitForMessageChange(
|
|
getElement(messageId, doc),
|
|
target => target.hidden
|
|
);
|
|
}
|
|
|
|
function waitForMessageShown(messageId, doc) {
|
|
return waitForMessageChange(
|
|
getElement(messageId, doc),
|
|
target => !target.hidden
|
|
);
|
|
}
|
|
|
|
function waitForEnableMessage(messageId, doc) {
|
|
return waitForMessageChange(
|
|
getElement(messageId, doc),
|
|
target => target.classList.contains("extension-controlled-disabled"),
|
|
{ attributeFilter: ["class"], attributes: true }
|
|
);
|
|
}
|
|
|
|
function waitForMessageContent(messageId, l10nId, doc) {
|
|
return waitForMessageChange(
|
|
getElement(messageId, doc),
|
|
target => doc.l10n.getAttributes(target).id === l10nId,
|
|
{ childList: true }
|
|
);
|
|
}
|
|
|
|
async function openNotificationsPermissionDialog() {
|
|
let dialogOpened = promiseLoadSubDialog(PERMISSIONS_URL);
|
|
|
|
await SpecialPowers.spawn(gBrowser.selectedBrowser, [], function () {
|
|
let doc = content.document;
|
|
let settingsButton = doc.getElementById("notificationSettingsButton");
|
|
settingsButton.click();
|
|
});
|
|
|
|
sitePermissionsDialog = await dialogOpened;
|
|
await sitePermissionsDialog.document.mozSubdialogReady;
|
|
}
|
|
|
|
async function disableExtensionViaClick(labelId, disableButtonId, doc) {
|
|
let controlledLabel = doc.getElementById(labelId);
|
|
|
|
let enableMessageShown = waitForEnableMessage(labelId, doc);
|
|
doc.getElementById(disableButtonId).click();
|
|
await enableMessageShown;
|
|
|
|
let controlledDescription = controlledLabel.querySelector("description");
|
|
is(
|
|
doc.l10n.getAttributes(controlledDescription.querySelector("label")).id,
|
|
"extension-controlled-enable",
|
|
"The user is notified of how to enable the extension again."
|
|
);
|
|
|
|
// The user can dismiss the enable instructions.
|
|
let hidden = waitForMessageHidden(labelId, doc);
|
|
controlledLabel.querySelector("image:last-of-type").click();
|
|
await hidden;
|
|
}
|
|
|
|
async function reEnableExtension(addon, labelId) {
|
|
let controlledMessageShown = waitForMessageShown(labelId);
|
|
await addon.enable();
|
|
await controlledMessageShown;
|
|
}
|
|
|
|
add_task(async function testExtensionControlledHomepage() {
|
|
const ADDON_ID = "@set_homepage";
|
|
const SECOND_ADDON_ID = "@second_set_homepage";
|
|
|
|
await openPreferencesViaOpenPreferencesAPI("paneHome", { leaveOpen: true });
|
|
let homepagePref = () => Services.prefs.getCharPref(HOMEPAGE_URL_PREF);
|
|
let originalHomepagePref = homepagePref();
|
|
is(
|
|
gBrowser.currentURI.spec,
|
|
"about:preferences#home",
|
|
"#home should be in the URI for about:preferences"
|
|
);
|
|
let doc = gBrowser.contentDocument;
|
|
let homeModeEl = doc.getElementById("homeMode");
|
|
let customSettingsSection = doc.getElementById("customSettings");
|
|
|
|
is(homeModeEl.itemCount, 3, "The menu list starts with 3 options");
|
|
|
|
let promise = TestUtils.waitForCondition(
|
|
() => homeModeEl.itemCount === 4,
|
|
"wait for the addon option to be added as an option in the menu list"
|
|
);
|
|
let extension = ExtensionTestUtils.loadExtension({
|
|
useAddonManager: "permanent",
|
|
manifest: {
|
|
version: "1.0",
|
|
name: "set_homepage",
|
|
browser_specific_settings: {
|
|
gecko: {
|
|
id: ADDON_ID,
|
|
},
|
|
},
|
|
chrome_settings_overrides: { homepage: "/home.html" },
|
|
},
|
|
});
|
|
await extension.startup();
|
|
await promise;
|
|
|
|
// The homepage is set to the default and the custom settings section is hidden
|
|
is(homeModeEl.disabled, false, "The homepage menulist is enabled");
|
|
is(
|
|
customSettingsSection.hidden,
|
|
true,
|
|
"The custom settings element is hidden"
|
|
);
|
|
|
|
let addon = await AddonManager.getAddonByID(ADDON_ID);
|
|
is(
|
|
homeModeEl.value,
|
|
addon.id,
|
|
"the home select menu's value is set to the addon"
|
|
);
|
|
|
|
promise = TestUtils.waitForPrefChange(HOMEPAGE_URL_PREF);
|
|
// Set the Menu to the default value
|
|
homeModeEl.value = "0";
|
|
homeModeEl.dispatchEvent(new Event("command"));
|
|
await promise;
|
|
is(homepagePref(), originalHomepagePref, "homepage is set back to default");
|
|
let levelOfControl = await ExtensionPreferencesManager.getLevelOfControl(
|
|
addon.id,
|
|
HOMEPAGE_OVERRIDE_KEY,
|
|
PREF_SETTING_TYPE
|
|
);
|
|
is(
|
|
levelOfControl,
|
|
"not_controllable",
|
|
"getLevelOfControl returns not_controllable."
|
|
);
|
|
let setting = await ExtensionPreferencesManager.getSetting(
|
|
HOMEPAGE_OVERRIDE_KEY
|
|
);
|
|
ok(!setting.value, "the setting is not set.");
|
|
|
|
promise = TestUtils.waitForPrefChange(HOMEPAGE_URL_PREF);
|
|
// Set the menu to the addon value
|
|
homeModeEl.value = ADDON_ID;
|
|
homeModeEl.dispatchEvent(new Event("command"));
|
|
await promise;
|
|
ok(
|
|
homepagePref().startsWith("moz-extension") &&
|
|
homepagePref().endsWith("home.html"),
|
|
"Home url should be provided by the extension."
|
|
);
|
|
levelOfControl = await ExtensionPreferencesManager.getLevelOfControl(
|
|
addon.id,
|
|
HOMEPAGE_OVERRIDE_KEY,
|
|
PREF_SETTING_TYPE
|
|
);
|
|
is(
|
|
levelOfControl,
|
|
"controlled_by_this_extension",
|
|
"getLevelOfControl returns controlled_by_this_extension."
|
|
);
|
|
setting = await ExtensionPreferencesManager.getSetting(HOMEPAGE_OVERRIDE_KEY);
|
|
ok(
|
|
setting.value.startsWith("moz-extension") &&
|
|
setting.value.endsWith("home.html"),
|
|
"The setting value is the same as the extension."
|
|
);
|
|
|
|
// Add a second extension, ensure it is added to the menulist and selected.
|
|
promise = TestUtils.waitForCondition(
|
|
() => homeModeEl.itemCount == 5,
|
|
"addon option is added as an option in the menu list"
|
|
);
|
|
let secondExtension = ExtensionTestUtils.loadExtension({
|
|
useAddonManager: "permanent",
|
|
manifest: {
|
|
version: "1.0",
|
|
name: "second_set_homepage",
|
|
browser_specific_settings: {
|
|
gecko: {
|
|
id: SECOND_ADDON_ID,
|
|
},
|
|
},
|
|
chrome_settings_overrides: { homepage: "/home2.html" },
|
|
},
|
|
});
|
|
await secondExtension.startup();
|
|
await promise;
|
|
|
|
let secondAddon = await AddonManager.getAddonByID(SECOND_ADDON_ID);
|
|
is(homeModeEl.value, SECOND_ADDON_ID, "home menulist is set to the add-on");
|
|
|
|
levelOfControl = await ExtensionPreferencesManager.getLevelOfControl(
|
|
secondAddon.id,
|
|
HOMEPAGE_OVERRIDE_KEY,
|
|
PREF_SETTING_TYPE
|
|
);
|
|
is(
|
|
levelOfControl,
|
|
"controlled_by_this_extension",
|
|
"getLevelOfControl returns controlled_by_this_extension."
|
|
);
|
|
setting = await ExtensionPreferencesManager.getSetting(HOMEPAGE_OVERRIDE_KEY);
|
|
ok(
|
|
setting.value.startsWith("moz-extension") &&
|
|
setting.value.endsWith("home2.html"),
|
|
"The setting value is the same as the extension."
|
|
);
|
|
|
|
promise = TestUtils.waitForCondition(
|
|
() => homeModeEl.itemCount == 4,
|
|
"addon option is no longer an option in the menu list after disable, even if it was not selected"
|
|
);
|
|
await addon.disable();
|
|
await promise;
|
|
|
|
// Ensure that re-enabling an addon adds it back to the menulist
|
|
promise = TestUtils.waitForCondition(
|
|
() => homeModeEl.itemCount == 5,
|
|
"addon option is added again to the menulist when enabled"
|
|
);
|
|
await addon.enable();
|
|
await promise;
|
|
|
|
promise = TestUtils.waitForCondition(
|
|
() => homeModeEl.itemCount == 4,
|
|
"addon option is no longer an option in the menu list after disable"
|
|
);
|
|
await secondAddon.disable();
|
|
await promise;
|
|
|
|
promise = TestUtils.waitForCondition(
|
|
() => homeModeEl.itemCount == 5,
|
|
"addon option is added again to the menulist when enabled"
|
|
);
|
|
await secondAddon.enable();
|
|
await promise;
|
|
|
|
promise = TestUtils.waitForCondition(
|
|
() => homeModeEl.itemCount == 3,
|
|
"addon options are no longer an option in the menu list after disabling all addons"
|
|
);
|
|
await secondAddon.disable();
|
|
await addon.disable();
|
|
await promise;
|
|
|
|
is(homeModeEl.value, "0", "addon option is not selected in the menu list");
|
|
|
|
levelOfControl = await ExtensionPreferencesManager.getLevelOfControl(
|
|
secondAddon.id,
|
|
HOMEPAGE_OVERRIDE_KEY,
|
|
PREF_SETTING_TYPE
|
|
);
|
|
is(
|
|
levelOfControl,
|
|
"controllable_by_this_extension",
|
|
"getLevelOfControl returns controllable_by_this_extension."
|
|
);
|
|
setting = await ExtensionPreferencesManager.getSetting(HOMEPAGE_OVERRIDE_KEY);
|
|
ok(!setting.value, "The setting value is back to default.");
|
|
|
|
// The homepage elements are reset to their original state.
|
|
is(homepagePref(), originalHomepagePref, "homepage is set back to default");
|
|
is(homeModeEl.disabled, false, "The homepage menulist is enabled");
|
|
BrowserTestUtils.removeTab(gBrowser.selectedTab);
|
|
await extension.unload();
|
|
await secondExtension.unload();
|
|
});
|
|
|
|
add_task(async function testPrefLockedHomepage() {
|
|
const ADDON_ID = "@set_homepage";
|
|
await openPreferencesViaOpenPreferencesAPI("paneHome", { leaveOpen: true });
|
|
let doc = gBrowser.contentDocument;
|
|
is(
|
|
gBrowser.currentURI.spec,
|
|
"about:preferences#home",
|
|
"#home should be in the URI for about:preferences"
|
|
);
|
|
|
|
let homePagePref = "browser.startup.homepage";
|
|
let buttonPrefs = [
|
|
"pref.browser.homepage.disable_button.current_page",
|
|
"pref.browser.homepage.disable_button.bookmark_page",
|
|
"pref.browser.homepage.disable_button.restore_default",
|
|
];
|
|
let homeModeEl = doc.getElementById("homeMode");
|
|
let homePageInput = doc.getElementById("homePageUrl");
|
|
let prefs = Services.prefs.getDefaultBranch(null);
|
|
let mutationOpts = { attributes: true, attributeFilter: ["disabled"] };
|
|
|
|
// Helper functions.
|
|
let getButton = pref =>
|
|
doc.querySelector(`.homepage-button[preference="${pref}"`);
|
|
let waitForAllMutations = () =>
|
|
Promise.all(
|
|
buttonPrefs
|
|
.map(pref => waitForMutation(getButton(pref), mutationOpts))
|
|
.concat([
|
|
waitForMutation(homeModeEl, mutationOpts),
|
|
waitForMutation(homePageInput, mutationOpts),
|
|
])
|
|
);
|
|
let getHomepage = () =>
|
|
Services.prefs.getCharPref("browser.startup.homepage");
|
|
|
|
let originalHomepage = getHomepage();
|
|
let extensionHomepage = "https://developer.mozilla.org/";
|
|
let lockedHomepage = "http://www.yahoo.com";
|
|
|
|
let lockPrefs = () => {
|
|
buttonPrefs.forEach(pref => {
|
|
prefs.setBoolPref(pref, true);
|
|
prefs.lockPref(pref);
|
|
});
|
|
// Do the homepage last since that's the only pref that triggers a UI update.
|
|
prefs.setCharPref(homePagePref, lockedHomepage);
|
|
prefs.lockPref(homePagePref);
|
|
};
|
|
let unlockPrefs = () => {
|
|
buttonPrefs.forEach(pref => {
|
|
prefs.unlockPref(pref);
|
|
prefs.setBoolPref(pref, false);
|
|
});
|
|
// Do the homepage last since that's the only pref that triggers a UI update.
|
|
prefs.unlockPref(homePagePref);
|
|
prefs.setCharPref(homePagePref, originalHomepage);
|
|
};
|
|
|
|
// Lock or unlock prefs then wait for all mutations to finish.
|
|
// Expects a bool indicating if we should lock or unlock.
|
|
let waitForLockMutations = lock => {
|
|
let mutationsDone = waitForAllMutations();
|
|
if (lock) {
|
|
lockPrefs();
|
|
} else {
|
|
unlockPrefs();
|
|
}
|
|
return mutationsDone;
|
|
};
|
|
|
|
Assert.notEqual(
|
|
originalHomepage,
|
|
extensionHomepage,
|
|
"The extension will change the homepage"
|
|
);
|
|
|
|
// Install an extension that sets the homepage to MDN.
|
|
let promise = TestUtils.waitForPrefChange(HOMEPAGE_URL_PREF);
|
|
let extension = ExtensionTestUtils.loadExtension({
|
|
useAddonManager: "permanent",
|
|
manifest: {
|
|
version: "1.0",
|
|
name: "set_homepage",
|
|
browser_specific_settings: {
|
|
gecko: {
|
|
id: ADDON_ID,
|
|
},
|
|
},
|
|
chrome_settings_overrides: { homepage: "https://developer.mozilla.org/" },
|
|
},
|
|
});
|
|
await extension.startup();
|
|
await promise;
|
|
|
|
// Check that everything is still disabled, homepage didn't change.
|
|
is(
|
|
getHomepage(),
|
|
extensionHomepage,
|
|
"The reported homepage is set by the extension"
|
|
);
|
|
is(
|
|
homePageInput.value,
|
|
extensionHomepage,
|
|
"The homepage is set by the extension"
|
|
);
|
|
|
|
// Lock all of the prefs, wait for the UI to update.
|
|
await waitForLockMutations(true);
|
|
|
|
// Check that everything is now disabled.
|
|
is(getHomepage(), lockedHomepage, "The reported homepage is set by the pref");
|
|
is(homePageInput.value, lockedHomepage, "The homepage is set by the pref");
|
|
is(
|
|
homePageInput.disabled,
|
|
true,
|
|
"The homepage is disabed when the pref is locked"
|
|
);
|
|
|
|
buttonPrefs.forEach(pref => {
|
|
is(
|
|
getButton(pref).disabled,
|
|
true,
|
|
`The ${pref} button is disabled when locked`
|
|
);
|
|
});
|
|
|
|
let levelOfControl = await ExtensionPreferencesManager.getLevelOfControl(
|
|
ADDON_ID,
|
|
HOMEPAGE_OVERRIDE_KEY,
|
|
PREF_SETTING_TYPE
|
|
);
|
|
is(
|
|
levelOfControl,
|
|
"not_controllable",
|
|
"getLevelOfControl returns not_controllable, the pref is locked."
|
|
);
|
|
|
|
// Verify that the UI is selecting the extension's Id in the menulist
|
|
let unlockedPromise = TestUtils.waitForCondition(
|
|
() => homeModeEl.value == ADDON_ID,
|
|
"Homepage menulist value is equal to the extension ID"
|
|
);
|
|
// Unlock the prefs, wait for the UI to update.
|
|
unlockPrefs();
|
|
await unlockedPromise;
|
|
|
|
is(
|
|
homeModeEl.disabled,
|
|
false,
|
|
"the home select element is not disabled when the pref is not locked"
|
|
);
|
|
is(
|
|
homePageInput.disabled,
|
|
false,
|
|
"The homepage is enabled when the pref is unlocked"
|
|
);
|
|
is(
|
|
getHomepage(),
|
|
extensionHomepage,
|
|
"The homepage is reset to extension page"
|
|
);
|
|
|
|
levelOfControl = await ExtensionPreferencesManager.getLevelOfControl(
|
|
ADDON_ID,
|
|
HOMEPAGE_OVERRIDE_KEY,
|
|
PREF_SETTING_TYPE
|
|
);
|
|
is(
|
|
levelOfControl,
|
|
"controlled_by_this_extension",
|
|
"getLevelOfControl returns controlled_by_this_extension after prefs are unlocked."
|
|
);
|
|
let setting = await ExtensionPreferencesManager.getSetting(
|
|
HOMEPAGE_OVERRIDE_KEY
|
|
);
|
|
is(
|
|
setting.value,
|
|
extensionHomepage,
|
|
"The setting value is equal to the extensionHomepage."
|
|
);
|
|
|
|
// Uninstall the add-on.
|
|
promise = TestUtils.waitForPrefChange(HOMEPAGE_URL_PREF);
|
|
await extension.unload();
|
|
await promise;
|
|
|
|
setting = await ExtensionPreferencesManager.getSetting(HOMEPAGE_OVERRIDE_KEY);
|
|
ok(!setting, "The setting is gone after the addon is uninstalled.");
|
|
|
|
// Check that everything is now enabled again.
|
|
is(
|
|
getHomepage(),
|
|
originalHomepage,
|
|
"The reported homepage is reset to original value"
|
|
);
|
|
is(homePageInput.value, "", "The homepage is empty");
|
|
is(
|
|
homePageInput.disabled,
|
|
false,
|
|
"The homepage is enabled after clearing lock"
|
|
);
|
|
is(
|
|
homeModeEl.disabled,
|
|
false,
|
|
"Homepage menulist is enabled after clearing lock"
|
|
);
|
|
buttonPrefs.forEach(pref => {
|
|
is(
|
|
getButton(pref).disabled,
|
|
false,
|
|
`The ${pref} button is enabled when unlocked`
|
|
);
|
|
});
|
|
|
|
// Lock the prefs without an extension.
|
|
await waitForLockMutations(true);
|
|
|
|
// Check that everything is now disabled.
|
|
is(getHomepage(), lockedHomepage, "The reported homepage is set by the pref");
|
|
is(homePageInput.value, lockedHomepage, "The homepage is set by the pref");
|
|
is(
|
|
homePageInput.disabled,
|
|
true,
|
|
"The homepage is disabed when the pref is locked"
|
|
);
|
|
is(
|
|
homeModeEl.disabled,
|
|
true,
|
|
"Homepage menulist is disabled when pref is locked"
|
|
);
|
|
buttonPrefs.forEach(pref => {
|
|
is(
|
|
getButton(pref).disabled,
|
|
true,
|
|
`The ${pref} button is disabled when locked`
|
|
);
|
|
});
|
|
|
|
// Unlock the prefs without an extension.
|
|
await waitForLockMutations(false);
|
|
|
|
// Check that everything is enabled again.
|
|
is(
|
|
getHomepage(),
|
|
originalHomepage,
|
|
"The homepage is reset to the original value"
|
|
);
|
|
is(homePageInput.value, "", "The homepage is clear after being unlocked");
|
|
is(
|
|
homePageInput.disabled,
|
|
false,
|
|
"The homepage is enabled after clearing lock"
|
|
);
|
|
is(
|
|
homeModeEl.disabled,
|
|
false,
|
|
"Homepage menulist is enabled after clearing lock"
|
|
);
|
|
buttonPrefs.forEach(pref => {
|
|
is(
|
|
getButton(pref).disabled,
|
|
false,
|
|
`The ${pref} button is enabled when unlocked`
|
|
);
|
|
});
|
|
|
|
BrowserTestUtils.removeTab(gBrowser.selectedTab);
|
|
});
|
|
|
|
add_task(async function testExtensionControlledNewTab() {
|
|
const ADDON_ID = "@set_newtab";
|
|
const SECOND_ADDON_ID = "@second_set_newtab";
|
|
const DEFAULT_NEWTAB = "about:newtab";
|
|
const NEWTAB_CONTROLLED_PREF = "browser.newtab.extensionControlled";
|
|
|
|
await openPreferencesViaOpenPreferencesAPI("paneHome", { leaveOpen: true });
|
|
is(
|
|
gBrowser.currentURI.spec,
|
|
"about:preferences#home",
|
|
"#home should be in the URI for about:preferences"
|
|
);
|
|
|
|
let doc = gBrowser.contentDocument;
|
|
let newTabMenuList = doc.getElementById("newTabMode");
|
|
// The new tab page is set to the default.
|
|
is(AboutNewTab.newTabURL, DEFAULT_NEWTAB, "new tab is set to default");
|
|
|
|
let promise = TestUtils.waitForCondition(
|
|
() => newTabMenuList.itemCount == 3,
|
|
"addon option is added as an option in the menu list"
|
|
);
|
|
// Install an extension that will set the new tab page.
|
|
let extension = ExtensionTestUtils.loadExtension({
|
|
useAddonManager: "permanent",
|
|
manifest: {
|
|
version: "1.0",
|
|
name: "set_newtab",
|
|
browser_specific_settings: {
|
|
gecko: {
|
|
id: ADDON_ID,
|
|
},
|
|
},
|
|
chrome_url_overrides: { newtab: "/newtab.html" },
|
|
},
|
|
});
|
|
await extension.startup();
|
|
|
|
await promise;
|
|
let addon = await AddonManager.getAddonByID(ADDON_ID);
|
|
|
|
is(newTabMenuList.value, ADDON_ID, "New tab menulist is set to the add-on");
|
|
|
|
let levelOfControl = await ExtensionPreferencesManager.getLevelOfControl(
|
|
addon.id,
|
|
NEW_TAB_KEY,
|
|
URL_OVERRIDES_TYPE
|
|
);
|
|
is(
|
|
levelOfControl,
|
|
"controlled_by_this_extension",
|
|
"getLevelOfControl returns controlled_by_this_extension."
|
|
);
|
|
let setting = ExtensionSettingsStore.getSetting(
|
|
URL_OVERRIDES_TYPE,
|
|
NEW_TAB_KEY
|
|
);
|
|
ok(
|
|
setting.value.startsWith("moz-extension") &&
|
|
setting.value.endsWith("newtab.html"),
|
|
"The url_overrides is set by this extension"
|
|
);
|
|
|
|
promise = TestUtils.waitForPrefChange(NEWTAB_CONTROLLED_PREF);
|
|
// Set the menu to the default value
|
|
newTabMenuList.value = "0";
|
|
newTabMenuList.dispatchEvent(new Event("command"));
|
|
await promise;
|
|
let newTabPref = Services.prefs.getBoolPref(NEWTAB_CONTROLLED_PREF, false);
|
|
is(newTabPref, false, "the new tab is not controlled");
|
|
|
|
levelOfControl = await ExtensionPreferencesManager.getLevelOfControl(
|
|
addon.id,
|
|
NEW_TAB_KEY,
|
|
URL_OVERRIDES_TYPE
|
|
);
|
|
is(
|
|
levelOfControl,
|
|
"not_controllable",
|
|
"getLevelOfControl returns not_controllable."
|
|
);
|
|
setting = ExtensionSettingsStore.getSetting(URL_OVERRIDES_TYPE, NEW_TAB_KEY);
|
|
ok(!setting.value, "The url_overrides is not set by this extension");
|
|
|
|
promise = TestUtils.waitForPrefChange(NEWTAB_CONTROLLED_PREF);
|
|
// Set the menu to a the addon value
|
|
newTabMenuList.value = ADDON_ID;
|
|
newTabMenuList.dispatchEvent(new Event("command"));
|
|
await promise;
|
|
newTabPref = Services.prefs.getBoolPref(NEWTAB_CONTROLLED_PREF, false);
|
|
is(newTabPref, true, "the new tab is controlled");
|
|
|
|
// Add a second extension, ensure it is added to the menulist and selected.
|
|
promise = TestUtils.waitForCondition(
|
|
() => newTabMenuList.itemCount == 4,
|
|
"addon option is added as an option in the menu list"
|
|
);
|
|
let secondExtension = ExtensionTestUtils.loadExtension({
|
|
useAddonManager: "permanent",
|
|
manifest: {
|
|
version: "1.0",
|
|
name: "second_set_newtab",
|
|
browser_specific_settings: {
|
|
gecko: {
|
|
id: SECOND_ADDON_ID,
|
|
},
|
|
},
|
|
chrome_url_overrides: { newtab: "/newtab2.html" },
|
|
},
|
|
});
|
|
await secondExtension.startup();
|
|
await promise;
|
|
let secondAddon = await AddonManager.getAddonByID(SECOND_ADDON_ID);
|
|
is(
|
|
newTabMenuList.value,
|
|
SECOND_ADDON_ID,
|
|
"New tab menulist is set to the add-on"
|
|
);
|
|
|
|
levelOfControl = await ExtensionPreferencesManager.getLevelOfControl(
|
|
secondAddon.id,
|
|
NEW_TAB_KEY,
|
|
URL_OVERRIDES_TYPE
|
|
);
|
|
is(
|
|
levelOfControl,
|
|
"controlled_by_this_extension",
|
|
"getLevelOfControl returns controlled_by_this_extension."
|
|
);
|
|
setting = ExtensionSettingsStore.getSetting(URL_OVERRIDES_TYPE, NEW_TAB_KEY);
|
|
ok(
|
|
setting.value.startsWith("moz-extension") &&
|
|
setting.value.endsWith("newtab2.html"),
|
|
"The url_overrides is set by the second extension"
|
|
);
|
|
|
|
promise = TestUtils.waitForCondition(
|
|
() => newTabMenuList.itemCount == 3,
|
|
"addon option is no longer an option in the menu list after disable, even if it was not selected"
|
|
);
|
|
await addon.disable();
|
|
await promise;
|
|
|
|
// Ensure that re-enabling an addon adds it back to the menulist
|
|
promise = TestUtils.waitForCondition(
|
|
() => newTabMenuList.itemCount == 4,
|
|
"addon option is added again to the menulist when enabled"
|
|
);
|
|
await addon.enable();
|
|
await promise;
|
|
|
|
promise = TestUtils.waitForCondition(
|
|
() => newTabMenuList.itemCount == 3,
|
|
"addon option is no longer an option in the menu list after disable"
|
|
);
|
|
await secondAddon.disable();
|
|
await promise;
|
|
|
|
promise = TestUtils.waitForCondition(
|
|
() => newTabMenuList.itemCount == 4,
|
|
"addon option is added again to the menulist when enabled"
|
|
);
|
|
await secondAddon.enable();
|
|
await promise;
|
|
|
|
promise = TestUtils.waitForCondition(
|
|
() => newTabMenuList.itemCount == 2,
|
|
"addon options are all removed after disabling all"
|
|
);
|
|
await addon.disable();
|
|
await secondAddon.disable();
|
|
await promise;
|
|
is(
|
|
AboutNewTab.newTabURL,
|
|
DEFAULT_NEWTAB,
|
|
"new tab page is set back to default"
|
|
);
|
|
|
|
// Cleanup the tabs and add-on.
|
|
BrowserTestUtils.removeTab(gBrowser.selectedTab);
|
|
await extension.unload();
|
|
await secondExtension.unload();
|
|
});
|
|
|
|
add_task(async function testExtensionControlledWebNotificationsPermission() {
|
|
let manifest = {
|
|
manifest_version: 2,
|
|
name: "TestExtension",
|
|
version: "1.0",
|
|
description: "Testing WebNotificationsDisable",
|
|
browser_specific_settings: { gecko: { id: "@web_notifications_disable" } },
|
|
permissions: ["browserSettings"],
|
|
browser_action: {
|
|
default_title: "Testing",
|
|
},
|
|
};
|
|
|
|
await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
|
|
await openNotificationsPermissionDialog();
|
|
|
|
let doc = sitePermissionsDialog.document;
|
|
let extensionControlledContent = doc.getElementById(
|
|
"browserNotificationsPermissionExtensionContent"
|
|
);
|
|
|
|
// Test that extension content is initially hidden.
|
|
ok(
|
|
extensionControlledContent.hidden,
|
|
"Extension content is initially hidden"
|
|
);
|
|
|
|
// Install an extension that will disable web notifications permission.
|
|
let messageShown = waitForMessageShown(
|
|
"browserNotificationsPermissionExtensionContent",
|
|
doc
|
|
);
|
|
let extension = ExtensionTestUtils.loadExtension({
|
|
manifest,
|
|
useAddonManager: "permanent",
|
|
background() {
|
|
browser.browserSettings.webNotificationsDisabled.set({ value: true });
|
|
browser.test.sendMessage("load-extension");
|
|
},
|
|
});
|
|
await extension.startup();
|
|
await extension.awaitMessage("load-extension");
|
|
await messageShown;
|
|
|
|
let controlledDesc = extensionControlledContent.querySelector("description");
|
|
Assert.deepEqual(
|
|
doc.l10n.getAttributes(controlledDesc),
|
|
{
|
|
id: "extension-controlling-web-notifications",
|
|
args: {
|
|
name: "TestExtension",
|
|
},
|
|
},
|
|
"The user is notified that an extension is controlling the web notifications permission"
|
|
);
|
|
is(
|
|
extensionControlledContent.hidden,
|
|
false,
|
|
"The extension controlled row is not hidden"
|
|
);
|
|
|
|
// Disable the extension.
|
|
doc.getElementById("disableNotificationsPermissionExtension").click();
|
|
|
|
// Verify the user is notified how to enable the extension.
|
|
await waitForEnableMessage(extensionControlledContent.id, doc);
|
|
is(
|
|
doc.l10n.getAttributes(controlledDesc.querySelector("label")).id,
|
|
"extension-controlled-enable",
|
|
"The user is notified of how to enable the extension again"
|
|
);
|
|
|
|
// Verify the enable message can be dismissed.
|
|
let hidden = waitForMessageHidden(extensionControlledContent.id, doc);
|
|
let dismissButton = controlledDesc.querySelector("image:last-of-type");
|
|
dismissButton.click();
|
|
await hidden;
|
|
|
|
// Verify that the extension controlled content in hidden again.
|
|
is(
|
|
extensionControlledContent.hidden,
|
|
true,
|
|
"The extension controlled row is now hidden"
|
|
);
|
|
|
|
await extension.unload();
|
|
BrowserTestUtils.removeTab(gBrowser.selectedTab);
|
|
});
|
|
|
|
add_task(async function testExtensionControlledHomepageUninstalledAddon() {
|
|
async function checkHomepageEnabled() {
|
|
await openPreferencesViaOpenPreferencesAPI("paneHome", { leaveOpen: true });
|
|
let doc = gBrowser.contentDocument;
|
|
is(
|
|
gBrowser.currentURI.spec,
|
|
"about:preferences#home",
|
|
"#home should be in the URI for about:preferences"
|
|
);
|
|
|
|
// The homepage is enabled.
|
|
let homepageInput = doc.getElementById("homePageUrl");
|
|
is(homepageInput.disabled, false, "The homepage input is enabled");
|
|
is(homepageInput.value, "", "The homepage input is empty");
|
|
|
|
BrowserTestUtils.removeTab(gBrowser.selectedTab);
|
|
}
|
|
|
|
await ExtensionSettingsStore.initialize();
|
|
|
|
// Verify the setting isn't reported as controlled and the inputs are enabled.
|
|
is(
|
|
ExtensionSettingsStore.getSetting("prefs", "homepage_override"),
|
|
null,
|
|
"The homepage_override is not set"
|
|
);
|
|
await checkHomepageEnabled();
|
|
|
|
// Disarm any pending writes before we modify the JSONFile directly.
|
|
await ExtensionSettingsStore._reloadFile(false);
|
|
|
|
// Write out a bad store file.
|
|
let storeData = {
|
|
prefs: {
|
|
homepage_override: {
|
|
initialValue: "",
|
|
precedenceList: [
|
|
{
|
|
id: "bad@mochi.test",
|
|
installDate: 1508802672,
|
|
value: "https://developer.mozilla.org",
|
|
enabled: true,
|
|
},
|
|
],
|
|
},
|
|
},
|
|
};
|
|
let jsonFileName = "extension-settings.json";
|
|
let storePath = PathUtils.join(PathUtils.profileDir, jsonFileName);
|
|
|
|
await IOUtils.writeUTF8(storePath, JSON.stringify(storeData));
|
|
|
|
// Reload the ExtensionSettingsStore so it will read the file on disk. Don't
|
|
// finalize the current store since it will overwrite our file.
|
|
await ExtensionSettingsStore._reloadFile(false);
|
|
|
|
// Verify that the setting is reported as set, but the homepage is still enabled
|
|
// since there is no matching installed extension.
|
|
is(
|
|
ExtensionSettingsStore.getSetting("prefs", "homepage_override").value,
|
|
"https://developer.mozilla.org",
|
|
"The homepage_override appears to be set"
|
|
);
|
|
await checkHomepageEnabled();
|
|
|
|
// Remove the bad store file that we used.
|
|
await IOUtils.remove(storePath);
|
|
|
|
// Reload the ExtensionSettingsStore again so it clears the data we added.
|
|
// Don't finalize the current store since it will write out the bad data.
|
|
await ExtensionSettingsStore._reloadFile(false);
|
|
|
|
is(
|
|
ExtensionSettingsStore.getSetting("prefs", "homepage_override"),
|
|
null,
|
|
"The ExtensionSettingsStore is left empty."
|
|
);
|
|
});
|
|
|
|
add_task(async function testExtensionControlledTrackingProtection() {
|
|
const TP_PREF = "privacy.trackingprotection.enabled";
|
|
const TP_DEFAULT = false;
|
|
const EXTENSION_ID = "@set_tp";
|
|
const CONTROLLED_LABEL_ID =
|
|
"contentBlockingTrackingProtectionExtensionContentLabel";
|
|
const CONTROLLED_BUTTON_ID =
|
|
"contentBlockingDisableTrackingProtectionExtension";
|
|
|
|
let tpEnabledPref = () => Services.prefs.getBoolPref(TP_PREF);
|
|
|
|
await SpecialPowers.pushPrefEnv({ set: [[TP_PREF, TP_DEFAULT]] });
|
|
|
|
function background() {
|
|
browser.privacy.websites.trackingProtectionMode.set({ value: "always" });
|
|
}
|
|
|
|
function verifyState(isControlled) {
|
|
is(tpEnabledPref(), isControlled, "TP pref is set to the expected value.");
|
|
|
|
let controlledLabel = doc.getElementById(CONTROLLED_LABEL_ID);
|
|
let controlledButton = doc.getElementById(CONTROLLED_BUTTON_ID);
|
|
|
|
is(
|
|
controlledLabel.hidden,
|
|
!isControlled,
|
|
"The extension controlled row's visibility is as expected."
|
|
);
|
|
is(
|
|
controlledButton.hidden,
|
|
!isControlled,
|
|
"The disable extension button's visibility is as expected."
|
|
);
|
|
if (isControlled) {
|
|
let controlledDesc = controlledLabel.querySelector("description");
|
|
Assert.deepEqual(
|
|
doc.l10n.getAttributes(controlledDesc),
|
|
{
|
|
id: "extension-controlling-websites-content-blocking-all-trackers",
|
|
args: {
|
|
name: "set_tp",
|
|
},
|
|
},
|
|
"The user is notified that an extension is controlling TP."
|
|
);
|
|
}
|
|
|
|
is(
|
|
doc.getElementById("trackingProtectionMenu").disabled,
|
|
isControlled,
|
|
"TP control is enabled."
|
|
);
|
|
}
|
|
|
|
await openPreferencesViaOpenPreferencesAPI("panePrivacy", {
|
|
leaveOpen: true,
|
|
});
|
|
let doc = gBrowser.contentDocument;
|
|
|
|
is(
|
|
gBrowser.currentURI.spec,
|
|
"about:preferences#privacy",
|
|
"#privacy should be in the URI for about:preferences"
|
|
);
|
|
|
|
verifyState(false);
|
|
|
|
// Install an extension that sets Tracking Protection.
|
|
let extension = ExtensionTestUtils.loadExtension({
|
|
useAddonManager: "permanent",
|
|
manifest: {
|
|
name: "set_tp",
|
|
browser_specific_settings: { gecko: { id: EXTENSION_ID } },
|
|
permissions: ["privacy"],
|
|
},
|
|
background,
|
|
});
|
|
|
|
let messageShown = waitForMessageShown(CONTROLLED_LABEL_ID);
|
|
await extension.startup();
|
|
await messageShown;
|
|
let addon = await AddonManager.getAddonByID(EXTENSION_ID);
|
|
|
|
verifyState(true);
|
|
|
|
await disableExtensionViaClick(
|
|
CONTROLLED_LABEL_ID,
|
|
CONTROLLED_BUTTON_ID,
|
|
doc
|
|
);
|
|
|
|
verifyState(false);
|
|
|
|
// Enable the extension so we get the UNINSTALL event, which is needed by
|
|
// ExtensionPreferencesManager to clean up properly.
|
|
// TODO: BUG 1408226
|
|
await reEnableExtension(addon, CONTROLLED_LABEL_ID);
|
|
|
|
await extension.unload();
|
|
|
|
BrowserTestUtils.removeTab(gBrowser.selectedTab);
|
|
});
|
|
|
|
add_task(async function testExtensionControlledPasswordManager() {
|
|
const PASSWORD_MANAGER_ENABLED_PREF = "signon.rememberSignons";
|
|
const PASSWORD_MANAGER_ENABLED_DEFAULT = true;
|
|
const CONTROLLED_BUTTON_ID = "disablePasswordManagerExtension";
|
|
const CONTROLLED_LABEL_ID = "passwordManagerExtensionContent";
|
|
const EXTENSION_ID = "@remember_signons";
|
|
let manifest = {
|
|
manifest_version: 2,
|
|
name: "testPasswordManagerExtension",
|
|
version: "1.0",
|
|
description: "Testing rememberSignons",
|
|
browser_specific_settings: { gecko: { id: EXTENSION_ID } },
|
|
permissions: ["privacy"],
|
|
browser_action: {
|
|
default_title: "Testing rememberSignons",
|
|
},
|
|
};
|
|
|
|
let passwordManagerEnabledPref = () =>
|
|
Services.prefs.getBoolPref(PASSWORD_MANAGER_ENABLED_PREF);
|
|
|
|
await SpecialPowers.pushPrefEnv({
|
|
set: [[PASSWORD_MANAGER_ENABLED_PREF, PASSWORD_MANAGER_ENABLED_DEFAULT]],
|
|
});
|
|
is(
|
|
passwordManagerEnabledPref(),
|
|
true,
|
|
"Password manager is enabled by default."
|
|
);
|
|
|
|
function verifyState(isControlled) {
|
|
is(
|
|
passwordManagerEnabledPref(),
|
|
!isControlled,
|
|
"Password manager pref is set to the expected value."
|
|
);
|
|
let controlledLabel =
|
|
gBrowser.contentDocument.getElementById(CONTROLLED_LABEL_ID);
|
|
let controlledButton =
|
|
gBrowser.contentDocument.getElementById(CONTROLLED_BUTTON_ID);
|
|
is(
|
|
controlledLabel.hidden,
|
|
!isControlled,
|
|
"The extension's controlled row visibility is as expected."
|
|
);
|
|
is(
|
|
controlledButton.hidden,
|
|
!isControlled,
|
|
"The extension's controlled button visibility is as expected."
|
|
);
|
|
if (isControlled) {
|
|
let controlledDesc = controlledLabel.querySelector("description");
|
|
Assert.deepEqual(
|
|
gBrowser.contentDocument.l10n.getAttributes(controlledDesc),
|
|
{
|
|
id: "extension-controlling-password-saving",
|
|
args: {
|
|
name: "testPasswordManagerExtension",
|
|
},
|
|
},
|
|
"The user is notified that an extension is controlling the remember signons pref."
|
|
);
|
|
}
|
|
}
|
|
|
|
await openPreferencesViaOpenPreferencesAPI("panePrivacy", {
|
|
leaveOpen: true,
|
|
});
|
|
|
|
info("Verify that no extension is controlling the password manager pref.");
|
|
verifyState(false);
|
|
|
|
let extension = ExtensionTestUtils.loadExtension({
|
|
manifest,
|
|
useAddonManager: "permanent",
|
|
background() {
|
|
browser.privacy.services.passwordSavingEnabled.set({ value: false });
|
|
},
|
|
});
|
|
let messageShown = waitForMessageShown(CONTROLLED_LABEL_ID);
|
|
await extension.startup();
|
|
await messageShown;
|
|
|
|
info(
|
|
"Verify that the test extension is controlling the password manager pref."
|
|
);
|
|
verifyState(true);
|
|
|
|
info("Verify that the extension shows as controlled when loaded again.");
|
|
BrowserTestUtils.removeTab(gBrowser.selectedTab);
|
|
await openPreferencesViaOpenPreferencesAPI("panePrivacy", {
|
|
leaveOpen: true,
|
|
});
|
|
verifyState(true);
|
|
|
|
await disableExtensionViaClick(
|
|
CONTROLLED_LABEL_ID,
|
|
CONTROLLED_BUTTON_ID,
|
|
gBrowser.contentDocument
|
|
);
|
|
|
|
info(
|
|
"Verify that disabling the test extension removes the lock on the password manager pref."
|
|
);
|
|
verifyState(false);
|
|
|
|
await extension.unload();
|
|
|
|
BrowserTestUtils.removeTab(gBrowser.selectedTab);
|
|
});
|
|
|
|
add_task(async function testExtensionControlledProxyConfig() {
|
|
const proxySvc = Ci.nsIProtocolProxyService;
|
|
const PROXY_DEFAULT = proxySvc.PROXYCONFIG_SYSTEM;
|
|
const EXTENSION_ID = "@set_proxy";
|
|
const CONTROLLED_SECTION_ID = "proxyExtensionContent";
|
|
const CONTROLLED_BUTTON_ID = "disableProxyExtension";
|
|
const CONNECTION_SETTINGS_DESC_ID = "connectionSettingsDescription";
|
|
const PANEL_URL =
|
|
"chrome://browser/content/preferences/dialogs/connection.xhtml";
|
|
|
|
await SpecialPowers.pushPrefEnv({ set: [[PROXY_PREF, PROXY_DEFAULT]] });
|
|
|
|
function background() {
|
|
browser.proxy.settings.set({ value: { proxyType: "none" } });
|
|
}
|
|
|
|
function expectedConnectionSettingsMessage(doc, isControlled) {
|
|
return isControlled
|
|
? "extension-controlling-proxy-config"
|
|
: "network-proxy-connection-description";
|
|
}
|
|
|
|
function connectionSettingsMessagePromise(doc, isControlled) {
|
|
return waitForMessageContent(
|
|
CONNECTION_SETTINGS_DESC_ID,
|
|
expectedConnectionSettingsMessage(doc, isControlled),
|
|
doc
|
|
);
|
|
}
|
|
|
|
function verifyProxyState(doc, isControlled) {
|
|
let isPanel = doc.getElementById(CONTROLLED_BUTTON_ID);
|
|
is(
|
|
proxyType === proxySvc.PROXYCONFIG_DIRECT,
|
|
isControlled,
|
|
"Proxy pref is set to the expected value."
|
|
);
|
|
|
|
if (isPanel) {
|
|
let controlledSection = doc.getElementById(CONTROLLED_SECTION_ID);
|
|
|
|
is(
|
|
controlledSection.hidden,
|
|
!isControlled,
|
|
"The extension controlled row's visibility is as expected."
|
|
);
|
|
if (isPanel) {
|
|
is(
|
|
doc.getElementById(CONTROLLED_BUTTON_ID).hidden,
|
|
!isControlled,
|
|
"The disable extension button's visibility is as expected."
|
|
);
|
|
}
|
|
if (isControlled) {
|
|
let controlledDesc = controlledSection.querySelector("description");
|
|
Assert.deepEqual(
|
|
doc.l10n.getAttributes(controlledDesc),
|
|
{
|
|
id: "extension-controlling-proxy-config",
|
|
args: {
|
|
name: "set_proxy",
|
|
},
|
|
},
|
|
"The user is notified that an extension is controlling proxy settings."
|
|
);
|
|
}
|
|
function getProxyControls() {
|
|
let controlGroup = doc.getElementById("networkProxyType");
|
|
let manualControlContainer = controlGroup.querySelector("#proxy-grid");
|
|
return {
|
|
manualControls: [
|
|
...manualControlContainer.querySelectorAll(
|
|
"label[data-l10n-id]:not([control=networkProxyNone])"
|
|
),
|
|
...manualControlContainer.querySelectorAll("input"),
|
|
...manualControlContainer.querySelectorAll("checkbox"),
|
|
...doc.querySelectorAll("#networkProxySOCKSVersion > radio"),
|
|
],
|
|
pacControls: [doc.getElementById("networkProxyAutoconfigURL")],
|
|
otherControls: [
|
|
doc.querySelector("label[control=networkProxyNone]"),
|
|
doc.getElementById("networkProxyNone"),
|
|
...controlGroup.querySelectorAll(":scope > radio"),
|
|
...doc.querySelectorAll("#ConnectionsDialogPane > checkbox"),
|
|
],
|
|
};
|
|
}
|
|
let controlState = isControlled ? "disabled" : "enabled";
|
|
let controls = getProxyControls();
|
|
for (let element of controls.manualControls) {
|
|
let disabled =
|
|
isControlled || proxyType !== proxySvc.PROXYCONFIG_MANUAL;
|
|
is(
|
|
element.disabled,
|
|
disabled,
|
|
`Manual proxy controls should be ${controlState} - control: ${element.outerHTML}.`
|
|
);
|
|
}
|
|
for (let element of controls.pacControls) {
|
|
let disabled = isControlled || proxyType !== proxySvc.PROXYCONFIG_PAC;
|
|
is(
|
|
element.disabled,
|
|
disabled,
|
|
`PAC proxy controls should be ${controlState} - control: ${element.outerHTML}.`
|
|
);
|
|
}
|
|
for (let element of controls.otherControls) {
|
|
is(
|
|
element.disabled,
|
|
isControlled,
|
|
`Other proxy controls should be ${controlState} - control: ${element.outerHTML}.`
|
|
);
|
|
}
|
|
} else {
|
|
let elem = doc.getElementById(CONNECTION_SETTINGS_DESC_ID);
|
|
is(
|
|
doc.l10n.getAttributes(elem).id,
|
|
expectedConnectionSettingsMessage(doc, isControlled),
|
|
"The connection settings description is as expected."
|
|
);
|
|
}
|
|
}
|
|
|
|
async function reEnableProxyExtension(addon) {
|
|
let messageChanged = connectionSettingsMessagePromise(mainDoc, true);
|
|
await addon.enable();
|
|
await messageChanged;
|
|
}
|
|
|
|
async function openProxyPanel() {
|
|
let panel = await openAndLoadSubDialog(PANEL_URL);
|
|
let closingPromise = BrowserTestUtils.waitForEvent(
|
|
panel.document.getElementById("ConnectionsDialog"),
|
|
"dialogclosing"
|
|
);
|
|
ok(panel, "Proxy panel opened.");
|
|
return { panel, closingPromise };
|
|
}
|
|
|
|
async function closeProxyPanel(panelObj) {
|
|
let dialog = panelObj.panel.document.getElementById("ConnectionsDialog");
|
|
dialog.cancelDialog();
|
|
let panelClosingEvent = await panelObj.closingPromise;
|
|
ok(panelClosingEvent, "Proxy panel closed.");
|
|
}
|
|
|
|
await openPreferencesViaOpenPreferencesAPI("paneGeneral", {
|
|
leaveOpen: true,
|
|
});
|
|
let mainDoc = gBrowser.contentDocument;
|
|
|
|
is(
|
|
gBrowser.currentURI.spec,
|
|
"about:preferences#general",
|
|
"#general should be in the URI for about:preferences"
|
|
);
|
|
|
|
verifyProxyState(mainDoc, false);
|
|
|
|
// Open the connections panel.
|
|
let panelObj = await openProxyPanel();
|
|
let panelDoc = panelObj.panel.document;
|
|
|
|
verifyProxyState(panelDoc, false);
|
|
|
|
await closeProxyPanel(panelObj);
|
|
|
|
verifyProxyState(mainDoc, false);
|
|
|
|
// Install an extension that controls proxy settings. The extension needs
|
|
// incognitoOverride because controlling the proxy.settings requires private
|
|
// browsing access.
|
|
let extension = ExtensionTestUtils.loadExtension({
|
|
incognitoOverride: "spanning",
|
|
useAddonManager: "permanent",
|
|
manifest: {
|
|
name: "set_proxy",
|
|
browser_specific_settings: { gecko: { id: EXTENSION_ID } },
|
|
permissions: ["proxy"],
|
|
},
|
|
background,
|
|
});
|
|
|
|
let messageChanged = connectionSettingsMessagePromise(mainDoc, true);
|
|
await extension.startup();
|
|
await messageChanged;
|
|
let addon = await AddonManager.getAddonByID(EXTENSION_ID);
|
|
|
|
verifyProxyState(mainDoc, true);
|
|
messageChanged = connectionSettingsMessagePromise(mainDoc, false);
|
|
|
|
panelObj = await openProxyPanel();
|
|
panelDoc = panelObj.panel.document;
|
|
|
|
verifyProxyState(panelDoc, true);
|
|
|
|
await disableExtensionViaClick(
|
|
CONTROLLED_SECTION_ID,
|
|
CONTROLLED_BUTTON_ID,
|
|
panelDoc
|
|
);
|
|
|
|
verifyProxyState(panelDoc, false);
|
|
|
|
await closeProxyPanel(panelObj);
|
|
await messageChanged;
|
|
|
|
verifyProxyState(mainDoc, false);
|
|
|
|
await reEnableProxyExtension(addon);
|
|
|
|
verifyProxyState(mainDoc, true);
|
|
messageChanged = connectionSettingsMessagePromise(mainDoc, false);
|
|
|
|
panelObj = await openProxyPanel();
|
|
panelDoc = panelObj.panel.document;
|
|
|
|
verifyProxyState(panelDoc, true);
|
|
|
|
await disableExtensionViaClick(
|
|
CONTROLLED_SECTION_ID,
|
|
CONTROLLED_BUTTON_ID,
|
|
panelDoc
|
|
);
|
|
|
|
verifyProxyState(panelDoc, false);
|
|
|
|
await closeProxyPanel(panelObj);
|
|
await messageChanged;
|
|
|
|
verifyProxyState(mainDoc, false);
|
|
|
|
// Enable the extension so we get the UNINSTALL event, which is needed by
|
|
// ExtensionPreferencesManager to clean up properly.
|
|
// TODO: BUG 1408226
|
|
await reEnableProxyExtension(addon);
|
|
|
|
await extension.unload();
|
|
|
|
BrowserTestUtils.removeTab(gBrowser.selectedTab);
|
|
});
|
|
|
|
// Test that the newtab menu selection is correct when loading about:preferences
|
|
add_task(async function testMenuSyncFromPrefs() {
|
|
const DEFAULT_NEWTAB = "about:newtab";
|
|
|
|
await openPreferencesViaOpenPreferencesAPI("paneHome", { leaveOpen: true });
|
|
is(
|
|
gBrowser.currentURI.spec,
|
|
"about:preferences#home",
|
|
"#home should be in the URI for about:preferences"
|
|
);
|
|
|
|
let doc = gBrowser.contentDocument;
|
|
let newTabMenuList = doc.getElementById("newTabMode");
|
|
// The new tab page is set to the default.
|
|
is(AboutNewTab.newTabURL, DEFAULT_NEWTAB, "new tab is set to default");
|
|
|
|
is(newTabMenuList.value, "0", "New tab menulist is set to the default");
|
|
|
|
newTabMenuList.value = "1";
|
|
newTabMenuList.dispatchEvent(new Event("command"));
|
|
is(newTabMenuList.value, "1", "New tab menulist is set to blank");
|
|
|
|
gBrowser.reloadTab(gBrowser.selectedTab);
|
|
|
|
await TestUtils.waitForCondition(
|
|
() => gBrowser.contentDocument.getElementById("newTabMode"),
|
|
"wait until element exists in new contentDoc"
|
|
);
|
|
|
|
is(
|
|
gBrowser.contentDocument.getElementById("newTabMode").value,
|
|
"1",
|
|
"New tab menulist is still set to blank"
|
|
);
|
|
|
|
// Cleanup
|
|
newTabMenuList.value = "0";
|
|
newTabMenuList.dispatchEvent(new Event("command"));
|
|
is(AboutNewTab.newTabURL, DEFAULT_NEWTAB, "new tab is set to default");
|
|
BrowserTestUtils.removeTab(gBrowser.selectedTab);
|
|
});
|