mirror of
https://github.com/Smaug123/KaTeX
synced 2025-10-05 11:18:39 +00:00
chore(deps): update selenium-webdriver to 4 (#3205)
* chore(deps): update selenium-webdriver to 4 refactor: use async/await * fix(screenshotter): disable static watch
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
"use strict";
|
||||
|
||||
const childProcess = require("child_process");
|
||||
const util = require("util");
|
||||
const fs = require("fs-extra");
|
||||
const jspngopt = require("jspngopt");
|
||||
const net = require("net");
|
||||
@@ -9,6 +10,9 @@ const os = require("os");
|
||||
const pako = require("pako");
|
||||
const path = require("path");
|
||||
const got = require("got");
|
||||
const pRetry = require('p-retry');
|
||||
|
||||
const execFile = util.promisify(childProcess.execFile);
|
||||
|
||||
const selenium = require("selenium-webdriver");
|
||||
const firefox = require("selenium-webdriver/firefox");
|
||||
@@ -112,15 +116,6 @@ if (opts.browserstack) {
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Work out connection to selenium docker container
|
||||
|
||||
function check(err) {
|
||||
if (!err) {
|
||||
return;
|
||||
}
|
||||
console.error(err);
|
||||
console.error(err.stack);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
function cmd() {
|
||||
const args = Array.prototype.slice.call(arguments);
|
||||
const cmd = args.shift();
|
||||
@@ -184,8 +179,36 @@ if (seleniumURL) {
|
||||
console.log("Selenium driver in local session");
|
||||
}
|
||||
|
||||
process.nextTick(startServer);
|
||||
let attempts = 0;
|
||||
(async() => {
|
||||
if (!(katexURL || katexPort)) {
|
||||
await pRetry(startServer, {retries: 50, minTimeout: 100});
|
||||
}
|
||||
if (opts.seleniumProxy) {
|
||||
driver = await getProxyDriver();
|
||||
} else {
|
||||
if (opts.browserstack) {
|
||||
await startBrowserstackLocal();
|
||||
}
|
||||
if (seleniumIP) {
|
||||
await pRetry(tryConnect, {retries: 50, minTimeout: 100});
|
||||
}
|
||||
driver = buildDriver();
|
||||
}
|
||||
await setupDriver();
|
||||
await findHostIP();
|
||||
await takeScreenshots();
|
||||
|
||||
await driver.quit();
|
||||
await devServer.stop();
|
||||
if (bsLocal) {
|
||||
const bsLocalStop = util.promisify(bsLocal.stop);
|
||||
await bsLocalStop();
|
||||
}
|
||||
process.exit(exitStatus);
|
||||
})().catch(err => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Start up development server
|
||||
@@ -195,13 +218,8 @@ let coverageMap;
|
||||
const minPort = 32768;
|
||||
const maxPort = 61000;
|
||||
|
||||
function startServer() {
|
||||
if (katexURL || katexPort) {
|
||||
process.nextTick(tryConnect);
|
||||
return;
|
||||
}
|
||||
const port = Math.floor(Math.random() * (maxPort - minPort)) + minPort;
|
||||
|
||||
async function startServer() {
|
||||
katexPort = Math.floor(Math.random() * (maxPort - minPort)) + minPort;
|
||||
if (opts.coverage) {
|
||||
coverageMap = istanbulLibCoverage.createCoverageMap({});
|
||||
webpackConfig.module.rules[0].use = {
|
||||
@@ -216,67 +234,50 @@ function startServer() {
|
||||
}
|
||||
const config = {
|
||||
...webpackConfig.devServer,
|
||||
port,
|
||||
static: [{directory: process.cwd(), watch: false}],
|
||||
port: katexPort,
|
||||
hot: false,
|
||||
liveReload: false,
|
||||
client: false,
|
||||
};
|
||||
const compiler = webpack(webpackConfig);
|
||||
const wds = new WebpackDevServer(config, compiler);
|
||||
wds.start(port).then(() => {
|
||||
devServer = wds;
|
||||
katexPort = port;
|
||||
attempts = 0;
|
||||
process.nextTick(opts.seleniumProxy ? getProxyDriver
|
||||
: opts.browserstack ? startBrowserstackLocal : tryConnect);
|
||||
})
|
||||
.catch((err) => {
|
||||
if (devServer !== null) { // error after we started listening
|
||||
throw err;
|
||||
} else if (++attempts > 50) {
|
||||
throw new Error("Failed to start up dev server");
|
||||
} else {
|
||||
process.nextTick(startServer);
|
||||
}
|
||||
});
|
||||
devServer = new WebpackDevServer(config, compiler);
|
||||
await devServer.start(katexPort);
|
||||
}
|
||||
|
||||
// Start Browserstack Local connection
|
||||
function startBrowserstackLocal() {
|
||||
async function startBrowserstackLocal() {
|
||||
// unique identifier for the session
|
||||
const localIdentifier = process.env.CIRCLE_BUILD_NUM || "p" + katexPort;
|
||||
opts.seleniumCapabilities["browserstack.localIdentifier"] = localIdentifier;
|
||||
|
||||
bsLocal = new browserstack.Local();
|
||||
bsLocal.start({localIdentifier}, function(err) {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
process.nextTick(tryConnect);
|
||||
await new Promise((resolve, reject) => {
|
||||
bsLocal.start({localIdentifier}, err => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Wait for container to become ready
|
||||
|
||||
function tryConnect() {
|
||||
if (!seleniumIP) {
|
||||
process.nextTick(buildDriver);
|
||||
return;
|
||||
}
|
||||
const sock = net.connect({
|
||||
host: seleniumIP,
|
||||
port: +seleniumPort,
|
||||
});
|
||||
sock.on("connect", function() {
|
||||
sock.end();
|
||||
attempts = 0;
|
||||
process.nextTick(buildDriver);
|
||||
}).on("error", function() {
|
||||
if (++attempts > 50) {
|
||||
throw new Error("Failed to connect selenium server.");
|
||||
}
|
||||
setTimeout(tryConnect, 200);
|
||||
async function tryConnect() {
|
||||
return new Promise((resolve, reject) => {
|
||||
const sock = net.connect({
|
||||
host: seleniumIP,
|
||||
port: +seleniumPort,
|
||||
});
|
||||
sock.on("connect", function() {
|
||||
sock.end();
|
||||
resolve();
|
||||
}).on("error", function(err) {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -288,11 +289,10 @@ let driverReady = false;
|
||||
function buildDriver() {
|
||||
const builder = new selenium.Builder().forBrowser(opts.browser);
|
||||
if (opts.browser === "firefox") {
|
||||
const ffProfile = new firefox.Profile();
|
||||
ffProfile.setPreference(
|
||||
const ffOptions = new firefox.Options();
|
||||
ffOptions.setPreference(
|
||||
"browser.startup.homepage_override.mstone", "ignore");
|
||||
ffProfile.setPreference("browser.startup.page", 0);
|
||||
const ffOptions = new firefox.Options().setProfile(ffProfile);
|
||||
ffOptions.setPreference("browser.startup.page", 0);
|
||||
builder.setFirefoxOptions(ffOptions);
|
||||
} else if (opts.browser === "chrome") {
|
||||
// https://stackoverflow.com/questions/48450594/selenium-timed-out-receiving-message-from-renderer
|
||||
@@ -305,39 +305,35 @@ function buildDriver() {
|
||||
if (opts.seleniumCapabilities) {
|
||||
builder.withCapabilities(opts.seleniumCapabilities);
|
||||
}
|
||||
driver = builder.build();
|
||||
setupDriver();
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
function getProxyDriver() {
|
||||
got.post(opts.seleniumProxy, {
|
||||
async function getProxyDriver() {
|
||||
const {body} = await got.post(opts.seleniumProxy, {
|
||||
json: {
|
||||
browserstack: opts.browserstack,
|
||||
capabilities: opts.seleniumCapabilities,
|
||||
seleniumURL,
|
||||
},
|
||||
responseType: 'json',
|
||||
}).then(({body}) => {
|
||||
const session = new selenium.Session(body.id, body.capabilities);
|
||||
const client = Promise.resolve(seleniumURL)
|
||||
.then(url => new seleniumHttp.HttpClient(url));
|
||||
const executor = new seleniumHttp.Executor(client);
|
||||
driver = new selenium.WebDriver(session, executor);
|
||||
setupDriver();
|
||||
});
|
||||
const session = new selenium.Session(body.id, body.capabilities);
|
||||
const client = Promise.resolve(new seleniumHttp.HttpClient(seleniumURL));
|
||||
const executor = new seleniumHttp.Executor(client);
|
||||
return new selenium.WebDriver(session, executor);
|
||||
}
|
||||
|
||||
function setupDriver() {
|
||||
driver.manage().timeouts().setScriptTimeout(3000).then(function() {
|
||||
let html = '<!DOCTYPE html>' +
|
||||
'<html><head><style type="text/css">html,body{' +
|
||||
'width:100%;height:100%;margin:0;padding:0;overflow:hidden;' +
|
||||
'}</style></head><body><p>Test</p></body></html>';
|
||||
html = "data:text/html," + encodeURIComponent(html);
|
||||
return driver.get(html);
|
||||
}).then(function() {
|
||||
setSize(targetW, targetH);
|
||||
});
|
||||
async function setupDriver() {
|
||||
await driver.manage().setTimeouts({script: 5000});
|
||||
|
||||
let html = '<!DOCTYPE html>' +
|
||||
'<html><head><style type="text/css">html,body{' +
|
||||
'width:100%;height:100%;margin:0;padding:0;overflow:hidden;' +
|
||||
'}</style></head><body><p>Test</p></body></html>';
|
||||
html = "data:text/html," + encodeURIComponent(html);
|
||||
await driver.get(html);
|
||||
|
||||
await setSize(targetW, targetH);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
@@ -345,22 +341,20 @@ function setupDriver() {
|
||||
|
||||
const targetW = 1024;
|
||||
const targetH = 768;
|
||||
function setSize(reqW, reqH) {
|
||||
return driver.manage().window().setSize(reqW, reqH).then(function() {
|
||||
return driver.takeScreenshot();
|
||||
}).then(function(img) {
|
||||
img = imageDimensions(img);
|
||||
const actualW = img.width;
|
||||
const actualH = img.height;
|
||||
if (actualW === targetW && actualH === targetH) {
|
||||
findHostIP();
|
||||
return;
|
||||
}
|
||||
if (++attempts > opts.attempts) {
|
||||
throw new Error("Failed to set window size correctly.");
|
||||
}
|
||||
return setSize(targetW + reqW - actualW, targetH + reqH - actualH);
|
||||
}, check);
|
||||
let attempts = 0;
|
||||
async function setSize(width, height) {
|
||||
await driver.manage().window().setRect({width, height});
|
||||
let img = await driver.takeScreenshot();
|
||||
img = imageDimensions(img);
|
||||
const actualW = img.width;
|
||||
const actualH = img.height;
|
||||
if (actualW === targetW && actualH === targetH) {
|
||||
return;
|
||||
}
|
||||
if (++attempts > opts.attempts) {
|
||||
throw new Error("Failed to set window size correctly.");
|
||||
}
|
||||
return setSize(targetW + width - actualW, targetH + height - actualH);
|
||||
}
|
||||
|
||||
function imageDimensions(img) {
|
||||
@@ -375,7 +369,7 @@ function imageDimensions(img) {
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Work out how to connect to host KaTeX server
|
||||
|
||||
function findHostIP() {
|
||||
async function findHostIP() {
|
||||
if (!katexIP) {
|
||||
katexIP = "localhost";
|
||||
}
|
||||
@@ -384,21 +378,22 @@ function findHostIP() {
|
||||
katexURL = "http://" + katexIP + ":" + katexPort + "/";
|
||||
console.log("KaTeX URL is " + katexURL);
|
||||
}
|
||||
process.nextTick(takeScreenshots);
|
||||
return;
|
||||
}
|
||||
|
||||
// Now we need to find an IP the container can connect to.
|
||||
// First, install a server component to get notified of successful connects
|
||||
devServer.app.get("/ss-connect.js", function(req, res, next) {
|
||||
if (!katexURL) {
|
||||
katexIP = req.query.ip;
|
||||
katexURL = "http://" + katexIP + ":" + katexPort + "/";
|
||||
console.log("KaTeX URL is " + katexURL);
|
||||
process.nextTick(takeScreenshots);
|
||||
}
|
||||
res.setHeader("Content-Type", "text/javascript");
|
||||
res.send("//OK");
|
||||
const connect = new Promise((resolve) => {
|
||||
devServer.app.get("/ss-connect.js", function(req, res, next) {
|
||||
if (!katexURL) {
|
||||
katexIP = req.query.ip;
|
||||
katexURL = "http://" + katexIP + ":" + katexPort + "/";
|
||||
console.log("KaTeX URL is " + katexURL);
|
||||
}
|
||||
res.setHeader("Content-Type", "text/javascript");
|
||||
res.send("//OK");
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
// Next, enumerate all network addresses
|
||||
@@ -427,22 +422,41 @@ function findHostIP() {
|
||||
}).join("\n");
|
||||
html += "\n</body></html>";
|
||||
html = "data:text/html," + encodeURIComponent(html);
|
||||
driver.get(html);
|
||||
await driver.get(html);
|
||||
await connect;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Take the screenshots
|
||||
|
||||
let countdown = listOfCases.length;
|
||||
|
||||
let exitStatus = 0;
|
||||
const listOfFailed = [];
|
||||
|
||||
function takeScreenshots() {
|
||||
listOfCases.forEach(takeScreenshot);
|
||||
async function takeScreenshots() {
|
||||
for (const key of listOfCases) {
|
||||
await takeScreenshot(key);
|
||||
}
|
||||
|
||||
if (listOfFailed.length) {
|
||||
console.error("Failed: " + listOfFailed.join(" "));
|
||||
}
|
||||
if (opts.diff) {
|
||||
console.log("Diffs have been generated in: " + diffDir);
|
||||
}
|
||||
if (opts.new) {
|
||||
console.log("New screenshots have been generated in: " + newDir);
|
||||
}
|
||||
if (opts.coverage) {
|
||||
await collectCoverage();
|
||||
const context = istanbulLibReport.createContext({coverageMap});
|
||||
['json', 'text', 'lcov'].forEach(fmt => {
|
||||
const report = istanbulReports.create(fmt);
|
||||
report.execute(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function takeScreenshot(key) {
|
||||
async function takeScreenshot(key) {
|
||||
const itm = data[key];
|
||||
if (!itm) {
|
||||
console.error("Test case " + key + " not known!");
|
||||
@@ -450,70 +464,43 @@ function takeScreenshot(key) {
|
||||
if (exitStatus === 0) {
|
||||
exitStatus = 1;
|
||||
}
|
||||
oneDone();
|
||||
return;
|
||||
}
|
||||
|
||||
let file = path.join(dstDir, key + "-" + opts.browser + ".png");
|
||||
let retry = 0;
|
||||
let loadExpected = null;
|
||||
if (opts.verify) {
|
||||
loadExpected = fs.readFile(file);
|
||||
let expected = null;
|
||||
if (opts.verify && await fs.pathExists(file)) {
|
||||
expected = await fs.readFile(file);
|
||||
}
|
||||
|
||||
const url = katexURL + "test/screenshotter/test.html?" + itm.query;
|
||||
driver.call(loadMath);
|
||||
let buf;
|
||||
|
||||
function loadMath() {
|
||||
while (++retry <= opts.attempts) {
|
||||
if (!opts.reload && driverReady) {
|
||||
driver.executeScript(
|
||||
await driver.executeScript(
|
||||
"handle_search_string(" +
|
||||
JSON.stringify("?" + itm.query) + ");")
|
||||
.then(waitThenScreenshot);
|
||||
} else if (opts.coverage) {
|
||||
// collect coverage before reloading
|
||||
collectCoverage().then(function() {
|
||||
return driver.get(url).then(loadFonts);
|
||||
});
|
||||
JSON.stringify("?" + itm.query) + ");");
|
||||
} else {
|
||||
driver.get(url).then(loadFonts);
|
||||
if (opts.coverage) {
|
||||
// collect coverage before reloading
|
||||
await collectCoverage();
|
||||
}
|
||||
await driver.get(url);
|
||||
await driver.executeAsyncScript(
|
||||
"var callback = arguments[arguments.length - 1]; " +
|
||||
"load_fonts_and_images(callback);");
|
||||
driverReady = true;
|
||||
}
|
||||
}
|
||||
|
||||
function collectCoverage() {
|
||||
return driver.executeScript('return window.__coverage__;')
|
||||
.then(function(result) {
|
||||
if (result) {
|
||||
coverageMap.merge(result);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function loadFonts() {
|
||||
driver.executeAsyncScript(
|
||||
"var callback = arguments[arguments.length - 1]; " +
|
||||
"load_fonts_and_images(callback);")
|
||||
.then(waitThenScreenshot);
|
||||
}
|
||||
|
||||
function waitThenScreenshot() {
|
||||
driverReady = true;
|
||||
if (opts.wait) {
|
||||
browserSideWait(1000 * opts.wait);
|
||||
await browserSideWait(1000 * opts.wait);
|
||||
}
|
||||
const promise = driver.takeScreenshot().then(haveScreenshot);
|
||||
if (retry === 0) {
|
||||
// The `oneDone` promise remains outstanding if we retry, so
|
||||
// don't re-add it
|
||||
promise.then(oneDone, check);
|
||||
}
|
||||
}
|
||||
|
||||
function haveScreenshot(img) {
|
||||
let img = await driver.takeScreenshot();
|
||||
img = imageDimensions(img);
|
||||
if (img.width !== targetW || img.height !== targetH) {
|
||||
throw new Error("Expected " + targetW + " x " + targetH +
|
||||
", got " + img.width + "x" + img.height);
|
||||
console.error("Expected " + targetW + " x " + targetH +
|
||||
", got " + img.width + "x" + img.height);
|
||||
await setSize(targetW, targetH);
|
||||
}
|
||||
if (key === "Lap" && opts.browser === "firefox" &&
|
||||
img.buf[0x32] === 0xf8) {
|
||||
@@ -525,141 +512,77 @@ function takeScreenshot(key) {
|
||||
*/
|
||||
key += "_alt";
|
||||
file = path.join(dstDir, key + "-" + opts.browser + ".png");
|
||||
if (loadExpected) {
|
||||
loadExpected = fs.readFile(file);
|
||||
if (expected) {
|
||||
expected = await fs.readFile(file);
|
||||
}
|
||||
}
|
||||
const opt = new jspngopt.Optimizer({
|
||||
pako: pako,
|
||||
});
|
||||
const buf = opt.bufferSync(img.buf);
|
||||
if (loadExpected) {
|
||||
return loadExpected.then(function(expected) {
|
||||
if (!buf.equals(expected)) {
|
||||
if (++retry >= opts.attempts) {
|
||||
console.error("FAIL! " + key);
|
||||
listOfFailed.push(key);
|
||||
exitStatus = 3;
|
||||
if (opts.diff || opts.new) {
|
||||
return saveFailedScreenshot(key, buf);
|
||||
}
|
||||
} else {
|
||||
console.log("error " + key);
|
||||
browserSideWait(300 * retry);
|
||||
if (retry > 1) {
|
||||
driverReady = false; // reload fully
|
||||
}
|
||||
return driver.call(loadMath);
|
||||
}
|
||||
} else {
|
||||
console.log("* ok " + key);
|
||||
}
|
||||
});
|
||||
buf = opt.bufferSync(img.buf);
|
||||
if (expected) {
|
||||
if (buf.equals(expected)) {
|
||||
console.log("* ok " + key);
|
||||
return;
|
||||
}
|
||||
console.log("error " + key);
|
||||
await browserSideWait(300 * retry);
|
||||
if (retry > 1) {
|
||||
driverReady = false; // reload fully
|
||||
}
|
||||
} else {
|
||||
return fs.writeFile(file, buf).then(function() {
|
||||
console.log(key);
|
||||
});
|
||||
await fs.writeFile(file, buf);
|
||||
console.log(key);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
function saveFailedScreenshot(key, buf) {
|
||||
console.error("FAIL! " + key);
|
||||
listOfFailed.push(key);
|
||||
exitStatus = 3;
|
||||
if (opts.diff || opts.new) {
|
||||
const filenamePrefix = key + "-" + opts.browser;
|
||||
const outputDir = opts.new ? newDir : diffDir;
|
||||
const baseFile = path.join(dstDir, filenamePrefix + ".png");
|
||||
const diffFile = path.join(diffDir, filenamePrefix + "-diff.png");
|
||||
const bufFile = path.join(outputDir, filenamePrefix + ".png");
|
||||
|
||||
let promise = fs.ensureDir(outputDir)
|
||||
.then(function() {
|
||||
return fs.writeFile(bufFile, buf);
|
||||
});
|
||||
await fs.ensureDir(outputDir);
|
||||
await fs.writeFile(bufFile, buf);
|
||||
|
||||
if (opts.diff) {
|
||||
promise = promise.then(fs.ensureDir(diffDir))
|
||||
.then(function() {
|
||||
return execFile("convert", [
|
||||
"-fill", "white",
|
||||
// First image: saved screenshot in red
|
||||
"(", baseFile, "-colorize", "100,0,0", ")",
|
||||
// Second image: new screenshot in green
|
||||
"(", bufFile, "-colorize", "0,80,0", ")",
|
||||
// Composite them
|
||||
"-compose", "darken", "-composite",
|
||||
"-trim", // remove everything with the same color as
|
||||
// the corners
|
||||
diffFile, // output file name
|
||||
]);
|
||||
});
|
||||
await fs.ensureDir(diffDir);
|
||||
await execFile("convert", [
|
||||
"-fill", "white",
|
||||
// First image: saved screenshot in red
|
||||
"(", baseFile, "-colorize", "100,0,0", ")",
|
||||
// Second image: new screenshot in green
|
||||
"(", bufFile, "-colorize", "0,80,0", ")",
|
||||
// Composite them
|
||||
"-compose", "darken", "-composite",
|
||||
"-trim", // remove everything with the same color as
|
||||
// the corners
|
||||
diffFile, // output file name
|
||||
]);
|
||||
}
|
||||
if (!opts.new) {
|
||||
promise = promise.then(function() {
|
||||
return fs.unlink(bufFile);
|
||||
});
|
||||
await fs.unlink(bufFile);
|
||||
}
|
||||
return promise;
|
||||
}
|
||||
|
||||
function oneDone() {
|
||||
if (--countdown === 0) {
|
||||
if (listOfFailed.length) {
|
||||
console.error("Failed: " + listOfFailed.join(" "));
|
||||
}
|
||||
if (opts.diff) {
|
||||
console.log("Diffs have been generated in: " + diffDir);
|
||||
}
|
||||
if (opts.new) {
|
||||
console.log("New screenshots have been generated in: " + newDir);
|
||||
}
|
||||
if (opts.coverage) {
|
||||
collectCoverage().then(function() {
|
||||
const context = istanbulLibReport.createContext({coverageMap});
|
||||
['json', 'text', 'lcov'].forEach(fmt => {
|
||||
const report = istanbulReports.create(fmt);
|
||||
report.execute(context);
|
||||
});
|
||||
done();
|
||||
});
|
||||
return;
|
||||
}
|
||||
done();
|
||||
}
|
||||
}
|
||||
|
||||
function done() {
|
||||
// devServer.close(cb) will take too long.
|
||||
driver.quit().then(() => {
|
||||
if (bsLocal) {
|
||||
bsLocal.stop(() => {
|
||||
process.exit(exitStatus);
|
||||
});
|
||||
} else {
|
||||
process.exit(exitStatus);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Wait using a timeout call in the browser, to ensure that the wait
|
||||
// time doesn't start before the page has reportedly been loaded.
|
||||
function browserSideWait(milliseconds) {
|
||||
async function browserSideWait(milliseconds) {
|
||||
// The last argument (arguments[1] here) is the callback to selenium
|
||||
return driver.executeAsyncScript(
|
||||
await driver.executeAsyncScript(
|
||||
"window.setTimeout(arguments[1], arguments[0]);",
|
||||
milliseconds);
|
||||
}
|
||||
|
||||
// Execute a given command, and return a promise to its output.
|
||||
function execFile(cmd, args, opts) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
childProcess.execFile(cmd, args, opts, function(err, stdout, stderr) {
|
||||
if (err) {
|
||||
console.error("Error executing " + cmd + " " + args.join(" "));
|
||||
console.error(stdout + stderr);
|
||||
err.stdout = stdout;
|
||||
err.stderr = stderr;
|
||||
reject(err);
|
||||
} else {
|
||||
resolve(stdout);
|
||||
}
|
||||
});
|
||||
});
|
||||
async function collectCoverage() {
|
||||
const result = await driver.executeScript('return window.__coverage__;');
|
||||
if (result) {
|
||||
coverageMap.merge(result);
|
||||
}
|
||||
}
|
||||
|
@@ -65,6 +65,7 @@
|
||||
"less-loader": "^10.0.0",
|
||||
"mini-css-extract-plugin": "^2.0.0",
|
||||
"mkdirp": "^1.0.4",
|
||||
"p-retry": "^4.6.1",
|
||||
"pako": "^2.0.0",
|
||||
"postcss": "^8.0.0",
|
||||
"postcss-loader": "^6.0.0",
|
||||
@@ -73,7 +74,7 @@
|
||||
"query-string": "^7.0.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"rollup": "^2.21.0",
|
||||
"selenium-webdriver": "^3.6.0",
|
||||
"selenium-webdriver": "^4.0.0-beta.4",
|
||||
"semantic-release": "^17.4.1",
|
||||
"sri-toolbox": "^0.2.0",
|
||||
"style-loader": "^3.0.0",
|
||||
|
90
yarn.lock
90
yarn.lock
@@ -8391,15 +8391,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"jszip@npm:^3.1.3":
|
||||
version: 3.5.0
|
||||
resolution: "jszip@npm:3.5.0"
|
||||
"jszip@npm:^3.6.0":
|
||||
version: 3.7.1
|
||||
resolution: "jszip@npm:3.7.1"
|
||||
dependencies:
|
||||
lie: ~3.3.0
|
||||
pako: ~1.0.2
|
||||
readable-stream: ~2.3.6
|
||||
set-immediate-shim: ~1.0.1
|
||||
checksum: e4c555273063ac1284f387e440c9b0ccef99af3dd87f3af4a7fc1b4396f33cc45fa10afdb059105dd15a61763288c99e53a5e078dd0af9183a83e694e005d054
|
||||
checksum: 67d737a82b294cc102e7451e32d5acbbab29860399be460cae598084327e6f2ea0c9bca2d3dad701da6a75ddf77f34c6a1dd7db0c3d5c0fec5998b7e56d6d59d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -8455,6 +8455,7 @@ __metadata:
|
||||
less-loader: ^10.0.0
|
||||
mini-css-extract-plugin: ^2.0.0
|
||||
mkdirp: ^1.0.4
|
||||
p-retry: ^4.6.1
|
||||
pako: ^2.0.0
|
||||
postcss: ^8.0.0
|
||||
postcss-loader: ^6.0.0
|
||||
@@ -8463,7 +8464,7 @@ __metadata:
|
||||
query-string: ^7.0.0
|
||||
rimraf: ^3.0.2
|
||||
rollup: ^2.21.0
|
||||
selenium-webdriver: ^3.6.0
|
||||
selenium-webdriver: ^4.0.0-beta.4
|
||||
semantic-release: ^17.4.1
|
||||
sri-toolbox: ^0.2.0
|
||||
style-loader: ^3.0.0
|
||||
@@ -10483,7 +10484,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"os-tmpdir@npm:^1.0.0, os-tmpdir@npm:~1.0.1":
|
||||
"os-tmpdir@npm:^1.0.0":
|
||||
version: 1.0.2
|
||||
resolution: "os-tmpdir@npm:1.0.2"
|
||||
checksum: 5666560f7b9f10182548bf7013883265be33620b1c1b4a4d405c25be2636f970c5488ff3e6c48de75b55d02bde037249fe5dbfbb4c0fb7714953d56aed062e6d
|
||||
@@ -10639,7 +10640,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"p-retry@npm:^4.0.0, p-retry@npm:^4.5.0":
|
||||
"p-retry@npm:^4.0.0, p-retry@npm:^4.5.0, p-retry@npm:^4.6.1":
|
||||
version: 4.6.1
|
||||
resolution: "p-retry@npm:4.6.1"
|
||||
dependencies:
|
||||
@@ -12785,7 +12786,7 @@ resolve@^2.0.0-next.3:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"sax@npm:>=0.6.0, sax@npm:^1.2.4":
|
||||
"sax@npm:^1.2.4":
|
||||
version: 1.2.4
|
||||
resolution: "sax@npm:1.2.4"
|
||||
checksum: d3df7d32b897a2c2f28e941f732c71ba90e27c24f62ee918bd4d9a8cfb3553f2f81e5493c7f0be94a11c1911b643a9108f231dd6f60df3fa9586b5d2e3e9e1fe
|
||||
@@ -12830,15 +12831,15 @@ resolve@^2.0.0-next.3:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"selenium-webdriver@npm:^3.6.0":
|
||||
version: 3.6.0
|
||||
resolution: "selenium-webdriver@npm:3.6.0"
|
||||
"selenium-webdriver@npm:^4.0.0-beta.4":
|
||||
version: 4.0.0-beta.4
|
||||
resolution: "selenium-webdriver@npm:4.0.0-beta.4"
|
||||
dependencies:
|
||||
jszip: ^3.1.3
|
||||
rimraf: ^2.5.4
|
||||
tmp: 0.0.30
|
||||
xml2js: ^0.4.17
|
||||
checksum: 5bc1045d0205c5aed1f3e3cf8047d3bb677e370e96ae4a8acd172846c07aeb40c031bee5017a7c432bec36e46c5bbce82fe3b40086b7daa4cb31dcaf69daad55
|
||||
jszip: ^3.6.0
|
||||
rimraf: ^3.0.2
|
||||
tmp: ^0.2.1
|
||||
ws: ">=7.4.6"
|
||||
checksum: c57ec5b41f8ff4a81280d548f95e899a01f6cf6b0b46fb4f7a92440a710836a2994368561c0be43abd301f76c293e29dca68d959a9ae6c15fb03f5a040dee240
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -14128,12 +14129,12 @@ resolve@^2.0.0-next.3:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"tmp@npm:0.0.30":
|
||||
version: 0.0.30
|
||||
resolution: "tmp@npm:0.0.30"
|
||||
"tmp@npm:^0.2.1":
|
||||
version: 0.2.1
|
||||
resolution: "tmp@npm:0.2.1"
|
||||
dependencies:
|
||||
os-tmpdir: ~1.0.1
|
||||
checksum: d3e97e8e73b2d2dfff9916072004088b4737c67d11ea255d0ccc8584f252b253b60ecf04122b21848ec46ad5a92e31febc6d6a3068f6c8a20c9b0e23a802e78d
|
||||
rimraf: ^3.0.0
|
||||
checksum: 8b1214654182575124498c87ca986ac53dc76ff36e8f0e0b67139a8d221eaecfdec108c0e6ec54d76f49f1f72ab9325500b246f562b926f85bcdfca8bf35df9e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -15158,6 +15159,21 @@ resolve@^2.0.0-next.3:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ws@npm:>=7.4.6, ws@npm:^8.1.0":
|
||||
version: 8.2.0
|
||||
resolution: "ws@npm:8.2.0"
|
||||
peerDependencies:
|
||||
bufferutil: ^4.0.1
|
||||
utf-8-validate: ^5.0.2
|
||||
peerDependenciesMeta:
|
||||
bufferutil:
|
||||
optional: true
|
||||
utf-8-validate:
|
||||
optional: true
|
||||
checksum: 7cd544312a48dafcb8158c9b4e5f20986cce980d516e0ef0602665911b0e95c5e0dea2846a4bb3153a1e2c839aa3d92fb7e69dd864fe432e881eee9d4e8cf70b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ws@npm:^7.3.1, ws@npm:^7.4.6":
|
||||
version: 7.5.3
|
||||
resolution: "ws@npm:7.5.3"
|
||||
@@ -15173,21 +15189,6 @@ resolve@^2.0.0-next.3:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ws@npm:^8.1.0":
|
||||
version: 8.2.0
|
||||
resolution: "ws@npm:8.2.0"
|
||||
peerDependencies:
|
||||
bufferutil: ^4.0.1
|
||||
utf-8-validate: ^5.0.2
|
||||
peerDependenciesMeta:
|
||||
bufferutil:
|
||||
optional: true
|
||||
utf-8-validate:
|
||||
optional: true
|
||||
checksum: 7cd544312a48dafcb8158c9b4e5f20986cce980d516e0ef0602665911b0e95c5e0dea2846a4bb3153a1e2c839aa3d92fb7e69dd864fe432e881eee9d4e8cf70b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"xdg-basedir@npm:^3.0.0":
|
||||
version: 3.0.0
|
||||
resolution: "xdg-basedir@npm:3.0.0"
|
||||
@@ -15202,23 +15203,6 @@ resolve@^2.0.0-next.3:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"xml2js@npm:^0.4.17":
|
||||
version: 0.4.23
|
||||
resolution: "xml2js@npm:0.4.23"
|
||||
dependencies:
|
||||
sax: ">=0.6.0"
|
||||
xmlbuilder: ~11.0.0
|
||||
checksum: ca0cf2dfbf6deeaae878a891c8fbc0db6fd04398087084edf143cdc83d0509ad0fe199b890f62f39c4415cf60268a27a6aed0d343f0658f8779bd7add690fa98
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"xmlbuilder@npm:~11.0.0":
|
||||
version: 11.0.1
|
||||
resolution: "xmlbuilder@npm:11.0.1"
|
||||
checksum: 7152695e16f1a9976658215abab27e55d08b1b97bca901d58b048d2b6e106b5af31efccbdecf9b07af37c8377d8e7e821b494af10b3a68b0ff4ae60331b415b0
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"xmlchars@npm:^2.2.0":
|
||||
version: 2.2.0
|
||||
resolution: "xmlchars@npm:2.2.0"
|
||||
|
Reference in New Issue
Block a user