187 lines
5.9 KiB
JavaScript
187 lines
5.9 KiB
JavaScript
const express = require("express");
|
|
const fs = require("fs");
|
|
const tap = require("tap");
|
|
const webdriver = require("selenium-webdriver");
|
|
const screenshot = require("./screenshooter");
|
|
const BlinkDiff = require("blink-diff");
|
|
const path = require("path");
|
|
|
|
// Command line arguments examples:
|
|
// node test.js win ie11,chrome
|
|
// node test.js macos safari,chrome,firefox
|
|
|
|
const environmentId = process.argv[2] || "";
|
|
const enabledBrowsers = (process.argv[3] || "").split(/[,;]/g).filter(name => name);
|
|
|
|
if (!enabledBrowsers.length) {
|
|
throw new Error("Expected browser names");
|
|
}
|
|
|
|
const screenshotDir = process.env.BROWSER_SCREENSHOT_DIR || path.join(__dirname, "artifacts/screenshots");
|
|
const diffDir = process.env.BROWSER_DIFF_DIR || path.join(__dirname, "artifacts/diffs");
|
|
const expectedDir = process.env.BROWSER_EXPECTED_DIR || path.join(__dirname, "expected");
|
|
|
|
// fs.mkdirSync(_ , { recursive: true }) did not work on GitHub Actions using Node v12.18.2 (Windows and macOS).
|
|
// Worked fine locally however. Replacing it with a custom recursive implementation.
|
|
// Ignored GitHub issue for tracking any status:
|
|
// https://github.com/nodejs/node/issues/27293
|
|
function mkdirRecursive(dirPath) {
|
|
if (!fs.existsSync(dirPath)) {
|
|
const parent = path.dirname(dirPath)
|
|
if (parent && parent !== dirPath) {
|
|
mkdirRecursive(parent);
|
|
}
|
|
fs.mkdirSync(dirPath);
|
|
}
|
|
}
|
|
|
|
mkdirRecursive(screenshotDir);
|
|
mkdirRecursive(diffDir);
|
|
|
|
const BROWSER_DEFINITIONS = [
|
|
{
|
|
name: "ie11",
|
|
uaCompatible: "IE=Edge",
|
|
capabilities: {
|
|
"browserName": webdriver.Browser.INTERNET_EXPLORER,
|
|
"ie.ensureCleanSession": true,
|
|
},
|
|
},
|
|
{
|
|
name: "ie10",
|
|
uaCompatible: "IE=10",
|
|
capabilities: {
|
|
"browserName": webdriver.Browser.INTERNET_EXPLORER,
|
|
"ie.ensureCleanSession": true,
|
|
},
|
|
},
|
|
{
|
|
name: "ie9",
|
|
uaCompatible: "IE=9",
|
|
capabilities: {
|
|
"browserName": webdriver.Browser.INTERNET_EXPLORER,
|
|
"ie.ensureCleanSession": true,
|
|
},
|
|
},
|
|
{
|
|
name: "firefox",
|
|
capabilities: {
|
|
"browserName": webdriver.Browser.FIREFOX,
|
|
},
|
|
},
|
|
{
|
|
name: "chrome",
|
|
capabilities: {
|
|
"browserName": webdriver.Browser.CHROME,
|
|
},
|
|
},
|
|
{
|
|
name: "edge",
|
|
capabilities: {
|
|
"browserName": webdriver.Browser.EDGE,
|
|
"ms:edgeChromium": true,
|
|
},
|
|
},
|
|
{
|
|
name: "safari",
|
|
capabilities: {
|
|
"browserName": webdriver.Browser.SAFARI,
|
|
},
|
|
},
|
|
]
|
|
|
|
async function serve(root, options, asyncCallback) {
|
|
const app = express();
|
|
|
|
app.use(express.static(root, options));
|
|
|
|
await new Promise((resolve, reject) => {
|
|
const listener = app.listen(async () => {
|
|
try {
|
|
await asyncCallback(listener);
|
|
resolve();
|
|
|
|
} catch (e) {
|
|
reject(e);
|
|
|
|
} finally {
|
|
listener.close();
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
async function testBrowser(browserName) {
|
|
const browser = BROWSER_DEFINITIONS.find(x => x.name === browserName);
|
|
await tap.test(browserName, async t => {
|
|
if (!browser) {
|
|
t.fail(`Could not find a browser with the name ${browserName}.`);
|
|
return;
|
|
}
|
|
|
|
await serve(
|
|
path.join(__dirname, "../../"),
|
|
{
|
|
"index": ["index.html"],
|
|
setHeaders: resp => {
|
|
// Prevent stale files
|
|
resp.setHeader("Cache-Control", "no-store");
|
|
|
|
if (browser.uaCompatible) {
|
|
resp.setHeader("X-UA-Compatible", browser.uaCompatible);
|
|
}
|
|
}
|
|
},
|
|
async listener => {
|
|
const url = "http://localhost:" + listener.address().port + "/e2e/browser/assets/";
|
|
|
|
console.log(`Screenshot in ${browserName}`);
|
|
console.log(url);
|
|
|
|
const driver = await new webdriver.Builder()
|
|
.withCapabilities(browser.capabilities)
|
|
.build();
|
|
|
|
await driver.manage().window().setRect({ width: 1000, height: 2000 });
|
|
|
|
const documentInitialised = () => driver.executeScript("return true");
|
|
|
|
try {
|
|
await driver.get(url);
|
|
await driver.wait(() => documentInitialised(), 10000);
|
|
await driver.sleep(2500);
|
|
|
|
const screenshotBuffer = await screenshot(driver);
|
|
fs.writeFileSync(path.join(screenshotDir, `${environmentId}-${browserName}.png`), screenshotBuffer);
|
|
|
|
} finally {
|
|
await driver.quit();
|
|
}
|
|
|
|
var diff = new BlinkDiff({
|
|
imageAPath: path.join(expectedDir, `${environmentId}-${browserName}.png`),
|
|
imageBPath: path.join(screenshotDir, `${environmentId}-${browserName}.png`),
|
|
|
|
thresholdType: BlinkDiff.THRESHOLD_PIXEL,
|
|
threshold: 1000,
|
|
|
|
imageOutputPath: path.join(diffDir, `${environmentId}-${browserName}.png`),
|
|
|
|
// Ignore test metadata area containing browser versions etc.
|
|
blockOut: [{ x: 0, y: 0, width: 20000, height: 100 }],
|
|
});
|
|
|
|
const diffResult = await diff.runWithPromise();
|
|
t.ok(diff.hasPassed(diffResult.code), `Found ${diffResult.differences} differences.`);
|
|
},
|
|
);
|
|
});
|
|
}
|
|
|
|
async function testBrowsers(enabledBrowsers) {
|
|
for (var i = 0; i < enabledBrowsers.length; i++) {
|
|
await testBrowser(enabledBrowsers[i]);
|
|
}
|
|
}
|
|
|
|
testBrowsers(enabledBrowsers); |