Source code

Revision control

Copy as Markdown

Other Tools

/* Any copyright is dedicated to the Public Domain.
ChromeUtils.defineESModuleGetters(this, {
BackgroundPageThumbs: "resource://gre/modules/BackgroundPageThumbs.sys.mjs",
FileUtils: "resource://gre/modules/FileUtils.sys.mjs",
NewTabUtils: "resource://gre/modules/NewTabUtils.sys.mjs",
PageThumbs: "resource://gre/modules/PageThumbs.sys.mjs",
PageThumbsStorage: "resource://gre/modules/PageThumbs.sys.mjs",
SessionStore: "resource:///modules/sessionstore/SessionStore.sys.mjs",
});
XPCOMUtils.defineLazyServiceGetter(
this,
"PageThumbsStorageService",
"@mozilla.org/thumbnails/pagethumbs-service;1",
"nsIPageThumbsStorageService"
);
var oldEnabledPref = Services.prefs.getBoolPref(
"browser.pagethumbnails.capturing_disabled"
);
Services.prefs.setBoolPref("browser.pagethumbnails.capturing_disabled", false);
registerCleanupFunction(function () {
while (gBrowser.tabs.length > 1) {
gBrowser.removeTab(gBrowser.tabs[1]);
}
Services.prefs.setBoolPref(
"browser.pagethumbnails.capturing_disabled",
oldEnabledPref
);
});
/**
* Captures a screenshot for the currently selected tab, stores it in the cache,
* retrieves it from the cache and compares pixel color values.
* @param aRed The red component's intensity.
* @param aGreen The green component's intensity.
* @param aBlue The blue component's intensity.
* @param aMessage The info message to print when comparing the pixel color.
*/
async function captureAndCheckColor(aRed, aGreen, aBlue, aMessage) {
let browser = gBrowser.selectedBrowser;
// We'll get oranges if the expiration filter removes the file during the
// test.
dontExpireThumbnailURLs([browser.currentURI.spec]);
// Capture the screenshot.
await PageThumbs.captureAndStore(browser);
let [r, g, b] = await retrieveImageDataForURL(browser.currentURI.spec);
is("" + [r, g, b], "" + [aRed, aGreen, aBlue], aMessage);
}
/**
* For a given URL, loads the corresponding thumbnail
* to a canvas and passes its image data to the callback.
* Note, not compat with e10s!
* @param aURL The url associated with the thumbnail.
* @returns Promise
*/
async function retrieveImageDataForURL(aURL) {
let width = 100,
height = 100;
let thumb = PageThumbs.getThumbnailURL(aURL, width, height);
let img = document.createElementNS(htmlns, "img");
img.setAttribute("src", thumb);
await BrowserTestUtils.waitForEvent(img, "load", true);
let canvas = document.createElementNS(htmlns, "canvas");
canvas.setAttribute("width", width);
canvas.setAttribute("height", height);
// Draw the image to a canvas and compare the pixel color values.
let ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0, width, height);
return ctx.getImageData(0, 0, 100, 100).data;
}
/**
* Returns the file of the thumbnail with the given URL.
* @param aURL The URL of the thumbnail.
*/
function thumbnailFile(aURL) {
return new FileUtils.File(PageThumbsStorageService.getFilePathForURL(aURL));
}
/**
* Checks if a thumbnail for the given URL exists.
* @param aURL The url associated to the thumbnail.
*/
function thumbnailExists(aURL) {
let file = thumbnailFile(aURL);
return file.exists() && file.fileSize;
}
/**
* Removes the thumbnail for the given URL.
* @param aURL The URL associated with the thumbnail.
*/
function removeThumbnail(aURL) {
let file = thumbnailFile(aURL);
file.remove(false);
}
/**
* Calls addVisits, and then forces the newtab module to repopulate its links.
* See addVisits for parameter descriptions.
*/
async function promiseAddVisitsAndRepopulateNewTabLinks(aPlaceInfo) {
await PlacesTestUtils.addVisits(makeURI(aPlaceInfo));
await new Promise(resolve => {
NewTabUtils.links.populateCache(resolve, true);
});
}
/**
* Resolves a Promise when the thumbnail for a given URL has been found
* on disk. Keeps trying until the thumbnail has been created.
*
* @param aURL The URL of the thumbnail's page.
* @returns Promise
*/
function whenFileExists(aURL) {
return TestUtils.waitForCondition(
() => {
return thumbnailExists(aURL);
},
`Waiting for ${aURL} to exist.`,
1000,
50
);
}
/**
* Resolves a Promise when the given file has been removed.
* Keeps trying until the file is removed.
*
* @param aFile The file that is being removed
* @returns Promise
*/
function whenFileRemoved(aFile) {
return TestUtils.waitForCondition(
() => {
return !aFile.exists();
},
`Waiting for ${aFile.leafName} to not exist.`,
1000,
50
);
}
/**
* Makes sure that a given list of URLs is not implicitly expired.
*
* @param aURLs The list of URLs that should not be expired.
*/
function dontExpireThumbnailURLs(aURLs) {
let dontExpireURLs = cb => cb(aURLs);
PageThumbs.addExpirationFilter(dontExpireURLs);
registerCleanupFunction(function () {
PageThumbs.removeExpirationFilter(dontExpireURLs);
});
}
function bgCapture(aURL, aOptions) {
return bgCaptureWithMethod("capture", aURL, aOptions);
}
function bgCaptureIfMissing(aURL, aOptions) {
return bgCaptureWithMethod("captureIfMissing", aURL, aOptions);
}
/**
* Queues a BackgroundPageThumbs capture with the supplied method.
*
* @param {String} aMethodName One of the method names on BackgroundPageThumbs
* for capturing thumbnails. Example: "capture", "captureIfMissing".
* @param {String} aURL The URL of the page to capture.
* @param {Object} aOptions The options object to pass to BackgroundPageThumbs.
*
* @returns {Promise}
* @resolves {Array} Resolves once the capture has completed with an Array of
* results. The first element of the Array is the URL of the captured page,
* and the second element is the completion reason from the BackgroundPageThumbs
* module.
*/
function bgCaptureWithMethod(aMethodName, aURL, aOptions = {}) {
// We'll get oranges if the expiration filter removes the file during the
// test.
dontExpireThumbnailURLs([aURL]);
return new Promise(resolve => {
let wrappedDoneFn = aOptions.onDone;
aOptions.onDone = (url, doneReason) => {
if (wrappedDoneFn) {
wrappedDoneFn(url, doneReason);
}
resolve([url, doneReason]);
};
BackgroundPageThumbs[aMethodName](aURL, aOptions);
});
}
function bgTestPageURL(aOpts = {}) {
let TEST_PAGE_URL =
return TEST_PAGE_URL + "?" + encodeURIComponent(JSON.stringify(aOpts));
}
function bgAddPageThumbObserver(url) {
return new Promise((resolve, reject) => {
function observe(subject, topic, data) {
if (data === url) {
switch (topic) {
case "page-thumbnail:create":
resolve();
break;
case "page-thumbnail:error":
reject(new Error("page-thumbnail:error"));
break;
}
Services.obs.removeObserver(observe, "page-thumbnail:create");
Services.obs.removeObserver(observe, "page-thumbnail:error");
}
}
Services.obs.addObserver(observe, "page-thumbnail:create");
Services.obs.addObserver(observe, "page-thumbnail:error");
});
}