eaa-kit 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -8
- package/dist/astro/index.d.ts +1 -1
- package/dist/astro/index.js +1 -1
- package/dist/audit/runners/worker.js +1 -1
- package/dist/audit-Bwm1xBdJ.js +2 -0
- package/dist/{audit-e_uixhPG.js → audit-DRjAY2iY.js} +164 -75
- package/dist/{baseline-D2qWmUC6.js → baseline-BpE7DbDq.js} +1 -1
- package/dist/{baseline-BscHfFSW.js → baseline-rtnj3RHB.js} +1 -1
- package/dist/cache-D4dOIuOi.js +219 -0
- package/dist/{checklist-BtgkxMEa.js → checklist-DDd9jewi.js} +3 -3
- package/dist/cli/index.js +28 -12
- package/dist/{command-CZKp9Wi_.js → command-3r4fht5f.js} +6 -5
- package/dist/{coverage-BD2_CYns.js → coverage-cb5kPp48.js} +3 -285
- package/dist/coverage-n1X9CkiG.js +3 -0
- package/dist/criteria-CnPJKGeb.js +286 -0
- package/dist/eleventy/index.d.ts +1 -1
- package/dist/eleventy/index.js +1 -1
- package/dist/{html-Bmh7X_sM.js → html-BIxxF3FC.js} +6 -4
- package/dist/index.d.ts +19 -0
- package/dist/index.js +2 -2
- package/dist/{init-BjKYttxc.js → init-DrFfzjvm.js} +2 -2
- package/dist/jsdom-BUYuVJJm.js +3 -0
- package/dist/{jsdom-CQar6OQS.js → jsdom-CsW_xVcA.js} +11 -12
- package/dist/{json-PNg6BeXp.js → json-Bus6YhxB.js} +4 -3
- package/dist/{json-HJDgJp09.js → json-CrQmoTj6.js} +1 -1
- package/dist/{load-vZdV_fD1.js → load-BaWMa-G_.js} +6 -1
- package/dist/load-n62iXDq_.js +2 -0
- package/dist/nuxt/index.d.ts +1 -1
- package/dist/nuxt/index.js +1 -1
- package/dist/{playwright-C-miJP2b.js → playwright-ukCr_5o3.js} +1 -1
- package/dist/{pool-dkexq5xo.js → pool-B4tEUa2S.js} +6 -2
- package/dist/{completeness-Dwq3CPB3.js → remediation-C0klJblu.js} +55 -42
- package/dist/{render-CtsqR0k-.js → render-C1sUZZI_.js} +41 -3
- package/dist/{result-DfUru6y_.js → result-B7_zVxAX.js} +1 -1
- package/dist/result-CRmjjoAA.js +2 -0
- package/dist/{run-YiqyQA2b.d.ts → run-BK2blxMI.d.ts} +8 -0
- package/dist/{run-D7hdVXLA.js → run-DrS0Komf.js} +6 -2
- package/dist/{sarif-BKvq_AUm.js → sarif-BNCE0PNT.js} +3 -2
- package/dist/statement/templates/at.de.md +14 -0
- package/dist/statement/templates/at.en.md +14 -0
- package/dist/statement/templates/ch.de.md +14 -0
- package/dist/statement/templates/ch.en.md +14 -0
- package/dist/statement/templates/de.de.md +14 -0
- package/dist/statement/templates/de.en.md +14 -0
- package/dist/statement/templates/es.en.md +14 -0
- package/dist/statement/templates/es.es.md +15 -0
- package/dist/statement/templates/fr.en.md +14 -0
- package/dist/statement/templates/fr.fr.md +15 -0
- package/dist/statement/templates/it.en.md +14 -0
- package/dist/statement/templates/it.it.md +15 -0
- package/dist/statement/templates/nl.en.md +14 -0
- package/dist/statement/templates/nl.nl.md +15 -0
- package/dist/vite/index.d.ts +1 -1
- package/dist/vite/index.js +1 -1
- package/dist/webpack/index.d.ts +1 -1
- package/dist/webpack/index.js +1 -1
- package/dist/{worksheet-eUjwYLxC.js → worksheet-BIxMtbUd.js} +3 -2
- package/package.json +3 -2
- package/dist/audit-DK2StT1_.js +0 -2
- package/dist/coverage-7bQqWNfN.js +0 -2
- package/dist/jsdom-DMvU2h-f.js +0 -3
- package/dist/load-Bc_xDGAh.js +0 -2
|
@@ -1,19 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { c as pageUrl, d as runOptions, f as shapeResults, i as blindRulesInScope, n as DEFAULT_TAGS, o as failedPage } from "./result-B7_zVxAX.js";
|
|
2
2
|
import axe from "axe-core";
|
|
3
3
|
import { Script } from "node:vm";
|
|
4
4
|
import { JSDOM, VirtualConsole } from "jsdom";
|
|
5
5
|
//#region src/audit/runners/jsdom.ts
|
|
6
6
|
/**
|
|
7
|
-
* Per-page ceiling.
|
|
8
|
-
*
|
|
9
|
-
* A soft one, and the limit is worth stating: this races axe-core against a
|
|
10
|
-
* timer, so it only fires where the work yields to the event loop. Neither
|
|
11
|
-
* jsdom's parse nor axe-core's walk of the tree does, so a document pathological
|
|
12
|
-
* enough to hold the thread runs past this unimpeded. The hard ceiling is the
|
|
13
|
-
* worker pool's, which terminates the thread; see the note on `runWorkers`.
|
|
14
|
-
*/
|
|
15
|
-
const DEFAULT_TIMEOUT_MS = DEFAULT_PAGE_TIMEOUT_MS;
|
|
16
|
-
/**
|
|
17
7
|
* Audit collected pages with axe-core inside jsdom.
|
|
18
8
|
*
|
|
19
9
|
* Pages are processed sequentially: jsdom parsing and axe-core are both
|
|
@@ -40,7 +30,7 @@ async function auditPage(page, options = {}) {
|
|
|
40
30
|
dom = createDom(page.html, url);
|
|
41
31
|
injectAxe(dom);
|
|
42
32
|
const { axe: pageAxe } = dom.window;
|
|
43
|
-
const results = await withTimeout(pageAxe.run(dom.window.document, runOptions(tags, { skipBlindRules: options.fast === true })), options.timeoutMs ??
|
|
33
|
+
const results = await withTimeout(pageAxe.run(dom.window.document, runOptions(tags, { skipBlindRules: options.fast === true })), options.timeoutMs ?? 3e4);
|
|
44
34
|
return shapeResults(results, {
|
|
45
35
|
...identity,
|
|
46
36
|
durationMs: Date.now() - startedAt,
|
|
@@ -74,6 +64,15 @@ function injectAxe(dom) {
|
|
|
74
64
|
axeScript ??= new Script(axe.source, { filename: "axe-core.js" });
|
|
75
65
|
axeScript.runInContext(dom.getInternalVMContext());
|
|
76
66
|
}
|
|
67
|
+
/**
|
|
68
|
+
* The per-page ceiling, and it is a soft one.
|
|
69
|
+
*
|
|
70
|
+
* This races axe-core against a timer, so it only fires where the work yields to
|
|
71
|
+
* the event loop. Neither jsdom's parse nor axe-core's walk of the tree does, so
|
|
72
|
+
* a document pathological enough to hold the thread runs past this unimpeded.
|
|
73
|
+
* The hard ceiling is the worker pool's, which terminates the thread; see the
|
|
74
|
+
* note on `runWorkers`.
|
|
75
|
+
*/
|
|
77
76
|
async function withTimeout(promise, ms) {
|
|
78
77
|
promise.catch(() => {});
|
|
79
78
|
let timer;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { a as impactLabel, i as countAtOrAbove, s as isImpactLevel } from "./impact-luGCnN8F.js";
|
|
2
2
|
import { t as TOOL_VERSION } from "./version-B3v4rNoG.js";
|
|
3
3
|
import { t as elementFingerprint } from "./fingerprint-BjYV_0F7.js";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { m as uniqueRuleOutcomes, u as runEngine } from "./result-B7_zVxAX.js";
|
|
5
|
+
import { t as buildCoverage } from "./coverage-cb5kPp48.js";
|
|
6
6
|
import axe from "axe-core";
|
|
7
7
|
/**
|
|
8
8
|
* Build the machine-readable report.
|
|
@@ -104,7 +104,8 @@ function toJsonPage(audit) {
|
|
|
104
104
|
incomplete: [...audit.incomplete].sort(byRuleId).map(toJsonIncomplete),
|
|
105
105
|
passes: [...audit.passes].sort(byRuleId).map((outcome) => outcome.ruleId),
|
|
106
106
|
inapplicable: [...audit.inapplicable].sort(byRuleId).map((outcome) => outcome.ruleId),
|
|
107
|
-
error: audit.error ?? null
|
|
107
|
+
error: audit.error ?? null,
|
|
108
|
+
...audit.reused === void 0 ? {} : { reusedFrom: audit.reused.on }
|
|
108
109
|
};
|
|
109
110
|
}
|
|
110
111
|
function toJsonFinding(finding) {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { r as serialiseJsonReport, t as buildJsonReport } from "./json-
|
|
1
|
+
import { r as serialiseJsonReport, t as buildJsonReport } from "./json-Bus6YhxB.js";
|
|
2
2
|
export { buildJsonReport, serialiseJsonReport };
|
|
@@ -131,7 +131,12 @@ const auditSchema = object({
|
|
|
131
131
|
* find something to audit. Written in the positive because that is the state
|
|
132
132
|
* being described, and because a config file has no flags to negate.
|
|
133
133
|
*/
|
|
134
|
-
build: optional(boolean())
|
|
134
|
+
build: optional(boolean()),
|
|
135
|
+
/**
|
|
136
|
+
* False is `--no-cache`: audit every page, reusing nothing an earlier run
|
|
137
|
+
* measured. Written in the positive for the same reason `build` is.
|
|
138
|
+
*/
|
|
139
|
+
cache: optional(boolean())
|
|
135
140
|
});
|
|
136
141
|
const configSchema = object({
|
|
137
142
|
site: object({
|
package/dist/nuxt/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as IntegrationOptions, t as BuildAuditError } from "../run-
|
|
1
|
+
import { n as IntegrationOptions, t as BuildAuditError } from "../run-BK2blxMI.js";
|
|
2
2
|
//#region src/nuxt/index.d.ts
|
|
3
3
|
/** The part of the Nitro instance this reads, handed over by `nitro:init`. */
|
|
4
4
|
interface NitroLike {
|
package/dist/nuxt/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as auditBuild, r as stderrLogger, t as BuildAuditError } from "../run-
|
|
1
|
+
import { n as auditBuild, r as stderrLogger, t as BuildAuditError } from "../run-DrS0Komf.js";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
//#region src/nuxt/index.ts
|
|
4
4
|
function eaaKitModule(options = {}, nuxt) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { r as isFile } from "./fs-BmPtmFke.js";
|
|
2
|
-
import {
|
|
2
|
+
import { c as pageUrl, d as runOptions, f as shapeResults, n as DEFAULT_TAGS, o as failedPage } from "./result-B7_zVxAX.js";
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
4
|
import { stat } from "node:fs/promises";
|
|
5
5
|
import path from "node:path";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { r as isFile } from "./fs-BmPtmFke.js";
|
|
2
|
-
import {
|
|
2
|
+
import { c as pageUrl, o as failedPage } from "./result-B7_zVxAX.js";
|
|
3
3
|
import { Worker } from "node:worker_threads";
|
|
4
4
|
import { availableParallelism } from "node:os";
|
|
5
5
|
//#region src/audit/runners/pool.ts
|
|
@@ -105,8 +105,12 @@ async function runPooledAudit(pages, options = {}) {
|
|
|
105
105
|
if (!entry) return auditHere(pages, runnerOptions);
|
|
106
106
|
return runWorkers(pages, runnerOptions, Math.min(workers, pages.length), entry);
|
|
107
107
|
}
|
|
108
|
+
/**
|
|
109
|
+
* Audit in this process: the fallback for a run with no threads, and the sweep
|
|
110
|
+
* for pages the threads never reported on.
|
|
111
|
+
*/
|
|
108
112
|
async function auditHere(pages, options) {
|
|
109
|
-
const { runJsdomAudit } = await import("./jsdom-
|
|
113
|
+
const { runJsdomAudit } = await import("./jsdom-BUYuVJJm.js");
|
|
110
114
|
return runJsdomAudit(pages, options);
|
|
111
115
|
}
|
|
112
116
|
/**
|
|
@@ -1,6 +1,59 @@
|
|
|
1
1
|
import { o as impactRank } from "./impact-luGCnN8F.js";
|
|
2
2
|
import { t as elementFingerprint } from "./fingerprint-BjYV_0F7.js";
|
|
3
|
-
import {
|
|
3
|
+
import { s as findingElements } from "./result-B7_zVxAX.js";
|
|
4
|
+
//#region src/audit/completeness.ts
|
|
5
|
+
/**
|
|
6
|
+
* Fold what the collector knew together with what the engine managed.
|
|
7
|
+
*
|
|
8
|
+
* The audits carry the second half: a page with an `error` was collected and
|
|
9
|
+
* then not audited, and is as unmeasured as one that was never fetched.
|
|
10
|
+
*/
|
|
11
|
+
function runCompleteness(audits, collection) {
|
|
12
|
+
const errored = audits.filter((audit) => audit.error).length;
|
|
13
|
+
const reused = audits.filter((audit) => audit.reused !== void 0).length;
|
|
14
|
+
return {
|
|
15
|
+
...collection,
|
|
16
|
+
audited: audits.length - errored - reused,
|
|
17
|
+
reused,
|
|
18
|
+
errored,
|
|
19
|
+
complete: collection.unreachable.length === 0 && !collection.truncated && errored === 0
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* What a run reused, in one phrase, or nothing when it audited everything.
|
|
24
|
+
*
|
|
25
|
+
* Its own sentence rather than a clause in `missedParts`: nothing was missed
|
|
26
|
+
* here. The pages have verdicts; they were reached on an earlier day, on markup
|
|
27
|
+
* identical to today's, and a reader is entitled to know which.
|
|
28
|
+
*/
|
|
29
|
+
function reusedPart(completeness) {
|
|
30
|
+
if (completeness.reused === 0) return void 0;
|
|
31
|
+
const pages = completeness.reused === 1 ? "page" : "pages";
|
|
32
|
+
return `${completeness.reused} ${pages} unchanged since the last run, so the earlier result was reused`;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* What was missed, as phrases both reports print.
|
|
36
|
+
*
|
|
37
|
+
* Separate clauses rather than one total, for the same reason the coverage
|
|
38
|
+
* parts are: a page that could not be fetched and a page that could not be
|
|
39
|
+
* parsed are different problems with different fixes, and summing them would
|
|
40
|
+
* name neither.
|
|
41
|
+
*/
|
|
42
|
+
function missedParts(completeness) {
|
|
43
|
+
const parts = [];
|
|
44
|
+
if (completeness.unreachable.length > 0) parts.push(`${completeness.unreachable.length} could not be reached`);
|
|
45
|
+
if (completeness.errored > 0) parts.push(`${completeness.errored} could not be audited`);
|
|
46
|
+
if (completeness.truncated) parts.push("the run stopped at its page limit");
|
|
47
|
+
return parts;
|
|
48
|
+
}
|
|
49
|
+
/** How the pages were found, in words, for the run details both reports show. */
|
|
50
|
+
function discoveryLabel(discovery) {
|
|
51
|
+
switch (discovery) {
|
|
52
|
+
case "directory": return "files in the build directory";
|
|
53
|
+
case "sitemap": return "sitemap.xml and links";
|
|
54
|
+
case "links": return "links from the entry page";
|
|
55
|
+
}
|
|
56
|
+
}
|
|
4
57
|
/** Whether this element looks like one component rendered on many pages. */
|
|
5
58
|
function isShared(element) {
|
|
6
59
|
return element.pages.length >= 3;
|
|
@@ -296,44 +349,4 @@ function remediationFor(ruleId, framework) {
|
|
|
296
349
|
};
|
|
297
350
|
}
|
|
298
351
|
//#endregion
|
|
299
|
-
|
|
300
|
-
/**
|
|
301
|
-
* Fold what the collector knew together with what the engine managed.
|
|
302
|
-
*
|
|
303
|
-
* The audits carry the second half: a page with an `error` was collected and
|
|
304
|
-
* then not audited, and is as unmeasured as one that was never fetched.
|
|
305
|
-
*/
|
|
306
|
-
function runCompleteness(audits, collection) {
|
|
307
|
-
const errored = audits.filter((audit) => audit.error).length;
|
|
308
|
-
return {
|
|
309
|
-
...collection,
|
|
310
|
-
audited: audits.length - errored,
|
|
311
|
-
errored,
|
|
312
|
-
complete: collection.unreachable.length === 0 && !collection.truncated && errored === 0
|
|
313
|
-
};
|
|
314
|
-
}
|
|
315
|
-
/**
|
|
316
|
-
* What was missed, as phrases both reports print.
|
|
317
|
-
*
|
|
318
|
-
* Separate clauses rather than one total, for the same reason the coverage
|
|
319
|
-
* parts are: a page that could not be fetched and a page that could not be
|
|
320
|
-
* parsed are different problems with different fixes, and summing them would
|
|
321
|
-
* name neither.
|
|
322
|
-
*/
|
|
323
|
-
function missedParts(completeness) {
|
|
324
|
-
const parts = [];
|
|
325
|
-
if (completeness.unreachable.length > 0) parts.push(`${completeness.unreachable.length} could not be reached`);
|
|
326
|
-
if (completeness.errored > 0) parts.push(`${completeness.errored} could not be audited`);
|
|
327
|
-
if (completeness.truncated) parts.push("the run stopped at its page limit");
|
|
328
|
-
return parts;
|
|
329
|
-
}
|
|
330
|
-
/** How the pages were found, in words, for the run details both reports show. */
|
|
331
|
-
function discoveryLabel(discovery) {
|
|
332
|
-
switch (discovery) {
|
|
333
|
-
case "directory": return "files in the build directory";
|
|
334
|
-
case "sitemap": return "sitemap.xml and links";
|
|
335
|
-
case "links": return "links from the entry page";
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
//#endregion
|
|
339
|
-
export { blindRules as a, isShared as c, remediationFor as i, issueTotals as l, missedParts as n, coverageParts as o, runCompleteness as r, groupIssues as s, discoveryLabel as t };
|
|
352
|
+
export { isShared as a, missedParts as c, groupIssues as i, reusedPart as l, blindRules as n, issueTotals as o, coverageParts as r, discoveryLabel as s, remediationFor as t, runCompleteness as u };
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { n as IMPACT_LEVELS, o as impactRank } from "./impact-luGCnN8F.js";
|
|
2
2
|
import { c as nullable, h as string, l as number, m as safeParse, p as record, s as isoDateTime, t as array, u as object, y as withDefault } from "./schema-DJSF4K05.js";
|
|
3
|
-
import { u as STATEMENT_LOCALES } from "./load-
|
|
3
|
+
import { u as STATEMENT_LOCALES } from "./load-BaWMa-G_.js";
|
|
4
4
|
import { n as isDirectory } from "./fs-BmPtmFke.js";
|
|
5
5
|
import { a as isoDate, i as escapeText, n as count, r as escapeAttribute, s as standardsReference } from "./text-BF1LHMiV.js";
|
|
6
6
|
import { t as TOOL_VERSION } from "./version-B3v4rNoG.js";
|
|
7
|
+
import { t as WCAG22_AA_CRITERIA } from "./criteria-CnPJKGeb.js";
|
|
7
8
|
import { readFile, readdir } from "node:fs/promises";
|
|
8
9
|
import path from "node:path";
|
|
9
10
|
import { fileURLToPath } from "node:url";
|
|
@@ -513,7 +514,7 @@ async function renderStatement(config, options = {}) {
|
|
|
513
514
|
const country = options.country ?? config.enforcement.country;
|
|
514
515
|
const locale = options.locale ?? defaultLocale(config);
|
|
515
516
|
const template = `${country.toLowerCase()}.${locale}`;
|
|
516
|
-
const markdown = tidy(renderTemplate(await loadTemplate(country, locale), buildScope(config, locale, options
|
|
517
|
+
const markdown = tidy(renderTemplate(await loadTemplate(country, locale), buildScope(config, locale, options)));
|
|
517
518
|
return {
|
|
518
519
|
markdown,
|
|
519
520
|
html: toHtmlDocument(markdown, {
|
|
@@ -543,7 +544,9 @@ function defaultLocale(config) {
|
|
|
543
544
|
* template, which keeps the template language trivial and puts the mapping
|
|
544
545
|
* somewhere that can be typechecked.
|
|
545
546
|
*/
|
|
546
|
-
function buildScope(config, locale,
|
|
547
|
+
function buildScope(config, locale, options) {
|
|
548
|
+
const audit = options.audit;
|
|
549
|
+
const review = options.review ? toReviewScope(options.review, locale) : void 0;
|
|
547
550
|
const issues = [...config.compliance.knownIssues.map((issue) => toIssueScope(issue, locale)), ...(audit?.findings ?? []).map((finding) => toFindingScope(finding, config.compliance.auditReason))];
|
|
548
551
|
return {
|
|
549
552
|
site: { ...config.site },
|
|
@@ -560,6 +563,8 @@ function buildScope(config, locale, audit) {
|
|
|
560
563
|
},
|
|
561
564
|
audit: audit ? toAuditScope(audit, locale) : void 0,
|
|
562
565
|
hasAudit: audit !== void 0,
|
|
566
|
+
review,
|
|
567
|
+
hasReview: review !== void 0,
|
|
563
568
|
hasKnownIssues: issues.length > 0,
|
|
564
569
|
hasNoKnownIssues: issues.length === 0
|
|
565
570
|
};
|
|
@@ -585,6 +590,39 @@ function toAuditScope(audit, locale) {
|
|
|
585
590
|
checkedOnFormatted: formatDate(audit.generatedAt.slice(0, 10), locale)
|
|
586
591
|
};
|
|
587
592
|
}
|
|
593
|
+
/**
|
|
594
|
+
* What a person's review contributes to the "preparation" section.
|
|
595
|
+
*
|
|
596
|
+
* One fact: how many of WCAG 2.2's success criteria at A and AA somebody
|
|
597
|
+
* checked by hand, and the last day one of those checks was recorded. It is
|
|
598
|
+
* there because the automated sentences beside it describe a run that cannot
|
|
599
|
+
* reach 34 of those 55 criteria, and a reader with no way to tell an unchecked
|
|
600
|
+
* criterion from an unchecked-by-machine one is being told less than the truth.
|
|
601
|
+
*
|
|
602
|
+
* What it never says is what the review concluded. A recorded result is a claim
|
|
603
|
+
* by a person, and the place for a claim in this document is the barrier list,
|
|
604
|
+
* where a person writes it in their own words. Turning `not-met` into a
|
|
605
|
+
* conformance sentence here would be this tool putting a legal position in
|
|
606
|
+
* somebody's mouth.
|
|
607
|
+
*
|
|
608
|
+
* Returns undefined for a record nobody has answered yet — the ordinary state
|
|
609
|
+
* of the file `eaa-kit checklist` has just written. Generating a worksheet is
|
|
610
|
+
* not doing the review, and the audit report refuses to count it for the same
|
|
611
|
+
* reason.
|
|
612
|
+
*/
|
|
613
|
+
function toReviewScope(record, locale) {
|
|
614
|
+
const answered = Object.values(record.criteria).filter((entry) => entry.result !== "unreviewed");
|
|
615
|
+
if (answered.length === 0) return void 0;
|
|
616
|
+
const latest = answered.map((entry) => entry.reviewedOn).filter((on) => on !== void 0).sort().at(-1);
|
|
617
|
+
return {
|
|
618
|
+
answered: answered.length,
|
|
619
|
+
total: WCAG22_AA_CRITERIA.length,
|
|
620
|
+
isSingle: answered.length === 1,
|
|
621
|
+
isPlural: answered.length > 1,
|
|
622
|
+
hasDate: latest !== void 0,
|
|
623
|
+
checkedOnFormatted: latest === void 0 ? "" : formatDate(latest, locale)
|
|
624
|
+
};
|
|
625
|
+
}
|
|
588
626
|
function toIssueScope(issue, locale) {
|
|
589
627
|
return {
|
|
590
628
|
...reasonScope(issue.reason),
|
|
@@ -336,4 +336,4 @@ function enClauses(tags) {
|
|
|
336
336
|
return [...clauses].sort();
|
|
337
337
|
}
|
|
338
338
|
//#endregion
|
|
339
|
-
export {
|
|
339
|
+
export { enClauses as a, pageUrl as c, runOptions as d, shapeResults as f, blindRulesInScope as i, ruleOutcomes as l, uniqueRuleOutcomes as m, DEFAULT_TAGS as n, failedPage as o, successCriteria as p, ENGINE_BLIND_RULES as r, findingElements as s, DEFAULT_PAGE_TIMEOUT_MS as t, runEngine as u };
|
|
@@ -42,6 +42,14 @@ interface IntegrationOptions {
|
|
|
42
42
|
format?: OutputFormat;
|
|
43
43
|
/** Write the report here instead of the build log. */
|
|
44
44
|
output?: string;
|
|
45
|
+
/**
|
|
46
|
+
* False audits every page, reusing nothing an earlier build measured.
|
|
47
|
+
*
|
|
48
|
+
* The cache is on by default here as everywhere, and a build is where it pays
|
|
49
|
+
* best: most builds change a handful of pages. Turn it off for a release
|
|
50
|
+
* build that should answer from nothing but the files in front of it.
|
|
51
|
+
*/
|
|
52
|
+
cache?: boolean;
|
|
45
53
|
/**
|
|
46
54
|
* Report without failing the build. For the week it takes to adopt this on a
|
|
47
55
|
* site that already exists — a baseline is the honest way to go green after
|
|
@@ -30,12 +30,16 @@ var BuildAuditError = class extends Error {
|
|
|
30
30
|
* when it should not.
|
|
31
31
|
*/
|
|
32
32
|
async function auditBuild(directory, options, logger) {
|
|
33
|
-
const { enabled, failBuild, ...
|
|
33
|
+
const { enabled, failBuild, cache, ...rest } = options;
|
|
34
|
+
const auditOptions = {
|
|
35
|
+
...rest,
|
|
36
|
+
...cache === false ? { noCache: true } : {}
|
|
37
|
+
};
|
|
34
38
|
if (enabled === false) {
|
|
35
39
|
logger.info("skipped (enabled: false)");
|
|
36
40
|
return;
|
|
37
41
|
}
|
|
38
|
-
const { runAuditCommand } = await import("./audit-
|
|
42
|
+
const { runAuditCommand } = await import("./audit-Bwm1xBdJ.js");
|
|
39
43
|
const { exitCode } = await runAuditCommand(directory, auditOptions);
|
|
40
44
|
if (exitCode === 0) {
|
|
41
45
|
logger.info("no violations at or above the threshold");
|
|
@@ -2,8 +2,8 @@ import { s as isImpactLevel } from "./impact-luGCnN8F.js";
|
|
|
2
2
|
import { s as standardsReference } from "./text-BF1LHMiV.js";
|
|
3
3
|
import { t as TOOL_VERSION } from "./version-B3v4rNoG.js";
|
|
4
4
|
import { t as elementFingerprint } from "./fingerprint-BjYV_0F7.js";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
5
|
+
import { m as uniqueRuleOutcomes, s as findingElements, u as runEngine } from "./result-B7_zVxAX.js";
|
|
6
|
+
import { t as buildCoverage } from "./coverage-cb5kPp48.js";
|
|
7
7
|
import path from "node:path";
|
|
8
8
|
//#region src/audit/report/sarif.ts
|
|
9
9
|
const SARIF_VERSION = "2.1.0";
|
|
@@ -155,6 +155,7 @@ function summaryProperties(audits, completeness, review) {
|
|
|
155
155
|
complete: completeness.complete,
|
|
156
156
|
discovery: completeness.discovery,
|
|
157
157
|
pagesAudited: completeness.audited,
|
|
158
|
+
pagesReused: completeness.reused,
|
|
158
159
|
pagesErrored: completeness.errored,
|
|
159
160
|
pagesUnreachable: completeness.unreachable.length,
|
|
160
161
|
truncated: completeness.truncated
|
|
@@ -64,6 +64,20 @@ Grundlage ist eine Selbstbewertung durch {{ provider.legalName }}.
|
|
|
64
64
|
Grundlage ist eine Prüfung durch Dritte.
|
|
65
65
|
{{/if}}
|
|
66
66
|
|
|
67
|
+
{{#if review.isSingle}}
|
|
68
|
+
Eines der {{ review.total }} Erfolgskriterien der WCAG 2.2 (Stufen A und AA) wurde manuell
|
|
69
|
+
geprüft.
|
|
70
|
+
{{/if}}
|
|
71
|
+
{{#if review.isPlural}}
|
|
72
|
+
{{ review.answered }} der {{ review.total }} Erfolgskriterien der WCAG 2.2 (Stufen A und AA)
|
|
73
|
+
wurden manuell geprüft.
|
|
74
|
+
{{/if}}
|
|
75
|
+
{{#if review.hasDate}}
|
|
76
|
+
Die jüngste dieser manuellen Prüfungen erfolgte am {{ review.checkedOnFormatted }}.
|
|
77
|
+
{{/if}}
|
|
78
|
+
{{#if hasReview}}
|
|
79
|
+
|
|
80
|
+
{{/if}}
|
|
67
81
|
{{#if audit.isSinglePage}}
|
|
68
82
|
Die automatisierte Prüfung vom {{ audit.checkedOnFormatted }} umfasste eine Seite dieser
|
|
69
83
|
Website.
|
|
@@ -63,6 +63,20 @@ It is based on a self-assessment carried out by {{ provider.legalName }}.
|
|
|
63
63
|
It is based on an assessment carried out by a third party.
|
|
64
64
|
{{/if}}
|
|
65
65
|
|
|
66
|
+
{{#if review.isSingle}}
|
|
67
|
+
One of the {{ review.total }} success criteria in WCAG 2.2 at Levels A and AA was checked
|
|
68
|
+
manually.
|
|
69
|
+
{{/if}}
|
|
70
|
+
{{#if review.isPlural}}
|
|
71
|
+
{{ review.answered }} of the {{ review.total }} success criteria in WCAG 2.2 at Levels A and
|
|
72
|
+
AA were checked manually.
|
|
73
|
+
{{/if}}
|
|
74
|
+
{{#if review.hasDate}}
|
|
75
|
+
The most recent of those manual checks was recorded on {{ review.checkedOnFormatted }}.
|
|
76
|
+
{{/if}}
|
|
77
|
+
{{#if hasReview}}
|
|
78
|
+
|
|
79
|
+
{{/if}}
|
|
66
80
|
{{#if audit.isSinglePage}}
|
|
67
81
|
The automated test run of {{ audit.checkedOnFormatted }} covered one page of this website.
|
|
68
82
|
{{/if}}
|
|
@@ -68,6 +68,20 @@ Grundlage ist eine Selbstbewertung durch {{ provider.legalName }}.
|
|
|
68
68
|
Grundlage ist eine Prüfung durch Dritte.
|
|
69
69
|
{{/if}}
|
|
70
70
|
|
|
71
|
+
{{#if review.isSingle}}
|
|
72
|
+
Eines der {{ review.total }} Erfolgskriterien der WCAG 2.2 (Stufen A und AA) wurde manuell
|
|
73
|
+
geprüft.
|
|
74
|
+
{{/if}}
|
|
75
|
+
{{#if review.isPlural}}
|
|
76
|
+
{{ review.answered }} der {{ review.total }} Erfolgskriterien der WCAG 2.2 (Stufen A und AA)
|
|
77
|
+
wurden manuell geprüft.
|
|
78
|
+
{{/if}}
|
|
79
|
+
{{#if review.hasDate}}
|
|
80
|
+
Die jüngste dieser manuellen Prüfungen erfolgte am {{ review.checkedOnFormatted }}.
|
|
81
|
+
{{/if}}
|
|
82
|
+
{{#if hasReview}}
|
|
83
|
+
|
|
84
|
+
{{/if}}
|
|
71
85
|
{{#if audit.isSinglePage}}
|
|
72
86
|
Die automatisierte Prüfung vom {{ audit.checkedOnFormatted }} umfasste eine Seite dieser
|
|
73
87
|
Website.
|
|
@@ -69,6 +69,20 @@ It is based on a self-assessment carried out by {{ provider.legalName }}.
|
|
|
69
69
|
It is based on an assessment carried out by a third party.
|
|
70
70
|
{{/if}}
|
|
71
71
|
|
|
72
|
+
{{#if review.isSingle}}
|
|
73
|
+
One of the {{ review.total }} success criteria in WCAG 2.2 at Levels A and AA was checked
|
|
74
|
+
manually.
|
|
75
|
+
{{/if}}
|
|
76
|
+
{{#if review.isPlural}}
|
|
77
|
+
{{ review.answered }} of the {{ review.total }} success criteria in WCAG 2.2 at Levels A and
|
|
78
|
+
AA were checked manually.
|
|
79
|
+
{{/if}}
|
|
80
|
+
{{#if review.hasDate}}
|
|
81
|
+
The most recent of those manual checks was recorded on {{ review.checkedOnFormatted }}.
|
|
82
|
+
{{/if}}
|
|
83
|
+
{{#if hasReview}}
|
|
84
|
+
|
|
85
|
+
{{/if}}
|
|
72
86
|
{{#if audit.isSinglePage}}
|
|
73
87
|
The automated test run of {{ audit.checkedOnFormatted }} covered one page of this website.
|
|
74
88
|
{{/if}}
|
|
@@ -64,6 +64,20 @@ Grundlage ist eine Selbstbewertung durch {{ provider.legalName }}.
|
|
|
64
64
|
Grundlage ist eine Prüfung durch Dritte.
|
|
65
65
|
{{/if}}
|
|
66
66
|
|
|
67
|
+
{{#if review.isSingle}}
|
|
68
|
+
Eines der {{ review.total }} Erfolgskriterien der WCAG 2.2 (Stufen A und AA) wurde manuell
|
|
69
|
+
geprüft.
|
|
70
|
+
{{/if}}
|
|
71
|
+
{{#if review.isPlural}}
|
|
72
|
+
{{ review.answered }} der {{ review.total }} Erfolgskriterien der WCAG 2.2 (Stufen A und AA)
|
|
73
|
+
wurden manuell geprüft.
|
|
74
|
+
{{/if}}
|
|
75
|
+
{{#if review.hasDate}}
|
|
76
|
+
Die jüngste dieser manuellen Prüfungen erfolgte am {{ review.checkedOnFormatted }}.
|
|
77
|
+
{{/if}}
|
|
78
|
+
{{#if hasReview}}
|
|
79
|
+
|
|
80
|
+
{{/if}}
|
|
67
81
|
{{#if audit.isSinglePage}}
|
|
68
82
|
Die automatisierte Prüfung vom {{ audit.checkedOnFormatted }} umfasste eine Seite dieser
|
|
69
83
|
Website.
|
|
@@ -64,6 +64,20 @@ It is based on a self-assessment carried out by {{ provider.legalName }}.
|
|
|
64
64
|
It is based on an assessment carried out by a third party.
|
|
65
65
|
{{/if}}
|
|
66
66
|
|
|
67
|
+
{{#if review.isSingle}}
|
|
68
|
+
One of the {{ review.total }} success criteria in WCAG 2.2 at Levels A and AA was checked
|
|
69
|
+
manually.
|
|
70
|
+
{{/if}}
|
|
71
|
+
{{#if review.isPlural}}
|
|
72
|
+
{{ review.answered }} of the {{ review.total }} success criteria in WCAG 2.2 at Levels A and
|
|
73
|
+
AA were checked manually.
|
|
74
|
+
{{/if}}
|
|
75
|
+
{{#if review.hasDate}}
|
|
76
|
+
The most recent of those manual checks was recorded on {{ review.checkedOnFormatted }}.
|
|
77
|
+
{{/if}}
|
|
78
|
+
{{#if hasReview}}
|
|
79
|
+
|
|
80
|
+
{{/if}}
|
|
67
81
|
{{#if audit.isSinglePage}}
|
|
68
82
|
The automated test run of {{ audit.checkedOnFormatted }} covered one page of this website.
|
|
69
83
|
{{/if}}
|
|
@@ -64,6 +64,20 @@ It is based on a self-assessment carried out by {{ provider.legalName }}.
|
|
|
64
64
|
It is based on an assessment carried out by a third party.
|
|
65
65
|
{{/if}}
|
|
66
66
|
|
|
67
|
+
{{#if review.isSingle}}
|
|
68
|
+
One of the {{ review.total }} success criteria in WCAG 2.2 at Levels A and AA was checked
|
|
69
|
+
manually.
|
|
70
|
+
{{/if}}
|
|
71
|
+
{{#if review.isPlural}}
|
|
72
|
+
{{ review.answered }} of the {{ review.total }} success criteria in WCAG 2.2 at Levels A and
|
|
73
|
+
AA were checked manually.
|
|
74
|
+
{{/if}}
|
|
75
|
+
{{#if review.hasDate}}
|
|
76
|
+
The most recent of those manual checks was recorded on {{ review.checkedOnFormatted }}.
|
|
77
|
+
{{/if}}
|
|
78
|
+
{{#if hasReview}}
|
|
79
|
+
|
|
80
|
+
{{/if}}
|
|
67
81
|
{{#if audit.isSinglePage}}
|
|
68
82
|
The automated test run of {{ audit.checkedOnFormatted }} covered one page of this website.
|
|
69
83
|
{{/if}}
|
|
@@ -64,6 +64,21 @@ Se basa en una autoevaluación realizada por {{ provider.legalName }}.
|
|
|
64
64
|
Se basa en una evaluación realizada por un tercero.
|
|
65
65
|
{{/if}}
|
|
66
66
|
|
|
67
|
+
{{#if review.isSingle}}
|
|
68
|
+
Uno de los {{ review.total }} criterios de conformidad de las WCAG 2.2 (niveles A y AA) se
|
|
69
|
+
comprobó manualmente.
|
|
70
|
+
{{/if}}
|
|
71
|
+
{{#if review.isPlural}}
|
|
72
|
+
{{ review.answered }} de los {{ review.total }} criterios de conformidad de las WCAG 2.2
|
|
73
|
+
(niveles A y AA) se comprobaron manualmente.
|
|
74
|
+
{{/if}}
|
|
75
|
+
{{#if review.hasDate}}
|
|
76
|
+
La más reciente de esas comprobaciones manuales se registró el
|
|
77
|
+
{{ review.checkedOnFormatted }}.
|
|
78
|
+
{{/if}}
|
|
79
|
+
{{#if hasReview}}
|
|
80
|
+
|
|
81
|
+
{{/if}}
|
|
67
82
|
{{#if audit.isSinglePage}}
|
|
68
83
|
El análisis automático del {{ audit.checkedOnFormatted }} abarcó una página de este sitio
|
|
69
84
|
web.
|
|
@@ -64,6 +64,20 @@ It is based on a self-assessment carried out by {{ provider.legalName }}.
|
|
|
64
64
|
It is based on an assessment carried out by a third party.
|
|
65
65
|
{{/if}}
|
|
66
66
|
|
|
67
|
+
{{#if review.isSingle}}
|
|
68
|
+
One of the {{ review.total }} success criteria in WCAG 2.2 at Levels A and AA was checked
|
|
69
|
+
manually.
|
|
70
|
+
{{/if}}
|
|
71
|
+
{{#if review.isPlural}}
|
|
72
|
+
{{ review.answered }} of the {{ review.total }} success criteria in WCAG 2.2 at Levels A and
|
|
73
|
+
AA were checked manually.
|
|
74
|
+
{{/if}}
|
|
75
|
+
{{#if review.hasDate}}
|
|
76
|
+
The most recent of those manual checks was recorded on {{ review.checkedOnFormatted }}.
|
|
77
|
+
{{/if}}
|
|
78
|
+
{{#if hasReview}}
|
|
79
|
+
|
|
80
|
+
{{/if}}
|
|
67
81
|
{{#if audit.isSinglePage}}
|
|
68
82
|
The automated test run of {{ audit.checkedOnFormatted }} covered one page of this website.
|
|
69
83
|
{{/if}}
|
|
@@ -64,6 +64,21 @@ Elle repose sur une auto-évaluation réalisée par {{ provider.legalName }}.
|
|
|
64
64
|
Elle repose sur une évaluation réalisée par un tiers.
|
|
65
65
|
{{/if}}
|
|
66
66
|
|
|
67
|
+
{{#if review.isSingle}}
|
|
68
|
+
Un des {{ review.total }} critères de succès des WCAG 2.2 (niveaux A et AA) a été vérifié
|
|
69
|
+
manuellement.
|
|
70
|
+
{{/if}}
|
|
71
|
+
{{#if review.isPlural}}
|
|
72
|
+
{{ review.answered }} des {{ review.total }} critères de succès des WCAG 2.2 (niveaux A et
|
|
73
|
+
AA) ont été vérifiés manuellement.
|
|
74
|
+
{{/if}}
|
|
75
|
+
{{#if review.hasDate}}
|
|
76
|
+
La plus récente de ces vérifications manuelles a été effectuée le
|
|
77
|
+
{{ review.checkedOnFormatted }}.
|
|
78
|
+
{{/if}}
|
|
79
|
+
{{#if hasReview}}
|
|
80
|
+
|
|
81
|
+
{{/if}}
|
|
67
82
|
{{#if audit.isSinglePage}}
|
|
68
83
|
Le test automatisé du {{ audit.checkedOnFormatted }} a porté sur une page de ce site.
|
|
69
84
|
{{/if}}
|
|
@@ -64,6 +64,20 @@ It is based on a self-assessment carried out by {{ provider.legalName }}.
|
|
|
64
64
|
It is based on an assessment carried out by a third party.
|
|
65
65
|
{{/if}}
|
|
66
66
|
|
|
67
|
+
{{#if review.isSingle}}
|
|
68
|
+
One of the {{ review.total }} success criteria in WCAG 2.2 at Levels A and AA was checked
|
|
69
|
+
manually.
|
|
70
|
+
{{/if}}
|
|
71
|
+
{{#if review.isPlural}}
|
|
72
|
+
{{ review.answered }} of the {{ review.total }} success criteria in WCAG 2.2 at Levels A and
|
|
73
|
+
AA were checked manually.
|
|
74
|
+
{{/if}}
|
|
75
|
+
{{#if review.hasDate}}
|
|
76
|
+
The most recent of those manual checks was recorded on {{ review.checkedOnFormatted }}.
|
|
77
|
+
{{/if}}
|
|
78
|
+
{{#if hasReview}}
|
|
79
|
+
|
|
80
|
+
{{/if}}
|
|
67
81
|
{{#if audit.isSinglePage}}
|
|
68
82
|
The automated test run of {{ audit.checkedOnFormatted }} covered one page of this website.
|
|
69
83
|
{{/if}}
|
|
@@ -64,6 +64,21 @@ Si basa su un'autovalutazione svolta da {{ provider.legalName }}.
|
|
|
64
64
|
Si basa su una valutazione svolta da terzi.
|
|
65
65
|
{{/if}}
|
|
66
66
|
|
|
67
|
+
{{#if review.isSingle}}
|
|
68
|
+
Uno dei {{ review.total }} criteri di successo delle WCAG 2.2 (livelli A e AA) è stato
|
|
69
|
+
verificato manualmente.
|
|
70
|
+
{{/if}}
|
|
71
|
+
{{#if review.isPlural}}
|
|
72
|
+
{{ review.answered }} dei {{ review.total }} criteri di successo delle WCAG 2.2 (livelli A e
|
|
73
|
+
AA) sono stati verificati manualmente.
|
|
74
|
+
{{/if}}
|
|
75
|
+
{{#if review.hasDate}}
|
|
76
|
+
La più recente di queste verifiche manuali è stata effettuata il
|
|
77
|
+
{{ review.checkedOnFormatted }}.
|
|
78
|
+
{{/if}}
|
|
79
|
+
{{#if hasReview}}
|
|
80
|
+
|
|
81
|
+
{{/if}}
|
|
67
82
|
{{#if audit.isSinglePage}}
|
|
68
83
|
Il test automatico del {{ audit.checkedOnFormatted }} ha riguardato una pagina di questo
|
|
69
84
|
sito.
|