Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Include axe-core node results all and none in output #66

Merged
merged 5 commits into from
Jan 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "axe-scan",
"version": "1.2.1",
"description": "A CLI tool to test web accessibility on multiple web pages based on a list of URLs in a text file.",
"type": "commonjs",
"type": "module",
"exports": "./build/src/index.js",
"main": "build/src/index.js",
"bin": {
Expand Down
127 changes: 69 additions & 58 deletions src/commands/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ interface PartialAxeResults {
incomplete: axe.Result[];
inapplicable: axe.Result[];
}
interface PartialAxeNodeResults {
any: axe.CheckResult[];
all: axe.CheckResult[];
none: axe.CheckResult[];
}

/**
* Run the accessibility test and returns the results as a standard output.
Expand Down Expand Up @@ -93,65 +98,71 @@ export default async function (options: CommandOption): Promise<void> {
results[resultType as keyof PartialAxeResults].forEach(
(resultItem: axe.Result) => {
resultItem.nodes.forEach((node: axe.NodeResult) => {
node.any.forEach((a: axe.CheckResult) => {
// Rule Set
const ruleSet: string = resultItem.tags
.filter((tag: string) => config.axeCoreTags.includes(tag))
.join();
// DOM Element
const domElement: string = node.target.join();
// WCAG Criteria
const wcagCriteria: string = resultItem.tags
.reduce((arr: string[], tag: string) => {
if (tag.match(/^wcag\d{3}$/)) {
arr.push(
[
tag.slice(-3, -2),
tag.slice(-2, -1),
tag.slice(-1),
].join('.')
);
['any', 'all', 'none'].forEach((nodeResult: string) => {
node[nodeResult as keyof PartialAxeNodeResults].forEach(
(a: axe.CheckResult, ind: number) => {
// Rule Set
const ruleSet: string = resultItem.tags
.filter((tag: string) => config.axeCoreTags.includes(tag))
.join();
// DOM Element
const domElement: string = node.target.join();
// WCAG Criteria
const wcagCriteria: string = resultItem.tags
.reduce((arr: string[], tag: string) => {
if (tag.match(/^wcag\d{3}$/)) {
arr.push(
[
tag.slice(-3, -2),
tag.slice(-2, -1),
tag.slice(-1),
].join('.')
);
}
return arr;
}, [])
.join(' ');
if (
allowlist &&
allowlist.some(
(row: ReportRowValue) =>
row.URL == results.url &&
row['Rule Type'] == resultItem.id &&
row['Result Type'] == resultType &&
row['Rule Set'] == ruleSet &&
row['Impact'] == resultItem.impact &&
convertStringForCsv(row['HTML Element']) ==
convertStringForCsv(node.html) &&
convertStringForCsv(row['DOM Element']) ==
convertStringForCsv(domElement) &&
row['WCAG Criteria'] == wcagCriteria
)
) {
return;
} else {
const outputRow: string = [
// Corresponds with the columns of REPORT_HEADER
results.url, // URL
resultItem.id, // Rule Type
resultType, // Result Type
nodeResult, // Result Condition
ind + 1, // Result Condition Index
ruleSet, // Rule Set
resultItem.impact, // Impact
a.message, // Message
node.html, // HTML Element
domElement, // DOM Element
resultItem.help, // Help
resultItem.helpUrl, // Help URL
wcagCriteria, // WCAG Criteria,
VERSION, // axe-scan version
]
.map((value) => convertStringForCsv(String(value)))
.join();
outputText += `\n${outputRow}`;
}
return arr;
}, [])
.join(' ');
if (
allowlist &&
allowlist.some(
(row: ReportRowValue) =>
row.URL == results.url &&
row['Rule Type'] == resultItem.id &&
row['Result Type'] == resultType &&
row['Rule Set'] == ruleSet &&
row['Impact'] == resultItem.impact &&
convertStringForCsv(row['HTML Element']) ==
convertStringForCsv(node.html) &&
convertStringForCsv(row['DOM Element']) ==
convertStringForCsv(domElement) &&
row['WCAG Criteria'] == wcagCriteria
)
) {
return;
} else {
const outputRow: string = [
// Corresponds with the columns of REPORT_HEADER
results.url, // URL
resultItem.id, // Rule Type
resultType, // Result Type
ruleSet, // Rule Set
resultItem.impact, // Impact
a.message, // Message
node.html, // HTML Element
domElement, // DOM Element
resultItem.help, // Help
resultItem.helpUrl, // Help URL
wcagCriteria, // WCAG Criteria,
VERSION, // axe-scan version
]
.map((value) => convertStringForCsv(String(value)))
.join();
outputText += `\n${outputRow}`;
}
}
);
});
});
}
Expand Down
2 changes: 2 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ export const REPORT_HEADER: string[] = [
'URL',
'Rule Type', // rule ID
'Result Type', // inapplicable, incomplete, passes, or violations
'Result Condition', // all, none, or any
'Result Condition Index', // results with the same index have the common result conditions
'Rule Set', // wcag2aa etc.
'Impact', // "minor", "moderate", "serious", or "critical"
'Message',
Expand Down
2 changes: 1 addition & 1 deletion src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import ora from 'ora';
import os from 'os';
import path from 'path';

import { DEFAULT_CONFIG, CONFIG_FILE_PATH, ConfigValue } from './constants';
import { DEFAULT_CONFIG, CONFIG_FILE_PATH, ConfigValue } from './constants.js';

/**
* ora - The elegant terminal spinner
Expand Down