From 9c99361b189b4a5962afa7a63994d2914daeca11 Mon Sep 17 00:00:00 2001 From: j-mendez Date: Sat, 9 Mar 2024 13:42:55 -0500 Subject: [PATCH] chore(rules): fix htmlcs rule builder base --- kayle/bench/fast_axecore-playwright.ts | 2 +- kayle/bench/fast_htmlcs-playwright.ts | 2 +- kayle/builder/build-extension.ts | 2 +- kayle/builder/build-htmlcs-params.ts | 13 + kayle/builder/build-rules.ts | 30 +- kayle/builder/htmlcs-rule-map.ts | 4 +- kayle/lib/action.ts | 22 +- kayle/lib/auto.ts | 8 +- kayle/lib/config.ts | 10 +- kayle/lib/kayle.ts | 16 +- kayle/lib/lint.ts | 4 +- kayle/lib/rules/ar/axe-rules.ts | 1224 +- kayle/lib/rules/ar/htmlcs-rules.ts | 4238 +++- kayle/lib/rules/da/axe-rules.ts | 1174 +- kayle/lib/rules/da/htmlcs-rules.ts | 23130 ++++++++++++++---- kayle/lib/rules/de/axe-rules.ts | 1220 +- kayle/lib/rules/de/htmlcs-rules.ts | 22827 +++++++++-------- kayle/lib/rules/en/axe-rules.ts | 1220 +- kayle/lib/rules/en/htmlcs-rules.ts | 17045 ++++++------- kayle/lib/rules/es/axe-rules.ts | 1180 +- kayle/lib/rules/es/htmlcs-rules.ts | 13138 ++-------- kayle/lib/rules/eu/axe-rules.ts | 1220 +- kayle/lib/rules/eu/htmlcs-rules.ts | 12339 ++++++---- kayle/lib/rules/fr/axe-rules.ts | 1186 +- kayle/lib/rules/fr/htmlcs-rules.ts | 7367 +++++- kayle/lib/rules/he/axe-rules.ts | 1220 +- kayle/lib/rules/he/htmlcs-rules.ts | 13856 ++++------- kayle/lib/rules/index.ts | 68 +- kayle/lib/rules/it/axe-rules.ts | 1220 +- kayle/lib/rules/it/htmlcs-rules.ts | 5680 +---- kayle/lib/rules/ja/axe-rules.ts | 1222 +- kayle/lib/rules/ja/htmlcs-rules.ts | 11657 +++++++-- kayle/lib/rules/ko/axe-rules.ts | 1222 +- kayle/lib/rules/ko/htmlcs-rules.ts | 17336 +++---------- kayle/lib/rules/nl/axe-rules.ts | 1220 +- kayle/lib/rules/nl/htmlcs-rules.ts | 20808 +++++++++++++--- kayle/lib/rules/no_NB/axe-rules.ts | 1220 +- kayle/lib/rules/no_NB/htmlcs-rules.ts | 22088 ++++++++++++++--- kayle/lib/rules/pl/axe-rules.ts | 1222 +- kayle/lib/rules/pl/htmlcs-rules.ts | 19010 +++++--------- kayle/lib/rules/pt_BR/axe-rules.ts | 1220 +- kayle/lib/rules/pt_BR/htmlcs-rules.ts | 14423 +++++------ kayle/lib/rules/zh_CN/axe-rules.ts | 1220 +- kayle/lib/rules/zh_CN/htmlcs-rules.ts | 4769 ++-- kayle/lib/rules/zh_TW/axe-rules.ts | 1220 +- kayle/lib/rules/zh_TW/htmlcs-rules.ts | 4983 +--- kayle/lib/runner-js.ts | 2 +- kayle/lib/runner.ts | 10 +- kayle/lib/runners/axe.ts | 4 +- kayle/lib/runners/htmlcs.ts | 2 +- 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 | 1 + kayle/tests/innate-playwright.spec.ts | 2 +- kayle/tests/innate.ts | 4 +- kayle/tests/wasm.ts | 2 +- 68 files changed, 141607 insertions(+), 113977 deletions(-) diff --git a/kayle/bench/fast_axecore-playwright.ts b/kayle/bench/fast_axecore-playwright.ts index 9f2707e4..bace8587 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 fc495d85..08925d20 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 91cdbeda..c28ab6b3 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-htmlcs-params.ts b/kayle/builder/build-htmlcs-params.ts index 2d0a2fa1..a513539e 100644 --- a/kayle/builder/build-htmlcs-params.ts +++ b/kayle/builder/build-htmlcs-params.ts @@ -22,6 +22,8 @@ const processFile = (filePath) => { const code = readFileSync(filePath, "utf8"); const ast = parse(code, { sourceType: "script", ecmaVersion: 2020 }); + let guide: RegExpMatchArray | null = null; + simple(ast, { CallExpression(node) { if ( @@ -64,6 +66,17 @@ const processFile = (filePath) => { params.push(pathParse(filePath).name); + // run regex on first match + if (!guide) { + guide = code.match( + /(_global\.HTMLCS_WCAG2AAA_Sniffs_)([A-Za-z0-9_]+)/, + ); + } + + if (guide && guide[2]) { + params.push(guide[2]); + } + paramList.push(params as ParamList); } }, diff --git a/kayle/builder/build-rules.ts b/kayle/builder/build-rules.ts index 31ee54e9..d422c132 100644 --- a/kayle/builder/build-rules.ts +++ b/kayle/builder/build-rules.ts @@ -34,7 +34,7 @@ import type { Rule } from "./build-types"; origin: "https://www.example.com", language, }, - true + true, ); const paramList = await processParams(); @@ -48,11 +48,11 @@ import type { Rule } from "./build-types"; }); await page.exposeFunction("pushHtmlcsRule", (t: Rule) => - fast_htmlcs_rules.push(t) + fast_htmlcs_rules.push(t), ); await page.exposeFunction("pushAxeRule", (t: Rule) => - fast_axe_rules.push(t) + fast_axe_rules.push(t), ); await page.evaluate(() => { @@ -77,12 +77,12 @@ import type { Rule } from "./build-types"; Buffer.from( await format( `/* ${DNE} */\nexport const htmlcsRules = ${JSON.stringify( - fast_htmlcs_rules.filter((r) => r.description) + fast_htmlcs_rules.filter((r) => r.description), )};`, - pConfig - ) + pConfig, + ), ), - "utf8" + "utf8", ); await writeFile( @@ -90,12 +90,12 @@ import type { Rule } from "./build-types"; Buffer.from( await format( `/* ${DNE} */\nexport const axeRules = ${JSON.stringify( - fast_axe_rules + fast_axe_rules, )};`, - pConfig - ) + pConfig, + ), ), - "utf8" + "utf8", ); await page.close({ @@ -104,7 +104,7 @@ import type { Rule } from "./build-types"; }; const localesList: string[] = Array.from( - new Set(htmlcsLocales.concat(axeLocales)) + new Set(htmlcsLocales.concat(axeLocales)), ); localesList.push("en"); @@ -121,10 +121,10 @@ import type { Rule } from "./build-types"; export { htmlcsRules as htmlcsRules${l.toUpperCase()} } from "./${l}/htmlcs-rules";`; }) .join(""), - pConfig - ) + pConfig, + ), ), - "utf8" + "utf8", ); await browser.close(); diff --git a/kayle/builder/htmlcs-rule-map.ts b/kayle/builder/htmlcs-rule-map.ts index 020c6270..d4ba8b71 100644 --- a/kayle/builder/htmlcs-rule-map.ts +++ b/kayle/builder/htmlcs-rule-map.ts @@ -53,7 +53,9 @@ export const htmlcsRuleMap = (rule: ParamList) => { : baseRuleId; return { - ruleId, + ruleId: rule[5] + ? `${rule[5].replace("_Guideline", ".Guideline")}.${ruleId}` + : ruleId, description, helpUrl: section508 ? [] diff --git a/kayle/lib/action.ts b/kayle/lib/action.ts index e336375a..909222c7 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 e92df798..dcde82d9 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 e51ab9b4..020b7dbd 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/kayle.ts b/kayle/lib/kayle.ts index b6864277..f4a2b6fa 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 d8c36e36..2b420f1a 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 index 84010e65..0729340f 100644 --- a/kayle/lib/rules/ar/axe-rules.ts +++ b/kayle/lib/rules/ar/axe-rules.ts @@ -1,978 +1,978 @@ /* THIS FILE WAS CREATED DYNAMICALLY - DO NOT EDIT */ export const axeRules = [ { - ruleId: "accesskeys", - description: "يضمن أن قيمة خاصية الوصول لكل مفتاح فريدة", - help: "يجب أن تكون قيمة خاصية الوصول فريدة", + ruleId: 'accesskeys', + description: 'يضمن أن قيمة خاصية الوصول لكل مفتاح فريدة', + help: 'يجب أن تكون قيمة خاصية الوصول فريدة', helpUrl: - "https://dequeuniversity.com/rules/axe/4.6/accesskeys?application=axeAPI&lang=ar", - tags: ["cat.keyboard", "best-practice"], + 'https://dequeuniversity.com/rules/axe/4.6/accesskeys?application=axeAPI&lang=ar', + tags: ['cat.keyboard', 'best-practice'], }, { - ruleId: "area-alt", - description: "يضمن أن عناصر لخرائط الصور لها نص بديل", - help: "يجب أن تحتوي عناصر الفعالة على نص بديل", + ruleId: 'area-alt', + description: 'يضمن أن عناصر لخرائط الصور لها نص بديل', + help: 'يجب أن تحتوي عناصر الفعالة على نص بديل', helpUrl: - "https://dequeuniversity.com/rules/axe/4.6/area-alt?application=axeAPI&lang=ar", + '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", + 'cat.text-alternatives', + 'wcag2a', + 'wcag244', + 'wcag412', + 'section508', + 'section508.22.a', + 'ACT', ], - actIds: ["c487ae"], + actIds: ['c487ae'], }, { - ruleId: "aria-allowed-attr", - description: "يضمن أن خصائص ARIA مسموحة لدور عنصر معين", - help: "يجب أن تستخدم العناصر خصائص ARIA المسموحة فقط", + 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"], + '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 مناسباً للعنصر", + 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"], + '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 على اسم متاح", + 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"], + '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 على اسم متاح", + 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"], + '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\"' على جسم الوثيقة", + 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"], + 'https://dequeuniversity.com/rules/axe/4.6/aria-hidden-body?application=axeAPI&lang=ar', + tags: ['cat.aria', 'wcag2a', 'wcag412'], }, { - ruleId: "aria-hidden-focus", + ruleId: 'aria-hidden-focus', description: - "يضمن أن العناصر المخفية بـ aria-hidden ليست قابلة للتركيز ولا تحتوي على عناصر قابلة للتركيز", - help: "يجب ألا يكون العنصر المخفي بـ ARIA قابل للتركيز أو يحتوي على عناصر قابلة للتركيز", + 'يضمن أن العناصر المخفية بـ 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"], + '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 على اسم متاح", + 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"], + '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 على اسم متاح", + 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"], + '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 على اسم متاح", + 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"], + '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 المطلوبة", + 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"], + '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 على أدوار فرعية محددة", + 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"], + '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 على أدوار أصلية محددة", + 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"], + 'https://dequeuniversity.com/rules/axe/4.6/aria-required-parent?application=axeAPI&lang=ar', + tags: ['cat.aria', 'wcag2a', 'wcag131'], + actIds: ['ff89c9'], }, { - ruleId: "aria-roledescription", + ruleId: 'aria-roledescription', description: - "يضمن استخدام aria-roledescription فقط على العناصر بدور ضمني أو صريح", - help: "يجب استخدام aria-roledescription على العناصر بدور دلالي", + 'يضمن استخدام aria-roledescription فقط على العناصر بدور ضمني أو صريح', + help: 'يجب استخدام aria-roledescription على العناصر بدور دلالي', helpUrl: - "https://dequeuniversity.com/rules/axe/4.6/aria-roledescription?application=axeAPI&lang=ar", - tags: ["cat.aria", "wcag2a", "wcag412"], + 'https://dequeuniversity.com/rules/axe/4.6/aria-roledescription?application=axeAPI&lang=ar', + tags: ['cat.aria', 'wcag2a', 'wcag412'], }, { - ruleId: "aria-roles", - description: "يضمن أن كل العناصر بخاصية دور تستخدم قيمة صالحة", - help: "يجب أن تتوافق الأدوار في ARIA مع قيم صالحة", + 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"], + 'https://dequeuniversity.com/rules/axe/4.6/aria-roles?application=axeAPI&lang=ar', + tags: ['cat.aria', 'wcag2a', 'wcag412'], + actIds: ['674b10'], }, { - ruleId: "aria-text", + 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"], + '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 على اسم متاح", + 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"], + '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 على اسم متاح", + 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"], + '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 على اسم متاح", + 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"], + '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 مع قيم صالحة", + 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"], + '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 مع أسماء صالحة", + 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"], + '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: "يضمن أن عناصر