@baseline-ui/test-utils 3.10.0 → 3.11.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
@@ -323,6 +323,26 @@ interface EditorTester {
323
323
  startMention: () => Promise<void>;
324
324
  }
325
325
 
326
+ interface FileInputTesterOptions extends Omit<BaseTesterOptions, "trigger"> {
327
+ /**
328
+ * The `<FileInput>` root element, not a wrapper around it, to pick one when
329
+ * a page renders several. A `data-testid` passed to `<FileInput>` lands on it.
330
+ */
331
+ root?: Locator;
332
+ }
333
+ /**
334
+ * Driver for a `<FileInput>` in Playwright component tests. Construct with
335
+ * {@link fileInputTester} (or `testers(frame).fileInput()`).
336
+ */
337
+ interface FileInputTester {
338
+ /** The root element. */
339
+ readonly root: Locator;
340
+ /** The button that opens the native file picker. */
341
+ readonly button: Locator;
342
+ /** The hidden native file input. */
343
+ readonly input: Locator;
344
+ }
345
+
326
346
  /**
327
347
  * Options for {@link fileUploaderTester}. The root is always resolved from the
328
348
  * stable `data-testid="file-uploader"`; `trigger` overrides the upload
@@ -582,12 +602,51 @@ interface SelectTesterFactoryFor<O extends {
582
602
  (options?: O): SelectTester;
583
603
  }
584
604
 
605
+ interface VideoPlayerTesterOptions extends Omit<BaseTesterOptions, "trigger"> {
606
+ /** The accessible name of the player, to pick one when a page has several. */
607
+ name?: string | RegExp;
608
+ }
609
+ /**
610
+ * Driver for a `<VideoPlayer>` in Playwright component tests. Construct with
611
+ * {@link videoPlayerTester} (or `testers(frame).videoPlayer()`).
612
+ *
613
+ * While the video plays, the controls fade out and stop taking pointer input
614
+ * after `controlsHideDelay`; they still count as visible to `toBeVisible()`.
615
+ * Hover `root` to bring them back before clicking one, and assert on
616
+ * `data-controls-visible` rather than visibility.
617
+ */
618
+ interface VideoPlayerTester {
619
+ /** The player's `group`. Carries `data-state` and `data-controls-visible`. */
620
+ readonly root: Locator;
621
+ /** The native `<video>` element. */
622
+ readonly video: Locator;
623
+ /** The play/pause toggle. Its accessible name flips with the playback state. */
624
+ readonly playButton: Locator;
625
+ /** The timeline slider used to seek. */
626
+ readonly timeline: Locator;
627
+ /** The elapsed-time label. */
628
+ readonly currentTime: Locator;
629
+ /** The duration label. */
630
+ readonly duration: Locator;
631
+ /** The mute/unmute toggle. Its accessible name flips with the muted state. */
632
+ readonly muteButton: Locator;
633
+ /**
634
+ * The enter/exit full screen toggle. Matches nothing where the browser does
635
+ * not allow full screen.
636
+ */
637
+ readonly fullScreenButton: Locator;
638
+ /** The spinner shown until the video's metadata has loaded. */
639
+ readonly loadingIndicator: Locator;
640
+ }
641
+
585
642
  type BoundSelectOptions = Omit<SelectTesterOptions, "frame">;
586
643
  type BoundComboBoxOptions = Omit<ComboBoxTesterOptions, "frame">;
587
644
  type BoundEditorOptions = Omit<EditorTesterOptions, "frame">;
645
+ type BoundFileInputOptions = Omit<FileInputTesterOptions, "frame">;
588
646
  type BoundFileUploaderOptions = Omit<FileUploaderTesterOptions, "frame">;
589
647
  type BoundMenuOptions = Omit<MenuTesterOptions, "frame">;
590
648
  type BoundBreadcrumbsOptions = Omit<BreadcrumbsTesterOptions, "frame">;
649
+ type BoundVideoPlayerOptions = Omit<VideoPlayerTesterOptions, "frame">;
591
650
  /**
592
651
  * The frame-bound tester factory. Methods are flat — one per component — so
593
652
  * IDE autocomplete on `t.` lists the full surface in one place. Variants of a
@@ -601,9 +660,11 @@ interface Testers {
601
660
  select: SelectTesterFactoryFor<BoundSelectOptions>;
602
661
  comboBox: (options?: BoundComboBoxOptions) => ComboBoxTester;
603
662
  editor: (options?: BoundEditorOptions) => EditorTester;
663
+ fileInput: (options?: BoundFileInputOptions) => FileInputTester;
604
664
  fileUploader: (options?: BoundFileUploaderOptions) => FileUploaderTester;
605
665
  menu: (options?: BoundMenuOptions) => MenuTester;
606
666
  breadcrumbs: (options?: BoundBreadcrumbsOptions) => BreadcrumbsTester;
667
+ videoPlayer: (options?: BoundVideoPlayerOptions) => VideoPlayerTester;
607
668
  }
608
669
  /**
609
670
  * Build a frame-bound tester factory. Construct once per test and pick the
@@ -621,4 +682,4 @@ interface Testers {
621
682
  */
622
683
  declare function testers(frame: Frame): Testers;
623
684
 
624
- 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 };
685
+ export { type AutocompleteTester, type BreadcrumbsTester, type ComboBoxTester, DEFAULT_CRITICAL_INCOMPLETE_RULES, DEFAULT_DISABLED_RULES, DEFAULT_WCAG_TAGS, type EditorTester, type FileInputTester, type FileUploaderTester, type Frame, type MenuSubmenuTester, type MenuTester, type MultiSelectTester, type SelectTester, type Testers, type ToBeAccessibleOptions, type VideoPlayerTester, expect, testers };
package/dist/index.d.ts CHANGED
@@ -323,6 +323,26 @@ interface EditorTester {
323
323
  startMention: () => Promise<void>;
324
324
  }
325
325
 
326
+ interface FileInputTesterOptions extends Omit<BaseTesterOptions, "trigger"> {
327
+ /**
328
+ * The `<FileInput>` root element, not a wrapper around it, to pick one when
329
+ * a page renders several. A `data-testid` passed to `<FileInput>` lands on it.
330
+ */
331
+ root?: Locator;
332
+ }
333
+ /**
334
+ * Driver for a `<FileInput>` in Playwright component tests. Construct with
335
+ * {@link fileInputTester} (or `testers(frame).fileInput()`).
336
+ */
337
+ interface FileInputTester {
338
+ /** The root element. */
339
+ readonly root: Locator;
340
+ /** The button that opens the native file picker. */
341
+ readonly button: Locator;
342
+ /** The hidden native file input. */
343
+ readonly input: Locator;
344
+ }
345
+
326
346
  /**
327
347
  * Options for {@link fileUploaderTester}. The root is always resolved from the
328
348
  * stable `data-testid="file-uploader"`; `trigger` overrides the upload
@@ -582,12 +602,51 @@ interface SelectTesterFactoryFor<O extends {
582
602
  (options?: O): SelectTester;
583
603
  }
584
604
 
605
+ interface VideoPlayerTesterOptions extends Omit<BaseTesterOptions, "trigger"> {
606
+ /** The accessible name of the player, to pick one when a page has several. */
607
+ name?: string | RegExp;
608
+ }
609
+ /**
610
+ * Driver for a `<VideoPlayer>` in Playwright component tests. Construct with
611
+ * {@link videoPlayerTester} (or `testers(frame).videoPlayer()`).
612
+ *
613
+ * While the video plays, the controls fade out and stop taking pointer input
614
+ * after `controlsHideDelay`; they still count as visible to `toBeVisible()`.
615
+ * Hover `root` to bring them back before clicking one, and assert on
616
+ * `data-controls-visible` rather than visibility.
617
+ */
618
+ interface VideoPlayerTester {
619
+ /** The player's `group`. Carries `data-state` and `data-controls-visible`. */
620
+ readonly root: Locator;
621
+ /** The native `<video>` element. */
622
+ readonly video: Locator;
623
+ /** The play/pause toggle. Its accessible name flips with the playback state. */
624
+ readonly playButton: Locator;
625
+ /** The timeline slider used to seek. */
626
+ readonly timeline: Locator;
627
+ /** The elapsed-time label. */
628
+ readonly currentTime: Locator;
629
+ /** The duration label. */
630
+ readonly duration: Locator;
631
+ /** The mute/unmute toggle. Its accessible name flips with the muted state. */
632
+ readonly muteButton: Locator;
633
+ /**
634
+ * The enter/exit full screen toggle. Matches nothing where the browser does
635
+ * not allow full screen.
636
+ */
637
+ readonly fullScreenButton: Locator;
638
+ /** The spinner shown until the video's metadata has loaded. */
639
+ readonly loadingIndicator: Locator;
640
+ }
641
+
585
642
  type BoundSelectOptions = Omit<SelectTesterOptions, "frame">;
586
643
  type BoundComboBoxOptions = Omit<ComboBoxTesterOptions, "frame">;
587
644
  type BoundEditorOptions = Omit<EditorTesterOptions, "frame">;
645
+ type BoundFileInputOptions = Omit<FileInputTesterOptions, "frame">;
588
646
  type BoundFileUploaderOptions = Omit<FileUploaderTesterOptions, "frame">;
589
647
  type BoundMenuOptions = Omit<MenuTesterOptions, "frame">;
590
648
  type BoundBreadcrumbsOptions = Omit<BreadcrumbsTesterOptions, "frame">;
649
+ type BoundVideoPlayerOptions = Omit<VideoPlayerTesterOptions, "frame">;
591
650
  /**
592
651
  * The frame-bound tester factory. Methods are flat — one per component — so
593
652
  * IDE autocomplete on `t.` lists the full surface in one place. Variants of a
@@ -601,9 +660,11 @@ interface Testers {
601
660
  select: SelectTesterFactoryFor<BoundSelectOptions>;
602
661
  comboBox: (options?: BoundComboBoxOptions) => ComboBoxTester;
603
662
  editor: (options?: BoundEditorOptions) => EditorTester;
663
+ fileInput: (options?: BoundFileInputOptions) => FileInputTester;
604
664
  fileUploader: (options?: BoundFileUploaderOptions) => FileUploaderTester;
605
665
  menu: (options?: BoundMenuOptions) => MenuTester;
606
666
  breadcrumbs: (options?: BoundBreadcrumbsOptions) => BreadcrumbsTester;
667
+ videoPlayer: (options?: BoundVideoPlayerOptions) => VideoPlayerTester;
607
668
  }
608
669
  /**
609
670
  * Build a frame-bound tester factory. Construct once per test and pick the
@@ -621,4 +682,4 @@ interface Testers {
621
682
  */
622
683
  declare function testers(frame: Frame): Testers;
623
684
 
624
- 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 };
685
+ export { type AutocompleteTester, type BreadcrumbsTester, type ComboBoxTester, DEFAULT_CRITICAL_INCOMPLETE_RULES, DEFAULT_DISABLED_RULES, DEFAULT_WCAG_TAGS, type EditorTester, type FileInputTester, type FileUploaderTester, type Frame, type MenuSubmenuTester, type MenuTester, type MultiSelectTester, type SelectTester, type Testers, type ToBeAccessibleOptions, type VideoPlayerTester, expect, testers };
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- 'use strict';var test=require('@playwright/test'),j=require('axe-core'),promises=require('fs/promises'),F=require('path'),promises$1=require('timers/promises');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var j__default=/*#__PURE__*/_interopDefault(j);var F__default=/*#__PURE__*/_interopDefault(F);/**
1
+ 'use strict';var test=require('@playwright/test'),H=require('axe-core'),promises=require('fs/promises'),P=require('path'),promises$1=require('timers/promises');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var H__default=/*#__PURE__*/_interopDefault(H);var P__default=/*#__PURE__*/_interopDefault(P);/**
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 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(`
10
+ var O=["wcag2a","wcag2aa","wcag21a","wcag21aa","best-practice"],L=["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 A(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 x=u||f.getAttribute("aria-hidden")==="true",b=l(f),w=p(f,x);b.length>0?m.push({classes:b,children:w,hidden:x}):m.push(...w);}return m}function d(c,u="",m=false){let h=[];for(let f=0;f<c.length;f++){let x=c[f],b=f===c.length-1,w=m?"":b?"\u2514\u2500\u2500 ":"\u251C\u2500\u2500 ",j=m?"":u+(b?" ":"\u2502 "),z=x.classes.join(", ");h.push(u+w+z+(x.hidden?" [aria-hidden]":""),...d(x.children,j));}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
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},q=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);},J=["document-title","html-has-lang","html-lang-valid","html-xml-lang-mismatch"],K=(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]},Y=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 q(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 Z(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 ee=300,te=25,T=(e,t)=>{if(typeof e?.callCount!="number")throw new TypeError(`${t}: expected a sinon spy.`)},oe=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}}},async toBeCalled(e){if(T(e,"toBeCalled"),this.isNot){let t=Date.now()+ee;for(;e.callCount===0&&Date.now()<t;)await promises$1.setTimeout(te);return {message:()=>`Expected function not to be called, but it was called ${e.callCount} time(s).`,pass:e.callCount>0}}try{return await test.expect.poll(()=>e.called).toBe(!0),{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=K(t,r?J:[]),s,l=async()=>{let i=await Y(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(`
12
+ `)}var T=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"}},K=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},Y=async e=>{await e.first().evaluate((t,o)=>{if(window.axe)return;let n=document.createElement("script");n.textContent=o,document.head.append(n);},H__default.default.source);},X=["document-title","html-has-lang","html-lang-valid","html-xml-lang-mismatch"],Q=(e,t=[])=>{let o=new Set([...L,...t,...e.disableRules??[]]);return {runOnly:{type:"tag",values:[...e.tags??O]},rules:Object.fromEntries([...o].map(r=>[r,{enabled:false}]))}},F=e=>{if(e!==void 0)return typeof e=="string"?[e]:[...e]},Z=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 Y(e);let n=F(t.include),s=F(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})},I="BaselineUI-";function S(e){return e.replaceAll(/\W+/g,"-").replaceAll(/^-|-$/g,"")}function ee(e){return Array.isArray(e)?e.length===1&&e[0]===I:e===I}function te(e){return (Array.isArray(e)?e:[e]).join("+")}function oe(e,t,o,r,n){let s=t.slice(1).map(l=>S(l));return o&&s.push(S(o)),r!==void 0&&!ee(r)&&s.push(S(te(r))),n&&s.push("ignoreHashed"),P__default.default.join(e,`${s.join("--")}.txt`)}var re=300,ne=25,B=(e,t)=>{if(typeof e?.callCount!="number")throw new TypeError(`${t}: expected a sinon spy.`)},k=async e=>{let t=Date.now()+re;for(;e.callCount===0&&Date.now()<t;)await promises$1.setTimeout(ne);},se=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){B(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:()=>T(t),pass:false}}},async toBeCalledTwice(e){B(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:()=>T(t),pass:false}}},async toBeCalledThrice(e){B(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:()=>T(t),pass:false}}},async toBeCalledWith(e,...t){B(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:()=>T(o),pass:false}}},async toBeCalledWithExactly(e,...t){B(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:()=>T(o),pass:false}}},async toBeCalled(e){if(B(e,"toBeCalled"),this.isNot)return await k(e),{message:()=>`Expected function not to be called, but it was called ${e.callCount} time(s).`,pass:e.callCount>0};try{return await test.expect.poll(()=>e.called).toBe(!0),{message:()=>"Expected function to be called.",pass:!0}}catch(t){return {message:()=>T(t),pass:false}}},async toBeCalledTimes(e,t){if(B(e,"toBeCalledTimes"),!Number.isInteger(t)||t<0)throw new TypeError("toBeCalledTimes: times must be a non-negative integer.");if(t===0)return await k(e),e.callCount===0?{message:()=>"Expected function to be called.",pass:true}:{message:()=>`Expected function not to be called, but it was called ${e.callCount} time(s).`,pass:false};try{return await test.expect.poll(()=>e.callCount).toBe(t),{message:()=>`Expected function to be called ${t} times.`,pass:!0}}catch(o){return {message:()=>T(o),pass:false}}},async toBeAccessible(e,t={}){let o=await K(e),r=await o.first().evaluate(i=>{let c=i.ownerDocument?.defaultView;return c!==null&&c!==window.top}).catch(()=>false),n=Q(t,r?X:[]),s,l=async()=>{let i=await Z(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
+ ${T(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
14
  `);return ` \u2022 [${i.id}] ${i.help}
15
15
  ${c}
16
16
  ${i.helpUrl??""}`}).join(`
17
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=Z(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}
18
+ ${d}`,pass:false}},async toMatchClassTree(e,t,o={}){let{prefix:r=I,ignoreHashed:n=false}=o,s=await e.evaluate(A,{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=oe(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(P__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
- ${u.message}`,pass:false}}}return {message:()=>"Class tree matched snapshot.",pass:true}}});function D({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 v({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-box"}){let r=e.getByTestId("file-uploader"),n=r.locator('input[type="file"]'),s=t??r.getByTestId(o==="button"?"file-uploader-button":"file-uploader-trigger");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 N({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 _=(e=>{let o=re(e);return e.multiple&&(o=ne(o,e.frame)),e.autocomplete&&(o=se(o,e.frame)),o});function re({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 ne(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 se(e,t){let o=t.getByRole("searchbox");return {...e,searchbox:o,async filter(r){await o.fill(r);}}}function ie(e){return {select:((t={})=>_({frame:e,...t})),comboBox:(t={})=>v({frame:e,...t}),editor:(t={})=>P({frame:e,...t}),fileUploader:(t={})=>U({frame:e,...t}),menu:(t={})=>N({frame:e,...t}),breadcrumbs:(t={})=>D({frame:e,...t})}}exports.DEFAULT_CRITICAL_INCOMPLETE_RULES=E;exports.DEFAULT_DISABLED_RULES=O;exports.DEFAULT_WCAG_TAGS=L;exports.expect=oe;exports.testers=ie;
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 y(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}=y(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 U({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:y(r).open,openBackgroundColorPicker:y(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:y(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 M({frame:e,root:t}){let o=t??e.locator(".BaselineUI-FileInput");return {root:o,button:o.getByTestId("file-input-button"),input:o.locator('xpath=following-sibling::input[@type="file"][1]')}}function N({frame:e,trigger:t,variant:o="dropzone-box"}){let r=e.getByTestId("file-uploader"),n=r.locator('input[type="file"]'),s=t??r.getByTestId(o==="button"?"file-uploader-button":"file-uploader-trigger");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 _(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}=y(o);return {menu:t,item:r,section:n,isOpen:s,submenu(l){let p=r(l),d=e.getByRole("menu",{name:l}),a=_(e,d,p),{open:i}=y(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=_(e,n,r),{button:l,open:p,isOpen:d}=y(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 W=(e=>{let o=ie(e);return e.multiple&&(o=ae(o,e.frame)),e.autocomplete&&(o=le(o,e.frame)),o});function ie({frame:e,trigger:t}){let o=t??e.getByTestId("select-button"),r=s=>e.getByRole("option",{name:s,exact:typeof s=="string"}),{open:n}=y(o);return {trigger:o,listbox:e.getByRole("listbox"),option:r,open:n,async selectOption(s){await n(),await r(s).click();}}}function ae(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 le(e,t){let o=t.getByRole("searchbox");return {...e,searchbox:o,async filter(r){await o.fill(r);}}}function V({frame:e,name:t}){let o=e.locator(".BaselineUI-VideoPlayer"),r=t===void 0?o:o.and(e.getByRole("group",{name:t,exact:typeof t=="string"}));return {root:r,video:r.locator("video"),playButton:r.getByTestId("video-player-play-button"),timeline:r.getByRole("slider"),currentTime:r.getByTestId("video-player-current-time"),duration:r.getByTestId("video-player-duration"),muteButton:r.getByTestId("video-player-mute-button"),fullScreenButton:r.getByTestId("video-player-full-screen-button"),loadingIndicator:r.getByRole("progressbar")}}function ce(e){return {select:((t={})=>W({frame:e,...t})),comboBox:(t={})=>D({frame:e,...t}),editor:(t={})=>U({frame:e,...t}),fileInput:(t={})=>M({frame:e,...t}),fileUploader:(t={})=>N({frame:e,...t}),menu:(t={})=>$({frame:e,...t}),breadcrumbs:(t={})=>v({frame:e,...t}),videoPlayer:(t={})=>V({frame:e,...t})}}exports.DEFAULT_CRITICAL_INCOMPLETE_RULES=E;exports.DEFAULT_DISABLED_RULES=L;exports.DEFAULT_WCAG_TAGS=O;exports.expect=se;exports.testers=ce;
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import {expect,test}from'@playwright/test';import j from'axe-core';import {readFile,mkdir,writeFile}from'fs/promises';import F from'path';import {setTimeout}from'timers/promises';/**
1
+ import {expect,test}from'@playwright/test';import H from'axe-core';import {readFile,mkdir,writeFile}from'fs/promises';import P from'path';import {setTimeout}from'timers/promises';/**
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 j from'axe-core';import {readF
7
7
  * This notice may not be removed from this file.
8
8
  *
9
9
  */
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(`
10
+ var O=["wcag2a","wcag2aa","wcag21a","wcag21aa","best-practice"],L=["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 A(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 x=u||f.getAttribute("aria-hidden")==="true",b=l(f),w=p(f,x);b.length>0?m.push({classes:b,children:w,hidden:x}):m.push(...w);}return m}function d(c,u="",m=false){let h=[];for(let f=0;f<c.length;f++){let x=c[f],b=f===c.length-1,w=m?"":b?"\u2514\u2500\u2500 ":"\u251C\u2500\u2500 ",j=m?"":u+(b?" ":"\u2502 "),z=x.classes.join(", ");h.push(u+w+z+(x.hidden?" [aria-hidden]":""),...d(x.children,j));}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
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},q=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);},J=["document-title","html-has-lang","html-lang-valid","html-xml-lang-mismatch"],K=(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]},Y=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 q(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 Z(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 ee=300,te=25,T=(e,t)=>{if(typeof e?.callCount!="number")throw new TypeError(`${t}: expected a sinon spy.`)},oe=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}}},async toBeCalled(e){if(T(e,"toBeCalled"),this.isNot){let t=Date.now()+ee;for(;e.callCount===0&&Date.now()<t;)await setTimeout(te);return {message:()=>`Expected function not to be called, but it was called ${e.callCount} time(s).`,pass:e.callCount>0}}try{return await expect.poll(()=>e.called).toBe(!0),{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=K(t,r?J:[]),s,l=async()=>{let i=await Y(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(`
12
+ `)}var T=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"}},K=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},Y=async e=>{await e.first().evaluate((t,o)=>{if(window.axe)return;let n=document.createElement("script");n.textContent=o,document.head.append(n);},H.source);},X=["document-title","html-has-lang","html-lang-valid","html-xml-lang-mismatch"],Q=(e,t=[])=>{let o=new Set([...L,...t,...e.disableRules??[]]);return {runOnly:{type:"tag",values:[...e.tags??O]},rules:Object.fromEntries([...o].map(r=>[r,{enabled:false}]))}},F=e=>{if(e!==void 0)return typeof e=="string"?[e]:[...e]},Z=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 Y(e);let n=F(t.include),s=F(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})},I="BaselineUI-";function S(e){return e.replaceAll(/\W+/g,"-").replaceAll(/^-|-$/g,"")}function ee(e){return Array.isArray(e)?e.length===1&&e[0]===I:e===I}function te(e){return (Array.isArray(e)?e:[e]).join("+")}function oe(e,t,o,r,n){let s=t.slice(1).map(l=>S(l));return o&&s.push(S(o)),r!==void 0&&!ee(r)&&s.push(S(te(r))),n&&s.push("ignoreHashed"),P.join(e,`${s.join("--")}.txt`)}var re=300,ne=25,B=(e,t)=>{if(typeof e?.callCount!="number")throw new TypeError(`${t}: expected a sinon spy.`)},k=async e=>{let t=Date.now()+re;for(;e.callCount===0&&Date.now()<t;)await setTimeout(ne);},se=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){B(e,"toBeCalledOnce");try{return await expect.poll(()=>e.callCount).toBe(1),{message:()=>"Expected function to be called once.",pass:!0}}catch(t){return {message:()=>T(t),pass:false}}},async toBeCalledTwice(e){B(e,"toBeCalledTwice");try{return await expect.poll(()=>e.callCount).toBe(2),{message:()=>"Expected function to be called twice.",pass:!0}}catch(t){return {message:()=>T(t),pass:false}}},async toBeCalledThrice(e){B(e,"toBeCalledThrice");try{return await expect.poll(()=>e.callCount).toBe(3),{message:()=>"Expected function to be called thrice.",pass:!0}}catch(t){return {message:()=>T(t),pass:false}}},async toBeCalledWith(e,...t){B(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:()=>T(o),pass:false}}},async toBeCalledWithExactly(e,...t){B(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:()=>T(o),pass:false}}},async toBeCalled(e){if(B(e,"toBeCalled"),this.isNot)return await k(e),{message:()=>`Expected function not to be called, but it was called ${e.callCount} time(s).`,pass:e.callCount>0};try{return await expect.poll(()=>e.called).toBe(!0),{message:()=>"Expected function to be called.",pass:!0}}catch(t){return {message:()=>T(t),pass:false}}},async toBeCalledTimes(e,t){if(B(e,"toBeCalledTimes"),!Number.isInteger(t)||t<0)throw new TypeError("toBeCalledTimes: times must be a non-negative integer.");if(t===0)return await k(e),e.callCount===0?{message:()=>"Expected function to be called.",pass:true}:{message:()=>`Expected function not to be called, but it was called ${e.callCount} time(s).`,pass:false};try{return await expect.poll(()=>e.callCount).toBe(t),{message:()=>`Expected function to be called ${t} times.`,pass:!0}}catch(o){return {message:()=>T(o),pass:false}}},async toBeAccessible(e,t={}){let o=await K(e),r=await o.first().evaluate(i=>{let c=i.ownerDocument?.defaultView;return c!==null&&c!==window.top}).catch(()=>false),n=Q(t,r?X:[]),s,l=async()=>{let i=await Z(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
+ ${T(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
14
  `);return ` \u2022 [${i.id}] ${i.help}
15
15
  ${c}
16
16
  ${i.helpUrl??""}`}).join(`
17
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=Z(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}
18
+ ${d}`,pass:false}},async toMatchClassTree(e,t,o={}){let{prefix:r=I,ignoreHashed:n=false}=o,s=await e.evaluate(A,{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=oe(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(P.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
- ${u.message}`,pass:false}}}return {message:()=>"Class tree matched snapshot.",pass:true}}});function D({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 v({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-box"}){let r=e.getByTestId("file-uploader"),n=r.locator('input[type="file"]'),s=t??r.getByTestId(o==="button"?"file-uploader-button":"file-uploader-trigger");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 N({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 _=(e=>{let o=re(e);return e.multiple&&(o=ne(o,e.frame)),e.autocomplete&&(o=se(o,e.frame)),o});function re({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 ne(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 se(e,t){let o=t.getByRole("searchbox");return {...e,searchbox:o,async filter(r){await o.fill(r);}}}function ie(e){return {select:((t={})=>_({frame:e,...t})),comboBox:(t={})=>v({frame:e,...t}),editor:(t={})=>P({frame:e,...t}),fileUploader:(t={})=>U({frame:e,...t}),menu:(t={})=>N({frame:e,...t}),breadcrumbs:(t={})=>D({frame:e,...t})}}export{E as DEFAULT_CRITICAL_INCOMPLETE_RULES,O as DEFAULT_DISABLED_RULES,L as DEFAULT_WCAG_TAGS,oe as expect,ie 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 y(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}=y(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 U({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:y(r).open,openBackgroundColorPicker:y(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:y(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 M({frame:e,root:t}){let o=t??e.locator(".BaselineUI-FileInput");return {root:o,button:o.getByTestId("file-input-button"),input:o.locator('xpath=following-sibling::input[@type="file"][1]')}}function N({frame:e,trigger:t,variant:o="dropzone-box"}){let r=e.getByTestId("file-uploader"),n=r.locator('input[type="file"]'),s=t??r.getByTestId(o==="button"?"file-uploader-button":"file-uploader-trigger");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 _(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}=y(o);return {menu:t,item:r,section:n,isOpen:s,submenu(l){let p=r(l),d=e.getByRole("menu",{name:l}),a=_(e,d,p),{open:i}=y(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=_(e,n,r),{button:l,open:p,isOpen:d}=y(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 W=(e=>{let o=ie(e);return e.multiple&&(o=ae(o,e.frame)),e.autocomplete&&(o=le(o,e.frame)),o});function ie({frame:e,trigger:t}){let o=t??e.getByTestId("select-button"),r=s=>e.getByRole("option",{name:s,exact:typeof s=="string"}),{open:n}=y(o);return {trigger:o,listbox:e.getByRole("listbox"),option:r,open:n,async selectOption(s){await n(),await r(s).click();}}}function ae(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 le(e,t){let o=t.getByRole("searchbox");return {...e,searchbox:o,async filter(r){await o.fill(r);}}}function V({frame:e,name:t}){let o=e.locator(".BaselineUI-VideoPlayer"),r=t===void 0?o:o.and(e.getByRole("group",{name:t,exact:typeof t=="string"}));return {root:r,video:r.locator("video"),playButton:r.getByTestId("video-player-play-button"),timeline:r.getByRole("slider"),currentTime:r.getByTestId("video-player-current-time"),duration:r.getByTestId("video-player-duration"),muteButton:r.getByTestId("video-player-mute-button"),fullScreenButton:r.getByTestId("video-player-full-screen-button"),loadingIndicator:r.getByRole("progressbar")}}function ce(e){return {select:((t={})=>W({frame:e,...t})),comboBox:(t={})=>D({frame:e,...t}),editor:(t={})=>U({frame:e,...t}),fileInput:(t={})=>M({frame:e,...t}),fileUploader:(t={})=>N({frame:e,...t}),menu:(t={})=>$({frame:e,...t}),breadcrumbs:(t={})=>v({frame:e,...t}),videoPlayer:(t={})=>V({frame:e,...t})}}export{E as DEFAULT_CRITICAL_INCOMPLETE_RULES,L as DEFAULT_DISABLED_RULES,O as DEFAULT_WCAG_TAGS,se as expect,ce as testers};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@baseline-ui/test-utils",
3
- "version": "3.10.0",
3
+ "version": "3.11.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.10.0"
55
+ "@baseline-ui/core": "3.11.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:a679a48a-0a2a-4cc6-8d11-d003a5a35c9f",
5
+ "serialNumber": "urn:uuid:6eb8daef-325e-4fb2-aacd-4455f6457452",
6
6
  "version": 1,
7
7
  "metadata": {
8
- "timestamp": "2026-11-03T19:08:02.135Z",
8
+ "timestamp": "2026-11-06T09:09:14.944Z",
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.10.0",
27
- "purl": "pkg:npm/@baseline-ui/test-utils@3.10.0",
28
- "bom-ref": "pkg:npm/@baseline-ui/test-utils@3.10.0",
26
+ "version": "3.11.0",
27
+ "purl": "pkg:npm/@baseline-ui/test-utils@3.11.0",
28
+ "bom-ref": "pkg:npm/@baseline-ui/test-utils@3.11.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.10.0",
503
+ "ref": "pkg:npm/@baseline-ui/test-utils@3.11.0",
504
504
  "dependsOn": [
505
505
  "pkg:npm/%40neondatabase/serverless@1.1.0",
506
506
  "pkg:npm/%40playwright/test@1.62.1",