`,
"other_extpage.html": `
`,
"extpage.css": CSS_RED_BG,
"image.png": IMAGE_RED,
};
const getBackgroundColor = () => {
return this.content.getComputedStyle(this.content.document.body)
.backgroundColor;
};
const hasCachedImage = imgUrl => {
const { document } = this.content;
const imageCache = Cc["@mozilla.org/image/tools;1"]
.getService(Ci.imgITools)
.getImgCacheForDocument(document);
const imgCacheProps = imageCache.findEntryProperties(
Services.io.newURI(imgUrl),
document
);
// return true if the image was in the cache.
return !!imgCacheProps;
};
const getImageColor = () => {
const { document } = this.content;
const img = document.querySelector("img#test-image");
const canvas = document.createElement("canvas");
canvas.width = 1;
canvas.height = 1;
const ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0); // Draw without scaling.
const [r, g, b, a] = ctx.getImageData(0, 0, 1, 1).data;
if (a < 1) {
return `rgba(${r}, ${g}, ${b}, ${a})`;
}
return `rgb(${r}, ${g}, ${b})`;
};
async function assertBackgroundColor(page, color, message) {
equal(
await page.spawn([], getBackgroundColor),
color,
`Got the expected ${message}`
);
}
async function assertImageColor(page, color, message) {
equal(await page.spawn([], getImageColor), color, message);
}
async function assertImageCached(page, imageUrl, message) {
ok(await page.spawn([imageUrl], hasCachedImage), message);
}
// This test verifies that cached css are cleared across addon upgrades and downgrades
// for permanently installed addon (See Bug 1746841).
add_task(async function test_cached_resources_cleared_across_addon_updates() {
await AddonTestUtils.promiseStartupManager();
const extension = ExtensionTestUtils.loadExtension({
useAddonManager: "permanent",
manifest,
files,
});
await extension.startup();
equal(
extension.version,
"1",
"Got the expected version for the initial extension"
);
const url = extension.extension.baseURI.resolve("extpage.html");
let page = await ExtensionTestUtils.loadContentPage(url);
await assertBackgroundColor(
page,
RGB_RED,
"background color (initial extension version)"
);
await assertImageColor(page, RGB_RED, "image (initial extension version)");
info("Verify extension page css and image after addon upgrade");
await extension.upgrade({
useAddonManager: "permanent",
manifest: {
...manifest,
version: "2",
},
files: {
...files,
"extpage.css": CSS_GREEN_BG,
"image.png": IMAGE_GREEN,
},
});
equal(
extension.version,
"2",
"Got the expected version for the upgraded extension"
);
await page.loadURL(url);
await assertBackgroundColor(
page,
RGB_GREEN,
"background color (upgraded extension version)"
);
await assertImageColor(page, RGB_GREEN, "image (upgraded extension version)");
info("Verify extension page css and image after addon downgrade");
await extension.upgrade({
useAddonManager: "permanent",
manifest,
files,
});
equal(
extension.version,
"1",
"Got the expected version for the downgraded extension"
);
await page.loadURL(url);
await assertBackgroundColor(
page,
RGB_RED,
"background color (downgraded extension version)"
);
await assertImageColor(
page,
RGB_RED,
"image color (downgraded extension version)"
);
await page.close();
await extension.unload();
await AddonTestUtils.promiseShutdownManager();
});
// This test verifies that cached css are cleared if we are installing a new
// extension and we did not clear the cache for a previous one with the same uuid
// when it was uninstalled (See Bug 1746841).
add_task(async function test_cached_resources_cleared_on_addon_install() {
// Make sure the test addon installed without an AddonManager addon wrapper
// and the ones installed right after that using the AddonManager will share
// the same uuid (and so also the same moz-extension resource urls).
Services.prefs.setBoolPref(LEAVE_UUID_PREF, true);
registerCleanupFunction(() => Services.prefs.clearUserPref(LEAVE_UUID_PREF));
await AddonTestUtils.promiseStartupManager();
const nonAOMExtension = ExtensionTestUtils.loadExtension({
manifest,
files: {
...files,
// Override css with a different color from the one expected
// later in this test case.
"extpage.css": CSS_BLUE_BG,
"image.png": IMAGE_BLUE,
},
});
await nonAOMExtension.startup();
equal(
await AddonManager.getAddonByID(ADDON_ID),
null,
"No AOM addon wrapper found as expected"
);
let url = nonAOMExtension.extension.baseURI.resolve("extpage.html");
let page = await ExtensionTestUtils.loadContentPage(url);
await assertBackgroundColor(
page,
RGB_BLUE,
"background color (addon installed without uninstall observer)"
);
await assertImageColor(
page,
RGB_BLUE,
"image (addon uninstalled without clearing cache)"
);
// NOTE: unloading a test extension that does not have an AddonManager addon wrapper
// does not trigger the uninstall observer, and this is what this test needs to make
// sure that if the cached resources were not cleared on uninstall, then we will still
// clear it when a newly installed addon is installed even if the two extensions
// are sharing the same addon uuid (and so also the same moz-extension resource urls).
await nonAOMExtension.unload();
const extension = ExtensionTestUtils.loadExtension({
useAddonManager: "permanent",
manifest,
files,
});
await extension.startup();
await page.loadURL(url);
await assertBackgroundColor(
page,
RGB_RED,
"background color (newly installed addon, same addon id)"
);
await assertImageColor(
page,
RGB_RED,
"image (newly installed addon, same addon id)"
);
await page.close();
await extension.unload();
await AddonTestUtils.promiseShutdownManager();
});
// This test verifies that reloading a temporarily installed addon after
// changing a css file cached in a previous run clears the previously
// cached css and uses the new one changed on disk (See Bug 1746841).
add_task(
async function test_cached_resources_cleared_on_temporary_addon_reload() {
await AddonTestUtils.promiseStartupManager();
const xpi = AddonTestUtils.createTempWebExtensionFile({
manifest,
files,
});
// This temporary directory is going to be removed from the
// cleanup function, but also make it unique as we do for the
// other temporary files (e.g. like getTemporaryFile as defined
// in XPInstall.jsm).
const random = Math.round(Math.random() * 36 ** 3).toString(36);
const tmpDirName = `xpcshelltest_unpacked_addons_${random}`;
let tmpExtPath = FileUtils.getDir("TmpD", [tmpDirName]);
tmpExtPath.create(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
registerCleanupFunction(() => {
tmpExtPath.remove(true);
});
// Unpacking the xpi file into the temporary directory.
const extDir = await AddonTestUtils.manuallyInstall(
xpi,
tmpExtPath,
null,
/* unpacked */ true
);
let extension = ExtensionTestUtils.expectExtension(ADDON_ID);
await AddonManager.installTemporaryAddon(extDir);
await extension.awaitStartup();
equal(
extension.version,
"1",
"Got the expected version for the initial extension"
);
const url = extension.extension.baseURI.resolve("extpage.html");
let page = await ExtensionTestUtils.loadContentPage(url);
await assertBackgroundColor(
page,
RGB_RED,
"background color (initial extension version)"
);
await assertImageColor(page, RGB_RED, "image (initial extension version)");
info("Verify updated extension page css and image after addon reload");
const targetCSSFile = extDir.clone();
targetCSSFile.append("extpage.css");
ok(
targetCSSFile.exists(),
`Found the ${targetCSSFile.path} target file on disk`
);
await IOUtils.writeUTF8(targetCSSFile.path, CSS_GREEN_BG);
const targetPNGFile = extDir.clone();
targetPNGFile.append("image.png");
ok(
targetPNGFile.exists(),
`Found the ${targetPNGFile.path} target file on disk`
);
await IOUtils.write(targetPNGFile.path, toArrayBuffer(BASE64_G_PIXEL));
const addon = await AddonManager.getAddonByID(ADDON_ID);
ok(addon, "Got an AddonWrapper for the test extension");
await addon.reload();
await page.loadURL(url);
await assertBackgroundColor(
page,
RGB_GREEN,
"background (updated files on disk)"
);
await assertImageColor(page, RGB_GREEN, "image (updated files on disk)");
await page.close();
await addon.uninstall();
await AddonTestUtils.promiseShutdownManager();
}
);
// This test verifies that cached images are not cleared between
// permanently installed addon reloads.
add_task(async function test_cached_image_kept_on_permanent_addon_restarts() {
await AddonTestUtils.promiseStartupManager();
const extension = ExtensionTestUtils.loadExtension({
useAddonManager: "permanent",
manifest,
files,
});
await extension.startup();
equal(
extension.version,
"1",
"Got the expected version for the initial extension"
);
const imageUrl = extension.extension.baseURI.resolve("image.png");
const url = extension.extension.baseURI.resolve("extpage.html");
let page = await ExtensionTestUtils.loadContentPage(url);
await assertBackgroundColor(
page,
RGB_RED,
"background color (first startup)"
);
await assertImageColor(page, RGB_RED, "image (first startup)");
await assertImageCached(page, imageUrl, "image cached (first startup)");
info("Reload the AddonManager to simulate browser restart");
extension.setRestarting();
await AddonTestUtils.promiseRestartManager();
await extension.awaitStartup();
await page.loadURL(extension.extension.baseURI.resolve("other_extpage.html"));
await assertImageCached(
page,
imageUrl,
"image still cached after AddonManager restart"
);
await page.close();
await extension.unload();
await AddonTestUtils.promiseShutdownManager();
});