123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 |
- /* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
- "use strict";
- const ADDON_ID = "test-devtools@mozilla.org";
- const ADDON_NAME = "test-devtools";
- /**
- * Returns a promise that resolves when the given add-on event is fired. The
- * resolved value is an array of arguments passed for the event.
- */
- function promiseAddonEvent(event) {
- return new Promise(resolve => {
- let listener = {
- [event]: function (...args) {
- AddonManager.removeAddonListener(listener);
- resolve(args);
- }
- };
- AddonManager.addAddonListener(listener);
- });
- }
- function* tearDownAddon(addon) {
- const onUninstalled = promiseAddonEvent("onUninstalled");
- addon.uninstall();
- const [uninstalledAddon] = yield onUninstalled;
- is(uninstalledAddon.id, addon.id,
- `Add-on was uninstalled: ${uninstalledAddon.id}`);
- }
- function getReloadButton(document, addonName) {
- const names = [...document.querySelectorAll("#addons .target-name")];
- const name = names.filter(element => element.textContent === addonName)[0];
- ok(name, `Found ${addonName} add-on in the list`);
- const targetElement = name.parentNode.parentNode;
- const reloadButton = targetElement.querySelector(".reload-button");
- info(`Found reload button for ${addonName}`);
- return reloadButton;
- }
- function installAddonWithManager(filePath) {
- return new Promise((resolve, reject) => {
- AddonManager.getInstallForFile(filePath, install => {
- if (!install) {
- throw new Error(`An install was not created for ${filePath}`);
- }
- install.addListener({
- onDownloadFailed: reject,
- onDownloadCancelled: reject,
- onInstallFailed: reject,
- onInstallCancelled: reject,
- onInstallEnded: resolve
- });
- install.install();
- });
- });
- }
- function getAddonByID(addonId) {
- return new Promise(resolve => {
- AddonManager.getAddonByID(addonId, addon => resolve(addon));
- });
- }
- /**
- * Creates a web extension from scratch in a temporary location.
- * The object must be removed when you're finished working with it.
- */
- class TempWebExt {
- constructor(addonId) {
- this.addonId = addonId;
- this.tmpDir = FileUtils.getDir("TmpD", ["browser_addons_reload"]);
- if (!this.tmpDir.exists()) {
- this.tmpDir.create(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
- }
- this.sourceDir = this.tmpDir.clone();
- this.sourceDir.append(this.addonId);
- if (!this.sourceDir.exists()) {
- this.sourceDir.create(Ci.nsIFile.DIRECTORY_TYPE,
- FileUtils.PERMS_DIRECTORY);
- }
- }
- writeManifest(manifestData) {
- const manifest = this.sourceDir.clone();
- manifest.append("manifest.json");
- if (manifest.exists()) {
- manifest.remove(true);
- }
- const fos = Cc["@mozilla.org/network/file-output-stream;1"]
- .createInstance(Ci.nsIFileOutputStream);
- fos.init(manifest,
- FileUtils.MODE_WRONLY | FileUtils.MODE_CREATE |
- FileUtils.MODE_TRUNCATE,
- FileUtils.PERMS_FILE, 0);
- const manifestString = JSON.stringify(manifestData);
- fos.write(manifestString, manifestString.length);
- fos.close();
- }
- remove() {
- return this.tmpDir.remove(true);
- }
- }
- add_task(function* reloadButtonReloadsAddon() {
- const { tab, document } = yield openAboutDebugging("addons");
- yield waitForInitialAddonList(document);
- yield installAddon({
- document,
- path: "addons/unpacked/install.rdf",
- name: ADDON_NAME,
- });
- const reloadButton = getReloadButton(document, ADDON_NAME);
- is(reloadButton.disabled, false, "Reload button should not be disabled");
- is(reloadButton.title, "", "Reload button should not have a tooltip");
- const onInstalled = promiseAddonEvent("onInstalled");
- const onBootstrapInstallCalled = new Promise(done => {
- Services.obs.addObserver(function listener() {
- Services.obs.removeObserver(listener, ADDON_NAME, false);
- info("Add-on was re-installed: " + ADDON_NAME);
- done();
- }, ADDON_NAME, false);
- });
- reloadButton.click();
- const [reloadedAddon] = yield onInstalled;
- is(reloadedAddon.name, ADDON_NAME,
- "Add-on was reloaded: " + reloadedAddon.name);
- yield onBootstrapInstallCalled;
- yield tearDownAddon(reloadedAddon);
- yield closeAboutDebugging(tab);
- });
- add_task(function* reloadButtonRefreshesMetadata() {
- const { tab, document } = yield openAboutDebugging("addons");
- yield waitForInitialAddonList(document);
- const manifestBase = {
- "manifest_version": 2,
- "name": "Temporary web extension",
- "version": "1.0",
- "applications": {
- "gecko": {
- "id": ADDON_ID
- }
- }
- };
- const tempExt = new TempWebExt(ADDON_ID);
- tempExt.writeManifest(manifestBase);
- const onAddonListUpdated = waitForMutation(getAddonList(document),
- { childList: true });
- const onInstalled = promiseAddonEvent("onInstalled");
- yield AddonManager.installTemporaryAddon(tempExt.sourceDir);
- const [addon] = yield onInstalled;
- info(`addon installed: ${addon.id}`);
- yield onAddonListUpdated;
- const newName = "Temporary web extension (updated)";
- tempExt.writeManifest(Object.assign({}, manifestBase, {name: newName}));
- // Wait for the add-on list to be updated with the reloaded name.
- const onReInstall = promiseAddonEvent("onInstalled");
- const onAddonReloaded = waitForContentMutation(getAddonList(document));
- const reloadButton = getReloadButton(document, manifestBase.name);
- reloadButton.click();
- yield onAddonReloaded;
- const [reloadedAddon] = yield onReInstall;
- // Make sure the name was updated correctly.
- const allAddons = [...document.querySelectorAll("#addons .target-name")]
- .map(element => element.textContent);
- const nameWasUpdated = allAddons.some(name => name === newName);
- ok(nameWasUpdated, `New name appeared in reloaded add-ons: ${allAddons}`);
- yield tearDownAddon(reloadedAddon);
- tempExt.remove();
- yield closeAboutDebugging(tab);
- });
- add_task(function* onlyTempInstalledAddonsCanBeReloaded() {
- const { tab, document } = yield openAboutDebugging("addons");
- yield waitForInitialAddonList(document);
- const onAddonListUpdated = waitForMutation(getAddonList(document),
- { childList: true });
- yield installAddonWithManager(getSupportsFile("addons/bug1273184.xpi").file);
- yield onAddonListUpdated;
- const addon = yield getAddonByID("bug1273184@tests");
- const reloadButton = getReloadButton(document, addon.name);
- ok(reloadButton, "Reload button exists");
- is(reloadButton.disabled, true, "Reload button should be disabled");
- ok(reloadButton.title, "Disabled reload button should have a tooltip");
- yield tearDownAddon(addon);
- yield closeAboutDebugging(tab);
- });
|