noredink-ui/script/puppeteer-tests.js

215 lines
6.0 KiB
JavaScript
Raw Normal View History

2022-05-24 19:42:36 +03:00
const expect = require("expect");
const puppeteer = require("puppeteer");
const httpServer = require("http-server");
const percySnapshot = require("@percy/puppeteer");
2022-01-22 03:49:18 +03:00
2022-05-24 19:42:36 +03:00
const platform = require("os").platform();
2022-01-22 03:49:18 +03:00
// We need to change the args passed to puppeteer based on the platform they're using
2022-05-24 19:42:36 +03:00
const puppeteerArgs = /^win/.test(platform) ? [] : ["--single-process"];
2022-01-22 03:49:18 +03:00
const PORT = process.env.PORT_NUMBER || 8000;
2022-05-24 19:42:36 +03:00
const { AxePuppeteer } = require("@axe-core/puppeteer");
const assert = require("assert");
2022-05-24 19:42:36 +03:00
describe("UI tests", function () {
2022-01-22 03:49:18 +03:00
let page;
let server;
let browser;
before(async () => {
server = httpServer.createServer({ root: `${__dirname}/../public` });
server.listen(PORT);
browser = await puppeteer.launch({
headless: true,
timeout: 10000,
2022-05-24 19:42:36 +03:00
args: puppeteerArgs,
2022-01-22 03:49:18 +03:00
});
});
after(() => {
server.close();
});
2019-11-15 14:16:10 +03:00
2022-05-24 19:42:36 +03:00
const handleAxeResults = function (name, results) {
const violations = results["violations"];
if (violations.length > 0) {
2022-05-24 19:42:36 +03:00
violations.map(function (violation) {
console.log("\n\n", violation["id"], ":", violation["description"]);
console.log(violation["help"]);
console.log(violation["helpUrl"]);
2022-05-24 19:42:36 +03:00
console.table(violation["nodes"], ["html"]);
});
2022-05-24 19:42:36 +03:00
assert.fail(
`Expected no axe violations in ${name} but got ${violations.length} violations`
);
}
2022-05-24 19:42:36 +03:00
};
2022-06-27 21:00:54 +03:00
const goTo = async (name, location) => {
2022-06-29 03:42:12 +03:00
await page.goto(location, { waitUntil: "load" });
2022-06-28 22:40:14 +03:00
await page.waitForSelector(`#${name.replace(".", "-")}`, { visible: true });
2022-06-27 21:00:54 +03:00
};
const defaultProcessing = async (name, location) => {
await goTo(name, location);
2022-05-24 19:42:36 +03:00
await percySnapshot(page, name);
2022-05-24 19:42:36 +03:00
const results = await new AxePuppeteer(page)
.disableRules(skippedRules[name] || [])
.analyze();
handleAxeResults(name, results);
2022-05-24 19:42:36 +03:00
};
2022-01-22 03:49:18 +03:00
2022-07-15 01:36:09 +03:00
const forAllOptions = async (labelName, callback) => {
await page.waitForXPath(
`//label[contains(., '${labelName}')]//select`,
200
);
const [select] = await page.$x(
`//label[contains(., '${labelName}')]//select`
);
const options = await select.$x(
2022-07-15 01:36:09 +03:00
`//label[contains(., '${labelName}')]//option`
);
for (const optionEl of options) {
const option = await page.evaluate((el) => el.innerText, optionEl);
2022-07-15 03:05:50 +03:00
await page.select("select", option);
2022-07-15 01:36:09 +03:00
callback(option);
}
};
2022-06-18 02:17:09 +03:00
const messageProcessing = async (name, location) => {
2022-06-27 21:00:54 +03:00
await goTo(name, location);
2022-06-18 02:17:09 +03:00
await percySnapshot(page, name);
var axe = await new AxePuppeteer(page)
.disableRules(skippedRules[name] || [])
.analyze();
handleAxeResults(name, axe);
const [theme] = await page.$x("//label[contains(., 'theme')]");
await theme.click();
2022-07-15 01:36:09 +03:00
await forAllOptions("theme", async (option) => {
await percySnapshot(page, `${name} - ${option}`);
2022-06-18 02:17:09 +03:00
axe = await new AxePuppeteer(page)
.withRules(["color-contrast"])
.analyze();
handleAxeResults(`${name} - ${option}`, axe);
2022-07-15 01:36:09 +03:00
});
2022-06-18 02:17:09 +03:00
};
2022-07-15 00:17:39 +03:00
const modalProcessing = async (name, location) => {
await goTo(name, location);
2022-07-15 01:36:09 +03:00
await forAllOptions("Theme", async (option) => {
await page.click("#launch-modal");
await page.waitForSelector('[role="dialog"]');
await percySnapshot(page, `${name} - ${option}`);
axe = await new AxePuppeteer(page).analyze();
await page.click('[aria-label="Close modal"]');
2022-07-15 00:17:39 +03:00
2022-07-15 01:36:09 +03:00
handleAxeResults(`${name} - ${option}`, axe);
});
2022-07-15 01:08:32 +03:00
};
2022-07-15 00:17:39 +03:00
const pageProcessing = async (name, location) => {
await goTo(name, location);
var axe = await new AxePuppeteer(page)
.disableRules(skippedRules[name] || [])
.analyze();
handleAxeResults(name, axe);
2022-07-15 01:36:09 +03:00
await forAllOptions("page", async (option) => {
2022-07-15 01:08:32 +03:00
await percySnapshot(page, `${name} - ${option}`, {
scope: "[data-page-container='']",
});
2022-07-15 01:36:09 +03:00
});
2022-07-15 01:08:32 +03:00
};
2022-07-15 00:17:39 +03:00
2022-05-24 19:42:36 +03:00
const iconProcessing = async (name, location) => {
await page.goto(location);
2022-06-27 20:56:15 +03:00
await page.waitForSelector(`#${name}`);
2022-05-24 19:42:36 +03:00
await percySnapshot(page, name);
2022-03-22 01:06:15 +03:00
// visible icon names snapshot
await page.click("label");
2022-05-24 19:42:36 +03:00
await page.waitForSelector(".checkbox-V5__Checked");
await percySnapshot(page, `${name} - display icon names`);
2022-03-22 01:06:15 +03:00
2022-05-24 19:42:36 +03:00
const results = await new AxePuppeteer(page)
.disableRules(skippedRules[name] || [])
.analyze();
handleAxeResults(name, results);
2022-05-24 19:42:36 +03:00
};
2022-03-22 01:06:15 +03:00
const skippedRules = {
2022-04-19 19:40:48 +03:00
// Loading's color contrast check seems to change behavior depending on whether Percy snapshots are taken or not
2022-05-24 19:42:36 +03:00
Loading: ["color-contrast"],
RadioButton: ["duplicate-id"],
};
const specialProcessing = {
2022-06-18 02:17:09 +03:00
Message: messageProcessing,
2022-07-15 00:17:39 +03:00
Modal: modalProcessing,
Page: pageProcessing,
2022-05-24 19:42:36 +03:00
AssignmentIcon: iconProcessing,
UiIcon: iconProcessing,
Logo: iconProcessing,
Pennant: iconProcessing,
};
2022-01-22 03:49:18 +03:00
2022-05-24 19:42:36 +03:00
it("All", async function () {
2022-01-22 03:49:18 +03:00
page = await browser.newPage();
await page.goto(`http://localhost:${PORT}`);
2022-05-24 19:42:36 +03:00
await page.$("#maincontent");
2022-01-22 03:49:18 +03:00
await percySnapshot(page, this.test.fullTitle());
2022-05-24 19:42:36 +03:00
const results = await new AxePuppeteer(page)
.disableRules([
"aria-hidden-focus",
"color-contrast",
"duplicate-id-aria",
"duplicate-id",
2022-05-24 19:42:36 +03:00
])
.analyze();
2022-01-22 03:49:18 +03:00
page.close();
handleAxeResults("index view", results);
2020-09-09 22:46:24 +03:00
});
2022-05-24 19:42:36 +03:00
it("Doodads", async function () {
2022-01-22 03:49:18 +03:00
page = await browser.newPage();
await page.goto(`http://localhost:${PORT}`);
2022-05-24 19:42:36 +03:00
await page.$("#maincontent");
2022-01-22 03:49:18 +03:00
let links = await page.evaluate(() => {
2022-05-24 19:42:36 +03:00
let nodes = Array.from(
document.querySelectorAll("[data-nri-description='doodad-link']")
);
return nodes.map((node) => [node.text, node.href]);
});
2022-01-22 03:49:18 +03:00
await links.reduce((acc, [name, location]) => {
return acc.then(() => {
2022-05-24 19:42:36 +03:00
if (
process.env.ONLYDOODAD == "default" ||
process.env.ONLYDOODAD == name
) {
console.log(`Testing ${name}`);
let handler = specialProcessing[name] || defaultProcessing;
return handler(name, location);
2022-01-22 03:49:18 +03:00
}
2022-05-24 19:42:36 +03:00
});
}, Promise.resolve());
page.close();
2022-05-24 19:42:36 +03:00
});
});