aria-ease 7.8.1 → 7.8.2

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 (60) hide show
  1. package/README.md +3 -3
  2. package/dist/AccordionComponentStrategy-PGBPZ5AV.js +1 -0
  3. package/dist/CheckboxComponentStrategy-C4AE24NT.js +1 -0
  4. package/dist/ComboboxComponentStrategy-AAYXTWW2.js +5 -0
  5. package/dist/MenuComponentStrategy-XPVKRFYX.js +5 -0
  6. package/dist/RadioComponentStrategy-ATVI5I3L.js +1 -0
  7. package/dist/ToggleComponentStrategy-H737DAFU.js +1 -0
  8. package/dist/cli.cjs +32 -32
  9. package/dist/cli.js +1 -1
  10. package/dist/{contractTestRunnerPlaywright-CHCVW7VO.js → contractTestRunnerPlaywright-2KC3RAV5.js} +2 -2
  11. package/dist/{contractTestRunnerPlaywright-FECB4HSX.js → contractTestRunnerPlaywright-OZOFEW66.js} +2 -2
  12. package/dist/index.cjs +8 -8
  13. package/dist/index.d.cts +2 -2
  14. package/dist/index.d.ts +2 -2
  15. package/dist/index.js +1 -1
  16. package/dist/src/{Types.d-BjBTlIzl.d.cts → Types.d-DO31Kt2y.d.cts} +2 -2
  17. package/dist/src/{Types.d-BjBTlIzl.d.ts → Types.d-DO31Kt2y.d.ts} +2 -2
  18. package/dist/src/accordion/index.d.cts +1 -1
  19. package/dist/src/accordion/index.d.ts +1 -1
  20. package/dist/src/block/index.d.cts +1 -1
  21. package/dist/src/block/index.d.ts +1 -1
  22. package/dist/src/checkbox/index.d.cts +1 -1
  23. package/dist/src/checkbox/index.d.ts +1 -1
  24. package/dist/src/combobox/index.cjs +1 -1
  25. package/dist/src/combobox/index.d.cts +1 -1
  26. package/dist/src/combobox/index.d.ts +1 -1
  27. package/dist/src/combobox/index.js +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/radio/index.d.cts +1 -1
  31. package/dist/src/radio/index.d.ts +1 -1
  32. package/dist/src/tabs/index.d.cts +1 -1
  33. package/dist/src/tabs/index.d.ts +1 -1
  34. package/dist/src/toggle/index.d.cts +1 -1
  35. package/dist/src/toggle/index.d.ts +1 -1
  36. package/dist/src/utils/test/AccordionComponentStrategy-3GGMDTRW.js +1 -0
  37. package/dist/src/utils/test/CheckboxComponentStrategy-VVOJGXVS.js +1 -0
  38. package/dist/src/utils/test/ComboboxComponentStrategy-27RZ5MBQ.js +5 -0
  39. package/dist/src/utils/test/MenuComponentStrategy-C7WC6OXZ.js +5 -0
  40. package/dist/src/utils/test/RadioComponentStrategy-4KONDPM2.js +1 -0
  41. package/dist/src/utils/test/ToggleComponentStrategy-DKEYKK47.js +1 -0
  42. package/dist/src/utils/test/{contractTestRunnerPlaywright-7ERFIHCM.js → contractTestRunnerPlaywright-GM4W4SKJ.js} +2 -2
  43. package/dist/src/utils/test/dsl/index.cjs +1 -1
  44. package/dist/src/utils/test/dsl/index.js +1 -1
  45. package/dist/src/utils/test/index.cjs +4 -4
  46. package/dist/src/utils/test/index.js +1 -1
  47. package/dist/{test-CMD6E5YF.js → test-6TU4J43V.js} +1 -1
  48. package/package.json +1 -1
  49. package/dist/AccordionComponentStrategy-T5YODP3A.js +0 -1
  50. package/dist/CheckboxComponentStrategy-AZF2Y4MN.js +0 -1
  51. package/dist/ComboboxComponentStrategy-DHZS4NW6.js +0 -5
  52. package/dist/MenuComponentStrategy-L3QXLC6S.js +0 -5
  53. package/dist/RadioComponentStrategy-GKA5KOM5.js +0 -1
  54. package/dist/ToggleComponentStrategy-TMRNXFSL.js +0 -1
  55. package/dist/src/utils/test/AccordionComponentStrategy-S35ZYITU.js +0 -1
  56. package/dist/src/utils/test/CheckboxComponentStrategy-ST2DWNYT.js +0 -1
  57. package/dist/src/utils/test/ComboboxComponentStrategy-5AWO63DA.js +0 -5
  58. package/dist/src/utils/test/MenuComponentStrategy-QHVBLUBR.js +0 -5
  59. package/dist/src/utils/test/RadioComponentStrategy-TWMIMSYX.js +0 -1
  60. package/dist/src/utils/test/ToggleComponentStrategy-UOGYK2U4.js +0 -1
@@ -1,4 +1,4 @@
1
- import {a as a$1}from'./chunk-WIWSYIGK.js';import {d,a,c,e}from'./chunk-APUMBDOT.js';import {readFileSync}from'fs';import ge from'path';import {pathToFileURL}from'url';import {expect}from'@playwright/test';var ie=class{builtInStrategies=new Map;constructor(){this.registerBuiltInStrategies();}registerBuiltInStrategies(){this.builtInStrategies.set("menu",()=>import('./MenuComponentStrategy-QHVBLUBR.js').then(t=>t.MenuComponentStrategy)),this.builtInStrategies.set("accordion",()=>import('./AccordionComponentStrategy-S35ZYITU.js').then(t=>t.AccordionComponentStrategy)),this.builtInStrategies.set("combobox",()=>import('./ComboboxComponentStrategy-5AWO63DA.js').then(t=>t.ComboboxComponentStrategy)),this.builtInStrategies.set("tabs",()=>import('./TabsComponentStrategy-DTQQUCK2.js').then(t=>t.TabsComponentStrategy)),this.builtInStrategies.set("radio",()=>import('./RadioComponentStrategy-TWMIMSYX.js').then(t=>t.RadioComponentStrategy)),this.builtInStrategies.set("checkbox",()=>import('./CheckboxComponentStrategy-ST2DWNYT.js').then(t=>t.CheckboxComponentStrategy)),this.builtInStrategies.set("toggle",()=>import('./ToggleComponentStrategy-UOGYK2U4.js').then(t=>t.ToggleComponentStrategy));}async loadStrategy(t,s,r){try{if(s)try{let n=ge.isAbsolute(s)?s:ge.resolve(r||process.cwd(),s),l=await import(pathToFileURL(n).href),i=l.default||l;if(!i)throw new Error(`No default export found in ${s}`);return i}catch(n){throw new Error(`Failed to load custom strategy from ${s}: ${n instanceof Error?n.message:String(n)}`)}let o=this.builtInStrategies.get(t);return o?o():null}catch(o){throw new Error(`Strategy loading failed for ${t}: ${o instanceof Error?o.message:String(o)}`)}}has(t,s){return !!s||this.builtInStrategies.has(t)}};var ne=class{static strategyRegistry=new ie;static isComponentConfig(t){return typeof t=="object"&&t!==null}static async detect(t,s,r=400,o=400,n){let l=this.isComponentConfig(s)?s:void 0,i=l?.contractPath;if(!i)throw new Error(`Contract path not found for component: ${t}`);let C=(()=>{if(ge.isAbsolute(i))return i;if(n){let se=ge.resolve(n,i);try{return readFileSync(se,"utf-8"),se}catch{}}let Q=ge.resolve(process.cwd(),i);try{return readFileSync(Q,"utf-8"),Q}catch{return new URL(i,import.meta.url).pathname}})(),k=readFileSync(C,"utf-8"),ee=JSON.parse(k).selectors,K=await this.strategyRegistry.loadStrategy(t,l?.strategyPath,n);if(!K)return null;let z=ee.main;return t==="tabs"?new K(z,ee):new K(z,ee,r,o)}};var oe=class{startTime=0;componentName="";staticPasses=0;staticFailures=0;staticWarnings=0;dynamicResults=[];totalTests=0;skipped=0;warnings=0;isPlaywright=false;isCustomContract=false;apgUrl="https://www.w3.org/WAI/ARIA/apg/";hasPrintedStaticSection=false;hasPrintedDynamicSection=false;constructor(t=false,s=false){this.isPlaywright=t,this.isCustomContract=s;}log(t){process.stderr.write(t+`
1
+ import {a as a$1}from'./chunk-WIWSYIGK.js';import {d,a,c,e}from'./chunk-APUMBDOT.js';import {readFileSync}from'fs';import ge from'path';import {pathToFileURL}from'url';import {expect}from'@playwright/test';var ie=class{builtInStrategies=new Map;constructor(){this.registerBuiltInStrategies();}registerBuiltInStrategies(){this.builtInStrategies.set("menu",()=>import('./MenuComponentStrategy-C7WC6OXZ.js').then(t=>t.MenuComponentStrategy)),this.builtInStrategies.set("accordion",()=>import('./AccordionComponentStrategy-3GGMDTRW.js').then(t=>t.AccordionComponentStrategy)),this.builtInStrategies.set("combobox",()=>import('./ComboboxComponentStrategy-27RZ5MBQ.js').then(t=>t.ComboboxComponentStrategy)),this.builtInStrategies.set("tabs",()=>import('./TabsComponentStrategy-DTQQUCK2.js').then(t=>t.TabsComponentStrategy)),this.builtInStrategies.set("radio",()=>import('./RadioComponentStrategy-4KONDPM2.js').then(t=>t.RadioComponentStrategy)),this.builtInStrategies.set("checkbox",()=>import('./CheckboxComponentStrategy-VVOJGXVS.js').then(t=>t.CheckboxComponentStrategy)),this.builtInStrategies.set("toggle",()=>import('./ToggleComponentStrategy-DKEYKK47.js').then(t=>t.ToggleComponentStrategy));}async loadStrategy(t,s,r){try{if(s)try{let n=ge.isAbsolute(s)?s:ge.resolve(r||process.cwd(),s),l=await import(pathToFileURL(n).href),i=l.default||l;if(!i)throw new Error(`No default export found in ${s}`);return i}catch(n){throw new Error(`Failed to load custom strategy from ${s}: ${n instanceof Error?n.message:String(n)}`)}let o=this.builtInStrategies.get(t);return o?o():null}catch(o){throw new Error(`Strategy loading failed for ${t}: ${o instanceof Error?o.message:String(o)}`)}}has(t,s){return !!s||this.builtInStrategies.has(t)}};var ne=class{static strategyRegistry=new ie;static isComponentConfig(t){return typeof t=="object"&&t!==null}static async detect(t,s,r,o,n){let l=this.isComponentConfig(o)?o:void 0,i=l?.contractPath;if(!i)throw new Error(`Contract path not found for component: ${t}`);let C=(()=>{if(ge.isAbsolute(i))return i;if(n){let se=ge.resolve(n,i);try{return readFileSync(se,"utf-8"),se}catch{}}let Q=ge.resolve(process.cwd(),i);try{return readFileSync(Q,"utf-8"),Q}catch{return new URL(i,import.meta.url).pathname}})(),k=readFileSync(C,"utf-8"),ee=JSON.parse(k).selectors,K=await this.strategyRegistry.loadStrategy(t,l?.strategyPath,n);if(!K)return null;let z=ee.main;return t==="tabs"?new K(z,ee):new K(z,ee,s,r)}};var oe=class{startTime=0;componentName="";staticPasses=0;staticFailures=0;staticWarnings=0;dynamicResults=[];totalTests=0;skipped=0;warnings=0;isPlaywright=false;isCustomContract=false;apgUrl="https://www.w3.org/WAI/ARIA/apg/";hasPrintedStaticSection=false;hasPrintedDynamicSection=false;constructor(t=false,s=false){this.isPlaywright=t,this.isCustomContract=s;}log(t){process.stderr.write(t+`
2
2
  `);}start(t,s,r){this.startTime=Date.now(),this.componentName=t,this.totalTests=s,this.hasPrintedStaticSection=false,this.hasPrintedDynamicSection=false,r&&(this.apgUrl=r);let o="Playwright (Real Browser)";this.log(`
3
3
  ${"\u2550".repeat(60)}`),this.log(`\u{1F50D} Testing ${t.charAt(0).toUpperCase()+t.slice(1)} Component - ${o}`),this.log(`${"\u2550".repeat(60)}
4
4
  `);}reportStatic(t,s,r=0){this.staticPasses=t,this.staticFailures=s,this.staticWarnings=r;}reportStaticTest(t,s,r,o){this.hasPrintedStaticSection||(this.log(`${"\u2500".repeat(60)}`),this.log("\u{1F9EA} Static Assertions"),this.log(`${"\u2500".repeat(60)}`),this.hasPrintedStaticSection=true);let n=s==="pass"?"\u2713":s==="warn"?"\u26A0":s==="skip"?"\u25CB":"\u2717";this.log(` ${n} ${t}`),o&&this.log(` \u21B3 level=${o}`),(s==="fail"||s==="warn"||s==="skip")&&r&&this.log(` \u21B3 ${r}`);}reportTest(t,s,r){this.hasPrintedDynamicSection||(this.log(""),this.log(`${"\u2500".repeat(60)}`),this.log("\u2328\uFE0F Dynamic Interaction Tests"),this.log(`${"\u2500".repeat(60)}`),this.hasPrintedDynamicSection=true);let o={description:t.description,status:s,failureMessage:r,level:t.level};s==="skip"&&(o.skipReason="Requires real browser (addEventListener events)"),this.dynamicResults.push(o);let n={pass:"\u2713",fail:"\u2717",warn:"\u26A0",skip:"\u25CB"},l=t.level?`[${t.level.toUpperCase()}] `:"";this.log(` ${n[s]} ${l}${t.description}`),s==="skip"&&!this.isPlaywright&&this.log(" \u21B3 Skipped (runs only in Playwright)"),s==="fail"&&r&&this.log(` \u21B3 ${r}`),s==="warn"&&r&&this.log(` \u21B3 ${r}`),s==="skip"&&r&&this.log(` \u21B3 ${r}`);}reportFailures(t){t.length!==0&&(this.log(`
@@ -19,7 +19,7 @@ ${"\u2550".repeat(60)}`),this.log(`\u{1F4CA} Summary
19
19
  `),i>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
20
20
  `)):!this.isPlaywright&&this.skipped>0&&this.log(`\u2728 Optional: Run Playwright tests for complete validation
21
21
  `),{passes:l,failures:i,skipped:this.skipped,duration:s}}error(t,s){this.log(`
22
- \u274C Error: ${t}`),s&&this.log(` Context: ${s}`),this.log("");}};var N=class{constructor(t,s,r=400){this.page=t;this.selectors=s;this.timeoutMs=r;}isBrowserClosedError(t){return t instanceof Error&&t.message.includes("Target page, context or browser has been closed")}async focus(t,s,r){try{if(t==="virtual"&&r){let n=this.selectors.main;if(!n)return {success:!1,error:"Main selector not defined for virtual focus."};let l=this.page.locator(n).first();return await l.count()?(await l.evaluate((C,k)=>{C.setAttribute("aria-activedescendant",k);},r),{success:!0}):{success:!1,error:"Main element not found for virtual focus."}}if(t==="relative"&&s){let n=this.selectors.relative;if(!n)return {success:!1,error:"Relative selector not defined for focus action."};let l=await a$1.resolve(this.page,n,s);return l?(await l.focus({timeout:this.timeoutMs}),{success:!0}):{success:!1,error:`Could not resolve relative target ${s} for focus.`}}let o=this.selectors[t];return o?(await this.page.locator(o).first().focus({timeout:this.timeoutMs}),{success:!0}):{success:!1,error:`Selector for focus target ${t} not found.`}}catch(o){return this.isBrowserClosedError(o)?{success:false,error:"CRITICAL: Browser/page closed during test execution. Remaining actions skipped.",shouldBreak:true}:{success:false,error:`Failed to focus ${t}: ${o instanceof Error?o.message:String(o)}`}}}async type(t,s){try{let r=this.selectors[t];return r?(await this.page.locator(r).first().fill(s,{timeout:this.timeoutMs}),{success:!0}):{success:!1,error:`Selector for type target ${t} not found.`}}catch(r){return this.isBrowserClosedError(r)?{success:false,error:"CRITICAL: Browser/page closed during test execution. Remaining actions skipped.",shouldBreak:true}:{success:false,error:`Failed to type into ${t}: ${r instanceof Error?r.message:String(r)}`}}}async click(t,s){try{if(t==="document")return await this.page.mouse.click(10,10),{success:!0};if(t==="relative"&&s){let o=this.selectors.relative;if(!o)return {success:!1,error:"Relative selector not defined for click action."};let n=await a$1.resolve(this.page,o,s);return n?(await n.click({timeout:this.timeoutMs}),{success:!0}):{success:!1,error:`Could not resolve relative target ${s} for click.`}}let r=this.selectors[t];return r?(await this.page.locator(r).first().click({timeout:this.timeoutMs}),{success:!0}):{success:!1,error:`Selector for action target ${t} not found.`}}catch(r){return this.isBrowserClosedError(r)?{success:false,error:"CRITICAL: Browser/page closed during test execution. Remaining actions skipped.",shouldBreak:true}:{success:false,error:`Failed to click ${t}: ${r instanceof Error?r.message:String(r)}`}}}async keypress(t,s,r){try{let n={Space:"Space",Enter:"Enter",Escape:"Escape","Arrow Up":"ArrowUp","Arrow Down":"ArrowDown","Arrow Left":"ArrowLeft","Arrow Right":"ArrowRight",Home:"Home",End:"End",Tab:"Tab"}[s]||s;if(n==="Space"?n=" ":n.includes(" ")&&(n=n.replace(/ /g,"")),t==="relative"){if(r==null)return {success:!1,error:"relativeTarget must be provided for relative keypress."};let k=this.selectors.relative;if(!k)return {success:!1,error:"Relative selector not defined for keypress action."};let A=await a$1.resolve(this.page,k,r);return A?(await A.press(n,{timeout:this.timeoutMs}),{success:!0}):{success:!1,error:`Could not resolve relative target ${r} for keypress.`}}let l=this.selectors[t];if(!l)return {success:!1,error:`Selector for keypress target ${t} not found.`};let i=this.page.locator(l).first();return await i.count()===0?{success:!1,error:`${t} element not found.`,shouldBreak:!0}:(await i.press(n,{timeout:this.timeoutMs}),{success:!0})}catch(o){return this.isBrowserClosedError(o)?{success:false,error:"CRITICAL: Browser/page closed during test execution. Remaining actions skipped.",shouldBreak:true}:{success:false,error:`Failed to press ${s} on ${t}: ${o instanceof Error?o.message:String(o)}`}}}async hover(t,s){try{if(t==="relative"&&s){let o=this.selectors.relative;if(!o)return {success:!1,error:"Relative selector not defined for hover action."};let n=await a$1.resolve(this.page,o,s);return n?(await n.hover({timeout:this.timeoutMs}),{success:!0}):{success:!1,error:`Could not resolve relative target ${s} for hover.`}}let r=this.selectors[t];return r?(await this.page.locator(r).first().hover({timeout:this.timeoutMs}),{success:!0}):{success:!1,error:`Selector for hover target ${t} not found.`}}catch(r){return this.isBrowserClosedError(r)?{success:false,error:"CRITICAL: Browser/page closed during test execution. Remaining actions skipped.",shouldBreak:true}:{success:false,error:`Failed to hover ${t}: ${r instanceof Error?r.message:String(r)}`}}}};var te=class{constructor(t,s,r=400){this.page=t;this.selectors=s;this.timeoutMs=r;}async resolveTarget(t,s,r){try{if(t==="relative"){let n=r?this.selectors[r]:this.selectors.relative;if(!n)return {target:null,error:"Relative selector is not defined in the contract."};if(!s)return {target:null,error:"Relative target or expected value is not defined."};let l=await a$1.resolve(this.page,n,s);return l?{target:l}:{target:null,error:`Target ${t} not found.`}}let o=this.selectors[t];return o?{target:this.page.locator(o).first()}:{target:null,error:`Selector for assertion target ${t} not found.`}}catch(o){return {target:null,error:`Failed to resolve target ${t}: ${o instanceof Error?o.message:String(o)}`}}}async validateVisibility(t,s,r,o,n){try{return r?(await expect(t).toBeVisible({timeout:this.timeoutMs}),{success:!0,passMessage:`${s} is visible as expected. Test: "${n}".`}):(await expect(t).toBeHidden({timeout:this.timeoutMs}),{success:!0,passMessage:`${s} is not visible as expected. Test: "${n}".`})}catch{let l=this.selectors[s]||"",i=await this.page.evaluate(C=>{let k=C?document.querySelector(C):null;if(!k)return "element not found";let A=window.getComputedStyle(k);return `display:${A.display}, visibility:${A.visibility}, opacity:${A.opacity}`},l);return r?{success:false,failMessage:`${o} (actual: ${i})`}:{success:false,failMessage:`${o} ${s} is still visible (actual: ${i}).`}}}async validateAttribute(t,s,r,o,n,l){if(o==="!empty"){let k=await t.getAttribute(r);return k&&k.trim()!==""?{success:true,passMessage:`${s} has non-empty "${r}". Test: "${l}".`}:{success:false,failMessage:`${n} ${s} "${r}" should not be empty, found "${k}".`}}if(typeof o!="string")throw console.error("[AssertionRunner] expectedValue is not a string:",o),new Error(`AssertionRunner: expectedValue for attribute assertion must be a string, but got: ${JSON.stringify(o)}`);let i=o.split(" | ").map(k=>k.trim()),C=await t.getAttribute(r);return C!==null&&i.includes(C)?{success:true,passMessage:`${s} has expected "${r}". Test: "${l}".`}:{success:false,failMessage:`${n} ${s} "${r}" should be "${o}", found "${C}".`}}async validateValue(t,s,r,o,n){let l=await t.inputValue().catch(()=>"");return r==="!empty"?l&&l.trim()!==""?{success:true,passMessage:`${s} has non-empty value. Test: "${n}".`}:{success:false,failMessage:`${o} ${s} value should not be empty, found "${l}".`}:r===""?l===""?{success:true,passMessage:`${s} has empty value. Test: "${n}".`}:{success:false,failMessage:`${o} ${s} value should be empty, found "${l}".`}:l===r?{success:true,passMessage:`${s} has expected value. Test: "${n}".`}:{success:false,failMessage:`${o} ${s} value should be "${r}", found "${l}".`}}async validateFocus(t,s,r,o,n){try{return r?(await expect(t).toBeFocused({timeout:this.timeoutMs}),{success:!0,passMessage:`${s} has focus as expected. Test: "${n}".`}):(await expect(t).not.toBeFocused({timeout:this.timeoutMs}),{success:!0,passMessage:`${s} does not have focus as expected. Test: "${n}".`})}catch{let l=await this.page.evaluate(()=>{let i=document.activeElement;return i?`${i.tagName}#${i.id||"no-id"}.${i.className||"no-class"}`:"no element focused"});return {success:false,failMessage:`${o} (actual focus: ${l})`}}}async validateRole(t,s,r,o,n){let l=await t.getAttribute("role");return l===r?{success:true,passMessage:`${s} has role "${r}". Test: "${n}".`}:{success:false,failMessage:`${o} Expected role "${r}", found "${l}".`}}async validate(t,s){if(this.page.isClosed())return {success:false,failMessage:"CRITICAL: Browser/page closed before completing all tests. Increase test timeout or reduce test complexity."};let r=null,o;if(t.controlledBy){let n=t.controlledBy,l=this.selectors[n.target];if(!l)return {success:false,failMessage:`Selector for controlledBy.target '${n.target}' not found.`,target:null};let i=null;if(n.relativeTarget?i=await a$1.resolve(this.page,l,n.relativeTarget):i=this.page.locator(l).first(),!i)return {success:false,failMessage:"Controlling element for controlledBy not found.",target:null};let C=n.attribute||"aria-controls",k=await i.getAttribute(C);if(!k)return {success:false,failMessage:`Controlling element does not have attribute '${C}'.`,target:null};if(r=this.page.locator(`#${k}`),!r||await r.count()===0)return {success:false,failMessage:`Controlled element with id '${k}' not found.`,target:null}}else {let n=await this.resolveTarget(t.target,t.relativeTarget||t.expectedValue,t.selectorKey);if(r=n.target,o=n.error,o||!r)return {success:false,failMessage:o||`Target ${t.target} not found.`,target:null}}if(t.target==="input"&&t.attribute==="aria-activedescendant"&&t.expectedValue==="!empty"&&t.relativeTarget&&t.selectorKey){let n=await a$1.resolve(this.page,this.selectors[t.selectorKey],t.relativeTarget),l=n?await n.getAttribute("id"):null,i=await r.getAttribute("aria-activedescendant");return l&&i===l?{success:true,passMessage:`input[aria-activedescendant] matches id of ${t.relativeTarget}(${t.selectorKey}). Test: "${s}".`}:{success:false,failMessage:`input[aria-activedescendant] should match id of ${t.relativeTarget}(${t.selectorKey}), found "${i}".`}}switch(t.assertion){case "toBeVisible":return this.validateVisibility(r,t.target,true,t.failureMessage||"",s);case "notToBeVisible":return this.validateVisibility(r,t.target,false,t.failureMessage||"",s);case "toHaveAttribute":return t.attribute&&t.expectedValue!==void 0?this.validateAttribute(r,t.target,t.attribute,t.expectedValue,t.failureMessage||"",s):{success:false,failMessage:"Missing attribute or expectedValue for toHaveAttribute assertion"};case "toHaveValue":return t.expectedValue!==void 0?this.validateValue(r,t.target,t.expectedValue,t.failureMessage||"",s):{success:false,failMessage:"Missing expectedValue for toHaveValue assertion"};case "toHaveFocus":return this.validateFocus(r,t.target,true,t.failureMessage||"",s);case "notToHaveFocus":return this.validateFocus(r,t.target,false,t.failureMessage||"",s);case "toHaveRole":return t.expectedValue!==void 0?this.validateRole(r,t.target,t.expectedValue,t.failureMessage||"",s):{success:false,failMessage:"Missing expectedValue for toHaveRole assertion"};default:return {success:false,failMessage:`Unknown assertion type: ${t.assertion}`}}}};async function nt(M,t,s,r,o){let n=r?.test?.components?.find(g=>g.name===M),l=!!n?.contractPath,i=new oe(true,l),C={actionTimeoutMs:400,assertionTimeoutMs:400,navigationTimeoutMs:3e4,componentReadyTimeoutMs:5e3},k=r?.test?.disableTimeouts===true,ee=n?.disableTimeouts===true||k,K=(g,W,O)=>{if(ee)return 0;let L=g??W;return typeof L!="number"||!Number.isFinite(L)||L<0?O:L},z=K(n?.actionTimeoutMs,r?.test?.actionTimeoutMs,C.actionTimeoutMs),Q=K(n?.assertionTimeoutMs,r?.test?.assertionTimeoutMs,C.assertionTimeoutMs),se=K(n?.navigationTimeoutMs,r?.test?.navigationTimeoutMs,C.navigationTimeoutMs),ce=K(n?.componentReadyTimeoutMs,r?.test?.componentReadyTimeoutMs,C.componentReadyTimeoutMs),me=d(s),X=n?.contractPath;if(!X)throw new Error(`Contract path not found for component: ${M}`);let Ae=(()=>{if(ge.isAbsolute(X))return X;if(o){let W=ge.resolve(o,X);try{return readFileSync(W,"utf-8"),W}catch{}}let g=ge.resolve(process.cwd(),X);try{return readFileSync(g,"utf-8"),g}catch{return new URL(X,import.meta.url).pathname}})(),Me=readFileSync(Ae,"utf-8"),b=JSON.parse(Me),Ee=(b.relationships?.length||0)+(b.static.length||0)+b.dynamic.length,xe=b.meta?.source?.apg,V=[],q=[],J=[],E=[],v=null,x=(g,W)=>{let O=c(W),L=e(O,me);if(L==="error")return V.push(g),{status:"fail",level:O,detail:g};if(L==="warning")return q.push(g),{status:"warn",level:O,detail:g};let H=`${g} (ignored by strictness=${me}, level=${O})`;return E.push(H),{status:"skip",level:O,detail:H}},Pe=g=>g&&typeof g=="object"&&g.success===true;try{if(v=await a(),t){try{await v.goto(t,{waitUntil:"domcontentloaded",timeout:se});}catch(e){throw new Error(`Failed to navigate to ${t}. Ensure dev server is running and accessible. Original error: ${e instanceof Error?e.message:String(e)}`)}await v.addStyleTag({content:"* { transition: none !important; animation: none !important; }"});}let g=await ne.detect(M,n,z,Q,o);if(!g)throw new Error(`Unsupported component: ${M}`);let W=g.getMainSelector();if(!W)throw new Error(`CRITICAL: No selector found in contract for ${M}`);try{await v.locator(W).first().waitFor({state:"attached",timeout:ce});}catch(e){throw new Error(`
22
+ \u274C Error: ${t}`),s&&this.log(` Context: ${s}`),this.log("");}};var N=class{constructor(t,s,r){this.page=t;this.selectors=s;this.actionTimeoutMs=r;}isBrowserClosedError(t){return t instanceof Error&&t.message.includes("Target page, context or browser has been closed")}async focus(t,s,r){try{if(t==="virtual"&&r){let n=this.selectors.main;if(!n)return {success:!1,error:"Main selector not defined for virtual focus."};let l=this.page.locator(n).first();return await l.count()?(await l.evaluate((C,k)=>{C.setAttribute("aria-activedescendant",k);},r),{success:!0}):{success:!1,error:"Main element not found for virtual focus."}}if(t==="relative"&&s){let n=this.selectors.relative;if(!n)return {success:!1,error:"Relative selector not defined for focus action."};let l=await a$1.resolve(this.page,n,s);return l?(await l.focus({timeout:this.actionTimeoutMs}),{success:!0}):{success:!1,error:`Could not resolve relative target ${s} for focus.`}}let o=this.selectors[t];return o?(await this.page.locator(o).first().focus({timeout:this.actionTimeoutMs}),{success:!0}):{success:!1,error:`Selector for focus target ${t} not found.`}}catch(o){return this.isBrowserClosedError(o)?{success:false,error:"CRITICAL: Browser/page closed during test execution. Remaining actions skipped.",shouldBreak:true}:{success:false,error:`Failed to focus ${t}: ${o instanceof Error?o.message:String(o)}`}}}async type(t,s){try{let r=this.selectors[t];return r?(await this.page.locator(r).first().fill(s,{timeout:this.actionTimeoutMs}),{success:!0}):{success:!1,error:`Selector for type target ${t} not found.`}}catch(r){return this.isBrowserClosedError(r)?{success:false,error:"CRITICAL: Browser/page closed during test execution. Remaining actions skipped.",shouldBreak:true}:{success:false,error:`Failed to type into ${t}: ${r instanceof Error?r.message:String(r)}`}}}async click(t,s){try{if(t==="document")return await this.page.mouse.click(10,10),{success:!0};if(t==="relative"&&s){let o=this.selectors.relative;if(!o)return {success:!1,error:"Relative selector not defined for click action."};let n=await a$1.resolve(this.page,o,s);return n?(await n.click({timeout:this.actionTimeoutMs}),{success:!0}):{success:!1,error:`Could not resolve relative target ${s} for click.`}}let r=this.selectors[t];return r?(await this.page.locator(r).first().click({timeout:this.actionTimeoutMs}),{success:!0}):{success:!1,error:`Selector for action target ${t} not found.`}}catch(r){return this.isBrowserClosedError(r)?{success:false,error:"CRITICAL: Browser/page closed during test execution. Remaining actions skipped.",shouldBreak:true}:{success:false,error:`Failed to click ${t}: ${r instanceof Error?r.message:String(r)}`}}}async keypress(t,s,r){try{let n={Space:"Space",Enter:"Enter",Escape:"Escape","Arrow Up":"ArrowUp","Arrow Down":"ArrowDown","Arrow Left":"ArrowLeft","Arrow Right":"ArrowRight",Home:"Home",End:"End",Tab:"Tab"}[s]||s;if(n==="Space"?n=" ":n.includes(" ")&&(n=n.replace(/ /g,"")),t==="relative"){if(r==null)return {success:!1,error:"relativeTarget must be provided for relative keypress."};let k=this.selectors.relative;if(!k)return {success:!1,error:"Relative selector not defined for keypress action."};let A=await a$1.resolve(this.page,k,r);return A?(await A.press(n,{timeout:this.actionTimeoutMs}),{success:!0}):{success:!1,error:`Could not resolve relative target ${r} for keypress.`}}let l=this.selectors[t];if(!l)return {success:!1,error:`Selector for keypress target ${t} not found.`};let i=this.page.locator(l).first();return await i.count()===0?{success:!1,error:`${t} element not found.`,shouldBreak:!0}:(await i.press(n,{timeout:this.actionTimeoutMs}),{success:!0})}catch(o){return this.isBrowserClosedError(o)?{success:false,error:"CRITICAL: Browser/page closed during test execution. Remaining actions skipped.",shouldBreak:true}:{success:false,error:`Failed to press ${s} on ${t}: ${o instanceof Error?o.message:String(o)}`}}}async hover(t,s){try{if(t==="relative"&&s){let o=this.selectors.relative;if(!o)return {success:!1,error:"Relative selector not defined for hover action."};let n=await a$1.resolve(this.page,o,s);return n?(await n.hover({timeout:this.actionTimeoutMs}),{success:!0}):{success:!1,error:`Could not resolve relative target ${s} for hover.`}}let r=this.selectors[t];return r?(await this.page.locator(r).first().hover({timeout:this.actionTimeoutMs}),{success:!0}):{success:!1,error:`Selector for hover target ${t} not found.`}}catch(r){return this.isBrowserClosedError(r)?{success:false,error:"CRITICAL: Browser/page closed during test execution. Remaining actions skipped.",shouldBreak:true}:{success:false,error:`Failed to hover ${t}: ${r instanceof Error?r.message:String(r)}`}}}};var te=class{constructor(t,s,r){this.page=t;this.selectors=s;this.assertionTimeoutMs=r;}async resolveTarget(t,s,r){try{if(t==="relative"){let n=r?this.selectors[r]:this.selectors.relative;if(!n)return {target:null,error:"Relative selector is not defined in the contract."};if(!s)return {target:null,error:"Relative target or expected value is not defined."};let l=await a$1.resolve(this.page,n,s);return l?{target:l}:{target:null,error:`Target ${t} not found.`}}let o=this.selectors[t];return o?{target:this.page.locator(o).first()}:{target:null,error:`Selector for assertion target ${t} not found.`}}catch(o){return {target:null,error:`Failed to resolve target ${t}: ${o instanceof Error?o.message:String(o)}`}}}async validateVisibility(t,s,r,o,n){try{return r?(await expect(t).toBeVisible({timeout:this.assertionTimeoutMs}),{success:!0,passMessage:`${s} is visible as expected. Test: "${n}".`}):(await expect(t).toBeHidden({timeout:this.assertionTimeoutMs}),{success:!0,passMessage:`${s} is not visible as expected. Test: "${n}".`})}catch{let l=this.selectors[s]||"",i=await this.page.evaluate(C=>{let k=C?document.querySelector(C):null;if(!k)return "element not found";let A=window.getComputedStyle(k);return `display:${A.display}, visibility:${A.visibility}, opacity:${A.opacity}`},l);return r?{success:false,failMessage:`${o} (actual: ${i})`}:{success:false,failMessage:`${o} ${s} is still visible (actual: ${i}).`}}}async validateAttribute(t,s,r,o,n,l){if(o==="!empty"){let k=await t.getAttribute(r);return k&&k.trim()!==""?{success:true,passMessage:`${s} has non-empty "${r}". Test: "${l}".`}:{success:false,failMessage:`${n} ${s} "${r}" should not be empty, found "${k}".`}}if(typeof o!="string")throw new Error(`AssertionRunner: expectedValue for attribute assertion must be a string, but got: ${JSON.stringify(o)}`);let i=o.split(" | ").map(k=>k.trim()),C=await t.getAttribute(r);return C!==null&&i.includes(C)?{success:true,passMessage:`${s} has expected "${r}". Test: "${l}".`}:{success:false,failMessage:`${n} ${s} "${r}" should be "${o}", found "${C}".`}}async validateValue(t,s,r,o,n){let l=await t.inputValue().catch(()=>"");return r==="!empty"?l&&l.trim()!==""?{success:true,passMessage:`${s} has non-empty value. Test: "${n}".`}:{success:false,failMessage:`${o} ${s} value should not be empty, found "${l}".`}:r===""?l===""?{success:true,passMessage:`${s} has empty value. Test: "${n}".`}:{success:false,failMessage:`${o} ${s} value should be empty, found "${l}".`}:l===r?{success:true,passMessage:`${s} has expected value. Test: "${n}".`}:{success:false,failMessage:`${o} ${s} value should be "${r}", found "${l}".`}}async validateFocus(t,s,r,o,n){try{return r?(await expect(t).toBeFocused({timeout:this.assertionTimeoutMs}),{success:!0,passMessage:`${s} has focus as expected. Test: "${n}".`}):(await expect(t).not.toBeFocused({timeout:this.assertionTimeoutMs}),{success:!0,passMessage:`${s} does not have focus as expected. Test: "${n}".`})}catch{let l=await this.page.evaluate(()=>{let i=document.activeElement;return i?`${i.tagName}#${i.id||"no-id"}.${i.className||"no-class"} [text="${i.innerText||i.textContent||""}"]`:"no element focused"});return {success:false,failMessage:`${o} (actual focus: ${l})`}}}async validateRole(t,s,r,o,n){let l=await t.getAttribute("role");return l===r?{success:true,passMessage:`${s} has role "${r}". Test: "${n}".`}:{success:false,failMessage:`${o} Expected role "${r}", found "${l}".`}}async validate(t,s){if(this.page.isClosed())return {success:false,failMessage:"CRITICAL: Browser/page closed before completing all tests. Increase test timeout or reduce test complexity."};let r=null,o;if(t.controlledBy){let n=t.controlledBy,l=this.selectors[n.target];if(!l)return {success:false,failMessage:`Selector for controlledBy.target '${n.target}' not found.`,target:null};let i=null;if(n.relativeTarget?i=await a$1.resolve(this.page,l,n.relativeTarget):i=this.page.locator(l).first(),!i)return {success:false,failMessage:"Controlling element for controlledBy not found.",target:null};let C=n.attribute||"aria-controls",k=await i.getAttribute(C);if(!k)return {success:false,failMessage:`Controlling element does not have attribute '${C}'.`,target:null};if(r=this.page.locator(`#${k}`),!r||await r.count()===0)return {success:false,failMessage:`Controlled element with id '${k}' not found.`,target:null}}else {let n=await this.resolveTarget(t.target,t.relativeTarget||t.expectedValue,t.selectorKey);if(r=n.target,o=n.error,o||!r)return {success:false,failMessage:o||`Target ${t.target} not found.`,target:null}}if(t.target==="input"&&t.attribute==="aria-activedescendant"&&t.expectedValue==="!empty"&&t.relativeTarget&&t.selectorKey){let n=await a$1.resolve(this.page,this.selectors[t.selectorKey],t.relativeTarget),l=n?await n.getAttribute("id"):null,i=await r.getAttribute("aria-activedescendant");return l&&i===l?{success:true,passMessage:`input[aria-activedescendant] matches id of ${t.relativeTarget}(${t.selectorKey}). Test: "${s}".`}:{success:false,failMessage:`input[aria-activedescendant] should match id of ${t.relativeTarget}(${t.selectorKey}), found "${i}".`}}switch(t.assertion){case "toBeVisible":return this.validateVisibility(r,t.target,true,t.failureMessage||"",s);case "notToBeVisible":return this.validateVisibility(r,t.target,false,t.failureMessage||"",s);case "toHaveAttribute":return t.attribute&&t.expectedValue!==void 0?this.validateAttribute(r,t.target,t.attribute,t.expectedValue,t.failureMessage||"",s):{success:false,failMessage:"Missing attribute or expectedValue for toHaveAttribute assertion"};case "toHaveValue":return t.expectedValue!==void 0?this.validateValue(r,t.target,t.expectedValue,t.failureMessage||"",s):{success:false,failMessage:"Missing expectedValue for toHaveValue assertion"};case "toHaveFocus":return this.validateFocus(r,t.target,true,t.failureMessage||"",s);case "notToHaveFocus":return this.validateFocus(r,t.target,false,t.failureMessage||"",s);case "toHaveRole":return t.expectedValue!==void 0?this.validateRole(r,t.target,t.expectedValue,t.failureMessage||"",s):{success:false,failMessage:"Missing expectedValue for toHaveRole assertion"};default:return {success:false,failMessage:`Unknown assertion type: ${t.assertion}`}}}};async function nt(M,t,s,r,o){let n=r?.test?.components?.find(g=>g.name===M),l=!!n?.contractPath,i=new oe(true,l),C={actionTimeoutMs:400,assertionTimeoutMs:400,navigationTimeoutMs:3e4,componentReadyTimeoutMs:5e3},k=r?.test?.disableTimeouts===true,ee=n?.disableTimeouts===true||k,K=(g,W,O)=>{if(ee)return 0;let L=g??W;return typeof L!="number"||!Number.isFinite(L)||L<0?O:L},z=K(n?.actionTimeoutMs,r?.test?.actionTimeoutMs,C.actionTimeoutMs),Q=K(n?.assertionTimeoutMs,r?.test?.assertionTimeoutMs,C.assertionTimeoutMs),se=K(n?.navigationTimeoutMs,r?.test?.navigationTimeoutMs,C.navigationTimeoutMs),ce=K(n?.componentReadyTimeoutMs,r?.test?.componentReadyTimeoutMs,C.componentReadyTimeoutMs),me=d(s),X=n?.contractPath;if(!X)throw new Error(`Contract path not found for component: ${M}`);let Ae=(()=>{if(ge.isAbsolute(X))return X;if(o){let W=ge.resolve(o,X);try{return readFileSync(W,"utf-8"),W}catch{}}let g=ge.resolve(process.cwd(),X);try{return readFileSync(g,"utf-8"),g}catch{return new URL(X,import.meta.url).pathname}})(),Me=readFileSync(Ae,"utf-8"),b=JSON.parse(Me),Ee=(b.relationships?.length||0)+(b.static.length||0)+b.dynamic.length,xe=b.meta?.source?.apg,V=[],q=[],J=[],E=[],v=null,x=(g,W)=>{let O=c(W),L=e(O,me);if(L==="error")return V.push(g),{status:"fail",level:O,detail:g};if(L==="warning")return q.push(g),{status:"warn",level:O,detail:g};let H=`${g} (ignored by strictness=${me}, level=${O})`;return E.push(H),{status:"skip",level:O,detail:H}},Pe=g=>g&&typeof g=="object"&&g.success===true;try{if(v=await a(),t){try{await v.goto(t,{waitUntil:"domcontentloaded",timeout:se});}catch(e){throw new Error(`Failed to navigate to ${t}. Ensure dev server is running and accessible. Original error: ${e instanceof Error?e.message:String(e)}`)}await v.addStyleTag({content:"* { transition: none !important; animation: none !important; }"});}let g=await ne.detect(M,z,Q,n,o);if(!g)throw new Error(`Unsupported component: ${M}`);let W=g.getMainSelector();if(!W)throw new Error(`CRITICAL: No selector found in contract for ${M}`);try{await v.locator(W).first().waitFor({state:"attached",timeout:ce});}catch(e){throw new Error(`
23
23
  \u274C CRITICAL: Component not found on page!
24
24
  This usually means:
25
25
  - The component didn't render
@@ -1 +1 @@
1
- 'use strict';function o(e,t){return t==="first"?`first ${e}`:t==="last"?`last ${e}`:t==="next"?`next ${e}`:t==="previous"?`previous ${e}`:typeof t=="number"?`${e} at index ${t}`:`${t} ${e}`}var x={"comboboxpopup.open":{setup:[{when:["keyboard","textInput","pointer"],steps:()=>[{type:"keypress",target:"input",key:"ArrowDown"}]},{when:["pointer"],steps:()=>[{type:"click",target:"button"}]}],assertion:C},"comboboxpopup.closed":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:[...D(),...k()]},"main.focused":{setup:[{when:["keyboard","pointer"],steps:()=>[{type:"focus",target:"main"}]}],assertion:B},"main.blurred":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:I},"input.filled":{setup:[{when:["keyboard","textInput","pointer"],steps:()=>[{type:"type",target:"input",value:"test"}]}],assertion:F},"input.empty":{setup:[{when:["keyboard","textInput","pointer"],steps:()=>[{type:"type",target:"input",value:""}]}],assertion:$},"option.active":{requires:["comboboxpopup.open"],setup:[{when:["keyboard","pointer"],steps:(e={})=>typeof e.relativeTarget=="number"?Array.from({length:e.relativeTarget},()=>({type:"keypress",target:"main",key:"ArrowDown"})):e.relativeTarget==="first"?[{type:"keypress",target:"main",key:"ArrowDown"}]:e.relativeTarget==="last"?[{type:"keypress",target:"main",key:"ArrowDown"},{type:"keypress",target:"main",key:"ArrowUp"}]:[]}],assertion:(e={})=>R(e.relativeTarget)},"activedescendant.set":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:V},"activedescendant.unset":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:k},"option.selected":{requires:["comboboxpopup.open"],setup:[{when:["keyboard"],steps:(e={})=>[{type:"keypress",target:"relative",key:"Enter",relativeTarget:e.relativeTarget}]},{when:["pointer"],steps:(e={})=>[{type:"click",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>q(e.relativeTarget)}};function C(){return [{target:"popup",assertion:"toBeVisible",failureMessage:"Expected popup to be visible"},{target:"main",assertion:"toHaveAttribute",attribute:"aria-expanded",expectedValue:"true",failureMessage:"Expected combobox main to have aria-expanded='true'."}]}function D(){return [{target:"popup",assertion:"notToBeVisible",failureMessage:"Expected popup to be closed"},{target:"main",assertion:"toHaveAttribute",attribute:"aria-expanded",expectedValue:"false",failureMessage:"Expected combobox main to have aria-expanded='false'."}]}function R(e){return [{target:"main",assertion:"toHaveAttribute",attribute:"aria-activedescendant",expectedValue:{ref:"relative",relativeTarget:e,property:"id"},failureMessage:"Expected aria-activedescendant on main to match the id of the first relative item."}]}function V(){return [{target:"main",assertion:"toHaveAttribute",attribute:"aria-activedescendant",expectedValue:"!empty",failureMessage:"Expected aria-activedescendant on main to not be empty."}]}function k(){return [{target:"main",assertion:"toHaveAttribute",attribute:"aria-activedescendant",expectedValue:"",failureMessage:"Expected aria-activedescendant on main to be empty."}]}function q(e){return [{target:"relative",relativeTarget:e,assertion:"toHaveAttribute",attribute:"aria-selected",expectedValue:"true",failureMessage:`Expected ${o("option",e)} to have aria-selected='true'.`}]}function B(){return [{target:"main",assertion:"toHaveFocus",failureMessage:"Expected main to be focused."}]}function I(){return [{target:"main",assertion:"notToHaveFocus",failureMessage:"Expected main to not have focused."}]}function F(){return [{target:"input",assertion:"toHaveValue",expectedValue:"test",failureMessage:"Expected input to have the value 'test'."}]}function $(){return [{target:"input",assertion:"toHaveValue",expectedValue:"",failureMessage:"Expected input to have the value ''."}]}var A={"menupopup.open":{setup:[{when:["keyboard"],steps:()=>[{type:"keypress",target:"main",key:"Enter"}]},{when:["pointer"],steps:()=>[{type:"click",target:"main"}]}],assertion:P},"menupopup.closed":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:O},"main.focused":{setup:[{when:["keyboard","pointer"],steps:()=>[{type:"focus",target:"main"}]}],assertion:z},"main.blurred":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:L},"menuitem.focused":{requires:["menupopup.open"],setup:[{when:["keyboard"],steps:(e={})=>[{type:"focus",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>j(e.relativeTarget)},"submenupopup.open":{requires:["menupopup.open"],setup:[{when:["keyboard"],steps:()=>[{type:"keypress",target:"submenuTrigger",key:"ArrowRight"}]},{when:["pointer"],steps:()=>[{type:"click",target:"submenuTrigger"}]}],assertion:U},"submenupopup.closed":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:K},"submenutrigger.focused":{setup:[{when:["keyboard","pointer"],steps:()=>[{type:"focus",target:"submenuTrigger"}]}],assertion:J},"submenutrigger.blurred":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:G},"submenuitem.focused":{requires:["submenupopup.open"],setup:[{when:["keyboard"],steps:(e={})=>{let t=[{type:"focus",target:"submenuTrigger"},{type:"keypress",target:"submenuTrigger",key:"ArrowRight"}];return typeof e.relativeTarget=="number"&&(t=t.concat(Array.from({length:e.relativeTarget},()=>({type:"keypress",target:"submenuItems",key:"ArrowDown"})))),e.relativeTarget==="first"&&(t=t.concat({type:"keypress",target:"submenuItems",key:"ArrowDown"})),e.relativeTarget==="last"&&(t=t.concat({type:"keypress",target:"submenuItems",key:"ArrowUp"})),t}},{when:["pointer"],steps:(e={})=>[{type:"click",target:"submenuTrigger"},{type:"click",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>X(e.relativeTarget)}};function P(){return [{target:"popup",assertion:"toBeVisible",failureMessage:"Expected popup to be visible"},{target:"main",assertion:"toHaveAttribute",attribute:"aria-expanded",expectedValue:"true",failureMessage:"Expected menu main to have aria-expanded='true'."}]}function O(){return [{target:"popup",assertion:"notToBeVisible",failureMessage:"Expected popup to be closed"},{target:"main",assertion:"toHaveAttribute",attribute:"aria-expanded",expectedValue:"false",failureMessage:"Expected menu main to have aria-expanded='false'."}]}function z(){return [{target:"main",assertion:"toHaveFocus",failureMessage:"Expected menu main to be focused."}]}function L(){return [{target:"main",assertion:"notToHaveFocus",failureMessage:"Expected menu main to not have focused."}]}function j(e){return [{target:"relative",assertion:"toHaveFocus",expectedValue:e,failureMessage:`${e} menu item should have focus.`}]}function U(){return [{target:"submenu",assertion:"toBeVisible",failureMessage:"Expected submenu to be visible"},{target:"submenuTrigger",assertion:"toHaveAttribute",attribute:"aria-expanded",expectedValue:"true",failureMessage:"Expected submenu trigger to have aria-expanded='true'."}]}function K(){return [{target:"submenu",assertion:"notToBeVisible",failureMessage:"Expected submenu to be closed"},{target:"submenuTrigger",assertion:"toHaveAttribute",attribute:"aria-expanded",expectedValue:"false",failureMessage:"Expected submenu trigger to have aria-expanded='false'."}]}function J(){return [{target:"submenuTrigger",assertion:"toHaveFocus",failureMessage:"Expected submenu trigger to be focused."}]}function G(){return [{target:"submenuTrigger",assertion:"notToHaveFocus",failureMessage:"Expected submenu trigger to not have focused."}]}function X(e){return [{target:"relative",relativeTarget:e,assertion:"toHaveFocus",failureMessage:`Expected submenu item ${e} to have focus.`}]}var w={"tab.active":{setup:[{when:["keyboard"],steps:(e={})=>[{type:"keypress",target:"relative",relativeTarget:e.relativeTarget,key:"ArrowLeft"}]},{when:["pointer"],steps:(e={})=>[{type:"click",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>Y(e.relativeTarget)},"tab.focused":{setup:[{when:["keyboard","pointer"],steps:(e={})=>[{type:"focus",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>N(e.relativeTarget)},"tab.blurred":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:(e={})=>W(e.relativeTarget)}};function N(e){return [{target:"relative",assertion:"toHaveFocus",relativeTarget:e,failureMessage:`Expected ${o("tab",e)} to have focus.`}]}function W(e){return [{target:"relative",assertion:"toHaveFocus",relativeTarget:e,failureMessage:`Expected ${o("tab",e)} not to have focus.`}]}function Q(e){return [{target:"relative",assertion:"toHaveAttribute",attribute:"aria-selected",expectedValue:"true",relativeTarget:e,failureMessage:`Expected ${o("tab",e)} to have tabindex='0'.`}]}function Y(e){return [{target:"relative",assertion:"toHaveAttribute",attribute:"aria-selected",expectedValue:"true",relativeTarget:e,failureMessage:`Expected ${o("tab",e)} to have aria-selected='true'.`},{target:"panel",assertion:"toBeVisible",controlledBy:{target:"relative",relativeTarget:e},failureMessage:`Expected panel controlled by the ${o("tab",e)} to be visible.`},Q(e)]}var S={"panel.expanded":{setup:[{when:["keyboard"],steps:e=>[{type:"keypress",target:"relative",relativeTarget:e.relativeTarget,key:"Enter"}]},{when:["pointer"],steps:e=>[{type:"click",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>Z(e.relativeTarget)},"panel.collapsed":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:(e={})=>ee(e.relativeTarget)},"trigger.focused":{setup:[{when:["keyboard","pointer"],steps:e=>[{type:"focus",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>te(e.relativeTarget)},"trigger.blurred":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:(e={})=>re(e.relativeTarget)}};function Z(e){return [{target:"panel",assertion:"toBeVisible",controlledBy:{target:"relative",relativeTarget:e},failureMessage:`Expected panel controlled by the ${e} trigger to be visible.`},{target:"relative",relativeTarget:e,assertion:"toHaveAttribute",attribute:"aria-expanded",expectedValue:"true",failureMessage:"Expected trigger to have aria-expanded='true' when panel expands."}]}function ee(e){return [{target:"panel",assertion:"notToBeVisible",controlledBy:{target:"relative",relativeTarget:e},failureMessage:`Expected panel controlled by the ${e} trigger not to be visible.`},{target:"relative",relativeTarget:e,assertion:"toHaveAttribute",attribute:"aria-expanded",expectedValue:"false",failureMessage:"Expected trigger to have aria-expanded='false' when panel collapses."}]}function te(e){return [{target:"relative",assertion:"toHaveFocus",relativeTarget:e,failureMessage:`Expected ${o("trigger",e)} to have focus.`}]}function re(e){return [{target:"relative",assertion:"toHaveFocus",relativeTarget:e,failureMessage:`Expected ${o("trigger",e)} not to have focus.`}]}var E={"radio.checked":{setup:[{when:["keyboard"],steps:e=>[{type:"keypress",target:"relative",relativeTarget:e.relativeTarget,key:"Space"}]},{when:["pointer"],steps:e=>[{type:"click",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>ie(e.relativeTarget)},"radio.unchecked":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:(e={})=>ae(e.relativeTarget)},"radio.focused":{setup:[{when:["keyboard","pointer"],steps:e=>[{type:"focus",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>se(e.relativeTarget)},"radio.blurred":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:(e={})=>ne(e.relativeTarget)}};function ie(e){return [{target:"relative",relativeTarget:e,assertion:"toHaveAttribute",attribute:"aria-checked",expectedValue:"true",failureMessage:"Expected radio to have aria-checked='true' when checked."}]}function ae(e){return [{target:"relative",relativeTarget:e,assertion:"toHaveAttribute",attribute:"aria-checked",expectedValue:"false",failureMessage:"Expected radio to have aria-checked='false' when unchecked."}]}function se(e){return [{target:"relative",assertion:"toHaveFocus",relativeTarget:e,failureMessage:`Expected ${o("radio",e)} to have focus.`}]}function ne(e){return [{target:"relative",assertion:"toHaveFocus",relativeTarget:e,failureMessage:`Expected ${o("radio",e)} not to have focus.`}]}var M={"checkbox.checked":{setup:[{when:["keyboard"],steps:e=>[{type:"keypress",target:"relative",relativeTarget:e.relativeTarget,key:"Space"}]},{when:["pointer"],steps:e=>[{type:"click",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>oe(e.relativeTarget)},"checkbox.unchecked":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:(e={})=>ue(e.relativeTarget)},"checkbox.focused":{setup:[{when:["keyboard","pointer"],steps:e=>[{type:"focus",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>pe(e.relativeTarget)},"checkbox.blurred":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:(e={})=>ce(e.relativeTarget)}};function oe(e){return [{target:"relative",relativeTarget:e,assertion:"toHaveAttribute",attribute:"aria-checked",expectedValue:"true",failureMessage:"Expected checkbox to have aria-checked='true' when checked."}]}function ue(e){return [{target:"relative",relativeTarget:e,assertion:"toHaveAttribute",attribute:"aria-checked",expectedValue:"false",failureMessage:"Expected checkbox to have aria-checked='false' when unchecked."}]}function pe(e){return [{target:"relative",assertion:"toHaveFocus",relativeTarget:e,failureMessage:`Expected ${o("checkbox",e)} to have focus.`}]}function ce(e){return [{target:"relative",assertion:"toHaveFocus",relativeTarget:e,failureMessage:`Expected ${o("checkbox",e)} not to have focus.`}]}var H={"toggle.pressed":{setup:[{when:["keyboard"],steps:e=>[{type:"keypress",target:"relative",relativeTarget:e.relativeTarget,key:"Enter"}]},{when:["pointer"],steps:e=>[{type:"click",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>le(e.relativeTarget)},"toggle.unpressed":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:(e={})=>ge(e.relativeTarget)},"toggle.focused":{setup:[{when:["keyboard","pointer"],steps:e=>[{type:"focus",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>de(e.relativeTarget)},"toggle.blurred":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:(e={})=>ve(e.relativeTarget)}};function le(e){return [{target:"relative",relativeTarget:e,assertion:"toHaveAttribute",attribute:"aria-pressed",expectedValue:"true",failureMessage:"Expected toggle to have aria-pressed='true' when pressed."}]}function ge(e){return [{target:"relative",relativeTarget:e,assertion:"toHaveAttribute",attribute:"aria-pressed",expectedValue:"false",failureMessage:"Expected toggle to have aria-pressed='false' when unpressed."}]}function de(e){return [{target:"relative",assertion:"toHaveFocus",relativeTarget:e,failureMessage:`Expected ${o("toggle",e)} to have focus.`}]}function ve(e){return [{target:"relative",assertion:"notToHaveFocus",relativeTarget:e,failureMessage:`Expected ${o("toggle",e)} not to have focus.`}]}function be(e,t){return t.some(l=>e.capabilities.includes(l))}function f(e,t){Array.isArray(e)&&e.length&&!e[0].when&&(e=[{when:["keyboard"],steps:()=>e}]);for(let l of e)if(be(t,l.when))return l.steps(t);throw new Error(`No setup strategy matches capabilities: ${t.capabilities.join(", ")}`)}var me={combobox:x,menu:A,tabs:w,accordion:S,radio:E,checkbox:M,toggle:H},h=class{constructor(t){this.jsonContract=t;}toJSON(){return this.jsonContract}},y=class{constructor(t){this.componentName=t;this.statePack=me[t]||{};}metaValue={};selectorsValue={};relationshipInvariants=[];staticAssertions=[];dynamicTests=[];statePack;meta(t){return this.metaValue=t,this}selectors(t){return this.selectorsValue=t,this}relationships(t){let l=this.statePack,u={capabilities:["keyboard"]},v=(n,i=new Set)=>{if(i.has(n))return [];i.add(n);let s=l[n];if(!s)return [];let r=[];if(Array.isArray(s.requires))for(let a of s.requires)r=r.concat(v(a,i));return s.setup&&(r=r.concat(f(s.setup,u))),r};return t({ariaReference:(n,i,s)=>({requires:r=>{let a=v(r,new Set);return {required:()=>this.relationshipInvariants.push({type:"aria-reference",from:n,attribute:i,to:s,level:"required",setup:a}),optional:()=>this.relationshipInvariants.push({type:"aria-reference",from:n,attribute:i,to:s,level:"optional",setup:a}),recommended:()=>this.relationshipInvariants.push({type:"aria-reference",from:n,attribute:i,to:s,level:"recommended",setup:a})}},required:()=>this.relationshipInvariants.push({type:"aria-reference",from:n,attribute:i,to:s,level:"required"}),optional:()=>this.relationshipInvariants.push({type:"aria-reference",from:n,attribute:i,to:s,level:"optional"}),recommended:()=>this.relationshipInvariants.push({type:"aria-reference",from:n,attribute:i,to:s,level:"recommended"})}),contains:(n,i)=>({requires:s=>{let r=v(s,new Set);return {required:()=>this.relationshipInvariants.push({type:"contains",parent:n,child:i,level:"required",setup:r}),optional:()=>this.relationshipInvariants.push({type:"contains",parent:n,child:i,level:"optional",setup:r}),recommended:()=>this.relationshipInvariants.push({type:"contains",parent:n,child:i,level:"recommended",setup:r})}},required:()=>this.relationshipInvariants.push({type:"contains",parent:n,child:i,level:"required"}),optional:()=>this.relationshipInvariants.push({type:"contains",parent:n,child:i,level:"optional"}),recommended:()=>this.relationshipInvariants.push({type:"contains",parent:n,child:i,level:"recommended"})})}),this}static(t){return t({target:u=>{let v=i=>{let s=this.statePack,r={capabilities:["keyboard"]},a=(p,c=new Set)=>{if(c.has(p))return [];c.add(p);let g=s[p];if(!g)return [];let b=[];if(Array.isArray(g.requires))for(let m of g.requires)b=b.concat(a(m,c));return g.setup&&(b=b.concat(f(g.setup,r))),b};return a(i,new Set)},d=i=>i==="role"?"toHaveRole":"toHaveAttribute",n=(i,s,r)=>{let a=d(i);return {required:()=>this.staticAssertions.push({target:u,assertion:a,attribute:i,expectedValue:s,failureMessage:"",level:"required",setup:r}),optional:()=>this.staticAssertions.push({target:u,assertion:a,attribute:i,expectedValue:s,failureMessage:"",level:"optional",setup:r}),recommended:()=>this.staticAssertions.push({target:u,assertion:a,attribute:i,expectedValue:s,failureMessage:"",level:"recommended",setup:r})}};return {has:(i,s)=>({...n(i,s),requires:a=>{let p=v(a);return n(i,s,p)}})}}}),this}when(t){return new T(this,this.statePack,t)}addDynamicTest(t){this.dynamicTests.push(t);}build(){return {meta:this.metaValue,selectors:this.selectorsValue,relationships:this.relationshipInvariants.length?this.relationshipInvariants:void 0,static:this.staticAssertions.length?this.staticAssertions:[],dynamic:this.dynamicTests}}},T=class{constructor(t,l,u){this.parent=t;this.statePack=l;this.event=u;}_as;_onTarget;_onRelativeTarget;_given=[];_then=[];_desc="";_level="required";_orientation;as(t){return this._as=t,this}on(t,l){return this._onTarget=t,this._onRelativeTarget=l,this}given(t){return this._given=this._normalizeStates(t),this}then(t){return this._then=this._normalizeStates(t),this}orientation(t){return this._orientation=t,this}_normalizeStates(t){return (Array.isArray(t)?t:[t]).flatMap(u=>typeof u=="string"?[u]:typeof u=="object"&&u!==null&&"type"in u&&"ref"in u?this._findStateKeyByTypeAndRef(u.type)?[{type:u.type,ref:u.ref}]:[]:[u])}_findStateKeyByTypeAndRef(t){if(Object.keys(this.statePack).includes(t))return t}describe(t){return this._desc=t,this}required(){return this._level="required",this._finalize(),this.parent}optional(){return this._level="optional",this._finalize(),this.parent}recommended(){return this._level="recommended",this._finalize(),this.parent}_finalize(){let u={capabilities:[{keypress:"keyboard",click:"pointer",type:"textInput",focus:"keyboard",hover:"pointer"}[this._as||"keyboard"]||this._as||"keyboard"]},v=(r,a=new Set,p)=>{if(a.has(r))return [];a.add(r);let c=this.statePack[r];if(!c)return [];let g=[];if(Array.isArray(c.requires))for(let b of c.requires)g=g.concat(v(b,a,p));if(c.setup){let b=c.setup.filter(m=>m.when.some(_=>u.capabilities.includes(_)));for(let m of b)typeof m.steps=="function"?g=g.concat(m.steps({relativeTarget:p})):g=g.concat(m.steps);}return g},d=[];for(let r of this._given)typeof r=="string"?d=d.concat(v(r,new Set)):typeof r=="object"&&r.type&&(d=d.concat(v(r.type,new Set,r.ref)));let n=new Set;d=d.filter(r=>{let a=[r.type,r.target,r.relativeTarget].join(":");return n.has(a)?false:(n.add(a),true)});let i=[];for(let r of this._then)if(typeof r=="string"){let a=this.statePack[r];if(a&&a.assertion!==void 0){let p=a.assertion;if(typeof p=="function")try{p=p();}catch(c){throw new Error(`Error calling assertion function for state '${r}': ${c.message}`)}Array.isArray(p)?i.push(...p):i.push(p);}}else if(typeof r=="object"&&r!==null&&"type"in r&&"ref"in r){let a=this._findStateKeyByTypeAndRef(r.type);if(a){let p=this.statePack[a];if(p&&p.assertion!==void 0){let c=p.assertion;if(typeof c=="function")try{c=c({relativeTarget:r.ref});}catch(g){throw new Error(`Error calling assertion function for state '${a}': ${g.message}`)}Array.isArray(c)?i.push(...c):i.push(c);}}}let s=[{type:this._as,target:this._onTarget,key:this._as==="keypress"?this.event:void 0,relativeTarget:this._onRelativeTarget}];this.parent.addDynamicTest({description:this._desc||"",level:this._level,orientation:this._orientation||"horizontal",action:s,assertions:i,...d.length?{setup:d}:{}});}};function ze(e,t){let l=new y(e);return t(l),new h(l.build())}exports.createContract=ze;
1
+ 'use strict';function o(e,t){return t==="first"?`first ${e}`:t==="last"?`last ${e}`:t==="next"?`next ${e}`:t==="previous"?`previous ${e}`:typeof t=="number"?`${e} at index ${t}`:`${t} ${e}`}var x={"comboboxpopup.open":{setup:[{when:["keyboard","textInput"],steps:()=>[{type:"keypress",target:"input",key:"ArrowDown"}]},{when:["pointer"],steps:()=>[{type:"click",target:"button"}]}],assertion:C},"comboboxpopup.closed":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:[...D(),...k()]},"main.focused":{setup:[{when:["keyboard","pointer"],steps:()=>[{type:"focus",target:"main"}]}],assertion:B},"main.blurred":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:F},"input.filled":{setup:[{when:["keyboard","textInput","pointer"],steps:()=>[{type:"type",target:"input",value:"test"}]}],assertion:I},"input.empty":{setup:[{when:["keyboard","textInput","pointer"],steps:()=>[{type:"type",target:"input",value:""}]}],assertion:$},"option.active":{requires:["comboboxpopup.open"],setup:[{when:["keyboard","pointer"],steps:(e={})=>typeof e.relativeTarget=="number"?Array.from({length:e.relativeTarget},()=>({type:"keypress",target:"main",key:"ArrowDown"})):e.relativeTarget==="first"?[{type:"keypress",target:"main",key:"ArrowDown"}]:e.relativeTarget==="last"?[{type:"keypress",target:"main",key:"ArrowDown"},{type:"keypress",target:"main",key:"ArrowUp"}]:[]}],assertion:(e={})=>V(e.relativeTarget)},"activedescendant.set":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:R},"activedescendant.unset":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:k},"option.selected":{requires:["comboboxpopup.open"],setup:[{when:["keyboard"],steps:(e={})=>[{type:"keypress",target:"relative",key:"Enter",relativeTarget:e.relativeTarget}]},{when:["pointer"],steps:(e={})=>[{type:"click",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>q(e.relativeTarget)}};function C(){return [{target:"popup",assertion:"toBeVisible",failureMessage:"Expected popup to be visible"},{target:"main",assertion:"toHaveAttribute",attribute:"aria-expanded",expectedValue:"true",failureMessage:"Expected combobox main to have aria-expanded='true'."}]}function D(){return [{target:"popup",assertion:"notToBeVisible",failureMessage:"Expected popup to be closed"},{target:"main",assertion:"toHaveAttribute",attribute:"aria-expanded",expectedValue:"false",failureMessage:"Expected combobox main to have aria-expanded='false'."}]}function V(e){return [{target:"main",assertion:"toHaveAttribute",attribute:"aria-activedescendant",expectedValue:{ref:"relative",relativeTarget:e,property:"id"},failureMessage:"Expected aria-activedescendant on main to match the id of the first relative item."}]}function R(){return [{target:"main",assertion:"toHaveAttribute",attribute:"aria-activedescendant",expectedValue:"!empty",failureMessage:"Expected aria-activedescendant on main to not be empty."}]}function k(){return [{target:"main",assertion:"toHaveAttribute",attribute:"aria-activedescendant",expectedValue:"",failureMessage:"Expected aria-activedescendant on main to be empty."}]}function q(e){return [{target:"relative",relativeTarget:e,assertion:"toHaveAttribute",attribute:"aria-selected",expectedValue:"true",failureMessage:`Expected ${o("option",e)} to have aria-selected='true'.`}]}function B(){return [{target:"main",assertion:"toHaveFocus",failureMessage:"Expected main to be focused."}]}function F(){return [{target:"main",assertion:"notToHaveFocus",failureMessage:"Expected main to not have focused."}]}function I(){return [{target:"input",assertion:"toHaveValue",expectedValue:"test",failureMessage:"Expected input to have the value 'test'."}]}function $(){return [{target:"input",assertion:"toHaveValue",expectedValue:"",failureMessage:"Expected input to have the value ''."}]}var A={"menupopup.open":{setup:[{when:["keyboard"],steps:()=>[{type:"keypress",target:"main",key:"Enter"}]},{when:["pointer"],steps:()=>[{type:"click",target:"main"}]}],assertion:P},"menupopup.closed":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:O},"main.focused":{setup:[{when:["keyboard","pointer"],steps:()=>[{type:"focus",target:"main"}]}],assertion:z},"main.blurred":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:L},"menuitem.focused":{requires:["menupopup.open"],setup:[{when:["keyboard"],steps:(e={})=>[{type:"focus",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>j(e.relativeTarget)},"submenupopup.open":{requires:["menupopup.open"],setup:[{when:["keyboard"],steps:()=>[{type:"keypress",target:"submenuTrigger",key:"ArrowRight"}]},{when:["pointer"],steps:()=>[{type:"click",target:"submenuTrigger"}]}],assertion:U},"submenupopup.closed":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:K},"submenutrigger.focused":{setup:[{when:["keyboard","pointer"],steps:()=>[{type:"focus",target:"submenuTrigger"}]}],assertion:J},"submenutrigger.blurred":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:G},"submenuitem.focused":{requires:["submenupopup.open"],setup:[{when:["keyboard","pointer"],steps:(e={})=>{let t=[];return typeof e.relativeTarget=="number"&&e.relativeTarget>1&&(t=t.concat(Array.from({length:e.relativeTarget-1},()=>({type:"keypress",target:"submenuItems",key:"ArrowDown"})))),e.relativeTarget==="last"&&(t=t.concat({type:"keypress",target:"submenuItems",key:"ArrowUp"})),t}}],assertion:(e={})=>X(e.relativeTarget)}};function P(){return [{target:"popup",assertion:"toBeVisible",failureMessage:"Expected popup to be visible"},{target:"main",assertion:"toHaveAttribute",attribute:"aria-expanded",expectedValue:"true",failureMessage:"Expected menu main to have aria-expanded='true'."}]}function O(){return [{target:"popup",assertion:"notToBeVisible",failureMessage:"Expected popup to be closed"},{target:"main",assertion:"toHaveAttribute",attribute:"aria-expanded",expectedValue:"false",failureMessage:"Expected menu main to have aria-expanded='false'."}]}function z(){return [{target:"main",assertion:"toHaveFocus",failureMessage:"Expected menu main to be focused."}]}function L(){return [{target:"main",assertion:"notToHaveFocus",failureMessage:"Expected menu main to not have focused."}]}function j(e){return [{target:"relative",assertion:"toHaveFocus",expectedValue:e,failureMessage:`${e} menu item should have focus.`}]}function U(){return [{target:"submenu",assertion:"toBeVisible",failureMessage:"Expected submenu to be visible"},{target:"submenuTrigger",assertion:"toHaveAttribute",attribute:"aria-expanded",expectedValue:"true",failureMessage:"Expected submenu trigger to have aria-expanded='true'."}]}function K(){return [{target:"submenu",assertion:"notToBeVisible",failureMessage:"Expected submenu to be closed"},{target:"submenuTrigger",assertion:"toHaveAttribute",attribute:"aria-expanded",expectedValue:"false",failureMessage:"Expected submenu trigger to have aria-expanded='false'."}]}function J(){return [{target:"submenuTrigger",assertion:"toHaveFocus",failureMessage:"Expected submenu trigger to be focused."}]}function G(){return [{target:"submenuTrigger",assertion:"notToHaveFocus",failureMessage:"Expected submenu trigger to not have focused."}]}function X(e){return [{target:"relative",relativeTarget:e,assertion:"toHaveFocus",failureMessage:`Expected submenu item ${e} to have focus.`}]}var w={"tab.active":{setup:[{when:["keyboard"],steps:(e={})=>[{type:"keypress",target:"relative",relativeTarget:e.relativeTarget,key:"ArrowLeft"}]},{when:["pointer"],steps:(e={})=>[{type:"click",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>Y(e.relativeTarget)},"tab.focused":{setup:[{when:["keyboard","pointer"],steps:(e={})=>[{type:"focus",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>N(e.relativeTarget)},"tab.blurred":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:(e={})=>W(e.relativeTarget)}};function N(e){return [{target:"relative",assertion:"toHaveFocus",relativeTarget:e,failureMessage:`Expected ${o("tab",e)} to have focus.`}]}function W(e){return [{target:"relative",assertion:"toHaveFocus",relativeTarget:e,failureMessage:`Expected ${o("tab",e)} not to have focus.`}]}function Q(e){return [{target:"relative",assertion:"toHaveAttribute",attribute:"aria-selected",expectedValue:"true",relativeTarget:e,failureMessage:`Expected ${o("tab",e)} to have tabindex='0'.`}]}function Y(e){return [{target:"relative",assertion:"toHaveAttribute",attribute:"aria-selected",expectedValue:"true",relativeTarget:e,failureMessage:`Expected ${o("tab",e)} to have aria-selected='true'.`},{target:"panel",assertion:"toBeVisible",controlledBy:{target:"relative",relativeTarget:e},failureMessage:`Expected panel controlled by the ${o("tab",e)} to be visible.`},Q(e)]}var S={"panel.expanded":{setup:[{when:["keyboard"],steps:e=>[{type:"keypress",target:"relative",relativeTarget:e.relativeTarget,key:"Enter"}]},{when:["pointer"],steps:e=>[{type:"click",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>Z(e.relativeTarget)},"panel.collapsed":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:(e={})=>ee(e.relativeTarget)},"trigger.focused":{setup:[{when:["keyboard","pointer"],steps:e=>[{type:"focus",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>te(e.relativeTarget)},"trigger.blurred":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:(e={})=>re(e.relativeTarget)}};function Z(e){return [{target:"panel",assertion:"toBeVisible",controlledBy:{target:"relative",relativeTarget:e},failureMessage:`Expected panel controlled by the ${e} trigger to be visible.`},{target:"relative",relativeTarget:e,assertion:"toHaveAttribute",attribute:"aria-expanded",expectedValue:"true",failureMessage:"Expected trigger to have aria-expanded='true' when panel expands."}]}function ee(e){return [{target:"panel",assertion:"notToBeVisible",controlledBy:{target:"relative",relativeTarget:e},failureMessage:`Expected panel controlled by the ${e} trigger not to be visible.`},{target:"relative",relativeTarget:e,assertion:"toHaveAttribute",attribute:"aria-expanded",expectedValue:"false",failureMessage:"Expected trigger to have aria-expanded='false' when panel collapses."}]}function te(e){return [{target:"relative",assertion:"toHaveFocus",relativeTarget:e,failureMessage:`Expected ${o("trigger",e)} to have focus.`}]}function re(e){return [{target:"relative",assertion:"toHaveFocus",relativeTarget:e,failureMessage:`Expected ${o("trigger",e)} not to have focus.`}]}var E={"radio.checked":{setup:[{when:["keyboard"],steps:e=>[{type:"keypress",target:"relative",relativeTarget:e.relativeTarget,key:"Space"}]},{when:["pointer"],steps:e=>[{type:"click",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>ie(e.relativeTarget)},"radio.unchecked":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:(e={})=>ae(e.relativeTarget)},"radio.focused":{setup:[{when:["keyboard","pointer"],steps:e=>[{type:"focus",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>se(e.relativeTarget)},"radio.blurred":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:(e={})=>ne(e.relativeTarget)}};function ie(e){return [{target:"relative",relativeTarget:e,assertion:"toHaveAttribute",attribute:"aria-checked",expectedValue:"true",failureMessage:"Expected radio to have aria-checked='true' when checked."}]}function ae(e){return [{target:"relative",relativeTarget:e,assertion:"toHaveAttribute",attribute:"aria-checked",expectedValue:"false",failureMessage:"Expected radio to have aria-checked='false' when unchecked."}]}function se(e){return [{target:"relative",assertion:"toHaveFocus",relativeTarget:e,failureMessage:`Expected ${o("radio",e)} to have focus.`}]}function ne(e){return [{target:"relative",assertion:"toHaveFocus",relativeTarget:e,failureMessage:`Expected ${o("radio",e)} not to have focus.`}]}var M={"checkbox.checked":{setup:[{when:["keyboard"],steps:e=>[{type:"keypress",target:"relative",relativeTarget:e.relativeTarget,key:"Space"}]},{when:["pointer"],steps:e=>[{type:"click",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>oe(e.relativeTarget)},"checkbox.unchecked":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:(e={})=>ue(e.relativeTarget)},"checkbox.focused":{setup:[{when:["keyboard","pointer"],steps:e=>[{type:"focus",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>pe(e.relativeTarget)},"checkbox.blurred":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:(e={})=>ce(e.relativeTarget)}};function oe(e){return [{target:"relative",relativeTarget:e,assertion:"toHaveAttribute",attribute:"aria-checked",expectedValue:"true",failureMessage:"Expected checkbox to have aria-checked='true' when checked."}]}function ue(e){return [{target:"relative",relativeTarget:e,assertion:"toHaveAttribute",attribute:"aria-checked",expectedValue:"false",failureMessage:"Expected checkbox to have aria-checked='false' when unchecked."}]}function pe(e){return [{target:"relative",assertion:"toHaveFocus",relativeTarget:e,failureMessage:`Expected ${o("checkbox",e)} to have focus.`}]}function ce(e){return [{target:"relative",assertion:"toHaveFocus",relativeTarget:e,failureMessage:`Expected ${o("checkbox",e)} not to have focus.`}]}var H={"toggle.pressed":{setup:[{when:["keyboard"],steps:e=>[{type:"keypress",target:"relative",relativeTarget:e.relativeTarget,key:"Enter"}]},{when:["pointer"],steps:e=>[{type:"click",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>le(e.relativeTarget)},"toggle.unpressed":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:(e={})=>ge(e.relativeTarget)},"toggle.focused":{setup:[{when:["keyboard","pointer"],steps:e=>[{type:"focus",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>de(e.relativeTarget)},"toggle.blurred":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:(e={})=>ve(e.relativeTarget)}};function le(e){return [{target:"relative",relativeTarget:e,assertion:"toHaveAttribute",attribute:"aria-pressed",expectedValue:"true",failureMessage:"Expected toggle to have aria-pressed='true' when pressed."}]}function ge(e){return [{target:"relative",relativeTarget:e,assertion:"toHaveAttribute",attribute:"aria-pressed",expectedValue:"false",failureMessage:"Expected toggle to have aria-pressed='false' when unpressed."}]}function de(e){return [{target:"relative",assertion:"toHaveFocus",relativeTarget:e,failureMessage:`Expected ${o("toggle",e)} to have focus.`}]}function ve(e){return [{target:"relative",assertion:"notToHaveFocus",relativeTarget:e,failureMessage:`Expected ${o("toggle",e)} not to have focus.`}]}function be(e,t){return t.some(l=>e.capabilities.includes(l))}function f(e,t){Array.isArray(e)&&e.length&&!e[0].when&&(e=[{when:["keyboard"],steps:()=>e}]);for(let l of e)if(be(t,l.when))return l.steps(t);throw new Error(`No setup strategy matches capabilities: ${t.capabilities.join(", ")}`)}var me={combobox:x,menu:A,tabs:w,accordion:S,radio:E,checkbox:M,toggle:H},h=class{constructor(t){this.jsonContract=t;}toJSON(){return this.jsonContract}},y=class{constructor(t){this.componentName=t;this.statePack=me[t]||{};}metaValue={};selectorsValue={};relationshipInvariants=[];staticAssertions=[];dynamicTests=[];statePack;meta(t){return this.metaValue=t,this}selectors(t){return this.selectorsValue=t,this}relationships(t){let l=this.statePack,u={capabilities:["keyboard"]},v=(n,i=new Set)=>{if(i.has(n))return [];i.add(n);let s=l[n];if(!s)return [];let r=[];if(Array.isArray(s.requires))for(let a of s.requires)r=r.concat(v(a,i));return s.setup&&(r=r.concat(f(s.setup,u))),r};return t({ariaReference:(n,i,s)=>({requires:r=>{let a=v(r,new Set);return {required:()=>this.relationshipInvariants.push({type:"aria-reference",from:n,attribute:i,to:s,level:"required",setup:a}),optional:()=>this.relationshipInvariants.push({type:"aria-reference",from:n,attribute:i,to:s,level:"optional",setup:a}),recommended:()=>this.relationshipInvariants.push({type:"aria-reference",from:n,attribute:i,to:s,level:"recommended",setup:a})}},required:()=>this.relationshipInvariants.push({type:"aria-reference",from:n,attribute:i,to:s,level:"required"}),optional:()=>this.relationshipInvariants.push({type:"aria-reference",from:n,attribute:i,to:s,level:"optional"}),recommended:()=>this.relationshipInvariants.push({type:"aria-reference",from:n,attribute:i,to:s,level:"recommended"})}),contains:(n,i)=>({requires:s=>{let r=v(s,new Set);return {required:()=>this.relationshipInvariants.push({type:"contains",parent:n,child:i,level:"required",setup:r}),optional:()=>this.relationshipInvariants.push({type:"contains",parent:n,child:i,level:"optional",setup:r}),recommended:()=>this.relationshipInvariants.push({type:"contains",parent:n,child:i,level:"recommended",setup:r})}},required:()=>this.relationshipInvariants.push({type:"contains",parent:n,child:i,level:"required"}),optional:()=>this.relationshipInvariants.push({type:"contains",parent:n,child:i,level:"optional"}),recommended:()=>this.relationshipInvariants.push({type:"contains",parent:n,child:i,level:"recommended"})})}),this}static(t){return t({target:u=>{let v=i=>{let s=this.statePack,r={capabilities:["keyboard"]},a=(p,c=new Set)=>{if(c.has(p))return [];c.add(p);let g=s[p];if(!g)return [];let b=[];if(Array.isArray(g.requires))for(let m of g.requires)b=b.concat(a(m,c));return g.setup&&(b=b.concat(f(g.setup,r))),b};return a(i,new Set)},d=i=>i==="role"?"toHaveRole":"toHaveAttribute",n=(i,s,r)=>{let a=d(i);return {required:()=>this.staticAssertions.push({target:u,assertion:a,attribute:i,expectedValue:s,failureMessage:"",level:"required",setup:r}),optional:()=>this.staticAssertions.push({target:u,assertion:a,attribute:i,expectedValue:s,failureMessage:"",level:"optional",setup:r}),recommended:()=>this.staticAssertions.push({target:u,assertion:a,attribute:i,expectedValue:s,failureMessage:"",level:"recommended",setup:r})}};return {has:(i,s)=>({...n(i,s),requires:a=>{let p=v(a);return n(i,s,p)}})}}}),this}when(t){return new T(this,this.statePack,t)}addDynamicTest(t){this.dynamicTests.push(t);}build(){return {meta:this.metaValue,selectors:this.selectorsValue,relationships:this.relationshipInvariants.length?this.relationshipInvariants:void 0,static:this.staticAssertions.length?this.staticAssertions:[],dynamic:this.dynamicTests}}},T=class{constructor(t,l,u){this.parent=t;this.statePack=l;this.event=u;}_as;_onTarget;_onRelativeTarget;_given=[];_then=[];_desc="";_level="required";_orientation;as(t){return this._as=t,this}on(t,l){return this._onTarget=t,this._onRelativeTarget=l,this}given(t){return this._given=this._normalizeStates(t),this}then(t){return this._then=this._normalizeStates(t),this}orientation(t){return this._orientation=t,this}_normalizeStates(t){return (Array.isArray(t)?t:[t]).flatMap(u=>typeof u=="string"?[u]:typeof u=="object"&&u!==null&&"type"in u&&"ref"in u?this._findStateKeyByTypeAndRef(u.type)?[{type:u.type,ref:u.ref}]:[]:[u])}_findStateKeyByTypeAndRef(t){if(Object.keys(this.statePack).includes(t))return t}describe(t){return this._desc=t,this}required(){return this._level="required",this._finalize(),this.parent}optional(){return this._level="optional",this._finalize(),this.parent}recommended(){return this._level="recommended",this._finalize(),this.parent}_finalize(){let u={capabilities:[{keypress:"keyboard",click:"pointer",type:"textInput",focus:"keyboard",hover:"pointer"}[this._as||"keyboard"]||this._as||"keyboard"]},v=(r,a=new Set,p)=>{if(a.has(r))return [];a.add(r);let c=this.statePack[r];if(!c)return [];let g=[];if(Array.isArray(c.requires))for(let b of c.requires)g=g.concat(v(b,a,p));if(c.setup){let b=c.setup.filter(m=>m.when.some(_=>u.capabilities.includes(_)));for(let m of b)typeof m.steps=="function"?g=g.concat(m.steps({relativeTarget:p})):g=g.concat(m.steps);}return g},d=[];for(let r of this._given)typeof r=="string"?d=d.concat(v(r,new Set)):typeof r=="object"&&r.type&&(d=d.concat(v(r.type,new Set,r.ref)));let n=new Set;d=d.filter(r=>{let a=[r.type,r.target,r.relativeTarget].join(":");return n.has(a)?false:(n.add(a),true)});let i=[];for(let r of this._then)if(typeof r=="string"){let a=this.statePack[r];if(a&&a.assertion!==void 0){let p=a.assertion;if(typeof p=="function")try{p=p();}catch(c){throw new Error(`Error calling assertion function for state '${r}': ${c.message}`)}Array.isArray(p)?i.push(...p):i.push(p);}}else if(typeof r=="object"&&r!==null&&"type"in r&&"ref"in r){let a=this._findStateKeyByTypeAndRef(r.type);if(a){let p=this.statePack[a];if(p&&p.assertion!==void 0){let c=p.assertion;if(typeof c=="function")try{c=c({relativeTarget:r.ref});}catch(g){throw new Error(`Error calling assertion function for state '${a}': ${g.message}`)}Array.isArray(c)?i.push(...c):i.push(c);}}}let s=[{type:this._as,target:this._onTarget,key:this._as==="keypress"?this.event:void 0,relativeTarget:this._onRelativeTarget}];this.parent.addDynamicTest({description:this._desc||"",level:this._level,orientation:this._orientation||"horizontal",action:s,assertions:i,...d.length?{setup:d}:{}});}};function ze(e,t){let l=new y(e);return t(l),new h(l.build())}exports.createContract=ze;
@@ -1 +1 @@
1
- function o(e,t){return t==="first"?`first ${e}`:t==="last"?`last ${e}`:t==="next"?`next ${e}`:t==="previous"?`previous ${e}`:typeof t=="number"?`${e} at index ${t}`:`${t} ${e}`}var x={"comboboxpopup.open":{setup:[{when:["keyboard","textInput","pointer"],steps:()=>[{type:"keypress",target:"input",key:"ArrowDown"}]},{when:["pointer"],steps:()=>[{type:"click",target:"button"}]}],assertion:C},"comboboxpopup.closed":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:[...D(),...k()]},"main.focused":{setup:[{when:["keyboard","pointer"],steps:()=>[{type:"focus",target:"main"}]}],assertion:B},"main.blurred":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:I},"input.filled":{setup:[{when:["keyboard","textInput","pointer"],steps:()=>[{type:"type",target:"input",value:"test"}]}],assertion:F},"input.empty":{setup:[{when:["keyboard","textInput","pointer"],steps:()=>[{type:"type",target:"input",value:""}]}],assertion:$},"option.active":{requires:["comboboxpopup.open"],setup:[{when:["keyboard","pointer"],steps:(e={})=>typeof e.relativeTarget=="number"?Array.from({length:e.relativeTarget},()=>({type:"keypress",target:"main",key:"ArrowDown"})):e.relativeTarget==="first"?[{type:"keypress",target:"main",key:"ArrowDown"}]:e.relativeTarget==="last"?[{type:"keypress",target:"main",key:"ArrowDown"},{type:"keypress",target:"main",key:"ArrowUp"}]:[]}],assertion:(e={})=>R(e.relativeTarget)},"activedescendant.set":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:V},"activedescendant.unset":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:k},"option.selected":{requires:["comboboxpopup.open"],setup:[{when:["keyboard"],steps:(e={})=>[{type:"keypress",target:"relative",key:"Enter",relativeTarget:e.relativeTarget}]},{when:["pointer"],steps:(e={})=>[{type:"click",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>q(e.relativeTarget)}};function C(){return [{target:"popup",assertion:"toBeVisible",failureMessage:"Expected popup to be visible"},{target:"main",assertion:"toHaveAttribute",attribute:"aria-expanded",expectedValue:"true",failureMessage:"Expected combobox main to have aria-expanded='true'."}]}function D(){return [{target:"popup",assertion:"notToBeVisible",failureMessage:"Expected popup to be closed"},{target:"main",assertion:"toHaveAttribute",attribute:"aria-expanded",expectedValue:"false",failureMessage:"Expected combobox main to have aria-expanded='false'."}]}function R(e){return [{target:"main",assertion:"toHaveAttribute",attribute:"aria-activedescendant",expectedValue:{ref:"relative",relativeTarget:e,property:"id"},failureMessage:"Expected aria-activedescendant on main to match the id of the first relative item."}]}function V(){return [{target:"main",assertion:"toHaveAttribute",attribute:"aria-activedescendant",expectedValue:"!empty",failureMessage:"Expected aria-activedescendant on main to not be empty."}]}function k(){return [{target:"main",assertion:"toHaveAttribute",attribute:"aria-activedescendant",expectedValue:"",failureMessage:"Expected aria-activedescendant on main to be empty."}]}function q(e){return [{target:"relative",relativeTarget:e,assertion:"toHaveAttribute",attribute:"aria-selected",expectedValue:"true",failureMessage:`Expected ${o("option",e)} to have aria-selected='true'.`}]}function B(){return [{target:"main",assertion:"toHaveFocus",failureMessage:"Expected main to be focused."}]}function I(){return [{target:"main",assertion:"notToHaveFocus",failureMessage:"Expected main to not have focused."}]}function F(){return [{target:"input",assertion:"toHaveValue",expectedValue:"test",failureMessage:"Expected input to have the value 'test'."}]}function $(){return [{target:"input",assertion:"toHaveValue",expectedValue:"",failureMessage:"Expected input to have the value ''."}]}var A={"menupopup.open":{setup:[{when:["keyboard"],steps:()=>[{type:"keypress",target:"main",key:"Enter"}]},{when:["pointer"],steps:()=>[{type:"click",target:"main"}]}],assertion:P},"menupopup.closed":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:O},"main.focused":{setup:[{when:["keyboard","pointer"],steps:()=>[{type:"focus",target:"main"}]}],assertion:z},"main.blurred":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:L},"menuitem.focused":{requires:["menupopup.open"],setup:[{when:["keyboard"],steps:(e={})=>[{type:"focus",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>j(e.relativeTarget)},"submenupopup.open":{requires:["menupopup.open"],setup:[{when:["keyboard"],steps:()=>[{type:"keypress",target:"submenuTrigger",key:"ArrowRight"}]},{when:["pointer"],steps:()=>[{type:"click",target:"submenuTrigger"}]}],assertion:U},"submenupopup.closed":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:K},"submenutrigger.focused":{setup:[{when:["keyboard","pointer"],steps:()=>[{type:"focus",target:"submenuTrigger"}]}],assertion:J},"submenutrigger.blurred":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:G},"submenuitem.focused":{requires:["submenupopup.open"],setup:[{when:["keyboard"],steps:(e={})=>{let t=[{type:"focus",target:"submenuTrigger"},{type:"keypress",target:"submenuTrigger",key:"ArrowRight"}];return typeof e.relativeTarget=="number"&&(t=t.concat(Array.from({length:e.relativeTarget},()=>({type:"keypress",target:"submenuItems",key:"ArrowDown"})))),e.relativeTarget==="first"&&(t=t.concat({type:"keypress",target:"submenuItems",key:"ArrowDown"})),e.relativeTarget==="last"&&(t=t.concat({type:"keypress",target:"submenuItems",key:"ArrowUp"})),t}},{when:["pointer"],steps:(e={})=>[{type:"click",target:"submenuTrigger"},{type:"click",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>X(e.relativeTarget)}};function P(){return [{target:"popup",assertion:"toBeVisible",failureMessage:"Expected popup to be visible"},{target:"main",assertion:"toHaveAttribute",attribute:"aria-expanded",expectedValue:"true",failureMessage:"Expected menu main to have aria-expanded='true'."}]}function O(){return [{target:"popup",assertion:"notToBeVisible",failureMessage:"Expected popup to be closed"},{target:"main",assertion:"toHaveAttribute",attribute:"aria-expanded",expectedValue:"false",failureMessage:"Expected menu main to have aria-expanded='false'."}]}function z(){return [{target:"main",assertion:"toHaveFocus",failureMessage:"Expected menu main to be focused."}]}function L(){return [{target:"main",assertion:"notToHaveFocus",failureMessage:"Expected menu main to not have focused."}]}function j(e){return [{target:"relative",assertion:"toHaveFocus",expectedValue:e,failureMessage:`${e} menu item should have focus.`}]}function U(){return [{target:"submenu",assertion:"toBeVisible",failureMessage:"Expected submenu to be visible"},{target:"submenuTrigger",assertion:"toHaveAttribute",attribute:"aria-expanded",expectedValue:"true",failureMessage:"Expected submenu trigger to have aria-expanded='true'."}]}function K(){return [{target:"submenu",assertion:"notToBeVisible",failureMessage:"Expected submenu to be closed"},{target:"submenuTrigger",assertion:"toHaveAttribute",attribute:"aria-expanded",expectedValue:"false",failureMessage:"Expected submenu trigger to have aria-expanded='false'."}]}function J(){return [{target:"submenuTrigger",assertion:"toHaveFocus",failureMessage:"Expected submenu trigger to be focused."}]}function G(){return [{target:"submenuTrigger",assertion:"notToHaveFocus",failureMessage:"Expected submenu trigger to not have focused."}]}function X(e){return [{target:"relative",relativeTarget:e,assertion:"toHaveFocus",failureMessage:`Expected submenu item ${e} to have focus.`}]}var w={"tab.active":{setup:[{when:["keyboard"],steps:(e={})=>[{type:"keypress",target:"relative",relativeTarget:e.relativeTarget,key:"ArrowLeft"}]},{when:["pointer"],steps:(e={})=>[{type:"click",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>Y(e.relativeTarget)},"tab.focused":{setup:[{when:["keyboard","pointer"],steps:(e={})=>[{type:"focus",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>N(e.relativeTarget)},"tab.blurred":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:(e={})=>W(e.relativeTarget)}};function N(e){return [{target:"relative",assertion:"toHaveFocus",relativeTarget:e,failureMessage:`Expected ${o("tab",e)} to have focus.`}]}function W(e){return [{target:"relative",assertion:"toHaveFocus",relativeTarget:e,failureMessage:`Expected ${o("tab",e)} not to have focus.`}]}function Q(e){return [{target:"relative",assertion:"toHaveAttribute",attribute:"aria-selected",expectedValue:"true",relativeTarget:e,failureMessage:`Expected ${o("tab",e)} to have tabindex='0'.`}]}function Y(e){return [{target:"relative",assertion:"toHaveAttribute",attribute:"aria-selected",expectedValue:"true",relativeTarget:e,failureMessage:`Expected ${o("tab",e)} to have aria-selected='true'.`},{target:"panel",assertion:"toBeVisible",controlledBy:{target:"relative",relativeTarget:e},failureMessage:`Expected panel controlled by the ${o("tab",e)} to be visible.`},Q(e)]}var S={"panel.expanded":{setup:[{when:["keyboard"],steps:e=>[{type:"keypress",target:"relative",relativeTarget:e.relativeTarget,key:"Enter"}]},{when:["pointer"],steps:e=>[{type:"click",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>Z(e.relativeTarget)},"panel.collapsed":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:(e={})=>ee(e.relativeTarget)},"trigger.focused":{setup:[{when:["keyboard","pointer"],steps:e=>[{type:"focus",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>te(e.relativeTarget)},"trigger.blurred":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:(e={})=>re(e.relativeTarget)}};function Z(e){return [{target:"panel",assertion:"toBeVisible",controlledBy:{target:"relative",relativeTarget:e},failureMessage:`Expected panel controlled by the ${e} trigger to be visible.`},{target:"relative",relativeTarget:e,assertion:"toHaveAttribute",attribute:"aria-expanded",expectedValue:"true",failureMessage:"Expected trigger to have aria-expanded='true' when panel expands."}]}function ee(e){return [{target:"panel",assertion:"notToBeVisible",controlledBy:{target:"relative",relativeTarget:e},failureMessage:`Expected panel controlled by the ${e} trigger not to be visible.`},{target:"relative",relativeTarget:e,assertion:"toHaveAttribute",attribute:"aria-expanded",expectedValue:"false",failureMessage:"Expected trigger to have aria-expanded='false' when panel collapses."}]}function te(e){return [{target:"relative",assertion:"toHaveFocus",relativeTarget:e,failureMessage:`Expected ${o("trigger",e)} to have focus.`}]}function re(e){return [{target:"relative",assertion:"toHaveFocus",relativeTarget:e,failureMessage:`Expected ${o("trigger",e)} not to have focus.`}]}var E={"radio.checked":{setup:[{when:["keyboard"],steps:e=>[{type:"keypress",target:"relative",relativeTarget:e.relativeTarget,key:"Space"}]},{when:["pointer"],steps:e=>[{type:"click",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>ie(e.relativeTarget)},"radio.unchecked":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:(e={})=>ae(e.relativeTarget)},"radio.focused":{setup:[{when:["keyboard","pointer"],steps:e=>[{type:"focus",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>se(e.relativeTarget)},"radio.blurred":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:(e={})=>ne(e.relativeTarget)}};function ie(e){return [{target:"relative",relativeTarget:e,assertion:"toHaveAttribute",attribute:"aria-checked",expectedValue:"true",failureMessage:"Expected radio to have aria-checked='true' when checked."}]}function ae(e){return [{target:"relative",relativeTarget:e,assertion:"toHaveAttribute",attribute:"aria-checked",expectedValue:"false",failureMessage:"Expected radio to have aria-checked='false' when unchecked."}]}function se(e){return [{target:"relative",assertion:"toHaveFocus",relativeTarget:e,failureMessage:`Expected ${o("radio",e)} to have focus.`}]}function ne(e){return [{target:"relative",assertion:"toHaveFocus",relativeTarget:e,failureMessage:`Expected ${o("radio",e)} not to have focus.`}]}var M={"checkbox.checked":{setup:[{when:["keyboard"],steps:e=>[{type:"keypress",target:"relative",relativeTarget:e.relativeTarget,key:"Space"}]},{when:["pointer"],steps:e=>[{type:"click",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>oe(e.relativeTarget)},"checkbox.unchecked":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:(e={})=>ue(e.relativeTarget)},"checkbox.focused":{setup:[{when:["keyboard","pointer"],steps:e=>[{type:"focus",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>pe(e.relativeTarget)},"checkbox.blurred":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:(e={})=>ce(e.relativeTarget)}};function oe(e){return [{target:"relative",relativeTarget:e,assertion:"toHaveAttribute",attribute:"aria-checked",expectedValue:"true",failureMessage:"Expected checkbox to have aria-checked='true' when checked."}]}function ue(e){return [{target:"relative",relativeTarget:e,assertion:"toHaveAttribute",attribute:"aria-checked",expectedValue:"false",failureMessage:"Expected checkbox to have aria-checked='false' when unchecked."}]}function pe(e){return [{target:"relative",assertion:"toHaveFocus",relativeTarget:e,failureMessage:`Expected ${o("checkbox",e)} to have focus.`}]}function ce(e){return [{target:"relative",assertion:"toHaveFocus",relativeTarget:e,failureMessage:`Expected ${o("checkbox",e)} not to have focus.`}]}var H={"toggle.pressed":{setup:[{when:["keyboard"],steps:e=>[{type:"keypress",target:"relative",relativeTarget:e.relativeTarget,key:"Enter"}]},{when:["pointer"],steps:e=>[{type:"click",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>le(e.relativeTarget)},"toggle.unpressed":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:(e={})=>ge(e.relativeTarget)},"toggle.focused":{setup:[{when:["keyboard","pointer"],steps:e=>[{type:"focus",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>de(e.relativeTarget)},"toggle.blurred":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:(e={})=>ve(e.relativeTarget)}};function le(e){return [{target:"relative",relativeTarget:e,assertion:"toHaveAttribute",attribute:"aria-pressed",expectedValue:"true",failureMessage:"Expected toggle to have aria-pressed='true' when pressed."}]}function ge(e){return [{target:"relative",relativeTarget:e,assertion:"toHaveAttribute",attribute:"aria-pressed",expectedValue:"false",failureMessage:"Expected toggle to have aria-pressed='false' when unpressed."}]}function de(e){return [{target:"relative",assertion:"toHaveFocus",relativeTarget:e,failureMessage:`Expected ${o("toggle",e)} to have focus.`}]}function ve(e){return [{target:"relative",assertion:"notToHaveFocus",relativeTarget:e,failureMessage:`Expected ${o("toggle",e)} not to have focus.`}]}function be(e,t){return t.some(l=>e.capabilities.includes(l))}function f(e,t){Array.isArray(e)&&e.length&&!e[0].when&&(e=[{when:["keyboard"],steps:()=>e}]);for(let l of e)if(be(t,l.when))return l.steps(t);throw new Error(`No setup strategy matches capabilities: ${t.capabilities.join(", ")}`)}var me={combobox:x,menu:A,tabs:w,accordion:S,radio:E,checkbox:M,toggle:H},h=class{constructor(t){this.jsonContract=t;}toJSON(){return this.jsonContract}},y=class{constructor(t){this.componentName=t;this.statePack=me[t]||{};}metaValue={};selectorsValue={};relationshipInvariants=[];staticAssertions=[];dynamicTests=[];statePack;meta(t){return this.metaValue=t,this}selectors(t){return this.selectorsValue=t,this}relationships(t){let l=this.statePack,u={capabilities:["keyboard"]},v=(n,i=new Set)=>{if(i.has(n))return [];i.add(n);let s=l[n];if(!s)return [];let r=[];if(Array.isArray(s.requires))for(let a of s.requires)r=r.concat(v(a,i));return s.setup&&(r=r.concat(f(s.setup,u))),r};return t({ariaReference:(n,i,s)=>({requires:r=>{let a=v(r,new Set);return {required:()=>this.relationshipInvariants.push({type:"aria-reference",from:n,attribute:i,to:s,level:"required",setup:a}),optional:()=>this.relationshipInvariants.push({type:"aria-reference",from:n,attribute:i,to:s,level:"optional",setup:a}),recommended:()=>this.relationshipInvariants.push({type:"aria-reference",from:n,attribute:i,to:s,level:"recommended",setup:a})}},required:()=>this.relationshipInvariants.push({type:"aria-reference",from:n,attribute:i,to:s,level:"required"}),optional:()=>this.relationshipInvariants.push({type:"aria-reference",from:n,attribute:i,to:s,level:"optional"}),recommended:()=>this.relationshipInvariants.push({type:"aria-reference",from:n,attribute:i,to:s,level:"recommended"})}),contains:(n,i)=>({requires:s=>{let r=v(s,new Set);return {required:()=>this.relationshipInvariants.push({type:"contains",parent:n,child:i,level:"required",setup:r}),optional:()=>this.relationshipInvariants.push({type:"contains",parent:n,child:i,level:"optional",setup:r}),recommended:()=>this.relationshipInvariants.push({type:"contains",parent:n,child:i,level:"recommended",setup:r})}},required:()=>this.relationshipInvariants.push({type:"contains",parent:n,child:i,level:"required"}),optional:()=>this.relationshipInvariants.push({type:"contains",parent:n,child:i,level:"optional"}),recommended:()=>this.relationshipInvariants.push({type:"contains",parent:n,child:i,level:"recommended"})})}),this}static(t){return t({target:u=>{let v=i=>{let s=this.statePack,r={capabilities:["keyboard"]},a=(p,c=new Set)=>{if(c.has(p))return [];c.add(p);let g=s[p];if(!g)return [];let b=[];if(Array.isArray(g.requires))for(let m of g.requires)b=b.concat(a(m,c));return g.setup&&(b=b.concat(f(g.setup,r))),b};return a(i,new Set)},d=i=>i==="role"?"toHaveRole":"toHaveAttribute",n=(i,s,r)=>{let a=d(i);return {required:()=>this.staticAssertions.push({target:u,assertion:a,attribute:i,expectedValue:s,failureMessage:"",level:"required",setup:r}),optional:()=>this.staticAssertions.push({target:u,assertion:a,attribute:i,expectedValue:s,failureMessage:"",level:"optional",setup:r}),recommended:()=>this.staticAssertions.push({target:u,assertion:a,attribute:i,expectedValue:s,failureMessage:"",level:"recommended",setup:r})}};return {has:(i,s)=>({...n(i,s),requires:a=>{let p=v(a);return n(i,s,p)}})}}}),this}when(t){return new T(this,this.statePack,t)}addDynamicTest(t){this.dynamicTests.push(t);}build(){return {meta:this.metaValue,selectors:this.selectorsValue,relationships:this.relationshipInvariants.length?this.relationshipInvariants:void 0,static:this.staticAssertions.length?this.staticAssertions:[],dynamic:this.dynamicTests}}},T=class{constructor(t,l,u){this.parent=t;this.statePack=l;this.event=u;}_as;_onTarget;_onRelativeTarget;_given=[];_then=[];_desc="";_level="required";_orientation;as(t){return this._as=t,this}on(t,l){return this._onTarget=t,this._onRelativeTarget=l,this}given(t){return this._given=this._normalizeStates(t),this}then(t){return this._then=this._normalizeStates(t),this}orientation(t){return this._orientation=t,this}_normalizeStates(t){return (Array.isArray(t)?t:[t]).flatMap(u=>typeof u=="string"?[u]:typeof u=="object"&&u!==null&&"type"in u&&"ref"in u?this._findStateKeyByTypeAndRef(u.type)?[{type:u.type,ref:u.ref}]:[]:[u])}_findStateKeyByTypeAndRef(t){if(Object.keys(this.statePack).includes(t))return t}describe(t){return this._desc=t,this}required(){return this._level="required",this._finalize(),this.parent}optional(){return this._level="optional",this._finalize(),this.parent}recommended(){return this._level="recommended",this._finalize(),this.parent}_finalize(){let u={capabilities:[{keypress:"keyboard",click:"pointer",type:"textInput",focus:"keyboard",hover:"pointer"}[this._as||"keyboard"]||this._as||"keyboard"]},v=(r,a=new Set,p)=>{if(a.has(r))return [];a.add(r);let c=this.statePack[r];if(!c)return [];let g=[];if(Array.isArray(c.requires))for(let b of c.requires)g=g.concat(v(b,a,p));if(c.setup){let b=c.setup.filter(m=>m.when.some(_=>u.capabilities.includes(_)));for(let m of b)typeof m.steps=="function"?g=g.concat(m.steps({relativeTarget:p})):g=g.concat(m.steps);}return g},d=[];for(let r of this._given)typeof r=="string"?d=d.concat(v(r,new Set)):typeof r=="object"&&r.type&&(d=d.concat(v(r.type,new Set,r.ref)));let n=new Set;d=d.filter(r=>{let a=[r.type,r.target,r.relativeTarget].join(":");return n.has(a)?false:(n.add(a),true)});let i=[];for(let r of this._then)if(typeof r=="string"){let a=this.statePack[r];if(a&&a.assertion!==void 0){let p=a.assertion;if(typeof p=="function")try{p=p();}catch(c){throw new Error(`Error calling assertion function for state '${r}': ${c.message}`)}Array.isArray(p)?i.push(...p):i.push(p);}}else if(typeof r=="object"&&r!==null&&"type"in r&&"ref"in r){let a=this._findStateKeyByTypeAndRef(r.type);if(a){let p=this.statePack[a];if(p&&p.assertion!==void 0){let c=p.assertion;if(typeof c=="function")try{c=c({relativeTarget:r.ref});}catch(g){throw new Error(`Error calling assertion function for state '${a}': ${g.message}`)}Array.isArray(c)?i.push(...c):i.push(c);}}}let s=[{type:this._as,target:this._onTarget,key:this._as==="keypress"?this.event:void 0,relativeTarget:this._onRelativeTarget}];this.parent.addDynamicTest({description:this._desc||"",level:this._level,orientation:this._orientation||"horizontal",action:s,assertions:i,...d.length?{setup:d}:{}});}};function ze(e,t){let l=new y(e);return t(l),new h(l.build())}export{ze as createContract};
1
+ function o(e,t){return t==="first"?`first ${e}`:t==="last"?`last ${e}`:t==="next"?`next ${e}`:t==="previous"?`previous ${e}`:typeof t=="number"?`${e} at index ${t}`:`${t} ${e}`}var x={"comboboxpopup.open":{setup:[{when:["keyboard","textInput"],steps:()=>[{type:"keypress",target:"input",key:"ArrowDown"}]},{when:["pointer"],steps:()=>[{type:"click",target:"button"}]}],assertion:C},"comboboxpopup.closed":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:[...D(),...k()]},"main.focused":{setup:[{when:["keyboard","pointer"],steps:()=>[{type:"focus",target:"main"}]}],assertion:B},"main.blurred":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:F},"input.filled":{setup:[{when:["keyboard","textInput","pointer"],steps:()=>[{type:"type",target:"input",value:"test"}]}],assertion:I},"input.empty":{setup:[{when:["keyboard","textInput","pointer"],steps:()=>[{type:"type",target:"input",value:""}]}],assertion:$},"option.active":{requires:["comboboxpopup.open"],setup:[{when:["keyboard","pointer"],steps:(e={})=>typeof e.relativeTarget=="number"?Array.from({length:e.relativeTarget},()=>({type:"keypress",target:"main",key:"ArrowDown"})):e.relativeTarget==="first"?[{type:"keypress",target:"main",key:"ArrowDown"}]:e.relativeTarget==="last"?[{type:"keypress",target:"main",key:"ArrowDown"},{type:"keypress",target:"main",key:"ArrowUp"}]:[]}],assertion:(e={})=>V(e.relativeTarget)},"activedescendant.set":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:R},"activedescendant.unset":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:k},"option.selected":{requires:["comboboxpopup.open"],setup:[{when:["keyboard"],steps:(e={})=>[{type:"keypress",target:"relative",key:"Enter",relativeTarget:e.relativeTarget}]},{when:["pointer"],steps:(e={})=>[{type:"click",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>q(e.relativeTarget)}};function C(){return [{target:"popup",assertion:"toBeVisible",failureMessage:"Expected popup to be visible"},{target:"main",assertion:"toHaveAttribute",attribute:"aria-expanded",expectedValue:"true",failureMessage:"Expected combobox main to have aria-expanded='true'."}]}function D(){return [{target:"popup",assertion:"notToBeVisible",failureMessage:"Expected popup to be closed"},{target:"main",assertion:"toHaveAttribute",attribute:"aria-expanded",expectedValue:"false",failureMessage:"Expected combobox main to have aria-expanded='false'."}]}function V(e){return [{target:"main",assertion:"toHaveAttribute",attribute:"aria-activedescendant",expectedValue:{ref:"relative",relativeTarget:e,property:"id"},failureMessage:"Expected aria-activedescendant on main to match the id of the first relative item."}]}function R(){return [{target:"main",assertion:"toHaveAttribute",attribute:"aria-activedescendant",expectedValue:"!empty",failureMessage:"Expected aria-activedescendant on main to not be empty."}]}function k(){return [{target:"main",assertion:"toHaveAttribute",attribute:"aria-activedescendant",expectedValue:"",failureMessage:"Expected aria-activedescendant on main to be empty."}]}function q(e){return [{target:"relative",relativeTarget:e,assertion:"toHaveAttribute",attribute:"aria-selected",expectedValue:"true",failureMessage:`Expected ${o("option",e)} to have aria-selected='true'.`}]}function B(){return [{target:"main",assertion:"toHaveFocus",failureMessage:"Expected main to be focused."}]}function F(){return [{target:"main",assertion:"notToHaveFocus",failureMessage:"Expected main to not have focused."}]}function I(){return [{target:"input",assertion:"toHaveValue",expectedValue:"test",failureMessage:"Expected input to have the value 'test'."}]}function $(){return [{target:"input",assertion:"toHaveValue",expectedValue:"",failureMessage:"Expected input to have the value ''."}]}var A={"menupopup.open":{setup:[{when:["keyboard"],steps:()=>[{type:"keypress",target:"main",key:"Enter"}]},{when:["pointer"],steps:()=>[{type:"click",target:"main"}]}],assertion:P},"menupopup.closed":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:O},"main.focused":{setup:[{when:["keyboard","pointer"],steps:()=>[{type:"focus",target:"main"}]}],assertion:z},"main.blurred":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:L},"menuitem.focused":{requires:["menupopup.open"],setup:[{when:["keyboard"],steps:(e={})=>[{type:"focus",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>j(e.relativeTarget)},"submenupopup.open":{requires:["menupopup.open"],setup:[{when:["keyboard"],steps:()=>[{type:"keypress",target:"submenuTrigger",key:"ArrowRight"}]},{when:["pointer"],steps:()=>[{type:"click",target:"submenuTrigger"}]}],assertion:U},"submenupopup.closed":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:K},"submenutrigger.focused":{setup:[{when:["keyboard","pointer"],steps:()=>[{type:"focus",target:"submenuTrigger"}]}],assertion:J},"submenutrigger.blurred":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:G},"submenuitem.focused":{requires:["submenupopup.open"],setup:[{when:["keyboard","pointer"],steps:(e={})=>{let t=[];return typeof e.relativeTarget=="number"&&e.relativeTarget>1&&(t=t.concat(Array.from({length:e.relativeTarget-1},()=>({type:"keypress",target:"submenuItems",key:"ArrowDown"})))),e.relativeTarget==="last"&&(t=t.concat({type:"keypress",target:"submenuItems",key:"ArrowUp"})),t}}],assertion:(e={})=>X(e.relativeTarget)}};function P(){return [{target:"popup",assertion:"toBeVisible",failureMessage:"Expected popup to be visible"},{target:"main",assertion:"toHaveAttribute",attribute:"aria-expanded",expectedValue:"true",failureMessage:"Expected menu main to have aria-expanded='true'."}]}function O(){return [{target:"popup",assertion:"notToBeVisible",failureMessage:"Expected popup to be closed"},{target:"main",assertion:"toHaveAttribute",attribute:"aria-expanded",expectedValue:"false",failureMessage:"Expected menu main to have aria-expanded='false'."}]}function z(){return [{target:"main",assertion:"toHaveFocus",failureMessage:"Expected menu main to be focused."}]}function L(){return [{target:"main",assertion:"notToHaveFocus",failureMessage:"Expected menu main to not have focused."}]}function j(e){return [{target:"relative",assertion:"toHaveFocus",expectedValue:e,failureMessage:`${e} menu item should have focus.`}]}function U(){return [{target:"submenu",assertion:"toBeVisible",failureMessage:"Expected submenu to be visible"},{target:"submenuTrigger",assertion:"toHaveAttribute",attribute:"aria-expanded",expectedValue:"true",failureMessage:"Expected submenu trigger to have aria-expanded='true'."}]}function K(){return [{target:"submenu",assertion:"notToBeVisible",failureMessage:"Expected submenu to be closed"},{target:"submenuTrigger",assertion:"toHaveAttribute",attribute:"aria-expanded",expectedValue:"false",failureMessage:"Expected submenu trigger to have aria-expanded='false'."}]}function J(){return [{target:"submenuTrigger",assertion:"toHaveFocus",failureMessage:"Expected submenu trigger to be focused."}]}function G(){return [{target:"submenuTrigger",assertion:"notToHaveFocus",failureMessage:"Expected submenu trigger to not have focused."}]}function X(e){return [{target:"relative",relativeTarget:e,assertion:"toHaveFocus",failureMessage:`Expected submenu item ${e} to have focus.`}]}var w={"tab.active":{setup:[{when:["keyboard"],steps:(e={})=>[{type:"keypress",target:"relative",relativeTarget:e.relativeTarget,key:"ArrowLeft"}]},{when:["pointer"],steps:(e={})=>[{type:"click",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>Y(e.relativeTarget)},"tab.focused":{setup:[{when:["keyboard","pointer"],steps:(e={})=>[{type:"focus",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>N(e.relativeTarget)},"tab.blurred":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:(e={})=>W(e.relativeTarget)}};function N(e){return [{target:"relative",assertion:"toHaveFocus",relativeTarget:e,failureMessage:`Expected ${o("tab",e)} to have focus.`}]}function W(e){return [{target:"relative",assertion:"toHaveFocus",relativeTarget:e,failureMessage:`Expected ${o("tab",e)} not to have focus.`}]}function Q(e){return [{target:"relative",assertion:"toHaveAttribute",attribute:"aria-selected",expectedValue:"true",relativeTarget:e,failureMessage:`Expected ${o("tab",e)} to have tabindex='0'.`}]}function Y(e){return [{target:"relative",assertion:"toHaveAttribute",attribute:"aria-selected",expectedValue:"true",relativeTarget:e,failureMessage:`Expected ${o("tab",e)} to have aria-selected='true'.`},{target:"panel",assertion:"toBeVisible",controlledBy:{target:"relative",relativeTarget:e},failureMessage:`Expected panel controlled by the ${o("tab",e)} to be visible.`},Q(e)]}var S={"panel.expanded":{setup:[{when:["keyboard"],steps:e=>[{type:"keypress",target:"relative",relativeTarget:e.relativeTarget,key:"Enter"}]},{when:["pointer"],steps:e=>[{type:"click",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>Z(e.relativeTarget)},"panel.collapsed":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:(e={})=>ee(e.relativeTarget)},"trigger.focused":{setup:[{when:["keyboard","pointer"],steps:e=>[{type:"focus",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>te(e.relativeTarget)},"trigger.blurred":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:(e={})=>re(e.relativeTarget)}};function Z(e){return [{target:"panel",assertion:"toBeVisible",controlledBy:{target:"relative",relativeTarget:e},failureMessage:`Expected panel controlled by the ${e} trigger to be visible.`},{target:"relative",relativeTarget:e,assertion:"toHaveAttribute",attribute:"aria-expanded",expectedValue:"true",failureMessage:"Expected trigger to have aria-expanded='true' when panel expands."}]}function ee(e){return [{target:"panel",assertion:"notToBeVisible",controlledBy:{target:"relative",relativeTarget:e},failureMessage:`Expected panel controlled by the ${e} trigger not to be visible.`},{target:"relative",relativeTarget:e,assertion:"toHaveAttribute",attribute:"aria-expanded",expectedValue:"false",failureMessage:"Expected trigger to have aria-expanded='false' when panel collapses."}]}function te(e){return [{target:"relative",assertion:"toHaveFocus",relativeTarget:e,failureMessage:`Expected ${o("trigger",e)} to have focus.`}]}function re(e){return [{target:"relative",assertion:"toHaveFocus",relativeTarget:e,failureMessage:`Expected ${o("trigger",e)} not to have focus.`}]}var E={"radio.checked":{setup:[{when:["keyboard"],steps:e=>[{type:"keypress",target:"relative",relativeTarget:e.relativeTarget,key:"Space"}]},{when:["pointer"],steps:e=>[{type:"click",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>ie(e.relativeTarget)},"radio.unchecked":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:(e={})=>ae(e.relativeTarget)},"radio.focused":{setup:[{when:["keyboard","pointer"],steps:e=>[{type:"focus",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>se(e.relativeTarget)},"radio.blurred":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:(e={})=>ne(e.relativeTarget)}};function ie(e){return [{target:"relative",relativeTarget:e,assertion:"toHaveAttribute",attribute:"aria-checked",expectedValue:"true",failureMessage:"Expected radio to have aria-checked='true' when checked."}]}function ae(e){return [{target:"relative",relativeTarget:e,assertion:"toHaveAttribute",attribute:"aria-checked",expectedValue:"false",failureMessage:"Expected radio to have aria-checked='false' when unchecked."}]}function se(e){return [{target:"relative",assertion:"toHaveFocus",relativeTarget:e,failureMessage:`Expected ${o("radio",e)} to have focus.`}]}function ne(e){return [{target:"relative",assertion:"toHaveFocus",relativeTarget:e,failureMessage:`Expected ${o("radio",e)} not to have focus.`}]}var M={"checkbox.checked":{setup:[{when:["keyboard"],steps:e=>[{type:"keypress",target:"relative",relativeTarget:e.relativeTarget,key:"Space"}]},{when:["pointer"],steps:e=>[{type:"click",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>oe(e.relativeTarget)},"checkbox.unchecked":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:(e={})=>ue(e.relativeTarget)},"checkbox.focused":{setup:[{when:["keyboard","pointer"],steps:e=>[{type:"focus",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>pe(e.relativeTarget)},"checkbox.blurred":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:(e={})=>ce(e.relativeTarget)}};function oe(e){return [{target:"relative",relativeTarget:e,assertion:"toHaveAttribute",attribute:"aria-checked",expectedValue:"true",failureMessage:"Expected checkbox to have aria-checked='true' when checked."}]}function ue(e){return [{target:"relative",relativeTarget:e,assertion:"toHaveAttribute",attribute:"aria-checked",expectedValue:"false",failureMessage:"Expected checkbox to have aria-checked='false' when unchecked."}]}function pe(e){return [{target:"relative",assertion:"toHaveFocus",relativeTarget:e,failureMessage:`Expected ${o("checkbox",e)} to have focus.`}]}function ce(e){return [{target:"relative",assertion:"toHaveFocus",relativeTarget:e,failureMessage:`Expected ${o("checkbox",e)} not to have focus.`}]}var H={"toggle.pressed":{setup:[{when:["keyboard"],steps:e=>[{type:"keypress",target:"relative",relativeTarget:e.relativeTarget,key:"Enter"}]},{when:["pointer"],steps:e=>[{type:"click",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>le(e.relativeTarget)},"toggle.unpressed":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:(e={})=>ge(e.relativeTarget)},"toggle.focused":{setup:[{when:["keyboard","pointer"],steps:e=>[{type:"focus",target:"relative",relativeTarget:e.relativeTarget}]}],assertion:(e={})=>de(e.relativeTarget)},"toggle.blurred":{setup:[{when:["keyboard","pointer"],steps:()=>[]}],assertion:(e={})=>ve(e.relativeTarget)}};function le(e){return [{target:"relative",relativeTarget:e,assertion:"toHaveAttribute",attribute:"aria-pressed",expectedValue:"true",failureMessage:"Expected toggle to have aria-pressed='true' when pressed."}]}function ge(e){return [{target:"relative",relativeTarget:e,assertion:"toHaveAttribute",attribute:"aria-pressed",expectedValue:"false",failureMessage:"Expected toggle to have aria-pressed='false' when unpressed."}]}function de(e){return [{target:"relative",assertion:"toHaveFocus",relativeTarget:e,failureMessage:`Expected ${o("toggle",e)} to have focus.`}]}function ve(e){return [{target:"relative",assertion:"notToHaveFocus",relativeTarget:e,failureMessage:`Expected ${o("toggle",e)} not to have focus.`}]}function be(e,t){return t.some(l=>e.capabilities.includes(l))}function f(e,t){Array.isArray(e)&&e.length&&!e[0].when&&(e=[{when:["keyboard"],steps:()=>e}]);for(let l of e)if(be(t,l.when))return l.steps(t);throw new Error(`No setup strategy matches capabilities: ${t.capabilities.join(", ")}`)}var me={combobox:x,menu:A,tabs:w,accordion:S,radio:E,checkbox:M,toggle:H},h=class{constructor(t){this.jsonContract=t;}toJSON(){return this.jsonContract}},y=class{constructor(t){this.componentName=t;this.statePack=me[t]||{};}metaValue={};selectorsValue={};relationshipInvariants=[];staticAssertions=[];dynamicTests=[];statePack;meta(t){return this.metaValue=t,this}selectors(t){return this.selectorsValue=t,this}relationships(t){let l=this.statePack,u={capabilities:["keyboard"]},v=(n,i=new Set)=>{if(i.has(n))return [];i.add(n);let s=l[n];if(!s)return [];let r=[];if(Array.isArray(s.requires))for(let a of s.requires)r=r.concat(v(a,i));return s.setup&&(r=r.concat(f(s.setup,u))),r};return t({ariaReference:(n,i,s)=>({requires:r=>{let a=v(r,new Set);return {required:()=>this.relationshipInvariants.push({type:"aria-reference",from:n,attribute:i,to:s,level:"required",setup:a}),optional:()=>this.relationshipInvariants.push({type:"aria-reference",from:n,attribute:i,to:s,level:"optional",setup:a}),recommended:()=>this.relationshipInvariants.push({type:"aria-reference",from:n,attribute:i,to:s,level:"recommended",setup:a})}},required:()=>this.relationshipInvariants.push({type:"aria-reference",from:n,attribute:i,to:s,level:"required"}),optional:()=>this.relationshipInvariants.push({type:"aria-reference",from:n,attribute:i,to:s,level:"optional"}),recommended:()=>this.relationshipInvariants.push({type:"aria-reference",from:n,attribute:i,to:s,level:"recommended"})}),contains:(n,i)=>({requires:s=>{let r=v(s,new Set);return {required:()=>this.relationshipInvariants.push({type:"contains",parent:n,child:i,level:"required",setup:r}),optional:()=>this.relationshipInvariants.push({type:"contains",parent:n,child:i,level:"optional",setup:r}),recommended:()=>this.relationshipInvariants.push({type:"contains",parent:n,child:i,level:"recommended",setup:r})}},required:()=>this.relationshipInvariants.push({type:"contains",parent:n,child:i,level:"required"}),optional:()=>this.relationshipInvariants.push({type:"contains",parent:n,child:i,level:"optional"}),recommended:()=>this.relationshipInvariants.push({type:"contains",parent:n,child:i,level:"recommended"})})}),this}static(t){return t({target:u=>{let v=i=>{let s=this.statePack,r={capabilities:["keyboard"]},a=(p,c=new Set)=>{if(c.has(p))return [];c.add(p);let g=s[p];if(!g)return [];let b=[];if(Array.isArray(g.requires))for(let m of g.requires)b=b.concat(a(m,c));return g.setup&&(b=b.concat(f(g.setup,r))),b};return a(i,new Set)},d=i=>i==="role"?"toHaveRole":"toHaveAttribute",n=(i,s,r)=>{let a=d(i);return {required:()=>this.staticAssertions.push({target:u,assertion:a,attribute:i,expectedValue:s,failureMessage:"",level:"required",setup:r}),optional:()=>this.staticAssertions.push({target:u,assertion:a,attribute:i,expectedValue:s,failureMessage:"",level:"optional",setup:r}),recommended:()=>this.staticAssertions.push({target:u,assertion:a,attribute:i,expectedValue:s,failureMessage:"",level:"recommended",setup:r})}};return {has:(i,s)=>({...n(i,s),requires:a=>{let p=v(a);return n(i,s,p)}})}}}),this}when(t){return new T(this,this.statePack,t)}addDynamicTest(t){this.dynamicTests.push(t);}build(){return {meta:this.metaValue,selectors:this.selectorsValue,relationships:this.relationshipInvariants.length?this.relationshipInvariants:void 0,static:this.staticAssertions.length?this.staticAssertions:[],dynamic:this.dynamicTests}}},T=class{constructor(t,l,u){this.parent=t;this.statePack=l;this.event=u;}_as;_onTarget;_onRelativeTarget;_given=[];_then=[];_desc="";_level="required";_orientation;as(t){return this._as=t,this}on(t,l){return this._onTarget=t,this._onRelativeTarget=l,this}given(t){return this._given=this._normalizeStates(t),this}then(t){return this._then=this._normalizeStates(t),this}orientation(t){return this._orientation=t,this}_normalizeStates(t){return (Array.isArray(t)?t:[t]).flatMap(u=>typeof u=="string"?[u]:typeof u=="object"&&u!==null&&"type"in u&&"ref"in u?this._findStateKeyByTypeAndRef(u.type)?[{type:u.type,ref:u.ref}]:[]:[u])}_findStateKeyByTypeAndRef(t){if(Object.keys(this.statePack).includes(t))return t}describe(t){return this._desc=t,this}required(){return this._level="required",this._finalize(),this.parent}optional(){return this._level="optional",this._finalize(),this.parent}recommended(){return this._level="recommended",this._finalize(),this.parent}_finalize(){let u={capabilities:[{keypress:"keyboard",click:"pointer",type:"textInput",focus:"keyboard",hover:"pointer"}[this._as||"keyboard"]||this._as||"keyboard"]},v=(r,a=new Set,p)=>{if(a.has(r))return [];a.add(r);let c=this.statePack[r];if(!c)return [];let g=[];if(Array.isArray(c.requires))for(let b of c.requires)g=g.concat(v(b,a,p));if(c.setup){let b=c.setup.filter(m=>m.when.some(_=>u.capabilities.includes(_)));for(let m of b)typeof m.steps=="function"?g=g.concat(m.steps({relativeTarget:p})):g=g.concat(m.steps);}return g},d=[];for(let r of this._given)typeof r=="string"?d=d.concat(v(r,new Set)):typeof r=="object"&&r.type&&(d=d.concat(v(r.type,new Set,r.ref)));let n=new Set;d=d.filter(r=>{let a=[r.type,r.target,r.relativeTarget].join(":");return n.has(a)?false:(n.add(a),true)});let i=[];for(let r of this._then)if(typeof r=="string"){let a=this.statePack[r];if(a&&a.assertion!==void 0){let p=a.assertion;if(typeof p=="function")try{p=p();}catch(c){throw new Error(`Error calling assertion function for state '${r}': ${c.message}`)}Array.isArray(p)?i.push(...p):i.push(p);}}else if(typeof r=="object"&&r!==null&&"type"in r&&"ref"in r){let a=this._findStateKeyByTypeAndRef(r.type);if(a){let p=this.statePack[a];if(p&&p.assertion!==void 0){let c=p.assertion;if(typeof c=="function")try{c=c({relativeTarget:r.ref});}catch(g){throw new Error(`Error calling assertion function for state '${a}': ${g.message}`)}Array.isArray(c)?i.push(...c):i.push(c);}}}let s=[{type:this._as,target:this._onTarget,key:this._as==="keypress"?this.event:void 0,relativeTarget:this._onRelativeTarget}];this.parent.addDynamicTest({description:this._desc||"",level:this._level,orientation:this._orientation||"horizontal",action:s,assertions:i,...d.length?{setup:d}:{}});}};function ze(e,t){let l=new y(e);return t(l),new h(l.build())}export{ze as createContract};
@@ -1,12 +1,12 @@
1
- 'use strict';var playwright=require('playwright'),Be=require('path'),Fe=require('fs-extra'),test=require('@playwright/test'),url=require('url'),fs=require('fs'),L=require('chalk'),Jt=require('readline');var _documentCurrentScript=typeof document!=='undefined'?document.currentScript:null;function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var Be__default=/*#__PURE__*/_interopDefault(Be);var Fe__default=/*#__PURE__*/_interopDefault(Fe);var L__default=/*#__PURE__*/_interopDefault(L);var Jt__default=/*#__PURE__*/_interopDefault(Jt);var Et=Object.defineProperty;var x=(c,e)=>()=>(c&&(e=c(c=0)),e);var q=(c,e)=>{for(var t in e)Et(c,t,{get:e[t],enumerable:true});};async function Bt(){return se||(se=await playwright.chromium.launch({headless:true,args:["--disable-extensions","--disable-blink-features=AutomationControlled"]})),se}async function It(){return re||(re=await(await Bt()).newContext({permissions:[],ignoreHTTPSErrors:true})),re}async function _e(){return await(await It()).newPage()}async function Je(){re&&(await re.close(),re=null),se&&(await se.close(),se=null);}var se,re,be=x(()=>{se=null,re=null;});function ie(c){return c==="required"||c==="recommended"||c==="optional"?c:Lt}function ae(c){return c==="minimal"||c==="balanced"||c==="strict"||c==="paranoid"?c:"balanced"}function Ke(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 Lt,Te=x(()=>{Lt="required";});var Ne={};q(Ne,{loadConfig:()=>Ut});function Ft(c){let e=[];if(!c||typeof c!="object")return e.push("Config must be an object"),{valid:false,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 i of r){let n=t.test[i];n!==void 0&&(typeof n!="number"||!Number.isFinite(n)||n<0)&&e.push(`test.${i} must be a non-negative number when provided`);}t.test.components!==void 0&&(Array.isArray(t.test.components)?t.test.components.forEach((i,n)=>{if(typeof i!="object"||i===null)e.push(`test.components[${n}] must be an object`);else {typeof i.name!="string"&&e.push(`test.components[${n}].name must be a string`),i.contractPath!==void 0&&typeof i.contractPath!="string"&&e.push(`test.components[${n}].contractPath must be a string when provided`),i.strategyPath!==void 0&&typeof i.strategyPath!="string"&&e.push(`test.components[${n}].strategyPath must be a string when provided`),i.strictness!==void 0&&!["minimal","balanced","strict","paranoid"].includes(i.strictness)&&e.push(`test.components[${n}].strictness must be one of: minimal, balanced, strict, paranoid`),i.disableTimeouts!==void 0&&typeof i.disableTimeouts!="boolean"&&e.push(`test.components[${n}].disableTimeouts must be a boolean when provided`);let a=["actionTimeoutMs","assertionTimeoutMs","navigationTimeoutMs","componentReadyTimeoutMs"];for(let o of a){let p=i[o];p!==void 0&&(typeof p!="number"||!Number.isFinite(p)||p<0)&&e.push(`test.components[${n}].${o} 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,i)=>{typeof r!="object"||r===null?e.push(`contracts[${i}] must be an object`):(typeof r.src!="string"&&e.push(`contracts[${i}].src is required and must be a string`),r.out!==void 0&&typeof r.out!="string"&&e.push(`contracts[${i}].out must be a string`));}):e.push("contracts must be an array")),{valid:e.length===0,errors:e}}async function Vt(c){try{let e=Be__default.default.extname(c);if(e===".json"){let t=await Fe__default.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 Ut(c=process.cwd()){let e=["ariaease.config.js","ariaease.config.mjs","ariaease.config.cjs","ariaease.config.json","ariaease.config.ts"],t=null,r=null,i=[];for(let n of e){let a=Be__default.default.resolve(c,n);if(await Fe__default.default.pathExists(a)){if(r=a,t=await Vt(a),t===null){i.push(`Found config at ${n} but failed to load it. Check for syntax errors.`);continue}let o=Ft(t);if(!o.valid){i.push(`Config validation failed in ${n}:`),i.push(...o.errors.map(p=>` - ${p}`)),t=null;continue}break}}return {config:t||{},configPath:t?r:null,errors:i}}var Ye=x(()=>{});var Qe={};q(Qe,{MenuComponentStrategy:()=>$e});var $e,Xe=x(()=>{$e=class{constructor(e,t,r=400,i=400){this.mainSelector=e;this.selectors=t;this.actionTimeoutMs=r;this.assertionTimeoutMs=i;}async resetState(e){if(!this.selectors.popup)return;let t=this.selectors.popup,r=e.locator(t).first();if(!await r.isVisible().catch(()=>false))return;let n=false,a=this.selectors.main;if(a&&(await e.locator(a).first().focus(),await e.keyboard.press("Escape"),n=await test.expect(r).toBeHidden({timeout:this.assertionTimeoutMs}).then(()=>true).catch(()=>false)),!n&&this.selectors.main&&(await e.locator(this.selectors.main).first().click({timeout:this.actionTimeoutMs}),n=await test.expect(r).toBeHidden({timeout:this.assertionTimeoutMs}).then(()=>true).catch(()=>false)),n||(await e.mouse.click(10,10),n=await test.expect(r).toBeHidden({timeout:this.assertionTimeoutMs}).then(()=>true).catch(()=>false)),!n)throw new Error(`\u274C FATAL: Cannot close menu between tests. Menu remains visible after trying:
1
+ 'use strict';var playwright=require('playwright'),Be=require('path'),Fe=require('fs-extra'),test=require('@playwright/test'),url=require('url'),fs=require('fs'),L=require('chalk'),Jt=require('readline');var _documentCurrentScript=typeof document!=='undefined'?document.currentScript:null;function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var Be__default=/*#__PURE__*/_interopDefault(Be);var Fe__default=/*#__PURE__*/_interopDefault(Fe);var L__default=/*#__PURE__*/_interopDefault(L);var Jt__default=/*#__PURE__*/_interopDefault(Jt);var Et=Object.defineProperty;var x=(c,e)=>()=>(c&&(e=c(c=0)),e);var q=(c,e)=>{for(var t in e)Et(c,t,{get:e[t],enumerable:true});};async function Bt(){return se||(se=await playwright.chromium.launch({headless:true,args:["--disable-extensions","--disable-blink-features=AutomationControlled"]})),se}async function It(){return re||(re=await(await Bt()).newContext({permissions:[],ignoreHTTPSErrors:true})),re}async function _e(){return await(await It()).newPage()}async function Je(){re&&(await re.close(),re=null),se&&(await se.close(),se=null);}var se,re,be=x(()=>{se=null,re=null;});function ie(c){return c==="required"||c==="recommended"||c==="optional"?c:Lt}function ae(c){return c==="minimal"||c==="balanced"||c==="strict"||c==="paranoid"?c:"balanced"}function Ke(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 Lt,Te=x(()=>{Lt="required";});var Ne={};q(Ne,{loadConfig:()=>Ut});function Ft(c){let e=[];if(!c||typeof c!="object")return e.push("Config must be an object"),{valid:false,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 i of r){let n=t.test[i];n!==void 0&&(typeof n!="number"||!Number.isFinite(n)||n<0)&&e.push(`test.${i} must be a non-negative number when provided`);}t.test.components!==void 0&&(Array.isArray(t.test.components)?t.test.components.forEach((i,n)=>{if(typeof i!="object"||i===null)e.push(`test.components[${n}] must be an object`);else {typeof i.name!="string"&&e.push(`test.components[${n}].name must be a string`),i.contractPath!==void 0&&typeof i.contractPath!="string"&&e.push(`test.components[${n}].contractPath must be a string when provided`),i.strategyPath!==void 0&&typeof i.strategyPath!="string"&&e.push(`test.components[${n}].strategyPath must be a string when provided`),i.strictness!==void 0&&!["minimal","balanced","strict","paranoid"].includes(i.strictness)&&e.push(`test.components[${n}].strictness must be one of: minimal, balanced, strict, paranoid`),i.disableTimeouts!==void 0&&typeof i.disableTimeouts!="boolean"&&e.push(`test.components[${n}].disableTimeouts must be a boolean when provided`);let a=["actionTimeoutMs","assertionTimeoutMs","navigationTimeoutMs","componentReadyTimeoutMs"];for(let o of a){let p=i[o];p!==void 0&&(typeof p!="number"||!Number.isFinite(p)||p<0)&&e.push(`test.components[${n}].${o} 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,i)=>{typeof r!="object"||r===null?e.push(`contracts[${i}] must be an object`):(typeof r.src!="string"&&e.push(`contracts[${i}].src is required and must be a string`),r.out!==void 0&&typeof r.out!="string"&&e.push(`contracts[${i}].out must be a string`));}):e.push("contracts must be an array")),{valid:e.length===0,errors:e}}async function Vt(c){try{let e=Be__default.default.extname(c);if(e===".json"){let t=await Fe__default.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 Ut(c=process.cwd()){let e=["ariaease.config.js","ariaease.config.mjs","ariaease.config.cjs","ariaease.config.json","ariaease.config.ts"],t=null,r=null,i=[];for(let n of e){let a=Be__default.default.resolve(c,n);if(await Fe__default.default.pathExists(a)){if(r=a,t=await Vt(a),t===null){i.push(`Found config at ${n} but failed to load it. Check for syntax errors.`);continue}let o=Ft(t);if(!o.valid){i.push(`Config validation failed in ${n}:`),i.push(...o.errors.map(p=>` - ${p}`)),t=null;continue}break}}return {config:t||{},configPath:t?r:null,errors:i}}var Ye=x(()=>{});var Qe={};q(Qe,{MenuComponentStrategy:()=>$e});var $e,Xe=x(()=>{$e=class{constructor(e,t,r,i){this.mainSelector=e;this.selectors=t;this.actionTimeoutMs=r;this.assertionTimeoutMs=i;}async resetState(e){if(!this.selectors.popup)return;let t=this.selectors.popup,r=e.locator(t).first();if(!await r.isVisible().catch(()=>false))return;let n=false,a=this.selectors.main;if(a&&(await e.locator(a).first().focus(),await e.keyboard.press("Escape"),n=await test.expect(r).toBeHidden({timeout:this.assertionTimeoutMs}).then(()=>true).catch(()=>false)),!n&&this.selectors.main&&(await e.locator(this.selectors.main).first().click({timeout:this.actionTimeoutMs}),n=await test.expect(r).toBeHidden({timeout:this.assertionTimeoutMs}).then(()=>true).catch(()=>false)),n||(await e.mouse.click(10,10),n=await test.expect(r).toBeHidden({timeout:this.assertionTimeoutMs}).then(()=>true).catch(()=>false)),!n)throw new Error(`\u274C FATAL: Cannot close menu between tests. Menu remains visible after trying:
2
2
  1. Escape key
3
3
  2. Clicking trigger
4
4
  3. Clicking outside
5
- 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(a=>a.target==="submenu"||a.target==="submenuTrigger"||a.target==="submenuItems")||e.assertions.some(a=>a.target==="submenu"||a.target==="submenuTrigger"||a.target==="submenuItems")))return false;let i=this.selectors.submenuTrigger;return i?await t.locator(i).count()===0:true}getMainSelector(){return this.mainSelector}};});var Ze={};q(Ze,{AccordionComponentStrategy:()=>Ce});var Ce,et=x(()=>{Ce=class{constructor(e,t,r=400,i=400){this.mainSelector=e;this.selectors=t;this.actionTimeoutMs=r;this.assertionTimeoutMs=i;}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 i=await e.locator(t).all();for(let n of i){let a=await n.getAttribute("aria-expanded")==="true",o=await n.getAttribute("aria-controls");if(a&&o){await n.click({timeout:this.actionTimeoutMs});let p=e.locator(`#${o}`);await test.expect(p).toBeHidden({timeout:this.assertionTimeoutMs}).catch(()=>{});}}}async shouldSkipTest(){return false}getMainSelector(){return this.mainSelector}};});var tt={};q(tt,{ComboboxComponentStrategy:()=>Ae});var Ae,st=x(()=>{Ae=class{constructor(e,t,r=400,i=400){this.mainSelector=e;this.selectors=t;this.actionTimeoutMs=r;this.assertionTimeoutMs=i;}async resetState(e){if(!this.selectors.popup)return;let t=this.selectors.popup,r=e.locator(t).first();if(!await r.isVisible().catch(()=>false))return;let n=false,a=this.selectors.main;if(a&&(await e.locator(a).first().focus(),await e.keyboard.press("Escape"),n=await test.expect(r).toBeHidden({timeout:this.assertionTimeoutMs}).then(()=>true).catch(()=>false)),!n&&this.selectors.button&&(await e.locator(this.selectors.button).first().click({timeout:this.actionTimeoutMs}),n=await test.expect(r).toBeHidden({timeout:this.assertionTimeoutMs}).then(()=>true).catch(()=>false)),n||(await e.mouse.click(10,10),n=await test.expect(r).toBeHidden({timeout:this.assertionTimeoutMs}).then(()=>true).catch(()=>false)),!n)throw new Error(`\u274C FATAL: Cannot close combobox popup between tests. Popup remains visible after trying:
5
+ 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(a=>a.target==="submenu"||a.target==="submenuTrigger"||a.target==="submenuItems")||e.assertions.some(a=>a.target==="submenu"||a.target==="submenuTrigger"||a.target==="submenuItems")))return false;let i=this.selectors.submenuTrigger;return i?await t.locator(i).count()===0:true}getMainSelector(){return this.mainSelector}};});var Ze={};q(Ze,{AccordionComponentStrategy:()=>Ce});var Ce,et=x(()=>{Ce=class{constructor(e,t,r,i){this.mainSelector=e;this.selectors=t;this.actionTimeoutMs=r;this.assertionTimeoutMs=i;}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 i=await e.locator(t).all();for(let n of i){let a=await n.getAttribute("aria-expanded")==="true",o=await n.getAttribute("aria-controls");if(a&&o){await n.click({timeout:this.actionTimeoutMs});let p=e.locator(`#${o}`);await test.expect(p).toBeHidden({timeout:this.assertionTimeoutMs}).catch(()=>{});}}}async shouldSkipTest(){return false}getMainSelector(){return this.mainSelector}};});var tt={};q(tt,{ComboboxComponentStrategy:()=>Ae});var Ae,st=x(()=>{Ae=class{constructor(e,t,r,i){this.mainSelector=e;this.selectors=t;this.actionTimeoutMs=r;this.assertionTimeoutMs=i;}async resetState(e){if(!this.selectors.popup)return;let t=this.selectors.popup,r=e.locator(t).first();if(!await r.isVisible().catch(()=>false))return;let n=false,a=this.selectors.main;if(a&&(await e.locator(a).first().focus(),await e.keyboard.press("Escape"),n=await test.expect(r).toBeHidden({timeout:this.assertionTimeoutMs}).then(()=>true).catch(()=>false)),!n&&this.selectors.button&&(await e.locator(this.selectors.button).first().click({timeout:this.actionTimeoutMs}),n=await test.expect(r).toBeHidden({timeout:this.assertionTimeoutMs}).then(()=>true).catch(()=>false)),n||(await e.mouse.click(10,10),n=await test.expect(r).toBeHidden({timeout:this.assertionTimeoutMs}).then(()=>true).catch(()=>false)),!n)throw new Error(`\u274C FATAL: Cannot close combobox popup between tests. Popup remains visible after trying:
6
6
  1. Escape key
7
7
  2. Clicking button
8
8
  3. Clicking outside
9
- 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 false}getMainSelector(){return this.mainSelector}};});var rt={};q(rt,{TabsComponentStrategy:()=>Re});var Re,it=x(()=>{Re=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,n=await t.locator(r).first().getAttribute("aria-orientation");if(e.orientation!==n)return true}return false}getMainSelector(){return this.mainSelector}};});var nt={};q(nt,{RadioComponentStrategy:()=>Me});var Me,ot=x(()=>{Me=class{constructor(e,t,r=400,i=400){this.mainSelector=e;this.selectors=t;this.actionTimeoutMs=r;this.assertionTimeoutMs=i;}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 i of r)if(await i.getAttribute("aria-checked")==="true"){await i.evaluate(o=>o.setAttribute("aria-checked","false"),{timeout:this.actionTimeoutMs});let a=e.locator(`#${i}`);await test.expect(a).toHaveAttribute("aria-checked","false",{timeout:this.assertionTimeoutMs}).catch(()=>{});}}async shouldSkipTest(){return false}getMainSelector(){return this.mainSelector}};});var at={};q(at,{CheckboxComponentStrategy:()=>xe});var xe,ct=x(()=>{xe=class{constructor(e,t,r=400,i=400){this.mainSelector=e;this.selectors=t;this.actionTimeoutMs=r;this.assertionTimeoutMs=i;}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 i of r)if(await i.getAttribute("aria-checked")==="true"){await i.click({timeout:this.actionTimeoutMs});let a=e.locator(`#${i}`);await test.expect(a).toHaveAttribute("aria-checked","false",{timeout:this.assertionTimeoutMs}).catch(()=>{});}}async shouldSkipTest(){return false}getMainSelector(){return this.mainSelector}};});var lt={};q(lt,{ToggleComponentStrategy:()=>Ee});var Ee,ut=x(()=>{Ee=class{constructor(e,t,r=400,i=400){this.mainSelector=e;this.selectors=t;this.actionTimeoutMs=r;this.assertionTimeoutMs=i;}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 i of r)if(await i.getAttribute("aria-pressed")==="true"){await i.click({timeout:this.actionTimeoutMs});let a=e.locator(`#${i}`);await test.expect(a).toHaveAttribute("aria-pressed","false",{timeout:this.assertionTimeoutMs}).catch(()=>{});}}async shouldSkipTest(){return false}getMainSelector(){return this.mainSelector}};});var pe,ft=x(()=>{pe=class{builtInStrategies=new Map;constructor(){this.registerBuiltInStrategies();}registerBuiltInStrategies(){this.builtInStrategies.set("menu",()=>Promise.resolve().then(()=>(Xe(),Qe)).then(e=>e.MenuComponentStrategy)),this.builtInStrategies.set("accordion",()=>Promise.resolve().then(()=>(et(),Ze)).then(e=>e.AccordionComponentStrategy)),this.builtInStrategies.set("combobox",()=>Promise.resolve().then(()=>(st(),tt)).then(e=>e.ComboboxComponentStrategy)),this.builtInStrategies.set("tabs",()=>Promise.resolve().then(()=>(it(),rt)).then(e=>e.TabsComponentStrategy)),this.builtInStrategies.set("radio",()=>Promise.resolve().then(()=>(ot(),nt)).then(e=>e.RadioComponentStrategy)),this.builtInStrategies.set("checkbox",()=>Promise.resolve().then(()=>(ct(),at)).then(e=>e.CheckboxComponentStrategy)),this.builtInStrategies.set("toggle",()=>Promise.resolve().then(()=>(ut(),lt)).then(e=>e.ToggleComponentStrategy));}async loadStrategy(e,t,r){try{if(t)try{let n=Be__default.default.isAbsolute(t)?t:Be__default.default.resolve(r||process.cwd(),t),a=await import(url.pathToFileURL(n).href),o=a.default||a;if(!o)throw new Error(`No default export found in ${t}`);return o}catch(n){throw new Error(`Failed to load custom strategy from ${t}: ${n instanceof Error?n.message:String(n)}`)}let i=this.builtInStrategies.get(e);return i?i():null}catch(i){throw new Error(`Strategy loading failed for ${e}: ${i instanceof Error?i.message:String(i)}`)}}has(e,t){return !!t||this.builtInStrategies.has(e)}};});var fe,gt=x(()=>{ft();fe=class{static strategyRegistry=new pe;static isComponentConfig(e){return typeof e=="object"&&e!==null}static async detect(e,t,r=400,i=400,n){let a=this.isComponentConfig(t)?t:void 0,o=a?.contractPath;if(!o)throw new Error(`Contract path not found for component: ${e}`);let p=(()=>{if(Be__default.default.isAbsolute(o))return o;if(n){let le=Be__default.default.resolve(n,o);try{return fs.readFileSync(le,"utf-8"),le}catch{}}let Z=Be__default.default.resolve(process.cwd(),o);try{return fs.readFileSync(Z,"utf-8"),Z}catch{return new URL(o,(typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href))).pathname}})(),$=fs.readFileSync(p,"utf-8"),E=JSON.parse($).selectors,P=await this.strategyRegistry.loadStrategy(e,a?.strategyPath,n);if(!P)return null;let z=E.main;return e==="tabs"?new P(z,E):new P(z,E,r,i)}};});var ge,dt=x(()=>{ge=class{startTime=0;componentName="";staticPasses=0;staticFailures=0;staticWarnings=0;dynamicResults=[];totalTests=0;skipped=0;warnings=0;isPlaywright=false;isCustomContract=false;apgUrl="https://www.w3.org/WAI/ARIA/apg/";hasPrintedStaticSection=false;hasPrintedDynamicSection=false;constructor(e=false,t=false){this.isPlaywright=e,this.isCustomContract=t;}log(e){process.stderr.write(e+`
9
+ 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 false}getMainSelector(){return this.mainSelector}};});var rt={};q(rt,{TabsComponentStrategy:()=>Re});var Re,it=x(()=>{Re=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,n=await t.locator(r).first().getAttribute("aria-orientation");if(e.orientation!==n)return true}return false}getMainSelector(){return this.mainSelector}};});var nt={};q(nt,{RadioComponentStrategy:()=>Me});var Me,ot=x(()=>{Me=class{constructor(e,t,r,i){this.mainSelector=e;this.selectors=t;this.actionTimeoutMs=r;this.assertionTimeoutMs=i;}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 i of r)if(await i.getAttribute("aria-checked")==="true"){await i.evaluate(o=>o.setAttribute("aria-checked","false"),{timeout:this.actionTimeoutMs});let a=e.locator(`#${i}`);await test.expect(a).toHaveAttribute("aria-checked","false",{timeout:this.assertionTimeoutMs}).catch(()=>{});}}async shouldSkipTest(){return false}getMainSelector(){return this.mainSelector}};});var at={};q(at,{CheckboxComponentStrategy:()=>xe});var xe,ct=x(()=>{xe=class{constructor(e,t,r,i){this.mainSelector=e;this.selectors=t;this.actionTimeoutMs=r;this.assertionTimeoutMs=i;}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 i of r)if(await i.getAttribute("aria-checked")==="true"){await i.click({timeout:this.actionTimeoutMs});let a=e.locator(`#${i}`);await test.expect(a).toHaveAttribute("aria-checked","false",{timeout:this.assertionTimeoutMs}).catch(()=>{});}}async shouldSkipTest(){return false}getMainSelector(){return this.mainSelector}};});var lt={};q(lt,{ToggleComponentStrategy:()=>Ee});var Ee,ut=x(()=>{Ee=class{constructor(e,t,r,i){this.mainSelector=e;this.selectors=t;this.actionTimeoutMs=r;this.assertionTimeoutMs=i;}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 i of r)if(await i.getAttribute("aria-pressed")==="true"){await i.click({timeout:this.actionTimeoutMs});let a=e.locator(`#${i}`);await test.expect(a).toHaveAttribute("aria-pressed","false",{timeout:this.assertionTimeoutMs}).catch(()=>{});}}async shouldSkipTest(){return false}getMainSelector(){return this.mainSelector}};});var pe,ft=x(()=>{pe=class{builtInStrategies=new Map;constructor(){this.registerBuiltInStrategies();}registerBuiltInStrategies(){this.builtInStrategies.set("menu",()=>Promise.resolve().then(()=>(Xe(),Qe)).then(e=>e.MenuComponentStrategy)),this.builtInStrategies.set("accordion",()=>Promise.resolve().then(()=>(et(),Ze)).then(e=>e.AccordionComponentStrategy)),this.builtInStrategies.set("combobox",()=>Promise.resolve().then(()=>(st(),tt)).then(e=>e.ComboboxComponentStrategy)),this.builtInStrategies.set("tabs",()=>Promise.resolve().then(()=>(it(),rt)).then(e=>e.TabsComponentStrategy)),this.builtInStrategies.set("radio",()=>Promise.resolve().then(()=>(ot(),nt)).then(e=>e.RadioComponentStrategy)),this.builtInStrategies.set("checkbox",()=>Promise.resolve().then(()=>(ct(),at)).then(e=>e.CheckboxComponentStrategy)),this.builtInStrategies.set("toggle",()=>Promise.resolve().then(()=>(ut(),lt)).then(e=>e.ToggleComponentStrategy));}async loadStrategy(e,t,r){try{if(t)try{let n=Be__default.default.isAbsolute(t)?t:Be__default.default.resolve(r||process.cwd(),t),a=await import(url.pathToFileURL(n).href),o=a.default||a;if(!o)throw new Error(`No default export found in ${t}`);return o}catch(n){throw new Error(`Failed to load custom strategy from ${t}: ${n instanceof Error?n.message:String(n)}`)}let i=this.builtInStrategies.get(e);return i?i():null}catch(i){throw new Error(`Strategy loading failed for ${e}: ${i instanceof Error?i.message:String(i)}`)}}has(e,t){return !!t||this.builtInStrategies.has(e)}};});var fe,gt=x(()=>{ft();fe=class{static strategyRegistry=new pe;static isComponentConfig(e){return typeof e=="object"&&e!==null}static async detect(e,t,r,i,n){let a=this.isComponentConfig(i)?i:void 0,o=a?.contractPath;if(!o)throw new Error(`Contract path not found for component: ${e}`);let p=(()=>{if(Be__default.default.isAbsolute(o))return o;if(n){let le=Be__default.default.resolve(n,o);try{return fs.readFileSync(le,"utf-8"),le}catch{}}let Z=Be__default.default.resolve(process.cwd(),o);try{return fs.readFileSync(Z,"utf-8"),Z}catch{return new URL(o,(typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href))).pathname}})(),$=fs.readFileSync(p,"utf-8"),E=JSON.parse($).selectors,P=await this.strategyRegistry.loadStrategy(e,a?.strategyPath,n);if(!P)return null;let z=E.main;return e==="tabs"?new P(z,E):new P(z,E,t,r)}};});var ge,dt=x(()=>{ge=class{startTime=0;componentName="";staticPasses=0;staticFailures=0;staticWarnings=0;dynamicResults=[];totalTests=0;skipped=0;warnings=0;isPlaywright=false;isCustomContract=false;apgUrl="https://www.w3.org/WAI/ARIA/apg/";hasPrintedStaticSection=false;hasPrintedDynamicSection=false;constructor(e=false,t=false){this.isPlaywright=e,this.isCustomContract=t;}log(e){process.stderr.write(e+`
10
10
  `);}start(e,t,r){this.startTime=Date.now(),this.componentName=e,this.totalTests=t,this.hasPrintedStaticSection=false,this.hasPrintedDynamicSection=false,r&&(this.apgUrl=r);let i="Playwright (Real Browser)";this.log(`
11
11
  ${"\u2550".repeat(60)}`),this.log(`\u{1F50D} Testing ${e.charAt(0).toUpperCase()+e.slice(1)} Component - ${i}`),this.log(`${"\u2550".repeat(60)}
12
12
  `);}reportStatic(e,t,r=0){this.staticPasses=e,this.staticFailures=t,this.staticWarnings=r;}reportStaticTest(e,t,r,i){this.hasPrintedStaticSection||(this.log(`${"\u2500".repeat(60)}`),this.log("\u{1F9EA} Static Assertions"),this.log(`${"\u2500".repeat(60)}`),this.hasPrintedStaticSection=true);let n=t==="pass"?"\u2713":t==="warn"?"\u26A0":t==="skip"?"\u25CB":"\u2717";this.log(` ${n} ${e}`),i&&this.log(` \u21B3 level=${i}`),(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=true);let i={description:e.description,status:t,failureMessage:r,level:e.level};t==="skip"&&(i.skipReason="Requires real browser (addEventListener events)"),this.dynamicResults.push(i);let n={pass:"\u2713",fail:"\u2717",warn:"\u26A0",skip:"\u25CB"},a=e.level?`[${e.level.toUpperCase()}] `:"";this.log(` ${n[t]} ${a}${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(`
@@ -27,7 +27,7 @@ ${"\u2550".repeat(60)}`),this.log(`\u{1F4CA} Summary
27
27
  `),o>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
28
28
  `)):!this.isPlaywright&&this.skipped>0&&this.log(`\u2728 Optional: Run Playwright tests for complete validation
29
29
  `),{passes:a,failures:o,skipped:this.skipped,duration:t}}error(e,t){this.log(`
30
- \u274C Error: ${e}`),t&&this.log(` Context: ${t}`),this.log("");}};});var mt={};q(mt,{RelativeTargetResolver:()=>D});var D,de=x(()=>{D=class{static async resolve(e,t,r){let i=await e.locator(t).all();if(typeof r=="number")return i[r-1];switch(r){case "first":return i[0];case "second":return i[1];case "last":return i[i.length-1];case "next":{let a=(await e.evaluate(([o])=>Array.from(document.querySelectorAll(o)).indexOf(document.activeElement),[t])+1)%i.length;return i[a]}case "previous":{let a=(await e.evaluate(([o])=>Array.from(document.querySelectorAll(o)).indexOf(document.activeElement),[t])-1+i.length)%i.length;return i[a]}default:return null}}};});var ne,ht=x(()=>{de();ne=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 n=this.selectors.main;if(!n)return {success:!1,error:"Main selector not defined for virtual focus."};let a=this.page.locator(n).first();return await a.count()?(await a.evaluate((p,$)=>{p.setAttribute("aria-activedescendant",$);},r),{success:!0}):{success:!1,error:"Main element not found for virtual focus."}}if(e==="relative"&&t){let n=this.selectors.relative;if(!n)return {success:!1,error:"Relative selector not defined for focus action."};let a=await D.resolve(this.page,n,t);return a?(await a.focus({timeout:this.timeoutMs}),{success:!0}):{success:!1,error:`Could not resolve relative target ${t} for focus.`}}let i=this.selectors[e];return i?(await this.page.locator(i).first().focus({timeout:this.timeoutMs}),{success:!0}):{success:!1,error:`Selector for focus target ${e} not found.`}}catch(i){return this.isBrowserClosedError(i)?{success:false,error:"CRITICAL: Browser/page closed during test execution. Remaining actions skipped.",shouldBreak:true}:{success:false,error:`Failed to focus ${e}: ${i instanceof Error?i.message:String(i)}`}}}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:false,error:"CRITICAL: Browser/page closed during test execution. Remaining actions skipped.",shouldBreak:true}:{success:false,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 i=this.selectors.relative;if(!i)return {success:!1,error:"Relative selector not defined for click action."};let n=await D.resolve(this.page,i,t);return n?(await n.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:false,error:"CRITICAL: Browser/page closed during test execution. Remaining actions skipped.",shouldBreak:true}:{success:false,error:`Failed to click ${e}: ${r instanceof Error?r.message:String(r)}`}}}async keypress(e,t,r){try{let n={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(n==="Space"?n=" ":n.includes(" ")&&(n=n.replace(/ /g,"")),e==="relative"){if(r==null)return {success:!1,error:"relativeTarget must be provided for relative keypress."};let $=this.selectors.relative;if(!$)return {success:!1,error:"Relative selector not defined for keypress action."};let v=await D.resolve(this.page,$,r);return v?(await v.press(n,{timeout:this.timeoutMs}),{success:!0}):{success:!1,error:`Could not resolve relative target ${r} for keypress.`}}let a=this.selectors[e];if(!a)return {success:!1,error:`Selector for keypress target ${e} not found.`};let o=this.page.locator(a).first();return await o.count()===0?{success:!1,error:`${e} element not found.`,shouldBreak:!0}:(await o.press(n,{timeout:this.timeoutMs}),{success:!0})}catch(i){return this.isBrowserClosedError(i)?{success:false,error:"CRITICAL: Browser/page closed during test execution. Remaining actions skipped.",shouldBreak:true}:{success:false,error:`Failed to press ${t} on ${e}: ${i instanceof Error?i.message:String(i)}`}}}async hover(e,t){try{if(e==="relative"&&t){let i=this.selectors.relative;if(!i)return {success:!1,error:"Relative selector not defined for hover action."};let n=await D.resolve(this.page,i,t);return n?(await n.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:false,error:"CRITICAL: Browser/page closed during test execution. Remaining actions skipped.",shouldBreak:true}:{success:false,error:`Failed to hover ${e}: ${r instanceof Error?r.message:String(r)}`}}}};});var ce,yt=x(()=>{de();ce=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 n=r?this.selectors[r]:this.selectors.relative;if(!n)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 a=await D.resolve(this.page,n,t);return a?{target:a}:{target:null,error:`Target ${e} not found.`}}let i=this.selectors[e];return i?{target:this.page.locator(i).first()}:{target:null,error:`Selector for assertion target ${e} not found.`}}catch(i){return {target:null,error:`Failed to resolve target ${e}: ${i instanceof Error?i.message:String(i)}`}}}async validateVisibility(e,t,r,i,n){try{return r?(await test.expect(e).toBeVisible({timeout:this.timeoutMs}),{success:!0,passMessage:`${t} is visible as expected. Test: "${n}".`}):(await test.expect(e).toBeHidden({timeout:this.timeoutMs}),{success:!0,passMessage:`${t} is not visible as expected. Test: "${n}".`})}catch{let a=this.selectors[t]||"",o=await this.page.evaluate(p=>{let $=p?document.querySelector(p):null;if(!$)return "element not found";let v=window.getComputedStyle($);return `display:${v.display}, visibility:${v.visibility}, opacity:${v.opacity}`},a);return r?{success:false,failMessage:`${i} (actual: ${o})`}:{success:false,failMessage:`${i} ${t} is still visible (actual: ${o}).`}}}async validateAttribute(e,t,r,i,n,a){if(i==="!empty"){let $=await e.getAttribute(r);return $&&$.trim()!==""?{success:true,passMessage:`${t} has non-empty "${r}". Test: "${a}".`}:{success:false,failMessage:`${n} ${t} "${r}" should not be empty, found "${$}".`}}if(typeof i!="string")throw console.error("[AssertionRunner] expectedValue is not a string:",i),new Error(`AssertionRunner: expectedValue for attribute assertion must be a string, but got: ${JSON.stringify(i)}`);let o=i.split(" | ").map($=>$.trim()),p=await e.getAttribute(r);return p!==null&&o.includes(p)?{success:true,passMessage:`${t} has expected "${r}". Test: "${a}".`}:{success:false,failMessage:`${n} ${t} "${r}" should be "${i}", found "${p}".`}}async validateValue(e,t,r,i,n){let a=await e.inputValue().catch(()=>"");return r==="!empty"?a&&a.trim()!==""?{success:true,passMessage:`${t} has non-empty value. Test: "${n}".`}:{success:false,failMessage:`${i} ${t} value should not be empty, found "${a}".`}:r===""?a===""?{success:true,passMessage:`${t} has empty value. Test: "${n}".`}:{success:false,failMessage:`${i} ${t} value should be empty, found "${a}".`}:a===r?{success:true,passMessage:`${t} has expected value. Test: "${n}".`}:{success:false,failMessage:`${i} ${t} value should be "${r}", found "${a}".`}}async validateFocus(e,t,r,i,n){try{return r?(await test.expect(e).toBeFocused({timeout:this.timeoutMs}),{success:!0,passMessage:`${t} has focus as expected. Test: "${n}".`}):(await test.expect(e).not.toBeFocused({timeout:this.timeoutMs}),{success:!0,passMessage:`${t} does not have focus as expected. Test: "${n}".`})}catch{let a=await this.page.evaluate(()=>{let o=document.activeElement;return o?`${o.tagName}#${o.id||"no-id"}.${o.className||"no-class"}`:"no element focused"});return {success:false,failMessage:`${i} (actual focus: ${a})`}}}async validateRole(e,t,r,i,n){let a=await e.getAttribute("role");return a===r?{success:true,passMessage:`${t} has role "${r}". Test: "${n}".`}:{success:false,failMessage:`${i} Expected role "${r}", found "${a}".`}}async validate(e,t){if(this.page.isClosed())return {success:false,failMessage:"CRITICAL: Browser/page closed before completing all tests. Increase test timeout or reduce test complexity."};let r=null,i;if(e.controlledBy){let n=e.controlledBy,a=this.selectors[n.target];if(!a)return {success:false,failMessage:`Selector for controlledBy.target '${n.target}' not found.`,target:null};let o=null;if(n.relativeTarget?o=await D.resolve(this.page,a,n.relativeTarget):o=this.page.locator(a).first(),!o)return {success:false,failMessage:"Controlling element for controlledBy not found.",target:null};let p=n.attribute||"aria-controls",$=await o.getAttribute(p);if(!$)return {success:false,failMessage:`Controlling element does not have attribute '${p}'.`,target:null};if(r=this.page.locator(`#${$}`),!r||await r.count()===0)return {success:false,failMessage:`Controlled element with id '${$}' not found.`,target:null}}else {let n=await this.resolveTarget(e.target,e.relativeTarget||e.expectedValue,e.selectorKey);if(r=n.target,i=n.error,i||!r)return {success:false,failMessage:i||`Target ${e.target} not found.`,target:null}}if(e.target==="input"&&e.attribute==="aria-activedescendant"&&e.expectedValue==="!empty"&&e.relativeTarget&&e.selectorKey){let n=await D.resolve(this.page,this.selectors[e.selectorKey],e.relativeTarget),a=n?await n.getAttribute("id"):null,o=await r.getAttribute("aria-activedescendant");return a&&o===a?{success:true,passMessage:`input[aria-activedescendant] matches id of ${e.relativeTarget}(${e.selectorKey}). Test: "${t}".`}:{success:false,failMessage:`input[aria-activedescendant] should match id of ${e.relativeTarget}(${e.selectorKey}), found "${o}".`}}switch(e.assertion){case "toBeVisible":return this.validateVisibility(r,e.target,true,e.failureMessage||"",t);case "notToBeVisible":return this.validateVisibility(r,e.target,false,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:false,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:false,failMessage:"Missing expectedValue for toHaveValue assertion"};case "toHaveFocus":return this.validateFocus(r,e.target,true,e.failureMessage||"",t);case "notToHaveFocus":return this.validateFocus(r,e.target,false,e.failureMessage||"",t);case "toHaveRole":return e.expectedValue!==void 0?this.validateRole(r,e.target,e.expectedValue,e.failureMessage||"",t):{success:false,failMessage:"Missing expectedValue for toHaveRole assertion"};default:return {success:false,failMessage:`Unknown assertion type: ${e.assertion}`}}}};});var vt={};q(vt,{runContractTestsPlaywright:()=>qt});async function qt(c,e,t,r,i){let n=r?.test?.components?.find(m=>m.name===c),a=!!n?.contractPath,o=new ge(true,a),p={actionTimeoutMs:400,assertionTimeoutMs:400,navigationTimeoutMs:3e4,componentReadyTimeoutMs:5e3},$=r?.test?.disableTimeouts===true,E=n?.disableTimeouts===true||$,P=(m,_,J)=>{if(E)return 0;let j=m??_;return typeof j!="number"||!Number.isFinite(j)||j<0?J:j},z=P(n?.actionTimeoutMs,r?.test?.actionTimeoutMs,p.actionTimeoutMs),Z=P(n?.assertionTimeoutMs,r?.test?.assertionTimeoutMs,p.assertionTimeoutMs),le=P(n?.navigationTimeoutMs,r?.test?.navigationTimeoutMs,p.navigationTimeoutMs),he=P(n?.componentReadyTimeoutMs,r?.test?.componentReadyTimeoutMs,p.componentReadyTimeoutMs),Ue=ae(t),ee=n?.contractPath;if(!ee)throw new Error(`Contract path not found for component: ${c}`);let $t=(()=>{if(Be__default.default.isAbsolute(ee))return ee;if(i){let _=Be__default.default.resolve(i,ee);try{return fs.readFileSync(_,"utf-8"),_}catch{}}let m=Be__default.default.resolve(process.cwd(),ee);try{return fs.readFileSync(m,"utf-8"),m}catch{return new URL(ee,(typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href))).pathname}})(),Ct=fs.readFileSync($t,"utf-8"),C=JSON.parse(Ct),kt=(C.relationships?.length||0)+(C.static.length||0)+C.dynamic.length,At=C.meta?.source?.apg,W=[],Y=[],Q=[],B=[],T=null,I=(m,_)=>{let J=ie(_),j=Ke(J,Ue);if(j==="error")return W.push(m),{status:"fail",level:J,detail:m};if(j==="warning")return Y.push(m),{status:"warn",level:J,detail:m};let K=`${m} (ignored by strictness=${Ue}, level=${J})`;return B.push(K),{status:"skip",level:J,detail:K}},Rt=m=>m&&typeof m=="object"&&m.success===true;try{if(T=await _e(),e){try{await T.goto(e,{waitUntil:"domcontentloaded",timeout:le});}catch(s){throw new Error(`Failed to navigate to ${e}. Ensure dev server is running and accessible. Original error: ${s instanceof Error?s.message:String(s)}`)}await T.addStyleTag({content:"* { transition: none !important; animation: none !important; }"});}let m=await fe.detect(c,n,z,Z,i);if(!m)throw new Error(`Unsupported component: ${c}`);let _=m.getMainSelector();if(!_)throw new Error(`CRITICAL: No selector found in contract for ${c}`);try{await T.locator(_).first().waitFor({state:"attached",timeout:he});}catch(s){throw new Error(`
30
+ \u274C Error: ${e}`),t&&this.log(` Context: ${t}`),this.log("");}};});var mt={};q(mt,{RelativeTargetResolver:()=>D});var D,de=x(()=>{D=class{static async resolve(e,t,r){let i=await e.locator(t).all();if(typeof r=="number")return i[r-1];switch(r){case "first":return i[0];case "second":return i[1];case "last":return i[i.length-1];case "next":{let a=(await e.evaluate(([o])=>Array.from(document.querySelectorAll(o)).indexOf(document.activeElement),[t])+1)%i.length;return i[a]}case "previous":{let a=(await e.evaluate(([o])=>Array.from(document.querySelectorAll(o)).indexOf(document.activeElement),[t])-1+i.length)%i.length;return i[a]}default:return null}}};});var ne,ht=x(()=>{de();ne=class{constructor(e,t,r){this.page=e;this.selectors=t;this.actionTimeoutMs=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 n=this.selectors.main;if(!n)return {success:!1,error:"Main selector not defined for virtual focus."};let a=this.page.locator(n).first();return await a.count()?(await a.evaluate((p,$)=>{p.setAttribute("aria-activedescendant",$);},r),{success:!0}):{success:!1,error:"Main element not found for virtual focus."}}if(e==="relative"&&t){let n=this.selectors.relative;if(!n)return {success:!1,error:"Relative selector not defined for focus action."};let a=await D.resolve(this.page,n,t);return a?(await a.focus({timeout:this.actionTimeoutMs}),{success:!0}):{success:!1,error:`Could not resolve relative target ${t} for focus.`}}let i=this.selectors[e];return i?(await this.page.locator(i).first().focus({timeout:this.actionTimeoutMs}),{success:!0}):{success:!1,error:`Selector for focus target ${e} not found.`}}catch(i){return this.isBrowserClosedError(i)?{success:false,error:"CRITICAL: Browser/page closed during test execution. Remaining actions skipped.",shouldBreak:true}:{success:false,error:`Failed to focus ${e}: ${i instanceof Error?i.message:String(i)}`}}}async type(e,t){try{let r=this.selectors[e];return r?(await this.page.locator(r).first().fill(t,{timeout:this.actionTimeoutMs}),{success:!0}):{success:!1,error:`Selector for type target ${e} not found.`}}catch(r){return this.isBrowserClosedError(r)?{success:false,error:"CRITICAL: Browser/page closed during test execution. Remaining actions skipped.",shouldBreak:true}:{success:false,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 i=this.selectors.relative;if(!i)return {success:!1,error:"Relative selector not defined for click action."};let n=await D.resolve(this.page,i,t);return n?(await n.click({timeout:this.actionTimeoutMs}),{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.actionTimeoutMs}),{success:!0}):{success:!1,error:`Selector for action target ${e} not found.`}}catch(r){return this.isBrowserClosedError(r)?{success:false,error:"CRITICAL: Browser/page closed during test execution. Remaining actions skipped.",shouldBreak:true}:{success:false,error:`Failed to click ${e}: ${r instanceof Error?r.message:String(r)}`}}}async keypress(e,t,r){try{let n={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(n==="Space"?n=" ":n.includes(" ")&&(n=n.replace(/ /g,"")),e==="relative"){if(r==null)return {success:!1,error:"relativeTarget must be provided for relative keypress."};let $=this.selectors.relative;if(!$)return {success:!1,error:"Relative selector not defined for keypress action."};let v=await D.resolve(this.page,$,r);return v?(await v.press(n,{timeout:this.actionTimeoutMs}),{success:!0}):{success:!1,error:`Could not resolve relative target ${r} for keypress.`}}let a=this.selectors[e];if(!a)return {success:!1,error:`Selector for keypress target ${e} not found.`};let o=this.page.locator(a).first();return await o.count()===0?{success:!1,error:`${e} element not found.`,shouldBreak:!0}:(await o.press(n,{timeout:this.actionTimeoutMs}),{success:!0})}catch(i){return this.isBrowserClosedError(i)?{success:false,error:"CRITICAL: Browser/page closed during test execution. Remaining actions skipped.",shouldBreak:true}:{success:false,error:`Failed to press ${t} on ${e}: ${i instanceof Error?i.message:String(i)}`}}}async hover(e,t){try{if(e==="relative"&&t){let i=this.selectors.relative;if(!i)return {success:!1,error:"Relative selector not defined for hover action."};let n=await D.resolve(this.page,i,t);return n?(await n.hover({timeout:this.actionTimeoutMs}),{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.actionTimeoutMs}),{success:!0}):{success:!1,error:`Selector for hover target ${e} not found.`}}catch(r){return this.isBrowserClosedError(r)?{success:false,error:"CRITICAL: Browser/page closed during test execution. Remaining actions skipped.",shouldBreak:true}:{success:false,error:`Failed to hover ${e}: ${r instanceof Error?r.message:String(r)}`}}}};});var ce,yt=x(()=>{de();ce=class{constructor(e,t,r){this.page=e;this.selectors=t;this.assertionTimeoutMs=r;}async resolveTarget(e,t,r){try{if(e==="relative"){let n=r?this.selectors[r]:this.selectors.relative;if(!n)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 a=await D.resolve(this.page,n,t);return a?{target:a}:{target:null,error:`Target ${e} not found.`}}let i=this.selectors[e];return i?{target:this.page.locator(i).first()}:{target:null,error:`Selector for assertion target ${e} not found.`}}catch(i){return {target:null,error:`Failed to resolve target ${e}: ${i instanceof Error?i.message:String(i)}`}}}async validateVisibility(e,t,r,i,n){try{return r?(await test.expect(e).toBeVisible({timeout:this.assertionTimeoutMs}),{success:!0,passMessage:`${t} is visible as expected. Test: "${n}".`}):(await test.expect(e).toBeHidden({timeout:this.assertionTimeoutMs}),{success:!0,passMessage:`${t} is not visible as expected. Test: "${n}".`})}catch{let a=this.selectors[t]||"",o=await this.page.evaluate(p=>{let $=p?document.querySelector(p):null;if(!$)return "element not found";let v=window.getComputedStyle($);return `display:${v.display}, visibility:${v.visibility}, opacity:${v.opacity}`},a);return r?{success:false,failMessage:`${i} (actual: ${o})`}:{success:false,failMessage:`${i} ${t} is still visible (actual: ${o}).`}}}async validateAttribute(e,t,r,i,n,a){if(i==="!empty"){let $=await e.getAttribute(r);return $&&$.trim()!==""?{success:true,passMessage:`${t} has non-empty "${r}". Test: "${a}".`}:{success:false,failMessage:`${n} ${t} "${r}" should not be empty, found "${$}".`}}if(typeof i!="string")throw new Error(`AssertionRunner: expectedValue for attribute assertion must be a string, but got: ${JSON.stringify(i)}`);let o=i.split(" | ").map($=>$.trim()),p=await e.getAttribute(r);return p!==null&&o.includes(p)?{success:true,passMessage:`${t} has expected "${r}". Test: "${a}".`}:{success:false,failMessage:`${n} ${t} "${r}" should be "${i}", found "${p}".`}}async validateValue(e,t,r,i,n){let a=await e.inputValue().catch(()=>"");return r==="!empty"?a&&a.trim()!==""?{success:true,passMessage:`${t} has non-empty value. Test: "${n}".`}:{success:false,failMessage:`${i} ${t} value should not be empty, found "${a}".`}:r===""?a===""?{success:true,passMessage:`${t} has empty value. Test: "${n}".`}:{success:false,failMessage:`${i} ${t} value should be empty, found "${a}".`}:a===r?{success:true,passMessage:`${t} has expected value. Test: "${n}".`}:{success:false,failMessage:`${i} ${t} value should be "${r}", found "${a}".`}}async validateFocus(e,t,r,i,n){try{return r?(await test.expect(e).toBeFocused({timeout:this.assertionTimeoutMs}),{success:!0,passMessage:`${t} has focus as expected. Test: "${n}".`}):(await test.expect(e).not.toBeFocused({timeout:this.assertionTimeoutMs}),{success:!0,passMessage:`${t} does not have focus as expected. Test: "${n}".`})}catch{let a=await this.page.evaluate(()=>{let o=document.activeElement;return o?`${o.tagName}#${o.id||"no-id"}.${o.className||"no-class"} [text="${o.innerText||o.textContent||""}"]`:"no element focused"});return {success:false,failMessage:`${i} (actual focus: ${a})`}}}async validateRole(e,t,r,i,n){let a=await e.getAttribute("role");return a===r?{success:true,passMessage:`${t} has role "${r}". Test: "${n}".`}:{success:false,failMessage:`${i} Expected role "${r}", found "${a}".`}}async validate(e,t){if(this.page.isClosed())return {success:false,failMessage:"CRITICAL: Browser/page closed before completing all tests. Increase test timeout or reduce test complexity."};let r=null,i;if(e.controlledBy){let n=e.controlledBy,a=this.selectors[n.target];if(!a)return {success:false,failMessage:`Selector for controlledBy.target '${n.target}' not found.`,target:null};let o=null;if(n.relativeTarget?o=await D.resolve(this.page,a,n.relativeTarget):o=this.page.locator(a).first(),!o)return {success:false,failMessage:"Controlling element for controlledBy not found.",target:null};let p=n.attribute||"aria-controls",$=await o.getAttribute(p);if(!$)return {success:false,failMessage:`Controlling element does not have attribute '${p}'.`,target:null};if(r=this.page.locator(`#${$}`),!r||await r.count()===0)return {success:false,failMessage:`Controlled element with id '${$}' not found.`,target:null}}else {let n=await this.resolveTarget(e.target,e.relativeTarget||e.expectedValue,e.selectorKey);if(r=n.target,i=n.error,i||!r)return {success:false,failMessage:i||`Target ${e.target} not found.`,target:null}}if(e.target==="input"&&e.attribute==="aria-activedescendant"&&e.expectedValue==="!empty"&&e.relativeTarget&&e.selectorKey){let n=await D.resolve(this.page,this.selectors[e.selectorKey],e.relativeTarget),a=n?await n.getAttribute("id"):null,o=await r.getAttribute("aria-activedescendant");return a&&o===a?{success:true,passMessage:`input[aria-activedescendant] matches id of ${e.relativeTarget}(${e.selectorKey}). Test: "${t}".`}:{success:false,failMessage:`input[aria-activedescendant] should match id of ${e.relativeTarget}(${e.selectorKey}), found "${o}".`}}switch(e.assertion){case "toBeVisible":return this.validateVisibility(r,e.target,true,e.failureMessage||"",t);case "notToBeVisible":return this.validateVisibility(r,e.target,false,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:false,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:false,failMessage:"Missing expectedValue for toHaveValue assertion"};case "toHaveFocus":return this.validateFocus(r,e.target,true,e.failureMessage||"",t);case "notToHaveFocus":return this.validateFocus(r,e.target,false,e.failureMessage||"",t);case "toHaveRole":return e.expectedValue!==void 0?this.validateRole(r,e.target,e.expectedValue,e.failureMessage||"",t):{success:false,failMessage:"Missing expectedValue for toHaveRole assertion"};default:return {success:false,failMessage:`Unknown assertion type: ${e.assertion}`}}}};});var vt={};q(vt,{runContractTestsPlaywright:()=>qt});async function qt(c,e,t,r,i){let n=r?.test?.components?.find(m=>m.name===c),a=!!n?.contractPath,o=new ge(true,a),p={actionTimeoutMs:400,assertionTimeoutMs:400,navigationTimeoutMs:3e4,componentReadyTimeoutMs:5e3},$=r?.test?.disableTimeouts===true,E=n?.disableTimeouts===true||$,P=(m,_,J)=>{if(E)return 0;let j=m??_;return typeof j!="number"||!Number.isFinite(j)||j<0?J:j},z=P(n?.actionTimeoutMs,r?.test?.actionTimeoutMs,p.actionTimeoutMs),Z=P(n?.assertionTimeoutMs,r?.test?.assertionTimeoutMs,p.assertionTimeoutMs),le=P(n?.navigationTimeoutMs,r?.test?.navigationTimeoutMs,p.navigationTimeoutMs),he=P(n?.componentReadyTimeoutMs,r?.test?.componentReadyTimeoutMs,p.componentReadyTimeoutMs),Ue=ae(t),ee=n?.contractPath;if(!ee)throw new Error(`Contract path not found for component: ${c}`);let $t=(()=>{if(Be__default.default.isAbsolute(ee))return ee;if(i){let _=Be__default.default.resolve(i,ee);try{return fs.readFileSync(_,"utf-8"),_}catch{}}let m=Be__default.default.resolve(process.cwd(),ee);try{return fs.readFileSync(m,"utf-8"),m}catch{return new URL(ee,(typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href))).pathname}})(),Ct=fs.readFileSync($t,"utf-8"),C=JSON.parse(Ct),kt=(C.relationships?.length||0)+(C.static.length||0)+C.dynamic.length,At=C.meta?.source?.apg,W=[],Y=[],Q=[],B=[],T=null,I=(m,_)=>{let J=ie(_),j=Ke(J,Ue);if(j==="error")return W.push(m),{status:"fail",level:J,detail:m};if(j==="warning")return Y.push(m),{status:"warn",level:J,detail:m};let K=`${m} (ignored by strictness=${Ue}, level=${J})`;return B.push(K),{status:"skip",level:J,detail:K}},Rt=m=>m&&typeof m=="object"&&m.success===true;try{if(T=await _e(),e){try{await T.goto(e,{waitUntil:"domcontentloaded",timeout:le});}catch(s){throw new Error(`Failed to navigate to ${e}. Ensure dev server is running and accessible. Original error: ${s instanceof Error?s.message:String(s)}`)}await T.addStyleTag({content:"* { transition: none !important; animation: none !important; }"});}let m=await fe.detect(c,z,Z,n,i);if(!m)throw new Error(`Unsupported component: ${c}`);let _=m.getMainSelector();if(!_)throw new Error(`CRITICAL: No selector found in contract for ${c}`);try{await T.locator(_).first().waitFor({state:"attached",timeout:he});}catch(s){throw new Error(`
31
31
  \u274C CRITICAL: Component not found on page!
32
32
  This usually means:
33
33
  - The component didn't render
@@ -1,4 +1,4 @@
1
- import {d,b}from'./chunk-APUMBDOT.js';import m from'path';async function y(a,e,c={}){if(!a||typeof a!="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 i={violations:[]};async function l(t){try{let n=await fetch(t,{method:"HEAD",signal:AbortSignal.timeout(1e3)});if(n.ok||n.status===304)return t}catch{return null}return null}let p=d(c.strictness),o={},d$1=typeof process<"u"?process.cwd():"";if(typeof process<"u"&&typeof process.cwd=="function")try{let{loadConfig:t}=await import('./configLoader-NCYRL2O6.js'),n=await t(process.cwd());if(o=n.config,n.configPath&&(d$1=m.dirname(n.configPath)),c.strictness===void 0){let r=o.test?.components?.find(h=>h?.name===a)?.strictness;p=d(r??o.test?.strictness);}}catch{c.strictness===void 0&&(p="balanced");}let s;try{if(e){let t=await l(e);if(t){console.log(`\u{1F3AD} Running Playwright tests on ${t}`);let{runContractTestsPlaywright:n}=await import('./contractTestRunnerPlaywright-7ERFIHCM.js');s=await n(a,t,p,o,d$1);}else throw new Error(`\u274C Dev server not running at ${e}
1
+ import {d,b}from'./chunk-APUMBDOT.js';import m from'path';async function y(a,e,c={}){if(!a||typeof a!="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 i={violations:[]};async function l(t){try{let n=await fetch(t,{method:"HEAD",signal:AbortSignal.timeout(1e3)});if(n.ok||n.status===304)return t}catch{return null}return null}let p=d(c.strictness),o={},d$1=typeof process<"u"?process.cwd():"";if(typeof process<"u"&&typeof process.cwd=="function")try{let{loadConfig:t}=await import('./configLoader-NCYRL2O6.js'),n=await t(process.cwd());if(o=n.config,n.configPath&&(d$1=m.dirname(n.configPath)),c.strictness===void 0){let r=o.test?.components?.find(h=>h?.name===a)?.strictness;p=d(r??o.test?.strictness);}}catch{c.strictness===void 0&&(p="balanced");}let s;try{if(e){let t=await l(e);if(t){console.log(`\u{1F3AD} Running Playwright tests on ${t}`);let{runContractTestsPlaywright:n}=await import('./contractTestRunnerPlaywright-GM4W4SKJ.js');s=await n(a,t,p,o,d$1);}else throw new Error(`\u274C Dev server not running at ${e}
2
2
  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(t){throw t instanceof Error?t:new Error(`\u274C Contract test execution failed: ${String(t)}`)}let u={violations:i.violations,raw:i,contract:s};if(s.failures.length>0&&e==="Playwright")throw new Error(`
3
3
  \u274C ${s.failures.length} accessibility contract test${s.failures.length>1?"s":""} failed (Playwright mode)
4
4
  \u2705 ${s.passes.length} test${s.passes.length>1?"s":""} passed
@@ -1,4 +1,4 @@
1
- import{b as g,d as f}from"./chunk-APUMBDOT.js";import"./chunk-CNU4N4AY.js";import m from"path";async function y(a,e,c={}){if(!a||typeof a!="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 i={violations:[]};async function l(t){try{let n=await fetch(t,{method:"HEAD",signal:AbortSignal.timeout(1e3)});if(n.ok||n.status===304)return t}catch{return null}return null}let p=f(c.strictness),o={},d=typeof process<"u"?process.cwd():"";if(typeof process<"u"&&typeof process.cwd=="function")try{let{loadConfig:t}=await import("./configLoader-ZXTSCIP6.js"),n=await t(process.cwd());if(o=n.config,n.configPath&&(d=m.dirname(n.configPath)),c.strictness===void 0){let r=o.test?.components?.find(h=>h?.name===a)?.strictness;p=f(r??o.test?.strictness)}}catch{c.strictness===void 0&&(p="balanced")}let s;try{if(e){let t=await l(e);if(t){console.log(`\u{1F3AD} Running Playwright tests on ${t}`);let{runContractTestsPlaywright:n}=await import("./contractTestRunnerPlaywright-FECB4HSX.js");s=await n(a,t,p,o,d)}else throw new Error(`\u274C Dev server not running at ${e}
1
+ import{b as g,d as f}from"./chunk-APUMBDOT.js";import"./chunk-CNU4N4AY.js";import m from"path";async function y(a,e,c={}){if(!a||typeof a!="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 i={violations:[]};async function l(t){try{let n=await fetch(t,{method:"HEAD",signal:AbortSignal.timeout(1e3)});if(n.ok||n.status===304)return t}catch{return null}return null}let p=f(c.strictness),o={},d=typeof process<"u"?process.cwd():"";if(typeof process<"u"&&typeof process.cwd=="function")try{let{loadConfig:t}=await import("./configLoader-ZXTSCIP6.js"),n=await t(process.cwd());if(o=n.config,n.configPath&&(d=m.dirname(n.configPath)),c.strictness===void 0){let r=o.test?.components?.find(h=>h?.name===a)?.strictness;p=f(r??o.test?.strictness)}}catch{c.strictness===void 0&&(p="balanced")}let s;try{if(e){let t=await l(e);if(t){console.log(`\u{1F3AD} Running Playwright tests on ${t}`);let{runContractTestsPlaywright:n}=await import("./contractTestRunnerPlaywright-2KC3RAV5.js");s=await n(a,t,p,o,d)}else throw new Error(`\u274C Dev server not running at ${e}
2
2
  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(t){throw t instanceof Error?t:new Error(`\u274C Contract test execution failed: ${String(t)}`)}let u={violations:i.violations,raw:i,contract:s};if(s.failures.length>0&&e==="Playwright")throw new Error(`
3
3
  \u274C ${s.failures.length} accessibility contract test${s.failures.length>1?"s":""} failed (Playwright mode)
4
4
  \u2705 ${s.passes.length} test${s.passes.length>1?"s":""} passed
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aria-ease",
3
- "version": "7.8.1",
3
+ "version": "7.8.2",
4
4
  "description": "Accessibility infrastructure for the entire frontend engineering lifecycle. Build accessible patterns, run automated audits, verify component interactions, and gate deployments — all in one system.",
5
5
  "main": "dist/index.cjs",
6
6
  "type": "module",
@@ -1 +0,0 @@
1
- import{a as o}from"./chunk-SM6ZKEDR.js";import"./chunk-CNU4N4AY.js";var n=class{constructor(t,e,i=400,s=400){this.mainSelector=t;this.selectors=e;this.actionTimeoutMs=i;this.assertionTimeoutMs=s}async resetState(t){if(!this.selectors.panel||!this.selectors.trigger)return;let e=this.selectors.trigger,i=this.selectors.panel;if(!e||!i)return;let s=await t.locator(e).all();for(let r of s){let c=await r.getAttribute("aria-expanded")==="true",a=await r.getAttribute("aria-controls");if(c&&a){await r.click({timeout:this.actionTimeoutMs});let l=t.locator(`#${a}`);await(0,o.expect)(l).toBeHidden({timeout:this.assertionTimeoutMs}).catch(()=>{})}}}async shouldSkipTest(){return!1}getMainSelector(){return this.mainSelector}};export{n as AccordionComponentStrategy};
@@ -1 +0,0 @@
1
- import{a as r}from"./chunk-SM6ZKEDR.js";import"./chunk-CNU4N4AY.js";var i=class{constructor(e,o,s=400,t=400){this.mainSelector=e;this.selectors=o;this.actionTimeoutMs=s;this.assertionTimeoutMs=t}async resetState(e){if(!this.selectors.checkbox||!this.selectors.relative)return;let o=this.selectors.checkbox;if(!o)return;let s=await e.locator(o).all();for(let t of s)if(await t.getAttribute("aria-checked")==="true"){await t.click({timeout:this.actionTimeoutMs});let c=e.locator(`#${t}`);await(0,r.expect)(c).toHaveAttribute("aria-checked","false",{timeout:this.assertionTimeoutMs}).catch(()=>{})}}async shouldSkipTest(){return!1}getMainSelector(){return this.mainSelector}};export{i as CheckboxComponentStrategy};
@@ -1,5 +0,0 @@
1
- import{a as s}from"./chunk-SM6ZKEDR.js";import"./chunk-CNU4N4AY.js";var r=class{constructor(t,i,o=400,c=400){this.mainSelector=t;this.selectors=i;this.actionTimeoutMs=o;this.assertionTimeoutMs=c}async resetState(t){if(!this.selectors.popup)return;let i=this.selectors.popup,o=t.locator(i).first();if(!await o.isVisible().catch(()=>!1))return;let e=!1,n=this.selectors.main;if(n&&(await t.locator(n).first().focus(),await t.keyboard.press("Escape"),e=await(0,s.expect)(o).toBeHidden({timeout:this.assertionTimeoutMs}).then(()=>!0).catch(()=>!1)),!e&&this.selectors.button&&(await t.locator(this.selectors.button).first().click({timeout:this.actionTimeoutMs}),e=await(0,s.expect)(o).toBeHidden({timeout:this.assertionTimeoutMs}).then(()=>!0).catch(()=>!1)),e||(await t.mouse.click(10,10),e=await(0,s.expect)(o).toBeHidden({timeout:this.assertionTimeoutMs}).then(()=>!0).catch(()=>!1)),!e)throw new Error(`\u274C FATAL: Cannot close combobox popup between tests. Popup remains visible after trying:
2
- 1. Escape key
3
- 2. Clicking button
4
- 3. Clicking outside
5
- This indicates a problem with the combobox component's close functionality.`);this.selectors.input&&await t.locator(this.selectors.input).first().clear()}async shouldSkipTest(){return!1}getMainSelector(){return this.mainSelector}};export{r as ComboboxComponentStrategy};
@@ -1,5 +0,0 @@
1
- import{a as r}from"./chunk-SM6ZKEDR.js";import"./chunk-CNU4N4AY.js";var c=class{constructor(e,o,i=400,n=400){this.mainSelector=e;this.selectors=o;this.actionTimeoutMs=i;this.assertionTimeoutMs=n}async resetState(e){if(!this.selectors.popup)return;let o=this.selectors.popup,i=e.locator(o).first();if(!await i.isVisible().catch(()=>!1))return;let s=!1,t=this.selectors.main;if(t&&(await e.locator(t).first().focus(),await e.keyboard.press("Escape"),s=await(0,r.expect)(i).toBeHidden({timeout:this.assertionTimeoutMs}).then(()=>!0).catch(()=>!1)),!s&&this.selectors.main&&(await e.locator(this.selectors.main).first().click({timeout:this.actionTimeoutMs}),s=await(0,r.expect)(i).toBeHidden({timeout:this.assertionTimeoutMs}).then(()=>!0).catch(()=>!1)),s||(await e.mouse.click(10,10),s=await(0,r.expect)(i).toBeHidden({timeout:this.assertionTimeoutMs}).then(()=>!0).catch(()=>!1)),!s)throw new Error(`\u274C FATAL: Cannot close menu between tests. Menu remains visible after trying:
2
- 1. Escape key
3
- 2. Clicking trigger
4
- 3. Clicking outside
5
- 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,o){if(!(e.action.some(t=>t.target==="submenu"||t.target==="submenuTrigger"||t.target==="submenuItems")||e.assertions.some(t=>t.target==="submenu"||t.target==="submenuTrigger"||t.target==="submenuItems")))return!1;let n=this.selectors.submenuTrigger;return n?await o.locator(n).count()===0:!0}getMainSelector(){return this.mainSelector}};export{c as MenuComponentStrategy};