@uuv/a11y
Version:
A javascript lib for running a11y validation based on multiple reference(RGAA, etc)
136 lines (135 loc) • 5.59 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Engine = void 0;
const rxjs_1 = require("rxjs");
const model_1 = require("../model/");
class Engine {
targetUrl;
reference;
constructor(targetUrl, reference) {
this.targetUrl = targetUrl;
this.reference = reference;
}
buildCheckListItemFromRule(rule) {
return new rxjs_1.Observable(observer => {
const foundElements = rule.query.execute();
const result = this.getRuleResult(rule, foundElements);
observer.next(result);
observer.complete();
});
}
getRuleResult(rule, queryResults) {
if (rule.check === model_1.RuleCheckEnum.MANUAL) {
return this.buildResultForManualCheck(rule, queryResults);
}
else {
// Then we are considering rule as RuleCheckEnum.AUTO
const domNodes = queryResults.map((element) => element.domNode);
return this.buildResultForAutoCheck(rule, domNodes);
}
}
buildResultForAutoCheck(rule, $el) {
const a11YRuleresult = new model_1.A11yRuleResult(this.targetUrl, rule);
if (rule.shouldNotExist) {
if ($el?.length > 0) {
for (const element of $el) {
const selector = this.getSelector(element);
const validation = a11YRuleresult.getOrAddValidation(rule.criterion);
validation.errorNodes.push({
node: element,
selector: selector,
html: element.outerHTML
});
validation.status = model_1.A11yResultStatus.ERROR;
}
}
else {
const validation = a11YRuleresult.getOrAddValidation(rule.criterion);
validation.status = model_1.A11yResultStatus.SUCCESS;
}
}
else {
if ($el.length === 0 && !rule.elementType.includes("warning") && !rule.elementType.includes("obsolete")) {
const validation = a11YRuleresult.getOrAddValidation(rule.criterion);
validation.status = model_1.A11yResultStatus.ERROR;
validation.errorNodes.push({
selector: rule.query.getSelector(),
});
}
else {
const validation = a11YRuleresult.getOrAddValidation(rule.criterion);
validation.status = model_1.A11yResultStatus.SUCCESS;
}
}
return a11YRuleresult;
}
buildResultForManualCheck(rule, queryResults) {
const a11YRuleResult = new model_1.A11yRuleResult(this.targetUrl, rule);
const validation = a11YRuleResult.getOrAddValidation(rule.criterion);
validation.status = model_1.A11yResultStatus.SUCCESS;
for (const element of queryResults) {
const domNode = element.domNode;
const selector = this.getSelector(domNode);
const attributesToCheck = [];
rule.attributes.forEach((attribute) => {
const childData = attribute.split(":");
if (childData.length > 1) {
domNode.childNodes.forEach((childNode) => {
if (childNode.nodeName === childData[1]) {
attributesToCheck.push(`${attribute}=${childNode.textContent}`);
}
});
}
else {
const attributeFilledWithInformation = domNode.getAttribute(attribute);
if (attributeFilledWithInformation) {
attributesToCheck.push(`${attribute}=${attributeFilledWithInformation}`);
}
}
});
const manualValidation = a11YRuleResult.getOrAddValidation(rule.criterion);
manualValidation.status = model_1.A11yResultStatus.MANUAL;
manualValidation.nodesToCheckManually.push({
node: element,
selector: selector,
attributes: attributesToCheck.join(", "),
html: domNode.outerHTML,
help: rule.id ? `${this.reference.getRuleUrl(rule.id)}` : ""
});
}
return a11YRuleResult;
}
getSelector(element) {
const path = [];
while (element.nodeType === Node.ELEMENT_NODE) {
let selector = element.nodeName.toLowerCase();
if (element.id) {
selector += "#" + element.id;
path.unshift(selector);
break;
}
else if (element.getAttribute("data-testid")) {
selector += `[data-testid=${element.getAttribute("data-testid")}]`;
path.unshift(selector);
break;
}
else {
let sibling = element.previousSibling;
let index = 1;
while (sibling) {
if (sibling.nodeType === Node.ELEMENT_NODE && sibling.nodeName.toLowerCase() === selector) {
index++;
}
sibling = sibling.previousSibling;
}
if (index > 1 || element.nextSibling) {
selector += ":nth-of-type(" + index + ")";
}
}
path.unshift(selector);
element = element.parentNode;
}
return path.join(" > ");
}
}
exports.Engine = Engine;