139 lines
4.7 KiB
JavaScript
139 lines
4.7 KiB
JavaScript
"use strict";
|
|
|
|
const fs = require("fs");
|
|
const {createInstrumenter} = require("istanbul-lib-instrument");
|
|
const {jsdom, createVirtualConsole} = require("jsdom");
|
|
|
|
var virtualConsole = createVirtualConsole();
|
|
|
|
// Optionally print console logs from the jsdom window.
|
|
if (process.env.ENABLE_JSDOM_CONSOLE == "y") {
|
|
virtualConsole.sendTo(console);
|
|
}
|
|
|
|
// Path to the browser-polyfill script, relative to the current work dir
|
|
// where mocha is executed.
|
|
let BROWSER_POLYFILL_PATH = "./dist/browser-polyfill.js";
|
|
|
|
if (process.env.TEST_MINIFIED_POLYFILL) {
|
|
BROWSER_POLYFILL_PATH = "./dist/browser-polyfill.min.js";
|
|
} else if (process.env.TEST_BUNDLED_POLYFILL) {
|
|
BROWSER_POLYFILL_PATH = process.env.TEST_BUNDLED_POLYFILL;
|
|
}
|
|
|
|
function getInputSourceMap() {
|
|
// Enabled only on CI until we have fixed the mapping to the source file
|
|
// (by making sure that babel generates a sourcemap that does also take into
|
|
// account the api metadata being interpolated into the src script).
|
|
//
|
|
// TODO(https://github.com/mozilla/webextension-polyfill/issues/348):
|
|
// disabling the sourcemapped code coverage will not be necessary anymore
|
|
// once we fix the generated sourcemap to correctly map to src/browser-polyfill.js
|
|
if (process.env.COVERAGE_WITH_SOURCEMAP != "1") {
|
|
return undefined;
|
|
}
|
|
if (process.env.TEST_BUNDLED_POLYFILL) {
|
|
// Running the unit tests on the bundled files are meant to be used as smoke tests,
|
|
// we don't need to collect code coverage for it.
|
|
throw new Error("Unexpected code coverage enabled while testing bundled modules");
|
|
}
|
|
let sourceMapPath = process.env.TEST_MINIFIED_POLYFILL
|
|
? "./dist/browser-polyfill.js.min.map"
|
|
: "./dist/browser-polyfill.js.map";
|
|
let sourceMap = JSON.parse(fs.readFileSync(sourceMapPath, {encoding: "utf-8"}));
|
|
sourceMap.sources = ["../src/browser-polyfill.js"];
|
|
return sourceMap;
|
|
}
|
|
|
|
// Create the jsdom window used to run the tests
|
|
const testDOMWindow = jsdom("", {virtualConsole}).defaultView;
|
|
|
|
// Copy the code coverage of the browser-polyfill script from the jsdom window
|
|
// to the nodejs global, where nyc expects to find the code coverage data to
|
|
// render in the reports.
|
|
after(() => {
|
|
if (testDOMWindow && process.env.COVERAGE == "y") {
|
|
global.__coverage__ = testDOMWindow.__coverage__;
|
|
}
|
|
});
|
|
|
|
function setupTestDOMWindow(chromeObject, browserObject = undefined) {
|
|
return new Promise((resolve, reject) => {
|
|
const window = testDOMWindow;
|
|
|
|
// Ensure that "chrome.runtime.id" is set, because the polyfill is only
|
|
// loaded in extension environments.
|
|
if (chromeObject) {
|
|
if (!chromeObject.runtime) {
|
|
chromeObject.runtime = {};
|
|
}
|
|
if (!chromeObject.runtime.id) {
|
|
chromeObject.runtime.id = "some-test-id-from-test-setup";
|
|
}
|
|
}
|
|
|
|
// Inject the fake chrome object used as a fixture for the particular
|
|
// browser-polyfill test scenario.
|
|
window.chrome = chromeObject;
|
|
|
|
// Set (or reset) the browser property.
|
|
if (browserObject) {
|
|
// Make the fake browser object a `window.Object` instance, so that
|
|
// it passes the `Object.getPrototypeOf(browser) !== Object.prototype`
|
|
// check, otherwise it is going to be overridden by the polyfill (See #153).
|
|
window.browser = Object.assign(window.Object(), browserObject);
|
|
} else {
|
|
delete window.browser;
|
|
}
|
|
|
|
const scriptEl = window.document.createElement("script");
|
|
|
|
if (process.env.COVERAGE == "y") {
|
|
// If the code coverage is enabled, instrument the code on the fly
|
|
// before executing it in the jsdom window.
|
|
const inst = createInstrumenter({
|
|
compact: false, esModules: false, produceSourceMap: false,
|
|
});
|
|
const scriptContent = fs.readFileSync(BROWSER_POLYFILL_PATH, "utf-8");
|
|
scriptEl.textContent = inst.instrumentSync(
|
|
scriptContent,
|
|
BROWSER_POLYFILL_PATH,
|
|
getInputSourceMap()
|
|
);
|
|
} else {
|
|
scriptEl.src = BROWSER_POLYFILL_PATH;
|
|
}
|
|
|
|
let onLoad;
|
|
let onLoadError;
|
|
let onError;
|
|
|
|
let cleanLoadListeners = () => {
|
|
scriptEl.removeEventListener("load", onLoad);
|
|
scriptEl.removeEventListener("error", onLoadError);
|
|
|
|
window.removeEventListener("error", onError);
|
|
};
|
|
|
|
onLoad = () => { cleanLoadListeners(); resolve(window); };
|
|
onLoadError = () => {
|
|
cleanLoadListeners();
|
|
reject(new Error(`Error loading script: ${BROWSER_POLYFILL_PATH}`));
|
|
};
|
|
onError = (err) => { cleanLoadListeners(); reject(err); };
|
|
|
|
// Listen to any uncaught errors.
|
|
window.addEventListener("error", onError);
|
|
scriptEl.addEventListener("error", onLoadError);
|
|
|
|
scriptEl.addEventListener("load", onLoad);
|
|
|
|
window.document.body.appendChild(scriptEl);
|
|
});
|
|
}
|
|
|
|
module.exports = {
|
|
BROWSER_POLYFILL_PATH,
|
|
setupTestDOMWindow,
|
|
};
|