From 87c25db9d8181c786a0c7c536398bbf217322731 Mon Sep 17 00:00:00 2001 From: j-mendez Date: Sat, 9 Mar 2024 12:39:45 -0500 Subject: [PATCH] chore(rules): add rule split by locales --- fast_htmlcs/HTMLCS.ts | 6 +- fast_htmlcs/Standards/Section508/Sniffs/D.ts | 2 +- kayle/bench/fast_axecore-playwright.ts | 2 +- kayle/bench/fast_htmlcs-playwright.ts | 2 +- kayle/builder/build-extension.ts | 2 +- kayle/builder/build-rules.ts | 163 +- kayle/builder/htmlcs-rule-map.ts | 23 +- kayle/lib/action.ts | 22 +- kayle/lib/auto.ts | 8 +- kayle/lib/config.ts | 10 +- kayle/lib/index.ts | 4 +- kayle/lib/kayle.ts | 16 +- kayle/lib/lint.ts | 4 +- kayle/lib/rules/ar/axe-rules.ts | 978 + kayle/lib/rules/ar/htmlcs-rules.ts | 3105 +++ kayle/lib/rules/axe-rules.ts | 996 - kayle/lib/rules/da/axe-rules.ts | 960 + kayle/lib/rules/da/htmlcs-rules.ts | 12491 +++++++++ kayle/lib/rules/de/axe-rules.ts | 1035 + kayle/lib/rules/de/htmlcs-rules.ts | 23418 +++++++++++++++++ kayle/lib/rules/en/axe-rules.ts | 996 + kayle/lib/rules/en/htmlcs-rules.ts | 20296 ++++++++++++++ kayle/lib/rules/es/axe-rules.ts | 1021 + kayle/lib/rules/es/htmlcs-rules.ts | 14061 ++++++++++ kayle/lib/rules/eu/axe-rules.ts | 996 + kayle/lib/rules/eu/htmlcs-rules.ts | 10930 ++++++++ kayle/lib/rules/fr/axe-rules.ts | 1024 + kayle/lib/rules/fr/htmlcs-rules.ts | 1565 ++ kayle/lib/rules/he/axe-rules.ts | 977 + kayle/lib/rules/he/htmlcs-rules.ts | 15613 +++++++++++ kayle/lib/rules/htmlcs-rules.ts | 1564 -- kayle/lib/rules/index.ts | 34 + kayle/lib/rules/it/axe-rules.ts | 996 + kayle/lib/rules/it/htmlcs-rules.ts | 6247 +++++ kayle/lib/rules/ja/axe-rules.ts | 1010 + kayle/lib/rules/ja/htmlcs-rules.ts | 4626 ++++ kayle/lib/rules/ko/axe-rules.ts | 1008 + kayle/lib/rules/ko/htmlcs-rules.ts | 18687 +++++++++++++ kayle/lib/rules/nl/axe-rules.ts | 996 + kayle/lib/rules/nl/htmlcs-rules.ts | 7803 ++++++ kayle/lib/rules/no_NB/axe-rules.ts | 996 + kayle/lib/rules/no_NB/htmlcs-rules.ts | 9369 +++++++ kayle/lib/rules/pl/axe-rules.ts | 992 + kayle/lib/rules/pl/htmlcs-rules.ts | 21857 +++++++++++++++ kayle/lib/rules/pt_BR/axe-rules.ts | 996 + kayle/lib/rules/pt_BR/htmlcs-rules.ts | 17174 ++++++++++++ kayle/lib/rules/zh_CN/axe-rules.ts | 996 + kayle/lib/rules/zh_CN/htmlcs-rules.ts | 5358 ++++ kayle/lib/rules/zh_TW/axe-rules.ts | 996 + kayle/lib/rules/zh_TW/htmlcs-rules.ts | 5043 ++++ kayle/lib/runner-js.ts | 2 +- kayle/lib/runner.ts | 10 +- kayle/lib/runners/axe.ts | 10 +- kayle/lib/runners/htmlcs.ts | 8 +- kayle/lib/utils/adblock.ts | 4 +- kayle/lib/utils/cdp-blocking.ts | 6 +- kayle/lib/utils/go-to-page.ts | 4 +- kayle/lib/utils/resource-ignore.ts | 2 +- kayle/lib/wasm/extract.ts | 2 +- kayle/lib/watcher.ts | 2 +- kayle/package.json | 2 +- kayle/tests/basic-axe-playwright.spec.ts | 6 +- kayle/tests/basic-htmlcs-playwright.spec.ts | 6 +- kayle/tests/basic-playwright.spec.ts | 6 +- kayle/tests/clips-playwright.spec.ts | 6 +- kayle/tests/extend-runner.ts | 2 +- kayle/tests/extension.ts | 2 +- kayle/tests/i18n.ts | 2 +- kayle/tests/ignore-rules.ts | 8 +- kayle/tests/innate-playwright.spec.ts | 2 +- kayle/tests/innate.ts | 4 +- kayle/tests/wasm.ts | 2 +- 72 files changed, 214856 insertions(+), 2716 deletions(-) create mode 100644 kayle/lib/rules/ar/axe-rules.ts create mode 100644 kayle/lib/rules/ar/htmlcs-rules.ts delete mode 100644 kayle/lib/rules/axe-rules.ts create mode 100644 kayle/lib/rules/da/axe-rules.ts create mode 100644 kayle/lib/rules/da/htmlcs-rules.ts create mode 100644 kayle/lib/rules/de/axe-rules.ts create mode 100644 kayle/lib/rules/de/htmlcs-rules.ts create mode 100644 kayle/lib/rules/en/axe-rules.ts create mode 100644 kayle/lib/rules/en/htmlcs-rules.ts create mode 100644 kayle/lib/rules/es/axe-rules.ts create mode 100644 kayle/lib/rules/es/htmlcs-rules.ts create mode 100644 kayle/lib/rules/eu/axe-rules.ts create mode 100644 kayle/lib/rules/eu/htmlcs-rules.ts create mode 100644 kayle/lib/rules/fr/axe-rules.ts create mode 100644 kayle/lib/rules/fr/htmlcs-rules.ts create mode 100644 kayle/lib/rules/he/axe-rules.ts create mode 100644 kayle/lib/rules/he/htmlcs-rules.ts delete mode 100644 kayle/lib/rules/htmlcs-rules.ts create mode 100644 kayle/lib/rules/index.ts create mode 100644 kayle/lib/rules/it/axe-rules.ts create mode 100644 kayle/lib/rules/it/htmlcs-rules.ts create mode 100644 kayle/lib/rules/ja/axe-rules.ts create mode 100644 kayle/lib/rules/ja/htmlcs-rules.ts create mode 100644 kayle/lib/rules/ko/axe-rules.ts create mode 100644 kayle/lib/rules/ko/htmlcs-rules.ts create mode 100644 kayle/lib/rules/nl/axe-rules.ts create mode 100644 kayle/lib/rules/nl/htmlcs-rules.ts create mode 100644 kayle/lib/rules/no_NB/axe-rules.ts create mode 100644 kayle/lib/rules/no_NB/htmlcs-rules.ts create mode 100644 kayle/lib/rules/pl/axe-rules.ts create mode 100644 kayle/lib/rules/pl/htmlcs-rules.ts create mode 100644 kayle/lib/rules/pt_BR/axe-rules.ts create mode 100644 kayle/lib/rules/pt_BR/htmlcs-rules.ts create mode 100644 kayle/lib/rules/zh_CN/axe-rules.ts create mode 100644 kayle/lib/rules/zh_CN/htmlcs-rules.ts create mode 100644 kayle/lib/rules/zh_TW/axe-rules.ts create mode 100644 kayle/lib/rules/zh_TW/htmlcs-rules.ts diff --git a/fast_htmlcs/HTMLCS.ts b/fast_htmlcs/HTMLCS.ts index 2f031fcb..c1751505 100755 --- a/fast_htmlcs/HTMLCS.ts +++ b/fast_htmlcs/HTMLCS.ts @@ -384,7 +384,9 @@ _global.HTMLCS = new (function () { if (options.include && options.include.length > 0) { // Included sniffs. ruleSet.sniffs = options.include; - } else if (options.exclude) { + } + + if (options.exclude) { // Excluded sniffs. for (const exclude of options.exclude) { // @ts-ignore @@ -423,7 +425,7 @@ _global.HTMLCS = new (function () { standard, sniffs.shift(), function () { - _registerSniffs(standard, sniffs, callback, failCallback); + _registerSniffs(standard, sniffs, callback, failCallback); }, failCallback ); diff --git a/fast_htmlcs/Standards/Section508/Sniffs/D.ts b/fast_htmlcs/Standards/Section508/Sniffs/D.ts index 19eb310e..348b5df1 100644 --- a/fast_htmlcs/Standards/Section508/Sniffs/D.ts +++ b/fast_htmlcs/Standards/Section508/Sniffs/D.ts @@ -28,7 +28,7 @@ _global.HTMLCS_Section508_Sniffs_D = { _global.HTMLCS_WCAG2AAA_Sniffs_Principle1_Guideline1_3_1_3_1.testPresentationMarkup( top - ) + ); this.testHeadingOrder(top); // Look for any script elements, and fire off another notice regarding diff --git a/kayle/bench/fast_axecore-playwright.ts b/kayle/bench/fast_axecore-playwright.ts index bace8587..9f2707e4 100644 --- a/kayle/bench/fast_axecore-playwright.ts +++ b/kayle/bench/fast_axecore-playwright.ts @@ -53,7 +53,7 @@ async function launchBench() { unit: "OPS/S", value: 1000 / avg, }, - ]), + ]) ); } diff --git a/kayle/bench/fast_htmlcs-playwright.ts b/kayle/bench/fast_htmlcs-playwright.ts index 08925d20..fc495d85 100644 --- a/kayle/bench/fast_htmlcs-playwright.ts +++ b/kayle/bench/fast_htmlcs-playwright.ts @@ -53,7 +53,7 @@ async function launchBench() { unit: "OPS/S", value: 1000 / avg, }, - ]), + ]) ); } diff --git a/kayle/builder/build-extension.ts b/kayle/builder/build-extension.ts index c28ab6b3..91cdbeda 100644 --- a/kayle/builder/build-extension.ts +++ b/kayle/builder/build-extension.ts @@ -52,7 +52,7 @@ window.addEventListener("kayle_send", async (event) => { writeFileSync( `${ext}/content-script.js`, - `${extensionRunner}\n${extensionAxe}\n${extensionHtmlcs}\n${extensionRawEnd}`, + `${extensionRunner}\n${extensionAxe}\n${extensionHtmlcs}\n${extensionRawEnd}` ); const extensionManifest = `{ diff --git a/kayle/builder/build-rules.ts b/kayle/builder/build-rules.ts index f6a4a3e3..31ee54e9 100644 --- a/kayle/builder/build-rules.ts +++ b/kayle/builder/build-rules.ts @@ -1,6 +1,8 @@ import { chromium } from "playwright"; -import { Standard, kayle } from "kayle"; -import { writeFile } from "fs/promises"; +import { Standard, kayle, htmlcsLocales, axeLocales } from "kayle"; +import { writeFile, mkdir } from "fs/promises"; +import { existsSync } from "node:fs"; + import { format } from "prettier"; import { htmlcsRuleMap } from "./htmlcs-rule-map"; import { processParams } from "./build-htmlcs-params"; @@ -8,84 +10,121 @@ import type { Rule } from "./build-types"; (async () => { const browser = await chromium.launch({ headless: true }); - const page = await browser.newPage(); - page.on("console", (msg) => console.log("PAGE LOG:", msg.text())); - - const fast_htmlcs_rules: Rule[] = []; - const fast_axe_rules: Rule[] = []; - - // inject the scripts - await kayle( - { - page, - browser, - runners: ["htmlcs", "axe"], - html: ">

Build Rules list

", - standard: Standard.WCAG2AA, - origin: "https://www.example.com", - }, - true, - ); - const paramList = await processParams(); + const pConfig = { + singleQuote: true, + semi: false, + parser: "babel", + }; - await page.evaluate((o) => { - window.paramList = o; - }, paramList); + const runBuildRules = async (language: string) => { + const page = await browser.newPage(); - await page.addScriptTag({ - content: `window.htmlcsRuleMap = ${htmlcsRuleMap.toString()};`, - }); + const fast_htmlcs_rules: Rule[] = []; + const fast_axe_rules: Rule[] = []; - await page.exposeFunction("pushHtmlcsRule", (t: Rule) => - fast_htmlcs_rules.push(t), - ); + // inject the scripts + await kayle( + { + page, + browser, + runners: ["htmlcs", "axe"], + html: "

Build Rules list

", + standard: Standard.WCAG2AA, + origin: "https://www.example.com", + language, + }, + true + ); - await page.exposeFunction("pushAxeRule", (t: Rule) => fast_axe_rules.push(t)); + const paramList = await processParams(); - await page.evaluate(() => { - for (const r of window.axe.getRules()) { - window.pushAxeRule(r); - } - for (const k of window.paramList) { - if (k && k.length >= 4) { - window.pushHtmlcsRule(window.htmlcsRuleMap(k)); + await page.evaluate((o) => { + window.paramList = o; + }, paramList); + + await page.addScriptTag({ + content: `window.htmlcsRuleMap = ${htmlcsRuleMap.toString()};`, + }); + + await page.exposeFunction("pushHtmlcsRule", (t: Rule) => + fast_htmlcs_rules.push(t) + ); + + await page.exposeFunction("pushAxeRule", (t: Rule) => + fast_axe_rules.push(t) + ); + + await page.evaluate(() => { + for (const r of window.axe.getRules()) { + window.pushAxeRule(r); + } + for (const k of window.paramList) { + if (k && k.length >= 4) { + window.pushHtmlcsRule(window.htmlcsRuleMap(k)); + } } + }); + + if (!existsSync(`./lib/rules/${language}`)) { + await mkdir(`./lib/rules/${language}`); } - }); - const pConfig = { - singleQuote: true, - semi: false, - parser: "babel", - }; + const DNE = "THIS FILE WAS CREATED DYNAMICALLY - DO NOT EDIT"; - const DNE = "THIS FILE WAS CREATED DYNAMICALLY - DO NOT EDIT"; + await writeFile( + `./lib/rules/${language}/htmlcs-rules.ts`, + Buffer.from( + await format( + `/* ${DNE} */\nexport const htmlcsRules = ${JSON.stringify( + fast_htmlcs_rules.filter((r) => r.description) + )};`, + pConfig + ) + ), + "utf8" + ); - await writeFile( - "./lib/rules/htmlcs-rules.ts", - Buffer.from( - await format( - `/* ${DNE} */\nexport const htmlcsRules = ${JSON.stringify( - fast_htmlcs_rules.filter((r) => r.description), - )};`, - pConfig, + await writeFile( + `./lib/rules/${language}/axe-rules.ts`, + Buffer.from( + await format( + `/* ${DNE} */\nexport const axeRules = ${JSON.stringify( + fast_axe_rules + )};`, + pConfig + ) ), - ), - "utf8", + "utf8" + ); + + await page.close({ + runBeforeUnload: true, + }); + }; + + const localesList: string[] = Array.from( + new Set(htmlcsLocales.concat(axeLocales)) ); + localesList.push("en"); + + await Promise.all(localesList.map((r) => runBuildRules(r))); + await writeFile( - "./lib/rules/axe-rules.ts", + `./lib/rules/index.ts`, Buffer.from( await format( - `/* ${DNE} */\nexport const axeRules = ${JSON.stringify( - fast_axe_rules, - )};`, - pConfig, - ), + localesList + .map((l) => { + return `export { axeRules as axeRules${l.toUpperCase()} } from "./${l}/axe-rules"; + export { htmlcsRules as htmlcsRules${l.toUpperCase()} } from "./${l}/htmlcs-rules";`; + }) + .join(""), + pConfig + ) ), - "utf8", + "utf8" ); await browser.close(); diff --git a/kayle/builder/htmlcs-rule-map.ts b/kayle/builder/htmlcs-rule-map.ts index 3fe4f09f..020c6270 100644 --- a/kayle/builder/htmlcs-rule-map.ts +++ b/kayle/builder/htmlcs-rule-map.ts @@ -1,4 +1,4 @@ -import type { Rule, ParamList } from "./build-types"; +import type { ParamList } from "./build-types"; // Hand stich the rules to map from htmlcs. // We need to map the ruleId to the translation file key. @@ -26,14 +26,20 @@ export const htmlcsRuleMap = (rule: ParamList) => { const inlineTranslation = rule[2] && rule[2].startsWith("HTMLCS.getTranslation"); - const description = - (inlineTranslation && eval(rule[2])) || - rule[2] || - window.HTMLCS.getTranslation(`${rule[4]}_${rule[3]}`) || - window.HTMLCS.getTranslation(`${rule[4]}${rule[3]}`) || - ""; + let description = ""; - const baseRule = `${rule[4]}${directRuleAssignments.includes(rule[3]) ? "." : "_"}${rule[3]}`; + try { + description = + (inlineTranslation && eval(rule[2])) || + rule[2] || + window.HTMLCS.getTranslation(`${rule[4]}_${rule[3]}`) || + window.HTMLCS.getTranslation(`${rule[4]}${rule[3]}`) || + ""; + } catch (_e) {} + + const baseRule = `${rule[4]}${ + directRuleAssignments.includes(rule[3]) ? "." : "_" + }${rule[3]}`; const baseRuleId = section508 || !description ? rule[3] || baseRule : baseRule; @@ -41,6 +47,7 @@ export const htmlcsRuleMap = (rule: ParamList) => { ? rule[2].replace("HTMLCS.getTranslation(", "").replace(")", "") : ""; + // FIXME: we need to get the BASE GUIDELINES upfront like WCAG2AA.Principle1.Guideline1_4 to concat the id with. const ruleId = inlineTranslation ? inlineRule.substring(1, inlineRule.length - 1) : baseRuleId; diff --git a/kayle/lib/action.ts b/kayle/lib/action.ts index 909222c7..e336375a 100644 --- a/kayle/lib/action.ts +++ b/kayle/lib/action.ts @@ -56,13 +56,13 @@ export const actions = [ target.dispatchEvent( new Event("input", { bubbles: true, - }), + }) ); return Promise.resolve(); }, selector, - value, + value ); } catch (error) { throw new Error(`${failedActionElement} "${selector}"`); @@ -91,7 +91,7 @@ export const actions = [ target.dispatchEvent( new Event("input", { bubbles: true, - }), + }) ); return Promise.resolve(); }, selector); @@ -117,12 +117,12 @@ export const actions = [ target.dispatchEvent( new Event("change", { bubbles: true, - }), + }) ); return Promise.resolve(); }, selector, - checked, + checked ); } catch (error) { throw new Error(`${failedActionElement} "${selector}"`); @@ -176,7 +176,7 @@ export const actions = [ {}, property, expectedValue, - negated, + negated ); }, }, @@ -216,7 +216,7 @@ export const actions = [ polling: 200, }, selector, - state, + state ); }, }, @@ -244,11 +244,11 @@ export const actions = [ }, { once: true, - }, + } ); }, selector, - eventType, + eventType ); await page.waitForFunction( @@ -263,7 +263,7 @@ export const actions = [ }, { polling: 200, - }, + } ); } catch (error) { throw new Error(`${failedActionElement} "${selector}"`); @@ -283,7 +283,7 @@ export const actions = [ */ export async function runAction(browser, page, options, act, customActions?) { const action = (customActions ?? actions).find((item) => - item.match.test(act), + item.match.test(act) ); if (!action) { diff --git a/kayle/lib/auto.ts b/kayle/lib/auto.ts index dcde82d9..e92df798 100644 --- a/kayle/lib/auto.ts +++ b/kayle/lib/auto.ts @@ -17,7 +17,7 @@ export async function autoKayle( cb?: ((result: Audit) => Promise) | ((result: Audit) => void); } = {}, ignoreSet?: Set, - _results?: Audit[], + _results?: Audit[] ): Promise { if (!write) { const { writeFile } = await import("fs/promises"); @@ -51,7 +51,7 @@ export async function autoKayle( if (o.store) { await write( `${o.store}/${encodeURIComponent(o.page.url())}`, - await o.page.content(), + await o.page.content() ); } @@ -84,7 +84,7 @@ export async function autoKayle( origin: link, }, ignoreSet, - _results, + _results ); }) .catch((e) => { @@ -94,7 +94,7 @@ export async function autoKayle( console.error(e); } }); - }), + }) ); return _results; diff --git a/kayle/lib/config.ts b/kayle/lib/config.ts index 020b7dbd..e51ab9b4 100644 --- a/kayle/lib/config.ts +++ b/kayle/lib/config.ts @@ -42,7 +42,7 @@ type BrowserContext = { newCDPSession?(page: Partial | Frame): Partial; overridePermissions?( origin: string, - permissions: Permission[], + permissions: Permission[] ): Promise; }; @@ -89,7 +89,7 @@ type Page = { _routes?: { url: string }[]; route( path: string, - intercept: (config: any, next: any) => Promise | Promise, + intercept: (config: any, next: any) => Promise | Promise ): Promise; setRequestInterception?(enable?: boolean): Promise; listenerCount?(name: string): number; @@ -99,19 +99,19 @@ type Page = { | Function | { default: Function; - }, + } ): Promise; addInitScript?(script: { content?: string }): Promise; evaluateOnNewDocument?< Params extends unknown[], - Func extends (...args: Params) => unknown = (...args: Params) => unknown, + Func extends (...args: Params) => unknown = (...args: Params) => unknown >( pageFunction: Func | string, ...args: Params ): Promise<{ identifier: string }>; evaluate< Params extends unknown[], - Func extends EvaluateFunc = EvaluateFunc, + Func extends EvaluateFunc = EvaluateFunc >( pageFunction: Func | string, ...args: Params diff --git a/kayle/lib/index.ts b/kayle/lib/index.ts index f23b72ab..d556d60f 100644 --- a/kayle/lib/index.ts +++ b/kayle/lib/index.ts @@ -26,5 +26,5 @@ export { type WaitForOptions, } from "./config"; export { extractLinks, innateBuilder } from "./wasm"; -export { htmlcsRules } from "./rules/htmlcs-rules"; -export { axeRules } from "./rules/axe-rules"; +export { htmlcsLocales } from "./runners/htmlcs"; +export { axeLocales } from "./runners/axe"; diff --git a/kayle/lib/kayle.ts b/kayle/lib/kayle.ts index f4a2b6fa..b6864277 100644 --- a/kayle/lib/kayle.ts +++ b/kayle/lib/kayle.ts @@ -32,7 +32,7 @@ const audit = async (config: RunnerConfig): Promise => { origin: config.origin, language: config.language, clip: config.clip, - }, + } ); }; @@ -61,7 +61,7 @@ const injectRunners = async (config: RunnerConfig) => { return await Promise.allSettled([ config.page.evaluate(runnersJavascript["kayle"]), ...config.runners.map((r) => - config.page.evaluate(getRunner(config.language, r)), + config.page.evaluate(getRunner(config.language, r)) ), ]); } @@ -77,7 +77,7 @@ export const auditExtension = async (config: RunnerConfig): Promise => { } window.addEventListener("kayle_receive", (event: CustomEvent) => - resolve(event.detail.data), + resolve(event.detail.data) ); window.dispatchEvent( @@ -86,7 +86,7 @@ export const auditExtension = async (config: RunnerConfig): Promise => { name: "kayle", options: runOptions, }, - }), + }) ); }); }, @@ -100,7 +100,7 @@ export const auditExtension = async (config: RunnerConfig): Promise => { origin: config.origin, language: config.language, clip: config.clip, - }, + } ); }; @@ -121,7 +121,7 @@ const auditPageInnate = async (config: RunnerConf, results: Audit) => { const innateAudit: InnateIssue[] = await kayle_innate.audit( html, css, - config.clip, + config.clip ); for (const innateIssue of innateAudit) { @@ -163,7 +163,7 @@ const auditPageInnate = async (config: RunnerConf, results: Audit) => { */ export const kayle = async ( o: RunnerConf = {}, - preventClose?: boolean, + preventClose?: boolean ): Promise => { const watcher = new Watcher(); const navigate = o.page.url() === "about:blank" && (o.origin || o.html); @@ -212,7 +212,7 @@ export const kayle = async ( } return item; - }), + }) ); } diff --git a/kayle/lib/lint.ts b/kayle/lib/lint.ts index 2b420f1a..d8c36e36 100644 --- a/kayle/lib/lint.ts +++ b/kayle/lib/lint.ts @@ -12,7 +12,7 @@ export const kayleLint = async ( source?: string, // url or html source o: Partial = {}, runner?: keyof typeof runnersJavascript, - forward?: boolean, // forward messages to console + forward?: boolean // forward messages to console ) => { const config = extractArgs(o); let html = source; @@ -55,7 +55,7 @@ export const kayleLint = async ( dom.window.eval(runnersJavascript.kayle); dom.window.eval( - runner ? runnersJavascript[runner] : runnersJavascript["htmlcs"], + runner ? runnersJavascript[runner] : runnersJavascript["htmlcs"] ); const results = await dom.window.__a11y.run({ diff --git a/kayle/lib/rules/ar/axe-rules.ts b/kayle/lib/rules/ar/axe-rules.ts new file mode 100644 index 00000000..84010e65 --- /dev/null +++ b/kayle/lib/rules/ar/axe-rules.ts @@ -0,0 +1,978 @@ +/* THIS FILE WAS CREATED DYNAMICALLY - DO NOT EDIT */ +export const axeRules = [ + { + ruleId: "accesskeys", + description: "يضمن أن قيمة خاصية الوصول لكل مفتاح فريدة", + help: "يجب أن تكون قيمة خاصية الوصول فريدة", + helpUrl: + "https://dequeuniversity.com/rules/axe/4.6/accesskeys?application=axeAPI&lang=ar", + tags: ["cat.keyboard", "best-practice"], + }, + { + ruleId: "area-alt", + description: "يضمن أن عناصر لخرائط الصور لها نص بديل", + help: "يجب أن تحتوي عناصر الفعالة على نص بديل", + helpUrl: + "https://dequeuniversity.com/rules/axe/4.6/area-alt?application=axeAPI&lang=ar", + tags: [ + "cat.text-alternatives", + "wcag2a", + "wcag244", + "wcag412", + "section508", + "section508.22.a", + "ACT", + ], + actIds: ["c487ae"], + }, + { + ruleId: "aria-allowed-attr", + description: "يضمن أن خصائص ARIA مسموحة لدور عنصر معين", + help: "يجب أن تستخدم العناصر خصائص ARIA المسموحة فقط", + helpUrl: + "https://dequeuniversity.com/rules/axe/4.6/aria-allowed-attr?application=axeAPI&lang=ar", + tags: ["cat.aria", "wcag2a", "wcag412"], + actIds: ["5c01ea"], + }, + { + ruleId: "aria-allowed-role", + description: "يضمن أن خاصية الدور لها قيمة مناسبة للعنصر", + help: "يجب أن يكون دور ARIA مناسباً للعنصر", + helpUrl: + "https://dequeuniversity.com/rules/axe/4.6/aria-allowed-role?application=axeAPI&lang=ar", + tags: ["cat.aria", "best-practice"], + }, + { + ruleId: "aria-command-name", + description: "يضمن أن كل أمر ARIA ورابط وعنصر قائمة له اسم متاح", + help: "يجب أن تحتوي أوامر ARIA على اسم متاح", + helpUrl: + "https://dequeuniversity.com/rules/axe/4.6/aria-command-name?application=axeAPI&lang=ar", + tags: ["cat.aria", "wcag2a", "wcag412", "ACT"], + actIds: ["97a4e1"], + }, + { + ruleId: "aria-dialog-name", + description: "يضمن أن كل عقدة حوار وتنبيه حوار في ARIA لها اسم متاح", + help: "يجب أن تحتوي عقد الحوار وتنبيه الحوار في ARIA على اسم متاح", + helpUrl: + "https://dequeuniversity.com/rules/axe/4.6/aria-dialog-name?application=axeAPI&lang=ar", + tags: ["cat.aria", "best-practice"], + }, + { + ruleId: "aria-hidden-body", + description: "يضمن عدم وجود 'aria-hidden=\"true\"' على جسم الوثيقة", + help: "يجب ألا يتواجد 'aria-hidden=\"true\"' على جسم الوثيقة", + helpUrl: + "https://dequeuniversity.com/rules/axe/4.6/aria-hidden-body?application=axeAPI&lang=ar", + tags: ["cat.aria", "wcag2a", "wcag412"], + }, + { + ruleId: "aria-hidden-focus", + description: + "يضمن أن العناصر المخفية بـ aria-hidden ليست قابلة للتركيز ولا تحتوي على عناصر قابلة للتركيز", + help: "يجب ألا يكون العنصر المخفي بـ ARIA قابل للتركيز أو يحتوي على عناصر قابلة للتركيز", + helpUrl: + "https://dequeuniversity.com/rules/axe/4.6/aria-hidden-focus?application=axeAPI&lang=ar", + tags: ["cat.name-role-value", "wcag2a", "wcag412"], + actIds: ["6cfa84"], + }, + { + ruleId: "aria-input-field-name", + description: "يضمن أن كل حقل إدخال ARIA له اسم متاح", + help: "يجب أن تحتوي حقول إدخال ARIA على اسم متاح", + helpUrl: + "https://dequeuniversity.com/rules/axe/4.6/aria-input-field-name?application=axeAPI&lang=ar", + tags: ["cat.aria", "wcag2a", "wcag412", "ACT"], + actIds: ["e086e5"], + }, + { + ruleId: "aria-meter-name", + description: "يضمن أن كل عقدة قياس في ARIA لها اسم متاح", + help: "يجب أن تحتوي عقد القياس في ARIA على اسم متاح", + helpUrl: + "https://dequeuniversity.com/rules/axe/4.6/aria-meter-name?application=axeAPI&lang=ar", + tags: ["cat.aria", "wcag2a", "wcag111"], + }, + { + ruleId: "aria-progressbar-name", + description: "يضمن أن كل عقدة شريط تقدم في ARIA لها اسم متاح", + help: "يجب أن تحتوي عقد شريط التقدم في ARIA على اسم متاح", + helpUrl: + "https://dequeuniversity.com/rules/axe/4.6/aria-progressbar-name?application=axeAPI&lang=ar", + tags: ["cat.aria", "wcag2a", "wcag111"], + }, + { + ruleId: "aria-required-attr", + description: "يضمن أن العناصر بأدوار ARIA تحتوي على كل خصائص ARIA المطلوبة", + help: "يجب توفير خصائص ARIA المطلوبة", + helpUrl: + "https://dequeuniversity.com/rules/axe/4.6/aria-required-attr?application=axeAPI&lang=ar", + tags: ["cat.aria", "wcag2a", "wcag412"], + actIds: ["4e8ab6"], + }, + { + ruleId: "aria-required-children", + description: "يضمن أن العناصر بدور ARIA يحتوي على الأدوار الفرعية المطلوبة", + help: "يجب أن تحتوي بعض الأدوار في ARIA على أدوار فرعية محددة", + helpUrl: + "https://dequeuniversity.com/rules/axe/4.6/aria-required-children?application=axeAPI&lang=ar", + tags: ["cat.aria", "wcag2a", "wcag131"], + actIds: ["bc4a75", "ff89c9"], + }, + { + ruleId: "aria-required-parent", + description: "يضمن أن العناصر بدور ARIA تحتوي على الأدوار الأصلية المطلوبة", + help: "يجب أن تحتوي بعض الأدوار في ARIA على أدوار أصلية محددة", + helpUrl: + "https://dequeuniversity.com/rules/axe/4.6/aria-required-parent?application=axeAPI&lang=ar", + tags: ["cat.aria", "wcag2a", "wcag131"], + actIds: ["ff89c9"], + }, + { + ruleId: "aria-roledescription", + description: + "يضمن استخدام aria-roledescription فقط على العناصر بدور ضمني أو صريح", + help: "يجب استخدام aria-roledescription على العناصر بدور دلالي", + helpUrl: + "https://dequeuniversity.com/rules/axe/4.6/aria-roledescription?application=axeAPI&lang=ar", + tags: ["cat.aria", "wcag2a", "wcag412"], + }, + { + ruleId: "aria-roles", + description: "يضمن أن كل العناصر بخاصية دور تستخدم قيمة صالحة", + help: "يجب أن تتوافق الأدوار في ARIA مع قيم صالحة", + helpUrl: + "https://dequeuniversity.com/rules/axe/4.6/aria-roles?application=axeAPI&lang=ar", + tags: ["cat.aria", "wcag2a", "wcag412"], + actIds: ["674b10"], + }, + { + ruleId: "aria-text", + description: + 'يضمن استخدام "role=text" على العناصر بدون أحفاد قابلين للتركيز', + help: '"role=text" يجب ألا يحتوي على أحفاد قابلين للتركيز', + helpUrl: + "https://dequeuniversity.com/rules/axe/4.6/aria-text?application=axeAPI&lang=ar", + tags: ["cat.aria", "best-practice"], + }, + { + ruleId: "aria-toggle-field-name", + description: "يضمن أن كل حقل تبديل في ARIA له اسم متاح", + help: "يجب أن تحتوي حقول التبديل في ARIA على اسم متاح", + helpUrl: + "https://dequeuniversity.com/rules/axe/4.6/aria-toggle-field-name?application=axeAPI&lang=ar", + tags: ["cat.aria", "wcag2a", "wcag412", "ACT"], + actIds: ["e086e5"], + }, + { + ruleId: "aria-tooltip-name", + description: "يضمن أن كل عقدة تلميح في ARIA لها اسم متاح", + help: "يجب أن تحتوي عقد التلميح في ARIA على اسم متاح", + helpUrl: + "https://dequeuniversity.com/rules/axe/4.6/aria-tooltip-name?application=axeAPI&lang=ar", + tags: ["cat.aria", "wcag2a", "wcag412"], + }, + { + ruleId: "aria-treeitem-name", + description: "يضمن أن كل عقدة عنصر شجرة في ARIA لها اسم متاح", + help: "يجب أن تحتوي عقد عناصر الشجرة في ARIA على اسم متاح", + helpUrl: + "https://dequeuniversity.com/rules/axe/4.6/aria-treeitem-name?application=axeAPI&lang=ar", + tags: ["cat.aria", "best-practice"], + }, + { + ruleId: "aria-valid-attr-value", + description: "يضمن أن كل خصائص ARIA لها قيم صالحة", + help: "يجب أن تتوافق خصائص ARIA مع قيم صالحة", + helpUrl: + "https://dequeuniversity.com/rules/axe/4.6/aria-valid-attr-value?application=axeAPI&lang=ar", + tags: ["cat.aria", "wcag2a", "wcag412"], + actIds: ["6a7281"], + }, + { + ruleId: "aria-valid-attr", + description: "يضمن أن الخصائص التي تبدأ بـ aria- هي خصائص ARIA صالحة", + help: "يجب أن تتوافق خصائص ARIA مع أسماء صالحة", + helpUrl: + "https://dequeuniversity.com/rules/axe/4.6/aria-valid-attr?application=axeAPI&lang=ar", + tags: ["cat.aria", "wcag2a", "wcag412"], + actIds: ["5f99a7"], + }, + { + ruleId: "audio-caption", + description: "يضمن أن عناصر