aria-ease 7.5.0 → 7.8.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.
Files changed (57) hide show
  1. package/README.md +66 -81
  2. package/dist/ToggleComponentStrategy-TMRNXFSL.js +1 -0
  3. package/dist/cli.cjs +63 -63
  4. package/dist/cli.js +1 -1
  5. package/dist/contractTestRunnerPlaywright-CHCVW7VO.js +46 -0
  6. package/dist/contractTestRunnerPlaywright-FECB4HSX.js +46 -0
  7. package/dist/index.cjs +36 -36
  8. package/dist/index.d.cts +18 -19
  9. package/dist/index.d.ts +18 -19
  10. package/dist/index.js +10 -10
  11. package/dist/src/{Types.d-D96FYkCN.d.cts → Types.d-BjBTlIzl.d.cts} +18 -8
  12. package/dist/src/{Types.d-D96FYkCN.d.ts → Types.d-BjBTlIzl.d.ts} +18 -8
  13. package/dist/src/accordion/index.cjs +1 -1
  14. package/dist/src/accordion/index.d.cts +1 -1
  15. package/dist/src/accordion/index.d.ts +1 -1
  16. package/dist/src/accordion/index.js +1 -1
  17. package/dist/src/block/index.d.cts +1 -1
  18. package/dist/src/block/index.d.ts +1 -1
  19. package/dist/src/checkbox/index.cjs +1 -1
  20. package/dist/src/checkbox/index.d.cts +1 -1
  21. package/dist/src/checkbox/index.d.ts +1 -1
  22. package/dist/src/checkbox/index.js +1 -1
  23. package/dist/src/combobox/index.cjs +1 -1
  24. package/dist/src/combobox/index.d.cts +1 -1
  25. package/dist/src/combobox/index.d.ts +1 -1
  26. package/dist/src/combobox/index.js +1 -1
  27. package/dist/src/menu/index.cjs +1 -1
  28. package/dist/src/menu/index.d.cts +1 -1
  29. package/dist/src/menu/index.d.ts +1 -1
  30. package/dist/src/menu/index.js +1 -1
  31. package/dist/src/radio/index.cjs +1 -1
  32. package/dist/src/radio/index.d.cts +1 -1
  33. package/dist/src/radio/index.d.ts +1 -1
  34. package/dist/src/radio/index.js +1 -1
  35. package/dist/src/tabs/index.cjs +1 -1
  36. package/dist/src/tabs/index.d.cts +1 -2
  37. package/dist/src/tabs/index.d.ts +1 -2
  38. package/dist/src/tabs/index.js +1 -1
  39. package/dist/src/toggle/index.cjs +1 -1
  40. package/dist/src/toggle/index.d.cts +2 -7
  41. package/dist/src/toggle/index.d.ts +2 -7
  42. package/dist/src/toggle/index.js +1 -1
  43. package/dist/src/utils/test/ToggleComponentStrategy-UOGYK2U4.js +1 -0
  44. package/dist/src/utils/test/contractTestRunnerPlaywright-7ERFIHCM.js +46 -0
  45. package/dist/src/utils/test/dsl/index.cjs +1 -1
  46. package/dist/src/utils/test/dsl/index.d.cts +0 -5
  47. package/dist/src/utils/test/dsl/index.d.ts +0 -5
  48. package/dist/src/utils/test/dsl/index.js +1 -1
  49. package/dist/src/utils/test/index.cjs +29 -29
  50. package/dist/src/utils/test/index.d.cts +4 -3
  51. package/dist/src/utils/test/index.d.ts +4 -3
  52. package/dist/src/utils/test/index.js +1 -1
  53. package/dist/{test-FURQN5KO.js → test-CMD6E5YF.js} +1 -1
  54. package/package.json +1 -1
  55. package/dist/contractTestRunnerPlaywright-75NI6SN7.js +0 -46
  56. package/dist/contractTestRunnerPlaywright-VLOD5IB3.js +0 -46
  57. package/dist/src/utils/test/contractTestRunnerPlaywright-FSZDW7IR.js +0 -46
package/dist/cli.cjs CHANGED
@@ -1,15 +1,15 @@
1
1
  #!/usr/bin/env node
2
- "use strict";var ps=Object.create;var He=Object.defineProperty;var fs=Object.getOwnPropertyDescriptor;var ds=Object.getOwnPropertyNames;var gs=Object.getPrototypeOf,ms=Object.prototype.hasOwnProperty;var L=(c,e)=>()=>(c&&(e=c(c=0)),e);var G=(c,e)=>{for(var t in e)He(c,t,{get:e[t],enumerable:!0})},Oe=(c,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of ds(e))!ms.call(c,s)&&s!==t&&He(c,s,{get:()=>e[s],enumerable:!(r=fs(e,s))||r.enumerable});return c},Ae=(c,e,t)=>(Oe(c,e,"default"),t&&Oe(t,e,"default")),F=(c,e,t)=>(t=c!=null?ps(gs(c)):{},Oe(e||!c||!c.__esModule?He(t,"default",{value:c,enumerable:!0}):t,c));var _e={};G(_e,{loadConfig:()=>Je});function hs(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 n=["actionTimeoutMs","assertionTimeoutMs","navigationTimeoutMs","componentReadyTimeoutMs"];for(let a of n){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 ys(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 n=Ne.default.resolve(c,i);if(await We.default.pathExists(n)){if(r=n,t=await ys(n),t===null){s.push(`Found config at ${i} but failed to load it. Check for syntax errors.`);continue}let a=hs(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,Re=L(()=>{"use strict";Ne=F(require("path"),1),We=F(require("fs-extra"),1)});var vt={};G(vt,{BADGE_CONFIGS:()=>ze,displayAllBadges:()=>ws,displayBadgeInfo:()=>Ge,getBadgeMarkdown:()=>he,promptAddBadge:()=>Ye});function he(c){let e=ze[c];return`[![${e.label}](${e.markdownUrl})](https://github.com/aria-ease/aria-ease)`}function Ge(c){let e=he(c);console.log(O.default.cyan(`
2
+ "use strict";var ys=Object.create;var He=Object.defineProperty;var bs=Object.getOwnPropertyDescriptor;var ws=Object.getOwnPropertyNames;var vs=Object.getPrototypeOf,$s=Object.prototype.hasOwnProperty;var I=(c,e)=>()=>(c&&(e=c(c=0)),e);var W=(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 ws(e))!$s.call(c,s)&&s!==t&&He(c,s,{get:()=>e[s],enumerable:!(r=bs(e,s))||r.enumerable});return c},ke=(c,e,t)=>(qe(c,e,"default"),t&&qe(t,e,"default")),F=(c,e,t)=>(t=c!=null?ys(vs(c)):{},qe(e||!c||!c.__esModule?He(t,"default",{value:c,enumerable:!0}):t,c));var _e={};W(_e,{loadConfig:()=>Je});function Ss(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 o=t.test[s];o!==void 0&&(typeof o!="number"||!Number.isFinite(o)||o<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,o)=>{if(typeof s!="object"||s===null)e.push(`test.components[${o}] must be an object`);else{typeof s.name!="string"&&e.push(`test.components[${o}].name must be a string`),s.contractPath!==void 0&&typeof s.contractPath!="string"&&e.push(`test.components[${o}].contractPath must be a string when provided`),s.strategyPath!==void 0&&typeof s.strategyPath!="string"&&e.push(`test.components[${o}].strategyPath must be a string when provided`),s.strictness!==void 0&&!["minimal","balanced","strict","paranoid"].includes(s.strictness)&&e.push(`test.components[${o}].strictness must be one of: minimal, balanced, strict, paranoid`),s.disableTimeouts!==void 0&&typeof s.disableTimeouts!="boolean"&&e.push(`test.components[${o}].disableTimeouts must be a boolean when provided`);let n=["actionTimeoutMs","assertionTimeoutMs","navigationTimeoutMs","componentReadyTimeoutMs"];for(let a of n){let l=s[a];l!==void 0&&(typeof l!="number"||!Number.isFinite(l)||l<0)&&e.push(`test.components[${o}].${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 Ts(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 o of e){let n=Ne.default.resolve(c,o);if(await We.default.pathExists(n)){if(r=n,t=await Ts(n),t===null){s.push(`Found config at ${o} but failed to load it. Check for syntax errors.`);continue}let a=Ss(t);if(!a.valid){s.push(`Config validation failed in ${o}:`),s.push(...a.errors.map(l=>` - ${l}`)),t=null;continue}break}}return{config:t||{},configPath:t?r:null,errors:s}}var Ne,We,Ae=I(()=>{"use strict";Ne=F(require("path"),1),We=F(require("fs-extra"),1)});var St={};W(St,{BADGE_CONFIGS:()=>ze,displayAllBadges:()=>ks,displayBadgeInfo:()=>Ge,getBadgeMarkdown:()=>me,promptAddBadge:()=>Ye});function me(c){let e=ze[c];return`[![${e.label}](${e.markdownUrl})](https://github.com/aria-ease/aria-ease)`}function Ge(c){let e=me(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
- `))}async function Ye(c,e=process.cwd()){let t=bt.default.join(e,"README.md");if(!await Ee.default.pathExists(t)){console.log(O.default.yellow(" \u2139\uFE0F No README.md found in current directory"));return}let s=await Ee.default.readFile(t,"utf-8"),i=he(c);if(s.includes(i)||s.includes(ze[c].fileName)){console.log(O.default.gray(" \u2713 Badge already in README.md"));return}let n=wt.default.createInterface({input:process.stdin,output:process.stdout}),a=await new Promise(l=>{n.question(O.default.cyan(" Add badge to README.md now? (y/n): "),u=>{n.close(),l(u.toLowerCase().trim())})});a==="y"||a==="yes"?(await bs(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 bs(c,e,t){let r=e.split(`
7
- `),s=0;for(let i=0;i<r.length;i++){let n=r[i].trim();if(n.startsWith("[![")||n.startsWith("[!")){s=i+1;continue}if(s>0&&!n.startsWith("[![")&&!n.startsWith("[!")&&n.length>0)break;if(s===0&&n.startsWith("#")){s=i+2;break}}s===0&&(s=1),r.splice(s,0,t),await Ee.default.writeFile(c,r.join(`
8
- `),"utf-8")}function ws(){console.log(O.default.cyan(`
6
+ `))}async function Ye(c,e=process.cwd()){let t=vt.default.join(e,"README.md");if(!await Re.default.pathExists(t)){console.log(O.default.yellow(" \u2139\uFE0F No README.md found in current directory"));return}let s=await Re.default.readFile(t,"utf-8"),o=me(c);if(s.includes(o)||s.includes(ze[c].fileName)){console.log(O.default.gray(" \u2713 Badge already in README.md"));return}let n=$t.default.createInterface({input:process.stdin,output:process.stdout}),a=await new Promise(l=>{n.question(O.default.cyan(" Add badge to README.md now? (y/n): "),u=>{n.close(),l(u.toLowerCase().trim())})});a==="y"||a==="yes"?(await Cs(t,s,o),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 Cs(c,e,t){let r=e.split(`
7
+ `),s=0;for(let o=0;o<r.length;o++){let n=r[o].trim();if(n.startsWith("[![")||n.startsWith("[!")){s=o+1;continue}if(s>0&&!n.startsWith("[![")&&!n.startsWith("[!")&&n.length>0)break;if(s===0&&n.startsWith("#")){s=o+2;break}}s===0&&(s=1),r.splice(s,0,t),await Re.default.writeFile(c,r.join(`
8
+ `),"utf-8")}function ks(){console.log(O.default.cyan(`
9
9
  \u{1F4CD} Available badges:`)),console.log(O.default.white(`
10
- For audits:`)),console.log(O.default.green(" "+he("audit"))),console.log(O.default.white(`
11
- For component testing:`)),console.log(O.default.green(" "+he("component"))),console.log(O.default.white(`
12
- For both (verified):`)),console.log(O.default.green(" "+he("verified"))),console.log("")}var Ee,bt,O,wt,ze,Ke=L(()=>{"use strict";Ee=F(require("fs-extra"),1),bt=F(require("path"),1),O=F(require("chalk"),1),wt=F(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={};G(Xe,{createAuditBrowser:()=>vs,runAudit:()=>$s});async function vs(){return await Qe.chromium.launch({headless:!0})}async function $s(c,e){let t=e.browser,r=!1,s=6e4,i="domcontentloaded";try{t||(t=await Qe.chromium.launch({headless:!0}),r=!0);let n=await t.newContext(),a=await n.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 u=await new $t.default({page:a}).withTags(["wcag2a","wcag2aa","wcag21a","wcag21aa"]).analyze();return await a.close(),await n.close(),u}catch(n){throw n instanceof Error?n.message.includes("Executable doesn't exist")?(console.error(`
10
+ For audits:`)),console.log(O.default.green(" "+me("audit"))),console.log(O.default.white(`
11
+ For component testing:`)),console.log(O.default.green(" "+me("component"))),console.log(O.default.white(`
12
+ For both (verified):`)),console.log(O.default.green(" "+me("verified"))),console.log("")}var Re,vt,O,$t,ze,Ke=I(()=>{"use strict";Re=F(require("fs-extra"),1),vt=F(require("path"),1),O=F(require("chalk"),1),$t=F(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={};W(Xe,{createAuditBrowser:()=>As,runAudit:()=>Rs});async function As(){return await Qe.chromium.launch({headless:!0})}async function Rs(c,e){let t=e.browser,r=!1,s=6e4,o="domcontentloaded";try{t||(t=await Qe.chromium.launch({headless:!0}),r=!0);let n=await t.newContext(),a=await n.newPage();await a.goto(c,{waitUntil:o,timeout:s});try{await a.waitForSelector("main",{state:"visible",timeout:s})}catch(p){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. ${p instanceof Error?p.message:String(p)}`)}let u=await new Tt.default({page:a}).withTags(["wcag2a","wcag2aa","wcag21a","wcag21aa"]).analyze();return await a.close(),await n.close(),u}catch(n){throw n instanceof Error?n.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,18 +17,18 @@
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")):n.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:",n.message),console.log(" Make sure you provide a valid URL")):console.error("\u274C Audit error (non-Error):",String(n)),n}finally{t&&r&&await t.close()}}var $t,Qe,Ze=L(()=>{"use strict";$t=F(require("@axe-core/playwright"),1),Qe=require("playwright")});var Tt={};G(Tt,{formatResults:()=>Ss});function Ss(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 Ts(c);case"html":return Cs(c);default:return""}}function Ts(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(ye(t)+","+ye(s.id)+","+ye(s.impact)+","+ye(s.description)+","+ye(Array.isArray(i.target)?i.target.join("; "):String(i.target))+","+ye(i.failureSummary??""))})})}),e.join(`
21
- `)}function ye(c){return`"${String(c??"").replace(/"/g,'""')}"`}function Cs(c){let e={pagesAudited:0,pagesWithViolations:0,totalViolations:0,distinctRules:new Set,impactCounts:new Map};c.forEach(({result:u})=>{if(!u)return;e.pagesAudited++,u.violations.reduce((h,y)=>{let j=(y.nodes||[]).length;if(j>0){e.distinctRules.add(y.id),e.totalViolations+=j,h+=j;let H=String(y.impact??"unknown");e.impactCounts.set(H,(e.impactCounts.get(H)||0)+j)}return h},0)>0&&e.pagesWithViolations++});let t=[];c.forEach(({url:u,result:f})=>{f&&f.violations.forEach(h=>{h.nodes.forEach(y=>{let j=Array.isArray(y.target)?y.target.join("; "):String(y.target);t.push(`
20
+ `):(console.error("\u274C Audit error:",n.message),console.log(" Make sure you provide a valid URL")):console.error("\u274C Audit error (non-Error):",String(n)),n}finally{t&&r&&await t.close()}}var Tt,Qe,Ze=I(()=>{"use strict";Tt=F(require("@axe-core/playwright"),1),Qe=require("playwright")});var kt={};W(kt,{formatResults:()=>Es});function Es(c,e){switch(e){case"json":return JSON.stringify(c.flatMap(({url:t,result:r})=>r?r.violations.flatMap(s=>s.nodes.map(o=>({URL:t,Rule:s.id,Impact:s.impact,Description:s.description,Target:o.target,FailureSummary:o.failureSummary}))):[]),null,2);case"csv":return xs(c);case"html":return Ms(c);default:return""}}function xs(c){let e=["URL,Rule,Impact,Description,Target,FailureSummary"];return c.forEach(({url:t,result:r})=>{r&&r.violations.forEach(s=>{s.nodes.forEach(o=>{e.push(he(t)+","+he(s.id)+","+he(s.impact)+","+he(s.description)+","+he(Array.isArray(o.target)?o.target.join("; "):String(o.target))+","+he(o.failureSummary??""))})})}),e.join(`
21
+ `)}function he(c){return`"${String(c??"").replace(/"/g,'""')}"`}function Ms(c){let e={pagesAudited:0,pagesWithViolations:0,totalViolations:0,distinctRules:new Set,impactCounts:new Map};c.forEach(({result:u})=>{if(!u)return;e.pagesAudited++,u.violations.reduce((h,y)=>{let L=(y.nodes||[]).length;if(L>0){e.distinctRules.add(y.id),e.totalViolations+=L,h+=L;let q=String(y.impact??"unknown");e.impactCounts.set(q,(e.impactCounts.get(q)||0)+L)}return h},0)>0&&e.pagesWithViolations++});let t=[];c.forEach(({url:u,result:p})=>{p&&p.violations.forEach(h=>{h.nodes.forEach(y=>{let L=Array.isArray(y.target)?y.target.join("; "):String(y.target);t.push(`
22
22
  <tr>
23
- <td class="nowrap">${pe(u)}</td>
24
- <td class="nowrap">${pe(h.id)}</td>
25
- <td class="impact ${St(String(h.impact??"unknown"))}">${pe(String(h.impact??""))}</td>
26
- <td class="desc">${pe(h.description??"")}</td>
27
- <td class="target"><code>${pe(j)}</code></td>
28
- <td class="fail">${pe(y.failureSummary??"").split(/\r?\n/).join("<br/>")}</td>
23
+ <td class="nowrap">${fe(u)}</td>
24
+ <td class="nowrap">${fe(h.id)}</td>
25
+ <td class="impact ${Ct(String(h.impact??"unknown"))}">${fe(String(h.impact??""))}</td>
26
+ <td class="desc">${fe(h.description??"")}</td>
27
+ <td class="target"><code>${fe(L)}</code></td>
28
+ <td class="fail">${fe(y.failureSummary??"").split(/\r?\n/).join("<br/>")}</td>
29
29
  </tr>
30
- `)})})});let r=Array.from(e.impactCounts.entries()).map(([u,f])=>`<li><strong class="impact ${St(u)}">${pe(u)}</strong>: ${f}</li>`).join(`
31
- `),s=new Date,i=u=>String(u).padStart(2,"0");return`
30
+ `)})})});let r=Array.from(e.impactCounts.entries()).map(([u,p])=>`<li><strong class="impact ${Ct(u)}">${fe(u)}</strong>: ${p}</li>`).join(`
31
+ `),s=new Date,o=u=>String(u).padStart(2,"0");return`
32
32
  <!DOCTYPE html>
33
33
  <html lang="en">
34
34
  <head>
@@ -76,7 +76,7 @@
76
76
  <section class="summary">
77
77
  <h2>Report summary</h2>
78
78
  <ul>
79
- <li><strong>Date:</strong> ${`${i(s.getDate())}-${i(s.getMonth()+1)}-${s.getFullYear()} ${i(s.getHours())}:${i(s.getMinutes())}:${i(s.getSeconds())}`}</li>
79
+ <li><strong>Date:</strong> ${`${o(s.getDate())}-${o(s.getMonth()+1)}-${s.getFullYear()} ${o(s.getHours())}:${o(s.getMinutes())}:${o(s.getSeconds())}`}</li>
80
80
  <li><strong>Pages audited:</strong> ${e.pagesAudited}</li>
81
81
  <li><strong>Pages with violations:</strong> ${e.pagesWithViolations}</li>
82
82
  <li><strong>Total violations:</strong> ${e.totalViolations}</li>
@@ -103,18 +103,18 @@
103
103
  </table>
104
104
  </body>
105
105
  </html>
106
- `.trim()}function pe(c){return String(c??"").replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll('"',"&quot;").replaceAll("'","&#39;")}function St(c){return String(c??"").toLowerCase().replace(/[^a-z0-9]+/g,"-")}var Ct=L(()=>{"use strict"});async function ks(){return be||(be=await kt.chromium.launch({headless:!0,args:["--disable-extensions","--disable-blink-features=AutomationControlled"]})),be}async function As(){return we||(we=await(await ks()).newContext({permissions:[],ignoreHTTPSErrors:!0})),we}async function At(){return await(await As()).newPage()}async function Rt(){we&&(await we.close(),we=null),be&&(await be.close(),be=null)}var kt,be,we,et=L(()=>{"use strict";kt=require("playwright"),be=null,we=null});function fe(c){return c==="required"||c==="recommended"||c==="optional"?c:Rs}function Se(c){return c==="minimal"||c==="balanced"||c==="strict"||c==="paranoid"?c:"balanced"}function Et(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 Rs,tt=L(()=>{"use strict";Rs="required"});var I={};G(I,{default:()=>xt.default});var xt,de=L(()=>{"use strict";Ae(I,require("playwright/test"));xt=F(require("playwright/test"),1)});var Mt={};G(Mt,{MenuComponentStrategy:()=>st});var st,Pt=L(()=>{"use strict";de();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,n=this.selectors.main;if(n&&(await e.locator(n).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 fe(c){return String(c??"").replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll('"',"&quot;").replaceAll("'","&#39;")}function Ct(c){return String(c??"").toLowerCase().replace(/[^a-z0-9]+/g,"-")}var At=I(()=>{"use strict"});async function Ps(){return ye||(ye=await Rt.chromium.launch({headless:!0,args:["--disable-extensions","--disable-blink-features=AutomationControlled"]})),ye}async function Bs(){return be||(be=await(await Ps()).newContext({permissions:[],ignoreHTTPSErrors:!0})),be}async function Et(){return await(await Bs()).newPage()}async function xt(){be&&(await be.close(),be=null),ye&&(await ye.close(),ye=null)}var Rt,ye,be,et=I(()=>{"use strict";Rt=require("playwright"),ye=null,be=null});function we(c){return c==="required"||c==="recommended"||c==="optional"?c:Is}function $e(c){return c==="minimal"||c==="balanced"||c==="strict"||c==="paranoid"?c:"balanced"}function Mt(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 Is,tt=I(()=>{"use strict";Is="required"});var B={};W(B,{default:()=>Pt.default});var Pt,ue=I(()=>{"use strict";ke(B,require("playwright/test"));Pt=F(require("playwright/test"),1)});var Bt={};W(Bt,{MenuComponentStrategy:()=>st});var st,It=I(()=>{"use strict";ue();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 o=!1,n=this.selectors.main;if(n&&(await e.locator(n).first().focus(),await e.keyboard.press("Escape"),o=await(0,B.expect)(r).toBeHidden({timeout:this.assertionTimeoutMs}).then(()=>!0).catch(()=>!1)),!o&&this.selectors.main&&(await e.locator(this.selectors.main).first().click({timeout:this.actionTimeoutMs}),o=await(0,B.expect)(r).toBeHidden({timeout:this.assertionTimeoutMs}).then(()=>!0).catch(()=>!1)),o||(await e.mouse.click(10,10),o=await(0,B.expect)(r).toBeHidden({timeout:this.assertionTimeoutMs}).then(()=>!0).catch(()=>!1)),!o)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
110
- This indicates a problem with the menu component's close functionality.`);this.selectors.input&&await e.locator(this.selectors.input).first().clear(),this.selectors.main&&await e.locator(this.selectors.main).first().focus()}async shouldSkipTest(e,t){if(!(e.action.some(n=>n.target==="submenu"||n.target==="submenuTrigger"||n.target==="submenuItems")||e.assertions.some(n=>n.target==="submenu"||n.target==="submenuTrigger"||n.target==="submenuItems")))return!1;let s=this.selectors.submenuTrigger;return s?await t.locator(s).count()===0:!0}getMainSelector(){return this.mainSelector}}});var Bt={};G(Bt,{AccordionComponentStrategy:()=>rt});var rt,Lt=L(()=>{"use strict";de();rt=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.panel||!this.selectors.trigger)return;let t=this.selectors.trigger,r=this.selectors.panel;if(!t||!r)return;let s=await e.locator(t).all();for(let i of s){let n=await i.getAttribute("aria-expanded")==="true",a=await i.getAttribute("aria-controls");if(n&&a){await i.click({timeout:this.actionTimeoutMs});let l=e.locator(`#${a}`);await(0,I.expect)(l).toBeHidden({timeout:this.assertionTimeoutMs}).catch(()=>{})}}}async shouldSkipTest(){return!1}getMainSelector(){return this.mainSelector}}});var It={};G(It,{ComboboxComponentStrategy:()=>it});var it,jt=L(()=>{"use strict";de();it=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,n=this.selectors.main;if(n&&(await e.locator(n).first().focus(),await e.keyboard.press("Escape"),i=await(0,I.expect)(r).toBeHidden({timeout:this.assertionTimeoutMs}).then(()=>!0).catch(()=>!1)),!i&&this.selectors.button&&(await e.locator(this.selectors.button).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 combobox popup between tests. Popup remains visible after trying:
110
+ This indicates a problem with the menu component's close functionality.`);this.selectors.input&&await e.locator(this.selectors.input).first().clear(),this.selectors.main&&await e.locator(this.selectors.main).first().focus()}async shouldSkipTest(e,t){if(!(e.action.some(n=>n.target==="submenu"||n.target==="submenuTrigger"||n.target==="submenuItems")||e.assertions.some(n=>n.target==="submenu"||n.target==="submenuTrigger"||n.target==="submenuItems")))return!1;let s=this.selectors.submenuTrigger;return s?await t.locator(s).count()===0:!0}getMainSelector(){return this.mainSelector}}});var Lt={};W(Lt,{AccordionComponentStrategy:()=>rt});var rt,jt=I(()=>{"use strict";ue();rt=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.panel||!this.selectors.trigger)return;let t=this.selectors.trigger,r=this.selectors.panel;if(!t||!r)return;let s=await e.locator(t).all();for(let o of s){let n=await o.getAttribute("aria-expanded")==="true",a=await o.getAttribute("aria-controls");if(n&&a){await o.click({timeout:this.actionTimeoutMs});let l=e.locator(`#${a}`);await(0,B.expect)(l).toBeHidden({timeout:this.assertionTimeoutMs}).catch(()=>{})}}}async shouldSkipTest(){return!1}getMainSelector(){return this.mainSelector}}});var Ft={};W(Ft,{ComboboxComponentStrategy:()=>ot});var ot,Vt=I(()=>{"use strict";ue();ot=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 o=!1,n=this.selectors.main;if(n&&(await e.locator(n).first().focus(),await e.keyboard.press("Escape"),o=await(0,B.expect)(r).toBeHidden({timeout:this.assertionTimeoutMs}).then(()=>!0).catch(()=>!1)),!o&&this.selectors.button&&(await e.locator(this.selectors.button).first().click({timeout:this.actionTimeoutMs}),o=await(0,B.expect)(r).toBeHidden({timeout:this.assertionTimeoutMs}).then(()=>!0).catch(()=>!1)),o||(await e.mouse.click(10,10),o=await(0,B.expect)(r).toBeHidden({timeout:this.assertionTimeoutMs}).then(()=>!0).catch(()=>!1)),!o)throw new Error(`\u274C FATAL: Cannot close combobox popup between tests. Popup remains visible after trying:
111
111
  1. Escape key
112
112
  2. Clicking button
113
113
  3. Clicking outside
114
- This indicates a problem with the combobox component's close functionality.`);this.selectors.input&&await e.locator(this.selectors.input).first().clear()}async shouldSkipTest(){return!1}getMainSelector(){return this.mainSelector}}});var Ft={};G(Ft,{TabsComponentStrategy:()=>ot});var ot,Vt=L(()=>{"use strict";ot=class{constructor(e,t){this.mainSelector=e;this.selectors=t}async resetState(){}async shouldSkipTest(e,t){if(e.orientation!==void 0&&this.selectors.tablist){let r=this.selectors.tablist,i=await t.locator(r).first().getAttribute("aria-orientation");if(e.orientation!==i)return!0}return!1}getMainSelector(){return this.mainSelector}}});var Ut={};G(Ut,{RadioComponentStrategy:()=>nt});var nt,Dt=L(()=>{"use strict";de();nt=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.radio||!this.selectors.relative)return;let t=this.selectors.radio;if(!t)return;let r=await e.locator(t).all();for(let s of r)if(await s.getAttribute("aria-checked")==="true"){await s.evaluate(a=>a.setAttribute("aria-checked","false"),{timeout:this.actionTimeoutMs});let n=e.locator(`#${s}`);await(0,I.expect)(n).toHaveAttribute("aria-checked","false",{timeout:this.assertionTimeoutMs}).catch(()=>{})}}async shouldSkipTest(){return!1}getMainSelector(){return this.mainSelector}}});var qt={};G(qt,{CheckboxComponentStrategy:()=>at});var at,Ot=L(()=>{"use strict";de();at=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.checkbox||!this.selectors.relative)return;let t=this.selectors.checkbox;if(!t)return;let r=await e.locator(t).all();for(let s of r)if(await s.getAttribute("aria-checked")==="true"){await s.click({timeout:this.actionTimeoutMs});let n=e.locator(`#${s}`);await(0,I.expect)(n).toHaveAttribute("aria-checked","false",{timeout:this.assertionTimeoutMs}).catch(()=>{})}}async shouldSkipTest(){return!1}getMainSelector(){return this.mainSelector}}});var ct,Ht,xe,Nt=L(()=>{"use strict";ct=F(require("path"),1),Ht=require("url"),xe=class{builtInStrategies=new Map;constructor(){this.registerBuiltInStrategies()}registerBuiltInStrategies(){this.builtInStrategies.set("menu",()=>Promise.resolve().then(()=>(Pt(),Mt)).then(e=>e.MenuComponentStrategy)),this.builtInStrategies.set("accordion",()=>Promise.resolve().then(()=>(Lt(),Bt)).then(e=>e.AccordionComponentStrategy)),this.builtInStrategies.set("combobox",()=>Promise.resolve().then(()=>(jt(),It)).then(e=>e.ComboboxComponentStrategy)),this.builtInStrategies.set("tabs",()=>Promise.resolve().then(()=>(Vt(),Ft)).then(e=>e.TabsComponentStrategy)),this.builtInStrategies.set("radio",()=>Promise.resolve().then(()=>(Dt(),Ut)).then(e=>e.RadioComponentStrategy)),this.builtInStrategies.set("checkbox",()=>Promise.resolve().then(()=>(Ot(),qt)).then(e=>e.CheckboxComponentStrategy))}async loadStrategy(e,t,r){try{if(t)try{let i=ct.default.isAbsolute(t)?t:ct.default.resolve(r||process.cwd(),t),n=await import((0,Ht.pathToFileURL)(i).href),a=n.default||n;if(!a)throw new Error(`No default export found in ${t}`);return a}catch(i){throw new Error(`Failed to load custom strategy from ${t}: ${i instanceof Error?i.message:String(i)}`)}let s=this.builtInStrategies.get(e);return s?s():null}catch(s){throw new Error(`Strategy loading failed for ${e}: ${s instanceof Error?s.message:String(s)}`)}}has(e,t){return!!t||this.builtInStrategies.has(e)}}});var Me,Pe,Es,Be,Wt=L(()=>{"use strict";Me=require("fs"),Pe=F(require("path"),1);Nt();Es={},Be=class{static strategyRegistry=new xe;static isComponentConfig(e){return typeof e=="object"&&e!==null}static async detect(e,t,r=400,s=400,i){let n=this.isComponentConfig(t)?t:void 0,a=n?.contractPath;if(!a)throw new Error(`Contract path not found for component: ${e}`);let l=(()=>{if(Pe.default.isAbsolute(a))return a;if(i){let M=Pe.default.resolve(i,a);try{return(0,Me.readFileSync)(M,"utf-8"),M}catch{}}let H=Pe.default.resolve(process.cwd(),a);try{return(0,Me.readFileSync)(H,"utf-8"),H}catch{return new URL(a,Es.url).pathname}})(),u=(0,Me.readFileSync)(l,"utf-8"),h=JSON.parse(u).selectors,y=await this.strategyRegistry.loadStrategy(e,n?.strategyPath,i);if(!y)return null;let j=h.main;return e==="tabs"?new y(j,h):new y(j,h,r,s)}}});var Le,Jt=L(()=>{"use strict";Le=class{startTime=0;componentName="";staticPasses=0;staticFailures=0;staticWarnings=0;dynamicResults=[];totalTests=0;skipped=0;warnings=0;isPlaywright=!1;isCustomContract=!1;apgUrl="https://www.w3.org/WAI/ARIA/apg/";hasPrintedStaticSection=!1;hasPrintedDynamicSection=!1;constructor(e=!1,t=!1){this.isPlaywright=e,this.isCustomContract=t}log(e){process.stderr.write(e+`
114
+ This indicates a problem with the combobox component's close functionality.`);this.selectors.input&&await e.locator(this.selectors.input).first().clear()}async shouldSkipTest(){return!1}getMainSelector(){return this.mainSelector}}});var Ut={};W(Ut,{TabsComponentStrategy:()=>it});var it,Dt=I(()=>{"use strict";it=class{constructor(e,t){this.mainSelector=e;this.selectors=t}async resetState(){}async shouldSkipTest(e,t){if(e.orientation!==void 0&&this.selectors.tablist){let r=this.selectors.tablist,o=await t.locator(r).first().getAttribute("aria-orientation");if(e.orientation!==o)return!0}return!1}getMainSelector(){return this.mainSelector}}});var Ot={};W(Ot,{RadioComponentStrategy:()=>nt});var nt,qt=I(()=>{"use strict";ue();nt=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.radio||!this.selectors.relative)return;let t=this.selectors.radio;if(!t)return;let r=await e.locator(t).all();for(let s of r)if(await s.getAttribute("aria-checked")==="true"){await s.evaluate(a=>a.setAttribute("aria-checked","false"),{timeout:this.actionTimeoutMs});let n=e.locator(`#${s}`);await(0,B.expect)(n).toHaveAttribute("aria-checked","false",{timeout:this.assertionTimeoutMs}).catch(()=>{})}}async shouldSkipTest(){return!1}getMainSelector(){return this.mainSelector}}});var Ht={};W(Ht,{CheckboxComponentStrategy:()=>at});var at,Nt=I(()=>{"use strict";ue();at=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.checkbox||!this.selectors.relative)return;let t=this.selectors.checkbox;if(!t)return;let r=await e.locator(t).all();for(let s of r)if(await s.getAttribute("aria-checked")==="true"){await s.click({timeout:this.actionTimeoutMs});let n=e.locator(`#${s}`);await(0,B.expect)(n).toHaveAttribute("aria-checked","false",{timeout:this.assertionTimeoutMs}).catch(()=>{})}}async shouldSkipTest(){return!1}getMainSelector(){return this.mainSelector}}});var Wt={};W(Wt,{ToggleComponentStrategy:()=>ct});var ct,Jt=I(()=>{"use strict";ue();ct=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.toggle||!this.selectors.relative)return;let t=this.selectors.toggle;if(!t)return;let r=await e.locator(t).all();for(let s of r)if(await s.getAttribute("aria-pressed")==="true"){await s.click({timeout:this.actionTimeoutMs});let n=e.locator(`#${s}`);await(0,B.expect)(n).toHaveAttribute("aria-pressed","false",{timeout:this.assertionTimeoutMs}).catch(()=>{})}}async shouldSkipTest(){return!1}getMainSelector(){return this.mainSelector}}});var lt,_t,Ee,zt=I(()=>{"use strict";lt=F(require("path"),1),_t=require("url"),Ee=class{builtInStrategies=new Map;constructor(){this.registerBuiltInStrategies()}registerBuiltInStrategies(){this.builtInStrategies.set("menu",()=>Promise.resolve().then(()=>(It(),Bt)).then(e=>e.MenuComponentStrategy)),this.builtInStrategies.set("accordion",()=>Promise.resolve().then(()=>(jt(),Lt)).then(e=>e.AccordionComponentStrategy)),this.builtInStrategies.set("combobox",()=>Promise.resolve().then(()=>(Vt(),Ft)).then(e=>e.ComboboxComponentStrategy)),this.builtInStrategies.set("tabs",()=>Promise.resolve().then(()=>(Dt(),Ut)).then(e=>e.TabsComponentStrategy)),this.builtInStrategies.set("radio",()=>Promise.resolve().then(()=>(qt(),Ot)).then(e=>e.RadioComponentStrategy)),this.builtInStrategies.set("checkbox",()=>Promise.resolve().then(()=>(Nt(),Ht)).then(e=>e.CheckboxComponentStrategy)),this.builtInStrategies.set("toggle",()=>Promise.resolve().then(()=>(Jt(),Wt)).then(e=>e.ToggleComponentStrategy))}async loadStrategy(e,t,r){try{if(t)try{let o=lt.default.isAbsolute(t)?t:lt.default.resolve(r||process.cwd(),t),n=await import((0,_t.pathToFileURL)(o).href),a=n.default||n;if(!a)throw new Error(`No default export found in ${t}`);return a}catch(o){throw new Error(`Failed to load custom strategy from ${t}: ${o instanceof Error?o.message:String(o)}`)}let s=this.builtInStrategies.get(e);return s?s():null}catch(s){throw new Error(`Strategy loading failed for ${e}: ${s instanceof Error?s.message:String(s)}`)}}has(e,t){return!!t||this.builtInStrategies.has(e)}}});var xe,Me,Ls,Pe,Gt=I(()=>{"use strict";xe=require("fs"),Me=F(require("path"),1);zt();Ls={},Pe=class{static strategyRegistry=new Ee;static isComponentConfig(e){return typeof e=="object"&&e!==null}static async detect(e,t,r=400,s=400,o){let n=this.isComponentConfig(t)?t:void 0,a=n?.contractPath;if(!a)throw new Error(`Contract path not found for component: ${e}`);let l=(()=>{if(Me.default.isAbsolute(a))return a;if(o){let x=Me.default.resolve(o,a);try{return(0,xe.readFileSync)(x,"utf-8"),x}catch{}}let q=Me.default.resolve(process.cwd(),a);try{return(0,xe.readFileSync)(q,"utf-8"),q}catch{return new URL(a,Ls.url).pathname}})(),u=(0,xe.readFileSync)(l,"utf-8"),h=JSON.parse(u).selectors,y=await this.strategyRegistry.loadStrategy(e,n?.strategyPath,o);if(!y)return null;let L=h.main;return e==="tabs"?new y(L,h):new y(L,h,r,s)}}});var Be,Yt=I(()=>{"use strict";Be=class{startTime=0;componentName="";staticPasses=0;staticFailures=0;staticWarnings=0;dynamicResults=[];totalTests=0;skipped=0;warnings=0;isPlaywright=!1;isCustomContract=!1;apgUrl="https://www.w3.org/WAI/ARIA/apg/";hasPrintedStaticSection=!1;hasPrintedDynamicSection=!1;constructor(e=!1,t=!1){this.isPlaywright=e,this.isCustomContract=t}log(e){process.stderr.write(e+`
115
115
  `)}start(e,t,r){this.startTime=Date.now(),this.componentName=e,this.totalTests=t,this.hasPrintedStaticSection=!1,this.hasPrintedDynamicSection=!1,r&&(this.apgUrl=r);let s="Playwright (Real Browser)";this.log(`
116
116
  ${"\u2550".repeat(60)}`),this.log(`\u{1F50D} Testing ${e.charAt(0).toUpperCase()+e.slice(1)} Component - ${s}`),this.log(`${"\u2550".repeat(60)}
117
- `)}reportStatic(e,t,r=0){this.staticPasses=e,this.staticFailures=t,this.staticWarnings=r}reportStaticTest(e,t,r,s){this.hasPrintedStaticSection||(this.log(`${"\u2500".repeat(60)}`),this.log("\u{1F9EA} Static Assertions"),this.log(`${"\u2500".repeat(60)}`),this.hasPrintedStaticSection=!0);let i=t==="pass"?"\u2713":t==="warn"?"\u26A0":t==="skip"?"\u25CB":"\u2717";this.log(` ${i} ${e}`),s&&this.log(` \u21B3 level=${s}`),(t==="fail"||t==="warn"||t==="skip")&&r&&this.log(` \u21B3 ${r}`)}reportTest(e,t,r){this.hasPrintedDynamicSection||(this.log(""),this.log(`${"\u2500".repeat(60)}`),this.log("\u2328\uFE0F Dynamic Interaction Tests"),this.log(`${"\u2500".repeat(60)}`),this.hasPrintedDynamicSection=!0);let s={description:e.description,status:t,failureMessage:r,level:e.level};t==="skip"&&(s.skipReason="Requires real browser (addEventListener events)"),this.dynamicResults.push(s);let i={pass:"\u2713",fail:"\u2717",warn:"\u26A0",skip:"\u25CB"},n=e.level?`[${e.level.toUpperCase()}] `:"";this.log(` ${i[t]} ${n}${e.description}`),t==="skip"&&!this.isPlaywright&&this.log(" \u21B3 Skipped (runs only in Playwright)"),t==="fail"&&r&&this.log(` \u21B3 ${r}`),t==="warn"&&r&&this.log(` \u21B3 ${r}`),t==="skip"&&r&&this.log(` \u21B3 ${r}`)}reportFailures(e){e.length!==0&&(this.log(`
117
+ `)}reportStatic(e,t,r=0){this.staticPasses=e,this.staticFailures=t,this.staticWarnings=r}reportStaticTest(e,t,r,s){this.hasPrintedStaticSection||(this.log(`${"\u2500".repeat(60)}`),this.log("\u{1F9EA} Static Assertions"),this.log(`${"\u2500".repeat(60)}`),this.hasPrintedStaticSection=!0);let o=t==="pass"?"\u2713":t==="warn"?"\u26A0":t==="skip"?"\u25CB":"\u2717";this.log(` ${o} ${e}`),s&&this.log(` \u21B3 level=${s}`),(t==="fail"||t==="warn"||t==="skip")&&r&&this.log(` \u21B3 ${r}`)}reportTest(e,t,r){this.hasPrintedDynamicSection||(this.log(""),this.log(`${"\u2500".repeat(60)}`),this.log("\u2328\uFE0F Dynamic Interaction Tests"),this.log(`${"\u2500".repeat(60)}`),this.hasPrintedDynamicSection=!0);let s={description:e.description,status:t,failureMessage:r,level:e.level};t==="skip"&&(s.skipReason="Requires real browser (addEventListener events)"),this.dynamicResults.push(s);let o={pass:"\u2713",fail:"\u2717",warn:"\u26A0",skip:"\u25CB"},n=e.level?`[${e.level.toUpperCase()}] `:"";this.log(` ${o[t]} ${n}${e.description}`),t==="skip"&&!this.isPlaywright&&this.log(" \u21B3 Skipped (runs only in Playwright)"),t==="fail"&&r&&this.log(` \u21B3 ${r}`),t==="warn"&&r&&this.log(` \u21B3 ${r}`),t==="skip"&&r&&this.log(` \u21B3 ${r}`)}reportFailures(e){e.length!==0&&(this.log(`
118
118
  ${"\u2500".repeat(60)}`),this.log(`\u274C Failures (${e.length}):
119
119
  `),e.forEach((t,r)=>{this.log(`${r+1}. ${t}`),t.includes("aria-")?this.log(" \u{1F4A1} Add the missing ARIA attribute to improve screen reader support"):t.includes("focus")?this.log(" \u{1F4A1} Check keyboard event handlers and focus management"):t.includes("visible")&&this.log(" \u{1F4A1} Verify display/visibility styles and state management"),this.log("")}))}reportWarnings(){let e=this.dynamicResults.filter(t=>t.status==="warn");e.length===0&&this.staticWarnings===0||(this.log(`
120
120
  ${"\u2500".repeat(60)}`),this.log(`\u26A0\uFE0F Warnings (${this.staticWarnings+e.length}):
@@ -126,82 +126,82 @@ ${"\u2500".repeat(60)}`),this.log(`\u2139\uFE0F Skipped Tests (${this.skipped})
126
126
  `),this.log("These tests use native keyboard events via addEventListener,"),this.log(`which only run in Playwright (real browser).
127
127
  `),e.forEach((t,r)=>{this.log(`${r+1}. ${t.description}`)}),this.log(`
128
128
  \u{1F4A1} Run with Playwright for full validation:`),this.log(` testUiComponent('${this.componentName}', null, 'http://localhost:5173/test-harness?component=component_name')
129
- `)}summary(e){let t=Date.now()-this.startTime,r=this.dynamicResults.filter(f=>f.status==="pass").length,s=this.dynamicResults.filter(f=>f.status==="fail").length,i=this.dynamicResults.filter(f=>f.status==="warn").length;this.skipped=this.dynamicResults.filter(f=>f.status==="skip").length,this.warnings=this.staticWarnings+i;let n=this.staticPasses+r,a=this.staticFailures+s,l=n+a+this.warnings,u=()=>{let f=`${this.componentName.charAt(0).toUpperCase()}${this.componentName.slice(1)}`;return this.isCustomContract?`${f} component validates against your custom accessibility policy \u2713`:`${f} component meets Aria-Ease baseline WAI-ARIA expectations \u2713`};return e.length>0&&this.reportFailures(e),this.reportWarnings(),this.reportSkipped(),this.log(`
129
+ `)}summary(e){let t=Date.now()-this.startTime,r=this.dynamicResults.filter(p=>p.status==="pass").length,s=this.dynamicResults.filter(p=>p.status==="fail").length,o=this.dynamicResults.filter(p=>p.status==="warn").length;this.skipped=this.dynamicResults.filter(p=>p.status==="skip").length,this.warnings=this.staticWarnings+o;let n=this.staticPasses+r,a=this.staticFailures+s,l=n+a+this.warnings,u=()=>{let p=`${this.componentName.charAt(0).toUpperCase()}${this.componentName.slice(1)}`;return this.isCustomContract?`${p} component validates against your custom accessibility policy \u2713`:`${p} component meets Aria-Ease baseline WAI-ARIA expectations \u2713`};return e.length>0&&this.reportFailures(e),this.reportWarnings(),this.reportSkipped(),this.log(`
130
130
  ${"\u2550".repeat(60)}`),this.log(`\u{1F4CA} Summary
131
131
  `),a===0&&this.skipped===0&&this.warnings===0?(this.log(`\u2705 All ${l} tests passed!`),this.log(` ${u()}`)):a===0?(this.log(`\u2705 ${n}/${l} tests passed`),this.skipped>0&&this.log(`\u25CB ${this.skipped} tests skipped`),this.warnings>0&&this.log(`\u26A0\uFE0F ${this.warnings} warning${this.warnings>1?"s":""}`),this.log(` ${u()}`)):(this.log(`\u274C ${a} test${a>1?"s":""} failed`),this.log(`\u2705 ${n} test${n>1?"s":""} passed`),this.warnings>0&&this.log(`\u26A0\uFE0F ${this.warnings} warning${this.warnings>1?"s":""}`),this.skipped>0&&this.log(`\u25CB ${this.skipped} test${this.skipped>1?"s":""} skipped`)),this.log(`\u23F1\uFE0F Duration: ${t}ms`),this.log(`${"\u2550".repeat(60)}
132
132
  `),a>0?(this.log("\u{1F527} Next Steps:"),this.log(" 1. Review the failures above"),this.log(" 2. Fix ARIA attributes and keyboard handlers"),this.log(` 3. Re-run tests to verify fixes
133
133
  `)):!this.isPlaywright&&this.skipped>0&&this.log(`\u2728 Optional: Run Playwright tests for complete validation
134
134
  `),{passes:n,failures:a,skipped:this.skipped,duration:t}}error(e,t){this.log(`
135
- \u274C Error: ${e}`),t&&this.log(` Context: ${t}`),this.log("")}}});var _t={};G(_t,{RelativeTargetResolver:()=>se});var se,Ie=L(()=>{"use strict";se=class{static async resolve(e,t,r){let s=await e.locator(t).all();if(typeof r=="number")return s[r-1];switch(r){case"first":return s[0];case"second":return s[1];case"last":return s[s.length-1];case"next":{let n=(await e.evaluate(([a])=>Array.from(document.querySelectorAll(a)).indexOf(document.activeElement),[t])+1)%s.length;return s[n]}case"previous":{let n=(await e.evaluate(([a])=>Array.from(document.querySelectorAll(a)).indexOf(document.activeElement),[t])-1+s.length)%s.length;return s[n]}default:return null}}}});var ve,zt=L(()=>{"use strict";Ie();ve=class{constructor(e,t,r=400){this.page=e;this.selectors=t;this.timeoutMs=r}isBrowserClosedError(e){return e instanceof Error&&e.message.includes("Target page, context or browser has been closed")}async focus(e,t,r){try{if(e==="virtual"&&r){let i=this.selectors.main;if(!i)return{success:!1,error:"Main selector not defined for virtual focus."};let n=this.page.locator(i).first();return await n.count()?(await n.evaluate((l,u)=>{l.setAttribute("aria-activedescendant",u)},r),{success:!0}):{success:!1,error:"Main element not found for virtual focus."}}if(e==="relative"&&t){let i=this.selectors.relative;if(!i)return{success:!1,error:"Relative selector not defined for focus action."};let n=await se.resolve(this.page,i,t);return n?(await n.focus({timeout:this.timeoutMs}),{success:!0}):{success:!1,error:`Could not resolve relative target ${t} for focus.`}}let s=this.selectors[e];return s?(await this.page.locator(s).first().focus({timeout:this.timeoutMs}),{success:!0}):{success:!1,error:`Selector for focus target ${e} not found.`}}catch(s){return this.isBrowserClosedError(s)?{success:!1,error:"CRITICAL: Browser/page closed during test execution. Remaining actions skipped.",shouldBreak:!0}:{success:!1,error:`Failed to focus ${e}: ${s instanceof Error?s.message:String(s)}`}}}async type(e,t){try{let r=this.selectors[e];return r?(await this.page.locator(r).first().fill(t,{timeout:this.timeoutMs}),{success:!0}):{success:!1,error:`Selector for type target ${e} not found.`}}catch(r){return this.isBrowserClosedError(r)?{success:!1,error:"CRITICAL: Browser/page closed during test execution. Remaining actions skipped.",shouldBreak:!0}:{success:!1,error:`Failed to type into ${e}: ${r instanceof Error?r.message:String(r)}`}}}async click(e,t){try{if(e==="document")return await this.page.mouse.click(10,10),{success:!0};if(e==="relative"&&t){let s=this.selectors.relative;if(!s)return{success:!1,error:"Relative selector not defined for click action."};let i=await se.resolve(this.page,s,t);return i?(await i.click({timeout:this.timeoutMs}),{success:!0}):{success:!1,error:`Could not resolve relative target ${t} for click.`}}let r=this.selectors[e];return r?(await this.page.locator(r).first().click({timeout:this.timeoutMs}),{success:!0}):{success:!1,error:`Selector for action target ${e} not found.`}}catch(r){return this.isBrowserClosedError(r)?{success:!1,error:"CRITICAL: Browser/page closed during test execution. Remaining actions skipped.",shouldBreak:!0}:{success:!1,error:`Failed to click ${e}: ${r instanceof Error?r.message:String(r)}`}}}async keypress(e,t,r){try{let i={Space:"Space",Enter:"Enter",Escape:"Escape","Arrow Up":"ArrowUp","Arrow Down":"ArrowDown","Arrow Left":"ArrowLeft","Arrow Right":"ArrowRight",Home:"Home",End:"End",Tab:"Tab"}[t]||t;if(i==="Space"?i=" ":i.includes(" ")&&(i=i.replace(/ /g,"")),e==="relative"){if(r==null)return{success:!1,error:"relativeTarget must be provided for relative keypress."};let u=this.selectors.relative;if(!u)return{success:!1,error:"Relative selector not defined for keypress action."};let f=await se.resolve(this.page,u,r);return f?(await f.press(i,{timeout:this.timeoutMs}),{success:!0}):{success:!1,error:`Could not resolve relative target ${r} for keypress.`}}let n=this.selectors[e];if(!n)return{success:!1,error:`Selector for keypress target ${e} not found.`};let a=this.page.locator(n).first();return await a.count()===0?{success:!1,error:`${e} element not found.`,shouldBreak:!0}:(await a.press(i,{timeout:this.timeoutMs}),{success:!0})}catch(s){return this.isBrowserClosedError(s)?{success:!1,error:"CRITICAL: Browser/page closed during test execution. Remaining actions skipped.",shouldBreak:!0}:{success:!1,error:`Failed to press ${t} on ${e}: ${s instanceof Error?s.message:String(s)}`}}}async hover(e,t){try{if(e==="relative"&&t){let s=this.selectors.relative;if(!s)return{success:!1,error:"Relative selector not defined for hover action."};let i=await se.resolve(this.page,s,t);return i?(await i.hover({timeout:this.timeoutMs}),{success:!0}):{success:!1,error:`Could not resolve relative target ${t} for hover.`}}let r=this.selectors[e];return r?(await this.page.locator(r).first().hover({timeout:this.timeoutMs}),{success:!0}):{success:!1,error:`Selector for hover target ${e} not found.`}}catch(r){return this.isBrowserClosedError(r)?{success:!1,error:"CRITICAL: Browser/page closed during test execution. Remaining actions skipped.",shouldBreak:!0}:{success:!1,error:`Failed to hover ${e}: ${r instanceof Error?r.message:String(r)}`}}}}});var Te,Gt=L(()=>{"use strict";de();Ie();Te=class{constructor(e,t,r=400){this.page=e;this.selectors=t;this.timeoutMs=r}async resolveTarget(e,t,r){try{if(e==="relative"){let i=r?this.selectors[r]:this.selectors.relative;if(!i)return{target:null,error:"Relative selector is not defined in the contract."};if(!t)return{target:null,error:"Relative target or expected value is not defined."};let n=await se.resolve(this.page,i,t);return n?{target:n}:{target:null,error:`Target ${e} not found.`}}let s=this.selectors[e];return s?{target:this.page.locator(s).first()}:{target:null,error:`Selector for assertion target ${e} not found.`}}catch(s){return{target:null,error:`Failed to resolve target ${e}: ${s instanceof Error?s.message:String(s)}`}}}async validateVisibility(e,t,r,s,i){try{return r?(await(0,I.expect)(e).toBeVisible({timeout:this.timeoutMs}),{success:!0,passMessage:`${t} is visible as expected. Test: "${i}".`}):(await(0,I.expect)(e).toBeHidden({timeout:this.timeoutMs}),{success:!0,passMessage:`${t} is not visible as expected. Test: "${i}".`})}catch{let n=this.selectors[t]||"",a=await this.page.evaluate(l=>{let u=l?document.querySelector(l):null;if(!u)return"element not found";let f=window.getComputedStyle(u);return`display:${f.display}, visibility:${f.visibility}, opacity:${f.opacity}`},n);return r?{success:!1,failMessage:`${s} (actual: ${a})`}:{success:!1,failMessage:`${s} ${t} is still visible (actual: ${a}).`}}}async validateAttribute(e,t,r,s,i,n){if(s==="!empty"){let u=await e.getAttribute(r);return u&&u.trim()!==""?{success:!0,passMessage:`${t} has non-empty "${r}". Test: "${n}".`}:{success:!1,failMessage:`${i} ${t} "${r}" should not be empty, found "${u}".`}}if(typeof s!="string")throw console.error("[AssertionRunner] expectedValue is not a string:",s),new Error(`AssertionRunner: expectedValue for attribute assertion must be a string, but got: ${JSON.stringify(s)}`);let a=s.split(" | ").map(u=>u.trim()),l=await e.getAttribute(r);return l!==null&&a.includes(l)?{success:!0,passMessage:`${t} has expected "${r}". Test: "${n}".`}:{success:!1,failMessage:`${i} ${t} "${r}" should be "${s}", found "${l}".`}}async validateValue(e,t,r,s,i){let n=await e.inputValue().catch(()=>"");return r==="!empty"?n&&n.trim()!==""?{success:!0,passMessage:`${t} has non-empty value. Test: "${i}".`}:{success:!1,failMessage:`${s} ${t} value should not be empty, found "${n}".`}:r===""?n===""?{success:!0,passMessage:`${t} has empty value. Test: "${i}".`}:{success:!1,failMessage:`${s} ${t} value should be empty, found "${n}".`}:n===r?{success:!0,passMessage:`${t} has expected value. Test: "${i}".`}:{success:!1,failMessage:`${s} ${t} value should be "${r}", found "${n}".`}}async validateFocus(e,t,r,s,i){try{return r?(await(0,I.expect)(e).toBeFocused({timeout:this.timeoutMs}),{success:!0,passMessage:`${t} has focus as expected. Test: "${i}".`}):(await(0,I.expect)(e).not.toBeFocused({timeout:this.timeoutMs}),{success:!0,passMessage:`${t} does not have focus as expected. Test: "${i}".`})}catch{let n=await this.page.evaluate(()=>{let a=document.activeElement;return a?`${a.tagName}#${a.id||"no-id"}.${a.className||"no-class"}`:"no element focused"});return{success:!1,failMessage:`${s} (actual focus: ${n})`}}}async validateRole(e,t,r,s,i){let n=await e.getAttribute("role");return n===r?{success:!0,passMessage:`${t} has role "${r}". Test: "${i}".`}:{success:!1,failMessage:`${s} Expected role "${r}", found "${n}".`}}async validate(e,t){if(this.page.isClosed())return{success:!1,failMessage:"CRITICAL: Browser/page closed before completing all tests. Increase test timeout or reduce test complexity."};let r=null,s;if(e.controlledBy){let i=e.controlledBy,n=this.selectors[i.target];if(!n)return{success:!1,failMessage:`Selector for controlledBy.target '${i.target}' not found.`,target:null};let a=null;if(i.relativeTarget?a=await se.resolve(this.page,n,i.relativeTarget):a=this.page.locator(n).first(),!a)return{success:!1,failMessage:"Controlling element for controlledBy not found.",target:null};let l=i.attribute||"aria-controls",u=await a.getAttribute(l);if(!u)return{success:!1,failMessage:`Controlling element does not have attribute '${l}'.`,target:null};if(r=this.page.locator(`#${u}`),!r||await r.count()===0)return{success:!1,failMessage:`Controlled element with id '${u}' not found.`,target:null}}else{let i=await this.resolveTarget(e.target,e.relativeTarget||e.expectedValue,e.selectorKey);if(r=i.target,s=i.error,s||!r)return{success:!1,failMessage:s||`Target ${e.target} not found.`,target:null}}if(e.target==="input"&&e.attribute==="aria-activedescendant"&&e.expectedValue==="!empty"&&e.relativeTarget&&e.selectorKey){let i=await se.resolve(this.page,this.selectors[e.selectorKey],e.relativeTarget),n=i?await i.getAttribute("id"):null,a=await r.getAttribute("aria-activedescendant");return n&&a===n?{success:!0,passMessage:`input[aria-activedescendant] matches id of ${e.relativeTarget}(${e.selectorKey}). Test: "${t}".`}:{success:!1,failMessage:`input[aria-activedescendant] should match id of ${e.relativeTarget}(${e.selectorKey}), found "${a}".`}}switch(e.assertion){case"toBeVisible":return this.validateVisibility(r,e.target,!0,e.failureMessage||"",t);case"notToBeVisible":return this.validateVisibility(r,e.target,!1,e.failureMessage||"",t);case"toHaveAttribute":return e.attribute&&e.expectedValue!==void 0?this.validateAttribute(r,e.target,e.attribute,e.expectedValue,e.failureMessage||"",t):{success:!1,failMessage:"Missing attribute or expectedValue for toHaveAttribute assertion"};case"toHaveValue":return e.expectedValue!==void 0?this.validateValue(r,e.target,e.expectedValue,e.failureMessage||"",t):{success:!1,failMessage:"Missing expectedValue for toHaveValue assertion"};case"toHaveFocus":return this.validateFocus(r,e.target,!0,e.failureMessage||"",t);case"notToHaveFocus":return this.validateFocus(r,e.target,!1,e.failureMessage||"",t);case"toHaveRole":return e.expectedValue!==void 0?this.validateRole(r,e.target,e.expectedValue,e.failureMessage||"",t):{success:!1,failMessage:"Missing expectedValue for toHaveRole assertion"};default:return{success:!1,failMessage:`Unknown assertion type: ${e.assertion}`}}}}});var Yt={};G(Yt,{runContractTestsPlaywright:()=>xs});async function xs(c,e,t,r,s){let i=r?.test?.components?.find(S=>S.name===c),n=!!i?.contractPath,a=new Le(!0,n),l={actionTimeoutMs:400,assertionTimeoutMs:400,navigationTimeoutMs:3e4,componentReadyTimeoutMs:5e3},u=r?.test?.disableTimeouts===!0,h=i?.disableTimeouts===!0||u,y=(S,ie,oe)=>{if(h)return 0;let ee=S??ie;return typeof ee!="number"||!Number.isFinite(ee)||ee<0?oe:ee},j=y(i?.actionTimeoutMs,r?.test?.actionTimeoutMs,l.actionTimeoutMs),H=y(i?.assertionTimeoutMs,r?.test?.assertionTimeoutMs,l.assertionTimeoutMs),M=y(i?.navigationTimeoutMs,r?.test?.navigationTimeoutMs,l.navigationTimeoutMs),U=y(i?.componentReadyTimeoutMs,r?.test?.componentReadyTimeoutMs,l.componentReadyTimeoutMs),W=Se(t),J=i?.contractPath;if(!J)throw new Error(`Contract path not found for component: ${c}`);let Y=(()=>{if(Fe.default.isAbsolute(J))return J;if(s){let ie=Fe.default.resolve(s,J);try{return(0,je.readFileSync)(ie,"utf-8"),ie}catch{}}let S=Fe.default.resolve(process.cwd(),J);try{return(0,je.readFileSync)(S,"utf-8"),S}catch{return new URL(J,Ms.url).pathname}})(),K=(0,je.readFileSync)(Y,"utf-8"),v=JSON.parse(K),Ce=(v.relationships?.length||0)+(v.static.length||0)+v.dynamic.length,Ue=v.meta?.source?.apg,Z=[],ae=[],ce=[],N=[],A=null,q=(S,ie)=>{let oe=fe(ie),ee=Et(oe,W);if(ee==="error")return Z.push(S),{status:"fail",level:oe,detail:S};if(ee==="warning")return ae.push(S),{status:"warn",level:oe,detail:S};let ne=`${S} (ignored by strictness=${W}, level=${oe})`;return N.push(ne),{status:"skip",level:oe,detail:ne}};try{if(A=await At(),e){try{await A.goto(e,{waitUntil:"domcontentloaded",timeout:M})}catch(o){throw new Error(`Failed to navigate to ${e}. Ensure dev server is running and accessible. Original error: ${o instanceof Error?o.message:String(o)}`)}await A.addStyleTag({content:"* { transition: none !important; animation: none !important; }"})}let S=await Be.detect(c,i,j,H,s);if(!S)throw new Error(`Unsupported component: ${c}`);let ie=S.getMainSelector();if(!ie)throw new Error(`CRITICAL: No selector found in contract for ${c}`);try{await A.locator(ie).first().waitFor({state:"attached",timeout:U})}catch(o){throw new Error(`
135
+ \u274C Error: ${e}`),t&&this.log(` Context: ${t}`),this.log("")}}});var Kt={};W(Kt,{RelativeTargetResolver:()=>ee});var ee,Ie=I(()=>{"use strict";ee=class{static async resolve(e,t,r){let s=await e.locator(t).all();if(typeof r=="number")return s[r-1];switch(r){case"first":return s[0];case"second":return s[1];case"last":return s[s.length-1];case"next":{let n=(await e.evaluate(([a])=>Array.from(document.querySelectorAll(a)).indexOf(document.activeElement),[t])+1)%s.length;return s[n]}case"previous":{let n=(await e.evaluate(([a])=>Array.from(document.querySelectorAll(a)).indexOf(document.activeElement),[t])-1+s.length)%s.length;return s[n]}default:return null}}}});var ve,Qt=I(()=>{"use strict";Ie();ve=class{constructor(e,t,r=400){this.page=e;this.selectors=t;this.timeoutMs=r}isBrowserClosedError(e){return e instanceof Error&&e.message.includes("Target page, context or browser has been closed")}async focus(e,t,r){try{if(e==="virtual"&&r){let o=this.selectors.main;if(!o)return{success:!1,error:"Main selector not defined for virtual focus."};let n=this.page.locator(o).first();return await n.count()?(await n.evaluate((l,u)=>{l.setAttribute("aria-activedescendant",u)},r),{success:!0}):{success:!1,error:"Main element not found for virtual focus."}}if(e==="relative"&&t){let o=this.selectors.relative;if(!o)return{success:!1,error:"Relative selector not defined for focus action."};let n=await ee.resolve(this.page,o,t);return n?(await n.focus({timeout:this.timeoutMs}),{success:!0}):{success:!1,error:`Could not resolve relative target ${t} for focus.`}}let s=this.selectors[e];return s?(await this.page.locator(s).first().focus({timeout:this.timeoutMs}),{success:!0}):{success:!1,error:`Selector for focus target ${e} not found.`}}catch(s){return this.isBrowserClosedError(s)?{success:!1,error:"CRITICAL: Browser/page closed during test execution. Remaining actions skipped.",shouldBreak:!0}:{success:!1,error:`Failed to focus ${e}: ${s instanceof Error?s.message:String(s)}`}}}async type(e,t){try{let r=this.selectors[e];return r?(await this.page.locator(r).first().fill(t,{timeout:this.timeoutMs}),{success:!0}):{success:!1,error:`Selector for type target ${e} not found.`}}catch(r){return this.isBrowserClosedError(r)?{success:!1,error:"CRITICAL: Browser/page closed during test execution. Remaining actions skipped.",shouldBreak:!0}:{success:!1,error:`Failed to type into ${e}: ${r instanceof Error?r.message:String(r)}`}}}async click(e,t){try{if(e==="document")return await this.page.mouse.click(10,10),{success:!0};if(e==="relative"&&t){let s=this.selectors.relative;if(!s)return{success:!1,error:"Relative selector not defined for click action."};let o=await ee.resolve(this.page,s,t);return o?(await o.click({timeout:this.timeoutMs}),{success:!0}):{success:!1,error:`Could not resolve relative target ${t} for click.`}}let r=this.selectors[e];return r?(await this.page.locator(r).first().click({timeout:this.timeoutMs}),{success:!0}):{success:!1,error:`Selector for action target ${e} not found.`}}catch(r){return this.isBrowserClosedError(r)?{success:!1,error:"CRITICAL: Browser/page closed during test execution. Remaining actions skipped.",shouldBreak:!0}:{success:!1,error:`Failed to click ${e}: ${r instanceof Error?r.message:String(r)}`}}}async keypress(e,t,r){try{let o={Space:"Space",Enter:"Enter",Escape:"Escape","Arrow Up":"ArrowUp","Arrow Down":"ArrowDown","Arrow Left":"ArrowLeft","Arrow Right":"ArrowRight",Home:"Home",End:"End",Tab:"Tab"}[t]||t;if(o==="Space"?o=" ":o.includes(" ")&&(o=o.replace(/ /g,"")),e==="relative"){if(r==null)return{success:!1,error:"relativeTarget must be provided for relative keypress."};let u=this.selectors.relative;if(!u)return{success:!1,error:"Relative selector not defined for keypress action."};let p=await ee.resolve(this.page,u,r);return p?(await p.press(o,{timeout:this.timeoutMs}),{success:!0}):{success:!1,error:`Could not resolve relative target ${r} for keypress.`}}let n=this.selectors[e];if(!n)return{success:!1,error:`Selector for keypress target ${e} not found.`};let a=this.page.locator(n).first();return await a.count()===0?{success:!1,error:`${e} element not found.`,shouldBreak:!0}:(await a.press(o,{timeout:this.timeoutMs}),{success:!0})}catch(s){return this.isBrowserClosedError(s)?{success:!1,error:"CRITICAL: Browser/page closed during test execution. Remaining actions skipped.",shouldBreak:!0}:{success:!1,error:`Failed to press ${t} on ${e}: ${s instanceof Error?s.message:String(s)}`}}}async hover(e,t){try{if(e==="relative"&&t){let s=this.selectors.relative;if(!s)return{success:!1,error:"Relative selector not defined for hover action."};let o=await ee.resolve(this.page,s,t);return o?(await o.hover({timeout:this.timeoutMs}),{success:!0}):{success:!1,error:`Could not resolve relative target ${t} for hover.`}}let r=this.selectors[e];return r?(await this.page.locator(r).first().hover({timeout:this.timeoutMs}),{success:!0}):{success:!1,error:`Selector for hover target ${e} not found.`}}catch(r){return this.isBrowserClosedError(r)?{success:!1,error:"CRITICAL: Browser/page closed during test execution. Remaining actions skipped.",shouldBreak:!0}:{success:!1,error:`Failed to hover ${e}: ${r instanceof Error?r.message:String(r)}`}}}}});var Se,Xt=I(()=>{"use strict";ue();Ie();Se=class{constructor(e,t,r=400){this.page=e;this.selectors=t;this.timeoutMs=r}async resolveTarget(e,t,r){try{if(e==="relative"){let o=r?this.selectors[r]:this.selectors.relative;if(!o)return{target:null,error:"Relative selector is not defined in the contract."};if(!t)return{target:null,error:"Relative target or expected value is not defined."};let n=await ee.resolve(this.page,o,t);return n?{target:n}:{target:null,error:`Target ${e} not found.`}}let s=this.selectors[e];return s?{target:this.page.locator(s).first()}:{target:null,error:`Selector for assertion target ${e} not found.`}}catch(s){return{target:null,error:`Failed to resolve target ${e}: ${s instanceof Error?s.message:String(s)}`}}}async validateVisibility(e,t,r,s,o){try{return r?(await(0,B.expect)(e).toBeVisible({timeout:this.timeoutMs}),{success:!0,passMessage:`${t} is visible as expected. Test: "${o}".`}):(await(0,B.expect)(e).toBeHidden({timeout:this.timeoutMs}),{success:!0,passMessage:`${t} is not visible as expected. Test: "${o}".`})}catch{let n=this.selectors[t]||"",a=await this.page.evaluate(l=>{let u=l?document.querySelector(l):null;if(!u)return"element not found";let p=window.getComputedStyle(u);return`display:${p.display}, visibility:${p.visibility}, opacity:${p.opacity}`},n);return r?{success:!1,failMessage:`${s} (actual: ${a})`}:{success:!1,failMessage:`${s} ${t} is still visible (actual: ${a}).`}}}async validateAttribute(e,t,r,s,o,n){if(s==="!empty"){let u=await e.getAttribute(r);return u&&u.trim()!==""?{success:!0,passMessage:`${t} has non-empty "${r}". Test: "${n}".`}:{success:!1,failMessage:`${o} ${t} "${r}" should not be empty, found "${u}".`}}if(typeof s!="string")throw console.error("[AssertionRunner] expectedValue is not a string:",s),new Error(`AssertionRunner: expectedValue for attribute assertion must be a string, but got: ${JSON.stringify(s)}`);let a=s.split(" | ").map(u=>u.trim()),l=await e.getAttribute(r);return l!==null&&a.includes(l)?{success:!0,passMessage:`${t} has expected "${r}". Test: "${n}".`}:{success:!1,failMessage:`${o} ${t} "${r}" should be "${s}", found "${l}".`}}async validateValue(e,t,r,s,o){let n=await e.inputValue().catch(()=>"");return r==="!empty"?n&&n.trim()!==""?{success:!0,passMessage:`${t} has non-empty value. Test: "${o}".`}:{success:!1,failMessage:`${s} ${t} value should not be empty, found "${n}".`}:r===""?n===""?{success:!0,passMessage:`${t} has empty value. Test: "${o}".`}:{success:!1,failMessage:`${s} ${t} value should be empty, found "${n}".`}:n===r?{success:!0,passMessage:`${t} has expected value. Test: "${o}".`}:{success:!1,failMessage:`${s} ${t} value should be "${r}", found "${n}".`}}async validateFocus(e,t,r,s,o){try{return r?(await(0,B.expect)(e).toBeFocused({timeout:this.timeoutMs}),{success:!0,passMessage:`${t} has focus as expected. Test: "${o}".`}):(await(0,B.expect)(e).not.toBeFocused({timeout:this.timeoutMs}),{success:!0,passMessage:`${t} does not have focus as expected. Test: "${o}".`})}catch{let n=await this.page.evaluate(()=>{let a=document.activeElement;return a?`${a.tagName}#${a.id||"no-id"}.${a.className||"no-class"}`:"no element focused"});return{success:!1,failMessage:`${s} (actual focus: ${n})`}}}async validateRole(e,t,r,s,o){let n=await e.getAttribute("role");return n===r?{success:!0,passMessage:`${t} has role "${r}". Test: "${o}".`}:{success:!1,failMessage:`${s} Expected role "${r}", found "${n}".`}}async validate(e,t){if(this.page.isClosed())return{success:!1,failMessage:"CRITICAL: Browser/page closed before completing all tests. Increase test timeout or reduce test complexity."};let r=null,s;if(e.controlledBy){let o=e.controlledBy,n=this.selectors[o.target];if(!n)return{success:!1,failMessage:`Selector for controlledBy.target '${o.target}' not found.`,target:null};let a=null;if(o.relativeTarget?a=await ee.resolve(this.page,n,o.relativeTarget):a=this.page.locator(n).first(),!a)return{success:!1,failMessage:"Controlling element for controlledBy not found.",target:null};let l=o.attribute||"aria-controls",u=await a.getAttribute(l);if(!u)return{success:!1,failMessage:`Controlling element does not have attribute '${l}'.`,target:null};if(r=this.page.locator(`#${u}`),!r||await r.count()===0)return{success:!1,failMessage:`Controlled element with id '${u}' not found.`,target:null}}else{let o=await this.resolveTarget(e.target,e.relativeTarget||e.expectedValue,e.selectorKey);if(r=o.target,s=o.error,s||!r)return{success:!1,failMessage:s||`Target ${e.target} not found.`,target:null}}if(e.target==="input"&&e.attribute==="aria-activedescendant"&&e.expectedValue==="!empty"&&e.relativeTarget&&e.selectorKey){let o=await ee.resolve(this.page,this.selectors[e.selectorKey],e.relativeTarget),n=o?await o.getAttribute("id"):null,a=await r.getAttribute("aria-activedescendant");return n&&a===n?{success:!0,passMessage:`input[aria-activedescendant] matches id of ${e.relativeTarget}(${e.selectorKey}). Test: "${t}".`}:{success:!1,failMessage:`input[aria-activedescendant] should match id of ${e.relativeTarget}(${e.selectorKey}), found "${a}".`}}switch(e.assertion){case"toBeVisible":return this.validateVisibility(r,e.target,!0,e.failureMessage||"",t);case"notToBeVisible":return this.validateVisibility(r,e.target,!1,e.failureMessage||"",t);case"toHaveAttribute":return e.attribute&&e.expectedValue!==void 0?this.validateAttribute(r,e.target,e.attribute,e.expectedValue,e.failureMessage||"",t):{success:!1,failMessage:"Missing attribute or expectedValue for toHaveAttribute assertion"};case"toHaveValue":return e.expectedValue!==void 0?this.validateValue(r,e.target,e.expectedValue,e.failureMessage||"",t):{success:!1,failMessage:"Missing expectedValue for toHaveValue assertion"};case"toHaveFocus":return this.validateFocus(r,e.target,!0,e.failureMessage||"",t);case"notToHaveFocus":return this.validateFocus(r,e.target,!1,e.failureMessage||"",t);case"toHaveRole":return e.expectedValue!==void 0?this.validateRole(r,e.target,e.expectedValue,e.failureMessage||"",t):{success:!1,failMessage:"Missing expectedValue for toHaveRole assertion"};default:return{success:!1,failMessage:`Unknown assertion type: ${e.assertion}`}}}}});var Zt={};W(Zt,{runContractTestsPlaywright:()=>js});async function js(c,e,t,r,s){let o=r?.test?.components?.find(w=>w.name===c),n=!!o?.contractPath,a=new Be(!0,n),l={actionTimeoutMs:400,assertionTimeoutMs:400,navigationTimeoutMs:3e4,componentReadyTimeoutMs:5e3},u=r?.test?.disableTimeouts===!0,h=o?.disableTimeouts===!0||u,y=(w,re,oe)=>{if(h)return 0;let X=w??re;return typeof X!="number"||!Number.isFinite(X)||X<0?oe:X},L=y(o?.actionTimeoutMs,r?.test?.actionTimeoutMs,l.actionTimeoutMs),q=y(o?.assertionTimeoutMs,r?.test?.assertionTimeoutMs,l.assertionTimeoutMs),x=y(o?.navigationTimeoutMs,r?.test?.navigationTimeoutMs,l.navigationTimeoutMs),U=y(o?.componentReadyTimeoutMs,r?.test?.componentReadyTimeoutMs,l.componentReadyTimeoutMs),J=$e(t),_=o?.contractPath;if(!_)throw new Error(`Contract path not found for component: ${c}`);let K=(()=>{if(je.default.isAbsolute(_))return _;if(s){let re=je.default.resolve(s,_);try{return(0,Le.readFileSync)(re,"utf-8"),re}catch{}}let w=je.default.resolve(process.cwd(),_);try{return(0,Le.readFileSync)(w,"utf-8"),w}catch{return new URL(_,Fs.url).pathname}})(),Q=(0,Le.readFileSync)(K,"utf-8"),$=JSON.parse(Q),Te=($.relationships?.length||0)+($.static.length||0)+$.dynamic.length,Ve=$.meta?.source?.apg,te=[],ce=[],le=[],H=[],A=null,N=(w,re)=>{let oe=we(re),X=Mt(oe,J);if(X==="error")return te.push(w),{status:"fail",level:oe,detail:w};if(X==="warning")return ce.push(w),{status:"warn",level:oe,detail:w};let ie=`${w} (ignored by strictness=${J}, level=${oe})`;return H.push(ie),{status:"skip",level:oe,detail:ie}},ds=w=>w&&typeof w=="object"&&w.success===!0;try{if(A=await Et(),e){try{await A.goto(e,{waitUntil:"domcontentloaded",timeout:x})}catch(i){throw new Error(`Failed to navigate to ${e}. Ensure dev server is running and accessible. Original error: ${i instanceof Error?i.message:String(i)}`)}await A.addStyleTag({content:"* { transition: none !important; animation: none !important; }"})}let w=await Pe.detect(c,o,L,q,s);if(!w)throw new Error(`Unsupported component: ${c}`);let re=w.getMainSelector();if(!re)throw new Error(`CRITICAL: No selector found in contract for ${c}`);try{await A.locator(re).first().waitFor({state:"attached",timeout:U})}catch(i){throw new Error(`
136
136
  \u274C CRITICAL: Component not found on page!
137
137
  This usually means:
138
138
  - The component didn't render
139
139
  - The URL is incorrect
140
- - The component selector '${ie}' in the contract is wrong
141
- - Original error: ${o}`)}a.start(c,Ce,Ue),c==="menu"&&v.selectors.main&&await A.locator(v.selectors.main).first().waitFor({state:"visible",timeout:U}).catch(()=>{});let oe=c==="menu"&&v.selectors.submenuTrigger?await A.locator(v.selectors.submenuTrigger).count()>0:!1,ee=o=>o.type==="aria-reference"&&[o.from,o.to].some(m=>["submenu","submenuTrigger","submenuItems"].includes(m||""))||o.type==="contains"&&[o.parent,o.child].some(m=>["submenu","submenuTrigger","submenuItems"].includes(m||"")),ne=0,_=0,z=0;for(let o of v.relationships||[]){if(S&&typeof S.resetState=="function")try{await S.resetState(A)}catch(w){ae.push(`Warning: resetState failed before relationship test: ${w instanceof Error?w.message:String(w)}`)}let m=fe(o.level);if(Array.isArray(o.setup)&&o.setup.length>0){let R=function(g){return T.includes(g)};var dt=R;let w=new ve(A,v.selectors,j),P=o.type==="aria-reference"?`${o.from}.${o.attribute} references ${o.to}`:`${o.parent} contains ${o.child}`,T=["focus","type","click","keypress","hover"],C=g=>({...g,type:R(g.type)?g.type:"click"}),E=o.setup.map(C),B=await De(E,w,S,A,P,["submenu","submenuTrigger","submenuItems"]);if(B.skip){N.push(B.message||"Setup action skipped"),a.reportStaticTest(P,"skip",B.message,m);continue}if(!B.success){let g=`Relationship setup failed: ${B.error}`,d=q(g,o.level);d.status==="fail"&&(_+=1),d.status==="warn"&&(z+=1),a.reportStaticTest(P,d.status,d.detail,d.level);continue}}if(c==="menu"&&!oe&&ee(o)){let P=o.type==="aria-reference"?`${o.from}.${o.attribute} references ${o.to}`:`${o.parent} contains ${o.child}`,T="Skipping submenu relationship assertion: no submenu capability detected in rendered component.";N.push(T),a.reportStaticTest(P,"skip",T,m);continue}if(o.type==="aria-reference"){let w=`${o.from}.${o.attribute} references ${o.to}`,P=v.selectors[o.from],T=v.selectors[o.to];if(!P||!T){let b=q(`Relationship selector missing: from="${o.from}" or to="${o.to}" not found in selectors.`,o.level);b.status==="fail"&&(_+=1),b.status==="warn"&&(z+=1),a.reportStaticTest(w,b.status,b.detail,b.level);continue}let R=A.locator(P).first(),C=A.locator(T).first(),E=await R.count()>0,B=await C.count()>0;if(!E||!B){if(c==="menu"&&ee(o)){let Q="Skipping submenu relationship assertion in static phase: submenu elements are not present until submenu is opened.";N.push(Q),a.reportStaticTest(w,"skip",Q,m);continue}let b=q(`Relationship target not found: ${E?o.to:o.from}.`,o.level);b.status==="fail"&&(_+=1),b.status==="warn"&&(z+=1),a.reportStaticTest(w,b.status,b.detail,b.level);continue}let g=await R.getAttribute(o.attribute),d=await C.getAttribute("id");if(!d){let b=q(`Relationship target "${o.to}" must have an id for ${o.attribute} validation.`,o.level);b.status==="fail"&&(_+=1),b.status==="warn"&&(z+=1),a.reportStaticTest(w,b.status,b.detail,b.level);continue}if(!(g||"").split(/\s+/).filter(Boolean).includes(d)){let b=q(`Expected ${o.from} ${o.attribute} to reference id "${d}", found "${g||""}".`,o.level);b.status==="fail"&&(_+=1),b.status==="warn"&&(z+=1),a.reportStaticTest(w,b.status,b.detail,b.level);continue}ce.push(`Relationship valid: ${o.from}.${o.attribute} -> ${o.to} (id=${d}).`),ne+=1,a.reportStaticTest(w,"pass",void 0,m);continue}if(o.type==="contains"){let w=`${o.parent} contains ${o.child}`,P=v.selectors[o.parent],T=v.selectors[o.child];if(!P||!T){let g=q(`Relationship selector missing: parent="${o.parent}" or child="${o.child}" not found in selectors.`,o.level);g.status==="fail"&&(_+=1),g.status==="warn"&&(z+=1),a.reportStaticTest(w,g.status,g.detail,g.level);continue}let R=A.locator(P).first();if(!(await R.count()>0)){if(c==="menu"&&ee(o)){let d="Skipping submenu relationship assertion in static phase: submenu container is not present until submenu is opened.";N.push(d),a.reportStaticTest(w,"skip",d,m);continue}let g=q(`Relationship parent target not found: ${o.parent}.`,o.level);g.status==="fail"&&(_+=1),g.status==="warn"&&(z+=1),a.reportStaticTest(w,g.status,g.detail,g.level);continue}if(await R.locator(T).count()<1){if(c==="menu"&&ee(o)){let d="Skipping submenu relationship assertion in static phase: submenu descendants are not present until submenu is opened.";N.push(d),a.reportStaticTest(w,"skip",d,m);continue}let g=q(`Expected ${o.parent} to contain descendant matching selector for ${o.child}.`,o.level);g.status==="fail"&&(_+=1),g.status==="warn"&&(z+=1),a.reportStaticTest(w,g.status,g.detail,g.level);continue}ce.push(`Relationship valid: ${o.parent} contains ${o.child}.`),ne+=1,a.reportStaticTest(w,"pass",void 0,m)}}async function gt(o,m,w,P={}){if(!o||typeof o!="object"||!("ref"in o))return o;let T;if(o.ref==="relative"){if(!o.relativeTarget||!P.relativeBaseSelector)return;let R=w.locator(P.relativeBaseSelector),C=await R.count(),E=0;if(o.relativeTarget==="first"?E=0:o.relativeTarget==="second"?E=1:o.relativeTarget==="last"?E=C-1:isNaN(Number(o.relativeTarget))?E=0:E=Number(o.relativeTarget),E<0||E>=C)return;let B=R.nth(E);return await mt(B,o.property||o.attribute)}else{if(T=m[o.ref],!T)throw new Error(`Selector for ref '${o.ref}' not found in contract selectors.`);let R=w.locator(T).first();return await mt(R,o.property||o.attribute)}}async function mt(o,m){if(o)return!m||m==="id"?await o.getAttribute("id")??void 0:m==="class"?await o.getAttribute("class")??void 0:m==="textContent"?await o.evaluate(w=>w.textContent??void 0):m.startsWith("aria-")?await o.getAttribute(m)??void 0:m.endsWith("*")?await o.evaluate(P=>{let T=[];for(let R of Array.from(P.attributes))R.name.startsWith("aria-")&&T.push(`${R.name}=${R.value}`);return T.join(";")}):await o.getAttribute(m)??void 0}let us=new Te(A,v.selectors,H);async function De(o,m,w,P,T,R=[]){if(!Array.isArray(o)||o.length===0)return{success:!0};w&&typeof w.resetState=="function"&&await w.resetState(P);for(let C of o){let E={success:!0};try{if(C.type==="focus")C.target==="relative"&&C.relativeTarget?E=await m.focus("relative",C.relativeTarget):E=await m.focus(C.target);else if(C.type==="type"&&C.value)E=await m.type(C.target,C.value);else if(C.type==="click")E=await m.click(C.target,C.relativeTarget);else if(C.type==="keypress"&&C.key)E=await m.keypress(C.target,C.key,C.relativeTarget);else if(C.type==="hover")E=await m.hover(C.target,C.relativeTarget);else continue}catch(B){E={success:!1,error:B instanceof Error?B.message:String(B)}}if(!E.success){let B=E.error||"Setup action failed";return R.some(d=>T.includes(d)||B.includes(d))?{success:!1,skip:!0,message:`Skipping test - capability not present: ${B}`}:{success:!1,error:B}}}return{success:!0}}for(let o of v.static||[]){if(S&&typeof S.resetState=="function")try{await S.resetState(A)}catch(g){ae.push(`Warning: resetState failed before static test: ${g instanceof Error?g.message:String(g)}`)}if(o.target==="relative")continue;let m=`${o.target}${o.attribute?` (${o.attribute})`:""}`,w=fe(o.level);if(c==="menu"&&o.target==="submenuTrigger"&&!oe){let g=`Skipping submenu static assertion for ${o.target}: no submenu capability detected in rendered component.`;N.push(g),a.reportStaticTest(m,"skip",g,w);continue}let P=[];if(o.target||P.push("target"),o.attribute||P.push("attribute"),typeof o.expectedValue>"u"&&P.push("expectedValue"),P.length>0){let g=`${o.target||""}${o.attribute?` (${o.attribute})`:""}`,d=`Static assertion missing required field(s): ${P.join(", ")}`,k=q(d,o.level);k.status==="fail"&&(_+=1),k.status==="warn"&&(z+=1),a.reportStaticTest(g,k.status,k.detail,k.level);continue}if(Array.isArray(o.setup)&&o.setup.length>0){let k=function(p){return d.includes(p)};var dt=k;let g=new ve(A,v.selectors,j),d=["focus","type","click","keypress","hover"],te=p=>({...p,type:k(p.type)?p.type:"click"}),b=o.setup.map(te),Q=await De(b,g,S,A,m,["submenu","submenuTrigger","submenuItems"]);if(Q.skip){N.push(Q.message||"Setup action skipped"),a.reportStaticTest(m,"skip",Q.message,w);continue}if(!Q.success){let p=`Static setup failed: ${Q.error}`,x=q(p,o.level);x.status==="fail"&&(_+=1),x.status==="warn"&&(z+=1),a.reportStaticTest(m,x.status,x.detail,x.level);continue}}let T=v.selectors[o.target];if(!T){let g=`Selector for target ${o.target} not found.`,d=q(g,o.level);d.status==="fail"&&(_+=1),d.status==="warn"&&(z+=1),a.reportStaticTest(m,d.status,d.detail,d.level);continue}let R=A.locator(T).first();if(!(await R.count()>0)){let g=`Target ${o.target} not found.`,d=q(g,o.level);d.status==="fail"&&(_+=1),d.status==="warn"&&(z+=1),a.reportStaticTest(m,d.status,d.detail,d.level);continue}let E=(g,d,k)=>{let te=new RegExp(`\\[${d}(?:=["']?([^\\]"']+)["']?)?\\]`),b=g.match(te);if(!b)return!1;if(!k)return!0;let Q=b[1];return Q?k.split(" | ").includes(Q):!1},B=o.expectedValue;if(o.expectedValue&&typeof o.expectedValue=="object"&&"ref"in o.expectedValue){let g={},d=o.relativeTarget;if(o.expectedValue.ref==="relative"&&o.target==="relative"&&d){let k=v.selectors[d];if(!k)throw new Error(`Selector for relativeTarget '${d}' not found in contract selectors.`);g.relativeBaseSelector=k}else if(o.expectedValue.ref==="relative"&&d){let k=v.selectors[d];if(!k)throw new Error(`Selector for relativeTarget '${d}' not found in contract selectors.`);g.relativeBaseSelector=k}B=await gt(o.expectedValue,v.selectors,A,g)}if(o.expectedValue)if(E(T,o.attribute,typeof B=="string"?B:void 0))ce.push(`${o.attribute}="${B}" on ${o.target} verified by selector (already present in: ${T}).`),ne+=1,a.reportStaticTest(m,"pass",void 0,w);else{let g=B??"",d=await us.validateAttribute(R,o.target,o.attribute,g,o.failureMessage,"Static ARIA Test");if(d.success&&d.passMessage)ce.push(d.passMessage),ne+=1,a.reportStaticTest(m,"pass",void 0,w);else if(!d.success&&d.failMessage){let k=q(d.failMessage,o.level);k.status==="fail"&&(_+=1),k.status==="warn"&&(z+=1),a.reportStaticTest(m,k.status,k.detail,k.level)}}else{let g=o.attribute.split(" | "),d=!1,k=!0;for(let te of g){let b=te.trim();if(E(T,b)){ce.push(`${b} on ${o.target} verified by selector (already present in: ${T}).`),d=!0;continue}if(k=!1,await R.getAttribute(b)!==null){d=!0;break}}if(!d&&!k){let te=o.failureMessage+` None of the attributes "${o.attribute}" are present.`,b=q(te,o.level);b.status==="fail"&&(_+=1),b.status==="warn"&&(z+=1),a.reportStaticTest(m,b.status,b.detail,b.level)}else!k&&d?(ce.push(`At least one of the attributes "${o.attribute}" exists on the element.`),ne+=1,a.reportStaticTest(m,"pass",void 0,w)):(ne+=1,a.reportStaticTest(m,"pass",void 0,w))}}for(let o of v.dynamic||[]){if(!o.assertions||o.assertions.length===0){let p="Skipping test - no assertions found for this dynamic test.";N.push(p),a.reportTest({description:o.description,level:fe(o.level)},"skip",p);continue}if(!A||A.isClosed()){console.warn(`
142
- \u26A0\uFE0F Browser closed - skipping remaining ${v.dynamic.length-v.dynamic.indexOf(o)} tests
143
- `),Z.push(`CRITICAL: Browser/page closed before completing all tests. ${v.dynamic.length-v.dynamic.indexOf(o)} tests skipped.`);break}try{await S.resetState(A)}catch(p){let x=p instanceof Error?p.message:String(p);throw a.error(x),p}let{setup:m=[],action:w,assertions:P}=o,T=fe(o.level),R=new ve(A,v.selectors,j);if(Array.isArray(m)&&m.length>0){let x=function(X){return p.includes(X)};var dt=x;let p=["focus","type","click","keypress","hover"],me=X=>({...X,type:x(X.type)?X.type:"click"}),qe=m.map(me),re=await De(qe,R,S,A,o.description,["submenu","submenuTrigger","submenuItems"]);if(re.skip){N.push(re.message||"Setup action skipped"),a.reportTest({description:o.description,level:T},"skip",re.message);continue}if(!re.success){let X=q(`Setup failed: ${re.error}`,o.level);a.reportTest({description:o.description,level:T},X.status,X.detail);continue}}let C=Z.length,E=ae.length,B=N.length;if(await S.shouldSkipTest(o,A)){let p="Skipping test - component-specific conditions not met";N.push(p),a.reportTest({description:o.description,level:T},"skip",p);continue}let d=new Te(A,v.selectors,H),k=!1,te=null;for(let p of w){if(!A||A.isClosed()){Z.push("CRITICAL: Browser/page closed during test execution. Remaining actions skipped."),k=!0;break}let x;if(p.type==="focus")p.target==="relative"&&p.relativeTarget?x=await R.focus("relative",p.relativeTarget):x=await R.focus(p.target);else if(p.type==="type"&&p.value)x=await R.type(p.target,p.value);else if(p.type==="click")x=await R.click(p.target,p.relativeTarget);else if(p.type==="keypress"&&p.key)x=await R.keypress(p.target,p.key,p.relativeTarget);else if(p.type==="hover")x=await R.hover(p.target,p.relativeTarget);else continue;if(!x.success){if(x.error){let me=q(x.error,o.level);te={status:me.status,detail:me.detail}}k=!0;break}}if(k){a.reportTest({description:o.description,level:T},te?.status||"fail",te?.detail||Z[Z.length-1]);continue}for(let p of P){let x;if(p.expectedValue&&typeof p.expectedValue=="object"&&"ref"in p.expectedValue)if(p.expectedValue.ref==="relative"){let{RelativeTargetResolver:le}=await Promise.resolve().then(()=>(Ie(),_t)),X=v.selectors.relative;if(!X)throw new Error("Relative selector not defined in contract selectors.");let $e=p.relativeTarget||"first",ue=await le.resolve(A,X,$e);if(!ue)throw new Error(`Could not resolve relative target '${$e}' for expectedValue.`);let yt=p.expectedValue.property||p.expectedValue.attribute||"id";if(yt==="textContent")x=await ue.evaluate(ke=>ke.textContent??void 0);else{let ke=await ue.getAttribute(yt);x=ke===null?void 0:ke}}else x=await gt(p.expectedValue,v.selectors,A,{});else typeof p.expectedValue=="string"||typeof p.expectedValue>"u"?x=p.expectedValue:x="";let me={...p,expectedValue:x},qe=x??"",re=await d.validate({...me,expectedValue:qe},o.description);if(re.success&&re.passMessage)ce.push(re.passMessage);else if(!re.success&&re.failMessage){let le=[];if(p.target||le.push("target"),p.assertion||le.push("assertion"),["toHaveAttribute","toHaveValue","toHaveRole"].includes(p.assertion)&&(typeof p.attribute>"u"&&p.assertion==="toHaveAttribute"&&le.push("attribute"),typeof p.expectedValue>"u"&&le.push("expectedValue")),le.length>0){let X=fe(p.level||o.level),$e=`Dynamic assertion missing required field(s): ${le.join(", ")}`,ue=q($e,X);if(ue.status==="skip")continue;Z.push($e),a.reportTest({description:o.description,level:X},ue.status,ue.detail);continue}}}let b=Z.length,Q=ae.length,ht=N.length;b>C?a.reportTest({description:o.description,level:T},"fail",Z[Z.length-1]):Q>E?a.reportTest({description:o.description,level:T},"warn",ae[ae.length-1]):ht>B?a.reportTest({description:o.description,level:T},"skip",N[N.length-1]):a.reportTest({description:o.description,level:T},"pass")}a.reportStatic(ne,_,z),a.summary(Z)}catch(S){if(S instanceof Error)throw S.message.includes("Executable doesn't exist")||S.message.includes("browserType.launch")?new Error(`
140
+ - The component selector '${re}' in the contract is wrong
141
+ - Original error: ${i}`)}a.start(c,Te,Ve),c==="menu"&&$.selectors.main&&await A.locator($.selectors.main).first().waitFor({state:"visible",timeout:U}).catch(()=>{});let oe=c==="menu"&&$.selectors.submenuTrigger?await A.locator($.selectors.submenuTrigger).count()>0:!1,X=i=>i.type==="aria-reference"&&[i.from,i.to].some(d=>["submenu","submenuTrigger","submenuItems"].includes(d||""))||i.type==="contains"&&[i.parent,i.child].some(d=>["submenu","submenuTrigger","submenuItems"].includes(d||"")),ie=0,z=0,G=0;for(let i of $.relationships||[]){if(w&&typeof w.resetState=="function")try{await w.resetState(A)}catch(v){ce.push(`Warning: resetState failed before relationship test: ${v instanceof Error?v.message:String(v)}`)}let d=we(i.level);if(Array.isArray(i.setup)&&i.setup.length>0){let R=function(g){return T.includes(g)};var dt=R;let v=new ve(A,$.selectors,L),M=i.type==="aria-reference"?`${i.from}.${i.attribute} references ${i.to}`:`${i.parent} contains ${i.child}`,T=["focus","type","click","keypress","hover"],C=g=>({...g,type:R(g.type)?g.type:"click"}),E=i.setup.map(C),P=await Ue(E,v,w,A,M,["submenu","submenuTrigger","submenuItems"]);if(P.skip){H.push(P.message||"Setup action skipped"),a.reportStaticTest(M,"skip",P.message,d);continue}if(!P.success){let g=`Relationship setup failed: ${P.error}`,f=N(g,i.level);f.status==="fail"&&(z+=1),f.status==="warn"&&(G+=1),a.reportStaticTest(M,f.status,f.detail,f.level);continue}}if(c==="menu"&&!oe&&X(i)){let M=i.type==="aria-reference"?`${i.from}.${i.attribute} references ${i.to}`:`${i.parent} contains ${i.child}`,T="Skipping submenu relationship assertion: no submenu capability detected in rendered component.";H.push(T),a.reportStaticTest(M,"skip",T,d);continue}if(i.type==="aria-reference"){let v=`${i.from}.${i.attribute} references ${i.to}`,M=$.selectors[i.from],T=$.selectors[i.to];if(!M||!T){let b=N(`Relationship selector missing: from="${i.from}" or to="${i.to}" not found in selectors.`,i.level);b.status==="fail"&&(z+=1),b.status==="warn"&&(G+=1),a.reportStaticTest(v,b.status,b.detail,b.level);continue}let R=A.locator(M).first(),C=A.locator(T).first(),E=await R.count()>0,P=await C.count()>0;if(!E||!P){if(c==="menu"&&X(i)){let Y="Skipping submenu relationship assertion in static phase: submenu elements are not present until submenu is opened.";H.push(Y),a.reportStaticTest(v,"skip",Y,d);continue}let b=N(`Relationship target not found: ${E?i.to:i.from}.`,i.level);b.status==="fail"&&(z+=1),b.status==="warn"&&(G+=1),a.reportStaticTest(v,b.status,b.detail,b.level);continue}let g=await R.getAttribute(i.attribute),f=await C.getAttribute("id");if(!f){let b=N(`Relationship target "${i.to}" must have an id for ${i.attribute} validation.`,i.level);b.status==="fail"&&(z+=1),b.status==="warn"&&(G+=1),a.reportStaticTest(v,b.status,b.detail,b.level);continue}if(!(g||"").split(/\s+/).filter(Boolean).includes(f)){let b=N(`Expected ${i.from} ${i.attribute} to reference id "${f}", found "${g||""}".`,i.level);b.status==="fail"&&(z+=1),b.status==="warn"&&(G+=1),a.reportStaticTest(v,b.status,b.detail,b.level);continue}le.push(`Relationship valid: ${i.from}.${i.attribute} -> ${i.to} (id=${f}).`),ie+=1,a.reportStaticTest(v,"pass",void 0,d);continue}if(i.type==="contains"){let v=`${i.parent} contains ${i.child}`,M=$.selectors[i.parent],T=$.selectors[i.child];if(!M||!T){let g=N(`Relationship selector missing: parent="${i.parent}" or child="${i.child}" not found in selectors.`,i.level);g.status==="fail"&&(z+=1),g.status==="warn"&&(G+=1),a.reportStaticTest(v,g.status,g.detail,g.level);continue}let R=A.locator(M).first();if(!(await R.count()>0)){if(c==="menu"&&X(i)){let f="Skipping submenu relationship assertion in static phase: submenu container is not present until submenu is opened.";H.push(f),a.reportStaticTest(v,"skip",f,d);continue}let g=N(`Relationship parent target not found: ${i.parent}.`,i.level);g.status==="fail"&&(z+=1),g.status==="warn"&&(G+=1),a.reportStaticTest(v,g.status,g.detail,g.level);continue}if(await R.locator(T).count()<1){if(c==="menu"&&X(i)){let f="Skipping submenu relationship assertion in static phase: submenu descendants are not present until submenu is opened.";H.push(f),a.reportStaticTest(v,"skip",f,d);continue}let g=N(`Expected ${i.parent} to contain descendant matching selector for ${i.child}.`,i.level);g.status==="fail"&&(z+=1),g.status==="warn"&&(G+=1),a.reportStaticTest(v,g.status,g.detail,g.level);continue}le.push(`Relationship valid: ${i.parent} contains ${i.child}.`),ie+=1,a.reportStaticTest(v,"pass",void 0,d)}}async function mt(i,d,v,M={}){if(!i||typeof i!="object"||!("ref"in i))return i;let T;if(i.ref==="relative"){if(!i.relativeTarget||!M.relativeBaseSelector)return;let R=v.locator(M.relativeBaseSelector),C=await R.count(),E=0;if(i.relativeTarget==="first"?E=0:i.relativeTarget==="second"?E=1:i.relativeTarget==="last"?E=C-1:isNaN(Number(i.relativeTarget))?E=0:E=Number(i.relativeTarget),E<0||E>=C)return;let P=R.nth(E);return await ht(P,i.property||i.attribute)}else{if(T=d[i.ref],!T)throw new Error(`Selector for ref '${i.ref}' not found in contract selectors.`);let R=v.locator(T).first();return await ht(R,i.property||i.attribute)}}async function ht(i,d){if(i)return!d||d==="id"?await i.getAttribute("id")??void 0:d==="class"?await i.getAttribute("class")??void 0:d==="textContent"?await i.evaluate(v=>v.textContent??void 0):d.startsWith("aria-")?await i.getAttribute(d)??void 0:d.endsWith("*")?await i.evaluate(M=>{let T=[];for(let R of Array.from(M.attributes))R.name.startsWith("aria-")&&T.push(`${R.name}=${R.value}`);return T.join(";")}):await i.getAttribute(d)??void 0}let ms=new Se(A,$.selectors,q);async function Ue(i,d,v,M,T,R=[]){if(!Array.isArray(i)||i.length===0)return{success:!0};v&&typeof v.resetState=="function"&&await v.resetState(M);for(let C of i){let E={success:!0};try{if(C.type==="focus")C.target==="relative"&&C.relativeTarget?E=await d.focus("relative",C.relativeTarget):E=await d.focus(C.target);else if(C.type==="type"&&C.value)E=await d.type(C.target,C.value);else if(C.type==="click")E=await d.click(C.target,C.relativeTarget);else if(C.type==="keypress"&&C.key)E=await d.keypress(C.target,C.key,C.relativeTarget);else if(C.type==="hover")E=await d.hover(C.target,C.relativeTarget);else continue}catch(P){E={success:!1,error:P instanceof Error?P.message:String(P)}}if(!E.success){let P=E.error||"Setup action failed";return R.some(f=>T.includes(f)||P.includes(f))?{success:!1,skip:!0,message:`Skipping test - capability not present: ${P}`}:{success:!1,error:P}}}return{success:!0}}for(let i of $.static||[]){if(w&&typeof w.resetState=="function")try{await w.resetState(A)}catch(g){ce.push(`Warning: resetState failed before static test: ${g instanceof Error?g.message:String(g)}`)}if(i.target==="relative")continue;let d=`${i.target}${i.attribute?` (${i.attribute})`:""}`,v=we(i.level);if(c==="menu"&&i.target==="submenuTrigger"&&!oe){let g=`Skipping submenu static assertion for ${i.target}: no submenu capability detected in rendered component.`;H.push(g),a.reportStaticTest(d,"skip",g,v);continue}let M=[];if(i.target||M.push("target"),i.attribute||M.push("attribute"),typeof i.expectedValue>"u"&&M.push("expectedValue"),M.length>0){let g=`${i.target||""}${i.attribute?` (${i.attribute})`:""}`,f=`Static assertion missing required field(s): ${M.join(", ")}`,k=N(f,i.level);k.status==="fail"&&(z+=1),k.status==="warn"&&(G+=1),a.reportStaticTest(g,k.status,k.detail,k.level);continue}if(Array.isArray(i.setup)&&i.setup.length>0){let k=function(ne){return f.includes(ne)};var dt=k;let g=new ve(A,$.selectors,L),f=["focus","type","click","keypress","hover"],Z=ne=>({...ne,type:k(ne.type)?ne.type:"click"}),b=i.setup.map(Z),Y=await Ue(b,g,w,A,d,["submenu","submenuTrigger","submenuItems"]);if(Y.skip){H.push(Y.message||"Setup action skipped"),a.reportStaticTest(d,"skip",Y.message,v);continue}if(!Y.success){let ne=`Static setup failed: ${Y.error}`,pe=N(ne,i.level);pe.status==="fail"&&(z+=1),pe.status==="warn"&&(G+=1),a.reportStaticTest(d,pe.status,pe.detail,pe.level);continue}}let T=$.selectors[i.target];if(!T){let g=`Selector for target ${i.target} not found.`,f=N(g,i.level);f.status==="fail"&&(z+=1),f.status==="warn"&&(G+=1),a.reportStaticTest(d,f.status,f.detail,f.level);continue}let R=A.locator(T).first();if(!(await R.count()>0)){let g=`Target ${i.target} not found.`,f=N(g,i.level);f.status==="fail"&&(z+=1),f.status==="warn"&&(G+=1),a.reportStaticTest(d,f.status,f.detail,f.level);continue}let E=(g,f,k)=>{let Z=new RegExp(`\\[${f}(?:=["']?([^\\]"']+)["']?)?\\]`),b=g.match(Z);if(!b)return!1;if(!k)return!0;let Y=b[1];return Y?k.split(" | ").includes(Y):!1},P=i.expectedValue;if(i.expectedValue&&typeof i.expectedValue=="object"&&"ref"in i.expectedValue){let g={},f=i.relativeTarget;if(i.expectedValue.ref==="relative"&&i.target==="relative"&&f){let k=$.selectors[f];if(!k)throw new Error(`Selector for relativeTarget '${f}' not found in contract selectors.`);g.relativeBaseSelector=k}else if(i.expectedValue.ref==="relative"&&f){let k=$.selectors[f];if(!k)throw new Error(`Selector for relativeTarget '${f}' not found in contract selectors.`);g.relativeBaseSelector=k}P=await mt(i.expectedValue,$.selectors,A,g)}if(i.expectedValue)if(E(T,i.attribute,typeof P=="string"?P:void 0))le.push(`${i.attribute}="${P}" on ${i.target} verified by selector (already present in: ${T}).`),ie+=1,a.reportStaticTest(d,"pass",void 0,v);else{let g=P??"",f=await ms.validateAttribute(R,i.target,i.attribute,g,i.failureMessage,"Static ARIA Test");if(f.success&&f.passMessage)le.push(f.passMessage),ie+=1,a.reportStaticTest(d,"pass",void 0,v);else if(!f.success&&f.failMessage){let k=N(f.failMessage,i.level);k.status==="fail"&&(z+=1),k.status==="warn"&&(G+=1),a.reportStaticTest(d,k.status,k.detail,k.level)}}else{let g=i.attribute.split(" | "),f=!1,k=!0;for(let Z of g){let b=Z.trim();if(E(T,b)){le.push(`${b} on ${i.target} verified by selector (already present in: ${T}).`),f=!0;continue}if(k=!1,await R.getAttribute(b)!==null){f=!0;break}}if(!f&&!k){let Z=i.failureMessage+` None of the attributes "${i.attribute}" are present.`,b=N(Z,i.level);b.status==="fail"&&(z+=1),b.status==="warn"&&(G+=1),a.reportStaticTest(d,b.status,b.detail,b.level)}else!k&&f?(le.push(`At least one of the attributes "${i.attribute}" exists on the element.`),ie+=1,a.reportStaticTest(d,"pass",void 0,v)):(ie+=1,a.reportStaticTest(d,"pass",void 0,v))}}for(let i of $.dynamic||[]){if(!i.assertions||i.assertions.length===0){let m="Skipping test - no assertions found for this dynamic test.";H.push(m),a.reportTest({description:i.description,level:we(i.level)},"skip",m);continue}if(!A||A.isClosed()){console.warn(`
142
+ \u26A0\uFE0F Browser closed - skipping remaining ${$.dynamic.length-$.dynamic.indexOf(i)} tests
143
+ `),te.push(`CRITICAL: Browser/page closed before completing all tests. ${$.dynamic.length-$.dynamic.indexOf(i)} tests skipped.`);break}try{await w.resetState(A)}catch(m){let j=m instanceof Error?m.message:String(m);throw a.error(j),m}let{setup:d=[],action:v,assertions:M}=i,T=we(i.level),R=new ve(A,$.selectors,L);if(Array.isArray(d)&&d.length>0){let j=function(se){return m.includes(se)};var dt=j;let m=["focus","type","click","keypress","hover"],de=se=>({...se,type:j(se.type)?se.type:"click"}),De=d.map(de),ae=await Ue(De,R,w,A,i.description,["submenu","submenuTrigger","submenuItems"]);if(ae.skip){H.push(ae.message||"Setup action skipped"),a.reportTest({description:i.description,level:T},"skip",ae.message);continue}if(!ae.success){let se=N(`Setup failed: ${ae.error}`,i.level);a.reportTest({description:i.description,level:T},se.status,se.detail);continue}}let C=te.length,E=ce.length,P=H.length;if(await w.shouldSkipTest(i,A)){let m="Skipping test - component-specific conditions not met";H.push(m),a.reportTest({description:i.description,level:T},"skip",m);continue}let f=new Se(A,$.selectors,q),k=!1,Z=null;for(let m of v){if(!A||A.isClosed()){te.push("CRITICAL: Browser/page closed during test execution. Remaining actions skipped."),k=!0;break}let j;if(m.type==="focus")m.target==="relative"&&m.relativeTarget?j=await R.focus("relative",m.relativeTarget):j=await R.focus(m.target);else if(m.type==="type"&&m.value)j=await R.type(m.target,m.value);else if(m.type==="click")j=await R.click(m.target,m.relativeTarget);else if(m.type==="keypress"&&m.key)j=await R.keypress(m.target,m.key,m.relativeTarget);else if(m.type==="hover")j=await R.hover(m.target,m.relativeTarget);else continue;if(!j.success){if(j.error){let de=N(j.error,i.level);Z={status:de.status,detail:de.detail}}k=!0;break}}if(k){a.reportTest({description:i.description,level:T},Z?.status||"fail",Z?.detail||te[te.length-1]);continue}let b=!1,Y="";for(let m of M){let j;if(m.expectedValue&&typeof m.expectedValue=="object"&&"ref"in m.expectedValue)if(m.expectedValue.ref==="relative"){let{RelativeTargetResolver:hs}=await Promise.resolve().then(()=>(Ie(),Kt)),se=$.selectors.relative;if(!se)throw new Error("Relative selector not defined in contract selectors.");let bt=m.relativeTarget||"first",Oe=await hs.resolve(A,se,bt);if(!Oe)throw new Error(`Could not resolve relative target '${bt}' for expectedValue.`);let wt=m.expectedValue.property||m.expectedValue.attribute||"id";if(wt==="textContent")j=await Oe.evaluate(Ce=>Ce.textContent??void 0);else{let Ce=await Oe.getAttribute(wt);j=Ce===null?void 0:Ce}}else j=await mt(m.expectedValue,$.selectors,A,{});else typeof m.expectedValue=="string"||typeof m.expectedValue>"u"?j=m.expectedValue:j="";let de={...m,expectedValue:j},De=j??"",ae=await f.validate({...de,expectedValue:De},i.description);ds(ae)?le.push(ae.passMessage):(b=!0,Y=ae.failMessage||"Assertion failed.")}if(b){a.reportTest({description:i.description,level:T},"fail",Y);continue}let yt=te.length,ne=ce.length,pe=H.length;yt>C?a.reportTest({description:i.description,level:T},"fail",te[te.length-1]):ne>E?a.reportTest({description:i.description,level:T},"warn",ce[ce.length-1]):pe>P?a.reportTest({description:i.description,level:T},"skip",H[H.length-1]):a.reportTest({description:i.description,level:T},"pass")}a.reportStatic(ie,z,G),a.summary(te)}catch(w){if(w instanceof Error)throw w.message.includes("Executable doesn't exist")||w.message.includes("browserType.launch")?new Error(`
144
144
  \u274C CRITICAL: Playwright browsers not found!
145
- \u{1F4E6} Run: npx playwright install chromium`):S.message.includes("net::ERR_CONNECTION_REFUSED")||S.message.includes("NS_ERROR_CONNECTION_REFUSED")?new Error(`
145
+ \u{1F4E6} Run: npx playwright install chromium`):w.message.includes("net::ERR_CONNECTION_REFUSED")||w.message.includes("NS_ERROR_CONNECTION_REFUSED")?new Error(`
146
146
  \u274C CRITICAL: Cannot connect to dev server!
147
- Make sure your dev server is running at ${e}`):S.message.includes("Timeout")&&S.message.includes("waitFor")?new Error(`
147
+ Make sure your dev server is running at ${e}`):w.message.includes("Timeout")&&w.message.includes("waitFor")?new Error(`
148
148
  \u274C CRITICAL: Component not found on page!
149
149
  The component selector could not be found within ${U}ms.
150
150
  This usually means:
151
151
  - The component didn't render
152
152
  - The URL is incorrect
153
153
  - The component selector was not provided to the component utility, or a wrong selector was used
154
- `):S.message.includes("Target page, context or browser has been closed")?new Error(`
154
+ `):w.message.includes("Target page, context or browser has been closed")?new Error(`
155
155
  \u274C CRITICAL: Browser/page was closed unexpectedly!
156
156
  This usually means:
157
157
  - The test timeout was too short
158
158
  - The browser crashed
159
- - An external process killed the browser`):S}finally{A&&await A.close()}return{passes:ce,failures:Z,skipped:N,warnings:ae}}var je,Fe,Ms,Kt=L(()=>{"use strict";je=require("fs"),Fe=F(require("path"),1);et();Wt();Jt();zt();Gt();tt();Ms={}});async function Xt(c,e,t={}){if(!c||typeof c!="string")throw new Error("\u274C testUiComponent requires a valid componentName (string)");if(!e)throw new Error("\u274C testUiComponent requires a URL");if(e&&typeof e!="string")throw new Error("\u274C testUiComponent url parameter must be a string");let r={violations:[]};async function s(f){try{let h=await fetch(f,{method:"HEAD",signal:AbortSignal.timeout(1e3)});if(h.ok||h.status===304)return f}catch{return null}return null}let i=Se(t.strictness),n={},a=typeof process<"u"?process.cwd():"";if(typeof process<"u"&&typeof process.cwd=="function")try{let{loadConfig:f}=await Promise.resolve().then(()=>(Re(),_e)),h=await f(process.cwd());if(n=h.config,h.configPath&&(a=Qt.default.dirname(h.configPath)),t.strictness===void 0){let y=n.test?.components?.find(j=>j?.name===c)?.strictness;i=Se(y??n.test?.strictness)}}catch{t.strictness===void 0&&(i="balanced")}let l;try{if(e){let f=await s(e);if(f){console.log(`\u{1F3AD} Running Playwright tests on ${f}`);let{runContractTestsPlaywright:h}=await Promise.resolve().then(()=>(Kt(),Yt));l=await h(c,f,i,n,a)}else throw new Error(`\u274C Dev server not running at ${e}
160
- Please start your dev server and try again.`)}else throw new Error("\u274C URL is required for component testing. Please provide a URL to run full accessibility tests with testUiComponent.")}catch(f){throw f instanceof Error?f:new Error(`\u274C Contract test execution failed: ${String(f)}`)}let u={violations:r.violations,raw:r,contract:l};if(l.failures.length>0&&e==="Playwright")throw new Error(`
159
+ - An external process killed the browser`):w}finally{A&&await A.close()}return{passes:le,failures:te,skipped:H,warnings:ce}}var Le,je,Fs,es=I(()=>{"use strict";Le=require("fs"),je=F(require("path"),1);et();Gt();Yt();Qt();Xt();tt();Fs={}});async function ss(c,e,t={}){if(!c||typeof c!="string")throw new Error("\u274C testUiComponent requires a valid componentName (string)");if(!e)throw new Error("\u274C testUiComponent requires a URL");if(e&&typeof e!="string")throw new Error("\u274C testUiComponent url parameter must be a string");let r={violations:[]};async function s(p){try{let h=await fetch(p,{method:"HEAD",signal:AbortSignal.timeout(1e3)});if(h.ok||h.status===304)return p}catch{return null}return null}let o=$e(t.strictness),n={},a=typeof process<"u"?process.cwd():"";if(typeof process<"u"&&typeof process.cwd=="function")try{let{loadConfig:p}=await Promise.resolve().then(()=>(Ae(),_e)),h=await p(process.cwd());if(n=h.config,h.configPath&&(a=ts.default.dirname(h.configPath)),t.strictness===void 0){let y=n.test?.components?.find(L=>L?.name===c)?.strictness;o=$e(y??n.test?.strictness)}}catch{t.strictness===void 0&&(o="balanced")}let l;try{if(e){let p=await s(e);if(p){console.log(`\u{1F3AD} Running Playwright tests on ${p}`);let{runContractTestsPlaywright:h}=await Promise.resolve().then(()=>(es(),Zt));l=await h(c,p,o,n,a)}else throw new Error(`\u274C Dev server not running at ${e}
160
+ Please start your dev server and try again.`)}else throw new Error("\u274C URL is required for component testing. Please provide a URL to run full accessibility tests with testUiComponent.")}catch(p){throw p instanceof Error?p:new Error(`\u274C Contract test execution failed: ${String(p)}`)}let u={violations:r.violations,raw:r,contract:l};if(l.failures.length>0&&e==="Playwright")throw new Error(`
161
161
  \u274C ${l.failures.length} accessibility contract test${l.failures.length>1?"s":""} failed (Playwright mode)
162
162
  \u2705 ${l.passes.length} test${l.passes.length>1?"s":""} passed
163
163
 
164
164
  \u{1F4CB} Review the detailed test report above for specific failures.
165
- \u{1F4A1} Contract tests validate ARIA attributes and keyboard interactions per W3C APG guidelines.`);if(r.violations.length>0){let f=r.violations.length,h=r.violations.map(y=>`
165
+ \u{1F4A1} Contract tests validate ARIA attributes and keyboard interactions per W3C APG guidelines.`);if(r.violations.length>0){let p=r.violations.length,h=r.violations.map(y=>`
166
166
  - ${y.id}: ${y.description}
167
167
  Impact: ${y.impact}
168
168
  Affected elements: ${y.nodes.length}
169
169
  Help: ${y.helpUrl}`).join(`
170
170
  `);throw new Error(`
171
- \u274C ${f} axe accessibility violation${f>1?"s":""} detected
171
+ \u274C ${p} axe accessibility violation${p>1?"s":""} detected
172
172
  ${h}
173
173
 
174
- \u{1F4CB} Full details available in result.violations`)}return u}async function Zt(){await Rt()}var Qt,lt,es=L(()=>{"use strict";et();tt();Qt=F(require("path"),1);lt=async()=>({passes:[],failures:[],skipped:[]});typeof window>"u"&&(lt=async()=>{console.log(`\u{1F680} Running component accessibility tests...
175
- `);let{exec:c}=await import("child_process"),e=(await import("chalk")).default;return new Promise((t,r)=>{c("npx vitest --run --reporter verbose",async(s,i,n)=>{if(console.log(i),n&&console.error(n),!s||s.code===0){try{let{displayBadgeInfo:l,promptAddBadge:u}=await Promise.resolve().then(()=>(Ke(),vt));l("component"),await u("component",process.cwd()),console.log(e.dim(`
174
+ \u{1F4CB} Full details available in result.violations`)}return u}async function rs(){await xt()}var ts,ut,os=I(()=>{"use strict";et();tt();ts=F(require("path"),1);ut=async()=>({passes:[],failures:[],skipped:[]});typeof window>"u"&&(ut=async()=>{console.log(`\u{1F680} Running component accessibility tests...
175
+ `);let{exec:c}=await import("child_process"),e=(await import("chalk")).default;return new Promise((t,r)=>{c("npx vitest --run --reporter verbose",async(s,o,n)=>{if(console.log(o),n&&console.error(n),!s||s.code===0){try{let{displayBadgeInfo:l,promptAddBadge:u}=await Promise.resolve().then(()=>(Ke(),St));l("component"),await u("component",process.cwd()),console.log(e.dim(`
176
176
  `+"\u2500".repeat(60))),console.log(e.cyan("\u{1F499} Found aria-ease helpful?")),console.log(e.white(" \u2022 Star us on GitHub: ")+e.blue.underline("https://github.com/aria-ease/aria-ease")),console.log(e.white(" \u2022 Share feedback: ")+e.blue.underline("https://github.com/aria-ease/aria-ease/discussions")),console.log(e.dim("\u2500".repeat(60)+`
177
- `))}catch(l){console.error("Warning: Could not display badge prompt:",l)}t({passes:[],failures:[],skipped:[]}),process.exit(0)}else{let l=s?.code||1;r(new Error(`Tests failed with code ${l}`)),process.exit(l)}})})})});var ts={};G(ts,{cleanupTests:()=>Zt,runTest:()=>lt,testUiComponent:()=>Xt});var ss=L(()=>{"use strict";es()});function rs(c){let e=[];if(!c||typeof c!="object")return{valid:!1,errors:[{path:"$",message:"Contract must be an object"}]};let t=c;if(!t.selectors)e.push({path:"$.selectors",message:"selectors is required"});else if(typeof t.selectors!="object"||t.selectors===null||Array.isArray(t.selectors))e.push({path:"$.selectors",message:"selectors must be an object"});else{let r=t.selectors;Object.entries(r).forEach(([s,i])=>{typeof i!="string"&&e.push({path:`$.selectors['${s}']`,message:"All selectors must be strings"})})}return Array.isArray(t.static)?t.static.forEach((r,s)=>{if(typeof r!="object"||r===null){e.push({path:`$.static[${s}]`,message:"static item must be an object"});return}let i=r;typeof i.target!="string"&&e.push({path:`$.static[${s}].target`,message:"target is required and must be a string"}),typeof i.attribute!="string"&&e.push({path:`$.static[${s}].attribute`,message:"attribute is required and must be a string"}),typeof i.failureMessage!="string"&&e.push({path:`$.static[${s}].failureMessage`,message:"failureMessage is required and must be a string"}),i.level!==void 0&&!["required","recommended","optional"].includes(i.level)&&e.push({path:`$.static[${s}].level`,message:"level must be one of: required, recommended, optional"})}):e.push({path:"$.static",message:"static must be an array"}),Array.isArray(t.dynamic)?t.dynamic.forEach((r,s)=>{if(typeof r!="object"||r===null){e.push({path:`$.dynamic[${s}]`,message:"dynamic item must be an object"});return}let i=r;typeof i.description!="string"&&e.push({path:`$.dynamic[${s}].description`,message:"description is required and must be a string"}),Array.isArray(i.action)?i.action.forEach((n,a)=>{if(typeof n!="object"||n===null){e.push({path:`$.dynamic[${s}].action[${a}]`,message:"action item must be an object"});return}let l=n;typeof l.type!="string"&&e.push({path:`$.dynamic[${s}].action[${a}].type`,message:"type is required and must be a string"}),typeof l.target!="string"&&e.push({path:`$.dynamic[${s}].action[${a}].target`,message:"target is required and must be a string"})}):e.push({path:`$.dynamic[${s}].action`,message:"action is required and must be an array"}),Array.isArray(i.assertions)?i.assertions.forEach((n,a)=>{if(typeof n!="object"||n===null){e.push({path:`$.dynamic[${s}].assertions[${a}]`,message:"assertion must be an object"});return}let l=n;typeof l.target!="string"&&e.push({path:`$.dynamic[${s}].assertions[${a}].target`,message:"target is required and must be a string"}),typeof l.assertion!="string"&&e.push({path:`$.dynamic[${s}].assertions[${a}].assertion`,message:"assertion is required and must be a string"}),l.level!==void 0&&!["required","recommended","optional"].includes(l.level)&&e.push({path:`$.dynamic[${s}].assertions[${a}].level`,message:"level must be one of: required, recommended, optional"})}):e.push({path:`$.dynamic[${s}].assertions`,message:"assertions is required and must be an array"})}):e.push({path:"$.dynamic",message:"dynamic must be an array"}),t.relationships!==void 0&&(Array.isArray(t.relationships)?t.relationships.forEach((r,s)=>{if(typeof r!="object"||r===null){e.push({path:`$.relationships[${s}]`,message:"relationship must be an object"});return}let i=r,n=i.type;["aria-reference","contains"].includes(n)||e.push({path:`$.relationships[${s}].type`,message:"type must be one of: aria-reference, contains"}),n==="aria-reference"?(typeof i.from!="string"&&e.push({path:`$.relationships[${s}].from`,message:"from is required for aria-reference and must be a string"}),typeof i.attribute!="string"&&e.push({path:`$.relationships[${s}].attribute`,message:"attribute is required for aria-reference and must be a string"}),typeof i.to!="string"&&e.push({path:`$.relationships[${s}].to`,message:"to is required for aria-reference and must be a string"})):n==="contains"&&(typeof i.parent!="string"&&e.push({path:`$.relationships[${s}].parent`,message:"parent is required for contains and must be a string"}),typeof i.child!="string"&&e.push({path:`$.relationships[${s}].child`,message:"child is required for contains and must be a string"}))}):e.push({path:"$.relationships",message:"relationships must be an array"})),{valid:e.length===0,errors:e}}function is(c,e){let t=[];if(!c||typeof c!="object")return t;let s=c.relationships;return Array.isArray(s)&&s.forEach((i,n)=>{let a=i.type;if(a==="aria-reference"){let l=i.from,u=i.to;l&&!e.has(l)&&t.push({path:`$.relationships[${n}].from`,message:`Selector '${l}' not found in selectors`}),u&&!e.has(u)&&t.push({path:`$.relationships[${n}].to`,message:`Selector '${u}' not found in selectors`})}else if(a==="contains"){let l=i.parent,u=i.child;l&&!e.has(l)&&t.push({path:`$.relationships[${n}].parent`,message:`Selector '${l}' not found in selectors`}),u&&!e.has(u)&&t.push({path:`$.relationships[${n}].child`,message:`Selector '${u}' not found in selectors`})}}),t}function os(c,e){let t=[];if(!c||typeof c!="object")return t;let r=c,s=r.static;Array.isArray(s)&&s.forEach((n,a)=>{let l=n.assertions;Array.isArray(l)&&l.forEach((u,f)=>{let h=u.target;h&&!e.has(h)&&t.push({path:`$.static[${a}].assertions[${f}].target`,message:`Selector '${h}' not found in selectors`})})});let i=r.dynamic;return Array.isArray(i)&&i.forEach((n,a)=>{let l=n.action;Array.isArray(l)&&l.forEach((f,h)=>{let y=f.target;y&&y!=="document"&&!e.has(y)&&t.push({path:`$.dynamic[${a}].action[${h}].target`,message:`Selector '${y}' not found in selectors (or use 'document')`})});let u=n.assertions;Array.isArray(u)&&u.forEach((f,h)=>{let y=f.target;y&&y!=="relative"&&!e.has(y)&&t.push({path:`$.dynamic[${a}].assertions[${h}].target`,message:`Selector '${y}' not found in selectors (or use 'relative')`})})}),t}var ns=L(()=>{"use strict"});var cs={};G(cs,{buildContracts:()=>Ps});async function Ps(c,e){let t=[],r=[];if(!e.contracts||e.contracts.length===0)return console.log(V.default.yellow('\u2139\uFE0F No contracts configured. Add "contracts" array to ariaease.config.js')),{success:!0,built:r,errors:t};try{console.log(V.default.cyanBright(`
177
+ `))}catch(l){console.error("Warning: Could not display badge prompt:",l)}t({passes:[],failures:[],skipped:[]}),process.exit(0)}else{let l=s?.code||1;r(new Error(`Tests failed with code ${l}`)),process.exit(l)}})})})});var is={};W(is,{cleanupTests:()=>rs,runTest:()=>ut,testUiComponent:()=>ss});var ns=I(()=>{"use strict";os()});function as(c){let e=[];if(!c||typeof c!="object")return{valid:!1,errors:[{path:"$",message:"Contract must be an object"}]};let t=c;if(!t.selectors)e.push({path:"$.selectors",message:"selectors is required"});else if(typeof t.selectors!="object"||t.selectors===null||Array.isArray(t.selectors))e.push({path:"$.selectors",message:"selectors must be an object"});else{let r=t.selectors;Object.entries(r).forEach(([s,o])=>{typeof o!="string"&&e.push({path:`$.selectors['${s}']`,message:"All selectors must be strings"})})}return Array.isArray(t.static)?t.static.forEach((r,s)=>{if(typeof r!="object"||r===null){e.push({path:`$.static[${s}]`,message:"static item must be an object"});return}let o=r;typeof o.target!="string"&&e.push({path:`$.static[${s}].target`,message:"target is required and must be a string"}),typeof o.attribute!="string"&&e.push({path:`$.static[${s}].attribute`,message:"attribute is required and must be a string"}),typeof o.failureMessage!="string"&&e.push({path:`$.static[${s}].failureMessage`,message:"failureMessage is required and must be a string"}),o.level!==void 0&&!["required","recommended","optional"].includes(o.level)&&e.push({path:`$.static[${s}].level`,message:"level must be one of: required, recommended, optional"})}):e.push({path:"$.static",message:"static must be an array"}),Array.isArray(t.dynamic)?t.dynamic.forEach((r,s)=>{if(typeof r!="object"||r===null){e.push({path:`$.dynamic[${s}]`,message:"dynamic item must be an object"});return}let o=r;typeof o.description!="string"&&e.push({path:`$.dynamic[${s}].description`,message:"description is required and must be a string"}),Array.isArray(o.action)?o.action.forEach((n,a)=>{if(typeof n!="object"||n===null){e.push({path:`$.dynamic[${s}].action[${a}]`,message:"action item must be an object"});return}let l=n;typeof l.type!="string"&&e.push({path:`$.dynamic[${s}].action[${a}].type`,message:"type is required and must be a string"}),typeof l.target!="string"&&e.push({path:`$.dynamic[${s}].action[${a}].target`,message:"target is required and must be a string"})}):e.push({path:`$.dynamic[${s}].action`,message:"action is required and must be an array"}),Array.isArray(o.assertions)?o.assertions.forEach((n,a)=>{if(typeof n!="object"||n===null){e.push({path:`$.dynamic[${s}].assertions[${a}]`,message:"assertion must be an object"});return}let l=n;typeof l.target!="string"&&e.push({path:`$.dynamic[${s}].assertions[${a}].target`,message:"target is required and must be a string"}),typeof l.assertion!="string"&&e.push({path:`$.dynamic[${s}].assertions[${a}].assertion`,message:"assertion is required and must be a string"}),l.level!==void 0&&!["required","recommended","optional"].includes(l.level)&&e.push({path:`$.dynamic[${s}].assertions[${a}].level`,message:"level must be one of: required, recommended, optional"})}):e.push({path:`$.dynamic[${s}].assertions`,message:"assertions is required and must be an array"})}):e.push({path:"$.dynamic",message:"dynamic must be an array"}),t.relationships!==void 0&&(Array.isArray(t.relationships)?t.relationships.forEach((r,s)=>{if(typeof r!="object"||r===null){e.push({path:`$.relationships[${s}]`,message:"relationship must be an object"});return}let o=r,n=o.type;["aria-reference","contains"].includes(n)||e.push({path:`$.relationships[${s}].type`,message:"type must be one of: aria-reference, contains"}),n==="aria-reference"?(typeof o.from!="string"&&e.push({path:`$.relationships[${s}].from`,message:"from is required for aria-reference and must be a string"}),typeof o.attribute!="string"&&e.push({path:`$.relationships[${s}].attribute`,message:"attribute is required for aria-reference and must be a string"}),typeof o.to!="string"&&e.push({path:`$.relationships[${s}].to`,message:"to is required for aria-reference and must be a string"})):n==="contains"&&(typeof o.parent!="string"&&e.push({path:`$.relationships[${s}].parent`,message:"parent is required for contains and must be a string"}),typeof o.child!="string"&&e.push({path:`$.relationships[${s}].child`,message:"child is required for contains and must be a string"}))}):e.push({path:"$.relationships",message:"relationships must be an array"})),{valid:e.length===0,errors:e}}function cs(c,e){let t=[];if(!c||typeof c!="object")return t;let s=c.relationships;return Array.isArray(s)&&s.forEach((o,n)=>{let a=o.type;if(a==="aria-reference"){let l=o.from,u=o.to;l&&!e.has(l)&&t.push({path:`$.relationships[${n}].from`,message:`Selector '${l}' not found in selectors`}),u&&!e.has(u)&&t.push({path:`$.relationships[${n}].to`,message:`Selector '${u}' not found in selectors`})}else if(a==="contains"){let l=o.parent,u=o.child;l&&!e.has(l)&&t.push({path:`$.relationships[${n}].parent`,message:`Selector '${l}' not found in selectors`}),u&&!e.has(u)&&t.push({path:`$.relationships[${n}].child`,message:`Selector '${u}' not found in selectors`})}}),t}function ls(c,e){let t=[];if(!c||typeof c!="object")return t;let r=c,s=r.static;Array.isArray(s)&&s.forEach((n,a)=>{let l=n.assertions;Array.isArray(l)&&l.forEach((u,p)=>{let h=u.target;h&&!e.has(h)&&t.push({path:`$.static[${a}].assertions[${p}].target`,message:`Selector '${h}' not found in selectors`})})});let o=r.dynamic;return Array.isArray(o)&&o.forEach((n,a)=>{let l=n.action;Array.isArray(l)&&l.forEach((p,h)=>{let y=p.target;y&&y!=="document"&&!e.has(y)&&t.push({path:`$.dynamic[${a}].action[${h}].target`,message:`Selector '${y}' not found in selectors (or use 'document')`})});let u=n.assertions;Array.isArray(u)&&u.forEach((p,h)=>{let y=p.target;y&&y!=="relative"&&!e.has(y)&&t.push({path:`$.dynamic[${a}].assertions[${h}].target`,message:`Selector '${y}' not found in selectors (or use 'relative')`})})}),t}var us=I(()=>{"use strict"});var fs={};W(fs,{buildContracts:()=>Vs});async function Vs(c,e){let t=[],r=[];if(!e.contracts||e.contracts.length===0)return console.log(V.default.yellow('\u2139\uFE0F No contracts configured. Add "contracts" array to ariaease.config.js')),{success:!0,built:r,errors:t};try{console.log(V.default.cyanBright(`
178
178
  \u{1F3D7}\uFE0F Building contracts...
179
- `));for(let s of e.contracts){let i=D.default.resolve(c,s.src),n=s.out?D.default.resolve(c,s.out):void 0;console.log(V.default.gray(` Pattern: ${s.src}`)),console.log(n?V.default.gray(` Output: ${s.out}
179
+ `));for(let s of e.contracts){let o=D.default.resolve(c,s.src),n=s.out?D.default.resolve(c,s.out):void 0;console.log(V.default.gray(` Pattern: ${s.src}`)),console.log(n?V.default.gray(` Output: ${s.out}
180
180
  `):V.default.gray(` Output: Same directory as source
181
- `));let a=[];for await(let l of(0,as.glob)(i,{cwd:c}))a.push(l);if(a.length===0){console.log(V.default.yellow(`\u26A0\uFE0F No contract files found matching pattern: ${s.src}`));continue}n&&await ut.default.ensureDir(n);for(let l of a)try{let u=l.startsWith("/")?l:D.default.resolve(c,l),f=await import(`file://${u}`),h=f.default;if(!h){let Y=Object.entries(f).find(([,K])=>K&&typeof K=="object"&&"toJSON"in K);Y&&(h=Y[1])}if(!h||typeof h.toJSON!="function"){t.push(`${D.default.basename(l)}: No contract with toJSON() method found`);continue}let y=h.toJSON(),j=rs(y);if(!j.valid){let K=`Schema validation failed:
182
- ${j.errors.map(v=>` ${V.default.red("\u2717")} ${v.path}: ${v.message}`).join(`
183
- `)}`;t.push(`${D.default.basename(l)}: ${K}`),console.log(V.default.red(`\u274C ${D.default.basename(l)}`)),console.log(V.default.red(` ${K}`));continue}let H=new Set;if(y&&typeof y=="object"&&"selectors"in y){let Y=y.selectors;Object.keys(Y).forEach(K=>H.add(K))}let M=[...is(y,H),...os(y,H)];if(M.length>0){let K=`Reference validation failed:
184
- ${M.map(v=>` ${V.default.red("\u2717")} ${v.path}: ${v.message}`).join(`
185
- `)}`;t.push(`${D.default.basename(l)}: ${K}`),console.log(V.default.red(`\u274C ${D.default.basename(l)}`)),console.log(V.default.red(` ${K}`));continue}let U=D.default.basename(l,D.default.extname(l)),W=n?D.default.join(n,`${U}.json`):D.default.join(D.default.dirname(u),`${U}.json`);await ut.default.writeFile(W,JSON.stringify(y,null,2)+`
186
- `,"utf-8");let J=D.default.relative(c,W);r.push(J),console.log(V.default.green(`\u2705 ${D.default.basename(l)} \u2192 ${D.default.basename(W)}`))}catch(u){let f=u instanceof Error?u.message:String(u),h=D.default.basename(l);t.push(`${h}: ${f}`),console.log(V.default.red(`\u274C ${h}`)),console.log(V.default.red(` Error: ${f}`))}}return console.log(""),t.length===0?(console.log(V.default.green(`\u2705 Built ${r.length} contract${r.length!==1?"s":""} successfully
181
+ `));let a=[];for await(let l of(0,ps.glob)(o,{cwd:c}))a.push(l);if(a.length===0){console.log(V.default.yellow(`\u26A0\uFE0F No contract files found matching pattern: ${s.src}`));continue}n&&await pt.default.ensureDir(n);for(let l of a)try{let u=l.startsWith("/")?l:D.default.resolve(c,l),p=await import(`file://${u}`),h=p.default;if(!h){let K=Object.entries(p).find(([,Q])=>Q&&typeof Q=="object"&&"toJSON"in Q);K&&(h=K[1])}if(!h||typeof h.toJSON!="function"){t.push(`${D.default.basename(l)}: No contract with toJSON() method found`);continue}let y=h.toJSON(),L=as(y);if(!L.valid){let Q=`Schema validation failed:
182
+ ${L.errors.map($=>` ${V.default.red("\u2717")} ${$.path}: ${$.message}`).join(`
183
+ `)}`;t.push(`${D.default.basename(l)}: ${Q}`),console.log(V.default.red(`\u274C ${D.default.basename(l)}`)),console.log(V.default.red(` ${Q}`));continue}let q=new Set;if(y&&typeof y=="object"&&"selectors"in y){let K=y.selectors;Object.keys(K).forEach(Q=>q.add(Q))}let x=[...cs(y,q),...ls(y,q)];if(x.length>0){let Q=`Reference validation failed:
184
+ ${x.map($=>` ${V.default.red("\u2717")} ${$.path}: ${$.message}`).join(`
185
+ `)}`;t.push(`${D.default.basename(l)}: ${Q}`),console.log(V.default.red(`\u274C ${D.default.basename(l)}`)),console.log(V.default.red(` ${Q}`));continue}let U=D.default.basename(l,D.default.extname(l)),J=n?D.default.join(n,`${U}.json`):D.default.join(D.default.dirname(u),`${U}.json`);await pt.default.writeFile(J,JSON.stringify(y,null,2)+`
186
+ `,"utf-8");let _=D.default.relative(c,J);r.push(_),console.log(V.default.green(`\u2705 ${D.default.basename(l)} \u2192 ${D.default.basename(J)}`))}catch(u){let p=u instanceof Error?u.message:String(u),h=D.default.basename(l);t.push(`${h}: ${p}`),console.log(V.default.red(`\u274C ${h}`)),console.log(V.default.red(` Error: ${p}`))}}return console.log(""),t.length===0?(console.log(V.default.green(`\u2705 Built ${r.length} contract${r.length!==1?"s":""} successfully
187
187
  `)),{success:!0,built:r,errors:t}):(console.log(V.default.yellow(`\u26A0\uFE0F Built ${r.length} contracts with ${t.length} error${t.length!==1?"s":""}
188
188
  `)),{success:!1,built:r,errors:t})}catch(s){let n=`Failed to build contracts: ${s instanceof Error?s.message:String(s)}`;return t.push(n),console.log(V.default.red(`\u274C ${n}
189
- `)),{success:!1,built:r,errors:t}}}var D,ut,as,V,ls=L(()=>{"use strict";D=F(require("path"),1),ut=F(require("fs-extra"),1),as=require("fs/promises"),V=F(require("chalk"),1);ns()});var ft=require("commander"),$=F(require("chalk"),1),Ve=F(require("path"),1),pt=F(require("fs-extra"),1);Re();Ke();var ge=new ft.Command;ge.name("aria-ease").description("Run accessibility tests and audits").version("2.2.3");ge.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 c=>{console.log($.default.cyanBright(`\u{1F680} Starting accessibility audit...
190
- `));let{runAudit:e}=await Promise.resolve().then(()=>(Ze(),Xe)),{formatResults:t}=await Promise.resolve().then(()=>(Ct(),Tt)),r=!c.url,{config:s,configPath:i,errors:n}=await Je(process.cwd());i?console.log($.default.green(`\u2705 Loaded config from ${Ve.default.basename(i)}
191
- `)):n.length>0&&r?(console.log($.default.red(`\u274C Config file errors:
192
- `)),n.forEach(M=>console.log($.default.red(` ${M}`))),console.log(""),process.exit(1)):n.length>0?console.log($.default.yellow(`\u26A0\uFE0F Config file has errors (ignored, using CLI options)
193
- `)):!i&&r&&console.log($.default.yellow(`\u2139\uFE0F No config file found, using CLI options.
194
- `));let a=[];c.url?a.push(c.url):s.audit?.urls&&Array.isArray(s.audit.urls)&&a.push(...s.audit.urls);let l=s.audit?.output&&s.audit.output.format||c.format;["json","csv","html","all"].includes(l)||(console.log($.default.red('\u274C Invalid format. Use "json", "csv", "html" or "all".')),process.exit(1)),a.length===0&&(console.log($.default.red('\u274C No URLs provided. Use --url option or add "urls" in config file')),process.exit(1));let u=[],{createAuditBrowser:f}=await Promise.resolve().then(()=>(Ze(),Xe)),h=await f();try{let M={browser:h};for(let U of a){console.log($.default.yellow(`\u{1F50E} Auditing: ${U}`));try{let W=await e(U,M);u.push({url:U,result:W}),console.log($.default.green(`\u2705 Completed audit for ${U}
195
- `))}catch(W){W instanceof Error&&W.message&&console.log($.default.red(`\u274C Failed auditing ${U}: ${W.message}`))}}}finally{await h.close()}if(!u.some(M=>M.result&&M.result.violations&&M.result.violations.length>0)){let M=u.filter(U=>U.result).length;M===0&&(console.log($.default.red("\u274C No pages were successfully audited.")),process.exit(1)),console.log($.default.green(`
196
- \u{1F389} Great news! No static accessibility violations found!`)),console.log($.default.gray(` Audited ${M} page${M>1?"s":""} successfully.
197
- `)),Ge("audit"),await Ye("audit",process.cwd()),console.log($.default.dim(`
198
- `+"\u2500".repeat(60))),console.log($.default.cyan("\u{1F499} Found aria-ease helpful?")),console.log($.default.white(" \u2022 Star us on GitHub: ")+$.default.blue.underline("https://github.com/aria-ease/aria-ease")),console.log($.default.white(" \u2022 Share feedback: ")+$.default.blue.underline("https://github.com/aria-ease/aria-ease/discussions")),console.log($.default.dim("\u2500".repeat(60)+`
199
- `)),process.exit(0)}async function j(M){let U=t(u,M),W=s.audit?.output&&s.audit.output.out||c.out;await pt.default.ensureDir(W);let J=new Date,Y=Ue=>String(Ue).padStart(2,"0"),v=`ariaease-report-${`${Y(J.getDate())}-${Y(J.getMonth()+1)}-${J.getFullYear()} ${Y(J.getHours())}h ${Y(J.getMinutes())}m ${Y(J.getSeconds())}s`}.${M}`,Ce=Ve.default.join(W,v);await pt.default.writeFile(Ce,U,"utf-8"),console.log($.default.magentaBright(`\u{1F4C1} Report saved to ${Ce}`))}["json","csv","html"].includes(l)?await j(l):l==="all"&&await Promise.all(["json","csv","html"].map(M=>j(M)));let H=u.reduce((M,U)=>M+(U.result?.violations?.length||0),0);console.log($.default.red(`
200
- \u274C Accessibility violations found!`)),console.log($.default.yellow(` ${H} violation${H!==1?"s":""} detected across ${u.length} page${u.length!==1?"s":""}.`)),console.log($.default.gray(` Review the generated report for details.
201
- `)),console.log($.default.dim(`
202
- `+"\u2500".repeat(60))),console.log($.default.cyan("\u{1F499} Found aria-ease helpful?")),console.log($.default.white(" \u2022 Star us on GitHub: ")+$.default.blue.underline("https://github.com/aria-ease/aria-ease")),console.log($.default.white(" \u2022 Share feedback: ")+$.default.blue.underline("https://github.com/aria-ease/aria-ease/discussions")),console.log($.default.dim("\u2500".repeat(60)+`
203
- `)),process.exit(1)});ge.command("test").description("Run core a11y accessibility standard tests on UI components").action(async()=>{let{runTest:c}=await Promise.resolve().then(()=>(ss(),ts));c()});ge.command("build").description("Build accessibility artifacts").addCommand(new ft.Command("contracts").description("Build DSL contracts to JSON").action(async()=>{let{buildContracts:c}=await Promise.resolve().then(()=>(ls(),cs)),{loadConfig:e}=await Promise.resolve().then(()=>(Re(),_e)),t=process.cwd(),{config:r,configPath:s,errors:i}=await e(t);s?console.log($.default.green(`\u2705 Loaded config from ${Ve.default.basename(s)}
204
- `)):i.length>0&&(console.log($.default.red(`\u274C Config file has errors:
205
- `)),i.forEach(a=>console.log($.default.red(` ${a}`))),console.log(""),process.exit(1));let n=await c(t,r);!n.success&&n.errors.length>0&&(console.log($.default.red(`\u274C ${n.errors.length} error${n.errors.length!==1?"s":""} occurred during build
206
- `)),process.exit(1)),n.built.length===0&&(!r.contracts||r.contracts.length===0)&&process.exit(0),n.built.length===0&&(console.log($.default.yellow(`\u26A0\uFE0F No contracts were built
189
+ `)),{success:!1,built:r,errors:t}}}var D,pt,ps,V,gs=I(()=>{"use strict";D=F(require("path"),1),pt=F(require("fs-extra"),1),ps=require("fs/promises"),V=F(require("chalk"),1);us()});var gt=require("commander"),S=F(require("chalk"),1),Fe=F(require("path"),1),ft=F(require("fs-extra"),1);Ae();Ke();var ge=new gt.Command;ge.name("aria-ease").description("Run accessibility tests and audits").version("2.2.3");ge.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 c=>{console.log(S.default.cyanBright(`\u{1F680} Starting accessibility audit...
190
+ `));let{runAudit:e}=await Promise.resolve().then(()=>(Ze(),Xe)),{formatResults:t}=await Promise.resolve().then(()=>(At(),kt)),r=!c.url,{config:s,configPath:o,errors:n}=await Je(process.cwd());o?console.log(S.default.green(`\u2705 Loaded config from ${Fe.default.basename(o)}
191
+ `)):n.length>0&&r?(console.log(S.default.red(`\u274C Config file errors:
192
+ `)),n.forEach(x=>console.log(S.default.red(` ${x}`))),console.log(""),process.exit(1)):n.length>0?console.log(S.default.yellow(`\u26A0\uFE0F Config file has errors (ignored, using CLI options)
193
+ `)):!o&&r&&console.log(S.default.yellow(`\u2139\uFE0F No config file found, using CLI options.
194
+ `));let a=[];c.url?a.push(c.url):s.audit?.urls&&Array.isArray(s.audit.urls)&&a.push(...s.audit.urls);let l=s.audit?.output&&s.audit.output.format||c.format;["json","csv","html","all"].includes(l)||(console.log(S.default.red('\u274C Invalid format. Use "json", "csv", "html" or "all".')),process.exit(1)),a.length===0&&(console.log(S.default.red('\u274C No URLs provided. Use --url option or add "urls" in config file')),process.exit(1));let u=[],{createAuditBrowser:p}=await Promise.resolve().then(()=>(Ze(),Xe)),h=await p();try{let x={browser:h};for(let U of a){console.log(S.default.yellow(`\u{1F50E} Auditing: ${U}`));try{let J=await e(U,x);u.push({url:U,result:J}),console.log(S.default.green(`\u2705 Completed audit for ${U}
195
+ `))}catch(J){J instanceof Error&&J.message&&console.log(S.default.red(`\u274C Failed auditing ${U}: ${J.message}`))}}}finally{await h.close()}if(!u.some(x=>x.result&&x.result.violations&&x.result.violations.length>0)){let x=u.filter(U=>U.result).length;x===0&&(console.log(S.default.red("\u274C No pages were successfully audited.")),process.exit(1)),console.log(S.default.green(`
196
+ \u{1F389} Great news! No static accessibility violations found!`)),console.log(S.default.gray(` Audited ${x} page${x>1?"s":""} successfully.
197
+ `)),Ge("audit"),await Ye("audit",process.cwd()),console.log(S.default.dim(`
198
+ `+"\u2500".repeat(60))),console.log(S.default.cyan("\u{1F499} Found aria-ease helpful?")),console.log(S.default.white(" \u2022 Star us on GitHub: ")+S.default.blue.underline("https://github.com/aria-ease/aria-ease")),console.log(S.default.white(" \u2022 Share feedback: ")+S.default.blue.underline("https://github.com/aria-ease/aria-ease/discussions")),console.log(S.default.dim("\u2500".repeat(60)+`
199
+ `)),process.exit(0)}async function L(x){let U=t(u,x),J=s.audit?.output&&s.audit.output.out||c.out;await ft.default.ensureDir(J);let _=new Date,K=Ve=>String(Ve).padStart(2,"0"),$=`ariaease-report-${`${K(_.getDate())}-${K(_.getMonth()+1)}-${_.getFullYear()} ${K(_.getHours())}h ${K(_.getMinutes())}m ${K(_.getSeconds())}s`}.${x}`,Te=Fe.default.join(J,$);await ft.default.writeFile(Te,U,"utf-8"),console.log(S.default.magentaBright(`\u{1F4C1} Report saved to ${Te}`))}["json","csv","html"].includes(l)?await L(l):l==="all"&&await Promise.all(["json","csv","html"].map(x=>L(x)));let q=u.reduce((x,U)=>x+(U.result?.violations?.length||0),0);console.log(S.default.red(`
200
+ \u274C Accessibility violations found!`)),console.log(S.default.yellow(` ${q} violation${q!==1?"s":""} detected across ${u.length} page${u.length!==1?"s":""}.`)),console.log(S.default.gray(` Review the generated report for details.
201
+ `)),console.log(S.default.dim(`
202
+ `+"\u2500".repeat(60))),console.log(S.default.cyan("\u{1F499} Found aria-ease helpful?")),console.log(S.default.white(" \u2022 Star us on GitHub: ")+S.default.blue.underline("https://github.com/aria-ease/aria-ease")),console.log(S.default.white(" \u2022 Share feedback: ")+S.default.blue.underline("https://github.com/aria-ease/aria-ease/discussions")),console.log(S.default.dim("\u2500".repeat(60)+`
203
+ `)),process.exit(1)});ge.command("test").description("Run core a11y accessibility standard tests on UI components").action(async()=>{let{runTest:c}=await Promise.resolve().then(()=>(ns(),is));c()});ge.command("build").description("Build accessibility artifacts").addCommand(new gt.Command("contracts").description("Build DSL contracts to JSON").action(async()=>{let{buildContracts:c}=await Promise.resolve().then(()=>(gs(),fs)),{loadConfig:e}=await Promise.resolve().then(()=>(Ae(),_e)),t=process.cwd(),{config:r,configPath:s,errors:o}=await e(t);s?console.log(S.default.green(`\u2705 Loaded config from ${Fe.default.basename(s)}
204
+ `)):o.length>0&&(console.log(S.default.red(`\u274C Config file has errors:
205
+ `)),o.forEach(a=>console.log(S.default.red(` ${a}`))),console.log(""),process.exit(1));let n=await c(t,r);!n.success&&n.errors.length>0&&(console.log(S.default.red(`\u274C ${n.errors.length} error${n.errors.length!==1?"s":""} occurred during build
206
+ `)),process.exit(1)),n.built.length===0&&(!r.contracts||r.contracts.length===0)&&process.exit(0),n.built.length===0&&(console.log(S.default.yellow(`\u26A0\uFE0F No contracts were built
207
207
  `)),process.exit(1)),process.exit(0)}));ge.command("help").description("Display help information").action(()=>{ge.outputHelp()});ge.parse(process.argv);