aria-ease 7.0.0 → 7.0.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/README.md CHANGED
@@ -924,7 +924,7 @@ jobs:
924
924
  - name: Setup Node.js
925
925
  uses: actions/setup-node@v4
926
926
  with:
927
- node-version: "20"
927
+ node-version: "24.x"
928
928
  cache: "npm"
929
929
 
930
930
  - name: Install dependencies
@@ -1,4 +1,4 @@
1
- import"./chunk-CNU4N4AY.js";import d from"@axe-core/playwright";import{chromium as s}from"playwright";async function b(){return await s.launch({headless:!0})}async function h(a,l){let o=l.browser,i=!1,n=6e4,c="domcontentloaded";try{o||(o=await s.launch({headless:!0}),i=!0);let e=await o.newContext(),r=await e.newPage();await r.goto(a,{waitUntil:c,timeout:n});try{await r.waitForSelector("main",{state:"visible",timeout:n})}catch(t){console.warn(`\u26A0\uFE0F Warning: <main> landmark not found or not visible on ${a} after ${n}ms. Audit will continue, but results may be inaccurate. Consider adding a <main> element to improve audit accuracy. ${t instanceof Error?t.message:String(t)}`)}let u=await new d({page:r}).analyze();return await r.close(),await e.close(),u}catch(e){throw e instanceof Error?e.message.includes("Executable doesn't exist")?(console.error(`
1
+ import"./chunk-CNU4N4AY.js";import d from"@axe-core/playwright";import{chromium as s}from"playwright";async function h(){return await s.launch({headless:!0})}async function b(a,l){let o=l.browser,i=!1,n=6e4,c="domcontentloaded";try{o||(o=await s.launch({headless:!0}),i=!0);let e=await o.newContext(),r=await e.newPage();await r.goto(a,{waitUntil:c,timeout:n});try{await r.waitForSelector("main",{state:"visible",timeout:n})}catch(t){console.warn(`\u26A0\uFE0F Warning: <main> landmark not found or not visible on ${a} after ${n}ms. Audit will continue, but results may be inaccurate. Consider adding a <main> element to improve audit accuracy. ${t instanceof Error?t.message:String(t)}`)}let u=await new d({page:r}).withTags(["wcag2a","wcag2aa","wcag21a","wcag21aa"]).analyze();return await r.close(),await e.close(),u}catch(e){throw e instanceof Error?e.message.includes("Executable doesn't exist")?(console.error(`
2
2
  \u274C Playwright browsers not found!
3
3
  `),console.log("\u{1F4E6} First-time setup required:"),console.log(` Run: npx playwright install chromium
4
4
  `),console.log("\u{1F4A1} This downloads the browser needed for auditing (~200MB)"),console.log(` You only need to do this once.
@@ -6,4 +6,4 @@ import"./chunk-CNU4N4AY.js";import d from"@axe-core/playwright";import{chromium
6
6
  \u274C Server Not Running!
7
7
  `),console.log(" Make sure your server is running before auditing URL"),console.log(" Run: npm run dev # or your start command")):e.message.includes("page.goto: Protocol error (Page.navigate): Cannot navigate to invalid URL")?console.error(`
8
8
  \u274C Cannot audit invalid URL
9
- `):(console.error("\u274C Audit error:",e.message),console.log(" Make sure you provide a valid URL")):console.error("\u274C Audit error (non-Error):",String(e)),e}finally{o&&i&&await o.close()}}export{b as createAuditBrowser,h as runAudit};
9
+ `):(console.error("\u274C Audit error:",e.message),console.log(" Make sure you provide a valid URL")):console.error("\u274C Audit error (non-Error):",String(e)),e}finally{o&&i&&await o.close()}}export{h as createAuditBrowser,b as runAudit};
package/dist/cli.cjs CHANGED
@@ -1,15 +1,15 @@
1
1
  #!/usr/bin/env node
2
- "use strict";var os=Object.create;var He=Object.defineProperty;var ns=Object.getOwnPropertyDescriptor;var as=Object.getOwnPropertyNames;var cs=Object.getPrototypeOf,ls=Object.prototype.hasOwnProperty;var L=(c,e)=>()=>(c&&(e=c(c=0)),e);var K=(c,e)=>{for(var t in e)He(c,t,{get:e[t],enumerable:!0})},qe=(c,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of as(e))!ls.call(c,s)&&s!==t&&He(c,s,{get:()=>e[s],enumerable:!(r=ns(e,s))||r.enumerable});return c},Ce=(c,e,t)=>(qe(c,e,"default"),t&&qe(t,e,"default")),j=(c,e,t)=>(t=c!=null?os(cs(c)):{},qe(e||!c||!c.__esModule?He(t,"default",{value:c,enumerable:!0}):t,c));var _e={};K(_e,{loadConfig:()=>Je});function us(c){let e=[];if(!c||typeof c!="object")return e.push("Config must be an object"),{valid:!1,errors:e};let t=c;if(t.audit!==void 0){if(typeof t.audit!="object"||t.audit===null)e.push("audit must be an object");else if(t.audit.urls!==void 0&&(Array.isArray(t.audit.urls)?t.audit.urls.some(r=>typeof r!="string")&&e.push("audit.urls must contain only strings"):e.push("audit.urls must be an array")),t.audit.output!==void 0)if(typeof t.audit.output!="object")e.push("audit.output must be an object");else{let r=t.audit.output;r.format!==void 0&&(["json","csv","html","all"].includes(r.format)||e.push("audit.output.format must be one of: json, csv, html, all")),r.out!==void 0&&typeof r.out!="string"&&e.push("audit.output.out must be a string")}}if(t.test!==void 0)if(typeof t.test!="object"||t.test===null)e.push("test must be an object");else{t.test.disableTimeouts!==void 0&&typeof t.test.disableTimeouts!="boolean"&&e.push("test.disableTimeouts must be a boolean when provided");let r=["actionTimeoutMs","assertionTimeoutMs","navigationTimeoutMs","componentReadyTimeoutMs"];for(let s of r){let i=t.test[s];i!==void 0&&(typeof i!="number"||!Number.isFinite(i)||i<0)&&e.push(`test.${s} must be a non-negative number when provided`)}t.test.components!==void 0&&(Array.isArray(t.test.components)?t.test.components.forEach((s,i)=>{if(typeof s!="object"||s===null)e.push(`test.components[${i}] must be an object`);else{typeof s.name!="string"&&e.push(`test.components[${i}].name must be a string`),s.contractPath!==void 0&&typeof s.contractPath!="string"&&e.push(`test.components[${i}].contractPath must be a string when provided`),s.strategyPath!==void 0&&typeof s.strategyPath!="string"&&e.push(`test.components[${i}].strategyPath must be a string when provided`),s.strictness!==void 0&&!["minimal","balanced","strict","paranoid"].includes(s.strictness)&&e.push(`test.components[${i}].strictness must be one of: minimal, balanced, strict, paranoid`),s.disableTimeouts!==void 0&&typeof s.disableTimeouts!="boolean"&&e.push(`test.components[${i}].disableTimeouts must be a boolean when provided`);let o=["actionTimeoutMs","assertionTimeoutMs","navigationTimeoutMs","componentReadyTimeoutMs"];for(let a of o){let l=s[a];l!==void 0&&(typeof l!="number"||!Number.isFinite(l)||l<0)&&e.push(`test.components[${i}].${a} must be a non-negative number when provided`)}}}):e.push("test.components must be an array")),t.test.strictness!==void 0&&(["minimal","balanced","strict","paranoid"].includes(t.test.strictness)||e.push("test.strictness must be one of: minimal, balanced, strict, paranoid"))}return t.contracts!==void 0&&(Array.isArray(t.contracts)?t.contracts.forEach((r,s)=>{typeof r!="object"||r===null?e.push(`contracts[${s}] must be an object`):(typeof r.src!="string"&&e.push(`contracts[${s}].src is required and must be a string`),r.out!==void 0&&typeof r.out!="string"&&e.push(`contracts[${s}].out must be a string`))}):e.push("contracts must be an array")),{valid:e.length===0,errors:e}}async function ps(c){try{let e=Ne.default.extname(c);if(e===".json"){let t=await We.default.readFile(c,"utf-8");return JSON.parse(t)}else if([".js",".mjs",".cjs",".ts"].includes(e)){let t=await import(c);return t.default||t}return null}catch{return null}}async function Je(c=process.cwd()){let e=["ariaease.config.js","ariaease.config.mjs","ariaease.config.cjs","ariaease.config.json","ariaease.config.ts"],t=null,r=null,s=[];for(let i of e){let o=Ne.default.resolve(c,i);if(await We.default.pathExists(o)){if(r=o,t=await ps(o),t===null){s.push(`Found config at ${i} but failed to load it. Check for syntax errors.`);continue}let a=us(t);if(!a.valid){s.push(`Config validation failed in ${i}:`),s.push(...a.errors.map(l=>` - ${l}`)),t=null;continue}break}}return{config:t||{},configPath:t?r:null,errors:s}}var Ne,We,ke=L(()=>{"use strict";Ne=j(require("path"),1),We=j(require("fs-extra"),1)});var wt={};K(wt,{BADGE_CONFIGS:()=>ze,displayAllBadges:()=>ds,displayBadgeInfo:()=>Ge,getBadgeMarkdown:()=>fe,promptAddBadge:()=>Ye});function fe(c){let e=ze[c];return`[![${e.label}](${e.markdownUrl})](https://github.com/aria-ease/aria-ease)`}function Ge(c){let e=fe(c);console.log(O.default.cyan(`
2
+ "use strict";var os=Object.create;var He=Object.defineProperty;var ns=Object.getOwnPropertyDescriptor;var as=Object.getOwnPropertyNames;var cs=Object.getPrototypeOf,ls=Object.prototype.hasOwnProperty;var L=(c,e)=>()=>(c&&(e=c(c=0)),e);var K=(c,e)=>{for(var t in e)He(c,t,{get:e[t],enumerable:!0})},qe=(c,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of as(e))!ls.call(c,s)&&s!==t&&He(c,s,{get:()=>e[s],enumerable:!(r=ns(e,s))||r.enumerable});return c},Ce=(c,e,t)=>(qe(c,e,"default"),t&&qe(t,e,"default")),j=(c,e,t)=>(t=c!=null?os(cs(c)):{},qe(e||!c||!c.__esModule?He(t,"default",{value:c,enumerable:!0}):t,c));var _e={};K(_e,{loadConfig:()=>Je});function us(c){let e=[];if(!c||typeof c!="object")return e.push("Config must be an object"),{valid:!1,errors:e};let t=c;if(t.audit!==void 0){if(typeof t.audit!="object"||t.audit===null)e.push("audit must be an object");else if(t.audit.urls!==void 0&&(Array.isArray(t.audit.urls)?t.audit.urls.some(r=>typeof r!="string")&&e.push("audit.urls must contain only strings"):e.push("audit.urls must be an array")),t.audit.output!==void 0)if(typeof t.audit.output!="object")e.push("audit.output must be an object");else{let r=t.audit.output;r.format!==void 0&&(["json","csv","html","all"].includes(r.format)||e.push("audit.output.format must be one of: json, csv, html, all")),r.out!==void 0&&typeof r.out!="string"&&e.push("audit.output.out must be a string")}}if(t.test!==void 0)if(typeof t.test!="object"||t.test===null)e.push("test must be an object");else{t.test.disableTimeouts!==void 0&&typeof t.test.disableTimeouts!="boolean"&&e.push("test.disableTimeouts must be a boolean when provided");let r=["actionTimeoutMs","assertionTimeoutMs","navigationTimeoutMs","componentReadyTimeoutMs"];for(let s of r){let i=t.test[s];i!==void 0&&(typeof i!="number"||!Number.isFinite(i)||i<0)&&e.push(`test.${s} must be a non-negative number when provided`)}t.test.components!==void 0&&(Array.isArray(t.test.components)?t.test.components.forEach((s,i)=>{if(typeof s!="object"||s===null)e.push(`test.components[${i}] must be an object`);else{typeof s.name!="string"&&e.push(`test.components[${i}].name must be a string`),s.contractPath!==void 0&&typeof s.contractPath!="string"&&e.push(`test.components[${i}].contractPath must be a string when provided`),s.strategyPath!==void 0&&typeof s.strategyPath!="string"&&e.push(`test.components[${i}].strategyPath must be a string when provided`),s.strictness!==void 0&&!["minimal","balanced","strict","paranoid"].includes(s.strictness)&&e.push(`test.components[${i}].strictness must be one of: minimal, balanced, strict, paranoid`),s.disableTimeouts!==void 0&&typeof s.disableTimeouts!="boolean"&&e.push(`test.components[${i}].disableTimeouts must be a boolean when provided`);let o=["actionTimeoutMs","assertionTimeoutMs","navigationTimeoutMs","componentReadyTimeoutMs"];for(let a of o){let l=s[a];l!==void 0&&(typeof l!="number"||!Number.isFinite(l)||l<0)&&e.push(`test.components[${i}].${a} must be a non-negative number when provided`)}}}):e.push("test.components must be an array")),t.test.strictness!==void 0&&(["minimal","balanced","strict","paranoid"].includes(t.test.strictness)||e.push("test.strictness must be one of: minimal, balanced, strict, paranoid"))}return t.contracts!==void 0&&(Array.isArray(t.contracts)?t.contracts.forEach((r,s)=>{typeof r!="object"||r===null?e.push(`contracts[${s}] must be an object`):(typeof r.src!="string"&&e.push(`contracts[${s}].src is required and must be a string`),r.out!==void 0&&typeof r.out!="string"&&e.push(`contracts[${s}].out must be a string`))}):e.push("contracts must be an array")),{valid:e.length===0,errors:e}}async function ps(c){try{let e=Ne.default.extname(c);if(e===".json"){let t=await We.default.readFile(c,"utf-8");return JSON.parse(t)}else if([".js",".mjs",".cjs",".ts"].includes(e)){let t=await import(c);return t.default||t}return null}catch{return null}}async function Je(c=process.cwd()){let e=["ariaease.config.js","ariaease.config.mjs","ariaease.config.cjs","ariaease.config.json","ariaease.config.ts"],t=null,r=null,s=[];for(let i of e){let o=Ne.default.resolve(c,i);if(await We.default.pathExists(o)){if(r=o,t=await ps(o),t===null){s.push(`Found config at ${i} but failed to load it. Check for syntax errors.`);continue}let a=us(t);if(!a.valid){s.push(`Config validation failed in ${i}:`),s.push(...a.errors.map(l=>` - ${l}`)),t=null;continue}break}}return{config:t||{},configPath:t?r:null,errors:s}}var Ne,We,ke=L(()=>{"use strict";Ne=j(require("path"),1),We=j(require("fs-extra"),1)});var wt={};K(wt,{BADGE_CONFIGS:()=>ze,displayAllBadges:()=>gs,displayBadgeInfo:()=>Ge,getBadgeMarkdown:()=>fe,promptAddBadge:()=>Ye});function fe(c){let e=ze[c];return`[![${e.label}](${e.markdownUrl})](https://github.com/aria-ease/aria-ease)`}function Ge(c){let e=fe(c);console.log(O.default.cyan(`
3
3
  \u{1F3C5} Show your accessibility commitment!`)),console.log(O.default.white(` Add this badge to your README.md:
4
4
  `)),console.log(O.default.green(" "+e)),console.log(O.default.dim(`
5
5
  This helps others discover accessibility tools and shows you care!
6
6
  `))}async function Ye(c,e=process.cwd()){let t=ht.default.join(e,"README.md");if(!await Ae.default.pathExists(t)){console.log(O.default.yellow(" \u2139\uFE0F No README.md found in current directory"));return}let s=await Ae.default.readFile(t,"utf-8"),i=fe(c);if(s.includes(i)||s.includes(ze[c].fileName)){console.log(O.default.gray(" \u2713 Badge already in README.md"));return}let o=yt.default.createInterface({input:process.stdin,output:process.stdout}),a=await new Promise(l=>{o.question(O.default.cyan(" Add badge to README.md now? (y/n): "),p=>{o.close(),l(p.toLowerCase().trim())})});a==="y"||a==="yes"?(await fs(t,s,i),console.log(O.default.green(" \u2713 Badge added to README.md!"))):console.log(O.default.gray(" Skipped. You can add it manually anytime."))}async function fs(c,e,t){let r=e.split(`
7
7
  `),s=0;for(let i=0;i<r.length;i++){let o=r[i].trim();if(o.startsWith("[![")||o.startsWith("[!")){s=i+1;continue}if(s>0&&!o.startsWith("[![")&&!o.startsWith("[!")&&o.length>0)break;if(s===0&&o.startsWith("#")){s=i+2;break}}s===0&&(s=1),r.splice(s,0,t),await Ae.default.writeFile(c,r.join(`
8
- `),"utf-8")}function ds(){console.log(O.default.cyan(`
8
+ `),"utf-8")}function gs(){console.log(O.default.cyan(`
9
9
  \u{1F4CD} Available badges:`)),console.log(O.default.white(`
10
10
  For audits:`)),console.log(O.default.green(" "+fe("audit"))),console.log(O.default.white(`
11
11
  For component testing:`)),console.log(O.default.green(" "+fe("component"))),console.log(O.default.white(`
12
- For both (verified):`)),console.log(O.default.green(" "+fe("verified"))),console.log("")}var Ae,ht,O,yt,ze,Ke=L(()=>{"use strict";Ae=j(require("fs-extra"),1),ht=j(require("path"),1),O=j(require("chalk"),1),yt=j(require("readline"),1),ze={audit:{type:"audit",fileName:"audited-by-aria-ease.svg",label:"Audited by aria-ease",markdownUrl:"https://cdn.jsdelivr.net/gh/aria-ease/aria-ease@main/badges/audited-by-aria-ease.svg"},component:{type:"component",fileName:"components-tested-aria-ease.svg",label:"Components tested: aria-ease",markdownUrl:"https://cdn.jsdelivr.net/gh/aria-ease/aria-ease@main/badges/components-tested-aria-ease.svg"},verified:{type:"verified",fileName:"verified-by-aria-ease.svg",label:"Verified by aria-ease",markdownUrl:"https://cdn.jsdelivr.net/gh/aria-ease/aria-ease@main/badges/verified-by-aria-ease.svg"}}});var Xe={};K(Xe,{createAuditBrowser:()=>gs,runAudit:()=>ms});async function gs(){return await Qe.chromium.launch({headless:!0})}async function ms(c,e){let t=e.browser,r=!1,s=6e4,i="domcontentloaded";try{t||(t=await Qe.chromium.launch({headless:!0}),r=!0);let o=await t.newContext(),a=await o.newPage();await a.goto(c,{waitUntil:i,timeout:s});try{await a.waitForSelector("main",{state:"visible",timeout:s})}catch(f){console.warn(`\u26A0\uFE0F Warning: <main> landmark not found or not visible on ${c} after ${s}ms. Audit will continue, but results may be inaccurate. Consider adding a <main> element to improve audit accuracy. ${f instanceof Error?f.message:String(f)}`)}let p=await new bt.default({page:a}).analyze();return await a.close(),await o.close(),p}catch(o){throw o instanceof Error?o.message.includes("Executable doesn't exist")?(console.error(`
12
+ For both (verified):`)),console.log(O.default.green(" "+fe("verified"))),console.log("")}var Ae,ht,O,yt,ze,Ke=L(()=>{"use strict";Ae=j(require("fs-extra"),1),ht=j(require("path"),1),O=j(require("chalk"),1),yt=j(require("readline"),1),ze={audit:{type:"audit",fileName:"audited-by-aria-ease.svg",label:"Audited by aria-ease",markdownUrl:"https://cdn.jsdelivr.net/gh/aria-ease/aria-ease@main/badges/audited-by-aria-ease.svg"},component:{type:"component",fileName:"components-tested-aria-ease.svg",label:"Components tested: aria-ease",markdownUrl:"https://cdn.jsdelivr.net/gh/aria-ease/aria-ease@main/badges/components-tested-aria-ease.svg"},verified:{type:"verified",fileName:"verified-by-aria-ease.svg",label:"Verified by aria-ease",markdownUrl:"https://cdn.jsdelivr.net/gh/aria-ease/aria-ease@main/badges/verified-by-aria-ease.svg"}}});var Xe={};K(Xe,{createAuditBrowser:()=>ds,runAudit:()=>ms});async function ds(){return await Qe.chromium.launch({headless:!0})}async function ms(c,e){let t=e.browser,r=!1,s=6e4,i="domcontentloaded";try{t||(t=await Qe.chromium.launch({headless:!0}),r=!0);let o=await t.newContext(),a=await o.newPage();await a.goto(c,{waitUntil:i,timeout:s});try{await a.waitForSelector("main",{state:"visible",timeout:s})}catch(f){console.warn(`\u26A0\uFE0F Warning: <main> landmark not found or not visible on ${c} after ${s}ms. Audit will continue, but results may be inaccurate. Consider adding a <main> element to improve audit accuracy. ${f instanceof Error?f.message:String(f)}`)}let p=await new bt.default({page:a}).withTags(["wcag2a","wcag2aa","wcag21a","wcag21aa"]).analyze();return await a.close(),await o.close(),p}catch(o){throw o instanceof Error?o.message.includes("Executable doesn't exist")?(console.error(`
13
13
  \u274C Playwright browsers not found!
14
14
  `),console.log("\u{1F4E6} First-time setup required:"),console.log(` Run: npx playwright install chromium
15
15
  `),console.log("\u{1F4A1} This downloads the browser needed for auditing (~200MB)"),console.log(` You only need to do this once.
@@ -17,8 +17,8 @@
17
17
  \u274C Server Not Running!
18
18
  `),console.log(" Make sure your server is running before auditing URL"),console.log(" Run: npm run dev # or your start command")):o.message.includes("page.goto: Protocol error (Page.navigate): Cannot navigate to invalid URL")?console.error(`
19
19
  \u274C Cannot audit invalid URL
20
- `):(console.error("\u274C Audit error:",o.message),console.log(" Make sure you provide a valid URL")):console.error("\u274C Audit error (non-Error):",String(o)),o}finally{t&&r&&await t.close()}}var bt,Qe,Ze=L(()=>{"use strict";bt=j(require("@axe-core/playwright"),1),Qe=require("playwright")});var $t={};K($t,{formatResults:()=>hs});function hs(c,e){switch(e){case"json":return JSON.stringify(c.flatMap(({url:t,result:r})=>r?r.violations.flatMap(s=>s.nodes.map(i=>({URL:t,Rule:s.id,Impact:s.impact,Description:s.description,Target:i.target,FailureSummary:i.failureSummary}))):[]),null,2);case"csv":return ys(c);case"html":return ws(c);default:return""}}function ys(c){let e=["URL,Rule,Impact,Description,Target,FailureSummary"];return c.forEach(({url:t,result:r})=>{r&&r.violations.forEach(s=>{s.nodes.forEach(i=>{e.push(de(t)+","+de(s.id)+","+de(s.impact)+","+de(s.description)+","+de(Array.isArray(i.target)?i.target.join("; "):String(i.target))+","+de(i.failureSummary??""))})})}),e.join(`
21
- `)}function de(c){return`"${String(c??"").replace(/"/g,'""')}"`}function ws(c){let e={pagesAudited:0,pagesWithViolations:0,totalViolations:0,distinctRules:new Set,impactCounts:new Map};c.forEach(({result:p})=>{if(!p)return;e.pagesAudited++,p.violations.reduce((m,h)=>{let P=(h.nodes||[]).length;if(P>0){e.distinctRules.add(h.id),e.totalViolations+=P,m+=P;let q=String(h.impact??"unknown");e.impactCounts.set(q,(e.impactCounts.get(q)||0)+P)}return m},0)>0&&e.pagesWithViolations++});let t=[];c.forEach(({url:p,result:f})=>{f&&f.violations.forEach(m=>{m.nodes.forEach(h=>{let P=Array.isArray(h.target)?h.target.join("; "):String(h.target);t.push(`
20
+ `):(console.error("\u274C Audit error:",o.message),console.log(" Make sure you provide a valid URL")):console.error("\u274C Audit error (non-Error):",String(o)),o}finally{t&&r&&await t.close()}}var bt,Qe,Ze=L(()=>{"use strict";bt=j(require("@axe-core/playwright"),1),Qe=require("playwright")});var $t={};K($t,{formatResults:()=>hs});function hs(c,e){switch(e){case"json":return JSON.stringify(c.flatMap(({url:t,result:r})=>r?r.violations.flatMap(s=>s.nodes.map(i=>({URL:t,Rule:s.id,Impact:s.impact,Description:s.description,Target:i.target,FailureSummary:i.failureSummary}))):[]),null,2);case"csv":return ys(c);case"html":return ws(c);default:return""}}function ys(c){let e=["URL,Rule,Impact,Description,Target,FailureSummary"];return c.forEach(({url:t,result:r})=>{r&&r.violations.forEach(s=>{s.nodes.forEach(i=>{e.push(ge(t)+","+ge(s.id)+","+ge(s.impact)+","+ge(s.description)+","+ge(Array.isArray(i.target)?i.target.join("; "):String(i.target))+","+ge(i.failureSummary??""))})})}),e.join(`
21
+ `)}function ge(c){return`"${String(c??"").replace(/"/g,'""')}"`}function ws(c){let e={pagesAudited:0,pagesWithViolations:0,totalViolations:0,distinctRules:new Set,impactCounts:new Map};c.forEach(({result:p})=>{if(!p)return;e.pagesAudited++,p.violations.reduce((m,h)=>{let P=(h.nodes||[]).length;if(P>0){e.distinctRules.add(h.id),e.totalViolations+=P,m+=P;let q=String(h.impact??"unknown");e.impactCounts.set(q,(e.impactCounts.get(q)||0)+P)}return m},0)>0&&e.pagesWithViolations++});let t=[];c.forEach(({url:p,result:f})=>{f&&f.violations.forEach(m=>{m.nodes.forEach(h=>{let P=Array.isArray(h.target)?h.target.join("; "):String(h.target);t.push(`
22
22
  <tr>
23
23
  <td class="nowrap">${le(p)}</td>
24
24
  <td class="nowrap">${le(m.id)}</td>
@@ -103,7 +103,7 @@
103
103
  </table>
104
104
  </body>
105
105
  </html>
106
- `.trim()}function le(c){return String(c??"").replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll('"',"&quot;").replaceAll("'","&#39;")}function vt(c){return String(c??"").toLowerCase().replace(/[^a-z0-9]+/g,"-")}var St=L(()=>{"use strict"});async function bs(){return ge||(ge=await Tt.chromium.launch({headless:!0,args:["--disable-extensions","--disable-blink-features=AutomationControlled"]})),ge}async function vs(){return me||(me=await(await bs()).newContext({permissions:[],ignoreHTTPSErrors:!0})),me}async function Ct(){return await(await vs()).newPage()}async function kt(){me&&(await me.close(),me=null),ge&&(await ge.close(),ge=null)}var Tt,ge,me,et=L(()=>{"use strict";Tt=require("playwright"),ge=null,me=null});function he(c){return c==="required"||c==="recommended"||c==="optional"?c:$s}function be(c){return c==="minimal"||c==="balanced"||c==="strict"||c==="paranoid"?c:"balanced"}function At(c,e){return{minimal:{required:"error",recommended:"ignore",optional:"ignore"},balanced:{required:"error",recommended:"warning",optional:"ignore"},strict:{required:"error",recommended:"error",optional:"warning"},paranoid:{required:"error",recommended:"error",optional:"error"}}[e][c]}var $s,tt=L(()=>{"use strict";$s="required"});var I={};K(I,{default:()=>Rt.default});var Rt,ve=L(()=>{"use strict";Ce(I,require("playwright/test"));Rt=j(require("playwright/test"),1)});var Et={};K(Et,{MenuComponentStrategy:()=>st});var st,xt=L(()=>{"use strict";ve();st=class{constructor(e,t,r=400,s=400){this.mainSelector=e;this.selectors=t;this.actionTimeoutMs=r;this.assertionTimeoutMs=s}async resetState(e){if(!this.selectors.popup)return;let t=this.selectors.popup,r=e.locator(t).first();if(!await r.isVisible().catch(()=>!1))return;let i=!1,o=this.selectors.input;if(!o&&this.selectors.focusable?o=this.selectors.focusable:o||(o=this.selectors.main),o&&(await e.locator(o).first().focus(),await e.keyboard.press("Escape"),i=await(0,I.expect)(r).toBeHidden({timeout:this.assertionTimeoutMs}).then(()=>!0).catch(()=>!1)),!i&&this.selectors.main&&(await e.locator(this.selectors.main).first().click({timeout:this.actionTimeoutMs}),i=await(0,I.expect)(r).toBeHidden({timeout:this.assertionTimeoutMs}).then(()=>!0).catch(()=>!1)),i||(await e.mouse.click(10,10),i=await(0,I.expect)(r).toBeHidden({timeout:this.assertionTimeoutMs}).then(()=>!0).catch(()=>!1)),!i)throw new Error(`\u274C FATAL: Cannot close menu between tests. Menu remains visible after trying:
106
+ `.trim()}function le(c){return String(c??"").replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll('"',"&quot;").replaceAll("'","&#39;")}function vt(c){return String(c??"").toLowerCase().replace(/[^a-z0-9]+/g,"-")}var St=L(()=>{"use strict"});async function bs(){return de||(de=await Tt.chromium.launch({headless:!0,args:["--disable-extensions","--disable-blink-features=AutomationControlled"]})),de}async function vs(){return me||(me=await(await bs()).newContext({permissions:[],ignoreHTTPSErrors:!0})),me}async function Ct(){return await(await vs()).newPage()}async function kt(){me&&(await me.close(),me=null),de&&(await de.close(),de=null)}var Tt,de,me,et=L(()=>{"use strict";Tt=require("playwright"),de=null,me=null});function he(c){return c==="required"||c==="recommended"||c==="optional"?c:$s}function be(c){return c==="minimal"||c==="balanced"||c==="strict"||c==="paranoid"?c:"balanced"}function At(c,e){return{minimal:{required:"error",recommended:"ignore",optional:"ignore"},balanced:{required:"error",recommended:"warning",optional:"ignore"},strict:{required:"error",recommended:"error",optional:"warning"},paranoid:{required:"error",recommended:"error",optional:"error"}}[e][c]}var $s,tt=L(()=>{"use strict";$s="required"});var I={};K(I,{default:()=>Rt.default});var Rt,ve=L(()=>{"use strict";Ce(I,require("playwright/test"));Rt=j(require("playwright/test"),1)});var Et={};K(Et,{MenuComponentStrategy:()=>st});var st,xt=L(()=>{"use strict";ve();st=class{constructor(e,t,r=400,s=400){this.mainSelector=e;this.selectors=t;this.actionTimeoutMs=r;this.assertionTimeoutMs=s}async resetState(e){if(!this.selectors.popup)return;let t=this.selectors.popup,r=e.locator(t).first();if(!await r.isVisible().catch(()=>!1))return;let i=!1,o=this.selectors.input;if(!o&&this.selectors.focusable?o=this.selectors.focusable:o||(o=this.selectors.main),o&&(await e.locator(o).first().focus(),await e.keyboard.press("Escape"),i=await(0,I.expect)(r).toBeHidden({timeout:this.assertionTimeoutMs}).then(()=>!0).catch(()=>!1)),!i&&this.selectors.main&&(await e.locator(this.selectors.main).first().click({timeout:this.actionTimeoutMs}),i=await(0,I.expect)(r).toBeHidden({timeout:this.assertionTimeoutMs}).then(()=>!0).catch(()=>!1)),i||(await e.mouse.click(10,10),i=await(0,I.expect)(r).toBeHidden({timeout:this.assertionTimeoutMs}).then(()=>!0).catch(()=>!1)),!i)throw new Error(`\u274C FATAL: Cannot close menu between tests. Menu remains visible after trying:
107
107
  1. Escape key
108
108
  2. Clicking trigger
109
109
  3. Clicking outside
@@ -138,9 +138,9 @@ This usually means:
138
138
  - The component didn't render
139
139
  - The URL is incorrect
140
140
  - The component selector '${se}' in the contract is wrong
141
- - Original error: ${n}`)}a.start(c,Se,Fe),c==="menu"&&v.selectors.main&&await R.locator(v.selectors.main).first().waitFor({state:"visible",timeout:U}).catch(()=>{});let re=c==="menu"&&v.selectors.submenuTrigger?await R.locator(v.selectors.submenuTrigger).count()>0:!1,Q=n=>n.type==="aria-reference"&&[n.from,n.to].some(g=>["submenu","submenuTrigger","submenuItems"].includes(g||""))||n.type==="contains"&&[n.parent,n.child].some(g=>["submenu","submenuTrigger","submenuItems"].includes(g||"")),ie=0,G=0,Y=0;for(let n of v.relationships||[]){if(S&&typeof S.resetState=="function")try{await S.resetState(R)}catch(b){ae.push(`Warning: resetState failed before relationship test: ${b instanceof Error?b.message:String(b)}`)}let g=he(n.level);if(Array.isArray(n.setup)&&n.setup.length>0){let E=function(u){return A.includes(u)};var pt=E;let b=new ye(R,v.selectors,P),x=n.type==="aria-reference"?`${n.from}.${n.attribute} references ${n.to}`:`${n.parent} contains ${n.child}`,A=["focus","type","click","keypress","hover"],C=u=>({...u,type:E(u.type)?u.type:"click"}),k=n.setup.map(C),y=await Ve(k,b,S,R,x,["submenu","submenuTrigger","submenuItems"]);if(y.skip){J.push(y.message||"Setup action skipped"),a.reportStaticTest(x,"skip",y.message,g);continue}if(!y.success){let u=`Relationship setup failed: ${y.error}`,w=H(u,n.level);w.status==="fail"&&(G+=1),w.status==="warn"&&(Y+=1),a.reportStaticTest(x,w.status,w.detail,w.level);continue}}if(c==="menu"&&!re&&Q(n)){let x=n.type==="aria-reference"?`${n.from}.${n.attribute} references ${n.to}`:`${n.parent} contains ${n.child}`,A="Skipping submenu relationship assertion: no submenu capability detected in rendered component.";J.push(A),a.reportStaticTest(x,"skip",A,g);continue}if(n.type==="aria-reference"){let b=`${n.from}.${n.attribute} references ${n.to}`,x=v.selectors[n.from],A=v.selectors[n.to];if(!x||!A){let T=H(`Relationship selector missing: from="${n.from}" or to="${n.to}" not found in selectors.`,n.level);T.status==="fail"&&(G+=1),T.status==="warn"&&(Y+=1),a.reportStaticTest(b,T.status,T.detail,T.level);continue}let E=R.locator(x).first(),C=R.locator(A).first(),k=await E.count()>0,y=await C.count()>0;if(!k||!y){if(c==="menu"&&Q(n)){let we="Skipping submenu relationship assertion in static phase: submenu elements are not present until submenu is opened.";J.push(we),a.reportStaticTest(b,"skip",we,g);continue}let T=H(`Relationship target not found: ${k?n.to:n.from}.`,n.level);T.status==="fail"&&(G+=1),T.status==="warn"&&(Y+=1),a.reportStaticTest(b,T.status,T.detail,T.level);continue}let u=await E.getAttribute(n.attribute),w=await C.getAttribute("id");if(!w){let T=H(`Relationship target "${n.to}" must have an id for ${n.attribute} validation.`,n.level);T.status==="fail"&&(G+=1),T.status==="warn"&&(Y+=1),a.reportStaticTest(b,T.status,T.detail,T.level);continue}if(!(u||"").split(/\s+/).filter(Boolean).includes(w)){let T=H(`Expected ${n.from} ${n.attribute} to reference id "${w}", found "${u||""}".`,n.level);T.status==="fail"&&(G+=1),T.status==="warn"&&(Y+=1),a.reportStaticTest(b,T.status,T.detail,T.level);continue}ce.push(`Relationship valid: ${n.from}.${n.attribute} -> ${n.to} (id=${w}).`),ie+=1,a.reportStaticTest(b,"pass",void 0,g);continue}if(n.type==="contains"){let b=`${n.parent} contains ${n.child}`,x=v.selectors[n.parent],A=v.selectors[n.child];if(!x||!A){let u=H(`Relationship selector missing: parent="${n.parent}" or child="${n.child}" not found in selectors.`,n.level);u.status==="fail"&&(G+=1),u.status==="warn"&&(Y+=1),a.reportStaticTest(b,u.status,u.detail,u.level);continue}let E=R.locator(x).first();if(!(await E.count()>0)){if(c==="menu"&&Q(n)){let w="Skipping submenu relationship assertion in static phase: submenu container is not present until submenu is opened.";J.push(w),a.reportStaticTest(b,"skip",w,g);continue}let u=H(`Relationship parent target not found: ${n.parent}.`,n.level);u.status==="fail"&&(G+=1),u.status==="warn"&&(Y+=1),a.reportStaticTest(b,u.status,u.detail,u.level);continue}if(await E.locator(A).count()<1){if(c==="menu"&&Q(n)){let w="Skipping submenu relationship assertion in static phase: submenu descendants are not present until submenu is opened.";J.push(w),a.reportStaticTest(b,"skip",w,g);continue}let u=H(`Expected ${n.parent} to contain descendant matching selector for ${n.child}.`,n.level);u.status==="fail"&&(G+=1),u.status==="warn"&&(Y+=1),a.reportStaticTest(b,u.status,u.detail,u.level);continue}ce.push(`Relationship valid: ${n.parent} contains ${n.child}.`),ie+=1,a.reportStaticTest(b,"pass",void 0,g)}}async function ft(n,g,b,x={}){if(!n||typeof n!="object"||!("ref"in n))return n;let A;if(n.ref==="relative"){if(!n.relativeTarget||!x.relativeBaseSelector)return;let E=b.locator(x.relativeBaseSelector),C=await E.count(),k=0;if(n.relativeTarget==="first"?k=0:n.relativeTarget==="second"?k=1:n.relativeTarget==="last"?k=C-1:isNaN(Number(n.relativeTarget))?k=0:k=Number(n.relativeTarget),k<0||k>=C)return;let y=E.nth(k);return await dt(y,n.property||n.attribute)}else{if(A=g[n.ref],!A)throw new Error(`Selector for ref '${n.ref}' not found in contract selectors.`);let E=b.locator(A).first();return await dt(E,n.property||n.attribute)}}async function dt(n,g){if(n)return!g||g==="id"?await n.getAttribute("id")??void 0:g==="class"?await n.getAttribute("class")??void 0:g==="textContent"?await n.evaluate(b=>b.textContent??void 0):g.startsWith("aria-")?await n.getAttribute(g)??void 0:g.endsWith("*")?await n.evaluate(x=>{let A=[];for(let E of Array.from(x.attributes))E.name.startsWith("aria-")&&A.push(`${E.name}=${E.value}`);return A.join(";")}):await n.getAttribute(g)??void 0}let is=new $e(R,v.selectors,q);async function Ve(n,g,b,x,A,E=[]){if(!Array.isArray(n)||n.length===0)return{success:!0};b&&typeof b.resetState=="function"&&await b.resetState(x);for(let C of n){let k={success:!0};try{if(C.type==="focus")C.target==="relative"&&C.relativeTarget?k=await g.focus("relative",C.relativeTarget):k=await g.focus(C.target);else if(C.type==="type"&&C.value)k=await g.type(C.target,C.value);else if(C.type==="click")k=await g.click(C.target,C.relativeTarget);else if(C.type==="keypress"&&C.key)k=await g.keypress(C.target,C.key);else if(C.type==="hover")k=await g.hover(C.target,C.relativeTarget);else continue}catch(y){k={success:!1,error:y instanceof Error?y.message:String(y)}}if(!k.success){let y=k.error||"Setup action failed";return E.some(w=>A.includes(w)||y.includes(w))?{success:!1,skip:!0,message:`Skipping test - capability not present: ${y}`}:{success:!1,error:y}}}return{success:!0}}for(let n of v.static[0]?.assertions||[]){if(S&&typeof S.resetState=="function")try{await S.resetState(R)}catch(y){ae.push(`Warning: resetState failed before static test: ${y instanceof Error?y.message:String(y)}`)}if(n.target==="relative")continue;let g=`${n.target}${n.attribute?` (${n.attribute})`:""}`,b=he(n.level);if(c==="menu"&&n.target==="submenuTrigger"&&!re){let y=`Skipping submenu static assertion for ${n.target}: no submenu capability detected in rendered component.`;J.push(y),a.reportStaticTest(g,"skip",y,b);continue}if(Array.isArray(n.setup)&&n.setup.length>0){let w=function(ne){return u.includes(ne)};var pt=w;let y=new ye(R,v.selectors,P),u=["focus","type","click","keypress","hover"],X=ne=>({...ne,type:w(ne.type)?ne.type:"click"}),F=n.setup.map(X),T=await Ve(F,y,S,R,g,["submenu","submenuTrigger","submenuItems"]);if(T.skip){J.push(T.message||"Setup action skipped"),a.reportStaticTest(g,"skip",T.message,b);continue}if(!T.success){let ne=`Static setup failed: ${T.error}`,d=H(ne,n.level);d.status==="fail"&&(G+=1),d.status==="warn"&&(Y+=1),a.reportStaticTest(g,d.status,d.detail,d.level);continue}}let x=v.selectors[n.target];if(!x){let y=`Selector for target ${n.target} not found.`,u=H(y,n.level);u.status==="fail"&&(G+=1),u.status==="warn"&&(Y+=1),a.reportStaticTest(g,u.status,u.detail,u.level);continue}let A=R.locator(x).first();if(!(await A.count()>0)){let y=`Target ${n.target} not found.`,u=H(y,n.level);u.status==="fail"&&(G+=1),u.status==="warn"&&(Y+=1),a.reportStaticTest(g,u.status,u.detail,u.level);continue}let C=(y,u,w)=>{let X=new RegExp(`\\[${u}(?:=["']?([^\\]"']+)["']?)?\\]`),F=y.match(X);if(!F)return!1;if(!w)return!0;let T=F[1];return T?w.split(" | ").includes(T):!1},k=n.expectedValue;if(n.expectedValue&&typeof n.expectedValue=="object"&&"ref"in n.expectedValue){let y={},u=n.relativeTarget;if(n.expectedValue.ref==="relative"&&n.target==="relative"&&u){let w=v.selectors[u];if(!w)throw new Error(`Selector for relativeTarget '${u}' not found in contract selectors.`);y.relativeBaseSelector=w}else if(n.expectedValue.ref==="relative"&&u){let w=v.selectors[u];if(!w)throw new Error(`Selector for relativeTarget '${u}' not found in contract selectors.`);y.relativeBaseSelector=w}k=await ft(n.expectedValue,v.selectors,R,y),console.log("Expected value in static check",k)}if(n.expectedValue)if(C(x,n.attribute,typeof k=="string"?k:void 0))ce.push(`${n.attribute}="${k}" on ${n.target} verified by selector (already present in: ${x}).`),ie+=1,a.reportStaticTest(g,"pass",void 0,b);else{let y=k??"",u=await is.validateAttribute(A,n.target,n.attribute,y,n.failureMessage,"Static ARIA Test");if(u.success&&u.passMessage)ce.push(u.passMessage),ie+=1,a.reportStaticTest(g,"pass",void 0,b);else if(!u.success&&u.failMessage){let w=H(u.failMessage,n.level);w.status==="fail"&&(G+=1),w.status==="warn"&&(Y+=1),a.reportStaticTest(g,w.status,w.detail,w.level)}}else{let y=n.attribute.split(" | "),u=!1,w=!0;for(let X of y){let F=X.trim();if(C(x,F)){ce.push(`${F} on ${n.target} verified by selector (already present in: ${x}).`),u=!0;continue}if(w=!1,await A.getAttribute(F)!==null){u=!0;break}}if(!u&&!w){let X=n.failureMessage+` None of the attributes "${n.attribute}" are present.`,F=H(X,n.level);F.status==="fail"&&(G+=1),F.status==="warn"&&(Y+=1),a.reportStaticTest(g,F.status,F.detail,F.level)}else!w&&u?(ce.push(`At least one of the attributes "${n.attribute}" exists on the element.`),ie+=1,a.reportStaticTest(g,"pass",void 0,b)):(ie+=1,a.reportStaticTest(g,"pass",void 0,b))}}for(let n of v.dynamic||[]){if(!R||R.isClosed()){console.warn(`
141
+ - Original error: ${n}`)}a.start(c,Se,Fe),c==="menu"&&v.selectors.main&&await R.locator(v.selectors.main).first().waitFor({state:"visible",timeout:U}).catch(()=>{});let re=c==="menu"&&v.selectors.submenuTrigger?await R.locator(v.selectors.submenuTrigger).count()>0:!1,Q=n=>n.type==="aria-reference"&&[n.from,n.to].some(d=>["submenu","submenuTrigger","submenuItems"].includes(d||""))||n.type==="contains"&&[n.parent,n.child].some(d=>["submenu","submenuTrigger","submenuItems"].includes(d||"")),ie=0,G=0,Y=0;for(let n of v.relationships||[]){if(S&&typeof S.resetState=="function")try{await S.resetState(R)}catch(b){ae.push(`Warning: resetState failed before relationship test: ${b instanceof Error?b.message:String(b)}`)}let d=he(n.level);if(Array.isArray(n.setup)&&n.setup.length>0){let E=function(u){return A.includes(u)};var pt=E;let b=new ye(R,v.selectors,P),x=n.type==="aria-reference"?`${n.from}.${n.attribute} references ${n.to}`:`${n.parent} contains ${n.child}`,A=["focus","type","click","keypress","hover"],C=u=>({...u,type:E(u.type)?u.type:"click"}),k=n.setup.map(C),y=await Ve(k,b,S,R,x,["submenu","submenuTrigger","submenuItems"]);if(y.skip){J.push(y.message||"Setup action skipped"),a.reportStaticTest(x,"skip",y.message,d);continue}if(!y.success){let u=`Relationship setup failed: ${y.error}`,w=H(u,n.level);w.status==="fail"&&(G+=1),w.status==="warn"&&(Y+=1),a.reportStaticTest(x,w.status,w.detail,w.level);continue}}if(c==="menu"&&!re&&Q(n)){let x=n.type==="aria-reference"?`${n.from}.${n.attribute} references ${n.to}`:`${n.parent} contains ${n.child}`,A="Skipping submenu relationship assertion: no submenu capability detected in rendered component.";J.push(A),a.reportStaticTest(x,"skip",A,d);continue}if(n.type==="aria-reference"){let b=`${n.from}.${n.attribute} references ${n.to}`,x=v.selectors[n.from],A=v.selectors[n.to];if(!x||!A){let T=H(`Relationship selector missing: from="${n.from}" or to="${n.to}" not found in selectors.`,n.level);T.status==="fail"&&(G+=1),T.status==="warn"&&(Y+=1),a.reportStaticTest(b,T.status,T.detail,T.level);continue}let E=R.locator(x).first(),C=R.locator(A).first(),k=await E.count()>0,y=await C.count()>0;if(!k||!y){if(c==="menu"&&Q(n)){let we="Skipping submenu relationship assertion in static phase: submenu elements are not present until submenu is opened.";J.push(we),a.reportStaticTest(b,"skip",we,d);continue}let T=H(`Relationship target not found: ${k?n.to:n.from}.`,n.level);T.status==="fail"&&(G+=1),T.status==="warn"&&(Y+=1),a.reportStaticTest(b,T.status,T.detail,T.level);continue}let u=await E.getAttribute(n.attribute),w=await C.getAttribute("id");if(!w){let T=H(`Relationship target "${n.to}" must have an id for ${n.attribute} validation.`,n.level);T.status==="fail"&&(G+=1),T.status==="warn"&&(Y+=1),a.reportStaticTest(b,T.status,T.detail,T.level);continue}if(!(u||"").split(/\s+/).filter(Boolean).includes(w)){let T=H(`Expected ${n.from} ${n.attribute} to reference id "${w}", found "${u||""}".`,n.level);T.status==="fail"&&(G+=1),T.status==="warn"&&(Y+=1),a.reportStaticTest(b,T.status,T.detail,T.level);continue}ce.push(`Relationship valid: ${n.from}.${n.attribute} -> ${n.to} (id=${w}).`),ie+=1,a.reportStaticTest(b,"pass",void 0,d);continue}if(n.type==="contains"){let b=`${n.parent} contains ${n.child}`,x=v.selectors[n.parent],A=v.selectors[n.child];if(!x||!A){let u=H(`Relationship selector missing: parent="${n.parent}" or child="${n.child}" not found in selectors.`,n.level);u.status==="fail"&&(G+=1),u.status==="warn"&&(Y+=1),a.reportStaticTest(b,u.status,u.detail,u.level);continue}let E=R.locator(x).first();if(!(await E.count()>0)){if(c==="menu"&&Q(n)){let w="Skipping submenu relationship assertion in static phase: submenu container is not present until submenu is opened.";J.push(w),a.reportStaticTest(b,"skip",w,d);continue}let u=H(`Relationship parent target not found: ${n.parent}.`,n.level);u.status==="fail"&&(G+=1),u.status==="warn"&&(Y+=1),a.reportStaticTest(b,u.status,u.detail,u.level);continue}if(await E.locator(A).count()<1){if(c==="menu"&&Q(n)){let w="Skipping submenu relationship assertion in static phase: submenu descendants are not present until submenu is opened.";J.push(w),a.reportStaticTest(b,"skip",w,d);continue}let u=H(`Expected ${n.parent} to contain descendant matching selector for ${n.child}.`,n.level);u.status==="fail"&&(G+=1),u.status==="warn"&&(Y+=1),a.reportStaticTest(b,u.status,u.detail,u.level);continue}ce.push(`Relationship valid: ${n.parent} contains ${n.child}.`),ie+=1,a.reportStaticTest(b,"pass",void 0,d)}}async function ft(n,d,b,x={}){if(!n||typeof n!="object"||!("ref"in n))return n;let A;if(n.ref==="relative"){if(!n.relativeTarget||!x.relativeBaseSelector)return;let E=b.locator(x.relativeBaseSelector),C=await E.count(),k=0;if(n.relativeTarget==="first"?k=0:n.relativeTarget==="second"?k=1:n.relativeTarget==="last"?k=C-1:isNaN(Number(n.relativeTarget))?k=0:k=Number(n.relativeTarget),k<0||k>=C)return;let y=E.nth(k);return await gt(y,n.property||n.attribute)}else{if(A=d[n.ref],!A)throw new Error(`Selector for ref '${n.ref}' not found in contract selectors.`);let E=b.locator(A).first();return await gt(E,n.property||n.attribute)}}async function gt(n,d){if(n)return!d||d==="id"?await n.getAttribute("id")??void 0:d==="class"?await n.getAttribute("class")??void 0:d==="textContent"?await n.evaluate(b=>b.textContent??void 0):d.startsWith("aria-")?await n.getAttribute(d)??void 0:d.endsWith("*")?await n.evaluate(x=>{let A=[];for(let E of Array.from(x.attributes))E.name.startsWith("aria-")&&A.push(`${E.name}=${E.value}`);return A.join(";")}):await n.getAttribute(d)??void 0}let is=new $e(R,v.selectors,q);async function Ve(n,d,b,x,A,E=[]){if(!Array.isArray(n)||n.length===0)return{success:!0};b&&typeof b.resetState=="function"&&await b.resetState(x);for(let C of n){let k={success:!0};try{if(C.type==="focus")C.target==="relative"&&C.relativeTarget?k=await d.focus("relative",C.relativeTarget):k=await d.focus(C.target);else if(C.type==="type"&&C.value)k=await d.type(C.target,C.value);else if(C.type==="click")k=await d.click(C.target,C.relativeTarget);else if(C.type==="keypress"&&C.key)k=await d.keypress(C.target,C.key);else if(C.type==="hover")k=await d.hover(C.target,C.relativeTarget);else continue}catch(y){k={success:!1,error:y instanceof Error?y.message:String(y)}}if(!k.success){let y=k.error||"Setup action failed";return E.some(w=>A.includes(w)||y.includes(w))?{success:!1,skip:!0,message:`Skipping test - capability not present: ${y}`}:{success:!1,error:y}}}return{success:!0}}for(let n of v.static[0]?.assertions||[]){if(S&&typeof S.resetState=="function")try{await S.resetState(R)}catch(y){ae.push(`Warning: resetState failed before static test: ${y instanceof Error?y.message:String(y)}`)}if(n.target==="relative")continue;let d=`${n.target}${n.attribute?` (${n.attribute})`:""}`,b=he(n.level);if(c==="menu"&&n.target==="submenuTrigger"&&!re){let y=`Skipping submenu static assertion for ${n.target}: no submenu capability detected in rendered component.`;J.push(y),a.reportStaticTest(d,"skip",y,b);continue}if(Array.isArray(n.setup)&&n.setup.length>0){let w=function(ne){return u.includes(ne)};var pt=w;let y=new ye(R,v.selectors,P),u=["focus","type","click","keypress","hover"],X=ne=>({...ne,type:w(ne.type)?ne.type:"click"}),F=n.setup.map(X),T=await Ve(F,y,S,R,d,["submenu","submenuTrigger","submenuItems"]);if(T.skip){J.push(T.message||"Setup action skipped"),a.reportStaticTest(d,"skip",T.message,b);continue}if(!T.success){let ne=`Static setup failed: ${T.error}`,g=H(ne,n.level);g.status==="fail"&&(G+=1),g.status==="warn"&&(Y+=1),a.reportStaticTest(d,g.status,g.detail,g.level);continue}}let x=v.selectors[n.target];if(!x){let y=`Selector for target ${n.target} not found.`,u=H(y,n.level);u.status==="fail"&&(G+=1),u.status==="warn"&&(Y+=1),a.reportStaticTest(d,u.status,u.detail,u.level);continue}let A=R.locator(x).first();if(!(await A.count()>0)){let y=`Target ${n.target} not found.`,u=H(y,n.level);u.status==="fail"&&(G+=1),u.status==="warn"&&(Y+=1),a.reportStaticTest(d,u.status,u.detail,u.level);continue}let C=(y,u,w)=>{let X=new RegExp(`\\[${u}(?:=["']?([^\\]"']+)["']?)?\\]`),F=y.match(X);if(!F)return!1;if(!w)return!0;let T=F[1];return T?w.split(" | ").includes(T):!1},k=n.expectedValue;if(n.expectedValue&&typeof n.expectedValue=="object"&&"ref"in n.expectedValue){let y={},u=n.relativeTarget;if(n.expectedValue.ref==="relative"&&n.target==="relative"&&u){let w=v.selectors[u];if(!w)throw new Error(`Selector for relativeTarget '${u}' not found in contract selectors.`);y.relativeBaseSelector=w}else if(n.expectedValue.ref==="relative"&&u){let w=v.selectors[u];if(!w)throw new Error(`Selector for relativeTarget '${u}' not found in contract selectors.`);y.relativeBaseSelector=w}k=await ft(n.expectedValue,v.selectors,R,y),console.log("Expected value in static check",k)}if(n.expectedValue)if(C(x,n.attribute,typeof k=="string"?k:void 0))ce.push(`${n.attribute}="${k}" on ${n.target} verified by selector (already present in: ${x}).`),ie+=1,a.reportStaticTest(d,"pass",void 0,b);else{let y=k??"",u=await is.validateAttribute(A,n.target,n.attribute,y,n.failureMessage,"Static ARIA Test");if(u.success&&u.passMessage)ce.push(u.passMessage),ie+=1,a.reportStaticTest(d,"pass",void 0,b);else if(!u.success&&u.failMessage){let w=H(u.failMessage,n.level);w.status==="fail"&&(G+=1),w.status==="warn"&&(Y+=1),a.reportStaticTest(d,w.status,w.detail,w.level)}}else{let y=n.attribute.split(" | "),u=!1,w=!0;for(let X of y){let F=X.trim();if(C(x,F)){ce.push(`${F} on ${n.target} verified by selector (already present in: ${x}).`),u=!0;continue}if(w=!1,await A.getAttribute(F)!==null){u=!0;break}}if(!u&&!w){let X=n.failureMessage+` None of the attributes "${n.attribute}" are present.`,F=H(X,n.level);F.status==="fail"&&(G+=1),F.status==="warn"&&(Y+=1),a.reportStaticTest(d,F.status,F.detail,F.level)}else!w&&u?(ce.push(`At least one of the attributes "${n.attribute}" exists on the element.`),ie+=1,a.reportStaticTest(d,"pass",void 0,b)):(ie+=1,a.reportStaticTest(d,"pass",void 0,b))}}for(let n of v.dynamic||[]){if(!R||R.isClosed()){console.warn(`
142
142
  \u26A0\uFE0F Browser closed - skipping remaining ${v.dynamic.length-v.dynamic.indexOf(n)} tests
143
- `),te.push(`CRITICAL: Browser/page closed before completing all tests. ${v.dynamic.length-v.dynamic.indexOf(n)} tests skipped.`);break}try{await S.resetState(R)}catch(d){let B=d instanceof Error?d.message:String(d);throw a.error(B),d}let{setup:g=[],action:b,assertions:x}=n,A=he(n.level),E=new ye(R,v.selectors,P);if(Array.isArray(g)&&g.length>0){let B=function(ee){return d.includes(ee)};var pt=B;let d=["focus","type","click","keypress","hover"],pe=ee=>({...ee,type:B(ee.type)?ee.type:"click"}),Ue=g.map(pe),Z=await Ve(Ue,E,S,R,n.description,["submenu","submenuTrigger","submenuItems"]);if(Z.skip){J.push(Z.message||"Setup action skipped"),a.reportTest({description:n.description,level:A},"skip",Z.message);continue}if(!Z.success){let ee=H(`Setup failed: ${Z.error}`,n.level);a.reportTest({description:n.description,level:A},ee.status,ee.detail);continue}}let C=te.length,k=ae.length,y=J.length;if(await S.shouldSkipTest(n,R)){let d="Skipping test - component-specific conditions not met";J.push(d),a.reportTest({description:n.description,level:A},"skip",d);continue}let w=new $e(R,v.selectors,q),X=!1,F=null;for(let d of b){if(!R||R.isClosed()){te.push("CRITICAL: Browser/page closed during test execution. Remaining actions skipped."),X=!0;break}let B;if(d.type==="focus")d.target==="relative"&&d.relativeTarget?B=await E.focus("relative",d.relativeTarget):B=await E.focus(d.target);else if(d.type==="type"&&d.value)B=await E.type(d.target,d.value);else if(d.type==="click")B=await E.click(d.target,d.relativeTarget);else if(d.type==="keypress"&&d.key)B=await E.keypress(d.target,d.key);else if(d.type==="hover")B=await E.hover(d.target,d.relativeTarget);else continue;if(!B.success){if(B.error){let pe=H(B.error,n.level);F={status:pe.status,detail:pe.detail}}X=!0;break}}if(X){a.reportTest({description:n.description,level:A},F?.status||"fail",F?.detail||te[te.length-1]);continue}for(let d of x){let B;if(d.expectedValue&&typeof d.expectedValue=="object"&&"ref"in d.expectedValue)if(d.expectedValue.ref==="relative"){let{RelativeTargetResolver:De}=await Promise.resolve().then(()=>(Be(),Ot)),ee=v.selectors.relative;if(!ee)throw new Error("Relative selector not defined in contract selectors.");let gt=d.relativeTarget||"first",Oe=await De.resolve(R,ee,gt);if(!Oe)throw new Error(`Could not resolve relative target '${gt}' for expectedValue.`);let mt=d.expectedValue.property||d.expectedValue.attribute||"id";if(mt==="textContent")B=await Oe.evaluate(Te=>Te.textContent??void 0);else{let Te=await Oe.getAttribute(mt);B=Te===null?void 0:Te}}else B=await ft(d.expectedValue,v.selectors,R,{});else typeof d.expectedValue=="string"||typeof d.expectedValue>"u"?B=d.expectedValue:B="";let pe={...d,expectedValue:B},Ue=B??"",Z=await w.validate({...pe,expectedValue:Ue},n.description);if(Z.success&&Z.passMessage)ce.push(Z.passMessage);else if(!Z.success&&Z.failMessage){let De=he(d.level||n.level);if(H(Z.failMessage,De).status==="skip")continue}}let T=te.length,we=ae.length,ne=J.length;T>C?a.reportTest({description:n.description,level:A},"fail",te[te.length-1]):we>k?a.reportTest({description:n.description,level:A},"warn",ae[ae.length-1]):ne>y?a.reportTest({description:n.description,level:A},"skip",J[J.length-1]):a.reportTest({description:n.description,level:A},"pass")}a.reportStatic(ie,G,Y),a.summary(te)}catch(S){if(S instanceof Error)throw S.message.includes("Executable doesn't exist")||S.message.includes("browserType.launch")?new Error(`
143
+ `),te.push(`CRITICAL: Browser/page closed before completing all tests. ${v.dynamic.length-v.dynamic.indexOf(n)} tests skipped.`);break}try{await S.resetState(R)}catch(g){let B=g instanceof Error?g.message:String(g);throw a.error(B),g}let{setup:d=[],action:b,assertions:x}=n,A=he(n.level),E=new ye(R,v.selectors,P);if(Array.isArray(d)&&d.length>0){let B=function(ee){return g.includes(ee)};var pt=B;let g=["focus","type","click","keypress","hover"],pe=ee=>({...ee,type:B(ee.type)?ee.type:"click"}),Ue=d.map(pe),Z=await Ve(Ue,E,S,R,n.description,["submenu","submenuTrigger","submenuItems"]);if(Z.skip){J.push(Z.message||"Setup action skipped"),a.reportTest({description:n.description,level:A},"skip",Z.message);continue}if(!Z.success){let ee=H(`Setup failed: ${Z.error}`,n.level);a.reportTest({description:n.description,level:A},ee.status,ee.detail);continue}}let C=te.length,k=ae.length,y=J.length;if(await S.shouldSkipTest(n,R)){let g="Skipping test - component-specific conditions not met";J.push(g),a.reportTest({description:n.description,level:A},"skip",g);continue}let w=new $e(R,v.selectors,q),X=!1,F=null;for(let g of b){if(!R||R.isClosed()){te.push("CRITICAL: Browser/page closed during test execution. Remaining actions skipped."),X=!0;break}let B;if(g.type==="focus")g.target==="relative"&&g.relativeTarget?B=await E.focus("relative",g.relativeTarget):B=await E.focus(g.target);else if(g.type==="type"&&g.value)B=await E.type(g.target,g.value);else if(g.type==="click")B=await E.click(g.target,g.relativeTarget);else if(g.type==="keypress"&&g.key)B=await E.keypress(g.target,g.key);else if(g.type==="hover")B=await E.hover(g.target,g.relativeTarget);else continue;if(!B.success){if(B.error){let pe=H(B.error,n.level);F={status:pe.status,detail:pe.detail}}X=!0;break}}if(X){a.reportTest({description:n.description,level:A},F?.status||"fail",F?.detail||te[te.length-1]);continue}for(let g of x){let B;if(g.expectedValue&&typeof g.expectedValue=="object"&&"ref"in g.expectedValue)if(g.expectedValue.ref==="relative"){let{RelativeTargetResolver:De}=await Promise.resolve().then(()=>(Be(),Ot)),ee=v.selectors.relative;if(!ee)throw new Error("Relative selector not defined in contract selectors.");let dt=g.relativeTarget||"first",Oe=await De.resolve(R,ee,dt);if(!Oe)throw new Error(`Could not resolve relative target '${dt}' for expectedValue.`);let mt=g.expectedValue.property||g.expectedValue.attribute||"id";if(mt==="textContent")B=await Oe.evaluate(Te=>Te.textContent??void 0);else{let Te=await Oe.getAttribute(mt);B=Te===null?void 0:Te}}else B=await ft(g.expectedValue,v.selectors,R,{});else typeof g.expectedValue=="string"||typeof g.expectedValue>"u"?B=g.expectedValue:B="";let pe={...g,expectedValue:B},Ue=B??"",Z=await w.validate({...pe,expectedValue:Ue},n.description);if(Z.success&&Z.passMessage)ce.push(Z.passMessage);else if(!Z.success&&Z.failMessage){let De=he(g.level||n.level);if(H(Z.failMessage,De).status==="skip")continue}}let T=te.length,we=ae.length,ne=J.length;T>C?a.reportTest({description:n.description,level:A},"fail",te[te.length-1]):we>k?a.reportTest({description:n.description,level:A},"warn",ae[ae.length-1]):ne>y?a.reportTest({description:n.description,level:A},"skip",J[J.length-1]):a.reportTest({description:n.description,level:A},"pass")}a.reportStatic(ie,G,Y),a.summary(te)}catch(S){if(S instanceof Error)throw S.message.includes("Executable doesn't exist")||S.message.includes("browserType.launch")?new Error(`
144
144
  \u274C CRITICAL: Playwright browsers not found!
145
145
  \u{1F4E6} Run: npx playwright install chromium`):S.message.includes("net::ERR_CONNECTION_REFUSED")||S.message.includes("NS_ERROR_CONNECTION_REFUSED")?new Error(`
146
146
  \u274C CRITICAL: Cannot connect to dev server!
package/dist/cli.js CHANGED
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import{a as x}from"./chunk-ZNQ5BXVJ.js";import{c as R,d as C}from"./chunk-52I3INNG.js";import"./chunk-CNU4N4AY.js";import{Command as S}from"commander";import o from"chalk";import w from"path";import A from"fs-extra";var l=new S;l.name("aria-ease").description("Run accessibility tests and audits").version("2.2.3");l.command("audit").description("Run axe-core powered accessibility audit on webpages").option("-u, --url <url>","Single URL to audit").option("-f, --format <format>","Output format for the audit report: json | csv | html | all","all").option("-o, --out <path>","Directory to save the audit report","./accessibility-reports/audit").action(async n=>{console.log(o.cyanBright(`\u{1F680} Starting accessibility audit...
3
- `));let{runAudit:h}=await import("./audit-APAPHXRO.js"),{formatResults:f}=await import("./formatters-H3CPDLG5.js"),c=!n.url,{config:s,configPath:u,errors:i}=await x(process.cwd());u?console.log(o.green(`\u2705 Loaded config from ${w.basename(u)}
3
+ `));let{runAudit:h}=await import("./audit-WBKVW7H6.js"),{formatResults:f}=await import("./formatters-H3CPDLG5.js"),c=!n.url,{config:s,configPath:u,errors:i}=await x(process.cwd());u?console.log(o.green(`\u2705 Loaded config from ${w.basename(u)}
4
4
  `)):i.length>0&&c?(console.log(o.red(`\u274C Config file errors:
5
5
  `)),i.forEach(e=>console.log(o.red(` ${e}`))),console.log(""),process.exit(1)):i.length>0?console.log(o.yellow(`\u26A0\uFE0F Config file has errors (ignored, using CLI options)
6
6
  `)):!u&&c&&console.log(o.yellow(`\u2139\uFE0F No config file found, using CLI options.
7
- `));let d=[];n.url?d.push(n.url):s.audit?.urls&&Array.isArray(s.audit.urls)&&d.push(...s.audit.urls);let m=s.audit?.output&&s.audit.output.format||n.format;["json","csv","html","all"].includes(m)||(console.log(o.red('\u274C Invalid format. Use "json", "csv", "html" or "all".')),process.exit(1)),d.length===0&&(console.log(o.red('\u274C No URLs provided. Use --url option or add "urls" in config file')),process.exit(1));let r=[],{createAuditBrowser:B}=await import("./audit-APAPHXRO.js"),y=await B();try{let e={browser:y};for(let t of d){console.log(o.yellow(`\u{1F50E} Auditing: ${t}`));try{let a=await h(t,e);r.push({url:t,result:a}),console.log(o.green(`\u2705 Completed audit for ${t}
7
+ `));let d=[];n.url?d.push(n.url):s.audit?.urls&&Array.isArray(s.audit.urls)&&d.push(...s.audit.urls);let m=s.audit?.output&&s.audit.output.format||n.format;["json","csv","html","all"].includes(m)||(console.log(o.red('\u274C Invalid format. Use "json", "csv", "html" or "all".')),process.exit(1)),d.length===0&&(console.log(o.red('\u274C No URLs provided. Use --url option or add "urls" in config file')),process.exit(1));let r=[],{createAuditBrowser:B}=await import("./audit-WBKVW7H6.js"),y=await B();try{let e={browser:y};for(let t of d){console.log(o.yellow(`\u{1F50E} Auditing: ${t}`));try{let a=await h(t,e);r.push({url:t,result:a}),console.log(o.green(`\u2705 Completed audit for ${t}
8
8
  `))}catch(a){a instanceof Error&&a.message&&console.log(o.red(`\u274C Failed auditing ${t}: ${a.message}`))}}}finally{await y.close()}if(!r.some(e=>e.result&&e.result.violations&&e.result.violations.length>0)){let e=r.filter(t=>t.result).length;e===0&&(console.log(o.red("\u274C No pages were successfully audited.")),process.exit(1)),console.log(o.green(`
9
9
  \u{1F389} Great news! No static accessibility violations found!`)),console.log(o.gray(` Audited ${e} page${e>1?"s":""} successfully.
10
10
  `)),R("audit"),await C("audit",process.cwd()),console.log(o.dim(`