automatica11y 0.3.3 → 0.4.1
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/AGENTS.md +2 -0
- package/README.md +39 -11
- package/package.json +5 -3
- package/skills/automatica11y/SKILL.md +3 -1
- package/skills/automatica11y-runner/SKILL.md +47 -14
- package/skills/automatica11y-runner/references/fixtures.md +38 -2
- package/src/commands/common.js +5 -2
- package/src/frameworks/index.js +42 -0
- package/src/frameworks/react.js +77 -0
- package/src/frameworks/vue.js +90 -0
- package/src/frameworks/wc.js +55 -0
- package/src/globals.d.ts +1 -0
- package/src/harness/bundle.js +7 -6
- package/src/harness/generate/dialects.js +64 -0
- package/src/harness/generate/index.js +12 -0
- package/src/harness/generate/jsx-recipes.js +224 -0
- package/src/harness/generate/jsx.js +76 -0
- package/src/harness/generate/kit.js +50 -0
- package/src/harness/generate/marking.js +64 -0
- package/src/harness/generate/probe.js +97 -0
- package/src/harness/generate/shared.js +12 -0
- package/src/harness/generate/wc-recipes.js +132 -0
- package/src/harness/npm-install.js +38 -7
- package/src/harness/settle.js +17 -0
- package/src/harness/storybook.js +1 -0
- package/src/harness/url.js +13 -3
- package/src/plan/classify.js +11 -4
- package/src/plan/mapping.js +10 -7
- package/src/plan/resolve-npm.js +15 -9
- package/src/plan/subpath.js +133 -0
- package/src/report/comparison.js +14 -9
- package/src/report/parts.js +36 -12
- package/src/run/audit-npm.js +118 -28
- package/src/run/generate-fixture.js +74 -0
- package/src/run/run-plan.js +19 -4
- package/src/run/summary.js +5 -0
- package/src/schema.js +30 -6
- package/src/tiers/computed/checks.js +44 -5
- package/src/tiers/computed/color.js +8 -0
- package/src/tiers/computed/index.js +2 -2
- package/src/tiers/computed/measure-kit.js +30 -10
- package/src/tiers/conditions/checks.js +283 -0
- package/src/tiers/conditions/index.js +30 -0
- package/src/tiers/conditions/kit.js +133 -0
- package/src/tiers/interactions/archetypes.js +111 -0
- package/src/tiers/interactions/helpers.js +56 -0
- package/src/tiers/interactions/index.js +16 -3
- package/src/harness/npm-react.js +0 -39
- package/src/harness/npm-wc.js +0 -30
|
@@ -66,13 +66,25 @@ export function makeContext(page) {
|
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
/** Run one check on a fresh page, so no check inherits another's state. */
|
|
69
|
-
export async function runCheck(browser, url, check, { timeoutMs = CHECK_TIMEOUT_MS, kits = [installHelpers] } = {}) {
|
|
69
|
+
export async function runCheck(browser, url, check, { timeoutMs = CHECK_TIMEOUT_MS, kits = [installHelpers], needsTrigger = true, waitUntil = /** @type {"load" | "networkidle"} */ ("load") } = {}) {
|
|
70
70
|
/** @type {Awaited<ReturnType<typeof openPage>> | null} */
|
|
71
71
|
let opened = null;
|
|
72
|
+
/** @type {Array<Awaited<ReturnType<typeof openPage>>>} */
|
|
73
|
+
const variants = [];
|
|
74
|
+
const beforeGoto = async (page) => { for (const kit of kits) await page.addInitScript(kit); };
|
|
72
75
|
try {
|
|
73
|
-
opened = await openPage(browser, url, { beforeGoto
|
|
76
|
+
opened = await openPage(browser, url, { beforeGoto, waitUntil });
|
|
74
77
|
const ctx = makeContext(opened.page);
|
|
75
|
-
|
|
78
|
+
/**
|
|
79
|
+
* Open the same page again with other browser settings (reduced motion, dark mode, a narrow window), and get a context for it.
|
|
80
|
+
* It closes with the check.
|
|
81
|
+
*/
|
|
82
|
+
ctx.variant = async (options) => {
|
|
83
|
+
const other = await openPage(browser, url, { ...options, beforeGoto, waitUntil });
|
|
84
|
+
variants.push(other);
|
|
85
|
+
return makeContext(other.page);
|
|
86
|
+
};
|
|
87
|
+
if (needsTrigger) await ctx.trigger.waitFor({ state: "attached", timeout: 3000 });
|
|
76
88
|
const outcome = await Promise.race([
|
|
77
89
|
check.run(ctx),
|
|
78
90
|
new Promise((_, reject) => setTimeout(() => reject(new Error(`The check took longer than ${timeoutMs / 1000} seconds.`)), timeoutMs)),
|
|
@@ -82,6 +94,7 @@ export async function runCheck(browser, url, check, { timeoutMs = CHECK_TIMEOUT_
|
|
|
82
94
|
return { name: check.name, criteria: check.criteria, result: "error", detail: `The check couldn't finish: ${(error instanceof Error ? error.message : String(error)).split("\n")[0]}` };
|
|
83
95
|
} finally {
|
|
84
96
|
await opened?.close();
|
|
97
|
+
for (const other of variants) await other.close();
|
|
85
98
|
}
|
|
86
99
|
}
|
|
87
100
|
|
package/src/harness/npm-react.js
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
/** React flavor: the entry files and button and link templates that go into a bundle. */
|
|
2
|
-
|
|
3
|
-
/** Mounts a fixture's default export. */
|
|
4
|
-
export const entry = (fixturePath, _pkg) => `import { createElement } from "react";
|
|
5
|
-
import { createRoot } from "react-dom/client";
|
|
6
|
-
import Fixture from ${JSON.stringify(fixturePath)};
|
|
7
|
-
const libA11y = new URLSearchParams(location.search).get("libA11y") === "on";
|
|
8
|
-
createRoot(document.getElementById("root")).render(createElement(Fixture, { libA11y }));
|
|
9
|
-
`;
|
|
10
|
-
|
|
11
|
-
/** Loads the whole package, lists its exports, and records compound parts such as Dialog.Trigger. */
|
|
12
|
-
export const discoverEntry = (pkg) => `import * as lib from ${JSON.stringify(pkg)};
|
|
13
|
-
const out = [];
|
|
14
|
-
for (const name of Object.keys(lib)) {
|
|
15
|
-
const value = lib[name];
|
|
16
|
-
const type = typeof value;
|
|
17
|
-
if (value === null || (type !== "function" && type !== "object")) continue;
|
|
18
|
-
const parts = Object.keys(value).filter((key) => /^[A-Z]/.test(key)).slice(0, 30);
|
|
19
|
-
out.push({ name, type, parts });
|
|
20
|
-
}
|
|
21
|
-
window.__a11yExports = out;
|
|
22
|
-
`;
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* A fixture for the simple archetypes, from the export name alone.
|
|
26
|
-
* Compound components (dialog, tabs, menu) can't be guessed, so they need a fixture someone writes.
|
|
27
|
-
*/
|
|
28
|
-
export function template(archetype, pkg, exportName) {
|
|
29
|
-
const body = {
|
|
30
|
-
button: `<Component data-a11y-trigger data-a11y-root type="button">Save</Component>`,
|
|
31
|
-
link: `<Component data-a11y-trigger data-a11y-root href="#top">Read more</Component>`,
|
|
32
|
-
}[archetype];
|
|
33
|
-
if (!body) return null;
|
|
34
|
-
return `import { ${exportName} as Component } from ${JSON.stringify(pkg)};
|
|
35
|
-
export default function Fixture() {
|
|
36
|
-
return ${body};
|
|
37
|
-
}
|
|
38
|
-
`;
|
|
39
|
-
}
|
package/src/harness/npm-wc.js
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/** Web component flavor: framework-free entries and templates. */
|
|
2
|
-
|
|
3
|
-
/** Loads the package so its custom elements get defined, then calls the fixture's default export, `mount(container)`. */
|
|
4
|
-
export const entry = (fixturePath, pkg) => `import ${JSON.stringify(pkg)};
|
|
5
|
-
import mount from ${JSON.stringify(fixturePath)};
|
|
6
|
-
const libA11y = new URLSearchParams(location.search).get("libA11y") === "on";
|
|
7
|
-
await mount(document.getElementById("root"), { libA11y });
|
|
8
|
-
`;
|
|
9
|
-
|
|
10
|
-
/** Loads the whole package. The page's init script records every custom element the package defines. */
|
|
11
|
-
export const discoverEntry = (pkg) => `import * as lib from ${JSON.stringify(pkg)};
|
|
12
|
-
window.__a11yExports = Object.keys(lib).map((name) => ({ name, type: typeof lib[name], parts: [] }));
|
|
13
|
-
`;
|
|
14
|
-
|
|
15
|
-
/** A fixture for the simple archetypes, from the tag name alone. */
|
|
16
|
-
export function template(archetype, tag) {
|
|
17
|
-
const attrs = {
|
|
18
|
-
button: `el.textContent = "Save";`,
|
|
19
|
-
link: `el.setAttribute("href", "#top");\n el.textContent = "Read more";`,
|
|
20
|
-
}[archetype];
|
|
21
|
-
if (!attrs) return null;
|
|
22
|
-
return `export default function mount(container) {
|
|
23
|
-
const el = document.createElement(${JSON.stringify(tag)});
|
|
24
|
-
el.setAttribute("data-a11y-trigger", "");
|
|
25
|
-
el.setAttribute("data-a11y-root", "");
|
|
26
|
-
${attrs}
|
|
27
|
-
container.append(el);
|
|
28
|
-
}
|
|
29
|
-
`;
|
|
30
|
-
}
|