UNPKG

@uuv/a11y

Version:

A javascript lib for running a11y validation based on multiple reference(RGAA, etc)

136 lines (135 loc) 5.59 kB
"use strict"; 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;