@ghentcdh/ui 1.0.4 → 1.1.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/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "@ghentcdh/ui",
3
3
  "author": "GhentCDH",
4
- "version": "1.0.4",
4
+ "version": "1.1.0",
5
+ "type": "module",
5
6
  "main": "./index.js",
6
7
  "module": "./index.mjs",
7
8
  "types": "./index.d.ts",
@@ -11,6 +12,11 @@
11
12
  "import": "./index.mjs",
12
13
  "require": "./index.js"
13
14
  },
15
+ "./testing": {
16
+ "types": "./testing/index.d.ts",
17
+ "import": "./testing.mjs",
18
+ "require": "./testing.js"
19
+ },
14
20
  "./index.css": "./index.css",
15
21
  "./package.json": "./package.json"
16
22
  },
@@ -39,13 +45,20 @@
39
45
  "shell/**",
40
46
  "table/**",
41
47
  "test-utils/**",
48
+ "testing/**",
42
49
  "toast/**",
43
50
  "tree/**",
44
51
  "utils/**"
45
52
  ],
53
+ "peerDependenciesMeta": {
54
+ "@playwright/test": {
55
+ "optional": true
56
+ }
57
+ },
46
58
  "sideEffects": false,
47
59
  "peerDependencies": {
48
60
  "@ghentcdh/tools-vue": ">=0.6.0",
61
+ "@playwright/test": ">=1.50.0",
49
62
  "@heroicons/vue": "^2.2.0",
50
63
  "@tiptap/pm": "^3.0.0",
51
64
  "@tiptap/starter-kit": "^3.0.0",
@@ -0,0 +1,16 @@
1
+ import { Locator, Page } from '@playwright/test';
2
+ import { Harness } from './Harness';
3
+ /**
4
+ * Drives the `@ghentcdh/ui` `Alert` component.
5
+ *
6
+ * Renders `<div role="alert">` with a message and type-based CSS class.
7
+ */
8
+ export declare class AlertHarness extends Harness {
9
+ /** Resolve the alert by its message text. */
10
+ static byMessage(parent: Locator | Page, message: string): AlertHarness;
11
+ /** Resolve the first (or only) alert on the page. */
12
+ static first(parent: Locator | Page): AlertHarness;
13
+ static for(locator: Locator): AlertHarness;
14
+ message(): Promise<string>;
15
+ hasClass(cls: string): Promise<boolean>;
16
+ }
@@ -0,0 +1,29 @@
1
+ import { Locator, Page } from '@playwright/test';
2
+ import { Harness } from './Harness';
3
+ /**
4
+ * Drives the `@ghentcdh/ui` `AutoComplete` component.
5
+ *
6
+ * Input is `role="combobox"`. Options are portaled `role="option"` items.
7
+ * The component supports remote-fetched options, freeText mode, and an
8
+ * optional "Create new" button.
9
+ */
10
+ export declare class AutocompleteHarness extends Harness {
11
+ static byId(parent: Locator | Page, id: string): AutocompleteHarness;
12
+ static byLabel(parent: Locator | Page, label: string): AutocompleteHarness;
13
+ static for(locator: Locator): AutocompleteHarness;
14
+ /** Type a query, wait for the matching option, click it. */
15
+ fill(value: string): Promise<this>;
16
+ /** Just type a query without selecting — useful for asserting dropdown state. */
17
+ query(value: string): Promise<this>;
18
+ /** Pick a specific option by visible label, after `query()` has filtered. */
19
+ pickOption(label: string): Promise<this>;
20
+ /** Press a key — useful for arrow-down / Enter / Esc keyboard nav tests. */
21
+ press(key: string): Promise<this>;
22
+ /** Click the "Create new" button (requires `enableCreate`). */
23
+ clickCreateNew(): Promise<void>;
24
+ clear(): Promise<this>;
25
+ value(): Promise<string>;
26
+ /** The listbox is portaled — locate it relative to the Page. */
27
+ listbox(): Locator;
28
+ options(): Locator;
29
+ }
@@ -0,0 +1,14 @@
1
+ import { Locator, Page } from '@playwright/test';
2
+ import { Harness } from './Harness';
3
+ /**
4
+ * Drives the `@ghentcdh/ui` `Checkbox` component.
5
+ * Renders `<input role="checkbox" aria-label="{id}">`.
6
+ */
7
+ export declare class BooleanHarness extends Harness {
8
+ static byId(parent: Locator | Page, id: string): BooleanHarness;
9
+ static byLabel(parent: Locator | Page, label: string): BooleanHarness;
10
+ static for(locator: Locator): BooleanHarness;
11
+ fill(value: boolean): Promise<this>;
12
+ toggle(): Promise<this>;
13
+ value(): Promise<boolean>;
14
+ }
@@ -0,0 +1,16 @@
1
+ import { Locator, Page } from '@playwright/test';
2
+ import { Harness } from './Harness';
3
+ /**
4
+ * Drives the `@ghentcdh/ui` `Btn` component.
5
+ *
6
+ * Renders `<button>` (or `<a>`) with optional icon, tooltip, disabled state,
7
+ * and emits `click`.
8
+ */
9
+ export declare class ButtonHarness extends Harness {
10
+ /** Resolve by accessible name (button text / aria-label). */
11
+ static byName(parent: Locator | Page, name: string): ButtonHarness;
12
+ static for(locator: Locator): ButtonHarness;
13
+ click(): Promise<this>;
14
+ isDisabled(): Promise<boolean>;
15
+ text(): Promise<string>;
16
+ }
@@ -0,0 +1,22 @@
1
+ import { Locator, Page } from '@playwright/test';
2
+ import { Harness } from './Harness';
3
+ /**
4
+ * Drives the `@ghentcdh/ui` `Collapse` component.
5
+ *
6
+ * The collapse uses a hidden `<input type="checkbox" aria-label="Toggle {title}">`
7
+ * to control open/close state. Content lives inside `.collapse-content`.
8
+ */
9
+ export declare class CollapseHarness extends Harness {
10
+ /** Resolve by the collapse title text. */
11
+ static byTitle(parent: Locator | Page, title: string): CollapseHarness;
12
+ static for(locator: Locator): CollapseHarness;
13
+ /** Toggle open/close by clicking the hidden checkbox. */
14
+ toggle(): Promise<this>;
15
+ /** Whether the collapse is currently open (checkbox checked). */
16
+ isOpen(): Promise<boolean>;
17
+ /** The title text element. */
18
+ title(): Locator;
19
+ /** The content wrapper. */
20
+ content(): Locator;
21
+ private checkbox;
22
+ }
@@ -0,0 +1,21 @@
1
+ import { Locator, Page } from '@playwright/test';
2
+ import { Harness } from './Harness';
3
+ /**
4
+ * Drives the `@ghentcdh/ui` `Drawer` component.
5
+ *
6
+ * The drawer has left/right toggle buttons with aria-labels like
7
+ * "Collapse left panel" / "Expand left panel".
8
+ */
9
+ export declare class DrawerHarness extends Harness {
10
+ /** Resolve the drawer as the `<main>` containing the panels. */
11
+ static root(parent: Locator | Page): DrawerHarness;
12
+ static for(locator: Locator): DrawerHarness;
13
+ toggleLeft(): Promise<this>;
14
+ toggleRight(): Promise<this>;
15
+ isLeftOpen(): Promise<boolean>;
16
+ isRightOpen(): Promise<boolean>;
17
+ leftPanel(): Locator;
18
+ rightPanel(): Locator;
19
+ private leftButton;
20
+ private rightButton;
21
+ }
@@ -0,0 +1,27 @@
1
+ import { Locator, Page } from '@playwright/test';
2
+ /**
3
+ * Base class for a Locator-scoped control driver.
4
+ *
5
+ * A Harness wraps one UI control (input, checkbox, autocomplete, …). It is
6
+ * agnostic of routes, fixtures, and the surrounding form — that's the job of
7
+ * `*Fixture` and `*Page` classes in the consuming packages.
8
+ *
9
+ * Concrete harnesses provide one or more `static` factory methods. The two
10
+ * conventional ones are `byLabel` (the user-visible label or aria-label) and
11
+ * `byId` (the `aria-label="{id}"` that lib components emit). Subclasses can
12
+ * add more — e.g. `MarkdownHarness.byTitle`.
13
+ */
14
+ export declare abstract class Harness {
15
+ protected readonly locator: Locator;
16
+ constructor(locator: Locator);
17
+ /** Access the Page this harness was scoped against. */
18
+ protected page(): Page;
19
+ /** Get the underlying Locator — useful for assertions or further scoping. */
20
+ asLocator(): Locator;
21
+ }
22
+ /**
23
+ * Resolve a single role + accessible name inside a parent. The `name` option
24
+ * in Playwright matches accessible names case-insensitively by substring, so
25
+ * both `Author` and `author` will hit the same control.
26
+ */
27
+ export declare const byRole: (parent: Locator | Page, role: "textbox" | "spinbutton" | "checkbox" | "combobox" | "button" | "dialog", name: string) => Locator;
@@ -0,0 +1,24 @@
1
+ import { Locator, Page } from '@playwright/test';
2
+ import { Harness } from './Harness';
3
+ export type MarkdownToolbarButton = 'B' | 'I';
4
+ /**
5
+ * Drives the `@ghentcdh/ui` `Markdown` component (TipTap-backed).
6
+ *
7
+ * The component renders `<div role="textbox" aria-label="{id}">` with a
8
+ * toolbar of `<button>`s whose visible text is the mark label (`B`, `I`, …).
9
+ */
10
+ export declare class MarkdownHarness extends Harness {
11
+ static byId(parent: Locator | Page, id: string): MarkdownHarness;
12
+ static byLabel(parent: Locator | Page, label: string): MarkdownHarness;
13
+ static for(locator: Locator): MarkdownHarness;
14
+ /** The editable inner surface — TipTap renders a nested `role="textbox"`. */
15
+ private get editor();
16
+ fill(value: string): Promise<this>;
17
+ clear(): Promise<this>;
18
+ typeBold(text: string): Promise<this>;
19
+ typeItalic(text: string): Promise<this>;
20
+ type(text: string): Promise<this>;
21
+ toolbar(name: MarkdownToolbarButton): Locator;
22
+ /** Is a toolbar mark currently active (the lib adds `btn-active`)? */
23
+ isMarkActive(name: MarkdownToolbarButton): Promise<boolean>;
24
+ }
@@ -0,0 +1,35 @@
1
+ import { Locator, Page } from '@playwright/test';
2
+ import { Harness } from './Harness';
3
+ /**
4
+ * Drives the `@ghentcdh/ui` `Modal` component.
5
+ *
6
+ * Renders `<dialog role="dialog" aria-labelledby="{titleId}">` containing an
7
+ * `<h3 id="{titleId}">{{ modalTitle }}</h3>`, an `aria-label="Close"` button
8
+ * (unless `disableClose`), and `#content` / `#actions` slots.
9
+ *
10
+ * The native `<dialog>` element handles focus trap + Esc + backdrop click for
11
+ * us; the harness exposes the surface needed to assert that behavior.
12
+ */
13
+ export declare class ModalHarness extends Harness {
14
+ /**
15
+ * Resolve by the dialog's accessible name (the `modalTitle` shown in the
16
+ * `<h3>`). Note: matches are case-insensitive substring.
17
+ */
18
+ static byTitle(parent: Locator | Page, title: string): ModalHarness;
19
+ /** Resolve the only-open dialog. Useful when there's just one at a time. */
20
+ static current(parent: Locator | Page): ModalHarness;
21
+ static for(locator: Locator): ModalHarness;
22
+ clickClose(): Promise<this>;
23
+ /** Press Esc on the dialog (handled by the native `<dialog>` element). */
24
+ pressEscape(): Promise<this>;
25
+ /** Click outside the modal box to attempt a backdrop close. */
26
+ clickBackdrop(): Promise<this>;
27
+ /** Click an action button in the modal's `#actions` slot by accessible name. */
28
+ clickAction(name: string): Promise<this>;
29
+ /** The `<h3>` title element. */
30
+ title(): Locator;
31
+ /** The content slot wrapper. */
32
+ content(): Locator;
33
+ /** Whether the dialog is currently visible (for `expect().toBeVisible()`). */
34
+ asLocator(): Locator;
35
+ }
@@ -0,0 +1,16 @@
1
+ import { Locator, Page } from '@playwright/test';
2
+ import { Harness } from './Harness';
3
+ /**
4
+ * Drives the `@ghentcdh/ui` `MultiSelect` component.
5
+ * Combobox shape like `SelectHarness`, but the list stays open across picks.
6
+ */
7
+ export declare class MultiSelectHarness extends Harness {
8
+ static byId(parent: Locator | Page, id: string): MultiSelectHarness;
9
+ static byLabel(parent: Locator | Page, label: string): MultiSelectHarness;
10
+ static for(locator: Locator): MultiSelectHarness;
11
+ open(): Promise<this>;
12
+ fill(labels: string[]): Promise<this>;
13
+ select(label: string): Promise<this>;
14
+ /** Remove a selected chip by its label. */
15
+ removeChip(label: string): Promise<this>;
16
+ }
@@ -0,0 +1,14 @@
1
+ import { Locator, Page } from '@playwright/test';
2
+ import { Harness } from './Harness';
3
+ /**
4
+ * Drives the `@ghentcdh/ui` `InputNumber` component.
5
+ * Renders `<input type="number" aria-label="{id}">` — role `spinbutton`.
6
+ */
7
+ export declare class NumberHarness extends Harness {
8
+ static byId(parent: Locator | Page, id: string): NumberHarness;
9
+ static byLabel(parent: Locator | Page, label: string): NumberHarness;
10
+ static for(locator: Locator): NumberHarness;
11
+ fill(value: number): Promise<this>;
12
+ clear(): Promise<this>;
13
+ value(): Promise<number | null>;
14
+ }
@@ -0,0 +1,24 @@
1
+ import { Locator, Page } from '@playwright/test';
2
+ import { Harness } from './Harness';
3
+ /**
4
+ * Drives the `@ghentcdh/ui` `SelectComponent`.
5
+ *
6
+ * Combobox button (`role="combobox"`) opens a portaled `role="listbox"` with
7
+ * `role="option"` items, each containing an `<a>` that emits the selection.
8
+ */
9
+ export declare class SelectHarness extends Harness {
10
+ static byId(parent: Locator | Page, id: string): SelectHarness;
11
+ static byLabel(parent: Locator | Page, label: string): SelectHarness;
12
+ static for(locator: Locator): SelectHarness;
13
+ open(): Promise<this>;
14
+ fill(label: string): Promise<this>;
15
+ select(label: string): Promise<this>;
16
+ value(): Promise<string>;
17
+ /** Click the "Clear" button rendered next to the select. */
18
+ clear(): Promise<this>;
19
+ /**
20
+ * Click the "Create new" button. Requires `enableCreate` to be set on
21
+ * the component (SelectWrapper conditionally renders the button).
22
+ */
23
+ clickCreateNew(): Promise<void>;
24
+ }
@@ -0,0 +1,14 @@
1
+ import { Locator, Page } from '@playwright/test';
2
+ import { Harness } from './Harness';
3
+ /**
4
+ * Drives the `@ghentcdh/ui` `Textarea` component.
5
+ * Plain text-area; use `MarkdownHarness` for the rich editor.
6
+ */
7
+ export declare class TextAreaHarness extends Harness {
8
+ static byId(parent: Locator | Page, id: string): TextAreaHarness;
9
+ static byLabel(parent: Locator | Page, label: string): TextAreaHarness;
10
+ static for(locator: Locator): TextAreaHarness;
11
+ fill(value: string): Promise<this>;
12
+ clear(): Promise<this>;
13
+ value(): Promise<string>;
14
+ }
@@ -0,0 +1,19 @@
1
+ import { Locator, Page } from '@playwright/test';
2
+ import { Harness } from './Harness';
3
+ /**
4
+ * Drives the `@ghentcdh/ui` `Input` component. The component renders
5
+ * `<input aria-label="{id}">` inside a `ControlWrapper`, so we look up by
6
+ * the aria-label (= `id`) by default.
7
+ */
8
+ export declare class TextHarness extends Harness {
9
+ static byId(parent: Locator | Page, id: string): TextHarness;
10
+ /** Resolve by visible label (the `<legend>` text). */
11
+ static byLabel(parent: Locator | Page, label: string): TextHarness;
12
+ static for(locator: Locator): TextHarness;
13
+ fill(value: string): Promise<this>;
14
+ /** Type character-by-character — useful when the control reacts to each keystroke. */
15
+ type(value: string): Promise<this>;
16
+ clear(): Promise<this>;
17
+ value(): Promise<string>;
18
+ blur(): Promise<this>;
19
+ }
@@ -0,0 +1,14 @@
1
+ export { Harness, byRole } from './Harness';
2
+ export { TextHarness } from './TextHarness';
3
+ export { NumberHarness } from './NumberHarness';
4
+ export { TextAreaHarness } from './TextAreaHarness';
5
+ export { BooleanHarness } from './BooleanHarness';
6
+ export { SelectHarness } from './SelectHarness';
7
+ export { AutocompleteHarness } from './AutocompleteHarness';
8
+ export { MultiSelectHarness } from './MultiSelectHarness';
9
+ export { MarkdownHarness, type MarkdownToolbarButton } from './MarkdownHarness';
10
+ export { ModalHarness } from './ModalHarness';
11
+ export { ButtonHarness } from './ButtonHarness';
12
+ export { CollapseHarness } from './CollapseHarness';
13
+ export { AlertHarness } from './AlertHarness';
14
+ export { DrawerHarness } from './DrawerHarness';
package/testing.js ADDED
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class r{constructor(t){this.locator=t}page(){return this.locator.page()}asLocator(){return this.locator}}const e=(x,t,a)=>x.getByRole(t,{name:a});class i extends r{static byId(t,a){return new i(e(t,"textbox",a))}static byLabel(t,a){return new i(e(t,"textbox",a))}static for(t){return new i(t)}async fill(t){return await this.locator.click(),await this.locator.fill(t),this}async type(t){return await this.locator.click(),await this.locator.pressSequentially(t),this}async clear(){return await this.locator.fill(""),this}async value(){return this.locator.inputValue()}async blur(){return await this.locator.press("Tab"),this}}class o extends r{static byId(t,a){return new o(e(t,"spinbutton",a))}static byLabel(t,a){return new o(e(t,"spinbutton",a))}static for(t){return new o(t)}async fill(t){return await this.locator.click(),await this.locator.fill(String(t)),await this.locator.press("Tab"),this}async clear(){return await this.locator.fill(""),this}async value(){const t=await this.locator.inputValue();return t===""?null:Number(t)}}class c extends r{static byId(t,a){return new c(e(t,"textbox",a))}static byLabel(t,a){return new c(e(t,"textbox",a))}static for(t){return new c(t)}async fill(t){return await this.locator.click(),await this.locator.fill(t),this}async clear(){return await this.locator.fill(""),this}async value(){return this.locator.inputValue()}}class s extends r{static byId(t,a){return new s(e(t,"checkbox",a))}static byLabel(t,a){return new s(e(t,"checkbox",a))}static for(t){return new s(t)}async fill(t){return t?await this.locator.check():await this.locator.uncheck(),this}async toggle(){return await this.locator.click(),this}async value(){return this.locator.isChecked()}}class n extends r{static byId(t,a){return new n(e(t,"combobox",a))}static byLabel(t,a){return new n(e(t,"combobox",a))}static for(t){return new n(t)}async open(){return await this.locator.click(),this}async fill(t){return this.select(t)}async select(t){return await this.open(),await this.page().getByRole("option",{name:t}).locator("a").click(),this}async value(){return(await this.locator.textContent())?.trim()??""}async clear(){return await this.locator.locator('xpath=ancestor::*[@role="select"][1]').getByRole("button",{name:"Clear"}).click(),this}async clickCreateNew(){await this.locator.locator('xpath=ancestor::*[@role="select"][1]').getByRole("button",{name:"create"}).click()}}class l extends r{static byId(t,a){return new l(e(t,"combobox",a))}static byLabel(t,a){return new l(e(t,"combobox",a))}static for(t){return new l(t)}async fill(t){return await this.locator.click(),await this.locator.fill(t),await this.page().getByRole("option",{name:t}).locator("a").click(),this}async query(t){return await this.locator.click(),await this.locator.fill(t),this}async pickOption(t){return await this.page().getByRole("option",{name:t}).locator("a").click(),this}async press(t){return await this.locator.press(t),this}async clickCreateNew(){await this.locator.locator('xpath=ancestor::*[@role="select"][1]').getByRole("button",{name:"create"}).click()}async clear(){return await this.locator.locator('xpath=ancestor::*[@role="select"][1]').getByRole("button",{name:"Clear"}).click(),this}async value(){return this.locator.inputValue()}listbox(){return this.page().getByRole("listbox")}options(){return this.page().getByRole("option")}}class u extends r{static byId(t,a){return new u(e(t,"combobox",a))}static byLabel(t,a){return new u(e(t,"combobox",a))}static for(t){return new u(t)}async open(){return await this.locator.click(),this}async fill(t){await this.open();for(const a of t)await this.page().getByRole("option",{name:a}).locator("a").click();return await this.locator.click(),this}async select(t){return await this.open(),await this.page().getByRole("option",{name:t}).locator("a").click(),this}async removeChip(t){return await this.locator.locator('xpath=ancestor::*[@role="select"][1]').getByText(t,{exact:!0}).getByRole("button").click(),this}}class h extends r{static byId(t,a){return new h(e(t,"textbox",a))}static byLabel(t,a){return new h(e(t,"textbox",a))}static for(t){return new h(t)}get editor(){return this.locator.getByRole("textbox")}async fill(t){return await this.editor.fill(t),this}async clear(){return await this.editor.fill(""),this}async typeBold(t){return await this.toolbar("B").click(),await this.editor.pressSequentially(t),await this.toolbar("B").click(),this}async typeItalic(t){return await this.toolbar("I").click(),await this.editor.pressSequentially(t),await this.toolbar("I").click(),this}async type(t){return await this.editor.pressSequentially(t),this}toolbar(t){return this.locator.getByRole("button",{name:t})}async isMarkActive(t){return(await this.toolbar(t).getAttribute("class")??"").includes("btn-active")}}class y extends r{static byTitle(t,a){return new y(t.getByRole("dialog",{name:a}))}static current(t){return new y(t.getByRole("dialog"))}static for(t){return new y(t)}async clickClose(){return await this.locator.getByRole("button",{name:"Close"}).click(),this}async pressEscape(){return await this.locator.press("Escape"),this}async clickBackdrop(){return await this.locator.click({position:{x:5,y:5}}),this}async clickAction(t){return await this.locator.getByRole("button",{name:t}).click(),this}title(){return this.locator.locator("h3").first()}content(){return this.locator.locator('[id$="_content"]').first()}asLocator(){return this.locator}}class b extends r{static byName(t,a){return new b(e(t,"button",a))}static for(t){return new b(t)}async click(){return await this.locator.click(),this}async isDisabled(){return this.locator.isDisabled()}async text(){return await this.locator.textContent()??""}}class p extends r{static byTitle(t,a){const f=t.getByLabel(`Toggle ${a}`);return new p(f.locator(".."))}static for(t){return new p(t)}async toggle(){return await this.checkbox().click(),this}async isOpen(){return this.checkbox().isChecked()}title(){return this.locator.locator(".collapse-title span").first()}content(){return this.locator.locator(".collapse-content")}checkbox(){return this.locator.locator('input[type="checkbox"]')}}class w extends r{static byMessage(t,a){return new w(t.getByRole("alert").filter({hasText:a}))}static first(t){return new w(t.getByRole("alert").first())}static for(t){return new w(t)}async message(){return await this.locator.locator("span").textContent()??""}async hasClass(t){return(await this.locator.getAttribute("class")??"").includes(t)}}class g extends r{static root(t){return new g(t.locator("main").first())}static for(t){return new g(t)}async toggleLeft(){return await this.leftButton().click(),this}async toggleRight(){return await this.rightButton().click(),this}async isLeftOpen(){return await this.leftButton().getAttribute("aria-expanded")==="true"}async isRightOpen(){return await this.rightButton().getAttribute("aria-expanded")==="true"}leftPanel(){return this.locator.locator("#drawer-left-panel")}rightPanel(){return this.locator.locator("#drawer-right-panel")}leftButton(){return this.locator.locator('button[aria-controls="drawer-left-panel"]')}rightButton(){return this.locator.locator('button[aria-controls="drawer-right-panel"]')}}exports.AlertHarness=w;exports.AutocompleteHarness=l;exports.BooleanHarness=s;exports.ButtonHarness=b;exports.CollapseHarness=p;exports.DrawerHarness=g;exports.Harness=r;exports.MarkdownHarness=h;exports.ModalHarness=y;exports.MultiSelectHarness=u;exports.NumberHarness=o;exports.SelectHarness=n;exports.TextAreaHarness=c;exports.TextHarness=i;exports.byRole=e;