@baseline-ui/test-utils 3.4.0 → 3.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -99,10 +99,6 @@ declare const expect: playwright_test.Expect<{
99
99
  prefix?: string | string[];
100
100
  ignoreHashed?: boolean;
101
101
  }): Promise<{
102
- message: () => string;
103
- pass: false;
104
- shouldNotRetryTest?: undefined;
105
- } | {
106
102
  message: () => string;
107
103
  pass: true;
108
104
  shouldNotRetryTest?: undefined;
@@ -110,6 +106,10 @@ declare const expect: playwright_test.Expect<{
110
106
  message: () => string;
111
107
  pass: false;
112
108
  shouldNotRetryTest: boolean;
109
+ } | {
110
+ message: () => string;
111
+ pass: false;
112
+ shouldNotRetryTest?: undefined;
113
113
  }>;
114
114
  }>;
115
115
 
@@ -146,6 +146,35 @@ interface BaseTesterOptions {
146
146
  */
147
147
  type DisclosureOpenWith = "click" | "Space" | "Enter" | "ArrowDown" | "ArrowUp" | "ArrowRight" | "ArrowLeft";
148
148
 
149
+ interface BreadcrumbsTesterOptions extends Omit<BaseTesterOptions, "trigger"> {
150
+ /**
151
+ * The accessible name of the `nav`, to pick one trail when a page has several
152
+ * navigation landmarks.
153
+ */
154
+ name?: string | RegExp;
155
+ }
156
+ /**
157
+ * Driver for a `<Breadcrumbs>` in Playwright component tests. Construct with
158
+ * {@link breadcrumbsTester} (or `testers(frame).breadcrumbs()`).
159
+ */
160
+ interface BreadcrumbsTester {
161
+ /** The `navigation` landmark wrapping the breadcrumb trail. */
162
+ readonly root: Locator;
163
+ /**
164
+ * The current-page item (`aria-current="page"`). Matches nothing when the
165
+ * last breadcrumb is custom children.
166
+ */
167
+ readonly current: Locator;
168
+ /** The decorative separators between items. */
169
+ readonly separators: Locator;
170
+ /**
171
+ * A breadcrumb link, resolved by role and accessible name. A string matches
172
+ * the full name exactly; pass a RegExp for a partial match. Matches link items
173
+ * only: custom children are not links.
174
+ */
175
+ item: (name: string | RegExp) => Locator;
176
+ }
177
+
149
178
  /**
150
179
  * How to open a ComboBox from the keyboard. `Space` and `Enter` are excluded
151
180
  * from {@link DisclosureOpenWith}: the input is a text field, so `Space` would
@@ -331,7 +360,16 @@ interface FileUploaderTester {
331
360
  * `trigger` when the Menu renders a custom trigger via `renderTrigger` that
332
361
  * doesn't carry that test id.
333
362
  */
334
- type MenuTesterOptions = BaseTesterOptions;
363
+ interface MenuTesterOptions extends BaseTesterOptions {
364
+ /**
365
+ * For a Menu with `trigger="longPress"`. `open()` then holds the pointer
366
+ * instead of clicking, and keyboard opens press the key with `Alt` held, the
367
+ * long-press menu's keyboard opener.
368
+ *
369
+ * @default false
370
+ */
371
+ longPress?: boolean;
372
+ }
335
373
  /**
336
374
  * Locators + verbs shared by a menu and each of its submenus. A submenu is
337
375
  * itself a menu opened from a `menuitem`, so the recursive surface (items,
@@ -368,7 +406,11 @@ interface MenuTester extends MenuLevelTester {
368
406
  readonly trigger: Locator;
369
407
  /**
370
408
  * Opens the root menu if it isn't already open. Idempotent (checks
371
- * `aria-expanded`). Defaults to `"click"`.
409
+ * `aria-expanded`). Defaults to `"click"`. With `longPress`, `"click"` holds
410
+ * the pointer on the trigger's button and a key is pressed with `Alt` held;
411
+ * `"ArrowLeft"` and `"ArrowRight"` throw, since they never open a long-press
412
+ * menu and `open()` would otherwise do nothing. (`Alt` with either is also
413
+ * Back/Forward in desktop browsers on Windows and Linux.)
372
414
  */
373
415
  open: (how?: DisclosureOpenWith) => Promise<void>;
374
416
  /** Closes the menu if open, via `Escape`. Idempotent. */
@@ -534,6 +576,7 @@ type BoundComboBoxOptions = Omit<ComboBoxTesterOptions, "frame">;
534
576
  type BoundEditorOptions = Omit<EditorTesterOptions, "frame">;
535
577
  type BoundFileUploaderOptions = Omit<FileUploaderTesterOptions, "frame">;
536
578
  type BoundMenuOptions = Omit<MenuTesterOptions, "frame">;
579
+ type BoundBreadcrumbsOptions = Omit<BreadcrumbsTesterOptions, "frame">;
537
580
  /**
538
581
  * The frame-bound tester factory. Methods are flat — one per component — so
539
582
  * IDE autocomplete on `t.` lists the full surface in one place. Variants of a
@@ -549,6 +592,7 @@ interface Testers {
549
592
  editor: (options?: BoundEditorOptions) => EditorTester;
550
593
  fileUploader: (options?: BoundFileUploaderOptions) => FileUploaderTester;
551
594
  menu: (options?: BoundMenuOptions) => MenuTester;
595
+ breadcrumbs: (options?: BoundBreadcrumbsOptions) => BreadcrumbsTester;
552
596
  }
553
597
  /**
554
598
  * Build a frame-bound tester factory. Construct once per test and pick the
@@ -566,4 +610,4 @@ interface Testers {
566
610
  */
567
611
  declare function testers(frame: Frame): Testers;
568
612
 
569
- export { type AutocompleteTester, type ComboBoxTester, DEFAULT_CRITICAL_INCOMPLETE_RULES, DEFAULT_DISABLED_RULES, DEFAULT_WCAG_TAGS, type EditorTester, type FileUploaderTester, type Frame, type MenuSubmenuTester, type MenuTester, type MultiSelectTester, type SelectTester, type Testers, type ToBeAccessibleOptions, expect, testers };
613
+ export { type AutocompleteTester, type BreadcrumbsTester, type ComboBoxTester, DEFAULT_CRITICAL_INCOMPLETE_RULES, DEFAULT_DISABLED_RULES, DEFAULT_WCAG_TAGS, type EditorTester, type FileUploaderTester, type Frame, type MenuSubmenuTester, type MenuTester, type MultiSelectTester, type SelectTester, type Testers, type ToBeAccessibleOptions, expect, testers };
package/dist/index.d.ts CHANGED
@@ -99,10 +99,6 @@ declare const expect: playwright_test.Expect<{
99
99
  prefix?: string | string[];
100
100
  ignoreHashed?: boolean;
101
101
  }): Promise<{
102
- message: () => string;
103
- pass: false;
104
- shouldNotRetryTest?: undefined;
105
- } | {
106
102
  message: () => string;
107
103
  pass: true;
108
104
  shouldNotRetryTest?: undefined;
@@ -110,6 +106,10 @@ declare const expect: playwright_test.Expect<{
110
106
  message: () => string;
111
107
  pass: false;
112
108
  shouldNotRetryTest: boolean;
109
+ } | {
110
+ message: () => string;
111
+ pass: false;
112
+ shouldNotRetryTest?: undefined;
113
113
  }>;
114
114
  }>;
115
115
 
@@ -146,6 +146,35 @@ interface BaseTesterOptions {
146
146
  */
147
147
  type DisclosureOpenWith = "click" | "Space" | "Enter" | "ArrowDown" | "ArrowUp" | "ArrowRight" | "ArrowLeft";
148
148
 
149
+ interface BreadcrumbsTesterOptions extends Omit<BaseTesterOptions, "trigger"> {
150
+ /**
151
+ * The accessible name of the `nav`, to pick one trail when a page has several
152
+ * navigation landmarks.
153
+ */
154
+ name?: string | RegExp;
155
+ }
156
+ /**
157
+ * Driver for a `<Breadcrumbs>` in Playwright component tests. Construct with
158
+ * {@link breadcrumbsTester} (or `testers(frame).breadcrumbs()`).
159
+ */
160
+ interface BreadcrumbsTester {
161
+ /** The `navigation` landmark wrapping the breadcrumb trail. */
162
+ readonly root: Locator;
163
+ /**
164
+ * The current-page item (`aria-current="page"`). Matches nothing when the
165
+ * last breadcrumb is custom children.
166
+ */
167
+ readonly current: Locator;
168
+ /** The decorative separators between items. */
169
+ readonly separators: Locator;
170
+ /**
171
+ * A breadcrumb link, resolved by role and accessible name. A string matches
172
+ * the full name exactly; pass a RegExp for a partial match. Matches link items
173
+ * only: custom children are not links.
174
+ */
175
+ item: (name: string | RegExp) => Locator;
176
+ }
177
+
149
178
  /**
150
179
  * How to open a ComboBox from the keyboard. `Space` and `Enter` are excluded
151
180
  * from {@link DisclosureOpenWith}: the input is a text field, so `Space` would
@@ -331,7 +360,16 @@ interface FileUploaderTester {
331
360
  * `trigger` when the Menu renders a custom trigger via `renderTrigger` that
332
361
  * doesn't carry that test id.
333
362
  */
334
- type MenuTesterOptions = BaseTesterOptions;
363
+ interface MenuTesterOptions extends BaseTesterOptions {
364
+ /**
365
+ * For a Menu with `trigger="longPress"`. `open()` then holds the pointer
366
+ * instead of clicking, and keyboard opens press the key with `Alt` held, the
367
+ * long-press menu's keyboard opener.
368
+ *
369
+ * @default false
370
+ */
371
+ longPress?: boolean;
372
+ }
335
373
  /**
336
374
  * Locators + verbs shared by a menu and each of its submenus. A submenu is
337
375
  * itself a menu opened from a `menuitem`, so the recursive surface (items,
@@ -368,7 +406,11 @@ interface MenuTester extends MenuLevelTester {
368
406
  readonly trigger: Locator;
369
407
  /**
370
408
  * Opens the root menu if it isn't already open. Idempotent (checks
371
- * `aria-expanded`). Defaults to `"click"`.
409
+ * `aria-expanded`). Defaults to `"click"`. With `longPress`, `"click"` holds
410
+ * the pointer on the trigger's button and a key is pressed with `Alt` held;
411
+ * `"ArrowLeft"` and `"ArrowRight"` throw, since they never open a long-press
412
+ * menu and `open()` would otherwise do nothing. (`Alt` with either is also
413
+ * Back/Forward in desktop browsers on Windows and Linux.)
372
414
  */
373
415
  open: (how?: DisclosureOpenWith) => Promise<void>;
374
416
  /** Closes the menu if open, via `Escape`. Idempotent. */
@@ -534,6 +576,7 @@ type BoundComboBoxOptions = Omit<ComboBoxTesterOptions, "frame">;
534
576
  type BoundEditorOptions = Omit<EditorTesterOptions, "frame">;
535
577
  type BoundFileUploaderOptions = Omit<FileUploaderTesterOptions, "frame">;
536
578
  type BoundMenuOptions = Omit<MenuTesterOptions, "frame">;
579
+ type BoundBreadcrumbsOptions = Omit<BreadcrumbsTesterOptions, "frame">;
537
580
  /**
538
581
  * The frame-bound tester factory. Methods are flat — one per component — so
539
582
  * IDE autocomplete on `t.` lists the full surface in one place. Variants of a
@@ -549,6 +592,7 @@ interface Testers {
549
592
  editor: (options?: BoundEditorOptions) => EditorTester;
550
593
  fileUploader: (options?: BoundFileUploaderOptions) => FileUploaderTester;
551
594
  menu: (options?: BoundMenuOptions) => MenuTester;
595
+ breadcrumbs: (options?: BoundBreadcrumbsOptions) => BreadcrumbsTester;
552
596
  }
553
597
  /**
554
598
  * Build a frame-bound tester factory. Construct once per test and pick the
@@ -566,4 +610,4 @@ interface Testers {
566
610
  */
567
611
  declare function testers(frame: Frame): Testers;
568
612
 
569
- export { type AutocompleteTester, type ComboBoxTester, DEFAULT_CRITICAL_INCOMPLETE_RULES, DEFAULT_DISABLED_RULES, DEFAULT_WCAG_TAGS, type EditorTester, type FileUploaderTester, type Frame, type MenuSubmenuTester, type MenuTester, type MultiSelectTester, type SelectTester, type Testers, type ToBeAccessibleOptions, expect, testers };
613
+ export { type AutocompleteTester, type BreadcrumbsTester, type ComboBoxTester, DEFAULT_CRITICAL_INCOMPLETE_RULES, DEFAULT_DISABLED_RULES, DEFAULT_WCAG_TAGS, type EditorTester, type FileUploaderTester, type Frame, type MenuSubmenuTester, type MenuTester, type MultiSelectTester, type SelectTester, type Testers, type ToBeAccessibleOptions, expect, testers };
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- 'use strict';var test=require('@playwright/test'),W=require('axe-core'),promises=require('fs/promises'),I=require('path');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var W__default=/*#__PURE__*/_interopDefault(W);var I__default=/*#__PURE__*/_interopDefault(I);/**
1
+ 'use strict';var test=require('@playwright/test'),j=require('axe-core'),promises=require('fs/promises'),F=require('path');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var j__default=/*#__PURE__*/_interopDefault(j);var F__default=/*#__PURE__*/_interopDefault(F);/**
2
2
  * Copyright (c) 2023-2024 PSPDFKit GmbH. All rights reserved.
3
3
  *
4
4
  * THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
@@ -7,15 +7,15 @@
7
7
  * This notice may not be removed from this file.
8
8
  *
9
9
  */
10
- var w=["wcag2a","wcag2aa","wcag21a","wcag21aa","best-practice"],L=["landmark-one-main","page-has-heading-one","region","aria-allowed-role","duplicate-id","scrollable-region-focusable"],O=["aria-valid-attr-value","aria-valid-attr","aria-required-attr"];function A(e,t={}){let{prefix:o="BaselineUI-",ignoreHashed:n=false}=t,i=Array.isArray(o)?o:[o];function r(u){return u.split(/[-_]/).some(p=>p.length>=5&&/^[a-z\d]+$/.test(p)&&/[a-z]/.test(p)&&/\d/.test(p))}function s(u){return [...u.classList].filter(p=>i.some(m=>p.startsWith(m))&&(!n||!r(p)))}function l(u,p=false){let m=[],h=u.shadowRoot?u.shadowRoot.children:u.children;for(let T of h){let x=p||T.getAttribute("aria-hidden")==="true",B=s(T),b=l(T,x);B.length>0?m.push({classes:B,children:b,hidden:x}):m.push(...b);}return m}function d(u,p="",m=false){let h=[];for(let T=0;T<u.length;T++){let x=u[T],B=T===u.length-1,b=m?"":B?"\u2514\u2500\u2500 ":"\u251C\u2500\u2500 ",_=m?"":p+(B?" ":"\u2502 "),$=x.classes.join(", ");h.push(p+b+$+(x.hidden?" [aria-hidden]":""),...d(x.children,_));}return h}let a=s(e),c=l(e);return a.length===0&&c.length===0?"":a.length>0?d([{classes:a,children:c,hidden:false}],"",true).join(`
11
- `):d(c,"",true).join(`
12
- `)}var f=e=>{if(e instanceof Error)return e.message;if(typeof e=="string")return e;if(e==null)return "unknown error";try{return JSON.stringify(e)}catch{return "unstringifiable error"}},H=async e=>{let t=typeof e.goto=="function",o=!t&&typeof e.owner=="function";if(t||o)return e.locator("body");let n=e;return await n.first().evaluate(r=>r.tagName?.toLowerCase()==="iframe").catch(()=>false)?n.contentFrame().locator("body"):n},z=async e=>{await e.first().evaluate((t,o)=>{if(window.axe)return;let i=document.createElement("script");i.textContent=o,document.head.append(i);},W__default.default.source);},V=["document-title","html-has-lang","html-lang-valid","html-xml-lang-mismatch"],G=(e,t=[])=>{let o=new Set([...L,...t,...e.disableRules??[]]);return {runOnly:{type:"tag",values:[...e.tags??w]},rules:Object.fromEntries([...o].map(n=>[n,{enabled:false}]))}},k=e=>{if(e!==void 0)return typeof e=="string"?[e]:[...e]},q=async(e,t,o)=>{let n=await e.count();if(n===0)throw new Error("toBeAccessible: locator resolved to zero elements; nothing to scan.");await z(e);let i=k(t.include),r=k(t.exclude);return n===1?await e.evaluate(async(s,l)=>{let d=window,a={include:[s,...l.userInclude??[]],exclude:l.userExclude??[]};return await d.axe.run(a,l.runOptions)},{userInclude:i,userExclude:r,runOptions:o}):await e.evaluateAll(async(s,l)=>{let d=window,a={include:[...s,...l.userInclude??[]],exclude:l.userExclude??[]};return await d.axe.run(a,l.runOptions)},{userInclude:i,userExclude:r,runOptions:o})},S="BaselineUI-";function E(e){return e.replaceAll(/\W+/g,"-").replaceAll(/^-|-$/g,"")}function J(e){return Array.isArray(e)?e.length===1&&e[0]===S:e===S}function K(e){return (Array.isArray(e)?e:[e]).join("+")}function X(e,t,o,n,i){let r=t.slice(1).map(s=>E(s));return o&&r.push(E(o)),n!==void 0&&!J(n)&&r.push(E(K(n))),i&&r.push("ignoreHashed"),I__default.default.join(e,`${r.join("--")}.txt`)}var Q=test.expect.extend({toBeWithinDelta(e,t,o){return Math.abs(e-t)<=o?{message:()=>`expected ${e} not to be within ${o} of ${t}`,pass:true}:{message:()=>`expected ${e} to be within ${o} of ${t}`,pass:false}},async toBeCalledOnce(e){try{return await test.expect.poll(()=>e.callCount).toBe(1),{message:()=>"Expected function to be called once.",pass:!0}}catch(t){return {message:()=>f(t),pass:false}}},async toBeCalledTwice(e){try{return await test.expect.poll(()=>e.callCount).toBe(2),{message:()=>"Expected function to be called twice.",pass:!0}}catch(t){return {message:()=>f(t),pass:false}}},async toBeCalledThrice(e){try{return await test.expect.poll(()=>e.callCount).toBe(3),{message:()=>"Expected function to be called thrice.",pass:!0}}catch(t){return {message:()=>f(t),pass:false}}},async toBeCalledWith(e,...t){try{return await test.expect.poll(()=>({called:e.called,args:t.map((o,n)=>e.lastCall?.args[n])})).toStrictEqual({called:!0,args:t}),{message:()=>`Expected function to be called with ${t.join(", ")}.`,pass:!0}}catch(o){return {message:()=>f(o),pass:false}}},async toBeCalledWithExactly(e,...t){try{return await test.expect.poll(()=>e.lastCall?.args).toStrictEqual(t),{message:()=>`Expected function to be called with exactly ${t.join(", ")}.`,pass:!0}}catch(o){return {message:()=>f(o),pass:false}}},toBeCalled(e){try{return test.expect(e.called).toBeTruthy(),{message:()=>"Expected function to be called.",pass:!0}}catch(t){return {message:()=>f(t),pass:false}}},async toBeCalledTimes(e,t){try{return await test.expect.poll(()=>e.callCount).toBe(t),{message:()=>`Expected function to be called ${t} times.`,pass:!0}}catch(o){return {message:()=>f(o),pass:false}}},async toBeAccessible(e,t={}){let o=await H(e),n=await o.first().evaluate(c=>{let u=c.ownerDocument?.defaultView;return u!==null&&u!==window.top}).catch(()=>false),i=G(t,n?V:[]),r,s=async()=>{let c=await q(o,t,i),u=t.treatIncompleteAsViolationIds??O,p=[...c.violations,...c.incomplete.filter(m=>u.includes(m.id))];return r={result:c,violations:p},p},l;try{if(t.timeout&&t.timeout>0){let c=test.expect.poll(s,{timeout:t.timeout});await(this.isNot?c.not.toHaveLength(0):c.toHaveLength(0));}else await s();}catch(c){l=c;}if(!r)throw new Error(`toBeAccessible: axe scan never completed.
13
- ${f(l)}`);if(r.violations.length===0)return {message:()=>"Expected accessibility violations but found none.",pass:true};this.isNot||await test.test.info().attach(t.attachmentName??"accessibility-scan-results",{body:JSON.stringify(r.result,null,2),contentType:"application/json"});let d=r.violations.map(c=>{let u=c.nodes.map(p=>Array.isArray(p.target)?p.target.join(" "):String(p.target)).join(`
14
- `);return ` \u2022 [${c.id}] ${c.help}
15
- ${u}
16
- ${c.helpUrl??""}`}).join(`
17
- `),a=r.violations.length;return {message:()=>`Found ${a} accessibility violation${a===1?"":"s"}:
18
- ${d}`,pass:false}},async toMatchClassTree(e,t,o={}){let{prefix:n=S,ignoreHashed:i=false}=o,r=await e.evaluate(A,{prefix:n,ignoreHashed:i});if(!r){let s=Array.isArray(n)?n.map(l=>`${l}*`).join(" / "):`${n}*`;return {message:()=>`No ${s} classes found in the DOM tree.`,pass:false}}try{let s=`${r}
19
- `,l=test.test.info();if(l.config.ignoreSnapshots)return {message:()=>"Class tree snapshot check skipped.",pass:!0};let a=X(l.project.snapshotDir,l.titlePath,t,n,i),c=l.config.updateSnapshots;await promises.mkdir(I__default.default.dirname(a),{recursive:!0});let u;try{u=await promises.readFile(a,"utf8");}catch(p){let m=p.code;if(m==="ENOENT"&&this.isNot)return {message:()=>`A class tree snapshot doesn't exist at ${a}, matchers using ".not" won't write them automatically.`,pass:!0};if(m==="ENOENT"&&c!=="none")return await promises.writeFile(a,s),c==="missing"?{message:()=>`A class tree snapshot doesn't exist at ${a}, writing actual.`,pass:!1,shouldNotRetryTest:!0}:{message:()=>"Class tree snapshot created.",pass:!0};throw p}if(u!==s){if(c==="all"||c==="changed")return await promises.writeFile(a,s),{message:()=>"Class tree snapshot updated.",pass:!0};try{test.expect(s).toBe(u);}catch(p){return {message:()=>`Class tree snapshot mismatch at ${a}
10
+ var L=["wcag2a","wcag2aa","wcag21a","wcag21aa","best-practice"],O=["landmark-one-main","page-has-heading-one","region","aria-allowed-role","duplicate-id","scrollable-region-focusable"],E=["aria-valid-attr-value","aria-valid-attr","aria-required-attr"];function C(e,t={}){let{prefix:o="BaselineUI-",ignoreHashed:r=false}=t,n=Array.isArray(o)?o:[o];function s(c){return c.split(/[-_]/).some(u=>u.length>=5&&/^[a-z\d]+$/.test(u)&&/[a-z]/.test(u)&&/\d/.test(u))}function l(c){return [...c.classList].filter(u=>n.some(m=>u.startsWith(m))&&(!r||!s(u)))}function p(c,u=false){let m=[],h=c.shadowRoot?c.shadowRoot.children:c.children;for(let f of h){let b=u||f.getAttribute("aria-hidden")==="true",x=l(f),w=p(f,b);x.length>0?m.push({classes:x,children:w,hidden:b}):m.push(...w);}return m}function d(c,u="",m=false){let h=[];for(let f=0;f<c.length;f++){let b=c[f],x=f===c.length-1,w=m?"":x?"\u2514\u2500\u2500 ":"\u251C\u2500\u2500 ",_=m?"":u+(x?" ":"\u2502 "),W=b.classes.join(", ");h.push(u+w+W+(b.hidden?" [aria-hidden]":""),...d(b.children,_));}return h}let a=l(e),i=p(e);return a.length===0&&i.length===0?"":a.length>0?d([{classes:a,children:i,hidden:false}],"",true).join(`
11
+ `):d(i,"",true).join(`
12
+ `)}var B=e=>{if(e instanceof Error)return e.message;if(typeof e=="string")return e;if(e==null)return "unknown error";try{return JSON.stringify(e)}catch{return "unstringifiable error"}},V=async e=>{let t=typeof e.goto=="function",o=!t&&typeof e.owner=="function";if(t||o)return e.locator("body");let r=e;return await r.first().evaluate(s=>s.tagName?.toLowerCase()==="iframe").catch(()=>false)?r.contentFrame().locator("body"):r},G=async e=>{await e.first().evaluate((t,o)=>{if(window.axe)return;let n=document.createElement("script");n.textContent=o,document.head.append(n);},j__default.default.source);},q=["document-title","html-has-lang","html-lang-valid","html-xml-lang-mismatch"],J=(e,t=[])=>{let o=new Set([...O,...t,...e.disableRules??[]]);return {runOnly:{type:"tag",values:[...e.tags??L]},rules:Object.fromEntries([...o].map(r=>[r,{enabled:false}]))}},I=e=>{if(e!==void 0)return typeof e=="string"?[e]:[...e]},K=async(e,t,o)=>{let r=await e.count();if(r===0)throw new Error("toBeAccessible: locator resolved to zero elements; nothing to scan.");await G(e);let n=I(t.include),s=I(t.exclude);return r===1?await e.evaluate(async(l,p)=>{let d=window,a={include:[l,...p.userInclude??[]],exclude:p.userExclude??[]};return await d.axe.run(a,p.runOptions)},{userInclude:n,userExclude:s,runOptions:o}):await e.evaluateAll(async(l,p)=>{let d=window,a={include:[...l,...p.userInclude??[]],exclude:p.userExclude??[]};return await d.axe.run(a,p.runOptions)},{userInclude:n,userExclude:s,runOptions:o})},A="BaselineUI-";function S(e){return e.replaceAll(/\W+/g,"-").replaceAll(/^-|-$/g,"")}function X(e){return Array.isArray(e)?e.length===1&&e[0]===A:e===A}function Q(e){return (Array.isArray(e)?e:[e]).join("+")}function Y(e,t,o,r,n){let s=t.slice(1).map(l=>S(l));return o&&s.push(S(o)),r!==void 0&&!X(r)&&s.push(S(Q(r))),n&&s.push("ignoreHashed"),F__default.default.join(e,`${s.join("--")}.txt`)}var T=(e,t)=>{if(typeof e?.callCount!="number")throw new TypeError(`${t}: expected a sinon spy.`)},Z=test.expect.extend({toBeWithinDelta(e,t,o){let r=Math.abs(e-t);if(Number.isNaN(r)||Number.isNaN(Number(o))||o<0)throw new TypeError(`toBeWithinDelta: cannot compare ${e} with ${t} within ${o}; expected numbers and a non-negative delta.`);return r<=o?{message:()=>`expected ${e} not to be within ${o} of ${t}`,pass:true}:{message:()=>`expected ${e} to be within ${o} of ${t}`,pass:false}},async toBeCalledOnce(e){T(e,"toBeCalledOnce");try{return await test.expect.poll(()=>e.callCount).toBe(1),{message:()=>"Expected function to be called once.",pass:!0}}catch(t){return {message:()=>B(t),pass:false}}},async toBeCalledTwice(e){T(e,"toBeCalledTwice");try{return await test.expect.poll(()=>e.callCount).toBe(2),{message:()=>"Expected function to be called twice.",pass:!0}}catch(t){return {message:()=>B(t),pass:false}}},async toBeCalledThrice(e){T(e,"toBeCalledThrice");try{return await test.expect.poll(()=>e.callCount).toBe(3),{message:()=>"Expected function to be called thrice.",pass:!0}}catch(t){return {message:()=>B(t),pass:false}}},async toBeCalledWith(e,...t){T(e,"toBeCalledWith");try{return await test.expect.poll(()=>({called:e.called,args:t.map((o,r)=>e.lastCall?.args[r])})).toStrictEqual({called:!0,args:t}),{message:()=>`Expected function to be called with ${t.join(", ")}.`,pass:!0}}catch(o){return {message:()=>B(o),pass:false}}},async toBeCalledWithExactly(e,...t){T(e,"toBeCalledWithExactly");try{return await test.expect.poll(()=>e.lastCall?.args).toStrictEqual(t),{message:()=>`Expected function to be called with exactly ${t.join(", ")}.`,pass:!0}}catch(o){return {message:()=>B(o),pass:false}}},toBeCalled(e){T(e,"toBeCalled");try{return test.expect(e.called).toBeTruthy(),{message:()=>"Expected function to be called.",pass:!0}}catch(t){return {message:()=>B(t),pass:false}}},async toBeCalledTimes(e,t){if(T(e,"toBeCalledTimes"),!Number.isInteger(t)||t<0)throw new TypeError("toBeCalledTimes: times must be a non-negative integer.");try{return await test.expect.poll(()=>e.callCount).toBe(t),{message:()=>`Expected function to be called ${t} times.`,pass:!0}}catch(o){return {message:()=>B(o),pass:false}}},async toBeAccessible(e,t={}){let o=await V(e),r=await o.first().evaluate(i=>{let c=i.ownerDocument?.defaultView;return c!==null&&c!==window.top}).catch(()=>false),n=J(t,r?q:[]),s,l=async()=>{let i=await K(o,t,n),c=t.treatIncompleteAsViolationIds??E,u=[...i.violations,...i.incomplete.filter(m=>c.includes(m.id))];return s={result:i,violations:u},u},p;try{if(t.timeout&&t.timeout>0){let i=test.expect.poll(l,{timeout:t.timeout});await(this.isNot?i.not.toHaveLength(0):i.toHaveLength(0));}else await l();}catch(i){p=i;}if(!s)throw new Error(`toBeAccessible: axe scan never completed.
13
+ ${B(p)}`);if(s.violations.length===0)return {message:()=>"Expected accessibility violations but found none.",pass:true};this.isNot||await test.test.info().attach(t.attachmentName??"accessibility-scan-results",{body:JSON.stringify(s.result,null,2),contentType:"application/json"});let d=s.violations.map(i=>{let c=i.nodes.map(u=>Array.isArray(u.target)?u.target.join(" "):String(u.target)).join(`
14
+ `);return ` \u2022 [${i.id}] ${i.help}
15
+ ${c}
16
+ ${i.helpUrl??""}`}).join(`
17
+ `),a=s.violations.length;return {message:()=>`Found ${a} accessibility violation${a===1?"":"s"}:
18
+ ${d}`,pass:false}},async toMatchClassTree(e,t,o={}){let{prefix:r=A,ignoreHashed:n=false}=o,s=await e.evaluate(C,{prefix:r,ignoreHashed:n});if(!s){let u=Array.isArray(r)?r.map(m=>`${m}*`).join(" / "):`${r}*`;throw new Error(`No ${u} classes found in the DOM tree.`)}let l=`${s}
19
+ `,p=test.test.info();if(p.config.ignoreSnapshots)return {message:()=>"Class tree snapshot check skipped.",pass:true};let a=Y(p.project.snapshotDir,p.titlePath,t,r,n),i=p.config.updateSnapshots,c;try{c=await promises.readFile(a,"utf8");}catch(u){let m=u.code;if(m==="ENOENT"&&this.isNot)return {message:()=>`A class tree snapshot doesn't exist at ${a}, matchers using ".not" won't write them automatically.`,pass:true};if(m==="ENOENT"&&i!=="none")return await promises.mkdir(F__default.default.dirname(a),{recursive:true}),await promises.writeFile(a,l),i==="missing"?{message:()=>`A class tree snapshot doesn't exist at ${a}, writing actual.`,pass:false,shouldNotRetryTest:true}:{message:()=>"Class tree snapshot created.",pass:true};throw u}if(c!==l){if(!this.isNot&&(i==="all"||i==="changed"))return await promises.writeFile(a,l),{message:()=>"Class tree snapshot updated.",pass:true};try{test.expect(l).toBe(c);}catch(u){return {message:()=>`Class tree snapshot mismatch at ${a}
20
20
 
21
- ${p.message}`,pass:!1}}}return {message:()=>"Class tree matched snapshot.",pass:!0}}catch(s){return {message:()=>f(s),pass:false}}}});function g(e){let t=async()=>{if(await e.getAttribute("aria-expanded")!==null)return e;let i=e.locator("[aria-expanded]").first();return await i.count()>0?i:e},o=async()=>await(await t()).getAttribute("aria-expanded")==="true";return {isOpen:o,open:async(i="click")=>{if(await o())return;if(i==="click"){await e.click();return}await(await t()).press(i);}}}function F({frame:e,trigger:t,toggleButton:o}){let n=t??e.getByRole("combobox",{includeHidden:true}),i=o??e.getByTestId("combobox-toggle-button"),r=a=>e.getByRole("option",{name:a,exact:typeof a=="string"}),{isOpen:s,open:l}=g(n),d=async(a="click")=>{if(!await s()){if(a==="click"){await i.click();return}await l(a);}};return {input:n,toggleButton:i,listbox:e.getByRole("listbox"),option:r,isOpen:s,open:d,async selectOption(a){await d(),await r(a).click();},async filter(a){await n.fill(a);}}}function v({frame:e,root:t}){let o=t??e.locator(".BaselineUI-Editor"),n=o.getByTestId("editor-font-color-button"),i=o.getByTestId("editor-background-color-button"),r=o.getByTestId("editor-add-link-button"),s=o.getByTestId("editor-help-button"),l=o.getByTestId("editor-mention-button"),d=o.getByRole("combobox"),a=e.getByTestId("editor-mention-listbox"),c=e.getByTestId("editor-help-dialog-close-button"),u=e.getByRole("dialog").filter({has:c}),p=e.getByRole("dialog").filter({has:e.getByTestId(/^editor-link-/)});return {root:o,textbox:o.getByRole("textbox"),placeholder:o.getByTestId("editor-placeholder"),toolbar:o.getByRole("toolbar"),boldButton:o.getByTestId("editor-bold-button"),italicButton:o.getByTestId("editor-italic-button"),underlineButton:o.getByTestId("editor-underline-button"),fontColorButton:n,backgroundColorButton:i,openFontColorPicker:g(n).open,openBackgroundColorPicker:g(i).open,addLinkButton:r,linkDialog:p,linkInput:e.getByTestId("editor-link-input"),linkAddButton:e.getByTestId("editor-link-add-button"),linkEditButton:e.getByTestId("editor-link-edit-button"),linkRemoveButton:e.getByTestId("editor-link-remove-button"),linkCancelButton:e.getByTestId("editor-link-cancel-button"),linkSaveButton:e.getByTestId("editor-link-save-button"),openLinkDialog:g(r).open,saveButton:o.getByTestId("editor-save-button"),cancelButton:o.getByTestId("editor-cancel-button"),mentionButton:l,helpButton:s,helpDialog:u,helpDialogCloseButton:c,async openHelpDialog(){await u.isVisible()||await s.click();},mentionInput:d,mentionListbox:a,mentionOption:m=>a.getByRole("option",{name:m}),async startMention(){await d.isVisible()||await l.click();}}}function D({frame:e,trigger:t,variant:o="dropzone"}){let n=e.getByTestId("file-uploader"),i=n.locator('input[type="file"]'),r=t??(o==="button"?n.getByRole("button"):e.getByTestId("file-uploader-dropzone"));return {root:n,button:r,input:i,dropzone:e.getByTestId("file-uploader-dropzone"),errorMessage:n.getByRole("alert"),async upload(s){await i.setInputFiles(s);}}}function P(e,t,o){let n=s=>t.getByRole("menuitem",{name:s}).or(t.getByRole("menuitemradio",{name:s})).or(t.getByRole("menuitemcheckbox",{name:s})),i=s=>t.getByRole("group",{name:s}),{isOpen:r}=g(o);return {menu:t,item:n,section:i,isOpen:r,submenu(s){let l=n(s),d=e.getByRole("menu",{name:s}),a=P(e,d,l),{open:c}=g(l);return {...a,trigger:l,open:async(u="Enter")=>c(u)}}}}function U({frame:e,trigger:t}){let o=t??e.getByTestId("menu-trigger"),n=e.getByRole("menu").first(),i=P(e,n,o),{open:r,isOpen:s}=g(o);return {...i,trigger:o,open:r,isOpen:s,async close(){await s()&&await o.press("Escape");},async selectItem(l){await r(),await i.item(l).click();}}}var M=(e=>{let o=Y(e);return e.multiple&&(o=Z(o,e.frame)),e.autocomplete&&(o=ee(o,e.frame)),o});function Y({frame:e,trigger:t}){let o=t??e.getByTestId("select-button"),n=r=>e.getByRole("option",{name:r,exact:typeof r=="string"}),{open:i}=g(o);return {trigger:o,listbox:e.getByRole("listbox"),option:n,open:i,async selectOption(r){await i(),await n(r).click();}}}function Z(e,t){return {...e,selectAllButton:t.getByTestId("select-all-button"),clearButton:t.getByTestId("select-clear-button"),tag:o=>e.trigger.getByRole("row",{name:o}),removeTagButton:o=>e.trigger.getByRole("row",{name:o}).getByRole("button")}}function ee(e,t){let o=t.getByRole("searchbox");return {...e,searchbox:o,async filter(n){await o.fill(n);}}}function te(e){return {select:((t={})=>M({frame:e,...t})),comboBox:(t={})=>F({frame:e,...t}),editor:(t={})=>v({frame:e,...t}),fileUploader:(t={})=>D({frame:e,...t}),menu:(t={})=>U({frame:e,...t})}}exports.DEFAULT_CRITICAL_INCOMPLETE_RULES=O;exports.DEFAULT_DISABLED_RULES=L;exports.DEFAULT_WCAG_TAGS=w;exports.expect=Q;exports.testers=te;
21
+ ${u.message}`,pass:false}}}return {message:()=>"Class tree matched snapshot.",pass:true}}});function v({frame:e,name:t}){let o=e.locator(".BaselineUI-Breadcrumbs"),r=t===void 0?o:o.and(e.getByRole("navigation",{name:t,exact:typeof t=="string"}));return {root:r,current:r.locator('[aria-current="page"]'),separators:r.getByTestId("breadcrumbs-separator"),item:n=>r.getByRole("link",{name:n,exact:typeof n=="string"})}}function g(e){let t=async()=>{if(await e.getAttribute("aria-expanded")!==null)return e;let n=e.locator("[aria-expanded]").first();return await n.count()>0?n:e},o=async()=>await(await t()).getAttribute("aria-expanded")==="true";return {button:t,isOpen:o,open:async(n="click")=>{if(await o())return;if(n==="click"){await e.click();return}await(await t()).press(n);}}}function D({frame:e,trigger:t,toggleButton:o}){let r=t??e.getByRole("combobox",{includeHidden:true}),n=o??e.getByTestId("combobox-toggle-button"),s=a=>e.getByRole("option",{name:a,exact:typeof a=="string"}),{isOpen:l,open:p}=g(r),d=async(a="click")=>{if(!await l()){if(a==="click"){await n.click();return}await p(a);}};return {input:r,toggleButton:n,listbox:e.getByRole("listbox"),option:s,isOpen:l,open:d,async selectOption(a){await d(),await s(a).click();},async filter(a){await r.fill(a);}}}function P({frame:e,root:t}){let o=t??e.locator(".BaselineUI-Editor"),r=o.getByTestId("editor-font-color-button"),n=o.getByTestId("editor-background-color-button"),s=o.getByTestId("editor-add-link-button"),l=o.getByTestId("editor-help-button"),p=o.getByTestId("editor-mention-button"),d=o.getByRole("combobox"),a=e.getByTestId("editor-mention-listbox"),i=e.getByTestId("editor-help-dialog-close-button"),c=e.getByRole("dialog").filter({has:i}),u=e.getByRole("dialog").filter({has:e.getByTestId(/^editor-link-/)});return {root:o,textbox:o.getByRole("textbox"),placeholder:o.getByTestId("editor-placeholder"),toolbar:o.getByRole("toolbar"),boldButton:o.getByTestId("editor-bold-button"),italicButton:o.getByTestId("editor-italic-button"),underlineButton:o.getByTestId("editor-underline-button"),fontColorButton:r,backgroundColorButton:n,openFontColorPicker:g(r).open,openBackgroundColorPicker:g(n).open,addLinkButton:s,linkDialog:u,linkInput:e.getByTestId("editor-link-input"),linkAddButton:e.getByTestId("editor-link-add-button"),linkEditButton:e.getByTestId("editor-link-edit-button"),linkRemoveButton:e.getByTestId("editor-link-remove-button"),linkCancelButton:e.getByTestId("editor-link-cancel-button"),linkSaveButton:e.getByTestId("editor-link-save-button"),openLinkDialog:g(s).open,saveButton:o.getByTestId("editor-save-button"),cancelButton:o.getByTestId("editor-cancel-button"),mentionButton:p,helpButton:l,helpDialog:c,helpDialogCloseButton:i,async openHelpDialog(){await c.isVisible()||await l.click();},mentionInput:d,mentionListbox:a,mentionOption:m=>a.getByRole("option",{name:m}),async startMention(){await d.isVisible()||await p.click();}}}function U({frame:e,trigger:t,variant:o="dropzone"}){let r=e.getByTestId("file-uploader"),n=r.locator('input[type="file"]'),s=t??(o==="button"?r.getByRole("button"):e.getByTestId("file-uploader-dropzone"));return {root:r,button:s,input:n,dropzone:e.getByTestId("file-uploader-dropzone"),errorMessage:r.getByRole("alert"),async upload(l){await n.setInputFiles(l);}}}function M(e,t,o){let r=l=>t.getByRole("menuitem",{name:l}).or(t.getByRole("menuitemradio",{name:l})).or(t.getByRole("menuitemcheckbox",{name:l})),n=l=>t.getByRole("group",{name:l}),{isOpen:s}=g(o);return {menu:t,item:r,section:n,isOpen:s,submenu(l){let p=r(l),d=e.getByRole("menu",{name:l}),a=M(e,d,p),{open:i}=g(p);return {...a,trigger:p,open:async(c="Enter")=>i(c)}}}}function $({frame:e,trigger:t,longPress:o=false}){let r=t??e.getByTestId("menu-trigger"),n=e.getByRole("menu").first(),s=M(e,n,r),{button:l,open:p,isOpen:d}=g(r),a=async(i="click")=>{if(!o)return p(i);if(i==="ArrowLeft"||i==="ArrowRight")throw new Error(`menuTester: cannot open a long-press menu with "${i}"; use "click", "Enter", "Space", "ArrowDown" or "ArrowUp"`);if(await d())return;let c=await l();if(i==="click"){await c.click({delay:800});return}await c.press(`Alt+${i}`);};return {...s,trigger:r,open:a,isOpen:d,async close(){await d()&&await r.press("Escape");},async selectItem(i){await a(),await s.item(i).click();}}}var N=(e=>{let o=ee(e);return e.multiple&&(o=te(o,e.frame)),e.autocomplete&&(o=oe(o,e.frame)),o});function ee({frame:e,trigger:t}){let o=t??e.getByTestId("select-button"),r=s=>e.getByRole("option",{name:s,exact:typeof s=="string"}),{open:n}=g(o);return {trigger:o,listbox:e.getByRole("listbox"),option:r,open:n,async selectOption(s){await n(),await r(s).click();}}}function te(e,t){return {...e,selectAllButton:t.getByTestId("select-all-button"),clearButton:t.getByTestId("select-clear-button"),tag:o=>e.trigger.getByRole("row",{name:o}),removeTagButton:o=>e.trigger.getByRole("row",{name:o}).getByRole("button")}}function oe(e,t){let o=t.getByRole("searchbox");return {...e,searchbox:o,async filter(r){await o.fill(r);}}}function re(e){return {select:((t={})=>N({frame:e,...t})),comboBox:(t={})=>D({frame:e,...t}),editor:(t={})=>P({frame:e,...t}),fileUploader:(t={})=>U({frame:e,...t}),menu:(t={})=>$({frame:e,...t}),breadcrumbs:(t={})=>v({frame:e,...t})}}exports.DEFAULT_CRITICAL_INCOMPLETE_RULES=E;exports.DEFAULT_DISABLED_RULES=O;exports.DEFAULT_WCAG_TAGS=L;exports.expect=Z;exports.testers=re;
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import {expect,test}from'@playwright/test';import W from'axe-core';import {mkdir,readFile,writeFile}from'fs/promises';import I from'path';/**
1
+ import {expect,test}from'@playwright/test';import j from'axe-core';import {readFile,mkdir,writeFile}from'fs/promises';import F from'path';/**
2
2
  * Copyright (c) 2023-2024 PSPDFKit GmbH. All rights reserved.
3
3
  *
4
4
  * THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
@@ -7,15 +7,15 @@ import {expect,test}from'@playwright/test';import W from'axe-core';import {mkdir
7
7
  * This notice may not be removed from this file.
8
8
  *
9
9
  */
10
- var w=["wcag2a","wcag2aa","wcag21a","wcag21aa","best-practice"],L=["landmark-one-main","page-has-heading-one","region","aria-allowed-role","duplicate-id","scrollable-region-focusable"],O=["aria-valid-attr-value","aria-valid-attr","aria-required-attr"];function A(e,t={}){let{prefix:o="BaselineUI-",ignoreHashed:n=false}=t,i=Array.isArray(o)?o:[o];function r(u){return u.split(/[-_]/).some(p=>p.length>=5&&/^[a-z\d]+$/.test(p)&&/[a-z]/.test(p)&&/\d/.test(p))}function s(u){return [...u.classList].filter(p=>i.some(m=>p.startsWith(m))&&(!n||!r(p)))}function l(u,p=false){let m=[],h=u.shadowRoot?u.shadowRoot.children:u.children;for(let T of h){let x=p||T.getAttribute("aria-hidden")==="true",B=s(T),b=l(T,x);B.length>0?m.push({classes:B,children:b,hidden:x}):m.push(...b);}return m}function d(u,p="",m=false){let h=[];for(let T=0;T<u.length;T++){let x=u[T],B=T===u.length-1,b=m?"":B?"\u2514\u2500\u2500 ":"\u251C\u2500\u2500 ",_=m?"":p+(B?" ":"\u2502 "),$=x.classes.join(", ");h.push(p+b+$+(x.hidden?" [aria-hidden]":""),...d(x.children,_));}return h}let a=s(e),c=l(e);return a.length===0&&c.length===0?"":a.length>0?d([{classes:a,children:c,hidden:false}],"",true).join(`
11
- `):d(c,"",true).join(`
12
- `)}var f=e=>{if(e instanceof Error)return e.message;if(typeof e=="string")return e;if(e==null)return "unknown error";try{return JSON.stringify(e)}catch{return "unstringifiable error"}},H=async e=>{let t=typeof e.goto=="function",o=!t&&typeof e.owner=="function";if(t||o)return e.locator("body");let n=e;return await n.first().evaluate(r=>r.tagName?.toLowerCase()==="iframe").catch(()=>false)?n.contentFrame().locator("body"):n},z=async e=>{await e.first().evaluate((t,o)=>{if(window.axe)return;let i=document.createElement("script");i.textContent=o,document.head.append(i);},W.source);},V=["document-title","html-has-lang","html-lang-valid","html-xml-lang-mismatch"],G=(e,t=[])=>{let o=new Set([...L,...t,...e.disableRules??[]]);return {runOnly:{type:"tag",values:[...e.tags??w]},rules:Object.fromEntries([...o].map(n=>[n,{enabled:false}]))}},k=e=>{if(e!==void 0)return typeof e=="string"?[e]:[...e]},q=async(e,t,o)=>{let n=await e.count();if(n===0)throw new Error("toBeAccessible: locator resolved to zero elements; nothing to scan.");await z(e);let i=k(t.include),r=k(t.exclude);return n===1?await e.evaluate(async(s,l)=>{let d=window,a={include:[s,...l.userInclude??[]],exclude:l.userExclude??[]};return await d.axe.run(a,l.runOptions)},{userInclude:i,userExclude:r,runOptions:o}):await e.evaluateAll(async(s,l)=>{let d=window,a={include:[...s,...l.userInclude??[]],exclude:l.userExclude??[]};return await d.axe.run(a,l.runOptions)},{userInclude:i,userExclude:r,runOptions:o})},S="BaselineUI-";function E(e){return e.replaceAll(/\W+/g,"-").replaceAll(/^-|-$/g,"")}function J(e){return Array.isArray(e)?e.length===1&&e[0]===S:e===S}function K(e){return (Array.isArray(e)?e:[e]).join("+")}function X(e,t,o,n,i){let r=t.slice(1).map(s=>E(s));return o&&r.push(E(o)),n!==void 0&&!J(n)&&r.push(E(K(n))),i&&r.push("ignoreHashed"),I.join(e,`${r.join("--")}.txt`)}var Q=expect.extend({toBeWithinDelta(e,t,o){return Math.abs(e-t)<=o?{message:()=>`expected ${e} not to be within ${o} of ${t}`,pass:true}:{message:()=>`expected ${e} to be within ${o} of ${t}`,pass:false}},async toBeCalledOnce(e){try{return await expect.poll(()=>e.callCount).toBe(1),{message:()=>"Expected function to be called once.",pass:!0}}catch(t){return {message:()=>f(t),pass:false}}},async toBeCalledTwice(e){try{return await expect.poll(()=>e.callCount).toBe(2),{message:()=>"Expected function to be called twice.",pass:!0}}catch(t){return {message:()=>f(t),pass:false}}},async toBeCalledThrice(e){try{return await expect.poll(()=>e.callCount).toBe(3),{message:()=>"Expected function to be called thrice.",pass:!0}}catch(t){return {message:()=>f(t),pass:false}}},async toBeCalledWith(e,...t){try{return await expect.poll(()=>({called:e.called,args:t.map((o,n)=>e.lastCall?.args[n])})).toStrictEqual({called:!0,args:t}),{message:()=>`Expected function to be called with ${t.join(", ")}.`,pass:!0}}catch(o){return {message:()=>f(o),pass:false}}},async toBeCalledWithExactly(e,...t){try{return await expect.poll(()=>e.lastCall?.args).toStrictEqual(t),{message:()=>`Expected function to be called with exactly ${t.join(", ")}.`,pass:!0}}catch(o){return {message:()=>f(o),pass:false}}},toBeCalled(e){try{return expect(e.called).toBeTruthy(),{message:()=>"Expected function to be called.",pass:!0}}catch(t){return {message:()=>f(t),pass:false}}},async toBeCalledTimes(e,t){try{return await expect.poll(()=>e.callCount).toBe(t),{message:()=>`Expected function to be called ${t} times.`,pass:!0}}catch(o){return {message:()=>f(o),pass:false}}},async toBeAccessible(e,t={}){let o=await H(e),n=await o.first().evaluate(c=>{let u=c.ownerDocument?.defaultView;return u!==null&&u!==window.top}).catch(()=>false),i=G(t,n?V:[]),r,s=async()=>{let c=await q(o,t,i),u=t.treatIncompleteAsViolationIds??O,p=[...c.violations,...c.incomplete.filter(m=>u.includes(m.id))];return r={result:c,violations:p},p},l;try{if(t.timeout&&t.timeout>0){let c=expect.poll(s,{timeout:t.timeout});await(this.isNot?c.not.toHaveLength(0):c.toHaveLength(0));}else await s();}catch(c){l=c;}if(!r)throw new Error(`toBeAccessible: axe scan never completed.
13
- ${f(l)}`);if(r.violations.length===0)return {message:()=>"Expected accessibility violations but found none.",pass:true};this.isNot||await test.info().attach(t.attachmentName??"accessibility-scan-results",{body:JSON.stringify(r.result,null,2),contentType:"application/json"});let d=r.violations.map(c=>{let u=c.nodes.map(p=>Array.isArray(p.target)?p.target.join(" "):String(p.target)).join(`
14
- `);return ` \u2022 [${c.id}] ${c.help}
15
- ${u}
16
- ${c.helpUrl??""}`}).join(`
17
- `),a=r.violations.length;return {message:()=>`Found ${a} accessibility violation${a===1?"":"s"}:
18
- ${d}`,pass:false}},async toMatchClassTree(e,t,o={}){let{prefix:n=S,ignoreHashed:i=false}=o,r=await e.evaluate(A,{prefix:n,ignoreHashed:i});if(!r){let s=Array.isArray(n)?n.map(l=>`${l}*`).join(" / "):`${n}*`;return {message:()=>`No ${s} classes found in the DOM tree.`,pass:false}}try{let s=`${r}
19
- `,l=test.info();if(l.config.ignoreSnapshots)return {message:()=>"Class tree snapshot check skipped.",pass:!0};let a=X(l.project.snapshotDir,l.titlePath,t,n,i),c=l.config.updateSnapshots;await mkdir(I.dirname(a),{recursive:!0});let u;try{u=await readFile(a,"utf8");}catch(p){let m=p.code;if(m==="ENOENT"&&this.isNot)return {message:()=>`A class tree snapshot doesn't exist at ${a}, matchers using ".not" won't write them automatically.`,pass:!0};if(m==="ENOENT"&&c!=="none")return await writeFile(a,s),c==="missing"?{message:()=>`A class tree snapshot doesn't exist at ${a}, writing actual.`,pass:!1,shouldNotRetryTest:!0}:{message:()=>"Class tree snapshot created.",pass:!0};throw p}if(u!==s){if(c==="all"||c==="changed")return await writeFile(a,s),{message:()=>"Class tree snapshot updated.",pass:!0};try{expect(s).toBe(u);}catch(p){return {message:()=>`Class tree snapshot mismatch at ${a}
10
+ var L=["wcag2a","wcag2aa","wcag21a","wcag21aa","best-practice"],O=["landmark-one-main","page-has-heading-one","region","aria-allowed-role","duplicate-id","scrollable-region-focusable"],E=["aria-valid-attr-value","aria-valid-attr","aria-required-attr"];function C(e,t={}){let{prefix:o="BaselineUI-",ignoreHashed:r=false}=t,n=Array.isArray(o)?o:[o];function s(c){return c.split(/[-_]/).some(u=>u.length>=5&&/^[a-z\d]+$/.test(u)&&/[a-z]/.test(u)&&/\d/.test(u))}function l(c){return [...c.classList].filter(u=>n.some(m=>u.startsWith(m))&&(!r||!s(u)))}function p(c,u=false){let m=[],h=c.shadowRoot?c.shadowRoot.children:c.children;for(let f of h){let b=u||f.getAttribute("aria-hidden")==="true",x=l(f),w=p(f,b);x.length>0?m.push({classes:x,children:w,hidden:b}):m.push(...w);}return m}function d(c,u="",m=false){let h=[];for(let f=0;f<c.length;f++){let b=c[f],x=f===c.length-1,w=m?"":x?"\u2514\u2500\u2500 ":"\u251C\u2500\u2500 ",_=m?"":u+(x?" ":"\u2502 "),W=b.classes.join(", ");h.push(u+w+W+(b.hidden?" [aria-hidden]":""),...d(b.children,_));}return h}let a=l(e),i=p(e);return a.length===0&&i.length===0?"":a.length>0?d([{classes:a,children:i,hidden:false}],"",true).join(`
11
+ `):d(i,"",true).join(`
12
+ `)}var B=e=>{if(e instanceof Error)return e.message;if(typeof e=="string")return e;if(e==null)return "unknown error";try{return JSON.stringify(e)}catch{return "unstringifiable error"}},V=async e=>{let t=typeof e.goto=="function",o=!t&&typeof e.owner=="function";if(t||o)return e.locator("body");let r=e;return await r.first().evaluate(s=>s.tagName?.toLowerCase()==="iframe").catch(()=>false)?r.contentFrame().locator("body"):r},G=async e=>{await e.first().evaluate((t,o)=>{if(window.axe)return;let n=document.createElement("script");n.textContent=o,document.head.append(n);},j.source);},q=["document-title","html-has-lang","html-lang-valid","html-xml-lang-mismatch"],J=(e,t=[])=>{let o=new Set([...O,...t,...e.disableRules??[]]);return {runOnly:{type:"tag",values:[...e.tags??L]},rules:Object.fromEntries([...o].map(r=>[r,{enabled:false}]))}},I=e=>{if(e!==void 0)return typeof e=="string"?[e]:[...e]},K=async(e,t,o)=>{let r=await e.count();if(r===0)throw new Error("toBeAccessible: locator resolved to zero elements; nothing to scan.");await G(e);let n=I(t.include),s=I(t.exclude);return r===1?await e.evaluate(async(l,p)=>{let d=window,a={include:[l,...p.userInclude??[]],exclude:p.userExclude??[]};return await d.axe.run(a,p.runOptions)},{userInclude:n,userExclude:s,runOptions:o}):await e.evaluateAll(async(l,p)=>{let d=window,a={include:[...l,...p.userInclude??[]],exclude:p.userExclude??[]};return await d.axe.run(a,p.runOptions)},{userInclude:n,userExclude:s,runOptions:o})},A="BaselineUI-";function S(e){return e.replaceAll(/\W+/g,"-").replaceAll(/^-|-$/g,"")}function X(e){return Array.isArray(e)?e.length===1&&e[0]===A:e===A}function Q(e){return (Array.isArray(e)?e:[e]).join("+")}function Y(e,t,o,r,n){let s=t.slice(1).map(l=>S(l));return o&&s.push(S(o)),r!==void 0&&!X(r)&&s.push(S(Q(r))),n&&s.push("ignoreHashed"),F.join(e,`${s.join("--")}.txt`)}var T=(e,t)=>{if(typeof e?.callCount!="number")throw new TypeError(`${t}: expected a sinon spy.`)},Z=expect.extend({toBeWithinDelta(e,t,o){let r=Math.abs(e-t);if(Number.isNaN(r)||Number.isNaN(Number(o))||o<0)throw new TypeError(`toBeWithinDelta: cannot compare ${e} with ${t} within ${o}; expected numbers and a non-negative delta.`);return r<=o?{message:()=>`expected ${e} not to be within ${o} of ${t}`,pass:true}:{message:()=>`expected ${e} to be within ${o} of ${t}`,pass:false}},async toBeCalledOnce(e){T(e,"toBeCalledOnce");try{return await expect.poll(()=>e.callCount).toBe(1),{message:()=>"Expected function to be called once.",pass:!0}}catch(t){return {message:()=>B(t),pass:false}}},async toBeCalledTwice(e){T(e,"toBeCalledTwice");try{return await expect.poll(()=>e.callCount).toBe(2),{message:()=>"Expected function to be called twice.",pass:!0}}catch(t){return {message:()=>B(t),pass:false}}},async toBeCalledThrice(e){T(e,"toBeCalledThrice");try{return await expect.poll(()=>e.callCount).toBe(3),{message:()=>"Expected function to be called thrice.",pass:!0}}catch(t){return {message:()=>B(t),pass:false}}},async toBeCalledWith(e,...t){T(e,"toBeCalledWith");try{return await expect.poll(()=>({called:e.called,args:t.map((o,r)=>e.lastCall?.args[r])})).toStrictEqual({called:!0,args:t}),{message:()=>`Expected function to be called with ${t.join(", ")}.`,pass:!0}}catch(o){return {message:()=>B(o),pass:false}}},async toBeCalledWithExactly(e,...t){T(e,"toBeCalledWithExactly");try{return await expect.poll(()=>e.lastCall?.args).toStrictEqual(t),{message:()=>`Expected function to be called with exactly ${t.join(", ")}.`,pass:!0}}catch(o){return {message:()=>B(o),pass:false}}},toBeCalled(e){T(e,"toBeCalled");try{return expect(e.called).toBeTruthy(),{message:()=>"Expected function to be called.",pass:!0}}catch(t){return {message:()=>B(t),pass:false}}},async toBeCalledTimes(e,t){if(T(e,"toBeCalledTimes"),!Number.isInteger(t)||t<0)throw new TypeError("toBeCalledTimes: times must be a non-negative integer.");try{return await expect.poll(()=>e.callCount).toBe(t),{message:()=>`Expected function to be called ${t} times.`,pass:!0}}catch(o){return {message:()=>B(o),pass:false}}},async toBeAccessible(e,t={}){let o=await V(e),r=await o.first().evaluate(i=>{let c=i.ownerDocument?.defaultView;return c!==null&&c!==window.top}).catch(()=>false),n=J(t,r?q:[]),s,l=async()=>{let i=await K(o,t,n),c=t.treatIncompleteAsViolationIds??E,u=[...i.violations,...i.incomplete.filter(m=>c.includes(m.id))];return s={result:i,violations:u},u},p;try{if(t.timeout&&t.timeout>0){let i=expect.poll(l,{timeout:t.timeout});await(this.isNot?i.not.toHaveLength(0):i.toHaveLength(0));}else await l();}catch(i){p=i;}if(!s)throw new Error(`toBeAccessible: axe scan never completed.
13
+ ${B(p)}`);if(s.violations.length===0)return {message:()=>"Expected accessibility violations but found none.",pass:true};this.isNot||await test.info().attach(t.attachmentName??"accessibility-scan-results",{body:JSON.stringify(s.result,null,2),contentType:"application/json"});let d=s.violations.map(i=>{let c=i.nodes.map(u=>Array.isArray(u.target)?u.target.join(" "):String(u.target)).join(`
14
+ `);return ` \u2022 [${i.id}] ${i.help}
15
+ ${c}
16
+ ${i.helpUrl??""}`}).join(`
17
+ `),a=s.violations.length;return {message:()=>`Found ${a} accessibility violation${a===1?"":"s"}:
18
+ ${d}`,pass:false}},async toMatchClassTree(e,t,o={}){let{prefix:r=A,ignoreHashed:n=false}=o,s=await e.evaluate(C,{prefix:r,ignoreHashed:n});if(!s){let u=Array.isArray(r)?r.map(m=>`${m}*`).join(" / "):`${r}*`;throw new Error(`No ${u} classes found in the DOM tree.`)}let l=`${s}
19
+ `,p=test.info();if(p.config.ignoreSnapshots)return {message:()=>"Class tree snapshot check skipped.",pass:true};let a=Y(p.project.snapshotDir,p.titlePath,t,r,n),i=p.config.updateSnapshots,c;try{c=await readFile(a,"utf8");}catch(u){let m=u.code;if(m==="ENOENT"&&this.isNot)return {message:()=>`A class tree snapshot doesn't exist at ${a}, matchers using ".not" won't write them automatically.`,pass:true};if(m==="ENOENT"&&i!=="none")return await mkdir(F.dirname(a),{recursive:true}),await writeFile(a,l),i==="missing"?{message:()=>`A class tree snapshot doesn't exist at ${a}, writing actual.`,pass:false,shouldNotRetryTest:true}:{message:()=>"Class tree snapshot created.",pass:true};throw u}if(c!==l){if(!this.isNot&&(i==="all"||i==="changed"))return await writeFile(a,l),{message:()=>"Class tree snapshot updated.",pass:true};try{expect(l).toBe(c);}catch(u){return {message:()=>`Class tree snapshot mismatch at ${a}
20
20
 
21
- ${p.message}`,pass:!1}}}return {message:()=>"Class tree matched snapshot.",pass:!0}}catch(s){return {message:()=>f(s),pass:false}}}});function g(e){let t=async()=>{if(await e.getAttribute("aria-expanded")!==null)return e;let i=e.locator("[aria-expanded]").first();return await i.count()>0?i:e},o=async()=>await(await t()).getAttribute("aria-expanded")==="true";return {isOpen:o,open:async(i="click")=>{if(await o())return;if(i==="click"){await e.click();return}await(await t()).press(i);}}}function F({frame:e,trigger:t,toggleButton:o}){let n=t??e.getByRole("combobox",{includeHidden:true}),i=o??e.getByTestId("combobox-toggle-button"),r=a=>e.getByRole("option",{name:a,exact:typeof a=="string"}),{isOpen:s,open:l}=g(n),d=async(a="click")=>{if(!await s()){if(a==="click"){await i.click();return}await l(a);}};return {input:n,toggleButton:i,listbox:e.getByRole("listbox"),option:r,isOpen:s,open:d,async selectOption(a){await d(),await r(a).click();},async filter(a){await n.fill(a);}}}function v({frame:e,root:t}){let o=t??e.locator(".BaselineUI-Editor"),n=o.getByTestId("editor-font-color-button"),i=o.getByTestId("editor-background-color-button"),r=o.getByTestId("editor-add-link-button"),s=o.getByTestId("editor-help-button"),l=o.getByTestId("editor-mention-button"),d=o.getByRole("combobox"),a=e.getByTestId("editor-mention-listbox"),c=e.getByTestId("editor-help-dialog-close-button"),u=e.getByRole("dialog").filter({has:c}),p=e.getByRole("dialog").filter({has:e.getByTestId(/^editor-link-/)});return {root:o,textbox:o.getByRole("textbox"),placeholder:o.getByTestId("editor-placeholder"),toolbar:o.getByRole("toolbar"),boldButton:o.getByTestId("editor-bold-button"),italicButton:o.getByTestId("editor-italic-button"),underlineButton:o.getByTestId("editor-underline-button"),fontColorButton:n,backgroundColorButton:i,openFontColorPicker:g(n).open,openBackgroundColorPicker:g(i).open,addLinkButton:r,linkDialog:p,linkInput:e.getByTestId("editor-link-input"),linkAddButton:e.getByTestId("editor-link-add-button"),linkEditButton:e.getByTestId("editor-link-edit-button"),linkRemoveButton:e.getByTestId("editor-link-remove-button"),linkCancelButton:e.getByTestId("editor-link-cancel-button"),linkSaveButton:e.getByTestId("editor-link-save-button"),openLinkDialog:g(r).open,saveButton:o.getByTestId("editor-save-button"),cancelButton:o.getByTestId("editor-cancel-button"),mentionButton:l,helpButton:s,helpDialog:u,helpDialogCloseButton:c,async openHelpDialog(){await u.isVisible()||await s.click();},mentionInput:d,mentionListbox:a,mentionOption:m=>a.getByRole("option",{name:m}),async startMention(){await d.isVisible()||await l.click();}}}function D({frame:e,trigger:t,variant:o="dropzone"}){let n=e.getByTestId("file-uploader"),i=n.locator('input[type="file"]'),r=t??(o==="button"?n.getByRole("button"):e.getByTestId("file-uploader-dropzone"));return {root:n,button:r,input:i,dropzone:e.getByTestId("file-uploader-dropzone"),errorMessage:n.getByRole("alert"),async upload(s){await i.setInputFiles(s);}}}function P(e,t,o){let n=s=>t.getByRole("menuitem",{name:s}).or(t.getByRole("menuitemradio",{name:s})).or(t.getByRole("menuitemcheckbox",{name:s})),i=s=>t.getByRole("group",{name:s}),{isOpen:r}=g(o);return {menu:t,item:n,section:i,isOpen:r,submenu(s){let l=n(s),d=e.getByRole("menu",{name:s}),a=P(e,d,l),{open:c}=g(l);return {...a,trigger:l,open:async(u="Enter")=>c(u)}}}}function U({frame:e,trigger:t}){let o=t??e.getByTestId("menu-trigger"),n=e.getByRole("menu").first(),i=P(e,n,o),{open:r,isOpen:s}=g(o);return {...i,trigger:o,open:r,isOpen:s,async close(){await s()&&await o.press("Escape");},async selectItem(l){await r(),await i.item(l).click();}}}var M=(e=>{let o=Y(e);return e.multiple&&(o=Z(o,e.frame)),e.autocomplete&&(o=ee(o,e.frame)),o});function Y({frame:e,trigger:t}){let o=t??e.getByTestId("select-button"),n=r=>e.getByRole("option",{name:r,exact:typeof r=="string"}),{open:i}=g(o);return {trigger:o,listbox:e.getByRole("listbox"),option:n,open:i,async selectOption(r){await i(),await n(r).click();}}}function Z(e,t){return {...e,selectAllButton:t.getByTestId("select-all-button"),clearButton:t.getByTestId("select-clear-button"),tag:o=>e.trigger.getByRole("row",{name:o}),removeTagButton:o=>e.trigger.getByRole("row",{name:o}).getByRole("button")}}function ee(e,t){let o=t.getByRole("searchbox");return {...e,searchbox:o,async filter(n){await o.fill(n);}}}function te(e){return {select:((t={})=>M({frame:e,...t})),comboBox:(t={})=>F({frame:e,...t}),editor:(t={})=>v({frame:e,...t}),fileUploader:(t={})=>D({frame:e,...t}),menu:(t={})=>U({frame:e,...t})}}export{O as DEFAULT_CRITICAL_INCOMPLETE_RULES,L as DEFAULT_DISABLED_RULES,w as DEFAULT_WCAG_TAGS,Q as expect,te as testers};
21
+ ${u.message}`,pass:false}}}return {message:()=>"Class tree matched snapshot.",pass:true}}});function v({frame:e,name:t}){let o=e.locator(".BaselineUI-Breadcrumbs"),r=t===void 0?o:o.and(e.getByRole("navigation",{name:t,exact:typeof t=="string"}));return {root:r,current:r.locator('[aria-current="page"]'),separators:r.getByTestId("breadcrumbs-separator"),item:n=>r.getByRole("link",{name:n,exact:typeof n=="string"})}}function g(e){let t=async()=>{if(await e.getAttribute("aria-expanded")!==null)return e;let n=e.locator("[aria-expanded]").first();return await n.count()>0?n:e},o=async()=>await(await t()).getAttribute("aria-expanded")==="true";return {button:t,isOpen:o,open:async(n="click")=>{if(await o())return;if(n==="click"){await e.click();return}await(await t()).press(n);}}}function D({frame:e,trigger:t,toggleButton:o}){let r=t??e.getByRole("combobox",{includeHidden:true}),n=o??e.getByTestId("combobox-toggle-button"),s=a=>e.getByRole("option",{name:a,exact:typeof a=="string"}),{isOpen:l,open:p}=g(r),d=async(a="click")=>{if(!await l()){if(a==="click"){await n.click();return}await p(a);}};return {input:r,toggleButton:n,listbox:e.getByRole("listbox"),option:s,isOpen:l,open:d,async selectOption(a){await d(),await s(a).click();},async filter(a){await r.fill(a);}}}function P({frame:e,root:t}){let o=t??e.locator(".BaselineUI-Editor"),r=o.getByTestId("editor-font-color-button"),n=o.getByTestId("editor-background-color-button"),s=o.getByTestId("editor-add-link-button"),l=o.getByTestId("editor-help-button"),p=o.getByTestId("editor-mention-button"),d=o.getByRole("combobox"),a=e.getByTestId("editor-mention-listbox"),i=e.getByTestId("editor-help-dialog-close-button"),c=e.getByRole("dialog").filter({has:i}),u=e.getByRole("dialog").filter({has:e.getByTestId(/^editor-link-/)});return {root:o,textbox:o.getByRole("textbox"),placeholder:o.getByTestId("editor-placeholder"),toolbar:o.getByRole("toolbar"),boldButton:o.getByTestId("editor-bold-button"),italicButton:o.getByTestId("editor-italic-button"),underlineButton:o.getByTestId("editor-underline-button"),fontColorButton:r,backgroundColorButton:n,openFontColorPicker:g(r).open,openBackgroundColorPicker:g(n).open,addLinkButton:s,linkDialog:u,linkInput:e.getByTestId("editor-link-input"),linkAddButton:e.getByTestId("editor-link-add-button"),linkEditButton:e.getByTestId("editor-link-edit-button"),linkRemoveButton:e.getByTestId("editor-link-remove-button"),linkCancelButton:e.getByTestId("editor-link-cancel-button"),linkSaveButton:e.getByTestId("editor-link-save-button"),openLinkDialog:g(s).open,saveButton:o.getByTestId("editor-save-button"),cancelButton:o.getByTestId("editor-cancel-button"),mentionButton:p,helpButton:l,helpDialog:c,helpDialogCloseButton:i,async openHelpDialog(){await c.isVisible()||await l.click();},mentionInput:d,mentionListbox:a,mentionOption:m=>a.getByRole("option",{name:m}),async startMention(){await d.isVisible()||await p.click();}}}function U({frame:e,trigger:t,variant:o="dropzone"}){let r=e.getByTestId("file-uploader"),n=r.locator('input[type="file"]'),s=t??(o==="button"?r.getByRole("button"):e.getByTestId("file-uploader-dropzone"));return {root:r,button:s,input:n,dropzone:e.getByTestId("file-uploader-dropzone"),errorMessage:r.getByRole("alert"),async upload(l){await n.setInputFiles(l);}}}function M(e,t,o){let r=l=>t.getByRole("menuitem",{name:l}).or(t.getByRole("menuitemradio",{name:l})).or(t.getByRole("menuitemcheckbox",{name:l})),n=l=>t.getByRole("group",{name:l}),{isOpen:s}=g(o);return {menu:t,item:r,section:n,isOpen:s,submenu(l){let p=r(l),d=e.getByRole("menu",{name:l}),a=M(e,d,p),{open:i}=g(p);return {...a,trigger:p,open:async(c="Enter")=>i(c)}}}}function $({frame:e,trigger:t,longPress:o=false}){let r=t??e.getByTestId("menu-trigger"),n=e.getByRole("menu").first(),s=M(e,n,r),{button:l,open:p,isOpen:d}=g(r),a=async(i="click")=>{if(!o)return p(i);if(i==="ArrowLeft"||i==="ArrowRight")throw new Error(`menuTester: cannot open a long-press menu with "${i}"; use "click", "Enter", "Space", "ArrowDown" or "ArrowUp"`);if(await d())return;let c=await l();if(i==="click"){await c.click({delay:800});return}await c.press(`Alt+${i}`);};return {...s,trigger:r,open:a,isOpen:d,async close(){await d()&&await r.press("Escape");},async selectItem(i){await a(),await s.item(i).click();}}}var N=(e=>{let o=ee(e);return e.multiple&&(o=te(o,e.frame)),e.autocomplete&&(o=oe(o,e.frame)),o});function ee({frame:e,trigger:t}){let o=t??e.getByTestId("select-button"),r=s=>e.getByRole("option",{name:s,exact:typeof s=="string"}),{open:n}=g(o);return {trigger:o,listbox:e.getByRole("listbox"),option:r,open:n,async selectOption(s){await n(),await r(s).click();}}}function te(e,t){return {...e,selectAllButton:t.getByTestId("select-all-button"),clearButton:t.getByTestId("select-clear-button"),tag:o=>e.trigger.getByRole("row",{name:o}),removeTagButton:o=>e.trigger.getByRole("row",{name:o}).getByRole("button")}}function oe(e,t){let o=t.getByRole("searchbox");return {...e,searchbox:o,async filter(r){await o.fill(r);}}}function re(e){return {select:((t={})=>N({frame:e,...t})),comboBox:(t={})=>D({frame:e,...t}),editor:(t={})=>P({frame:e,...t}),fileUploader:(t={})=>U({frame:e,...t}),menu:(t={})=>$({frame:e,...t}),breadcrumbs:(t={})=>v({frame:e,...t})}}export{E as DEFAULT_CRITICAL_INCOMPLETE_RULES,O as DEFAULT_DISABLED_RULES,L as DEFAULT_WCAG_TAGS,Z as expect,re as testers};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@baseline-ui/test-utils",
3
- "version": "3.4.0",
3
+ "version": "3.6.0",
4
4
  "description": "A collection of test utilities for Baseline UI",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -52,7 +52,7 @@
52
52
  "dependencies": {
53
53
  "axe-core": "^4.11.4",
54
54
  "react-frame-component": "^5.3.2",
55
- "@baseline-ui/core": "3.4.0"
55
+ "@baseline-ui/core": "3.6.0"
56
56
  },
57
57
  "scripts": {
58
58
  "build": "tsup",
package/sbom.json CHANGED
@@ -2,10 +2,10 @@
2
2
  "$schema": "http://cyclonedx.org/schema/bom-1.6.schema.json",
3
3
  "bomFormat": "CycloneDX",
4
4
  "specVersion": "1.6",
5
- "serialNumber": "urn:uuid:22c72a5b-c951-4575-adf7-e61a58a4ae3c",
5
+ "serialNumber": "urn:uuid:094163e8-93fc-420e-bde3-8e2b3aac2bf9",
6
6
  "version": 1,
7
7
  "metadata": {
8
- "timestamp": "2026-10-15T12:21:09.558Z",
8
+ "timestamp": "2026-10-22T06:23:23.358Z",
9
9
  "lifecycles": [
10
10
  {
11
11
  "phase": "pre-build"
@@ -23,9 +23,9 @@
23
23
  "component": {
24
24
  "type": "library",
25
25
  "name": "@baseline-ui/test-utils",
26
- "version": "3.4.0",
27
- "purl": "pkg:npm/@baseline-ui/test-utils@3.4.0",
28
- "bom-ref": "pkg:npm/@baseline-ui/test-utils@3.4.0",
26
+ "version": "3.6.0",
27
+ "purl": "pkg:npm/@baseline-ui/test-utils@3.6.0",
28
+ "bom-ref": "pkg:npm/@baseline-ui/test-utils@3.6.0",
29
29
  "licenses": [
30
30
  {
31
31
  "license": {
@@ -500,7 +500,7 @@
500
500
  ],
501
501
  "dependencies": [
502
502
  {
503
- "ref": "pkg:npm/@baseline-ui/test-utils@3.4.0",
503
+ "ref": "pkg:npm/@baseline-ui/test-utils@3.6.0",
504
504
  "dependsOn": [
505
505
  "pkg:npm/%40neondatabase/serverless@1.1.0",
506
506
  "pkg:npm/%40playwright/test@1.62.1",