@uuv/cypress
Version:
A solution to facilitate the writing and execution of E2E tests understandable by any human being using cucumber(BDD) and cypress
187 lines (186 loc) • 7.4 kB
JavaScript
;
/**
* Software Name : UUV
*
* SPDX-License-Identifier: MIT
*
* This software is distributed under the MIT License,
* see the "LICENSE" file for more details
*
* Authors: NJAKO MOLOM Louis Fredice & SERVICAL Stanley
* Software description: Make test writing fast, understandable by any human
* understanding English or French.
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.showUvvA11yReport = exports.checkUvvA11y = exports.injectUvvA11y = void 0;
const a11y_1 = require("@uuv/a11y");
const jquery_1 = __importDefault(require("jquery"));
const __common_1 = require("./_.common");
const lodash_1 = __importDefault(require("lodash"));
const injectUvvA11y = () => {
const fileName = typeof require?.resolve === "function"
? require.resolve("@uuv/a11y/bundle")
: "node_modules/@uuv/a11y/bundle/uuv-a11y.bundle.js";
cy.readFile(fileName).then((source) => cy.window({ log: false }).then((window) => {
window.eval(source);
}));
};
exports.injectUvvA11y = injectUvvA11y;
const checkUvvA11y = (options) => {
cy.window({ log: false })
.then((win) => {
return new Cypress.Promise(async (resolve, reject) => {
try {
const url = win.location.href;
const a11yChecker = getA11yCheckerForReference(win, options, url);
assert.isDefined(a11yChecker, "A11y reference not found");
const reportOfUsecase = await (a11yChecker?.validate(Cypress.currentTest.title, "empty Script", {
file: Cypress.spec.relative,
column: 0,
line: 0
})).toPromise();
if ((0, __common_1.shouldGenerateA11yReport)() && reportOfUsecase) {
storeA11yResult(reportOfUsecase).then(() => {
logAllA11yRuleResult(options.reference, reportOfUsecase);
assertWithExpectedResult(options, reportOfUsecase);
});
resolve();
}
else {
logAllA11yRuleResult(options.reference, reportOfUsecase);
assertWithExpectedResult(options, reportOfUsecase);
resolve();
}
}
catch (error) {
reject(error);
}
});
});
};
exports.checkUvvA11y = checkUvvA11y;
const showUvvA11yReport = (reference) => {
const a11yReport = readA11yReport();
const log = buildCypressLog("a11y synthesis", reference, {
reference: reference,
nodes: a11yReport
});
log.finish();
};
exports.showUvvA11yReport = showUvvA11yReport;
function getA11yCheckerForReference(win, options, url) {
let checker;
console.debug("reference", options.reference);
switch (options.reference) {
case a11y_1.A11yReferenceEnum.WCAG_WEB:
checker = new win.uuvA11y.WcagChecker(url, options.runnerOptions);
break;
case a11y_1.A11yReferenceEnum.WCAG_ANDROID:
break;
case a11y_1.A11yReferenceEnum.WCAG_IOS:
break;
case a11y_1.A11yReferenceEnum.RGAA:
default:
checker = new win.uuvA11y.RgaaChecker(url);
break;
}
return checker;
}
function assertWithExpectedResult(options, reportOfUsecase) {
const validationFailedMessage = "A11y validation failed";
if (options.expectedResult) {
const summary = (reportOfUsecase?.result.rawResult).summary();
if (!options.expectedResult.isContainsMode) {
assert.deepEqual(summary, options.expectedResult.value, validationFailedMessage);
}
else {
cy.wrap(summary)
.should("containSubset", options.expectedResult.value);
}
}
else {
assert.equal(reportOfUsecase?.result.issues.filter(issue => issue.type === a11y_1.IssueType.Error).length, 0, validationFailedMessage);
assert.equal(reportOfUsecase?.result.issues.filter(issue => issue.type === a11y_1.IssueType.Warning).length, 0, validationFailedMessage);
}
}
function logAllA11yRuleResult(reference, reportOfUsecase) {
reportOfUsecase?.result.issues.forEach(a11yIssue => {
// logValidatingA11yRule(result.reference, ruleResult);
logA11yRuleResult(reference, a11yIssue);
});
}
function logA11yRuleResult(reference, a11yIssue) {
switch (a11yIssue.type) {
case "error":
case "warning":
logNonCompliantNode(reference, a11yIssue);
break;
// case A11yResultStatus.MANUAL:
// logNodeToCheckManually(reference, ruleResult);
// break;
// case A11yResultStatus.UNKNOWN:
// break;
// case A11yResultStatus.SUCCESS:
// break;
}
}
function buildCypressLog(name, message, consoleLog) {
return Cypress.log({
name: name,
displayName: name,
message: message,
consoleProps() {
return consoleLog ? consoleLog : {};
}
});
}
function logNonCompliantNode(reference, a11yIssue) {
const errorNode = a11yIssue.htmlElement;
const log = buildCypressLog(`${reference.toString()} error !`, `criteria ${a11yIssue.code} with message : ${a11yIssue.message}`, getConsoleDetails(a11yIssue, errorNode));
if (errorNode) {
log.set({ $el: (0, jquery_1.default)(errorNode) }).snapshot();
}
log.error(new Error(`Validation ${a11yIssue.type} on node: ${errorNode}`));
}
// function logNodeToCheckManually(reference: A11yReferenceEnum, ruleResult: A11yRuleResult) {
// const nodesToCheckManually = ruleResult.getNodesToCheckManually();
// const log = buildCypressLog(
// `${reference.toString()} to validate manually !`,
// `criteria ${ruleResult.rule.criterion} on ${nodesToCheckManually.length} nodes`,
// getConsoleDetails(reference, ruleResult, nodesToCheckManually)
// );
// nodesToCheckManually.forEach(nodeToCheck => log.set({ $el: $(nodeToCheck.node.domNode) }).snapshot());
// log.finish();
// }
function getConsoleDetails(a11yIssue, nodes) {
return {
// Id: a11yIssue.runnerExtras.help rule.id,
// WCAG: a11yIssue.code,
// targetUrl: ruleResult.url,
criteria: a11yIssue.code,
// "Element type": ruleResult.rule.elementType,
help: `${a11yIssue.runnerExtras.help}, ${a11yIssue.runnerExtras.helpUrl}`,
runnerExtra: a11yIssue.runnerExtras,
nodes: nodes
};
}
function storeA11yResult(reportOfUsecase) {
const reportOfUsecaseToSore = lodash_1.default.cloneDeep(reportOfUsecase);
reportOfUsecaseToSore.result.issues.forEach(issue => delete issue.htmlElement);
const filePath = (0, __common_1.getA11yResultFilePath)();
return cy.readFile(filePath).then((report) => {
report.app.usecases.push(reportOfUsecaseToSore);
writeA11yReport(report);
});
}
function readA11yReport() {
const filePath = (0, __common_1.getA11yResultFilePath)();
return cy.readFile(filePath);
}
function writeA11yReport(data) {
const filePath = (0, __common_1.getA11yResultFilePath)();
return cy.writeFile(filePath, data, { flag: "w" });
}