@atomic-testing/component-driver-mui-v9 0.89.0 → 0.90.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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["parts","HTMLElementDriver","ComponentDriver","timingUtil","parts","HTMLElementDriver","ContainerDriver","ComponentDriver","locatorUtil","ListComponentDriver","listHelper","parts","HTMLTextInputDriver","HTMLElementDriver","optionLocator","ComponentDriver","locatorUtil","listHelper","HTMLButtonDriver","parts","HTMLElementDriver","ComponentDriver","HTMLButtonDriver","ListComponentDriver","listHelper","HTMLButtonDriver","HTMLCheckboxDriver","ComponentDriver","locatorUtil","parts","HTMLElementDriver","ComponentDriver","parts","HTMLElementDriver","defaultTransitionDuration","ContainerDriver","ContainerDriver","locatorUtil","HTMLElementDriver","parts","HTMLTextInputDriver","ComponentDriver","getErrorMessage","ErrorBase","ComponentDriver","ListComponentDriver","listHelper","ErrorBase","parts","HTMLElementDriver","ComponentDriver","listHelper","previousButtonLocator","nextButtonLocator","ComponentDriver","locatorUtil","parts","HTMLRadioButtonGroupDriver","ComponentDriver","locatorUtil","ComponentDriver","locatorUtil","ListComponentDriver","locatorUtil","escapeUtil","parts","HTMLRadioButtonGroupDriver","ComponentDriver","locatorUtil","HTMLButtonDriver","HTMLElementDriver","HTMLTextInputDriver","HTMLSelectDriver","ComponentDriver","locatorUtil","listHelper","parts","HTMLTextInputDriver","ComponentDriver","locatorUtil","parts","HTMLElementDriver","ComponentDriver","locatorUtil","ComponentDriver","locatorUtil","escapeUtil","ComponentDriver","locatorUtil","parts","HTMLCheckboxDriver","ComponentDriver","ComponentDriver","ListComponentDriver","ListComponentDriver","locatorUtil","ComponentDriver","locatorUtil","HTMLButtonDriver","ListComponentDriver","listHelper","HTMLElementDriver","HTMLTextInputDriver","ComponentDriver","ComponentDriver","locatorUtil","listHelper","ComponentDriver"],"sources":["../src/components/AccordionDriver.ts","../src/components/AlertDriver.ts","../src/components/AvatarDriver.ts","../src/components/AvatarGroupDriver.ts","../src/components/AutoCompleteDriver.ts","../src/components/BadgeDriver.ts","../src/components/BottomNavigationActionDriver.ts","../src/components/BottomNavigationDriver.ts","../src/components/ButtonDriver.ts","../src/components/CheckboxDriver.ts","../src/components/ChipDriver.ts","../src/components/DialogDriver.ts","../src/components/OverlayDriver.ts","../src/components/DrawerDriver.ts","../src/components/FabDriver.ts","../src/components/InputDriver.ts","../src/errors/MenuItemDisabledError.ts","../src/components/ListItemDriver.ts","../src/components/ListDriver.ts","../src/errors/MenuItemNotFoundError.ts","../src/components/MenuItemDriver.ts","../src/components/MenuDriver.ts","../src/components/PaginationDriver.ts","../src/components/ProgressDriver.ts","../src/components/RadioDriver.ts","../src/components/RadioGroupDriver.ts","../src/components/RatingDriver.ts","../src/components/SelectDriver.ts","../src/components/SliderDriver.ts","../src/components/SnackbarDriver.ts","../src/components/SpeedDialDriver.ts","../src/components/StepperDriver.ts","../src/components/SwitchDriver.ts","../src/components/TableCellDriver.ts","../src/components/TableRowDriver.ts","../src/components/TableDriver.ts","../src/components/TablePaginationDriver.ts","../src/components/TabDriver.ts","../src/components/TabsDriver.ts","../src/components/TextFieldDriver.ts","../src/components/ToggleButtonDriver.ts","../src/components/ToggleButtonGroupDriver.ts","../src/components/TooltipDriver.ts"],"sourcesContent":["import { HTMLElementDriver } from '@atomic-testing/component-driver-html';\nimport {\n byCssClass,\n byRole,\n ComponentDriver,\n IComponentDriverOption,\n Interactor,\n PartLocator,\n ScenePart,\n timingUtil,\n} from '@atomic-testing/core';\n\nexport const parts = {\n /**\n * The clickable area to expand/collapse the accordion.\n */\n disclosure: {\n locator: byCssClass('MuiAccordionSummary-root'),\n driver: HTMLElementDriver,\n },\n summary: {\n locator: byCssClass('MuiAccordionSummary-content'),\n driver: HTMLElementDriver,\n },\n content: {\n locator: byRole('region'),\n driver: HTMLElementDriver,\n },\n} satisfies ScenePart;\n\n/**\n * Driver for Material UI v9 Accordion component.\n * @see https://mui.com/material-ui/react-accordion/\n */\nexport class AccordionDriver extends ComponentDriver<typeof parts> {\n constructor(locator: PartLocator, interactor: Interactor, option?: Partial<IComponentDriverOption>) {\n super(locator, interactor, {\n ...option,\n parts: parts,\n });\n }\n\n /**\n * Get the title/summary of the accordion.\n * @returns The title/summary of the accordion.\n */\n async getSummary(): Promise<string | null> {\n const title = await this.parts.summary.getText();\n return title ?? null;\n }\n\n /**\n * Whether the accordion is expanded.\n * @returns True if the accordion is expanded, false if collapsed.\n */\n async isExpanded(): Promise<boolean> {\n await this.enforcePartExistence('disclosure');\n const expanded = await this.parts.disclosure.getAttribute('aria-expanded');\n return expanded === 'true';\n }\n\n /**\n * Whether the accordion is disabled.\n * @returns True if the accordion is disabled, false if enabled.\n */\n async isDisabled(): Promise<boolean> {\n await this.enforcePartExistence('disclosure');\n const disabled = await this.parts.disclosure.getAttribute('disabled');\n return disabled != null;\n }\n\n override async click(): Promise<void> {\n await this.parts.disclosure.click();\n }\n\n /**\n * Expand the accordion.\n */\n async expand(): Promise<void> {\n const expanded = await this.isExpanded();\n if (!expanded) {\n await this.parts.disclosure.click();\n await timingUtil.waitUntil({\n probeFn: () => this.isExpanded(),\n terminateCondition: true,\n timeoutMs: 1000,\n });\n }\n }\n\n /**\n * Collapse the accordion.\n */\n async collapse(): Promise<void> {\n const expanded = await this.isExpanded();\n if (expanded) {\n await this.parts.disclosure.click();\n await timingUtil.waitUntil({\n probeFn: () => this.isExpanded(),\n terminateCondition: false,\n timeoutMs: 1000,\n });\n }\n }\n\n override get driverName(): string {\n return 'MuiV9AccordionDriver';\n }\n}\n","import { HTMLElementDriver } from '@atomic-testing/component-driver-html';\nimport {\n byCssClass,\n ContainerDriver,\n IContainerDriverOption,\n Interactor,\n PartLocator,\n ScenePart,\n} from '@atomic-testing/core';\n\nexport const parts = {\n title: {\n locator: byCssClass('MuiAlertTitle-root'),\n driver: HTMLElementDriver,\n },\n message: {\n locator: byCssClass('MuiAlert-message'),\n driver: HTMLElementDriver,\n },\n} satisfies ScenePart;\n\ninterface AlertSeverityEvaluator {\n value: string;\n pattern: RegExp;\n}\nconst alertSeverityEvaluators: AlertSeverityEvaluator[] = [\n { value: 'error', pattern: /MuiAlert-.*Error/ },\n { value: 'warning', pattern: /MuiAlert-.*Warning/ },\n { value: 'info', pattern: /MuiAlert-.*Info/ },\n { value: 'success', pattern: /MuiAlert-.*Success/ },\n];\n\n/**\n * Driver for Material UI v9 Alert component.\n * @see https://mui.com/material-ui/react-alert/\n */\nexport class AlertDriver<ContentT extends ScenePart = {}> extends ContainerDriver<ContentT, typeof parts> {\n constructor(locator: PartLocator, interactor: Interactor, option?: Partial<IContainerDriverOption>) {\n super(locator, interactor, {\n ...option,\n parts: parts,\n content: (option?.content ?? {}) as ContentT,\n });\n }\n\n async getTitle(): Promise<string | null> {\n const title = await this.parts.title.getText();\n return title ?? null;\n }\n\n async getMessage(): Promise<string | null> {\n const message = await this.parts.message.getText();\n return message ?? null;\n }\n\n async getSeverity(): Promise<string | null> {\n const cssClassString = await this.interactor.getAttribute(this.locator, 'class');\n if (cssClassString != null) {\n const cssClasses = cssClassString.split(/\\s+/);\n for (const cssClassName of cssClasses) {\n for (const evaluator of alertSeverityEvaluators) {\n if (evaluator.pattern.test(cssClassName)) {\n return evaluator.value;\n }\n }\n }\n }\n return null;\n }\n\n override get driverName(): string {\n return 'MuiV9AlertDriver';\n }\n}\n","import { byCssSelector, ComponentDriver, locatorUtil, Optional, PartLocator } from '@atomic-testing/core';\n\nconst imageLocator = byCssSelector('img.MuiAvatar-img');\n\n/**\n * Driver for the Material UI v9 Avatar component.\n *\n * An Avatar renders a `.MuiAvatar-root`; with a `src` it contains an\n * `img.MuiAvatar-img`, otherwise it shows letter initials (or an icon). The\n * driver reads the image's `alt`, the presence of the image, and the letter\n * initials accordingly.\n * @see https://mui.com/material-ui/react-avatar/\n */\nexport class AvatarDriver extends ComponentDriver {\n private get imageLocator(): PartLocator {\n return locatorUtil.append(this.locator, imageLocator);\n }\n\n /**\n * Whether the avatar renders an image (vs letter/icon fallback).\n */\n async hasImage(): Promise<boolean> {\n return this.interactor.exists(this.imageLocator);\n }\n\n /**\n * The image's alt text, or `undefined` when the avatar has no image.\n */\n async getAltText(): Promise<Optional<string>> {\n if (!(await this.hasImage())) {\n return undefined;\n }\n return (await this.interactor.getAttribute(this.imageLocator, 'alt')) ?? undefined;\n }\n\n /**\n * The letter initials of a text avatar, or `undefined` for an image or icon\n * avatar (which render no text).\n */\n async getInitials(): Promise<Optional<string>> {\n if (await this.hasImage()) {\n return undefined;\n }\n const text = (await this.getText())?.trim();\n return text ? text : undefined;\n }\n\n override get driverName(): string {\n return 'MuiV9AvatarDriver';\n }\n}\n","import {\n byCssSelector,\n IComponentDriverOption,\n Interactor,\n ListComponentDriver,\n ListComponentDriverSpecificOption,\n listHelper,\n Optional,\n PartLocator,\n} from '@atomic-testing/core';\n\nimport { AvatarDriver } from './AvatarDriver';\n\n// Every avatar inside the group (including the surplus \"+N\" avatar) carries the\n// MuiAvatarGroup-avatar class and is a direct-child sibling, so they enumerate\n// positionally.\nconst avatarItemLocator = byCssSelector('.MuiAvatarGroup-avatar');\n\n// The surplus avatar's only distinguishing feature is its \"+N\" text.\nconst surplusPattern = /^\\+\\d+$/;\n\nexport const defaultAvatarGroupDriverOption: ListComponentDriverSpecificOption<AvatarDriver> = {\n itemClass: AvatarDriver,\n itemLocator: avatarItemLocator,\n};\n\ntype AvatarGroupDriverOption<ItemT extends AvatarDriver> = ListComponentDriverSpecificOption<ItemT> &\n Partial<IComponentDriverOption<any>>;\n\n/**\n * Driver for the Material UI v9 AvatarGroup component.\n *\n * AvatarGroup renders up to `max` avatars plus a surplus \"+N\" avatar when there\n * are more. This is a {@link ListComponentDriver} over the rendered avatars\n * (surplus included via `getItems`), with helpers to count the real avatars and\n * read the surplus label.\n * @see https://mui.com/material-ui/react-avatar/#grouped\n */\nexport class AvatarGroupDriver<ItemT extends AvatarDriver = AvatarDriver> extends ListComponentDriver<ItemT> {\n constructor(locator: PartLocator, interactor: Interactor, option: Partial<AvatarGroupDriverOption<ItemT>> = {}) {\n // Merge defaults so the driver works as a bare scene part (see TabsDriver).\n super(locator, interactor, {\n ...defaultAvatarGroupDriverOption,\n ...option,\n } as AvatarGroupDriverOption<ItemT>);\n }\n\n /**\n * The number of real avatars shown, excluding the surplus \"+N\" indicator.\n */\n async getVisibleCount(): Promise<number> {\n let count = 0;\n for await (const item of listHelper.getListItemIterator(this, this.getItemLocator(), AvatarDriver)) {\n const text = (await item.getText())?.trim();\n if (text == null || !surplusPattern.test(text)) {\n count++;\n }\n }\n return count;\n }\n\n /**\n * The surplus indicator's label (e.g. \"+3\"), or `undefined` when every avatar\n * fits within `max` and no surplus is shown.\n */\n async getSurplusLabel(): Promise<Optional<string>> {\n for await (const item of listHelper.getListItemIterator(this, this.getItemLocator(), AvatarDriver)) {\n const text = (await item.getText())?.trim();\n if (text != null && surplusPattern.test(text)) {\n return text;\n }\n }\n return undefined;\n }\n\n override get driverName(): string {\n return 'MuiV9AvatarGroupDriver';\n }\n}\n","import { HTMLButtonDriver, HTMLElementDriver, HTMLTextInputDriver } from '@atomic-testing/component-driver-html';\nimport {\n byCssClass,\n byLinkedElement,\n byRole,\n ComponentDriver,\n IComponentDriverOption,\n IInputDriver,\n Interactor,\n listHelper,\n locatorUtil,\n PartLocator,\n ScenePart,\n} from '@atomic-testing/core';\n\nexport const parts = {\n input: {\n locator: byRole('combobox'),\n driver: HTMLTextInputDriver,\n },\n dropdown: {\n locator: byLinkedElement('Root')\n .onLinkedElement(byRole('combobox'))\n .extractAttribute('aria-controls')\n .toMatchMyAttribute('id'),\n driver: HTMLElementDriver,\n },\n} satisfies ScenePart;\n\nconst optionLocator = byRole('option');\n\n// In the \"no options\" and \"loading\" states MUI renders no listbox, so the popup\n// cannot be reached through the `dropdown` part (which keys off the combobox's\n// `aria-controls`). These nodes live in the popper (portaled outside the driver\n// subtree), so they are matched by their global class. Only one Autocomplete\n// popup is open at a time, so a global match is unambiguous in practice.\nconst noOptionsLocator = byCssClass('MuiAutocomplete-noOptions');\nconst loadingLocator = byCssClass('MuiAutocomplete-loading');\n\n/**\n * The match type of the autocomplete, default to 'exact'\n * 'exact': The value must match exactly to one of the options\n * 'first-available': The value will be set to the first available option\n */\nexport type AutoCompleteMatchType = 'exact' | 'first-available';\n\nexport interface AutoCompleteDriverSpecificOption {\n matchType: AutoCompleteMatchType;\n}\n\nexport interface AutoCompleteDriverOption extends IComponentDriverOption, AutoCompleteDriverSpecificOption {}\n\nexport const defaultAutoCompleteDriverOption: AutoCompleteDriverSpecificOption = {\n matchType: 'exact',\n};\n\nexport class AutoCompleteDriver extends ComponentDriver<typeof parts> implements IInputDriver<string | null> {\n private _option: Partial<AutoCompleteDriverOption> = {};\n constructor(locator: PartLocator, interactor: Interactor, option?: Partial<AutoCompleteDriverOption>) {\n super(locator, interactor, {\n ...option,\n parts,\n });\n\n this._option = option ?? {};\n }\n\n /**\n * Get the display of the autocomplete\n */\n async getValue(): Promise<string | null> {\n const value = await this.parts.input.getValue();\n return value ?? null;\n }\n\n /**\n * Set the value of the autocomplete, how selection happens\n * depends on the option assigned to AutoCompleteDriver\n * By default, when the option has matchType set to exact, only option with matching text would be selected\n * When the option has matchType set to first-available, the first option would be selected regardless of the text\n *\n * Option of auto complete can be set at the time of part definition, for example\n * ```\n * {\n * myAutoComplete: {\n * locator: byCssSelector('my-auto-complete'),\n * driver: AutoCompleteDriver,\n * option: {\n * matchType: 'first-available',\n * },\n * },\n * }\n * ```\n *\n * @param value\n * @returns\n */\n async setValue(value: string | null): Promise<boolean> {\n await this.parts.input.setValue(value ?? '');\n\n if (value === null) {\n return true;\n }\n\n const option = locatorUtil.append(this.parts.dropdown.locator, optionLocator);\n let index = 0;\n const matchType: AutoCompleteMatchType = this._option?.matchType ?? defaultAutoCompleteDriverOption.matchType;\n for await (const optionDriver of listHelper.getListItemIterator(this, option, HTMLButtonDriver)) {\n const optionValue = await optionDriver.getText();\n const isMatched =\n (matchType === 'exact' && optionValue?.trim() === value) || (matchType === 'first-available' && index === 0);\n if (isMatched) {\n await optionDriver.click();\n return true;\n }\n\n index++;\n }\n\n return false;\n }\n\n async isDisabled(): Promise<boolean> {\n return this.parts.input.isDisabled();\n }\n\n async isReadonly(): Promise<boolean> {\n return this.parts.input.isReadonly();\n }\n\n /**\n * Whether the popup is currently showing its loading indicator (the\n * `loadingText`). Only meaningful while the popup is open — open it first\n * (e.g. by typing into the input), since MUI renders nothing otherwise.\n */\n async isLoading(): Promise<boolean> {\n return this.interactor.exists(loadingLocator);\n }\n\n /**\n * Whether the popup is currently showing its \"no options\" message. Same\n * open-the-popup-first caveat as {@link AutoCompleteDriver.isLoading}.\n */\n async hasNoOptions(): Promise<boolean> {\n return this.interactor.exists(noOptionsLocator);\n }\n\n get driverName(): string {\n return 'MuiV9AutoCompleteDriver';\n }\n}\n","import { HTMLElementDriver } from '@atomic-testing/component-driver-html';\nimport {\n byCssClass,\n ComponentDriver,\n IComponentDriverOption,\n Interactor,\n PartLocator,\n ScenePart,\n} from '@atomic-testing/core';\n\nexport const parts = {\n contentDisplay: {\n locator: byCssClass('MuiBadge-badge'),\n driver: HTMLElementDriver,\n },\n} satisfies ScenePart;\n\n/**\n * Driver for Material UI v9 Badge component.\n * @see https://mui.com/material-ui/react-badge/\n */\nexport class BadgeDriver extends ComponentDriver<typeof parts> {\n constructor(locator: PartLocator, interactor: Interactor, option?: Partial<IComponentDriverOption>) {\n super(locator, interactor, {\n ...option,\n parts: parts,\n });\n }\n\n /**\n * Get the content of the badge.\n * @returns The content of the badge.\n */\n async getContent(): Promise<string | null> {\n await this.enforcePartExistence('contentDisplay');\n const content = await this.parts.contentDisplay.getText();\n return content ?? null;\n }\n\n override get driverName(): string {\n return 'MuiV9BadgeDriver';\n }\n}\n","import { HTMLButtonDriver } from '@atomic-testing/component-driver-html';\n\n/**\n * Driver for a single Material UI v9 BottomNavigationAction.\n *\n * Each action renders as a `<button>` (no explicit ARIA role); MUI marks the\n * active one with the `Mui-selected` state class, so selection is read from the\n * class while `getText`/`click`/`isDisabled` come from {@link HTMLButtonDriver}\n * and the base `ComponentDriver`.\n * @see https://mui.com/material-ui/react-bottom-navigation/\n */\nexport class BottomNavigationActionDriver extends HTMLButtonDriver {\n /**\n * Whether this action is selected (MUI applies the `Mui-selected` state class).\n */\n async isSelected(): Promise<boolean> {\n return this.interactor.hasCssClass(this.locator, 'Mui-selected');\n }\n\n override get driverName(): string {\n return 'MuiV9BottomNavigationActionDriver';\n }\n}\n","import {\n byCssSelector,\n IComponentDriverOption,\n Interactor,\n ListComponentDriver,\n ListComponentDriverSpecificOption,\n listHelper,\n Nullable,\n Optional,\n PartLocator,\n} from '@atomic-testing/core';\n\nimport { BottomNavigationActionDriver } from './BottomNavigationActionDriver';\n\nexport interface BottomNavigationActionInfo {\n /** The action's visible label. */\n label: Optional<string>;\n /** Whether the action is currently selected. */\n selected: boolean;\n}\n\n/**\n * BottomNavigation actions are direct-child `<button>` siblings of the root (no\n * ARIA role). They are located by their `MuiBottomNavigationAction-root` class\n * rather than a bare `button` tag, so positional enumeration is not thrown off by\n * any incidental nested button inside an action.\n */\nexport const defaultBottomNavigationDriverOption: ListComponentDriverSpecificOption<BottomNavigationActionDriver> = {\n itemClass: BottomNavigationActionDriver,\n itemLocator: byCssSelector('.MuiBottomNavigationAction-root'),\n};\n\ntype BottomNavigationDriverOption<ItemT extends BottomNavigationActionDriver> =\n ListComponentDriverSpecificOption<ItemT> & Partial<IComponentDriverOption<any>>;\n\n/**\n * Driver for the Material UI v9 BottomNavigation component.\n *\n * A {@link ListComponentDriver} over the action buttons, exposing the selected\n * index/label, selection by index/label, and per-action info, plus per-action\n * {@link BottomNavigationActionDriver} instances via `getItems`/`getItemByIndex`/\n * `getItemByLabel`.\n * @see https://mui.com/material-ui/react-bottom-navigation/\n */\nexport class BottomNavigationDriver<\n ItemT extends BottomNavigationActionDriver = BottomNavigationActionDriver,\n> extends ListComponentDriver<ItemT> {\n constructor(locator: PartLocator, interactor: Interactor, option: Partial<BottomNavigationDriverOption<ItemT>> = {}) {\n // Merge defaults so the driver works as a bare scene part (see TabsDriver).\n super(locator, interactor, {\n ...defaultBottomNavigationDriverOption,\n ...option,\n } as BottomNavigationDriverOption<ItemT>);\n }\n\n /**\n * Every action with its label and selected state, in order.\n */\n async getActions(): Promise<BottomNavigationActionInfo[]> {\n const actions: BottomNavigationActionInfo[] = [];\n for await (const item of listHelper.getListItemIterator(\n this,\n this.getItemLocator(),\n BottomNavigationActionDriver\n )) {\n actions.push({\n label: (await item.getText())?.trim(),\n selected: await item.isSelected(),\n });\n }\n return actions;\n }\n\n /**\n * Zero-based index of the selected action, or `-1` when none is selected.\n */\n async getSelectedIndex(): Promise<number> {\n let index = 0;\n for await (const item of listHelper.getListItemIterator(\n this,\n this.getItemLocator(),\n BottomNavigationActionDriver\n )) {\n if (await item.isSelected()) {\n return index;\n }\n index++;\n }\n return -1;\n }\n\n /**\n * Label of the selected action, or `null` when none is selected. Returns `null`\n * (not `undefined`) to match the sibling `TabsDriver.getSelectedLabel` contract.\n */\n async getSelectedLabel(): Promise<Nullable<string>> {\n for await (const item of listHelper.getListItemIterator(\n this,\n this.getItemLocator(),\n BottomNavigationActionDriver\n )) {\n if (await item.isSelected()) {\n return (await item.getText())?.trim() ?? null;\n }\n }\n return null;\n }\n\n /**\n * Select the action at the given zero-based index.\n * @returns `false` when the index is out of range.\n */\n async selectByIndex(index: number): Promise<boolean> {\n const item = await this.getItemByIndex(index);\n if (item == null) {\n return false;\n }\n await item.click();\n return true;\n }\n\n /**\n * Select the first action whose visible label equals `label`.\n * @returns `false` when no action matches.\n */\n async selectByLabel(label: string): Promise<boolean> {\n const item = await this.getItemByLabel(label);\n if (item == null) {\n return false;\n }\n await item.click();\n return true;\n }\n\n override get driverName(): string {\n return 'MuiV9BottomNavigationDriver';\n }\n}\n","import { HTMLButtonDriver } from '@atomic-testing/component-driver-html';\n\n/**\n * Driver for Material UI v9 Button component.\n * @see https://mui.com/material-ui/react-button/\n */\nexport class ButtonDriver extends HTMLButtonDriver {\n async getValue(): Promise<string | null> {\n const val = await this.interactor.getAttribute(this.locator, 'value');\n return val ?? null;\n }\n\n override get driverName(): string {\n return 'MuiV9ButtonDriver';\n }\n}\n","import { HTMLCheckboxDriver } from '@atomic-testing/component-driver-html';\nimport {\n byCssSelector,\n byTagName,\n ComponentDriver,\n IComponentDriverOption,\n IFormFieldDriver,\n Interactor,\n IToggleDriver,\n locatorUtil,\n Optional,\n PartLocator,\n ScenePart,\n ScenePartDriver,\n} from '@atomic-testing/core';\n\nexport const checkboxPart = {\n checkbox: {\n locator: byTagName('input'),\n driver: HTMLCheckboxDriver,\n },\n} satisfies ScenePart;\n\nexport type CheckboxScenePart = typeof checkboxPart;\nexport type CheckboxScenePartDriver = ScenePartDriver<CheckboxScenePart>;\n\nexport class CheckboxDriver\n extends ComponentDriver<CheckboxScenePart>\n implements IFormFieldDriver<string | null>, IToggleDriver\n{\n constructor(locator: PartLocator, interactor: Interactor, option?: Partial<IComponentDriverOption>) {\n super(locator, interactor, {\n ...option,\n parts: checkboxPart,\n });\n }\n isSelected(): Promise<boolean> {\n return this.parts.checkbox.isSelected();\n }\n async setSelected(selected: boolean): Promise<void> {\n const isIndeterminate = await this.isIndeterminate();\n if (isIndeterminate && selected === false) {\n // if the checkbox is indeterminate and we want to set it to false, we need to click it twice\n // this is done through setting it to true first, then to false\n await this.parts.checkbox.setSelected(true);\n }\n\n await this.parts.checkbox.setSelected(selected);\n }\n\n getValue(): Promise<string | null> {\n return this.parts.checkbox.getValue();\n }\n\n async isIndeterminate(): Promise<boolean> {\n const indeterminate = await this.interactor.getAttribute(this.parts.checkbox.locator, 'data-indeterminate');\n return indeterminate === 'true';\n }\n\n isDisabled(): Promise<boolean> {\n return this.parts.checkbox.isDisabled();\n }\n\n isReadonly(): Promise<boolean> {\n return this.parts.checkbox.isReadonly();\n }\n\n /**\n * Get the text of the label associated with the checkbox, or `undefined` when the checkbox\n * is rendered without one (e.g. a bare `<Checkbox>` outside of a `FormControlLabel`).\n *\n * MUI's `FormControlLabel` does not expose a `for`/`id` or `aria-labelledby` association; it\n * labels the control implicitly by wrapping it in a `<label>` and rendering the text as a\n * sibling. The label therefore lives outside this driver's own subtree, so we re-root at the\n * enclosing `<label>` — matched against this checkbox via `:has()`, while preserving the\n * surrounding scope — and read its text. This resolves to a single CSS selector, so it behaves\n * identically across every interactor (DOM/React/Vue and Playwright).\n */\n async getLabel(): Promise<Optional<string>> {\n const labelLocator = this.getEnclosingLabelLocator();\n const hasLabel = await this.interactor.exists(labelLocator);\n return hasLabel ? this.interactor.getText(labelLocator) : undefined;\n }\n\n /**\n * Build a locator for the `<label>` that encloses this checkbox, scoped to the same ancestor\n * context as the checkbox itself so that sibling checkboxes are never mismatched.\n */\n private getEnclosingLabelLocator(): PartLocator {\n const chain = locatorUtil.toChain(this.locator);\n const selfSelector = chain[chain.length - 1].selector;\n return locatorUtil.append(chain.slice(0, -1), byCssSelector(`label:has(${selfSelector})`));\n }\n\n get driverName(): string {\n return 'MuiV9CheckboxDriver';\n }\n}\n","import { HTMLElementDriver } from '@atomic-testing/component-driver-html';\nimport {\n byCssClass,\n byDataTestId,\n ComponentDriver,\n IComponentDriverOption,\n Interactor,\n PartLocator,\n ScenePart,\n} from '@atomic-testing/core';\n\nexport const parts = {\n contentDisplay: {\n locator: byCssClass('MuiChip-label'),\n driver: HTMLElementDriver,\n },\n removeButton: {\n locator: byDataTestId('CancelIcon'),\n driver: HTMLElementDriver,\n },\n} satisfies ScenePart;\n\n/**\n * Driver for Material UI v9 Chip component.\n * @see https://mui.com/material-ui/react-chip/\n */\nexport class ChipDriver extends ComponentDriver<typeof parts> {\n constructor(locator: PartLocator, interactor: Interactor, option?: Partial<IComponentDriverOption>) {\n super(locator, interactor, {\n ...option,\n parts: parts,\n });\n }\n\n /**\n * Get the label content of the chip.\n * @returns The label text content of the chip.\n */\n async getLabel(): Promise<string | null> {\n await this.enforcePartExistence('contentDisplay');\n const content = await this.parts.contentDisplay.getText();\n return content ?? null;\n }\n\n async clickRemove(): Promise<void> {\n await this.enforcePartExistence('removeButton');\n await this.parts.removeButton.click();\n }\n\n override get driverName(): string {\n return 'MuiV9ChipDriver';\n }\n}\n","import { HTMLElementDriver } from '@atomic-testing/component-driver-html';\nimport {\n byCssClass,\n byRole,\n ContainerDriver,\n IContainerDriverOption,\n Interactor,\n type LocatorRelativePosition,\n Optional,\n PartLocator,\n ScenePart,\n} from '@atomic-testing/core';\n\nexport const parts = {\n title: {\n locator: byCssClass('MuiDialogTitle-root'),\n driver: HTMLElementDriver,\n },\n dialogContainer: {\n locator: byRole('presentation'),\n driver: HTMLElementDriver,\n },\n} satisfies ScenePart;\n\nconst dialogRootLocator: PartLocator = byRole('presentation', 'Root');\n\nconst defaultTransitionDuration = 250;\n\nexport class DialogDriver<ContentT extends ScenePart> extends ContainerDriver<ContentT, typeof parts> {\n constructor(locator: PartLocator, interactor: Interactor, option?: Partial<IContainerDriverOption>) {\n super(locator, interactor, {\n ...option,\n parts: parts,\n content: (option?.content ?? {}) as ContentT,\n });\n }\n\n override overriddenParentLocator(): Optional<PartLocator> {\n return dialogRootLocator;\n }\n\n override overrideLocatorRelativePosition(): Optional<LocatorRelativePosition> {\n return 'Same';\n }\n\n async getTitle(): Promise<string | null> {\n await this.enforcePartExistence('title');\n const title = await this.parts.title.getText();\n return title ?? null;\n }\n\n /**\n * Dismiss the dialog by clicking outside its content, then wait for it to close.\n *\n * MUI's \"backdrop click\" is handled on the `.MuiDialog-container` surface (which\n * overlays the visual `.MuiBackdrop-root`), firing `onClose` only when the click\n * target is the container itself. The click therefore lands on the container near\n * its top-left corner to avoid the centered paper. Whether it actually closes\n * depends on the consumer's `onClose` handling (MUI reports a `\"backdropClick\"`\n * reason); the returned boolean reflects the observed close, not merely the click.\n *\n * @param timeoutMs How long to wait for the close transition to finish\n * @returns true if the dialog closed\n */\n async closeByBackdropClick(timeoutMs: number = defaultTransitionDuration): Promise<boolean> {\n await this.enforcePartExistence('dialogContainer');\n // MUI only dismisses when the same element receives mousedown and click, so\n // drive the full press/release/click sequence on the container's empty corner\n // (the click target must be the container, not the centered paper).\n const cornerClick = { position: { x: 5, y: 5 } } as const;\n await this.parts.dialogContainer.mouseDown(cornerClick);\n await this.parts.dialogContainer.mouseUp(cornerClick);\n await this.parts.dialogContainer.click(cornerClick);\n return this.waitForClose(timeoutMs);\n }\n\n /**\n * Wait for dialog to open\n * @param timeoutMs\n * @returns true open has performed successfully\n */\n async waitForOpen(timeoutMs: number = defaultTransitionDuration): Promise<boolean> {\n const isOpened = await this.interactor.waitUntil({\n probeFn: () => this.isOpen(),\n terminateCondition: true,\n timeoutMs,\n });\n return isOpened === true;\n }\n\n /**\n * Wait for dialog to close\n * @param timeoutMs\n * @returns true open has performed successfully\n */\n async waitForClose(timeoutMs: number = defaultTransitionDuration): Promise<boolean> {\n const isOpened = await this.interactor.waitUntil({\n probeFn: () => this.isOpen(),\n terminateCondition: false,\n timeoutMs,\n });\n return isOpened === false;\n }\n\n /**\n * Check if the dialog box is open. Caution, because of animation, upon an open/close action is performed\n * use waitForOpen() or waitForClose() before using isOpen() would result a more accurate open state of the dialog\n * @returns true if dialog box is open\n */\n async isOpen(): Promise<boolean> {\n const exists = await this.exists();\n if (!exists) {\n return false;\n }\n const isVisible = await this.interactor.isVisible(this.parts.dialogContainer.locator);\n return isVisible;\n }\n\n get driverName(): string {\n return 'MuiV9DialogDriver';\n }\n}\n","import { byCssClass, ContainerDriver, locatorUtil, PartLocator, ScenePart } from '@atomic-testing/core';\n\nconst backdropLocator = byCssClass('MuiBackdrop-root');\nconst defaultTransitionDuration = 250;\n\n/**\n * Shared base for MUI portal-rendered overlays (Drawer today; Dialog, Menu,\n * Popover and SpeedDial are prospective consumers). It owns the open/close\n * lifecycle that {@link DialogDriver} first proved out: `isOpen` derived from the\n * visible surface, `waitForOpen`/`waitForClose` spanning the transition, and\n * `closeByBackdrop`.\n *\n * Subclasses supply {@link getSurfaceLocator} (the element whose visibility means\n * \"open\") and, when the overlay is portal-rendered, override\n * `overriddenParentLocator()`/`overrideLocatorRelativePosition()` to re-root.\n *\n * `closeByEscape` is intentionally absent: keyboard dismissal needs a key-press\n * primitive the `Interactor` interface does not yet expose, which would have to be\n * added to every interactor (DOM/React/Vue/Playwright). It is deferred rather than\n * partially implemented.\n */\nexport abstract class OverlayDriver<ContentT extends ScenePart, T extends ScenePart = {}> extends ContainerDriver<\n ContentT,\n T\n> {\n /**\n * Locator of the surface whose visibility reflects the open state (e.g. the\n * drawer/dialog paper).\n */\n protected abstract getSurfaceLocator(): PartLocator;\n\n /**\n * Locator of the dismissible backdrop. Defaults to MUI's `.MuiBackdrop-root`.\n */\n protected getBackdropLocator(): PartLocator {\n return locatorUtil.append(this.locator, backdropLocator);\n }\n\n /**\n * Whether the overlay is mounted and its surface is visible. Because of open/close\n * transitions, prefer `waitForOpen()`/`waitForClose()` immediately after an action.\n */\n async isOpen(): Promise<boolean> {\n if (!(await this.exists())) {\n return false;\n }\n return this.interactor.isVisible(this.getSurfaceLocator());\n }\n\n /**\n * Wait until the overlay is open.\n * @returns true once open within the timeout.\n */\n async waitForOpen(timeoutMs: number = defaultTransitionDuration): Promise<boolean> {\n const result = await this.interactor.waitUntil({\n probeFn: () => this.isOpen(),\n terminateCondition: true,\n timeoutMs,\n });\n return result === true;\n }\n\n /**\n * Wait until the overlay is closed.\n * @returns true once closed within the timeout.\n */\n async waitForClose(timeoutMs: number = defaultTransitionDuration): Promise<boolean> {\n const result = await this.interactor.waitUntil({\n probeFn: () => this.isOpen(),\n terminateCondition: false,\n timeoutMs,\n });\n if (result === false) {\n return true;\n }\n // Under React's act() the close transition can commit only when the polling\n // act block exits (seen with MUI v5 in jsdom), so the loop above observes the\n // overlay as still open. A final fresh read reflects the now-committed state.\n return !(await this.isOpen());\n }\n\n /**\n * Dismiss by clicking the backdrop, then wait for the close transition. Whether\n * it actually closes depends on the consumer honoring the backdrop dismissal; the\n * returned boolean reflects the observed close, not merely the click.\n */\n async closeByBackdrop(timeoutMs: number = defaultTransitionDuration): Promise<boolean> {\n const backdrop = this.getBackdropLocator();\n if (await this.interactor.exists(backdrop)) {\n // A single click suffices in both worlds: a real browser click is a full\n // mouse sequence, and jsdom dispatches the click event MUI's backdrop\n // onClick listens for. (A separate trailing click would race the dismissal\n // and miss the unmounting backdrop in Playwright.)\n await this.interactor.click(backdrop);\n }\n return this.waitForClose(timeoutMs);\n }\n}\n","import { HTMLElementDriver } from '@atomic-testing/component-driver-html';\nimport {\n byCssClass,\n byRole,\n IContainerDriverOption,\n Interactor,\n type LocatorRelativePosition,\n Optional,\n PartLocator,\n ScenePart,\n} from '@atomic-testing/core';\n\nimport { OverlayDriver } from './OverlayDriver';\n\nexport const drawerParts = {\n paper: {\n locator: byCssClass('MuiDrawer-paper'),\n driver: HTMLElementDriver,\n },\n} satisfies ScenePart;\n\nexport type DrawerAnchor = 'left' | 'right' | 'top' | 'bottom';\n\n// In Material UI v9 the anchor class lives on the drawer root (`.MuiDrawer-root`,\n// the role=\"presentation\" element), not on the paper as in v7.\nconst anchorClassByAnchor: Record<DrawerAnchor, string> = {\n left: 'MuiDrawer-anchorLeft',\n right: 'MuiDrawer-anchorRight',\n top: 'MuiDrawer-anchorTop',\n bottom: 'MuiDrawer-anchorBottom',\n};\n\n// A temporary Drawer is a Modal rendered into a portal whose root carries\n// role=\"presentation\"; re-root to it like DialogDriver does.\nconst drawerRootLocator: PartLocator = byRole('presentation', 'Root');\n\n/**\n * Driver for the Material UI v9 Drawer (and SwipeableDrawer) component.\n *\n * A temporary Drawer is a portal-rendered Modal: its root `role=\"presentation\"`\n * (`.MuiDrawer-root`) carries the anchor class and holds a `.MuiBackdrop-root` plus\n * the `.MuiDrawer-paper` panel. Open/close/backdrop behavior is inherited from\n * {@link OverlayDriver}; this driver adds the anchor read and the portal re-rooting.\n * @see https://mui.com/material-ui/react-drawer/\n */\nexport class DrawerDriver<ContentT extends ScenePart> extends OverlayDriver<ContentT, typeof drawerParts> {\n constructor(locator: PartLocator, interactor: Interactor, option?: Partial<IContainerDriverOption>) {\n super(locator, interactor, {\n ...option,\n parts: drawerParts,\n content: (option?.content ?? {}) as ContentT,\n });\n }\n\n override overriddenParentLocator(): Optional<PartLocator> {\n return drawerRootLocator;\n }\n\n override overrideLocatorRelativePosition(): Optional<LocatorRelativePosition> {\n return 'Same';\n }\n\n protected getSurfaceLocator(): PartLocator {\n return this.parts.paper.locator;\n }\n\n /**\n * The side the drawer is anchored to, read from the portal root's anchor class, or\n * `undefined` when the drawer is closed/unmounted.\n *\n * The anchor class sits on the `role=\"presentation\"` root itself, so it is read\n * directly off {@link drawerRootLocator} rather than through a part (parts resolve\n * as descendants of that root, but the class is on the root).\n */\n async getAnchor(): Promise<Optional<DrawerAnchor>> {\n if (!(await this.interactor.exists(drawerRootLocator))) {\n return undefined;\n }\n for (const anchor of Object.keys(anchorClassByAnchor) as DrawerAnchor[]) {\n if (await this.interactor.hasCssClass(drawerRootLocator, anchorClassByAnchor[anchor])) {\n return anchor;\n }\n }\n return undefined;\n }\n\n get driverName(): string {\n return 'MuiV9DrawerDriver';\n }\n}\n","import { ButtonDriver } from './ButtonDriver';\n\n/**\n * Driver for Material UI v9 Floating Action Button component.\n * @see https://mui.com/material-ui/react-floating-action-button/\n */\nexport class FabDriver extends ButtonDriver {\n override get driverName(): string {\n return 'MuiV9FabDriver';\n }\n}\n","import { HTMLTextInputDriver } from '@atomic-testing/component-driver-html';\nimport {\n byCssSelector,\n ComponentDriver,\n IComponentDriverOption,\n IInputDriver,\n Interactor,\n PartLocator,\n ScenePart,\n} from '@atomic-testing/core';\n\nexport const parts = {\n singlelineInput: {\n locator: byCssSelector('input:not([aria-hidden])'),\n driver: HTMLTextInputDriver,\n },\n multilineInput: {\n locator: byCssSelector('textarea:not([aria-hidden])'),\n driver: HTMLTextInputDriver,\n },\n} satisfies ScenePart;\n\ntype TextFieldInputType = 'singleLine' | 'multiline';\n\n/**\n * A driver for the Material UI v9 Input, FilledInput, OutlinedInput, and StandardInput components.\n */\nexport class InputDriver extends ComponentDriver<typeof parts> implements IInputDriver<string | null> {\n constructor(locator: PartLocator, interactor: Interactor, option?: Partial<IComponentDriverOption>) {\n super(locator, interactor, {\n ...option,\n parts,\n });\n }\n\n private async getInputType(): Promise<TextFieldInputType> {\n // TODO: Detection of both input types can be done in parallel.\n const textInputExists = await this.interactor.exists(this.parts.singlelineInput.locator);\n if (textInputExists) {\n return 'singleLine';\n }\n\n const multilineExists = await this.interactor.exists(this.parts.multilineInput.locator);\n if (multilineExists) {\n return 'multiline';\n }\n\n throw new Error('Unable to determine input type in TextFieldInput');\n }\n\n /**\n * Retrieve the current value of the input element, handling both single line\n * and multiline configurations.\n */\n async getValue(): Promise<string | null> {\n const inputType = await this.getInputType();\n switch (inputType) {\n case 'singleLine':\n return this.parts.singlelineInput.getValue();\n case 'multiline':\n return this.parts.multilineInput.getValue();\n }\n }\n\n /**\n * Set the value of the underlying input element.\n *\n * @param value The text to assign to the input.\n */\n async setValue(value: string | null): Promise<boolean> {\n const inputType = await this.getInputType();\n switch (inputType) {\n case 'singleLine':\n return this.parts.singlelineInput.setValue(value);\n case 'multiline':\n return this.parts.multilineInput.setValue(value);\n }\n }\n\n /**\n * Determine whether the input element is disabled.\n */\n async isDisabled(): Promise<boolean> {\n const inputType = await this.getInputType();\n switch (inputType) {\n case 'singleLine':\n return this.parts.singlelineInput.isDisabled();\n case 'multiline':\n return this.parts.multilineInput.isDisabled();\n }\n }\n\n /**\n * Determine whether the input element is read only.\n */\n async isReadonly(): Promise<boolean> {\n const inputType = await this.getInputType();\n switch (inputType) {\n case 'singleLine':\n return this.parts.singlelineInput.isReadonly();\n case 'multiline':\n return this.parts.multilineInput.isReadonly();\n }\n }\n\n /**\n * Identifier for this driver.\n */\n get driverName(): string {\n return 'MuiV9InputDriver';\n }\n}\n","import { ComponentDriver, ErrorBase } from '@atomic-testing/core';\n\nexport const MenuItemDisabledErrorId = 'MenuItemDisabledError';\n\nfunction getErrorMessage(label: string): string {\n return `The menu item with label: ${label} is disabled`;\n}\n\nexport class MenuItemDisabledError extends ErrorBase {\n constructor(\n public readonly label: string,\n public readonly driver: ComponentDriver<any>\n ) {\n super(getErrorMessage(label), driver);\n this.name = MenuItemDisabledErrorId;\n }\n}\n","import { ComponentDriver } from '@atomic-testing/core';\n\nimport { MenuItemDisabledError } from '../errors/MenuItemDisabledError';\n\n/**\n * @internal\n */\nexport class ListItemDriver extends ComponentDriver {\n async label(): Promise<string | null> {\n const label = await this.getText();\n return label?.trim() || null;\n }\n\n async isSelected(): Promise<boolean> {\n return await this.interactor.hasCssClass(this.locator, 'Mui-selected');\n }\n\n async isDisabled(): Promise<boolean> {\n const disabledVal = await this.interactor.getAttribute(this.locator, 'aria-disabled');\n return disabledVal === 'true';\n }\n\n async click(): Promise<void> {\n if (await this.isDisabled()) {\n const label = await this.label();\n throw new MenuItemDisabledError(label ?? '', this);\n }\n await this.interactor.click(this.locator);\n }\n\n get driverName(): string {\n return 'MuiV9ListItemDriver';\n }\n}\n","import {\n byRole,\n IComponentDriverOption,\n Interactor,\n ListComponentDriver,\n ListComponentDriverSpecificOption,\n listHelper,\n PartLocator,\n} from '@atomic-testing/core';\n\nimport { ListItemDriver } from './ListItemDriver';\n\nexport const defaultListDriverOption: ListComponentDriverSpecificOption<ListItemDriver> = {\n itemClass: ListItemDriver,\n itemLocator: byRole('option'),\n};\n\ntype ListDriverOption<ItemT extends ListItemDriver> = ListComponentDriverSpecificOption<ItemT> &\n Partial<IComponentDriverOption<any>>;\n\nexport class ListDriver<ItemT extends ListItemDriver = ListItemDriver> extends ListComponentDriver<ItemT> {\n constructor(\n locator: PartLocator,\n interactor: Interactor,\n option: ListDriverOption<ItemT> = { ...defaultListDriverOption } as ListDriverOption<ItemT>\n ) {\n super(locator, interactor, option);\n }\n\n async getSelected(): Promise<ListItemDriver | null> {\n for await (const item of listHelper.getListItemIterator(this, this.getItemLocator(), ListItemDriver)) {\n if (await item.isSelected()) {\n return item;\n }\n }\n return null;\n }\n\n override get driverName(): string {\n return 'MuiV9ListDriver';\n }\n}\n","import { ComponentDriver, ErrorBase } from '@atomic-testing/core';\n\nexport const MenuItemNotFoundErrorId = 'MenuItemNotFoundError';\n\nfunction getErrorMessage(label: string): string {\n return `Cannot find menu item with label: ${label}`;\n}\n\nexport class MenuItemNotFoundError extends ErrorBase {\n constructor(\n public readonly label: string,\n public readonly driver: ComponentDriver<any>\n ) {\n super(getErrorMessage(label), driver);\n this.name = MenuItemNotFoundErrorId;\n }\n}\n","import { ListItemDriver } from './ListItemDriver';\n\n/**\n * @internal\n */\nexport class MenuItemDriver extends ListItemDriver {\n async value(): Promise<string | null> {\n const value = await this.interactor.getAttribute(this.locator, 'data-value');\n return value ?? null;\n }\n\n override get driverName(): string {\n return 'MuiV9MenuItemDriver';\n }\n}\n","import { HTMLElementDriver } from '@atomic-testing/component-driver-html';\nimport {\n byRole,\n ComponentDriver,\n IComponentDriverOption,\n Interactor,\n listHelper,\n type LocatorRelativePosition,\n Optional,\n PartLocator,\n ScenePart,\n} from '@atomic-testing/core';\n\nimport { MenuItemNotFoundError } from '../errors/MenuItemNotFoundError';\nimport { MenuItemDriver } from './MenuItemDriver';\n\nexport const parts = {\n menu: {\n locator: byRole('menu'),\n driver: HTMLElementDriver,\n },\n} satisfies ScenePart;\n\nconst menuRootLocator: PartLocator = byRole('presentation', 'Root');\nconst menuItemLocator = byRole('menuitem');\n\nexport class MenuDriver extends ComponentDriver<typeof parts> {\n constructor(locator: PartLocator, interactor: Interactor, option?: Partial<IComponentDriverOption>) {\n super(locator, interactor, {\n ...option,\n parts,\n });\n }\n\n override overriddenParentLocator(): Optional<PartLocator> {\n return menuRootLocator;\n }\n\n override overrideLocatorRelativePosition(): Optional<LocatorRelativePosition> {\n return 'Same';\n }\n\n async getMenuItemByLabel(label: string): Promise<MenuItemDriver | null> {\n for await (const item of listHelper.getListItemIterator(this, menuItemLocator, MenuItemDriver)) {\n const itemLabel = await item.label();\n if (itemLabel === label) {\n return item;\n }\n }\n return null;\n }\n\n async selectByLabel(label: string): Promise<void> {\n const item = await this.getMenuItemByLabel(label);\n if (item) {\n await item.click();\n } else {\n throw new MenuItemNotFoundError(label, this);\n }\n }\n\n get driverName(): string {\n return 'MuiV9MenuDriver';\n }\n}\n","import { byAttribute, byCssSelector, ComponentDriver, locatorUtil, PartLocator } from '@atomic-testing/core';\n\n// Numbered page controls are the only ones that carry the `MuiPaginationItem-page`\n// state class; matching on it selects every page button regardless of selection.\nconst pageItemLocator = byCssSelector('.MuiPaginationItem-page');\n// MUI marks exactly the selected page with an `aria-current` attribute (value\n// \"page\"); matching on its presence is version-agnostic.\nconst selectedPageLocator = byCssSelector('[aria-current]');\nconst firstButtonLocator = byAttribute('aria-label', 'Go to first page');\nconst previousButtonLocator = byAttribute('aria-label', 'Go to previous page');\nconst nextButtonLocator = byAttribute('aria-label', 'Go to next page');\nconst lastButtonLocator = byAttribute('aria-label', 'Go to last page');\n\n/**\n * Driver for the Material UI v9 Pagination component.\n *\n * Pagination renders a `<nav>` whose `MuiPaginationItem` buttons are each wrapped\n * in their own `<li>` (so they are not siblings — positional `:nth-of-type`\n * iteration does not apply). Page controls are read by their accessible name\n * instead: every page button's aria-label ends in its page number (\"Go to page N\",\n * or \"page N\" once selected), and first/previous/next/last carry stable\n * aria-labels and become `disabled` at the bounds.\n * @see https://mui.com/material-ui/react-pagination/\n */\nexport class PaginationDriver extends ComponentDriver {\n private get pageItemsLocator(): PartLocator {\n return locatorUtil.append(this.locator, pageItemLocator);\n }\n\n /**\n * The selected page number, or `-1` when no page is marked current.\n */\n async getSelectedPage(): Promise<number> {\n const locator = locatorUtil.append(this.locator, selectedPageLocator);\n if (!(await this.interactor.exists(locator))) {\n return -1;\n }\n const text = await this.interactor.getText(locator);\n const page = Number.parseInt(text?.trim() ?? '', 10);\n return Number.isNaN(page) ? -1 : page;\n }\n\n /**\n * Total number of pages, taken from the highest numbered page control. MUI\n * always renders the upper boundary page (boundaryCount >= 1), so this is exact\n * even when middle pages collapse into an ellipsis.\n */\n async getPageCount(): Promise<number> {\n const labels = await this.interactor.getAttribute(this.pageItemsLocator, 'aria-label', true);\n let max = 0;\n for (const label of labels) {\n const match = label?.match(/(\\d+)\\s*$/);\n if (match != null) {\n const page = Number.parseInt(match[1], 10);\n if (page > max) {\n max = page;\n }\n }\n }\n return max;\n }\n\n /**\n * Click the numbered control for `page`. A no-op (returns `true`) when `page` is\n * already selected.\n * @returns `false` when that page is not currently rendered (e.g. hidden behind\n * an ellipsis) or is disabled.\n */\n async goToPage(page: number): Promise<boolean> {\n if ((await this.getSelectedPage()) === page) {\n return true;\n }\n const locator = locatorUtil.append(this.locator, byAttribute('aria-label', `Go to page ${page}`));\n if (!(await this.interactor.exists(locator)) || (await this.interactor.isDisabled(locator))) {\n return false;\n }\n await this.interactor.click(locator);\n return true;\n }\n\n /**\n * Click a navigation control unless it is absent or disabled (at a bound).\n * @returns whether the click was performed.\n */\n private async clickNavButton(navLocator: PartLocator): Promise<boolean> {\n const locator = locatorUtil.append(this.locator, navLocator);\n if (!(await this.interactor.exists(locator)) || (await this.interactor.isDisabled(locator))) {\n return false;\n }\n await this.interactor.click(locator);\n return true;\n }\n\n /** Go to the next page. Returns `false` when on the last page or the control is hidden. */\n async next(): Promise<boolean> {\n return this.clickNavButton(nextButtonLocator);\n }\n\n /** Go to the previous page. Returns `false` when on the first page or the control is hidden. */\n async previous(): Promise<boolean> {\n return this.clickNavButton(previousButtonLocator);\n }\n\n /** Jump to the first page. Returns `false` when already there or the control is hidden (needs `showFirstButton`). */\n async first(): Promise<boolean> {\n return this.clickNavButton(firstButtonLocator);\n }\n\n /** Jump to the last page. Returns `false` when already there or the control is hidden (needs `showLastButton`). */\n async last(): Promise<boolean> {\n return this.clickNavButton(lastButtonLocator);\n }\n\n override get driverName(): string {\n return 'MuiV9PaginationDriver';\n }\n}\n","import { HTMLRadioButtonGroupDriver } from '@atomic-testing/component-driver-html';\nimport {\n byCssSelector,\n byInputType,\n byValue,\n ComponentDriver,\n IComponentDriverOption,\n IInputDriver,\n Interactor,\n locatorUtil,\n PartLocator,\n ScenePart,\n} from '@atomic-testing/core';\n\nexport const parts = {\n choices: {\n locator: byInputType('radio'),\n driver: HTMLRadioButtonGroupDriver,\n },\n} satisfies ScenePart;\n\nexport class ProgressDriver extends ComponentDriver<typeof parts> implements IInputDriver<number | null> {\n constructor(locator: PartLocator, interactor: Interactor, option?: Partial<IComponentDriverOption>) {\n super(locator, interactor, {\n ...option,\n parts,\n });\n }\n\n async getValue(): Promise<number | null> {\n const rawValue = await this.getAttribute('aria-valuenow');\n const numValue = Number(rawValue);\n if (rawValue == null || isNaN(numValue)) {\n return null;\n }\n return Number(rawValue);\n }\n\n async getType(): Promise<'linear' | 'circular'> {\n const cssClasses = await this.getAttribute('class');\n if (cssClasses?.includes('MuiCircularProgress-root')) {\n return 'circular';\n }\n return 'linear';\n }\n\n async isDeterminate(): Promise<boolean> {\n const val = await this.getValue();\n return val != null;\n }\n\n //TODO: Buffer value can be extracted from style=\"transform: translateX(-15%);\" actual value would be 100 - 15 = 85\n // <span class=\"MuiLinearProgress-bar MuiLinearProgress-bar2 MuiLinearProgress-colorPrimary MuiLinearProgress-bar2Buffer css-1v1662g-MuiLinearProgress-bar2\" style=\"transform: translateX(-15%);\"></span>\n\n async setValue(value: number | null): Promise<boolean> {\n // TODO: Setting value to null is not supported. https://github.com/atomic-testing/atomic-testing/issues/68\n const currentValue = await this.getValue();\n if (value === currentValue) {\n return true;\n }\n\n const valueToClick = (value == null ? currentValue : value) as number;\n const targetLocator = locatorUtil.append(this.parts.choices.locator, byValue(valueToClick.toString(), 'Same'));\n\n const targetExists = await this.interactor.exists(targetLocator);\n if (targetExists) {\n const id = await this.interactor.getAttribute(targetLocator, 'id');\n const labelLocator = locatorUtil.append(this.locator, byCssSelector(`label[for=\"${id}\"]`));\n await this.interactor.click(labelLocator);\n }\n // TODO: throw error if the value does not exist\n return targetExists;\n }\n\n get driverName(): string {\n return 'MuiV9ProgressDriver';\n }\n}\n","import { byCssSelector, ComponentDriver, locatorUtil, Optional, PartLocator } from '@atomic-testing/core';\n\n// The radio `<input>` carries checked/value/disabled; located as a descendant of\n// this option's FormControlLabel root.\nconst inputLocator: PartLocator = byCssSelector('input');\nconst checkedInputLocator: PartLocator = byCssSelector('input:checked');\n\n/**\n * Driver for a single Material UI v9 Radio option (a `FormControlLabel` wrapping a\n * `Radio`). Its label text is the `FormControlLabel`'s text; selected/value/disabled\n * state is read from the underlying radio `<input>`.\n *\n * Used as the item driver of {@link RadioGroupDriver}, but also usable on its own\n * when a single radio option is addressed directly. It declares no parts (so it\n * composes as a list item) and reads the input via descendant locators.\n * @see https://mui.com/material-ui/react-radio-button/\n */\nexport class RadioDriver extends ComponentDriver {\n private get input(): PartLocator {\n return locatorUtil.append(this.locator, inputLocator);\n }\n\n /**\n * The option's visible label, or `undefined` when it renders without text.\n */\n async getLabel(): Promise<Optional<string>> {\n const text = await this.getText();\n return text?.trim() || undefined;\n }\n\n /**\n * The option's `value` attribute.\n */\n async getValue(): Promise<string | null> {\n const value = await this.interactor.getAttribute(this.input, 'value');\n return value ?? null;\n }\n\n /**\n * Whether this option is the selected one in its group.\n */\n isSelected(): Promise<boolean> {\n return this.interactor.exists(locatorUtil.append(this.locator, checkedInputLocator));\n }\n\n /**\n * Whether this option is disabled.\n */\n isDisabled(): Promise<boolean> {\n return this.interactor.isDisabled(this.input);\n }\n\n /**\n * Select this option by clicking its radio input. No-op effect when already selected.\n */\n async select(): Promise<void> {\n await this.interactor.click(this.input);\n }\n\n get driverName(): string {\n return 'MuiV9RadioDriver';\n }\n}\n","import {\n byCssSelector,\n escapeUtil,\n IComponentDriverOption,\n IInputDriver,\n Interactor,\n ListComponentDriver,\n ListComponentDriverSpecificOption,\n locatorUtil,\n Nullable,\n PartLocator,\n} from '@atomic-testing/core';\n\nimport { RadioDriver } from './RadioDriver';\n\n/**\n * Radio options are located by their `FormControlLabel` root, which wraps the\n * radio `<input>` and renders the label text — the unit a {@link RadioDriver}\n * drives.\n */\nexport const defaultRadioGroupDriverOption: ListComponentDriverSpecificOption<RadioDriver> = {\n itemClass: RadioDriver,\n itemLocator: byCssSelector('.MuiFormControlLabel-root'),\n};\n\ntype RadioGroupDriverOption<ItemT extends RadioDriver> = ListComponentDriverSpecificOption<ItemT> &\n Partial<IComponentDriverOption<any>>;\n\n/**\n * Driver for the Material UI v9 RadioGroup component.\n *\n * `<RadioGroup>` renders a `role=\"radiogroup\"` whose options are `FormControlLabel`s\n * wrapping a radio `<input>`. This driver is a {@link ListComponentDriver} over those\n * options, so per-option {@link RadioDriver} instances are available via\n * `getItems`/`getItemByIndex`/`getItemByLabel`, on top of the group-level value and\n * label helpers. The selected value is read from the checked `<input>` and selection\n * is made by value or label.\n * @see https://mui.com/material-ui/react-radio-button/\n */\nexport class RadioGroupDriver<ItemT extends RadioDriver = RadioDriver>\n extends ListComponentDriver<ItemT>\n implements IInputDriver<string | null>\n{\n constructor(locator: PartLocator, interactor: Interactor, option: Partial<RadioGroupDriverOption<ItemT>> = {}) {\n // The option shape is fixed (FormControlLabel options driven by RadioDriver),\n // so defaults are merged in rather than relying on a default parameter, which a\n // scene part's always-present option object would otherwise shadow.\n super(locator, interactor, {\n ...defaultRadioGroupDriverOption,\n ...option,\n } as RadioGroupDriverOption<ItemT>);\n }\n\n /**\n * The `value` of the selected option, or `null` when none is selected.\n */\n async getValue(): Promise<string | null> {\n const checked = locatorUtil.append(this.locator, byCssSelector('input:checked'));\n const value = await this.interactor.getAttribute(checked, 'value');\n return value ?? null;\n }\n\n /**\n * Select the option whose radio `<input>` has the given `value`.\n * @returns `false` when no option has that value, or when `value` is `null`.\n */\n async setValue(value: string | null): Promise<boolean> {\n if (value == null) {\n return false;\n }\n const input = locatorUtil.append(this.locator, byCssSelector(`input[value=\"${escapeUtil.escapeValue(value)}\"]`));\n if (!(await this.interactor.exists(input))) {\n return false;\n }\n await this.interactor.click(input);\n return true;\n }\n\n /**\n * The visible label of every option, in DOM order.\n */\n async getOptions(): Promise<string[]> {\n const items = await this.getItems();\n const labels: string[] = [];\n for (const item of items) {\n labels.push((await item.getLabel()) ?? '');\n }\n return labels;\n }\n\n /**\n * The label of the selected option, or `null` when none is selected.\n */\n async getSelectedLabel(): Promise<Nullable<string>> {\n const items = await this.getItems();\n for (const item of items) {\n if (await item.isSelected()) {\n return (await item.getLabel()) ?? null;\n }\n }\n return null;\n }\n\n /**\n * Select the first option whose visible label equals `label`.\n * @returns `false` when no option matches.\n */\n async selectByLabel(label: string): Promise<boolean> {\n const option = await this.getItemByLabel(label);\n if (option == null) {\n return false;\n }\n await option.select();\n return true;\n }\n\n /**\n * Whether the option with the given label is disabled.\n * @returns `false` when no option matches.\n */\n async isOptionDisabled(label: string): Promise<boolean> {\n const option = await this.getItemByLabel(label);\n return option == null ? false : option.isDisabled();\n }\n\n override get driverName(): string {\n return 'MuiV9RadioGroupDriver';\n }\n}\n","import { HTMLRadioButtonGroupDriver } from '@atomic-testing/component-driver-html';\nimport {\n byCssClass,\n byInputType,\n byValue,\n ComponentDriver,\n IComponentDriverOption,\n IInputDriver,\n Interactor,\n locatorUtil,\n PartLocator,\n ScenePart,\n} from '@atomic-testing/core';\n\nexport const parts = {\n choices: {\n locator: byInputType('radio'),\n driver: HTMLRadioButtonGroupDriver,\n },\n} satisfies ScenePart;\n\n/**\n * MUI marks the disabled/read-only state with a class on the Rating root span\n * (`Mui-disabled` / `Mui-readOnly`), not on the visually-hidden radio inputs that\n * the composed {@link HTMLRadioButtonGroupDriver} can see — so these states are\n * only observable from the root element.\n */\nconst disabledClassName = 'Mui-disabled';\nconst readOnlyClassName = 'Mui-readOnly';\nconst filledIconClassName = 'MuiRating-iconFilled';\n\nexport class RatingDriver extends ComponentDriver<typeof parts> implements IInputDriver<number | null> {\n constructor(locator: PartLocator, interactor: Interactor, option?: Partial<IComponentDriverOption>) {\n super(locator, interactor, {\n ...option,\n parts,\n });\n }\n\n async getValue(): Promise<number | null> {\n // A read-only Rating renders no radio inputs (root becomes `role=\"img\"` with the\n // value carried in `aria-label`), so the radio-based read below cannot be used.\n const isReadOnly = await this.interactor.hasCssClass(this.locator, readOnlyClassName);\n if (isReadOnly) {\n return this.getReadOnlyValue();\n }\n\n await this.enforcePartExistence('choices');\n const value = await this.parts.choices.getValue();\n // The \"no rating\" state is the visually-hidden radio whose `value` attribute is the\n // empty string; treat it the same as an absent selection.\n if (value == null || value === '') {\n return null;\n }\n return parseFloat(value);\n }\n\n /**\n * Read the value of a read-only Rating.\n *\n * Primary source is the root's `aria-label`, which MUI populates with the accessible\n * name (e.g. `\"2.5 Stars\"`) — accessibility-first and precision-accurate. When a\n * caller supplies a custom, non-numeric `aria-label`, fall back to counting the\n * filled star icons; that count is exact for whole-star ratings.\n */\n private async getReadOnlyValue(): Promise<number | null> {\n const label = await this.interactor.getAttribute(this.locator, 'aria-label');\n if (label != null) {\n const parsed = parseFloat(label);\n if (!Number.isNaN(parsed)) {\n return parsed;\n }\n }\n\n const filledLocator = locatorUtil.append(this.locator, byCssClass(filledIconClassName));\n const filledIcons = await this.interactor.getAttribute(filledLocator, 'class', true);\n return filledIcons.length > 0 ? filledIcons.length : null;\n }\n\n /**\n * Whether the Rating is disabled. `disabled` is reflected as the `Mui-disabled`\n * class on the root span (the composed radio-group driver exposes no `isDisabled`).\n */\n async isDisabled(): Promise<boolean> {\n return this.interactor.hasCssClass(this.locator, disabledClassName);\n }\n\n async setValue(value: number | null): Promise<boolean> {\n const currentValue = await this.getValue();\n if (value === currentValue) {\n return true;\n }\n\n // Activate the visually-hidden `<input type=\"radio\">` whose `value` attribute\n // matches the target — the empty-string radio (MUI's \"no rating\") for a clear.\n // `activate` is coordinate-free, so it reaches inputs a positional click cannot:\n // the half-star label for fractional values is zero-width and unclickable in a\n // real browser (#86), and the clear radio has no `<label>` at all (#68). This\n // unifies integer, fractional, and clear on one portable path.\n const targetValue = value == null ? '' : value.toString();\n const targetLocator = locatorUtil.append(this.parts.choices.locator, byValue(targetValue, 'Same'));\n const targetExists = await this.interactor.exists(targetLocator);\n if (targetExists) {\n await this.interactor.activate(targetLocator);\n }\n // TODO: throw error if the value does not exist\n return targetExists;\n }\n\n get driverName(): string {\n return 'MuiV9RatingDriver';\n }\n}\n","import {\n HTMLButtonDriver,\n HTMLElementDriver,\n HTMLSelectDriver,\n HTMLTextInputDriver,\n} from '@atomic-testing/component-driver-html';\nimport {\n byAttribute,\n byCssSelector,\n byRole,\n byTagName,\n ComponentDriver,\n IComponentDriverOption,\n IInputDriver,\n Interactor,\n listHelper,\n locatorUtil,\n Nullable,\n PartLocator,\n ScenePart,\n ScenePartDriver,\n} from '@atomic-testing/core';\n\nimport { MenuItemNotFoundError } from '../errors/MenuItemNotFoundError';\nimport { MenuItemDriver } from './MenuItemDriver';\n\nexport const selectPart = {\n trigger: {\n locator: byRole('combobox'), // Starting in 5.12 and beyond, the role has changed from 'button' to 'combobox'\n driver: HTMLButtonDriver,\n },\n dropdown: {\n locator: byCssSelector('[role=presentation] [role=listbox]', 'Root'),\n driver: HTMLElementDriver,\n },\n input: {\n locator: byTagName('input'),\n driver: HTMLTextInputDriver,\n },\n nativeSelect: {\n locator: byTagName('select'),\n driver: HTMLSelectDriver,\n },\n} satisfies ScenePart;\n\nexport type SelectScenePart = typeof selectPart;\nexport type SelectScenePartDriver = ScenePartDriver<SelectScenePart>;\nexport interface MenuItemGetOption {\n /**\n * When true, the driver will not check if the dropdown is open, which helps speed the process up.\n */\n skipDropdownCheck?: boolean;\n}\nconst optionLocator = byRole('option');\n\nexport class SelectDriver extends ComponentDriver<SelectScenePart> implements IInputDriver<string | null> {\n constructor(locator: PartLocator, interactor: Interactor, option?: Partial<IComponentDriverOption>) {\n super(locator, interactor, {\n ...option,\n parts: selectPart,\n });\n }\n async isNative(): Promise<boolean> {\n const nativeSelectExists = await this.interactor.exists(this.parts.nativeSelect.locator);\n return Promise.resolve(nativeSelectExists);\n }\n\n async getValue(): Promise<string | null> {\n const isNative = await this.isNative();\n if (isNative) {\n const val = (await this.parts.nativeSelect.getValue()) as Nullable<string>;\n return val;\n }\n\n await this.enforcePartExistence('input');\n const value = await this.parts.input.getValue();\n return value ?? null;\n }\n\n async setValue(value: string | null): Promise<boolean> {\n let success = false;\n const isNative = await this.isNative();\n if (isNative) {\n success = await this.parts.nativeSelect.setValue(value);\n return success;\n }\n\n await this.openDropdown();\n await this.enforcePartExistence('dropdown');\n const optionSelector = byAttribute('data-value', value!);\n const optionLocator = locatorUtil.append(this.parts.dropdown.locator, optionSelector);\n const optionExists = await this.interactor.exists(optionLocator);\n\n if (optionExists) {\n await this.interactor.click(optionLocator);\n success = true;\n }\n\n return success;\n }\n\n /**\n * Select menu item by its label, if it exists\n * Limitation, this method will not work if the dropdown is a native select.\n * @param label\n * @returns\n */\n async getMenuItemByLabel(label: string, option?: MenuItemGetOption): Promise<MenuItemDriver | null> {\n if (!option?.skipDropdownCheck) {\n await this.openDropdown();\n }\n\n // TODO: Add native select support\n\n for await (const item of listHelper.getListItemIterator(this, optionLocator, MenuItemDriver)) {\n const itemLabel = await item.label();\n if (itemLabel === label) {\n return item;\n }\n }\n return null;\n }\n\n /**\n * Selects an option by its label\n * @param label\n * @returns\n */\n async selectByLabel(label: string): Promise<void> {\n const isNative = await this.isNative();\n if (isNative) {\n await this.parts.nativeSelect.selectByLabel(label);\n return;\n }\n\n await this.enforcePartExistence('trigger');\n await this.parts.trigger.click();\n\n await this.enforcePartExistence('dropdown');\n const item = await this.getMenuItemByLabel(label, { skipDropdownCheck: true });\n\n if (item) {\n await item.click();\n } else {\n throw new MenuItemNotFoundError(label, this);\n }\n }\n\n async getSelectedLabel(): Promise<string | null> {\n const isNative = await this.isNative();\n if (isNative) {\n return await this.parts.nativeSelect.getSelectedLabel();\n }\n\n await this.enforcePartExistence('trigger');\n const label = await this.parts.trigger.getText();\n return label ?? null;\n }\n\n override async exists(): Promise<boolean> {\n const triggerExists = await this.interactor.exists(this.parts.trigger.locator);\n if (triggerExists) {\n return true;\n }\n\n const nativeExists = await this.interactor.exists(this.parts.nativeSelect.locator);\n return nativeExists;\n }\n\n /**\n * Check if the dropdown is open, or if it is a native select, it is always open because there is no known way check its open state\n * @returns For native dropdown it is always true. For custom dropdown, it is true if the dropdown is open.\n */\n async isDropdownOpen(): Promise<boolean> {\n const isNative = await this.isNative();\n if (isNative) {\n return true;\n } else {\n return this.parts.dropdown.exists();\n }\n }\n\n async openDropdown(): Promise<void> {\n const isOpen = await this.isDropdownOpen();\n if (isOpen) {\n return;\n }\n await this.parts.trigger.click();\n }\n\n async closeDropdown(): Promise<void> {\n const isOpen = await this.isDropdownOpen();\n if (!isOpen) {\n return;\n }\n await this.parts.trigger.click();\n }\n\n async isDisabled(): Promise<boolean> {\n const isNative = await this.isNative();\n if (isNative) {\n return this.parts.nativeSelect.isDisabled();\n } else {\n await this.enforcePartExistence('trigger');\n const isDisabled = await this.interactor.getAttribute(this.parts.trigger.locator, 'aria-disabled');\n return isDisabled === 'true';\n }\n }\n\n async isReadonly(): Promise<boolean> {\n const isNative = await this.isNative();\n if (isNative) {\n return this.parts.nativeSelect.isReadonly();\n } else {\n // Cannot determine readonly state of a select input.\n return false;\n }\n }\n\n get driverName(): string {\n return 'MuiV9SelectDriver';\n }\n}\n","import { HTMLTextInputDriver } from '@atomic-testing/component-driver-html';\nimport {\n byCssSelector,\n ComponentDriver,\n IComponentDriverOption,\n IInputDriver,\n Interactor,\n locatorUtil,\n PartLocator,\n ScenePart,\n ScenePartDriver,\n} from '@atomic-testing/core';\n\nexport const parts = {\n input: {\n locator: byCssSelector('input[type=\"range\"][data-index=\"0\"]'),\n driver: HTMLTextInputDriver,\n },\n} satisfies ScenePart;\n\nexport type SelectScenePart = typeof parts;\nexport type SelectScenePartDriver = ScenePartDriver<SelectScenePart>;\n\nexport class SliderDriver extends ComponentDriver<SelectScenePart> implements IInputDriver<number> {\n constructor(locator: PartLocator, interactor: Interactor, option?: Partial<IComponentDriverOption>) {\n super(locator, interactor, {\n ...option,\n parts: parts,\n });\n }\n\n /**\n * Return the first occurrence of the Slider input\n * @returns\n */\n async getValue(): Promise<number> {\n const values = await this.getRangeValues(1);\n return values[0]!;\n }\n\n /**\n * Set slider's range value. Do not use as it will throw an error\n * @param values\n * @see https://github.com/atomic-testing/atomic-testing/issues/73\n */\n async setValue(value: number): Promise<boolean> {\n const success = await this.setRangeValues([value]);\n return success;\n }\n\n async getRangeValues(count?: number): Promise<readonly number[]> {\n await this.enforcePartExistence('input');\n const result: number[] = [];\n\n let index = 0;\n let done = false;\n while (!done) {\n const locator = locatorUtil.append(this.locator, this.getInputLocator(index));\n const exists = await this.interactor.exists(locator);\n if (exists) {\n index++;\n done = count != null && index >= count;\n const value = await this.interactor.getAttribute(locator, 'value');\n result.push(parseFloat(value!));\n } else {\n done = true;\n }\n }\n return result;\n }\n\n private getInputLocator(index: number): PartLocator {\n return byCssSelector(`input[type=\"range\"][data-index=\"${index}\"]`);\n }\n\n /**\n * Set slider's range values. Do not use as it will throw an error\n * @param values\n * @see https://github.com/atomic-testing/atomic-testing/issues/73\n */\n async setRangeValues(_values: readonly number[]): Promise<boolean> {\n await this.enforcePartExistence('input');\n throw new Error('setRangeValue is not supported.');\n // for (let index = 0; index < values.length; index++) {\n // const locator = locatorUtil.append(this.locator, this.getInputLocator(index));\n // const exists = await this.interactor.exists(locator);\n // if (exists) {\n // // @ts-ignore\n // await this.interactor.changeValue(locator, values[index].toString());\n // // const driver = new HTMLTextInputDriver(locator, this.interactor);\n // // await driver.setValue(values[index].toString());\n // } else {\n // return false;\n // }\n // }\n\n // return true;\n }\n\n async isDisabled(): Promise<boolean> {\n await this.enforcePartExistence('input');\n const disabled = await this.parts.input.isDisabled();\n return disabled;\n }\n\n get driverName(): string {\n return 'MuiV9SliderDriver';\n }\n}\n","import { HTMLElementDriver } from '@atomic-testing/component-driver-html';\nimport {\n byCssClass,\n ComponentDriver,\n IComponentDriverOption,\n Interactor,\n locatorUtil,\n PartLocator,\n ScenePart,\n ComponentDriverCtor,\n} from '@atomic-testing/core';\n\nexport const parts = {\n contentDisplay: {\n locator: byCssClass('MuiSnackbarContent-message'),\n driver: HTMLElementDriver,\n },\n actionArea: {\n locator: byCssClass('MuiSnackbarContent-action'),\n driver: HTMLElementDriver,\n },\n} satisfies ScenePart;\n\n/**\n * Driver for Material UI v9 Snackbar component.\n * @see https://mui.com/material-ui/react-snackbar/\n */\nexport class SnackbarDriver extends ComponentDriver<typeof parts> {\n constructor(locator: PartLocator, interactor: Interactor, option?: Partial<IComponentDriverOption>) {\n super(locator, interactor, {\n ...option,\n parts: parts,\n });\n }\n\n /**\n * Get the label content of the snackbar.\n * @returns The label text content of the snackbar.\n */\n async getLabel(): Promise<string | null> {\n await this.enforcePartExistence('contentDisplay');\n const content = await this.parts.contentDisplay.getText();\n return content ?? null;\n }\n\n /**\n * Get a driver instance of a component in the action area of the snackbar.\n * @param locator\n * @param driverClass\n * @returns\n */\n async getActionComponent<ItemClass extends ComponentDriver>(\n locator: PartLocator,\n driverClass: ComponentDriverCtor<ItemClass>\n ): Promise<ItemClass | null> {\n await this.enforcePartExistence('actionArea');\n const componentLocator = locatorUtil.append(this.parts.actionArea.locator, locator);\n const exists = await this.interactor.exists(componentLocator);\n if (exists) {\n return new driverClass(componentLocator, this.interactor, this.commutableOption);\n }\n return null;\n }\n\n override get driverName(): string {\n return 'MuiV9SnackbarDriver';\n }\n}\n","import { byCssSelector, ComponentDriver, escapeUtil, locatorUtil, PartLocator } from '@atomic-testing/core';\n\n// The trigger FAB carries the open state via aria-expanded; the action buttons\n// carry their name via aria-label. Both are distinct MUI classes within the root.\nconst fabLocator = byCssSelector('.MuiSpeedDial-fab');\nconst actionLocator = byCssSelector('.MuiSpeedDialAction-fab');\n\n/**\n * Driver for the Material UI v9 SpeedDial component.\n *\n * SpeedDial renders a trigger FAB (`.MuiSpeedDial-fab`, `aria-expanded` reflects\n * open state) and a set of action FABs (`.MuiSpeedDialAction-fab`, each\n * aria-labelled with its name). The actions stay mounted but are only revealed\n * when open, so open state is read from the FAB's `aria-expanded` rather than\n * action presence.\n * @see https://mui.com/material-ui/react-speed-dial/\n */\nexport class SpeedDialDriver extends ComponentDriver {\n private get fab(): PartLocator {\n return locatorUtil.append(this.locator, fabLocator);\n }\n\n /**\n * Whether the speed dial is open (its FAB reports `aria-expanded=\"true\"`).\n */\n async isOpen(): Promise<boolean> {\n const expanded = await this.interactor.getAttribute(this.fab, 'aria-expanded');\n return expanded === 'true';\n }\n\n /**\n * Open the speed dial by hovering its FAB. No-op when already open.\n *\n * Hover (`onMouseEnter`) is the trigger that opens consistently across MUI\n * versions and browsers — clicking only focuses-then-opens in Chromium, and\n * focus opens in v7 but not v5, whereas hover opens everywhere.\n */\n async open(): Promise<void> {\n if (!(await this.isOpen())) {\n await this.interactor.hover(this.fab);\n }\n }\n\n /**\n * Close the speed dial by moving the pointer off its FAB. No-op when already closed.\n */\n async close(): Promise<void> {\n if (await this.isOpen()) {\n await this.interactor.mouseLeave(this.fab);\n }\n }\n\n /**\n * The labels of every action, in order (read from each action FAB's aria-label).\n */\n async getActionLabels(): Promise<string[]> {\n const labels = await this.interactor.getAttribute(\n locatorUtil.append(this.locator, actionLocator),\n 'aria-label',\n true\n );\n return labels.filter((label): label is string => label != null);\n }\n\n /**\n * Trigger the action with the given label, opening the dial first if needed.\n * @returns `false` when no action has that label.\n */\n async triggerActionByLabel(label: string): Promise<boolean> {\n await this.open();\n const actionByLabel = byCssSelector(`.MuiSpeedDialAction-fab[aria-label=\"${escapeUtil.escapeValue(label)}\"]`);\n const locator = locatorUtil.append(this.locator, actionByLabel);\n if (!(await this.interactor.exists(locator))) {\n return false;\n }\n await this.interactor.click(locator);\n return true;\n }\n\n override get driverName(): string {\n return 'MuiV9SpeedDialDriver';\n }\n}\n","import { byCssSelector, ComponentDriver, locatorUtil, Optional, PartLocator } from '@atomic-testing/core';\n\nexport interface StepInfo {\n /** The step's visible label. */\n label: Optional<string>;\n /** Whether this is the active step (MUI marks the label `Mui-active`). */\n active: boolean;\n /** Whether the step has been completed (`Mui-completed`). */\n completed: boolean;\n /** Whether the step is disabled (`Mui-disabled`). */\n disabled: boolean;\n}\n\n// The `.MuiStepLabel-label` span carries both the clean label text and the\n// per-step state class, making it the single source of truth for step state.\nconst stepLabelLocator = byCssSelector('.MuiStepLabel-label');\n\n/**\n * Locator for the label of the step at `index`. In Material UI v9 the connector\n * is rendered *inside* each `.MuiStep-root` (in v7 it was an interleaved sibling),\n * so the step elements are now consecutive siblings and the step at `index` is the\n * `index+1`-th element of its type; nth-of-type addresses it directly.\n */\nfunction stepLabelAt(index: number): PartLocator {\n return byCssSelector(`.MuiStep-root:nth-of-type(${index + 1}) .MuiStepLabel-label`);\n}\n\nfunction stepButtonAt(index: number): PartLocator {\n return byCssSelector(`.MuiStep-root:nth-of-type(${index + 1}) .MuiStepButton-root`);\n}\n\n/**\n * Driver for the Material UI v9 Stepper component.\n *\n * Each step's state lives on its `.MuiStepLabel-label` (`Mui-active`,\n * `Mui-completed`, `Mui-disabled`); reading every label's class in one pass gives\n * the step states and count in document order. Steps are addressed positionally\n * for label text and clicks via {@link stepLabelAt}/{@link stepButtonAt}.\n *\n * Supported layouts: the default horizontal stepper and the vertical orientation.\n * In v9 every `.MuiStep-root` is a consecutive sibling (the connector lives inside\n * the step), and every step renders a text label, so positional addressing lines up\n * with the document-order class list. The unsupported case is icon-only steps, which\n * render no `.MuiStepLabel-label`; under those the document-order class list has fewer\n * entries than steps and the two desynchronize. Robustly supporting that needs an\n * interactor primitive to address the n-th of non-sibling matches\n * (CSS `:nth-child(of S)` is unsupported in jsdom), which is out of this driver's scope.\n * @see https://mui.com/material-ui/react-stepper/\n */\nexport class StepperDriver extends ComponentDriver {\n private async getStepClassList(): Promise<readonly string[]> {\n return this.interactor.getAttribute(locatorUtil.append(this.locator, stepLabelLocator), 'class', true);\n }\n\n /**\n * The number of steps.\n */\n async getStepCount(): Promise<number> {\n return (await this.getStepClassList()).length;\n }\n\n /**\n * Zero-based index of the active step, or `-1` when none is active.\n */\n async getActiveStepIndex(): Promise<number> {\n const classes = await this.getStepClassList();\n return classes.findIndex(c => c.split(/\\s+/).includes('Mui-active'));\n }\n\n /**\n * Every step with its label and active/completed/disabled state, in order.\n */\n async getSteps(): Promise<StepInfo[]> {\n const classes = await this.getStepClassList();\n const steps: StepInfo[] = [];\n for (let index = 0; index < classes.length; index++) {\n const stateClasses = classes[index].split(/\\s+/);\n const label = await this.interactor.getText(locatorUtil.append(this.locator, stepLabelAt(index)));\n steps.push({\n label: label?.trim(),\n active: stateClasses.includes('Mui-active'),\n completed: stateClasses.includes('Mui-completed'),\n disabled: stateClasses.includes('Mui-disabled'),\n });\n }\n return steps;\n }\n\n /**\n * Navigate to the step at `index` by clicking its control (requires a clickable\n * `StepButton`, e.g. a non-linear stepper).\n * @returns `false` when the step is out of range, has no button, or is disabled.\n */\n async goToStep(index: number): Promise<boolean> {\n if (index < 0 || index >= (await this.getStepCount())) {\n return false;\n }\n const button = locatorUtil.append(this.locator, stepButtonAt(index));\n if (!(await this.interactor.exists(button)) || (await this.interactor.isDisabled(button))) {\n return false;\n }\n await this.interactor.click(button);\n return true;\n }\n\n override get driverName(): string {\n return 'MuiV9StepperDriver';\n }\n}\n","import { HTMLCheckboxDriver } from '@atomic-testing/component-driver-html';\nimport {\n byAttribute,\n ComponentDriver,\n IComponentDriverOption,\n IFormFieldDriver,\n Interactor,\n IToggleDriver,\n PartLocator,\n ScenePart,\n} from '@atomic-testing/core';\n\nexport const parts = {\n input: {\n locator: byAttribute('type', 'checkbox'),\n driver: HTMLCheckboxDriver,\n },\n} satisfies ScenePart;\n\nexport class SwitchDriver\n extends ComponentDriver<typeof parts>\n implements IFormFieldDriver<string | null>, IToggleDriver\n{\n constructor(locator: PartLocator, interactor: Interactor, option?: Partial<IComponentDriverOption>) {\n super(locator, interactor, {\n ...option,\n parts,\n });\n }\n\n override async exists(): Promise<boolean> {\n return this.interactor.exists(this.parts.input.locator);\n }\n\n async isSelected(): Promise<boolean> {\n await this.enforcePartExistence('input');\n return this.parts.input.isSelected();\n }\n async setSelected(selected: boolean): Promise<void> {\n await this.enforcePartExistence('input');\n await this.parts.input.setSelected(selected);\n }\n\n async getValue(): Promise<string | null> {\n await this.enforcePartExistence('input');\n return this.parts.input.getValue();\n }\n\n async isDisabled(): Promise<boolean> {\n await this.enforcePartExistence('input');\n return this.parts.input.isDisabled();\n }\n\n async isReadonly(): Promise<boolean> {\n // MUI v5 does not have a readonly state for the switch\n return Promise.resolve(false);\n }\n\n get driverName(): string {\n return 'MuiV9SwitchDriver';\n }\n}\n","import { ComponentDriver } from '@atomic-testing/core';\n\n/**\n * Driver for a single Material UI v9 TableCell (`<td>`/`<th>`, `.MuiTableCell-root`).\n *\n * A cell's content is plain text, so it relies on the inherited `getText()`/`exists()`;\n * it exists as a distinct type so {@link TableRowDriver} can expose typed cell drivers.\n * @see https://mui.com/material-ui/react-table/\n */\nexport class TableCellDriver extends ComponentDriver {\n get driverName(): string {\n return 'MuiV9TableCellDriver';\n }\n}\n","import {\n byCssSelector,\n IComponentDriverOption,\n Interactor,\n ListComponentDriver,\n ListComponentDriverSpecificOption,\n PartLocator,\n} from '@atomic-testing/core';\n\nimport { TableCellDriver } from './TableCellDriver';\n\n/**\n * Cells are located by `.MuiTableCell-root`, covering both `<td>` body cells and\n * `<th>` header cells.\n */\nexport const defaultTableRowDriverOption: ListComponentDriverSpecificOption<TableCellDriver> = {\n itemClass: TableCellDriver,\n itemLocator: byCssSelector('.MuiTableCell-root'),\n};\n\ntype TableRowDriverOption<ItemT extends TableCellDriver> = ListComponentDriverSpecificOption<ItemT> &\n Partial<IComponentDriverOption<any>>;\n\n/**\n * Driver for a single Material UI v9 TableRow (`.MuiTableRow-root`).\n *\n * A {@link ListComponentDriver} over the row's cells, exposing per-cell\n * {@link TableCellDriver}s (via `getItems`/`getItemByIndex`) plus convenience reads\n * of the cell texts.\n *\n * Cells are addressed positionally via `:nth-of-type`, which counts per element type.\n * This assumes a row's cells are homogeneous (all `<td>`, or all `<th>` for a header\n * row) — the common MUI rendering. A row mixing a leading `<th scope=\"row\">` with\n * `<td>` data cells would desynchronize the index (the `<td>`s start at type-index 1\n * after the `<th>`); such rows are out of scope.\n * @see https://mui.com/material-ui/react-table/\n */\nexport class TableRowDriver<ItemT extends TableCellDriver = TableCellDriver> extends ListComponentDriver<ItemT> {\n constructor(locator: PartLocator, interactor: Interactor, option: Partial<TableRowDriverOption<ItemT>> = {}) {\n // A row's item shape is fixed (cells driven by TableCellDriver). The defaults are\n // applied LAST so they win over any inherited `itemLocator`/`itemClass`: when a\n // TableDriver builds its row drivers it forwards its own commutable option, whose\n // (row-level) item locator would otherwise shadow the cell locator here.\n super(locator, interactor, {\n ...option,\n ...defaultTableRowDriverOption,\n } as TableRowDriverOption<ItemT>);\n }\n\n /**\n * The number of cells in the row.\n */\n async getCellCount(): Promise<number> {\n return this.getItemCount();\n }\n\n /**\n * The cell driver at the given zero-based column index, or `null` when out of range.\n */\n async getCell(index: number): Promise<ItemT | null> {\n return this.getItemByIndex(index);\n }\n\n /**\n * The text of every cell, in column order.\n */\n async getCellTexts(): Promise<string[]> {\n const cells = await this.getItems();\n const texts: string[] = [];\n for (const cell of cells) {\n texts.push((await cell.getText())?.trim() ?? '');\n }\n return texts;\n }\n\n override get driverName(): string {\n return 'MuiV9TableRowDriver';\n }\n}\n","import {\n byCssSelector,\n IComponentDriverOption,\n Interactor,\n ListComponentDriver,\n ListComponentDriverSpecificOption,\n locatorUtil,\n Optional,\n PartLocator,\n} from '@atomic-testing/core';\n\nimport { TableRowDriver } from './TableRowDriver';\n\n/** Reported sort state of a column, mirroring the `aria-sort` values MUI emits. */\nexport type TableSortDirection = 'ascending' | 'descending';\n\n// Body rows are the iterated items; the header row is addressed separately.\nconst headerRowLocator: PartLocator = byCssSelector('.MuiTableHead-root .MuiTableRow-root');\n\n/**\n * Body rows are located under `.MuiTableBody-root`, so header rows are never\n * mistaken for data rows.\n */\nexport const defaultTableDriverOption: ListComponentDriverSpecificOption<TableRowDriver> = {\n itemClass: TableRowDriver,\n itemLocator: byCssSelector('.MuiTableBody-root .MuiTableRow-root'),\n};\n\ntype TableDriverOption<ItemT extends TableRowDriver> = ListComponentDriverSpecificOption<ItemT> &\n Partial<IComponentDriverOption<any>>;\n\n// The nth header cell (1-based for nth-of-type); header cells are `<th>` siblings.\nfunction headerCellAt(columnIndex: number): PartLocator {\n return byCssSelector(`.MuiTableHead-root .MuiTableRow-root .MuiTableCell-root:nth-of-type(${columnIndex + 1})`);\n}\n\n/**\n * Driver for the Material UI v9 Table component.\n *\n * A {@link ListComponentDriver} over the data rows (`.MuiTableBody-root > .MuiTableRow-root`),\n * exposing per-row {@link TableRowDriver}s plus header reads and column sort state.\n * Locators key off MUI's structural classes (`MuiTableHead/Body/Row/Cell-root`),\n * which are stable across v9. Sort state is read from the header cell's `aria-sort`\n * and driven by clicking its `TableSortLabel`.\n * @see https://mui.com/material-ui/react-table/\n */\nexport class TableDriver<ItemT extends TableRowDriver = TableRowDriver> extends ListComponentDriver<ItemT> {\n constructor(locator: PartLocator, interactor: Interactor, option: Partial<TableDriverOption<ItemT>> = {}) {\n super(locator, interactor, {\n ...defaultTableDriverOption,\n ...option,\n } as TableDriverOption<ItemT>);\n }\n\n /**\n * The number of data (body) rows.\n */\n async getRowCount(): Promise<number> {\n return this.getItemCount();\n }\n\n /**\n * The data-row driver at the given zero-based index, or `null` when out of range.\n */\n async getRow(index: number): Promise<ItemT | null> {\n return this.getItemByIndex(index);\n }\n\n /**\n * The header row as a {@link TableRowDriver}, or `null` when the table has no header.\n */\n async getHeaderRow(): Promise<TableRowDriver | null> {\n const locator = locatorUtil.append(this.locator, headerRowLocator);\n if (!(await this.interactor.exists(locator))) {\n return null;\n }\n return new TableRowDriver(locator, this.interactor);\n }\n\n /**\n * The number of columns, derived from the header cell count (0 when no header).\n */\n async getColumnCount(): Promise<number> {\n const header = await this.getHeaderRow();\n return header == null ? 0 : header.getCellCount();\n }\n\n /**\n * The header cell texts, in column order (empty when no header).\n */\n async getHeaderTexts(): Promise<string[]> {\n const header = await this.getHeaderRow();\n return header == null ? [] : header.getCellTexts();\n }\n\n /**\n * The text of the data cell at the given row/column, or `undefined` when either\n * index is out of range.\n */\n async getCellText(rowIndex: number, columnIndex: number): Promise<Optional<string>> {\n const row = await this.getRow(rowIndex);\n if (row == null) {\n return undefined;\n }\n const cell = await row.getCell(columnIndex);\n if (cell == null) {\n return undefined;\n }\n return (await cell.getText())?.trim();\n }\n\n /**\n * The sort direction applied to the column at `columnIndex`, read from the header\n * cell's `aria-sort`, or `undefined` when that column is not the sorted one.\n */\n async getSortDirection(columnIndex: number): Promise<Optional<TableSortDirection>> {\n const cell = headerCellAt(columnIndex);\n const fullLocator = locatorUtil.append(this.locator, cell);\n if (!(await this.interactor.exists(fullLocator))) {\n return undefined;\n }\n const ariaSort = await this.interactor.getAttribute(fullLocator, 'aria-sort');\n return ariaSort === 'ascending' || ariaSort === 'descending' ? ariaSort : undefined;\n }\n\n /**\n * Toggle/apply sorting on the column at `columnIndex` by clicking its\n * `TableSortLabel`.\n * @returns `false` when the column has no sort control.\n */\n async sortByColumn(columnIndex: number): Promise<boolean> {\n const sortLabel = locatorUtil.append(\n this.locator,\n byCssSelector(\n `.MuiTableHead-root .MuiTableRow-root .MuiTableCell-root:nth-of-type(${columnIndex + 1}) .MuiTableSortLabel-root`\n )\n );\n if (!(await this.interactor.exists(sortLabel))) {\n return false;\n }\n await this.interactor.click(sortLabel);\n return true;\n }\n\n override get driverName(): string {\n return 'MuiV9TableDriver';\n }\n}\n","import { byAttribute, byCssSelector, ComponentDriver, locatorUtil, Optional, PartLocator } from '@atomic-testing/core';\n\nimport { SelectDriver } from './SelectDriver';\n\nconst previousButtonLocator = byAttribute('aria-label', 'Go to previous page');\nconst nextButtonLocator = byAttribute('aria-label', 'Go to next page');\nconst displayedRowsLocator = byCssSelector('.MuiTablePagination-displayedRows');\n\n/**\n * Driver for the Material UI v9 TablePagination component.\n *\n * TablePagination is a composite: a \"rows per page\" MUI Select (a portal-backed\n * `role=\"combobox\"`), an aria-labelled previous/next pair that disables at the\n * bounds, and a `.MuiTablePagination-displayedRows` label (\"1–5 of 13\"). The\n * rows-per-page control is delegated to {@link SelectDriver} rather than\n * reimplemented — the driver's own root contains exactly one combobox/input, so\n * SelectDriver scoped to that root resolves it unambiguously.\n * @see https://mui.com/material-ui/react-pagination/#table-pagination\n */\nexport class TablePaginationDriver extends ComponentDriver {\n // The driver root contains exactly one combobox/input, so a SelectDriver scoped\n // to it resolves the rows-per-page control unambiguously. Constructed on demand\n // (stateless) to avoid overriding the base constructor.\n private get rowsPerPageSelect(): SelectDriver {\n return new SelectDriver(this.locator, this.interactor);\n }\n\n /**\n * The current rows-per-page value (read from the select's hidden input), or\n * `-1` when it cannot be parsed.\n */\n async getRowsPerPage(): Promise<number> {\n const value = await this.rowsPerPageSelect.getValue();\n const parsed = Number.parseInt(value ?? '', 10);\n return Number.isNaN(parsed) ? -1 : parsed;\n }\n\n /**\n * Choose a rows-per-page value by opening the select and picking the option.\n * @returns `false` when no such option exists.\n */\n async setRowsPerPage(rowsPerPage: number): Promise<boolean> {\n return this.rowsPerPageSelect.setValue(String(rowsPerPage));\n }\n\n /**\n * The raw \"displayed rows\" label (e.g. \"1–5 of 13\"), or `undefined` when absent.\n * Returned verbatim because its exact format (separator, \"of\") is locale-defined.\n */\n async getDisplayedRowsText(): Promise<Optional<string>> {\n const locator = locatorUtil.append(this.locator, displayedRowsLocator);\n if (!(await this.interactor.exists(locator))) {\n return undefined;\n }\n return (await this.interactor.getText(locator))?.trim();\n }\n\n /** Whether the previous-page control is disabled (i.e. on the first page). */\n async isPreviousDisabled(): Promise<boolean> {\n return this.isNavDisabled(previousButtonLocator);\n }\n\n /** Whether the next-page control is disabled (i.e. on the last page). */\n async isNextDisabled(): Promise<boolean> {\n return this.isNavDisabled(nextButtonLocator);\n }\n\n /**\n * An absent control counts as disabled — both to stay consistent with\n * {@link clickNavButton} (which reports a no-op for a missing control) and\n * because Playwright's `isDisabled` throws on a zero-match locator rather than\n * returning false the way jsdom does.\n */\n private async isNavDisabled(navLocator: PartLocator): Promise<boolean> {\n const locator = locatorUtil.append(this.locator, navLocator);\n if (!(await this.interactor.exists(locator))) {\n return true;\n }\n return this.interactor.isDisabled(locator);\n }\n\n /**\n * Advance to the next page unless the control is disabled (last page).\n * @returns whether the click was performed.\n */\n async nextPage(): Promise<boolean> {\n return this.clickNavButton(nextButtonLocator);\n }\n\n /**\n * Go back to the previous page unless the control is disabled (first page).\n * @returns whether the click was performed.\n */\n async previousPage(): Promise<boolean> {\n return this.clickNavButton(previousButtonLocator);\n }\n\n private async clickNavButton(navLocator: PartLocator): Promise<boolean> {\n const locator = locatorUtil.append(this.locator, navLocator);\n if (!(await this.interactor.exists(locator)) || (await this.interactor.isDisabled(locator))) {\n return false;\n }\n await this.interactor.click(locator);\n return true;\n }\n\n override get driverName(): string {\n return 'MuiV9TablePaginationDriver';\n }\n}\n","import { HTMLButtonDriver } from '@atomic-testing/component-driver-html';\n\n/**\n * Driver for a single Material UI v9 Tab.\n *\n * A `<Tab>` renders as a `<button role=\"tab\">`; MUI marks the active one with\n * `aria-selected=\"true\"` and renders a real `disabled` button when disabled, so\n * selection and disabled state are read straight off the accessible attributes\n * (`isDisabled` is inherited from {@link HTMLButtonDriver}; `getText`/`click` from\n * the base `ComponentDriver`).\n *\n * Unlike a toggle button this is intentionally not an `IToggleDriver`: a tab can\n * be selected but not toggled off (selecting another tab deselects it), so only\n * `isSelected`/`select` are exposed.\n * @see https://mui.com/material-ui/react-tabs/\n */\nexport class TabDriver extends HTMLButtonDriver {\n /**\n * Whether this tab is the selected one, i.e. MUI set `aria-selected=\"true\"`.\n */\n async isSelected(): Promise<boolean> {\n const val = await this.interactor.getAttribute(this.locator, 'aria-selected');\n return val === 'true';\n }\n\n /**\n * Activate this tab by clicking it, unless it is already selected. A selected\n * tab cannot be toggled off, so this is a no-op when already active.\n */\n async select(): Promise<void> {\n if (!(await this.isSelected())) {\n await this.interactor.click(this.locator);\n }\n }\n\n override get driverName(): string {\n return 'MuiV9TabDriver';\n }\n}\n","import {\n byRole,\n IComponentDriverOption,\n Interactor,\n ListComponentDriver,\n ListComponentDriverSpecificOption,\n listHelper,\n Nullable,\n PartLocator,\n} from '@atomic-testing/core';\n\nimport { TabDriver } from './TabDriver';\n\n/**\n * Tabs are located by their accessible `role=\"tab\"` children rather than by MUI\n * class names, so the driver is resilient to MUI styling/version changes.\n */\nexport const defaultTabsDriverOption: ListComponentDriverSpecificOption<TabDriver> = {\n itemClass: TabDriver,\n itemLocator: byRole('tab'),\n};\n\ntype TabsDriverOption<ItemT extends TabDriver> = ListComponentDriverSpecificOption<ItemT> &\n Partial<IComponentDriverOption<any>>;\n\n/**\n * Driver for the Material UI v9 Tabs component.\n *\n * `<Tabs>` renders a `role=\"tablist\"` whose `role=\"tab\"` buttons carry the\n * selected (`aria-selected`) and disabled state. This driver is a\n * {@link ListComponentDriver} over those tabs, exposing both group-level helpers\n * (selected index/label, select by index/label) and per-tab {@link TabDriver}\n * instances via `getItems`/`getItemByIndex`/`getItemByLabel`.\n * @see https://mui.com/material-ui/react-tabs/\n */\nexport class TabsDriver<ItemT extends TabDriver = TabDriver> extends ListComponentDriver<ItemT> {\n constructor(locator: PartLocator, interactor: Interactor, option: Partial<TabsDriverOption<ItemT>> = {}) {\n // A tab group's item shape is fixed (role=\"tab\" buttons driven by TabDriver),\n // so the defaults are merged in rather than relying on a default parameter:\n // the test engine always passes an option object for a scene part, which would\n // otherwise shadow a default-valued parameter and leave itemLocator unset.\n super(locator, interactor, {\n ...defaultTabsDriverOption,\n ...option,\n } as TabsDriverOption<ItemT>);\n }\n\n /**\n * The visible label of every tab, in DOM order.\n */\n async getTabLabels(): Promise<string[]> {\n const labels: string[] = [];\n for await (const tab of listHelper.getListItemIterator(this, this.getItemLocator(), TabDriver)) {\n const text = await tab.getText();\n labels.push(text?.trim() ?? '');\n }\n return labels;\n }\n\n /**\n * The number of tabs in the group.\n */\n async getTabCount(): Promise<number> {\n return this.getItemCount();\n }\n\n /**\n * Zero-based index of the selected tab, or `-1` when no tab is selected\n * (e.g. `<Tabs value={false}>`).\n */\n async getSelectedIndex(): Promise<number> {\n let index = 0;\n for await (const tab of listHelper.getListItemIterator(this, this.getItemLocator(), TabDriver)) {\n if (await tab.isSelected()) {\n return index;\n }\n index++;\n }\n return -1;\n }\n\n /**\n * Label of the selected tab, or `null` when no tab is selected. Returns `null`\n * (not `undefined`) to match the sibling `SelectDriver.getSelectedLabel` contract.\n */\n async getSelectedLabel(): Promise<Nullable<string>> {\n for await (const tab of listHelper.getListItemIterator(this, this.getItemLocator(), TabDriver)) {\n if (await tab.isSelected()) {\n return (await tab.getText())?.trim() ?? null;\n }\n }\n return null;\n }\n\n /**\n * Select the tab at the given zero-based index.\n * @returns `false` when the index is out of range.\n */\n async selectByIndex(index: number): Promise<boolean> {\n const tab = await this.getItemByIndex(index);\n if (tab == null) {\n return false;\n }\n await tab.click();\n return true;\n }\n\n /**\n * Select the first tab whose visible label equals `label`.\n * @returns `false` when no tab matches.\n */\n async selectByLabel(label: string): Promise<boolean> {\n const tab = await this.getItemByLabel(label);\n if (tab == null) {\n return false;\n }\n await tab.click();\n return true;\n }\n\n /**\n * Whether the tab at the given index is disabled.\n * @returns `false` when the index is out of range.\n */\n async isTabDisabled(index: number): Promise<boolean> {\n const tab = await this.getItemByIndex(index);\n return tab == null ? false : tab.isDisabled();\n }\n\n override get driverName(): string {\n return 'MuiV9TabsDriver';\n }\n}\n","import { HTMLElementDriver, HTMLTextInputDriver } from '@atomic-testing/component-driver-html';\nimport {\n byCssSelector,\n byRole,\n byTagName,\n ComponentDriver,\n IComponentDriverOption,\n IInputDriver,\n Interactor,\n Optional,\n PartLocator,\n ScenePart,\n} from '@atomic-testing/core';\n\nimport { SelectDriver } from './SelectDriver';\n\nexport const parts = {\n label: {\n // In v9 the label is a direct child `.MuiInputLabel-root`: a `<label>` for the\n // text/multiline variants, but a `<div>` for the select variant (where the\n // control is a combobox associated via aria-labelledby, not a focusable input).\n // Matching the class instead of the `<label>` tag covers both.\n locator: byCssSelector('>.MuiInputLabel-root'),\n driver: HTMLElementDriver,\n },\n helperText: {\n locator: byCssSelector('>p'),\n driver: HTMLElementDriver,\n },\n singlelineInput: {\n locator: byCssSelector('input:not([aria-hidden])'),\n driver: HTMLTextInputDriver,\n },\n multilineInput: {\n locator: byCssSelector('textarea:not([aria-hidden])'),\n driver: HTMLTextInputDriver,\n },\n selectInput: {\n // Target the input wrapper specifically: in v9 the select variant's label is\n // also a direct child `<div>`, so a bare `>div` is ambiguous (it matches the\n // label first, breaking class reads like the readonly state). `.MuiInputBase-root`\n // pins it to the actual input root.\n locator: byCssSelector('>.MuiInputBase-root'),\n driver: SelectDriver,\n },\n // Used to detect the presence of select input\n richSelectInputDetect: {\n locator: byRole('combobox'),\n driver: HTMLElementDriver,\n },\n nativeSelectInputDetect: {\n locator: byTagName('SELECT'),\n driver: HTMLElementDriver,\n },\n} satisfies ScenePart;\n\ntype TextFieldInputType = 'singleLine' | 'multiline' | 'select';\n\n/**\n * A driver for the Material UI v9 TextField component with single line or multiline text input.\n */\nexport class TextFieldDriver extends ComponentDriver<typeof parts> implements IInputDriver<string | null> {\n constructor(locator: PartLocator, interactor: Interactor, option?: Partial<IComponentDriverOption>) {\n super(locator, interactor, {\n ...option,\n parts,\n });\n }\n\n private async getInputType(): Promise<TextFieldInputType> {\n const result = await Promise.all([\n this.parts.singlelineInput.exists(),\n this.parts.richSelectInputDetect.exists(),\n this.parts.nativeSelectInputDetect.exists(),\n this.parts.multilineInput.exists(),\n ]).then(([singlelineExists, richSelectExists, nativeSelectExists, multilineExists]) => {\n if (singlelineExists) {\n return 'singleLine';\n }\n if (richSelectExists || nativeSelectExists) {\n return 'select';\n }\n if (multilineExists) {\n return 'multiline';\n }\n\n throw new Error('Unable to determine input type in TextFieldInput');\n });\n\n return result;\n }\n\n async getValue(): Promise<string | null> {\n const inputType = await this.getInputType();\n switch (inputType) {\n case 'singleLine':\n return this.parts.singlelineInput.getValue();\n case 'select':\n return this.parts.selectInput.getValue();\n case 'multiline':\n return this.parts.multilineInput.getValue();\n }\n }\n\n async setValue(value: string | null): Promise<boolean> {\n const inputType = await this.getInputType();\n switch (inputType) {\n case 'singleLine':\n return this.parts.singlelineInput.setValue(value);\n case 'select':\n return this.parts.selectInput.setValue(value);\n case 'multiline':\n return this.parts.multilineInput.setValue(value);\n }\n }\n\n async getLabel(): Promise<Optional<string>> {\n return this.parts.label.getText();\n }\n\n async getHelperText(): Promise<Optional<string>> {\n const helperTextExists = await this.interactor.exists(this.parts.helperText.locator);\n if (helperTextExists) {\n return this.parts.helperText.getText();\n }\n }\n\n async isDisabled(): Promise<boolean> {\n const inputType = await this.getInputType();\n switch (inputType) {\n case 'singleLine':\n return this.parts.singlelineInput.isDisabled();\n case 'select':\n return this.parts.selectInput.isDisabled();\n case 'multiline':\n return this.parts.multilineInput.isDisabled();\n }\n }\n\n async isReadonly(): Promise<boolean> {\n const inputType = await this.getInputType();\n switch (inputType) {\n case 'singleLine':\n return this.parts.singlelineInput.isReadonly();\n case 'select':\n return this.interactor.hasCssClass(this.parts.selectInput.locator, 'MuiInputBase-readOnly');\n case 'multiline':\n return this.parts.multilineInput.isReadonly();\n }\n }\n\n get driverName(): string {\n return 'MuiV9TextFieldDriver';\n }\n}\n","import { IToggleDriver } from '@atomic-testing/core';\n\nimport { ButtonDriver } from './ButtonDriver';\n\nexport class ToggleButtonDriver extends ButtonDriver implements IToggleDriver {\n async isSelected(): Promise<boolean> {\n const val = await this.interactor.getAttribute(this.locator, 'aria-pressed');\n return val === 'true';\n }\n\n async setSelected(targetState: boolean): Promise<void> {\n const currentState = await this.isSelected();\n if (currentState !== targetState) {\n await this.interactor.click(this.locator);\n }\n }\n\n override get driverName() {\n return 'MuiV9ToggleButtonDriver';\n }\n}\n","import { byTagName, ComponentDriver, IInputDriver, listHelper, locatorUtil } from '@atomic-testing/core';\n\nimport { ToggleButtonDriver } from './ToggleButtonDriver';\n\nconst toggleButtonLocator = byTagName('button');\n\nexport class ToggleButtonGroupDriver extends ComponentDriver implements IInputDriver<readonly string[]> {\n protected itemLocator = locatorUtil.append(this.locator, toggleButtonLocator);\n /**\n * Get all the selected toggle buttons' values.\n * @returns\n */\n async getValue(): Promise<readonly string[]> {\n const result: string[] = [];\n for await (const itemDriver of listHelper.getListItemIterator(this, this.itemLocator, ToggleButtonDriver)) {\n const isSelected = await itemDriver.isSelected();\n if (isSelected) {\n const value = await itemDriver.getValue();\n if (value != null) {\n result.push(value);\n }\n }\n }\n return result;\n }\n\n /**\n * Toggle all the toggle buttons such that only those with value in the given array are selected.\n * @param value Always true\n * @returns\n */\n async setValue(value: readonly string[]): Promise<boolean> {\n const valueSet = new Set(value);\n for await (const itemDriver of listHelper.getListItemIterator(this, this.itemLocator, ToggleButtonDriver)) {\n const value = await itemDriver.getValue();\n await itemDriver.setSelected(valueSet.has(value!));\n }\n return true;\n }\n\n get driverName(): string {\n return 'MuiV9ToggleButtonGroupDriver';\n }\n}\n\n/**\n * A toggle button group driver that only allows a single selection.\n *\n * INTENTIONAL @ts-ignore comments below: This class intentionally narrows the return type\n * from `readonly string[]` to `string | null` for exclusive selection mode. TypeScript\n * correctly flags this as a type incompatibility because the subclass changes the interface\n * contract. However, this design is intentional as exclusive and multi-select toggle groups\n * have fundamentally different value semantics, and we want the type system to reflect\n * `string | null` for exclusive mode rather than forcing consumers to work with arrays.\n */\nexport class ExclusiveToggleButtonGroupDriver extends ToggleButtonGroupDriver implements IInputDriver<string | null> {\n // @ts-ignore - See class comment for explanation of intentional type narrowing\n async getValue(): Promise<string | null> {\n const values = await super.getValue();\n return values?.[0] ?? null;\n }\n\n // @ts-ignore - See class comment for explanation of intentional type narrowing\n async setValue(value: string | null): Promise<boolean> {\n if (value === null) {\n return super.setValue([]);\n } else {\n return super.setValue([value]);\n }\n }\n\n get driverName(): string {\n return 'MuiV9ExclusiveToggleButtonGroupDriver';\n }\n}\n","import { byRole, ComponentDriver, Optional, PartLocator } from '@atomic-testing/core';\n\n// MUI renders the tooltip into a portal outside this driver's subtree, so it is\n// addressed from the document root by its `role=\"tooltip\"`.\nconst tooltipLocator: PartLocator = byRole('tooltip', 'Root');\n\nconst defaultRevealTimeout = 250;\n\n/**\n * Driver for the Material UI v9 Tooltip component.\n *\n * The driver is rooted at the **trigger** element. MUI shows the tooltip on\n * hover/focus and renders it into a portal (a `role=\"tooltip\"` popper) outside the\n * trigger's subtree, so the text is read from the document root via\n * {@link tooltipLocator} after revealing it. The tooltip unmounts when not shown,\n * so presence of that element doubles as the visible state.\n *\n * Note: hover reveal depends on the tooltip's `enterDelay`; with a non-zero delay\n * the reveal is timer-bound. {@link getTitle} waits for the tooltip to appear.\n * @see https://mui.com/material-ui/react-tooltip/\n */\nexport class TooltipDriver extends ComponentDriver {\n /**\n * Reveal the tooltip by hovering its trigger, waiting until it is shown (or the\n * timeout elapses, e.g. when the trigger has no tooltip).\n */\n async show(timeoutMs: number = defaultRevealTimeout): Promise<void> {\n await this.interactor.hover(this.locator);\n await this.interactor.waitUntil({\n probeFn: () => this.isVisible(),\n terminateCondition: true,\n timeoutMs,\n });\n }\n\n /**\n * Hide the tooltip by moving the pointer off its trigger, waiting until it is gone.\n */\n async hide(timeoutMs: number = defaultRevealTimeout): Promise<void> {\n await this.interactor.mouseLeave(this.locator);\n await this.interactor.waitUntil({\n probeFn: () => this.isVisible(),\n terminateCondition: false,\n timeoutMs,\n });\n }\n\n /**\n * Whether a tooltip is currently shown.\n */\n async isVisible(): Promise<boolean> {\n if (!(await this.interactor.exists(tooltipLocator))) {\n return false;\n }\n return this.interactor.isVisible(tooltipLocator);\n }\n\n /**\n * Reveal the tooltip, read its text, then restore the un-hovered state. Returns\n * `undefined` when the trigger has no tooltip (none appears within the timeout).\n *\n * The hover is undone before returning so a subsequent read on a *different*\n * trigger isn't shadowed by this still-open tooltip: MUI renders all tooltips into\n * one portal and provides no per-trigger DOM link, and jsdom's synthetic hover does\n * not fire `mouseout` on the previously-hovered sibling.\n *\n * @param timeoutMs How long to wait for the tooltip to appear after hovering.\n */\n async getTitle(timeoutMs: number = defaultRevealTimeout): Promise<Optional<string>> {\n await this.show(timeoutMs);\n if (!(await this.interactor.exists(tooltipLocator))) {\n return undefined;\n }\n const text = (await this.interactor.getText(tooltipLocator))?.trim();\n await this.hide(timeoutMs);\n return text;\n }\n\n override get driverName(): string {\n return 'MuiV9TooltipDriver';\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["parts","HTMLElementDriver","ComponentDriver","timingUtil","parts","HTMLElementDriver","ContainerDriver","ComponentDriver","locatorUtil","ListComponentDriver","listHelper","parts","HTMLTextInputDriver","HTMLElementDriver","optionLocator","ComponentDriver","locatorUtil","listHelper","HTMLButtonDriver","parts","HTMLElementDriver","ComponentDriver","HTMLButtonDriver","ListComponentDriver","listHelper","HTMLButtonDriver","HTMLCheckboxDriver","ComponentDriver","locatorUtil","parts","HTMLElementDriver","ComponentDriver","parts","HTMLElementDriver","defaultTransitionDuration","ContainerDriver","ContainerDriver","locatorUtil","HTMLElementDriver","parts","HTMLTextInputDriver","ComponentDriver","ErrorBase","ComponentDriver","ListComponentDriver","listHelper","ItemNotFoundError","parts","HTMLElementDriver","ComponentDriver","listHelper","previousButtonLocator","nextButtonLocator","ComponentDriver","locatorUtil","parts","HTMLRadioButtonGroupDriver","ComponentDriver","locatorUtil","ComponentDriver","locatorUtil","ListComponentDriver","locatorUtil","escapeUtil","parts","HTMLRadioButtonGroupDriver","ComponentDriver","locatorUtil","HTMLButtonDriver","HTMLElementDriver","HTMLTextInputDriver","HTMLSelectDriver","ComponentDriver","locatorUtil","listHelper","parts","HTMLTextInputDriver","ComponentDriver","locatorUtil","parts","HTMLElementDriver","ComponentDriver","locatorUtil","ComponentDriver","locatorUtil","escapeUtil","ComponentDriver","locatorUtil","parts","HTMLCheckboxDriver","ComponentDriver","ComponentDriver","ListComponentDriver","ListComponentDriver","locatorUtil","ComponentDriver","locatorUtil","HTMLButtonDriver","ListComponentDriver","listHelper","HTMLElementDriver","HTMLTextInputDriver","ComponentDriver","ComponentDriver","locatorUtil","listHelper","ComponentDriver"],"sources":["../src/components/AccordionDriver.ts","../src/components/AlertDriver.ts","../src/components/AvatarDriver.ts","../src/components/AvatarGroupDriver.ts","../src/components/AutoCompleteDriver.ts","../src/components/BadgeDriver.ts","../src/components/BottomNavigationActionDriver.ts","../src/components/BottomNavigationDriver.ts","../src/components/ButtonDriver.ts","../src/components/CheckboxDriver.ts","../src/components/ChipDriver.ts","../src/components/DialogDriver.ts","../src/components/OverlayDriver.ts","../src/components/DrawerDriver.ts","../src/components/FabDriver.ts","../src/components/InputDriver.ts","../src/errors/MenuItemDisabledError.ts","../src/components/ListItemDriver.ts","../src/components/ListDriver.ts","../src/errors/MenuItemNotFoundError.ts","../src/components/MenuItemDriver.ts","../src/components/MenuDriver.ts","../src/components/PaginationDriver.ts","../src/components/ProgressDriver.ts","../src/components/RadioDriver.ts","../src/components/RadioGroupDriver.ts","../src/components/RatingDriver.ts","../src/components/SelectDriver.ts","../src/components/SliderDriver.ts","../src/components/SnackbarDriver.ts","../src/components/SpeedDialDriver.ts","../src/components/StepperDriver.ts","../src/components/SwitchDriver.ts","../src/components/TableCellDriver.ts","../src/components/TableRowDriver.ts","../src/components/TableDriver.ts","../src/components/TablePaginationDriver.ts","../src/components/TabDriver.ts","../src/components/TabsDriver.ts","../src/components/TextFieldDriver.ts","../src/components/ToggleButtonDriver.ts","../src/components/ToggleButtonGroupDriver.ts","../src/components/TooltipDriver.ts"],"sourcesContent":["import { HTMLElementDriver } from '@atomic-testing/component-driver-html';\nimport {\n byCssClass,\n byRole,\n ComponentDriver,\n IComponentDriverOption,\n Interactor,\n PartLocator,\n ScenePart,\n timingUtil,\n} from '@atomic-testing/core';\n\nexport const parts = {\n /**\n * The clickable area to expand/collapse the accordion.\n */\n disclosure: {\n locator: byCssClass('MuiAccordionSummary-root'),\n driver: HTMLElementDriver,\n },\n summary: {\n locator: byCssClass('MuiAccordionSummary-content'),\n driver: HTMLElementDriver,\n },\n content: {\n locator: byRole('region'),\n driver: HTMLElementDriver,\n },\n} satisfies ScenePart;\n\n/**\n * Driver for Material UI v9 Accordion component.\n * @see https://mui.com/material-ui/react-accordion/\n */\nexport class AccordionDriver extends ComponentDriver<typeof parts> {\n constructor(locator: PartLocator, interactor: Interactor, option?: Partial<IComponentDriverOption>) {\n super(locator, interactor, {\n ...option,\n parts: parts,\n });\n }\n\n /**\n * Get the title/summary of the accordion.\n * @returns The title/summary of the accordion.\n */\n async getSummary(): Promise<string | null> {\n const title = await this.parts.summary.getText();\n return title ?? null;\n }\n\n /**\n * Whether the accordion is expanded.\n * @returns True if the accordion is expanded, false if collapsed.\n */\n async isExpanded(): Promise<boolean> {\n await this.enforcePartExistence('disclosure');\n const expanded = await this.parts.disclosure.getAttribute('aria-expanded');\n return expanded === 'true';\n }\n\n /**\n * Whether the accordion is disabled.\n * @returns True if the accordion is disabled, false if enabled.\n */\n async isDisabled(): Promise<boolean> {\n await this.enforcePartExistence('disclosure');\n const disabled = await this.parts.disclosure.getAttribute('disabled');\n return disabled != null;\n }\n\n override async click(): Promise<void> {\n await this.parts.disclosure.click();\n }\n\n /**\n * Expand the accordion.\n */\n async expand(): Promise<void> {\n const expanded = await this.isExpanded();\n if (!expanded) {\n await this.parts.disclosure.click();\n await timingUtil.waitUntil({\n probeFn: () => this.isExpanded(),\n terminateCondition: true,\n timeoutMs: 1000,\n });\n }\n }\n\n /**\n * Collapse the accordion.\n */\n async collapse(): Promise<void> {\n const expanded = await this.isExpanded();\n if (expanded) {\n await this.parts.disclosure.click();\n await timingUtil.waitUntil({\n probeFn: () => this.isExpanded(),\n terminateCondition: false,\n timeoutMs: 1000,\n });\n }\n }\n\n override get driverName(): string {\n return 'MuiV9AccordionDriver';\n }\n}\n","import { HTMLElementDriver } from '@atomic-testing/component-driver-html';\nimport {\n byCssClass,\n ContainerDriver,\n IContainerDriverOption,\n Interactor,\n PartLocator,\n ScenePart,\n} from '@atomic-testing/core';\n\nexport const parts = {\n title: {\n locator: byCssClass('MuiAlertTitle-root'),\n driver: HTMLElementDriver,\n },\n message: {\n locator: byCssClass('MuiAlert-message'),\n driver: HTMLElementDriver,\n },\n} satisfies ScenePart;\n\ninterface AlertSeverityEvaluator {\n value: string;\n pattern: RegExp;\n}\nconst alertSeverityEvaluators: AlertSeverityEvaluator[] = [\n { value: 'error', pattern: /MuiAlert-.*Error/ },\n { value: 'warning', pattern: /MuiAlert-.*Warning/ },\n { value: 'info', pattern: /MuiAlert-.*Info/ },\n { value: 'success', pattern: /MuiAlert-.*Success/ },\n];\n\n/**\n * Driver for Material UI v9 Alert component.\n * @see https://mui.com/material-ui/react-alert/\n */\nexport class AlertDriver<ContentT extends ScenePart = {}> extends ContainerDriver<ContentT, typeof parts> {\n constructor(locator: PartLocator, interactor: Interactor, option?: Partial<IContainerDriverOption>) {\n super(locator, interactor, {\n ...option,\n parts: parts,\n content: (option?.content ?? {}) as ContentT,\n });\n }\n\n async getTitle(): Promise<string | null> {\n const title = await this.parts.title.getText();\n return title ?? null;\n }\n\n async getMessage(): Promise<string | null> {\n const message = await this.parts.message.getText();\n return message ?? null;\n }\n\n async getSeverity(): Promise<string | null> {\n const cssClassString = await this.interactor.getAttribute(this.locator, 'class');\n if (cssClassString != null) {\n const cssClasses = cssClassString.split(/\\s+/);\n for (const cssClassName of cssClasses) {\n for (const evaluator of alertSeverityEvaluators) {\n if (evaluator.pattern.test(cssClassName)) {\n return evaluator.value;\n }\n }\n }\n }\n return null;\n }\n\n override get driverName(): string {\n return 'MuiV9AlertDriver';\n }\n}\n","import { byCssSelector, ComponentDriver, locatorUtil, Optional, PartLocator } from '@atomic-testing/core';\n\nconst imageLocator = byCssSelector('img.MuiAvatar-img');\n\n/**\n * Driver for the Material UI v9 Avatar component.\n *\n * An Avatar renders a `.MuiAvatar-root`; with a `src` it contains an\n * `img.MuiAvatar-img`, otherwise it shows letter initials (or an icon). The\n * driver reads the image's `alt`, the presence of the image, and the letter\n * initials accordingly.\n * @see https://mui.com/material-ui/react-avatar/\n */\nexport class AvatarDriver extends ComponentDriver {\n private get imageLocator(): PartLocator {\n return locatorUtil.append(this.locator, imageLocator);\n }\n\n /**\n * Whether the avatar renders an image (vs letter/icon fallback).\n */\n async hasImage(): Promise<boolean> {\n return this.interactor.exists(this.imageLocator);\n }\n\n /**\n * The image's alt text, or `undefined` when the avatar has no image.\n */\n async getAltText(): Promise<Optional<string>> {\n if (!(await this.hasImage())) {\n return undefined;\n }\n return (await this.interactor.getAttribute(this.imageLocator, 'alt')) ?? undefined;\n }\n\n /**\n * The letter initials of a text avatar, or `undefined` for an image or icon\n * avatar (which render no text).\n */\n async getInitials(): Promise<Optional<string>> {\n if (await this.hasImage()) {\n return undefined;\n }\n const text = (await this.getText())?.trim();\n return text ? text : undefined;\n }\n\n override get driverName(): string {\n return 'MuiV9AvatarDriver';\n }\n}\n","import {\n byCssSelector,\n IComponentDriverOption,\n Interactor,\n ListComponentDriver,\n ListComponentDriverSpecificOption,\n listHelper,\n Optional,\n PartLocator,\n} from '@atomic-testing/core';\n\nimport { AvatarDriver } from './AvatarDriver';\n\n// Every avatar inside the group (including the surplus \"+N\" avatar) carries the\n// MuiAvatarGroup-avatar class and is a direct-child sibling, so they enumerate\n// positionally.\nconst avatarItemLocator = byCssSelector('.MuiAvatarGroup-avatar');\n\n// The surplus avatar's only distinguishing feature is its \"+N\" text.\nconst surplusPattern = /^\\+\\d+$/;\n\nexport const defaultAvatarGroupDriverOption: ListComponentDriverSpecificOption<AvatarDriver> = {\n itemClass: AvatarDriver,\n itemLocator: avatarItemLocator,\n};\n\ntype AvatarGroupDriverOption<ItemT extends AvatarDriver> = ListComponentDriverSpecificOption<ItemT> &\n Partial<IComponentDriverOption<any>>;\n\n/**\n * Driver for the Material UI v9 AvatarGroup component.\n *\n * AvatarGroup renders up to `max` avatars plus a surplus \"+N\" avatar when there\n * are more. This is a {@link ListComponentDriver} over the rendered avatars\n * (surplus included via `getItems`), with helpers to count the real avatars and\n * read the surplus label.\n * @see https://mui.com/material-ui/react-avatar/#grouped\n */\nexport class AvatarGroupDriver<ItemT extends AvatarDriver = AvatarDriver> extends ListComponentDriver<ItemT> {\n constructor(locator: PartLocator, interactor: Interactor, option: Partial<AvatarGroupDriverOption<ItemT>> = {}) {\n // Merge defaults so the driver works as a bare scene part (see TabsDriver).\n super(locator, interactor, {\n ...defaultAvatarGroupDriverOption,\n ...option,\n } as AvatarGroupDriverOption<ItemT>);\n }\n\n /**\n * The number of real avatars shown, excluding the surplus \"+N\" indicator.\n */\n async getVisibleCount(): Promise<number> {\n let count = 0;\n for await (const item of listHelper.getListItemIterator(this, this.getItemLocator(), AvatarDriver)) {\n const text = (await item.getText())?.trim();\n if (text == null || !surplusPattern.test(text)) {\n count++;\n }\n }\n return count;\n }\n\n /**\n * The surplus indicator's label (e.g. \"+3\"), or `undefined` when every avatar\n * fits within `max` and no surplus is shown.\n */\n async getSurplusLabel(): Promise<Optional<string>> {\n for await (const item of listHelper.getListItemIterator(this, this.getItemLocator(), AvatarDriver)) {\n const text = (await item.getText())?.trim();\n if (text != null && surplusPattern.test(text)) {\n return text;\n }\n }\n return undefined;\n }\n\n override get driverName(): string {\n return 'MuiV9AvatarGroupDriver';\n }\n}\n","import { HTMLButtonDriver, HTMLElementDriver, HTMLTextInputDriver } from '@atomic-testing/component-driver-html';\nimport {\n byCssClass,\n byLinkedElement,\n byRole,\n ComponentDriver,\n IComponentDriverOption,\n IInputDriver,\n Interactor,\n listHelper,\n locatorUtil,\n PartLocator,\n ScenePart,\n} from '@atomic-testing/core';\n\nexport const parts = {\n input: {\n locator: byRole('combobox'),\n driver: HTMLTextInputDriver,\n },\n dropdown: {\n locator: byLinkedElement('Root')\n .onLinkedElement(byRole('combobox'))\n .extractAttribute('aria-controls')\n .toMatchMyAttribute('id'),\n driver: HTMLElementDriver,\n },\n} satisfies ScenePart;\n\nconst optionLocator = byRole('option');\n\n// In the \"no options\" and \"loading\" states MUI renders no listbox, so the popup\n// cannot be reached through the `dropdown` part (which keys off the combobox's\n// `aria-controls`). These nodes live in the popper (portaled outside the driver\n// subtree), so they are matched by their global class. Only one Autocomplete\n// popup is open at a time, so a global match is unambiguous in practice.\nconst noOptionsLocator = byCssClass('MuiAutocomplete-noOptions');\nconst loadingLocator = byCssClass('MuiAutocomplete-loading');\n\n/**\n * The match type of the autocomplete, default to 'exact'\n * 'exact': The value must match exactly to one of the options\n * 'first-available': The value will be set to the first available option\n */\nexport type AutoCompleteMatchType = 'exact' | 'first-available';\n\nexport interface AutoCompleteDriverSpecificOption {\n matchType: AutoCompleteMatchType;\n}\n\nexport interface AutoCompleteDriverOption extends IComponentDriverOption, AutoCompleteDriverSpecificOption {}\n\nexport const defaultAutoCompleteDriverOption: AutoCompleteDriverSpecificOption = {\n matchType: 'exact',\n};\n\nexport class AutoCompleteDriver extends ComponentDriver<typeof parts> implements IInputDriver<string | null> {\n private _option: Partial<AutoCompleteDriverOption> = {};\n constructor(locator: PartLocator, interactor: Interactor, option?: Partial<AutoCompleteDriverOption>) {\n super(locator, interactor, {\n ...option,\n parts,\n });\n\n this._option = option ?? {};\n }\n\n /**\n * Get the display of the autocomplete\n */\n async getValue(): Promise<string | null> {\n const value = await this.parts.input.getValue();\n return value ?? null;\n }\n\n /**\n * Set the value of the autocomplete, how selection happens\n * depends on the option assigned to AutoCompleteDriver\n * By default, when the option has matchType set to exact, only option with matching text would be selected\n * When the option has matchType set to first-available, the first option would be selected regardless of the text\n *\n * Option of auto complete can be set at the time of part definition, for example\n * ```\n * {\n * myAutoComplete: {\n * locator: byCssSelector('my-auto-complete'),\n * driver: AutoCompleteDriver,\n * option: {\n * matchType: 'first-available',\n * },\n * },\n * }\n * ```\n *\n * @param value\n * @returns\n */\n async setValue(value: string | null): Promise<boolean> {\n await this.parts.input.setValue(value ?? '');\n\n if (value === null) {\n return true;\n }\n\n const option = locatorUtil.append(this.parts.dropdown.locator, optionLocator);\n let index = 0;\n const matchType: AutoCompleteMatchType = this._option?.matchType ?? defaultAutoCompleteDriverOption.matchType;\n for await (const optionDriver of listHelper.getListItemIterator(this, option, HTMLButtonDriver)) {\n const optionValue = await optionDriver.getText();\n const isMatched =\n (matchType === 'exact' && optionValue?.trim() === value) || (matchType === 'first-available' && index === 0);\n if (isMatched) {\n await optionDriver.click();\n return true;\n }\n\n index++;\n }\n\n return false;\n }\n\n async isDisabled(): Promise<boolean> {\n return this.parts.input.isDisabled();\n }\n\n async isReadonly(): Promise<boolean> {\n return this.parts.input.isReadonly();\n }\n\n /**\n * Whether the popup is currently showing its loading indicator (the\n * `loadingText`). Only meaningful while the popup is open — open it first\n * (e.g. by typing into the input), since MUI renders nothing otherwise.\n */\n async isLoading(): Promise<boolean> {\n return this.interactor.exists(loadingLocator);\n }\n\n /**\n * Whether the popup is currently showing its \"no options\" message. Same\n * open-the-popup-first caveat as {@link AutoCompleteDriver.isLoading}.\n */\n async hasNoOptions(): Promise<boolean> {\n return this.interactor.exists(noOptionsLocator);\n }\n\n get driverName(): string {\n return 'MuiV9AutoCompleteDriver';\n }\n}\n","import { HTMLElementDriver } from '@atomic-testing/component-driver-html';\nimport {\n byCssClass,\n ComponentDriver,\n IComponentDriverOption,\n Interactor,\n PartLocator,\n ScenePart,\n} from '@atomic-testing/core';\n\nexport const parts = {\n contentDisplay: {\n locator: byCssClass('MuiBadge-badge'),\n driver: HTMLElementDriver,\n },\n} satisfies ScenePart;\n\n/**\n * Driver for Material UI v9 Badge component.\n * @see https://mui.com/material-ui/react-badge/\n */\nexport class BadgeDriver extends ComponentDriver<typeof parts> {\n constructor(locator: PartLocator, interactor: Interactor, option?: Partial<IComponentDriverOption>) {\n super(locator, interactor, {\n ...option,\n parts: parts,\n });\n }\n\n /**\n * Get the content of the badge.\n * @returns The content of the badge.\n */\n async getContent(): Promise<string | null> {\n await this.enforcePartExistence('contentDisplay');\n const content = await this.parts.contentDisplay.getText();\n return content ?? null;\n }\n\n override get driverName(): string {\n return 'MuiV9BadgeDriver';\n }\n}\n","import { HTMLButtonDriver } from '@atomic-testing/component-driver-html';\n\n/**\n * Driver for a single Material UI v9 BottomNavigationAction.\n *\n * Each action renders as a `<button>` (no explicit ARIA role); MUI marks the\n * active one with the `Mui-selected` state class, so selection is read from the\n * class while `getText`/`click`/`isDisabled` come from {@link HTMLButtonDriver}\n * and the base `ComponentDriver`.\n * @see https://mui.com/material-ui/react-bottom-navigation/\n */\nexport class BottomNavigationActionDriver extends HTMLButtonDriver {\n /**\n * Whether this action is selected (MUI applies the `Mui-selected` state class).\n */\n async isSelected(): Promise<boolean> {\n return this.interactor.hasCssClass(this.locator, 'Mui-selected');\n }\n\n override get driverName(): string {\n return 'MuiV9BottomNavigationActionDriver';\n }\n}\n","import {\n byCssSelector,\n IComponentDriverOption,\n Interactor,\n ListComponentDriver,\n ListComponentDriverSpecificOption,\n listHelper,\n Nullable,\n Optional,\n PartLocator,\n} from '@atomic-testing/core';\n\nimport { BottomNavigationActionDriver } from './BottomNavigationActionDriver';\n\nexport interface BottomNavigationActionInfo {\n /** The action's visible label. */\n label: Optional<string>;\n /** Whether the action is currently selected. */\n selected: boolean;\n}\n\n/**\n * BottomNavigation actions are direct-child `<button>` siblings of the root (no\n * ARIA role). They are located by their `MuiBottomNavigationAction-root` class\n * rather than a bare `button` tag, so positional enumeration is not thrown off by\n * any incidental nested button inside an action.\n */\nexport const defaultBottomNavigationDriverOption: ListComponentDriverSpecificOption<BottomNavigationActionDriver> = {\n itemClass: BottomNavigationActionDriver,\n itemLocator: byCssSelector('.MuiBottomNavigationAction-root'),\n};\n\ntype BottomNavigationDriverOption<ItemT extends BottomNavigationActionDriver> =\n ListComponentDriverSpecificOption<ItemT> & Partial<IComponentDriverOption<any>>;\n\n/**\n * Driver for the Material UI v9 BottomNavigation component.\n *\n * A {@link ListComponentDriver} over the action buttons, exposing the selected\n * index/label, selection by index/label, and per-action info, plus per-action\n * {@link BottomNavigationActionDriver} instances via `getItems`/`getItemByIndex`/\n * `getItemByLabel`.\n * @see https://mui.com/material-ui/react-bottom-navigation/\n */\nexport class BottomNavigationDriver<\n ItemT extends BottomNavigationActionDriver = BottomNavigationActionDriver,\n> extends ListComponentDriver<ItemT> {\n constructor(locator: PartLocator, interactor: Interactor, option: Partial<BottomNavigationDriverOption<ItemT>> = {}) {\n // Merge defaults so the driver works as a bare scene part (see TabsDriver).\n super(locator, interactor, {\n ...defaultBottomNavigationDriverOption,\n ...option,\n } as BottomNavigationDriverOption<ItemT>);\n }\n\n /**\n * Every action with its label and selected state, in order.\n */\n async getActions(): Promise<BottomNavigationActionInfo[]> {\n const actions: BottomNavigationActionInfo[] = [];\n for await (const item of listHelper.getListItemIterator(\n this,\n this.getItemLocator(),\n BottomNavigationActionDriver\n )) {\n actions.push({\n label: (await item.getText())?.trim(),\n selected: await item.isSelected(),\n });\n }\n return actions;\n }\n\n /**\n * Zero-based index of the selected action, or `-1` when none is selected.\n */\n async getSelectedIndex(): Promise<number> {\n let index = 0;\n for await (const item of listHelper.getListItemIterator(\n this,\n this.getItemLocator(),\n BottomNavigationActionDriver\n )) {\n if (await item.isSelected()) {\n return index;\n }\n index++;\n }\n return -1;\n }\n\n /**\n * Label of the selected action, or `null` when none is selected. Returns `null`\n * (not `undefined`) to match the sibling `TabsDriver.getSelectedLabel` contract.\n */\n async getSelectedLabel(): Promise<Nullable<string>> {\n for await (const item of listHelper.getListItemIterator(\n this,\n this.getItemLocator(),\n BottomNavigationActionDriver\n )) {\n if (await item.isSelected()) {\n return (await item.getText())?.trim() ?? null;\n }\n }\n return null;\n }\n\n /**\n * Select the action at the given zero-based index.\n * @returns `false` when the index is out of range.\n */\n async selectByIndex(index: number): Promise<boolean> {\n const item = await this.getItemByIndex(index);\n if (item == null) {\n return false;\n }\n await item.click();\n return true;\n }\n\n /**\n * Select the first action whose visible label equals `label`.\n * @returns `false` when no action matches.\n */\n async selectByLabel(label: string): Promise<boolean> {\n const item = await this.getItemByLabel(label);\n if (item == null) {\n return false;\n }\n await item.click();\n return true;\n }\n\n override get driverName(): string {\n return 'MuiV9BottomNavigationDriver';\n }\n}\n","import { HTMLButtonDriver } from '@atomic-testing/component-driver-html';\n\n/**\n * Driver for Material UI v9 Button component.\n * @see https://mui.com/material-ui/react-button/\n */\nexport class ButtonDriver extends HTMLButtonDriver {\n async getValue(): Promise<string | null> {\n const val = await this.interactor.getAttribute(this.locator, 'value');\n return val ?? null;\n }\n\n override get driverName(): string {\n return 'MuiV9ButtonDriver';\n }\n}\n","import { HTMLCheckboxDriver } from '@atomic-testing/component-driver-html';\nimport {\n byCssSelector,\n byTagName,\n ComponentDriver,\n IComponentDriverOption,\n IFormFieldDriver,\n Interactor,\n IToggleDriver,\n locatorUtil,\n Optional,\n PartLocator,\n ScenePart,\n ScenePartDriver,\n} from '@atomic-testing/core';\n\nexport const checkboxPart = {\n checkbox: {\n locator: byTagName('input'),\n driver: HTMLCheckboxDriver,\n },\n} satisfies ScenePart;\n\nexport type CheckboxScenePart = typeof checkboxPart;\nexport type CheckboxScenePartDriver = ScenePartDriver<CheckboxScenePart>;\n\nexport class CheckboxDriver\n extends ComponentDriver<CheckboxScenePart>\n implements IFormFieldDriver<string | null>, IToggleDriver\n{\n constructor(locator: PartLocator, interactor: Interactor, option?: Partial<IComponentDriverOption>) {\n super(locator, interactor, {\n ...option,\n parts: checkboxPart,\n });\n }\n isSelected(): Promise<boolean> {\n return this.parts.checkbox.isSelected();\n }\n async setSelected(selected: boolean): Promise<void> {\n const isIndeterminate = await this.isIndeterminate();\n if (isIndeterminate && selected === false) {\n // if the checkbox is indeterminate and we want to set it to false, we need to click it twice\n // this is done through setting it to true first, then to false\n await this.parts.checkbox.setSelected(true);\n }\n\n await this.parts.checkbox.setSelected(selected);\n }\n\n getValue(): Promise<string | null> {\n return this.parts.checkbox.getValue();\n }\n\n async isIndeterminate(): Promise<boolean> {\n const indeterminate = await this.interactor.getAttribute(this.parts.checkbox.locator, 'data-indeterminate');\n return indeterminate === 'true';\n }\n\n isDisabled(): Promise<boolean> {\n return this.parts.checkbox.isDisabled();\n }\n\n isReadonly(): Promise<boolean> {\n return this.parts.checkbox.isReadonly();\n }\n\n /**\n * Get the text of the label associated with the checkbox, or `undefined` when the checkbox\n * is rendered without one (e.g. a bare `<Checkbox>` outside of a `FormControlLabel`).\n *\n * MUI's `FormControlLabel` does not expose a `for`/`id` or `aria-labelledby` association; it\n * labels the control implicitly by wrapping it in a `<label>` and rendering the text as a\n * sibling. The label therefore lives outside this driver's own subtree, so we re-root at the\n * enclosing `<label>` — matched against this checkbox via `:has()`, while preserving the\n * surrounding scope — and read its text. This resolves to a single CSS selector, so it behaves\n * identically across every interactor (DOM/React/Vue and Playwright).\n */\n async getLabel(): Promise<Optional<string>> {\n const labelLocator = this.getEnclosingLabelLocator();\n const hasLabel = await this.interactor.exists(labelLocator);\n return hasLabel ? this.interactor.getText(labelLocator) : undefined;\n }\n\n /**\n * Build a locator for the `<label>` that encloses this checkbox, scoped to the same ancestor\n * context as the checkbox itself so that sibling checkboxes are never mismatched.\n */\n private getEnclosingLabelLocator(): PartLocator {\n const chain = locatorUtil.toChain(this.locator);\n const selfSelector = chain[chain.length - 1].selector;\n return locatorUtil.append(chain.slice(0, -1), byCssSelector(`label:has(${selfSelector})`));\n }\n\n get driverName(): string {\n return 'MuiV9CheckboxDriver';\n }\n}\n","import { HTMLElementDriver } from '@atomic-testing/component-driver-html';\nimport {\n byCssClass,\n byDataTestId,\n ComponentDriver,\n IComponentDriverOption,\n Interactor,\n PartLocator,\n ScenePart,\n} from '@atomic-testing/core';\n\nexport const parts = {\n contentDisplay: {\n locator: byCssClass('MuiChip-label'),\n driver: HTMLElementDriver,\n },\n removeButton: {\n locator: byDataTestId('CancelIcon'),\n driver: HTMLElementDriver,\n },\n} satisfies ScenePart;\n\n/**\n * Driver for Material UI v9 Chip component.\n * @see https://mui.com/material-ui/react-chip/\n */\nexport class ChipDriver extends ComponentDriver<typeof parts> {\n constructor(locator: PartLocator, interactor: Interactor, option?: Partial<IComponentDriverOption>) {\n super(locator, interactor, {\n ...option,\n parts: parts,\n });\n }\n\n /**\n * Get the label content of the chip.\n * @returns The label text content of the chip.\n */\n async getLabel(): Promise<string | null> {\n await this.enforcePartExistence('contentDisplay');\n const content = await this.parts.contentDisplay.getText();\n return content ?? null;\n }\n\n async clickRemove(): Promise<void> {\n await this.enforcePartExistence('removeButton');\n await this.parts.removeButton.click();\n }\n\n override get driverName(): string {\n return 'MuiV9ChipDriver';\n }\n}\n","import { HTMLElementDriver } from '@atomic-testing/component-driver-html';\nimport {\n byCssClass,\n byRole,\n ContainerDriver,\n IContainerDriverOption,\n Interactor,\n type LocatorRelativePosition,\n Optional,\n PartLocator,\n ScenePart,\n} from '@atomic-testing/core';\n\nexport const parts = {\n title: {\n locator: byCssClass('MuiDialogTitle-root'),\n driver: HTMLElementDriver,\n },\n dialogContainer: {\n locator: byRole('presentation'),\n driver: HTMLElementDriver,\n },\n} satisfies ScenePart;\n\nconst dialogRootLocator: PartLocator = byRole('presentation', 'Root');\n\nconst defaultTransitionDuration = 250;\n\nexport class DialogDriver<ContentT extends ScenePart> extends ContainerDriver<ContentT, typeof parts> {\n constructor(locator: PartLocator, interactor: Interactor, option?: Partial<IContainerDriverOption>) {\n super(locator, interactor, {\n ...option,\n parts: parts,\n content: (option?.content ?? {}) as ContentT,\n });\n }\n\n static override overriddenParentLocator(): Optional<PartLocator> {\n return dialogRootLocator;\n }\n\n static override overrideLocatorRelativePosition(): Optional<LocatorRelativePosition> {\n return 'Same';\n }\n\n async getTitle(): Promise<string | null> {\n await this.enforcePartExistence('title');\n const title = await this.parts.title.getText();\n return title ?? null;\n }\n\n /**\n * Dismiss the dialog by clicking outside its content, then wait for it to close.\n *\n * MUI's \"backdrop click\" is handled on the `.MuiDialog-container` surface (which\n * overlays the visual `.MuiBackdrop-root`), firing `onClose` only when the click\n * target is the container itself. The click therefore lands on the container near\n * its top-left corner to avoid the centered paper. Whether it actually closes\n * depends on the consumer's `onClose` handling (MUI reports a `\"backdropClick\"`\n * reason); the returned boolean reflects the observed close, not merely the click.\n *\n * @param timeoutMs How long to wait for the close transition to finish\n * @returns true if the dialog closed\n */\n async closeByBackdropClick(timeoutMs: number = defaultTransitionDuration): Promise<boolean> {\n await this.enforcePartExistence('dialogContainer');\n // MUI only dismisses when the same element receives mousedown and click, so\n // drive the full press/release/click sequence on the container's empty corner\n // (the click target must be the container, not the centered paper).\n const cornerClick = { position: { x: 5, y: 5 } } as const;\n await this.parts.dialogContainer.mouseDown(cornerClick);\n await this.parts.dialogContainer.mouseUp(cornerClick);\n await this.parts.dialogContainer.click(cornerClick);\n return this.waitForClose(timeoutMs);\n }\n\n /**\n * Wait for dialog to open\n * @param timeoutMs\n * @returns true open has performed successfully\n */\n async waitForOpen(timeoutMs: number = defaultTransitionDuration): Promise<boolean> {\n const isOpened = await this.interactor.waitUntil({\n probeFn: () => this.isOpen(),\n terminateCondition: true,\n timeoutMs,\n });\n return isOpened === true;\n }\n\n /**\n * Wait for dialog to close\n * @param timeoutMs\n * @returns true open has performed successfully\n */\n async waitForClose(timeoutMs: number = defaultTransitionDuration): Promise<boolean> {\n const isOpened = await this.interactor.waitUntil({\n probeFn: () => this.isOpen(),\n terminateCondition: false,\n timeoutMs,\n });\n return isOpened === false;\n }\n\n /**\n * Check if the dialog box is open. Caution, because of animation, upon an open/close action is performed\n * use waitForOpen() or waitForClose() before using isOpen() would result a more accurate open state of the dialog\n * @returns true if dialog box is open\n */\n async isOpen(): Promise<boolean> {\n const exists = await this.exists();\n if (!exists) {\n return false;\n }\n const isVisible = await this.interactor.isVisible(this.parts.dialogContainer.locator);\n return isVisible;\n }\n\n get driverName(): string {\n return 'MuiV9DialogDriver';\n }\n}\n","import { byCssClass, ContainerDriver, locatorUtil, PartLocator, ScenePart } from '@atomic-testing/core';\n\nconst backdropLocator = byCssClass('MuiBackdrop-root');\nconst defaultTransitionDuration = 250;\n\n/**\n * Shared base for MUI portal-rendered overlays (Drawer today; Dialog, Menu,\n * Popover and SpeedDial are prospective consumers). It owns the open/close\n * lifecycle that {@link DialogDriver} first proved out: `isOpen` derived from the\n * visible surface, `waitForOpen`/`waitForClose` spanning the transition, and\n * `closeByBackdrop`.\n *\n * Subclasses supply {@link getSurfaceLocator} (the element whose visibility means\n * \"open\") and, when the overlay is portal-rendered, override the static\n * `overriddenParentLocator()`/`overrideLocatorRelativePosition()` portal hooks to re-root.\n *\n * `closeByEscape` is intentionally absent: keyboard dismissal needs a key-press\n * primitive the `Interactor` interface does not yet expose, which would have to be\n * added to every interactor (DOM/React/Vue/Playwright). It is deferred rather than\n * partially implemented.\n */\nexport abstract class OverlayDriver<ContentT extends ScenePart, T extends ScenePart = {}> extends ContainerDriver<\n ContentT,\n T\n> {\n /**\n * Locator of the surface whose visibility reflects the open state (e.g. the\n * drawer/dialog paper).\n */\n protected abstract getSurfaceLocator(): PartLocator;\n\n /**\n * Locator of the dismissible backdrop. Defaults to MUI's `.MuiBackdrop-root`.\n */\n protected getBackdropLocator(): PartLocator {\n return locatorUtil.append(this.locator, backdropLocator);\n }\n\n /**\n * Whether the overlay is mounted and its surface is visible. Because of open/close\n * transitions, prefer `waitForOpen()`/`waitForClose()` immediately after an action.\n */\n async isOpen(): Promise<boolean> {\n if (!(await this.exists())) {\n return false;\n }\n return this.interactor.isVisible(this.getSurfaceLocator());\n }\n\n /**\n * Wait until the overlay is open.\n * @returns true once open within the timeout.\n */\n async waitForOpen(timeoutMs: number = defaultTransitionDuration): Promise<boolean> {\n const result = await this.interactor.waitUntil({\n probeFn: () => this.isOpen(),\n terminateCondition: true,\n timeoutMs,\n });\n return result === true;\n }\n\n /**\n * Wait until the overlay is closed.\n * @returns true once closed within the timeout.\n */\n async waitForClose(timeoutMs: number = defaultTransitionDuration): Promise<boolean> {\n const result = await this.interactor.waitUntil({\n probeFn: () => this.isOpen(),\n terminateCondition: false,\n timeoutMs,\n });\n if (result === false) {\n return true;\n }\n // Under React's act() the close transition can commit only when the polling\n // act block exits (seen with MUI v5 in jsdom), so the loop above observes the\n // overlay as still open. A final fresh read reflects the now-committed state.\n return !(await this.isOpen());\n }\n\n /**\n * Dismiss by clicking the backdrop, then wait for the close transition. Whether\n * it actually closes depends on the consumer honoring the backdrop dismissal; the\n * returned boolean reflects the observed close, not merely the click.\n */\n async closeByBackdrop(timeoutMs: number = defaultTransitionDuration): Promise<boolean> {\n const backdrop = this.getBackdropLocator();\n if (await this.interactor.exists(backdrop)) {\n // A single click suffices in both worlds: a real browser click is a full\n // mouse sequence, and jsdom dispatches the click event MUI's backdrop\n // onClick listens for. (A separate trailing click would race the dismissal\n // and miss the unmounting backdrop in Playwright.)\n await this.interactor.click(backdrop);\n }\n return this.waitForClose(timeoutMs);\n }\n}\n","import { HTMLElementDriver } from '@atomic-testing/component-driver-html';\nimport {\n byCssClass,\n byRole,\n IContainerDriverOption,\n Interactor,\n type LocatorRelativePosition,\n Optional,\n PartLocator,\n ScenePart,\n} from '@atomic-testing/core';\n\nimport { OverlayDriver } from './OverlayDriver';\n\nexport const drawerParts = {\n paper: {\n locator: byCssClass('MuiDrawer-paper'),\n driver: HTMLElementDriver,\n },\n} satisfies ScenePart;\n\nexport type DrawerAnchor = 'left' | 'right' | 'top' | 'bottom';\n\n// In Material UI v9 the anchor class lives on the drawer root (`.MuiDrawer-root`,\n// the role=\"presentation\" element), not on the paper as in v7.\nconst anchorClassByAnchor: Record<DrawerAnchor, string> = {\n left: 'MuiDrawer-anchorLeft',\n right: 'MuiDrawer-anchorRight',\n top: 'MuiDrawer-anchorTop',\n bottom: 'MuiDrawer-anchorBottom',\n};\n\n// A temporary Drawer is a Modal rendered into a portal whose root carries\n// role=\"presentation\"; re-root to it like DialogDriver does.\nconst drawerRootLocator: PartLocator = byRole('presentation', 'Root');\n\n/**\n * Driver for the Material UI v9 Drawer (and SwipeableDrawer) component.\n *\n * A temporary Drawer is a portal-rendered Modal: its root `role=\"presentation\"`\n * (`.MuiDrawer-root`) carries the anchor class and holds a `.MuiBackdrop-root` plus\n * the `.MuiDrawer-paper` panel. Open/close/backdrop behavior is inherited from\n * {@link OverlayDriver}; this driver adds the anchor read and the portal re-rooting.\n * @see https://mui.com/material-ui/react-drawer/\n */\nexport class DrawerDriver<ContentT extends ScenePart> extends OverlayDriver<ContentT, typeof drawerParts> {\n constructor(locator: PartLocator, interactor: Interactor, option?: Partial<IContainerDriverOption>) {\n super(locator, interactor, {\n ...option,\n parts: drawerParts,\n content: (option?.content ?? {}) as ContentT,\n });\n }\n\n static override overriddenParentLocator(): Optional<PartLocator> {\n return drawerRootLocator;\n }\n\n static override overrideLocatorRelativePosition(): Optional<LocatorRelativePosition> {\n return 'Same';\n }\n\n protected getSurfaceLocator(): PartLocator {\n return this.parts.paper.locator;\n }\n\n /**\n * The side the drawer is anchored to, read from the portal root's anchor class, or\n * `undefined` when the drawer is closed/unmounted.\n *\n * The anchor class sits on the `role=\"presentation\"` root itself, so it is read\n * directly off {@link drawerRootLocator} rather than through a part (parts resolve\n * as descendants of that root, but the class is on the root).\n */\n async getAnchor(): Promise<Optional<DrawerAnchor>> {\n if (!(await this.interactor.exists(drawerRootLocator))) {\n return undefined;\n }\n for (const anchor of Object.keys(anchorClassByAnchor) as DrawerAnchor[]) {\n if (await this.interactor.hasCssClass(drawerRootLocator, anchorClassByAnchor[anchor])) {\n return anchor;\n }\n }\n return undefined;\n }\n\n get driverName(): string {\n return 'MuiV9DrawerDriver';\n }\n}\n","import { ButtonDriver } from './ButtonDriver';\n\n/**\n * Driver for Material UI v9 Floating Action Button component.\n * @see https://mui.com/material-ui/react-floating-action-button/\n */\nexport class FabDriver extends ButtonDriver {\n override get driverName(): string {\n return 'MuiV9FabDriver';\n }\n}\n","import { HTMLTextInputDriver } from '@atomic-testing/component-driver-html';\nimport {\n byCssSelector,\n ComponentDriver,\n IComponentDriverOption,\n IInputDriver,\n Interactor,\n PartLocator,\n ScenePart,\n} from '@atomic-testing/core';\n\nexport const parts = {\n singlelineInput: {\n locator: byCssSelector('input:not([aria-hidden])'),\n driver: HTMLTextInputDriver,\n },\n multilineInput: {\n locator: byCssSelector('textarea:not([aria-hidden])'),\n driver: HTMLTextInputDriver,\n },\n} satisfies ScenePart;\n\ntype TextFieldInputType = 'singleLine' | 'multiline';\n\n/**\n * A driver for the Material UI v9 Input, FilledInput, OutlinedInput, and StandardInput components.\n */\nexport class InputDriver extends ComponentDriver<typeof parts> implements IInputDriver<string | null> {\n constructor(locator: PartLocator, interactor: Interactor, option?: Partial<IComponentDriverOption>) {\n super(locator, interactor, {\n ...option,\n parts,\n });\n }\n\n private async getInputType(): Promise<TextFieldInputType> {\n // TODO: Detection of both input types can be done in parallel.\n const textInputExists = await this.interactor.exists(this.parts.singlelineInput.locator);\n if (textInputExists) {\n return 'singleLine';\n }\n\n const multilineExists = await this.interactor.exists(this.parts.multilineInput.locator);\n if (multilineExists) {\n return 'multiline';\n }\n\n throw new Error('Unable to determine input type in TextFieldInput');\n }\n\n /**\n * Retrieve the current value of the input element, handling both single line\n * and multiline configurations.\n */\n async getValue(): Promise<string | null> {\n const inputType = await this.getInputType();\n switch (inputType) {\n case 'singleLine':\n return this.parts.singlelineInput.getValue();\n case 'multiline':\n return this.parts.multilineInput.getValue();\n }\n }\n\n /**\n * Set the value of the underlying input element.\n *\n * @param value The text to assign to the input.\n */\n async setValue(value: string | null): Promise<boolean> {\n const inputType = await this.getInputType();\n switch (inputType) {\n case 'singleLine':\n return this.parts.singlelineInput.setValue(value);\n case 'multiline':\n return this.parts.multilineInput.setValue(value);\n }\n }\n\n /**\n * Determine whether the input element is disabled.\n */\n async isDisabled(): Promise<boolean> {\n const inputType = await this.getInputType();\n switch (inputType) {\n case 'singleLine':\n return this.parts.singlelineInput.isDisabled();\n case 'multiline':\n return this.parts.multilineInput.isDisabled();\n }\n }\n\n /**\n * Determine whether the input element is read only.\n */\n async isReadonly(): Promise<boolean> {\n const inputType = await this.getInputType();\n switch (inputType) {\n case 'singleLine':\n return this.parts.singlelineInput.isReadonly();\n case 'multiline':\n return this.parts.multilineInput.isReadonly();\n }\n }\n\n /**\n * Identifier for this driver.\n */\n get driverName(): string {\n return 'MuiV9InputDriver';\n }\n}\n","import { ComponentDriver, ErrorBase } from '@atomic-testing/core';\n\nexport const MenuItemDisabledErrorId = 'MenuItemDisabledError';\n\nfunction getErrorMessage(label: string): string {\n return `The menu item with label: ${label} is disabled`;\n}\n\nexport class MenuItemDisabledError extends ErrorBase {\n constructor(\n public readonly label: string,\n public readonly driver: ComponentDriver<any>\n ) {\n super(getErrorMessage(label), driver);\n this.name = MenuItemDisabledErrorId;\n }\n}\n","import { ComponentDriver } from '@atomic-testing/core';\n\nimport { MenuItemDisabledError } from '../errors/MenuItemDisabledError';\n\n/**\n * @internal\n */\nexport class ListItemDriver extends ComponentDriver {\n async label(): Promise<string | null> {\n const label = await this.getText();\n return label?.trim() || null;\n }\n\n async isSelected(): Promise<boolean> {\n return await this.interactor.hasCssClass(this.locator, 'Mui-selected');\n }\n\n async isDisabled(): Promise<boolean> {\n const disabledVal = await this.interactor.getAttribute(this.locator, 'aria-disabled');\n return disabledVal === 'true';\n }\n\n async click(): Promise<void> {\n if (await this.isDisabled()) {\n const label = await this.label();\n throw new MenuItemDisabledError(label ?? '', this);\n }\n await this.interactor.click(this.locator);\n }\n\n get driverName(): string {\n return 'MuiV9ListItemDriver';\n }\n}\n","import {\n byRole,\n IComponentDriverOption,\n Interactor,\n ListComponentDriver,\n ListComponentDriverSpecificOption,\n listHelper,\n PartLocator,\n} from '@atomic-testing/core';\n\nimport { ListItemDriver } from './ListItemDriver';\n\nexport const defaultListDriverOption: ListComponentDriverSpecificOption<ListItemDriver> = {\n itemClass: ListItemDriver,\n itemLocator: byRole('option'),\n};\n\ntype ListDriverOption<ItemT extends ListItemDriver> = ListComponentDriverSpecificOption<ItemT> &\n Partial<IComponentDriverOption<any>>;\n\nexport class ListDriver<ItemT extends ListItemDriver = ListItemDriver> extends ListComponentDriver<ItemT> {\n constructor(\n locator: PartLocator,\n interactor: Interactor,\n option: ListDriverOption<ItemT> = { ...defaultListDriverOption } as ListDriverOption<ItemT>\n ) {\n super(locator, interactor, option);\n }\n\n async getSelected(): Promise<ListItemDriver | null> {\n for await (const item of listHelper.getListItemIterator(this, this.getItemLocator(), ListItemDriver)) {\n if (await item.isSelected()) {\n return item;\n }\n }\n return null;\n }\n\n override get driverName(): string {\n return 'MuiV9ListDriver';\n }\n}\n","import { ComponentDriver, ItemNotFoundError } from '@atomic-testing/core';\n\nexport const MenuItemNotFoundErrorId = 'MenuItemNotFoundError';\n\nexport class MenuItemNotFoundError extends ItemNotFoundError {\n constructor(\n public readonly label: string,\n driver: ComponentDriver<any>\n ) {\n super(label, driver, `Cannot find menu item with label: ${label}`);\n this.name = MenuItemNotFoundErrorId;\n }\n}\n","import { ListItemDriver } from './ListItemDriver';\n\n/**\n * @internal\n */\nexport class MenuItemDriver extends ListItemDriver {\n async value(): Promise<string | null> {\n const value = await this.interactor.getAttribute(this.locator, 'data-value');\n return value ?? null;\n }\n\n override get driverName(): string {\n return 'MuiV9MenuItemDriver';\n }\n}\n","import { HTMLElementDriver } from '@atomic-testing/component-driver-html';\nimport {\n byRole,\n ComponentDriver,\n IComponentDriverOption,\n Interactor,\n listHelper,\n type LocatorRelativePosition,\n Optional,\n PartLocator,\n ScenePart,\n} from '@atomic-testing/core';\n\nimport { MenuItemNotFoundError } from '../errors/MenuItemNotFoundError';\nimport { MenuItemDriver } from './MenuItemDriver';\n\nexport const parts = {\n menu: {\n locator: byRole('menu'),\n driver: HTMLElementDriver,\n },\n} satisfies ScenePart;\n\nconst menuRootLocator: PartLocator = byRole('presentation', 'Root');\nconst menuItemLocator = byRole('menuitem');\n\nexport class MenuDriver extends ComponentDriver<typeof parts> {\n constructor(locator: PartLocator, interactor: Interactor, option?: Partial<IComponentDriverOption>) {\n super(locator, interactor, {\n ...option,\n parts,\n });\n }\n\n static override overriddenParentLocator(): Optional<PartLocator> {\n return menuRootLocator;\n }\n\n static override overrideLocatorRelativePosition(): Optional<LocatorRelativePosition> {\n return 'Same';\n }\n\n async getMenuItemByLabel(label: string): Promise<MenuItemDriver | null> {\n for await (const item of listHelper.getListItemIterator(this, menuItemLocator, MenuItemDriver)) {\n const itemLabel = await item.label();\n if (itemLabel === label) {\n return item;\n }\n }\n return null;\n }\n\n async selectByLabel(label: string): Promise<void> {\n const item = await this.getMenuItemByLabel(label);\n if (item) {\n await item.click();\n } else {\n throw new MenuItemNotFoundError(label, this);\n }\n }\n\n get driverName(): string {\n return 'MuiV9MenuDriver';\n }\n}\n","import { byAttribute, byCssSelector, ComponentDriver, locatorUtil, PartLocator } from '@atomic-testing/core';\n\n// Numbered page controls are the only ones that carry the `MuiPaginationItem-page`\n// state class; matching on it selects every page button regardless of selection.\nconst pageItemLocator = byCssSelector('.MuiPaginationItem-page');\n// MUI marks exactly the selected page with an `aria-current` attribute (value\n// \"page\"); matching on its presence is version-agnostic.\nconst selectedPageLocator = byCssSelector('[aria-current]');\nconst firstButtonLocator = byAttribute('aria-label', 'Go to first page');\nconst previousButtonLocator = byAttribute('aria-label', 'Go to previous page');\nconst nextButtonLocator = byAttribute('aria-label', 'Go to next page');\nconst lastButtonLocator = byAttribute('aria-label', 'Go to last page');\n\n/**\n * Driver for the Material UI v9 Pagination component.\n *\n * Pagination renders a `<nav>` whose `MuiPaginationItem` buttons are each wrapped\n * in their own `<li>` (so they are not siblings — positional `:nth-of-type`\n * iteration does not apply). Page controls are read by their accessible name\n * instead: every page button's aria-label ends in its page number (\"Go to page N\",\n * or \"page N\" once selected), and first/previous/next/last carry stable\n * aria-labels and become `disabled` at the bounds.\n * @see https://mui.com/material-ui/react-pagination/\n */\nexport class PaginationDriver extends ComponentDriver {\n private get pageItemsLocator(): PartLocator {\n return locatorUtil.append(this.locator, pageItemLocator);\n }\n\n /**\n * The selected page number, or `-1` when no page is marked current.\n */\n async getSelectedPage(): Promise<number> {\n const locator = locatorUtil.append(this.locator, selectedPageLocator);\n if (!(await this.interactor.exists(locator))) {\n return -1;\n }\n const text = await this.interactor.getText(locator);\n const page = Number.parseInt(text?.trim() ?? '', 10);\n return Number.isNaN(page) ? -1 : page;\n }\n\n /**\n * Total number of pages, taken from the highest numbered page control. MUI\n * always renders the upper boundary page (boundaryCount >= 1), so this is exact\n * even when middle pages collapse into an ellipsis.\n */\n async getPageCount(): Promise<number> {\n const labels = await this.interactor.getAttribute(this.pageItemsLocator, 'aria-label', true);\n let max = 0;\n for (const label of labels) {\n const match = label?.match(/(\\d+)\\s*$/);\n if (match != null) {\n const page = Number.parseInt(match[1], 10);\n if (page > max) {\n max = page;\n }\n }\n }\n return max;\n }\n\n /**\n * Click the numbered control for `page`. A no-op (returns `true`) when `page` is\n * already selected.\n * @returns `false` when that page is not currently rendered (e.g. hidden behind\n * an ellipsis) or is disabled.\n */\n async goToPage(page: number): Promise<boolean> {\n if ((await this.getSelectedPage()) === page) {\n return true;\n }\n const locator = locatorUtil.append(this.locator, byAttribute('aria-label', `Go to page ${page}`));\n if (!(await this.interactor.exists(locator)) || (await this.interactor.isDisabled(locator))) {\n return false;\n }\n await this.interactor.click(locator);\n return true;\n }\n\n /**\n * Click a navigation control unless it is absent or disabled (at a bound).\n * @returns whether the click was performed.\n */\n private async clickNavButton(navLocator: PartLocator): Promise<boolean> {\n const locator = locatorUtil.append(this.locator, navLocator);\n if (!(await this.interactor.exists(locator)) || (await this.interactor.isDisabled(locator))) {\n return false;\n }\n await this.interactor.click(locator);\n return true;\n }\n\n /** Go to the next page. Returns `false` when on the last page or the control is hidden. */\n async next(): Promise<boolean> {\n return this.clickNavButton(nextButtonLocator);\n }\n\n /** Go to the previous page. Returns `false` when on the first page or the control is hidden. */\n async previous(): Promise<boolean> {\n return this.clickNavButton(previousButtonLocator);\n }\n\n /** Jump to the first page. Returns `false` when already there or the control is hidden (needs `showFirstButton`). */\n async first(): Promise<boolean> {\n return this.clickNavButton(firstButtonLocator);\n }\n\n /** Jump to the last page. Returns `false` when already there or the control is hidden (needs `showLastButton`). */\n async last(): Promise<boolean> {\n return this.clickNavButton(lastButtonLocator);\n }\n\n override get driverName(): string {\n return 'MuiV9PaginationDriver';\n }\n}\n","import { HTMLRadioButtonGroupDriver } from '@atomic-testing/component-driver-html';\nimport {\n byCssSelector,\n byInputType,\n byValue,\n ComponentDriver,\n IComponentDriverOption,\n IInputDriver,\n Interactor,\n locatorUtil,\n PartLocator,\n ScenePart,\n} from '@atomic-testing/core';\n\nexport const parts = {\n choices: {\n locator: byInputType('radio'),\n driver: HTMLRadioButtonGroupDriver,\n },\n} satisfies ScenePart;\n\nexport class ProgressDriver extends ComponentDriver<typeof parts> implements IInputDriver<number | null> {\n constructor(locator: PartLocator, interactor: Interactor, option?: Partial<IComponentDriverOption>) {\n super(locator, interactor, {\n ...option,\n parts,\n });\n }\n\n async getValue(): Promise<number | null> {\n const rawValue = await this.getAttribute('aria-valuenow');\n const numValue = Number(rawValue);\n if (rawValue == null || isNaN(numValue)) {\n return null;\n }\n return Number(rawValue);\n }\n\n async getType(): Promise<'linear' | 'circular'> {\n const cssClasses = await this.getAttribute('class');\n if (cssClasses?.includes('MuiCircularProgress-root')) {\n return 'circular';\n }\n return 'linear';\n }\n\n async isDeterminate(): Promise<boolean> {\n const val = await this.getValue();\n return val != null;\n }\n\n //TODO: Buffer value can be extracted from style=\"transform: translateX(-15%);\" actual value would be 100 - 15 = 85\n // <span class=\"MuiLinearProgress-bar MuiLinearProgress-bar2 MuiLinearProgress-colorPrimary MuiLinearProgress-bar2Buffer css-1v1662g-MuiLinearProgress-bar2\" style=\"transform: translateX(-15%);\"></span>\n\n async setValue(value: number | null): Promise<boolean> {\n // TODO: Setting value to null is not supported. https://github.com/atomic-testing/atomic-testing/issues/68\n const currentValue = await this.getValue();\n if (value === currentValue) {\n return true;\n }\n\n const valueToClick = (value == null ? currentValue : value) as number;\n const targetLocator = locatorUtil.append(this.parts.choices.locator, byValue(valueToClick.toString(), 'Same'));\n\n const targetExists = await this.interactor.exists(targetLocator);\n if (targetExists) {\n const id = await this.interactor.getAttribute(targetLocator, 'id');\n const labelLocator = locatorUtil.append(this.locator, byCssSelector(`label[for=\"${id}\"]`));\n await this.interactor.click(labelLocator);\n }\n // TODO: throw error if the value does not exist\n return targetExists;\n }\n\n get driverName(): string {\n return 'MuiV9ProgressDriver';\n }\n}\n","import { byCssSelector, ComponentDriver, locatorUtil, Optional, PartLocator } from '@atomic-testing/core';\n\n// The radio `<input>` carries checked/value/disabled; located as a descendant of\n// this option's FormControlLabel root.\nconst inputLocator: PartLocator = byCssSelector('input');\nconst checkedInputLocator: PartLocator = byCssSelector('input:checked');\n\n/**\n * Driver for a single Material UI v9 Radio option (a `FormControlLabel` wrapping a\n * `Radio`). Its label text is the `FormControlLabel`'s text; selected/value/disabled\n * state is read from the underlying radio `<input>`.\n *\n * Used as the item driver of {@link RadioGroupDriver}, but also usable on its own\n * when a single radio option is addressed directly. It declares no parts (so it\n * composes as a list item) and reads the input via descendant locators.\n * @see https://mui.com/material-ui/react-radio-button/\n */\nexport class RadioDriver extends ComponentDriver {\n private get input(): PartLocator {\n return locatorUtil.append(this.locator, inputLocator);\n }\n\n /**\n * The option's visible label, or `undefined` when it renders without text.\n */\n async getLabel(): Promise<Optional<string>> {\n const text = await this.getText();\n return text?.trim() || undefined;\n }\n\n /**\n * The option's `value` attribute.\n */\n async getValue(): Promise<string | null> {\n const value = await this.interactor.getAttribute(this.input, 'value');\n return value ?? null;\n }\n\n /**\n * Whether this option is the selected one in its group.\n */\n isSelected(): Promise<boolean> {\n return this.interactor.exists(locatorUtil.append(this.locator, checkedInputLocator));\n }\n\n /**\n * Whether this option is disabled.\n */\n isDisabled(): Promise<boolean> {\n return this.interactor.isDisabled(this.input);\n }\n\n /**\n * Select this option by clicking its radio input. No-op effect when already selected.\n */\n async select(): Promise<void> {\n await this.interactor.click(this.input);\n }\n\n get driverName(): string {\n return 'MuiV9RadioDriver';\n }\n}\n","import {\n byCssSelector,\n escapeUtil,\n IComponentDriverOption,\n IInputDriver,\n Interactor,\n ListComponentDriver,\n ListComponentDriverSpecificOption,\n locatorUtil,\n Nullable,\n PartLocator,\n} from '@atomic-testing/core';\n\nimport { RadioDriver } from './RadioDriver';\n\n/**\n * Radio options are located by their `FormControlLabel` root, which wraps the\n * radio `<input>` and renders the label text — the unit a {@link RadioDriver}\n * drives.\n */\nexport const defaultRadioGroupDriverOption: ListComponentDriverSpecificOption<RadioDriver> = {\n itemClass: RadioDriver,\n itemLocator: byCssSelector('.MuiFormControlLabel-root'),\n};\n\ntype RadioGroupDriverOption<ItemT extends RadioDriver> = ListComponentDriverSpecificOption<ItemT> &\n Partial<IComponentDriverOption<any>>;\n\n/**\n * Driver for the Material UI v9 RadioGroup component.\n *\n * `<RadioGroup>` renders a `role=\"radiogroup\"` whose options are `FormControlLabel`s\n * wrapping a radio `<input>`. This driver is a {@link ListComponentDriver} over those\n * options, so per-option {@link RadioDriver} instances are available via\n * `getItems`/`getItemByIndex`/`getItemByLabel`, on top of the group-level value and\n * label helpers. The selected value is read from the checked `<input>` and selection\n * is made by value or label.\n * @see https://mui.com/material-ui/react-radio-button/\n */\nexport class RadioGroupDriver<ItemT extends RadioDriver = RadioDriver>\n extends ListComponentDriver<ItemT>\n implements IInputDriver<string | null>\n{\n constructor(locator: PartLocator, interactor: Interactor, option: Partial<RadioGroupDriverOption<ItemT>> = {}) {\n // The option shape is fixed (FormControlLabel options driven by RadioDriver),\n // so defaults are merged in rather than relying on a default parameter, which a\n // scene part's always-present option object would otherwise shadow.\n super(locator, interactor, {\n ...defaultRadioGroupDriverOption,\n ...option,\n } as RadioGroupDriverOption<ItemT>);\n }\n\n /**\n * The `value` of the selected option, or `null` when none is selected.\n */\n async getValue(): Promise<string | null> {\n const checked = locatorUtil.append(this.locator, byCssSelector('input:checked'));\n const value = await this.interactor.getAttribute(checked, 'value');\n return value ?? null;\n }\n\n /**\n * Select the option whose radio `<input>` has the given `value`.\n * @returns `false` when no option has that value, or when `value` is `null`.\n */\n async setValue(value: string | null): Promise<boolean> {\n if (value == null) {\n return false;\n }\n const input = locatorUtil.append(this.locator, byCssSelector(`input[value=\"${escapeUtil.escapeValue(value)}\"]`));\n if (!(await this.interactor.exists(input))) {\n return false;\n }\n await this.interactor.click(input);\n return true;\n }\n\n /**\n * The visible label of every option, in DOM order.\n */\n async getOptions(): Promise<string[]> {\n const items = await this.getItems();\n const labels: string[] = [];\n for (const item of items) {\n labels.push((await item.getLabel()) ?? '');\n }\n return labels;\n }\n\n /**\n * The label of the selected option, or `null` when none is selected.\n */\n async getSelectedLabel(): Promise<Nullable<string>> {\n const items = await this.getItems();\n for (const item of items) {\n if (await item.isSelected()) {\n return (await item.getLabel()) ?? null;\n }\n }\n return null;\n }\n\n /**\n * Select the first option whose visible label equals `label`.\n * @returns `false` when no option matches.\n */\n async selectByLabel(label: string): Promise<boolean> {\n const option = await this.getItemByLabel(label);\n if (option == null) {\n return false;\n }\n await option.select();\n return true;\n }\n\n /**\n * Whether the option with the given label is disabled.\n * @returns `false` when no option matches.\n */\n async isOptionDisabled(label: string): Promise<boolean> {\n const option = await this.getItemByLabel(label);\n return option == null ? false : option.isDisabled();\n }\n\n override get driverName(): string {\n return 'MuiV9RadioGroupDriver';\n }\n}\n","import { HTMLRadioButtonGroupDriver } from '@atomic-testing/component-driver-html';\nimport {\n byCssClass,\n byInputType,\n byValue,\n ComponentDriver,\n IComponentDriverOption,\n IInputDriver,\n Interactor,\n locatorUtil,\n PartLocator,\n ScenePart,\n} from '@atomic-testing/core';\n\nexport const parts = {\n choices: {\n locator: byInputType('radio'),\n driver: HTMLRadioButtonGroupDriver,\n },\n} satisfies ScenePart;\n\n/**\n * MUI marks the disabled/read-only state with a class on the Rating root span\n * (`Mui-disabled` / `Mui-readOnly`), not on the visually-hidden radio inputs that\n * the composed {@link HTMLRadioButtonGroupDriver} can see — so these states are\n * only observable from the root element.\n */\nconst disabledClassName = 'Mui-disabled';\nconst readOnlyClassName = 'Mui-readOnly';\nconst filledIconClassName = 'MuiRating-iconFilled';\n\nexport class RatingDriver extends ComponentDriver<typeof parts> implements IInputDriver<number | null> {\n constructor(locator: PartLocator, interactor: Interactor, option?: Partial<IComponentDriverOption>) {\n super(locator, interactor, {\n ...option,\n parts,\n });\n }\n\n async getValue(): Promise<number | null> {\n // A read-only Rating renders no radio inputs (root becomes `role=\"img\"` with the\n // value carried in `aria-label`), so the radio-based read below cannot be used.\n const isReadOnly = await this.interactor.hasCssClass(this.locator, readOnlyClassName);\n if (isReadOnly) {\n return this.getReadOnlyValue();\n }\n\n await this.enforcePartExistence('choices');\n const value = await this.parts.choices.getValue();\n // The \"no rating\" state is the visually-hidden radio whose `value` attribute is the\n // empty string; treat it the same as an absent selection.\n if (value == null || value === '') {\n return null;\n }\n return parseFloat(value);\n }\n\n /**\n * Read the value of a read-only Rating.\n *\n * Primary source is the root's `aria-label`, which MUI populates with the accessible\n * name (e.g. `\"2.5 Stars\"`) — accessibility-first and precision-accurate. When a\n * caller supplies a custom, non-numeric `aria-label`, fall back to counting the\n * filled star icons; that count is exact for whole-star ratings.\n */\n private async getReadOnlyValue(): Promise<number | null> {\n const label = await this.interactor.getAttribute(this.locator, 'aria-label');\n if (label != null) {\n const parsed = parseFloat(label);\n if (!Number.isNaN(parsed)) {\n return parsed;\n }\n }\n\n const filledLocator = locatorUtil.append(this.locator, byCssClass(filledIconClassName));\n const filledIcons = await this.interactor.getAttribute(filledLocator, 'class', true);\n return filledIcons.length > 0 ? filledIcons.length : null;\n }\n\n /**\n * Whether the Rating is disabled. `disabled` is reflected as the `Mui-disabled`\n * class on the root span (the composed radio-group driver exposes no `isDisabled`).\n */\n async isDisabled(): Promise<boolean> {\n return this.interactor.hasCssClass(this.locator, disabledClassName);\n }\n\n async setValue(value: number | null): Promise<boolean> {\n const currentValue = await this.getValue();\n if (value === currentValue) {\n return true;\n }\n\n // Activate the visually-hidden `<input type=\"radio\">` whose `value` attribute\n // matches the target — the empty-string radio (MUI's \"no rating\") for a clear.\n // `activate` is coordinate-free, so it reaches inputs a positional click cannot:\n // the half-star label for fractional values is zero-width and unclickable in a\n // real browser (#86), and the clear radio has no `<label>` at all (#68). This\n // unifies integer, fractional, and clear on one portable path.\n const targetValue = value == null ? '' : value.toString();\n const targetLocator = locatorUtil.append(this.parts.choices.locator, byValue(targetValue, 'Same'));\n const targetExists = await this.interactor.exists(targetLocator);\n if (targetExists) {\n await this.interactor.activate(targetLocator);\n }\n // TODO: throw error if the value does not exist\n return targetExists;\n }\n\n get driverName(): string {\n return 'MuiV9RatingDriver';\n }\n}\n","import {\n HTMLButtonDriver,\n HTMLElementDriver,\n HTMLSelectDriver,\n HTMLTextInputDriver,\n} from '@atomic-testing/component-driver-html';\nimport {\n byAttribute,\n byCssSelector,\n byRole,\n byTagName,\n ComponentDriver,\n IComponentDriverOption,\n IInputDriver,\n Interactor,\n listHelper,\n locatorUtil,\n Nullable,\n PartLocator,\n ScenePart,\n ScenePartDriver,\n} from '@atomic-testing/core';\n\nimport { MenuItemNotFoundError } from '../errors/MenuItemNotFoundError';\nimport { MenuItemDriver } from './MenuItemDriver';\n\nexport const selectPart = {\n trigger: {\n locator: byRole('combobox'), // Starting in 5.12 and beyond, the role has changed from 'button' to 'combobox'\n driver: HTMLButtonDriver,\n },\n dropdown: {\n locator: byCssSelector('[role=presentation] [role=listbox]', 'Root'),\n driver: HTMLElementDriver,\n },\n input: {\n locator: byTagName('input'),\n driver: HTMLTextInputDriver,\n },\n nativeSelect: {\n locator: byTagName('select'),\n driver: HTMLSelectDriver,\n },\n} satisfies ScenePart;\n\nexport type SelectScenePart = typeof selectPart;\nexport type SelectScenePartDriver = ScenePartDriver<SelectScenePart>;\nexport interface MenuItemGetOption {\n /**\n * When true, the driver will not check if the dropdown is open, which helps speed the process up.\n */\n skipDropdownCheck?: boolean;\n}\nconst optionLocator = byRole('option');\n\nexport class SelectDriver extends ComponentDriver<SelectScenePart> implements IInputDriver<string | null> {\n constructor(locator: PartLocator, interactor: Interactor, option?: Partial<IComponentDriverOption>) {\n super(locator, interactor, {\n ...option,\n parts: selectPart,\n });\n }\n async isNative(): Promise<boolean> {\n const nativeSelectExists = await this.interactor.exists(this.parts.nativeSelect.locator);\n return Promise.resolve(nativeSelectExists);\n }\n\n async getValue(): Promise<string | null> {\n const isNative = await this.isNative();\n if (isNative) {\n const val = (await this.parts.nativeSelect.getValue()) as Nullable<string>;\n return val;\n }\n\n await this.enforcePartExistence('input');\n const value = await this.parts.input.getValue();\n return value ?? null;\n }\n\n async setValue(value: string | null): Promise<boolean> {\n let success = false;\n const isNative = await this.isNative();\n if (isNative) {\n success = await this.parts.nativeSelect.setValue(value);\n return success;\n }\n\n await this.openDropdown();\n await this.enforcePartExistence('dropdown');\n const optionSelector = byAttribute('data-value', value!);\n const optionLocator = locatorUtil.append(this.parts.dropdown.locator, optionSelector);\n const optionExists = await this.interactor.exists(optionLocator);\n\n if (optionExists) {\n await this.interactor.click(optionLocator);\n success = true;\n }\n\n return success;\n }\n\n /**\n * Select menu item by its label, if it exists\n * Limitation, this method will not work if the dropdown is a native select.\n * @param label\n * @returns\n */\n async getMenuItemByLabel(label: string, option?: MenuItemGetOption): Promise<MenuItemDriver | null> {\n if (!option?.skipDropdownCheck) {\n await this.openDropdown();\n }\n\n // TODO: Add native select support\n\n for await (const item of listHelper.getListItemIterator(this, optionLocator, MenuItemDriver)) {\n const itemLabel = await item.label();\n if (itemLabel === label) {\n return item;\n }\n }\n return null;\n }\n\n /**\n * Selects an option by its label\n * @param label\n * @returns\n */\n async selectByLabel(label: string): Promise<void> {\n const isNative = await this.isNative();\n if (isNative) {\n await this.parts.nativeSelect.selectByLabel(label);\n return;\n }\n\n await this.enforcePartExistence('trigger');\n await this.parts.trigger.click();\n\n await this.enforcePartExistence('dropdown');\n const item = await this.getMenuItemByLabel(label, { skipDropdownCheck: true });\n\n if (item) {\n await item.click();\n } else {\n throw new MenuItemNotFoundError(label, this);\n }\n }\n\n async getSelectedLabel(): Promise<string | null> {\n const isNative = await this.isNative();\n if (isNative) {\n return await this.parts.nativeSelect.getSelectedLabel();\n }\n\n await this.enforcePartExistence('trigger');\n const label = await this.parts.trigger.getText();\n return label ?? null;\n }\n\n override async exists(): Promise<boolean> {\n const triggerExists = await this.interactor.exists(this.parts.trigger.locator);\n if (triggerExists) {\n return true;\n }\n\n const nativeExists = await this.interactor.exists(this.parts.nativeSelect.locator);\n return nativeExists;\n }\n\n /**\n * Check if the dropdown is open, or if it is a native select, it is always open because there is no known way check its open state\n * @returns For native dropdown it is always true. For custom dropdown, it is true if the dropdown is open.\n */\n async isDropdownOpen(): Promise<boolean> {\n const isNative = await this.isNative();\n if (isNative) {\n return true;\n } else {\n return this.parts.dropdown.exists();\n }\n }\n\n async openDropdown(): Promise<void> {\n const isOpen = await this.isDropdownOpen();\n if (isOpen) {\n return;\n }\n await this.parts.trigger.click();\n }\n\n async closeDropdown(): Promise<void> {\n const isOpen = await this.isDropdownOpen();\n if (!isOpen) {\n return;\n }\n await this.parts.trigger.click();\n }\n\n async isDisabled(): Promise<boolean> {\n const isNative = await this.isNative();\n if (isNative) {\n return this.parts.nativeSelect.isDisabled();\n } else {\n await this.enforcePartExistence('trigger');\n const isDisabled = await this.interactor.getAttribute(this.parts.trigger.locator, 'aria-disabled');\n return isDisabled === 'true';\n }\n }\n\n async isReadonly(): Promise<boolean> {\n const isNative = await this.isNative();\n if (isNative) {\n return this.parts.nativeSelect.isReadonly();\n } else {\n // Cannot determine readonly state of a select input.\n return false;\n }\n }\n\n get driverName(): string {\n return 'MuiV9SelectDriver';\n }\n}\n","import { HTMLTextInputDriver } from '@atomic-testing/component-driver-html';\nimport {\n byCssSelector,\n ComponentDriver,\n IComponentDriverOption,\n IInputDriver,\n Interactor,\n locatorUtil,\n PartLocator,\n ScenePart,\n ScenePartDriver,\n} from '@atomic-testing/core';\n\nexport const parts = {\n input: {\n locator: byCssSelector('input[type=\"range\"][data-index=\"0\"]'),\n driver: HTMLTextInputDriver,\n },\n} satisfies ScenePart;\n\nexport type SelectScenePart = typeof parts;\nexport type SelectScenePartDriver = ScenePartDriver<SelectScenePart>;\n\nexport class SliderDriver extends ComponentDriver<SelectScenePart> implements IInputDriver<number> {\n constructor(locator: PartLocator, interactor: Interactor, option?: Partial<IComponentDriverOption>) {\n super(locator, interactor, {\n ...option,\n parts: parts,\n });\n }\n\n /**\n * Return the first occurrence of the Slider input\n * @returns\n */\n async getValue(): Promise<number> {\n const values = await this.getRangeValues(1);\n return values[0]!;\n }\n\n /**\n * Set slider's range value. Do not use as it will throw an error\n * @param values\n * @see https://github.com/atomic-testing/atomic-testing/issues/73\n */\n async setValue(value: number): Promise<boolean> {\n const success = await this.setRangeValues([value]);\n return success;\n }\n\n async getRangeValues(count?: number): Promise<readonly number[]> {\n await this.enforcePartExistence('input');\n const result: number[] = [];\n\n let index = 0;\n let done = false;\n while (!done) {\n const locator = locatorUtil.append(this.locator, this.getInputLocator(index));\n const exists = await this.interactor.exists(locator);\n if (exists) {\n index++;\n done = count != null && index >= count;\n const value = await this.interactor.getAttribute(locator, 'value');\n result.push(parseFloat(value!));\n } else {\n done = true;\n }\n }\n return result;\n }\n\n private getInputLocator(index: number): PartLocator {\n return byCssSelector(`input[type=\"range\"][data-index=\"${index}\"]`);\n }\n\n /**\n * Set slider's range values. Do not use as it will throw an error\n * @param values\n * @see https://github.com/atomic-testing/atomic-testing/issues/73\n */\n async setRangeValues(_values: readonly number[]): Promise<boolean> {\n await this.enforcePartExistence('input');\n throw new Error('setRangeValue is not supported.');\n // for (let index = 0; index < values.length; index++) {\n // const locator = locatorUtil.append(this.locator, this.getInputLocator(index));\n // const exists = await this.interactor.exists(locator);\n // if (exists) {\n // // @ts-ignore\n // await this.interactor.changeValue(locator, values[index].toString());\n // // const driver = new HTMLTextInputDriver(locator, this.interactor);\n // // await driver.setValue(values[index].toString());\n // } else {\n // return false;\n // }\n // }\n\n // return true;\n }\n\n async isDisabled(): Promise<boolean> {\n await this.enforcePartExistence('input');\n const disabled = await this.parts.input.isDisabled();\n return disabled;\n }\n\n get driverName(): string {\n return 'MuiV9SliderDriver';\n }\n}\n","import { HTMLElementDriver } from '@atomic-testing/component-driver-html';\nimport {\n byCssClass,\n ComponentDriver,\n IComponentDriverOption,\n Interactor,\n locatorUtil,\n PartLocator,\n ScenePart,\n ComponentDriverCtor,\n} from '@atomic-testing/core';\n\nexport const parts = {\n contentDisplay: {\n locator: byCssClass('MuiSnackbarContent-message'),\n driver: HTMLElementDriver,\n },\n actionArea: {\n locator: byCssClass('MuiSnackbarContent-action'),\n driver: HTMLElementDriver,\n },\n} satisfies ScenePart;\n\n/**\n * Driver for Material UI v9 Snackbar component.\n * @see https://mui.com/material-ui/react-snackbar/\n */\nexport class SnackbarDriver extends ComponentDriver<typeof parts> {\n constructor(locator: PartLocator, interactor: Interactor, option?: Partial<IComponentDriverOption>) {\n super(locator, interactor, {\n ...option,\n parts: parts,\n });\n }\n\n /**\n * Get the label content of the snackbar.\n * @returns The label text content of the snackbar.\n */\n async getLabel(): Promise<string | null> {\n await this.enforcePartExistence('contentDisplay');\n const content = await this.parts.contentDisplay.getText();\n return content ?? null;\n }\n\n /**\n * Get a driver instance of a component in the action area of the snackbar.\n * @param locator\n * @param driverClass\n * @returns\n */\n async getActionComponent<ItemClass extends ComponentDriver>(\n locator: PartLocator,\n driverClass: ComponentDriverCtor<ItemClass>\n ): Promise<ItemClass | null> {\n await this.enforcePartExistence('actionArea');\n const componentLocator = locatorUtil.append(this.parts.actionArea.locator, locator);\n const exists = await this.interactor.exists(componentLocator);\n if (exists) {\n return new driverClass(componentLocator, this.interactor, this.commutableOption);\n }\n return null;\n }\n\n override get driverName(): string {\n return 'MuiV9SnackbarDriver';\n }\n}\n","import { byCssSelector, ComponentDriver, escapeUtil, locatorUtil, PartLocator } from '@atomic-testing/core';\n\n// The trigger FAB carries the open state via aria-expanded; the action buttons\n// carry their name via aria-label. Both are distinct MUI classes within the root.\nconst fabLocator = byCssSelector('.MuiSpeedDial-fab');\nconst actionLocator = byCssSelector('.MuiSpeedDialAction-fab');\n\n/**\n * Driver for the Material UI v9 SpeedDial component.\n *\n * SpeedDial renders a trigger FAB (`.MuiSpeedDial-fab`, `aria-expanded` reflects\n * open state) and a set of action FABs (`.MuiSpeedDialAction-fab`, each\n * aria-labelled with its name). The actions stay mounted but are only revealed\n * when open, so open state is read from the FAB's `aria-expanded` rather than\n * action presence.\n * @see https://mui.com/material-ui/react-speed-dial/\n */\nexport class SpeedDialDriver extends ComponentDriver {\n private get fab(): PartLocator {\n return locatorUtil.append(this.locator, fabLocator);\n }\n\n /**\n * Whether the speed dial is open (its FAB reports `aria-expanded=\"true\"`).\n */\n async isOpen(): Promise<boolean> {\n const expanded = await this.interactor.getAttribute(this.fab, 'aria-expanded');\n return expanded === 'true';\n }\n\n /**\n * Open the speed dial by hovering its FAB. No-op when already open.\n *\n * Hover (`onMouseEnter`) is the trigger that opens consistently across MUI\n * versions and browsers — clicking only focuses-then-opens in Chromium, and\n * focus opens in v7 but not v5, whereas hover opens everywhere.\n */\n async open(): Promise<void> {\n if (!(await this.isOpen())) {\n await this.interactor.hover(this.fab);\n }\n }\n\n /**\n * Close the speed dial by moving the pointer off its FAB. No-op when already closed.\n */\n async close(): Promise<void> {\n if (await this.isOpen()) {\n await this.interactor.mouseLeave(this.fab);\n }\n }\n\n /**\n * The labels of every action, in order (read from each action FAB's aria-label).\n */\n async getActionLabels(): Promise<string[]> {\n const labels = await this.interactor.getAttribute(\n locatorUtil.append(this.locator, actionLocator),\n 'aria-label',\n true\n );\n return labels.filter((label): label is string => label != null);\n }\n\n /**\n * Trigger the action with the given label, opening the dial first if needed.\n * @returns `false` when no action has that label.\n */\n async triggerActionByLabel(label: string): Promise<boolean> {\n await this.open();\n const actionByLabel = byCssSelector(`.MuiSpeedDialAction-fab[aria-label=\"${escapeUtil.escapeValue(label)}\"]`);\n const locator = locatorUtil.append(this.locator, actionByLabel);\n if (!(await this.interactor.exists(locator))) {\n return false;\n }\n await this.interactor.click(locator);\n return true;\n }\n\n override get driverName(): string {\n return 'MuiV9SpeedDialDriver';\n }\n}\n","import { byCssSelector, ComponentDriver, locatorUtil, Optional, PartLocator } from '@atomic-testing/core';\n\nexport interface StepInfo {\n /** The step's visible label. */\n label: Optional<string>;\n /** Whether this is the active step (MUI marks the label `Mui-active`). */\n active: boolean;\n /** Whether the step has been completed (`Mui-completed`). */\n completed: boolean;\n /** Whether the step is disabled (`Mui-disabled`). */\n disabled: boolean;\n}\n\n// The `.MuiStepLabel-label` span carries both the clean label text and the\n// per-step state class, making it the single source of truth for step state.\nconst stepLabelLocator = byCssSelector('.MuiStepLabel-label');\n\n/**\n * Locator for the label of the step at `index`. In Material UI v9 the connector\n * is rendered *inside* each `.MuiStep-root` (in v7 it was an interleaved sibling),\n * so the step elements are now consecutive siblings and the step at `index` is the\n * `index+1`-th element of its type; nth-of-type addresses it directly.\n */\nfunction stepLabelAt(index: number): PartLocator {\n return byCssSelector(`.MuiStep-root:nth-of-type(${index + 1}) .MuiStepLabel-label`);\n}\n\nfunction stepButtonAt(index: number): PartLocator {\n return byCssSelector(`.MuiStep-root:nth-of-type(${index + 1}) .MuiStepButton-root`);\n}\n\n/**\n * Driver for the Material UI v9 Stepper component.\n *\n * Each step's state lives on its `.MuiStepLabel-label` (`Mui-active`,\n * `Mui-completed`, `Mui-disabled`); reading every label's class in one pass gives\n * the step states and count in document order. Steps are addressed positionally\n * for label text and clicks via {@link stepLabelAt}/{@link stepButtonAt}.\n *\n * Supported layouts: the default horizontal stepper and the vertical orientation.\n * In v9 every `.MuiStep-root` is a consecutive sibling (the connector lives inside\n * the step), and every step renders a text label, so positional addressing lines up\n * with the document-order class list. The unsupported case is icon-only steps, which\n * render no `.MuiStepLabel-label`; under those the document-order class list has fewer\n * entries than steps and the two desynchronize. Robustly supporting that needs an\n * interactor primitive to address the n-th of non-sibling matches\n * (CSS `:nth-child(of S)` is unsupported in jsdom), which is out of this driver's scope.\n * @see https://mui.com/material-ui/react-stepper/\n */\nexport class StepperDriver extends ComponentDriver {\n private async getStepClassList(): Promise<readonly string[]> {\n return this.interactor.getAttribute(locatorUtil.append(this.locator, stepLabelLocator), 'class', true);\n }\n\n /**\n * The number of steps.\n */\n async getStepCount(): Promise<number> {\n return (await this.getStepClassList()).length;\n }\n\n /**\n * Zero-based index of the active step, or `-1` when none is active.\n */\n async getActiveStepIndex(): Promise<number> {\n const classes = await this.getStepClassList();\n return classes.findIndex(c => c.split(/\\s+/).includes('Mui-active'));\n }\n\n /**\n * Every step with its label and active/completed/disabled state, in order.\n */\n async getSteps(): Promise<StepInfo[]> {\n const classes = await this.getStepClassList();\n const steps: StepInfo[] = [];\n for (let index = 0; index < classes.length; index++) {\n const stateClasses = classes[index].split(/\\s+/);\n const label = await this.interactor.getText(locatorUtil.append(this.locator, stepLabelAt(index)));\n steps.push({\n label: label?.trim(),\n active: stateClasses.includes('Mui-active'),\n completed: stateClasses.includes('Mui-completed'),\n disabled: stateClasses.includes('Mui-disabled'),\n });\n }\n return steps;\n }\n\n /**\n * Navigate to the step at `index` by clicking its control (requires a clickable\n * `StepButton`, e.g. a non-linear stepper).\n * @returns `false` when the step is out of range, has no button, or is disabled.\n */\n async goToStep(index: number): Promise<boolean> {\n if (index < 0 || index >= (await this.getStepCount())) {\n return false;\n }\n const button = locatorUtil.append(this.locator, stepButtonAt(index));\n if (!(await this.interactor.exists(button)) || (await this.interactor.isDisabled(button))) {\n return false;\n }\n await this.interactor.click(button);\n return true;\n }\n\n override get driverName(): string {\n return 'MuiV9StepperDriver';\n }\n}\n","import { HTMLCheckboxDriver } from '@atomic-testing/component-driver-html';\nimport {\n byAttribute,\n ComponentDriver,\n IComponentDriverOption,\n IFormFieldDriver,\n Interactor,\n IToggleDriver,\n PartLocator,\n ScenePart,\n} from '@atomic-testing/core';\n\nexport const parts = {\n input: {\n locator: byAttribute('type', 'checkbox'),\n driver: HTMLCheckboxDriver,\n },\n} satisfies ScenePart;\n\nexport class SwitchDriver\n extends ComponentDriver<typeof parts>\n implements IFormFieldDriver<string | null>, IToggleDriver\n{\n constructor(locator: PartLocator, interactor: Interactor, option?: Partial<IComponentDriverOption>) {\n super(locator, interactor, {\n ...option,\n parts,\n });\n }\n\n override async exists(): Promise<boolean> {\n return this.interactor.exists(this.parts.input.locator);\n }\n\n async isSelected(): Promise<boolean> {\n await this.enforcePartExistence('input');\n return this.parts.input.isSelected();\n }\n async setSelected(selected: boolean): Promise<void> {\n await this.enforcePartExistence('input');\n await this.parts.input.setSelected(selected);\n }\n\n async getValue(): Promise<string | null> {\n await this.enforcePartExistence('input');\n return this.parts.input.getValue();\n }\n\n async isDisabled(): Promise<boolean> {\n await this.enforcePartExistence('input');\n return this.parts.input.isDisabled();\n }\n\n async isReadonly(): Promise<boolean> {\n // MUI v5 does not have a readonly state for the switch\n return Promise.resolve(false);\n }\n\n get driverName(): string {\n return 'MuiV9SwitchDriver';\n }\n}\n","import { ComponentDriver } from '@atomic-testing/core';\n\n/**\n * Driver for a single Material UI v9 TableCell (`<td>`/`<th>`, `.MuiTableCell-root`).\n *\n * A cell's content is plain text, so it relies on the inherited `getText()`/`exists()`;\n * it exists as a distinct type so {@link TableRowDriver} can expose typed cell drivers.\n * @see https://mui.com/material-ui/react-table/\n */\nexport class TableCellDriver extends ComponentDriver {\n get driverName(): string {\n return 'MuiV9TableCellDriver';\n }\n}\n","import {\n byCssSelector,\n IComponentDriverOption,\n Interactor,\n ListComponentDriver,\n ListComponentDriverSpecificOption,\n PartLocator,\n} from '@atomic-testing/core';\n\nimport { TableCellDriver } from './TableCellDriver';\n\n/**\n * Cells are located by `.MuiTableCell-root`, covering both `<td>` body cells and\n * `<th>` header cells.\n */\nexport const defaultTableRowDriverOption: ListComponentDriverSpecificOption<TableCellDriver> = {\n itemClass: TableCellDriver,\n itemLocator: byCssSelector('.MuiTableCell-root'),\n};\n\ntype TableRowDriverOption<ItemT extends TableCellDriver> = ListComponentDriverSpecificOption<ItemT> &\n Partial<IComponentDriverOption<any>>;\n\n/**\n * Driver for a single Material UI v9 TableRow (`.MuiTableRow-root`).\n *\n * A {@link ListComponentDriver} over the row's cells, exposing per-cell\n * {@link TableCellDriver}s (via `getItems`/`getItemByIndex`) plus convenience reads\n * of the cell texts.\n *\n * Cells are addressed positionally via `:nth-of-type`, which counts per element type.\n * This assumes a row's cells are homogeneous (all `<td>`, or all `<th>` for a header\n * row) — the common MUI rendering. A row mixing a leading `<th scope=\"row\">` with\n * `<td>` data cells would desynchronize the index (the `<td>`s start at type-index 1\n * after the `<th>`); such rows are out of scope.\n * @see https://mui.com/material-ui/react-table/\n */\nexport class TableRowDriver<ItemT extends TableCellDriver = TableCellDriver> extends ListComponentDriver<ItemT> {\n constructor(locator: PartLocator, interactor: Interactor, option: Partial<TableRowDriverOption<ItemT>> = {}) {\n // A row's item shape is fixed (cells driven by TableCellDriver). The defaults are\n // applied LAST so they win over any inherited `itemLocator`/`itemClass`: when a\n // TableDriver builds its row drivers it forwards its own commutable option, whose\n // (row-level) item locator would otherwise shadow the cell locator here.\n super(locator, interactor, {\n ...option,\n ...defaultTableRowDriverOption,\n } as TableRowDriverOption<ItemT>);\n }\n\n /**\n * The number of cells in the row.\n */\n async getCellCount(): Promise<number> {\n return this.getItemCount();\n }\n\n /**\n * The cell driver at the given zero-based column index, or `null` when out of range.\n */\n async getCell(index: number): Promise<ItemT | null> {\n return this.getItemByIndex(index);\n }\n\n /**\n * The text of every cell, in column order.\n */\n async getCellTexts(): Promise<string[]> {\n const cells = await this.getItems();\n const texts: string[] = [];\n for (const cell of cells) {\n texts.push((await cell.getText())?.trim() ?? '');\n }\n return texts;\n }\n\n override get driverName(): string {\n return 'MuiV9TableRowDriver';\n }\n}\n","import {\n byCssSelector,\n IComponentDriverOption,\n Interactor,\n ListComponentDriver,\n ListComponentDriverSpecificOption,\n locatorUtil,\n Optional,\n PartLocator,\n} from '@atomic-testing/core';\n\nimport { TableRowDriver } from './TableRowDriver';\n\n/** Reported sort state of a column, mirroring the `aria-sort` values MUI emits. */\nexport type TableSortDirection = 'ascending' | 'descending';\n\n// Body rows are the iterated items; the header row is addressed separately.\nconst headerRowLocator: PartLocator = byCssSelector('.MuiTableHead-root .MuiTableRow-root');\n\n/**\n * Body rows are located under `.MuiTableBody-root`, so header rows are never\n * mistaken for data rows.\n */\nexport const defaultTableDriverOption: ListComponentDriverSpecificOption<TableRowDriver> = {\n itemClass: TableRowDriver,\n itemLocator: byCssSelector('.MuiTableBody-root .MuiTableRow-root'),\n};\n\ntype TableDriverOption<ItemT extends TableRowDriver> = ListComponentDriverSpecificOption<ItemT> &\n Partial<IComponentDriverOption<any>>;\n\n// The nth header cell (1-based for nth-of-type); header cells are `<th>` siblings.\nfunction headerCellAt(columnIndex: number): PartLocator {\n return byCssSelector(`.MuiTableHead-root .MuiTableRow-root .MuiTableCell-root:nth-of-type(${columnIndex + 1})`);\n}\n\n/**\n * Driver for the Material UI v9 Table component.\n *\n * A {@link ListComponentDriver} over the data rows (`.MuiTableBody-root > .MuiTableRow-root`),\n * exposing per-row {@link TableRowDriver}s plus header reads and column sort state.\n * Locators key off MUI's structural classes (`MuiTableHead/Body/Row/Cell-root`),\n * which are stable across v9. Sort state is read from the header cell's `aria-sort`\n * and driven by clicking its `TableSortLabel`.\n * @see https://mui.com/material-ui/react-table/\n */\nexport class TableDriver<ItemT extends TableRowDriver = TableRowDriver> extends ListComponentDriver<ItemT> {\n constructor(locator: PartLocator, interactor: Interactor, option: Partial<TableDriverOption<ItemT>> = {}) {\n super(locator, interactor, {\n ...defaultTableDriverOption,\n ...option,\n } as TableDriverOption<ItemT>);\n }\n\n /**\n * The number of data (body) rows.\n */\n async getRowCount(): Promise<number> {\n return this.getItemCount();\n }\n\n /**\n * The data-row driver at the given zero-based index, or `null` when out of range.\n */\n async getRow(index: number): Promise<ItemT | null> {\n return this.getItemByIndex(index);\n }\n\n /**\n * The header row as a {@link TableRowDriver}, or `null` when the table has no header.\n */\n async getHeaderRow(): Promise<TableRowDriver | null> {\n const locator = locatorUtil.append(this.locator, headerRowLocator);\n if (!(await this.interactor.exists(locator))) {\n return null;\n }\n return new TableRowDriver(locator, this.interactor);\n }\n\n /**\n * The number of columns, derived from the header cell count (0 when no header).\n */\n async getColumnCount(): Promise<number> {\n const header = await this.getHeaderRow();\n return header == null ? 0 : header.getCellCount();\n }\n\n /**\n * The header cell texts, in column order (empty when no header).\n */\n async getHeaderTexts(): Promise<string[]> {\n const header = await this.getHeaderRow();\n return header == null ? [] : header.getCellTexts();\n }\n\n /**\n * The text of the data cell at the given row/column, or `undefined` when either\n * index is out of range.\n */\n async getCellText(rowIndex: number, columnIndex: number): Promise<Optional<string>> {\n const row = await this.getRow(rowIndex);\n if (row == null) {\n return undefined;\n }\n const cell = await row.getCell(columnIndex);\n if (cell == null) {\n return undefined;\n }\n return (await cell.getText())?.trim();\n }\n\n /**\n * The sort direction applied to the column at `columnIndex`, read from the header\n * cell's `aria-sort`, or `undefined` when that column is not the sorted one.\n */\n async getSortDirection(columnIndex: number): Promise<Optional<TableSortDirection>> {\n const cell = headerCellAt(columnIndex);\n const fullLocator = locatorUtil.append(this.locator, cell);\n if (!(await this.interactor.exists(fullLocator))) {\n return undefined;\n }\n const ariaSort = await this.interactor.getAttribute(fullLocator, 'aria-sort');\n return ariaSort === 'ascending' || ariaSort === 'descending' ? ariaSort : undefined;\n }\n\n /**\n * Toggle/apply sorting on the column at `columnIndex` by clicking its\n * `TableSortLabel`.\n * @returns `false` when the column has no sort control.\n */\n async sortByColumn(columnIndex: number): Promise<boolean> {\n const sortLabel = locatorUtil.append(\n this.locator,\n byCssSelector(\n `.MuiTableHead-root .MuiTableRow-root .MuiTableCell-root:nth-of-type(${columnIndex + 1}) .MuiTableSortLabel-root`\n )\n );\n if (!(await this.interactor.exists(sortLabel))) {\n return false;\n }\n await this.interactor.click(sortLabel);\n return true;\n }\n\n override get driverName(): string {\n return 'MuiV9TableDriver';\n }\n}\n","import { byAttribute, byCssSelector, ComponentDriver, locatorUtil, Optional, PartLocator } from '@atomic-testing/core';\n\nimport { SelectDriver } from './SelectDriver';\n\nconst previousButtonLocator = byAttribute('aria-label', 'Go to previous page');\nconst nextButtonLocator = byAttribute('aria-label', 'Go to next page');\nconst displayedRowsLocator = byCssSelector('.MuiTablePagination-displayedRows');\n\n/**\n * Driver for the Material UI v9 TablePagination component.\n *\n * TablePagination is a composite: a \"rows per page\" MUI Select (a portal-backed\n * `role=\"combobox\"`), an aria-labelled previous/next pair that disables at the\n * bounds, and a `.MuiTablePagination-displayedRows` label (\"1–5 of 13\"). The\n * rows-per-page control is delegated to {@link SelectDriver} rather than\n * reimplemented — the driver's own root contains exactly one combobox/input, so\n * SelectDriver scoped to that root resolves it unambiguously.\n * @see https://mui.com/material-ui/react-pagination/#table-pagination\n */\nexport class TablePaginationDriver extends ComponentDriver {\n // The driver root contains exactly one combobox/input, so a SelectDriver scoped\n // to it resolves the rows-per-page control unambiguously. Constructed on demand\n // (stateless) to avoid overriding the base constructor.\n private get rowsPerPageSelect(): SelectDriver {\n return new SelectDriver(this.locator, this.interactor);\n }\n\n /**\n * The current rows-per-page value (read from the select's hidden input), or\n * `-1` when it cannot be parsed.\n */\n async getRowsPerPage(): Promise<number> {\n const value = await this.rowsPerPageSelect.getValue();\n const parsed = Number.parseInt(value ?? '', 10);\n return Number.isNaN(parsed) ? -1 : parsed;\n }\n\n /**\n * Choose a rows-per-page value by opening the select and picking the option.\n * @returns `false` when no such option exists.\n */\n async setRowsPerPage(rowsPerPage: number): Promise<boolean> {\n return this.rowsPerPageSelect.setValue(String(rowsPerPage));\n }\n\n /**\n * The raw \"displayed rows\" label (e.g. \"1–5 of 13\"), or `undefined` when absent.\n * Returned verbatim because its exact format (separator, \"of\") is locale-defined.\n */\n async getDisplayedRowsText(): Promise<Optional<string>> {\n const locator = locatorUtil.append(this.locator, displayedRowsLocator);\n if (!(await this.interactor.exists(locator))) {\n return undefined;\n }\n return (await this.interactor.getText(locator))?.trim();\n }\n\n /** Whether the previous-page control is disabled (i.e. on the first page). */\n async isPreviousDisabled(): Promise<boolean> {\n return this.isNavDisabled(previousButtonLocator);\n }\n\n /** Whether the next-page control is disabled (i.e. on the last page). */\n async isNextDisabled(): Promise<boolean> {\n return this.isNavDisabled(nextButtonLocator);\n }\n\n /**\n * An absent control counts as disabled — both to stay consistent with\n * {@link clickNavButton} (which reports a no-op for a missing control) and\n * because Playwright's `isDisabled` throws on a zero-match locator rather than\n * returning false the way jsdom does.\n */\n private async isNavDisabled(navLocator: PartLocator): Promise<boolean> {\n const locator = locatorUtil.append(this.locator, navLocator);\n if (!(await this.interactor.exists(locator))) {\n return true;\n }\n return this.interactor.isDisabled(locator);\n }\n\n /**\n * Advance to the next page unless the control is disabled (last page).\n * @returns whether the click was performed.\n */\n async nextPage(): Promise<boolean> {\n return this.clickNavButton(nextButtonLocator);\n }\n\n /**\n * Go back to the previous page unless the control is disabled (first page).\n * @returns whether the click was performed.\n */\n async previousPage(): Promise<boolean> {\n return this.clickNavButton(previousButtonLocator);\n }\n\n private async clickNavButton(navLocator: PartLocator): Promise<boolean> {\n const locator = locatorUtil.append(this.locator, navLocator);\n if (!(await this.interactor.exists(locator)) || (await this.interactor.isDisabled(locator))) {\n return false;\n }\n await this.interactor.click(locator);\n return true;\n }\n\n override get driverName(): string {\n return 'MuiV9TablePaginationDriver';\n }\n}\n","import { HTMLButtonDriver } from '@atomic-testing/component-driver-html';\n\n/**\n * Driver for a single Material UI v9 Tab.\n *\n * A `<Tab>` renders as a `<button role=\"tab\">`; MUI marks the active one with\n * `aria-selected=\"true\"` and renders a real `disabled` button when disabled, so\n * selection and disabled state are read straight off the accessible attributes\n * (`isDisabled` is inherited from {@link HTMLButtonDriver}; `getText`/`click` from\n * the base `ComponentDriver`).\n *\n * Unlike a toggle button this is intentionally not an `IToggleDriver`: a tab can\n * be selected but not toggled off (selecting another tab deselects it), so only\n * `isSelected`/`select` are exposed.\n * @see https://mui.com/material-ui/react-tabs/\n */\nexport class TabDriver extends HTMLButtonDriver {\n /**\n * Whether this tab is the selected one, i.e. MUI set `aria-selected=\"true\"`.\n */\n async isSelected(): Promise<boolean> {\n const val = await this.interactor.getAttribute(this.locator, 'aria-selected');\n return val === 'true';\n }\n\n /**\n * Activate this tab by clicking it, unless it is already selected. A selected\n * tab cannot be toggled off, so this is a no-op when already active.\n */\n async select(): Promise<void> {\n if (!(await this.isSelected())) {\n await this.interactor.click(this.locator);\n }\n }\n\n override get driverName(): string {\n return 'MuiV9TabDriver';\n }\n}\n","import {\n byRole,\n IComponentDriverOption,\n Interactor,\n ListComponentDriver,\n ListComponentDriverSpecificOption,\n listHelper,\n Nullable,\n PartLocator,\n} from '@atomic-testing/core';\n\nimport { TabDriver } from './TabDriver';\n\n/**\n * Tabs are located by their accessible `role=\"tab\"` children rather than by MUI\n * class names, so the driver is resilient to MUI styling/version changes.\n */\nexport const defaultTabsDriverOption: ListComponentDriverSpecificOption<TabDriver> = {\n itemClass: TabDriver,\n itemLocator: byRole('tab'),\n};\n\ntype TabsDriverOption<ItemT extends TabDriver> = ListComponentDriverSpecificOption<ItemT> &\n Partial<IComponentDriverOption<any>>;\n\n/**\n * Driver for the Material UI v9 Tabs component.\n *\n * `<Tabs>` renders a `role=\"tablist\"` whose `role=\"tab\"` buttons carry the\n * selected (`aria-selected`) and disabled state. This driver is a\n * {@link ListComponentDriver} over those tabs, exposing both group-level helpers\n * (selected index/label, select by index/label) and per-tab {@link TabDriver}\n * instances via `getItems`/`getItemByIndex`/`getItemByLabel`.\n * @see https://mui.com/material-ui/react-tabs/\n */\nexport class TabsDriver<ItemT extends TabDriver = TabDriver> extends ListComponentDriver<ItemT> {\n constructor(locator: PartLocator, interactor: Interactor, option: Partial<TabsDriverOption<ItemT>> = {}) {\n // A tab group's item shape is fixed (role=\"tab\" buttons driven by TabDriver),\n // so the defaults are merged in rather than relying on a default parameter:\n // the test engine always passes an option object for a scene part, which would\n // otherwise shadow a default-valued parameter and leave itemLocator unset.\n super(locator, interactor, {\n ...defaultTabsDriverOption,\n ...option,\n } as TabsDriverOption<ItemT>);\n }\n\n /**\n * The visible label of every tab, in DOM order.\n */\n async getTabLabels(): Promise<string[]> {\n const labels: string[] = [];\n for await (const tab of listHelper.getListItemIterator(this, this.getItemLocator(), TabDriver)) {\n const text = await tab.getText();\n labels.push(text?.trim() ?? '');\n }\n return labels;\n }\n\n /**\n * The number of tabs in the group.\n */\n async getTabCount(): Promise<number> {\n return this.getItemCount();\n }\n\n /**\n * Zero-based index of the selected tab, or `-1` when no tab is selected\n * (e.g. `<Tabs value={false}>`).\n */\n async getSelectedIndex(): Promise<number> {\n let index = 0;\n for await (const tab of listHelper.getListItemIterator(this, this.getItemLocator(), TabDriver)) {\n if (await tab.isSelected()) {\n return index;\n }\n index++;\n }\n return -1;\n }\n\n /**\n * Label of the selected tab, or `null` when no tab is selected. Returns `null`\n * (not `undefined`) to match the sibling `SelectDriver.getSelectedLabel` contract.\n */\n async getSelectedLabel(): Promise<Nullable<string>> {\n for await (const tab of listHelper.getListItemIterator(this, this.getItemLocator(), TabDriver)) {\n if (await tab.isSelected()) {\n return (await tab.getText())?.trim() ?? null;\n }\n }\n return null;\n }\n\n /**\n * Select the tab at the given zero-based index.\n * @returns `false` when the index is out of range.\n */\n async selectByIndex(index: number): Promise<boolean> {\n const tab = await this.getItemByIndex(index);\n if (tab == null) {\n return false;\n }\n await tab.click();\n return true;\n }\n\n /**\n * Select the first tab whose visible label equals `label`.\n * @returns `false` when no tab matches.\n */\n async selectByLabel(label: string): Promise<boolean> {\n const tab = await this.getItemByLabel(label);\n if (tab == null) {\n return false;\n }\n await tab.click();\n return true;\n }\n\n /**\n * Whether the tab at the given index is disabled.\n * @returns `false` when the index is out of range.\n */\n async isTabDisabled(index: number): Promise<boolean> {\n const tab = await this.getItemByIndex(index);\n return tab == null ? false : tab.isDisabled();\n }\n\n override get driverName(): string {\n return 'MuiV9TabsDriver';\n }\n}\n","import { HTMLElementDriver, HTMLTextInputDriver } from '@atomic-testing/component-driver-html';\nimport {\n byCssSelector,\n byRole,\n byTagName,\n ComponentDriver,\n IComponentDriverOption,\n IInputDriver,\n Interactor,\n Optional,\n PartLocator,\n ScenePart,\n} from '@atomic-testing/core';\n\nimport { SelectDriver } from './SelectDriver';\n\nexport const parts = {\n label: {\n // In v9 the label is a direct child `.MuiInputLabel-root`: a `<label>` for the\n // text/multiline variants, but a `<div>` for the select variant (where the\n // control is a combobox associated via aria-labelledby, not a focusable input).\n // Matching the class instead of the `<label>` tag covers both.\n locator: byCssSelector('>.MuiInputLabel-root'),\n driver: HTMLElementDriver,\n },\n helperText: {\n locator: byCssSelector('>p'),\n driver: HTMLElementDriver,\n },\n singlelineInput: {\n locator: byCssSelector('input:not([aria-hidden])'),\n driver: HTMLTextInputDriver,\n },\n multilineInput: {\n locator: byCssSelector('textarea:not([aria-hidden])'),\n driver: HTMLTextInputDriver,\n },\n selectInput: {\n // Target the input wrapper specifically: in v9 the select variant's label is\n // also a direct child `<div>`, so a bare `>div` is ambiguous (it matches the\n // label first, breaking class reads like the readonly state). `.MuiInputBase-root`\n // pins it to the actual input root.\n locator: byCssSelector('>.MuiInputBase-root'),\n driver: SelectDriver,\n },\n // Used to detect the presence of select input\n richSelectInputDetect: {\n locator: byRole('combobox'),\n driver: HTMLElementDriver,\n },\n nativeSelectInputDetect: {\n locator: byTagName('SELECT'),\n driver: HTMLElementDriver,\n },\n} satisfies ScenePart;\n\ntype TextFieldInputType = 'singleLine' | 'multiline' | 'select';\n\n/**\n * A driver for the Material UI v9 TextField component with single line or multiline text input.\n */\nexport class TextFieldDriver extends ComponentDriver<typeof parts> implements IInputDriver<string | null> {\n constructor(locator: PartLocator, interactor: Interactor, option?: Partial<IComponentDriverOption>) {\n super(locator, interactor, {\n ...option,\n parts,\n });\n }\n\n private async getInputType(): Promise<TextFieldInputType> {\n const result = await Promise.all([\n this.parts.singlelineInput.exists(),\n this.parts.richSelectInputDetect.exists(),\n this.parts.nativeSelectInputDetect.exists(),\n this.parts.multilineInput.exists(),\n ]).then(([singlelineExists, richSelectExists, nativeSelectExists, multilineExists]) => {\n if (singlelineExists) {\n return 'singleLine';\n }\n if (richSelectExists || nativeSelectExists) {\n return 'select';\n }\n if (multilineExists) {\n return 'multiline';\n }\n\n throw new Error('Unable to determine input type in TextFieldInput');\n });\n\n return result;\n }\n\n async getValue(): Promise<string | null> {\n const inputType = await this.getInputType();\n switch (inputType) {\n case 'singleLine':\n return this.parts.singlelineInput.getValue();\n case 'select':\n return this.parts.selectInput.getValue();\n case 'multiline':\n return this.parts.multilineInput.getValue();\n }\n }\n\n async setValue(value: string | null): Promise<boolean> {\n const inputType = await this.getInputType();\n switch (inputType) {\n case 'singleLine':\n return this.parts.singlelineInput.setValue(value);\n case 'select':\n return this.parts.selectInput.setValue(value);\n case 'multiline':\n return this.parts.multilineInput.setValue(value);\n }\n }\n\n async getLabel(): Promise<Optional<string>> {\n return this.parts.label.getText();\n }\n\n async getHelperText(): Promise<Optional<string>> {\n const helperTextExists = await this.interactor.exists(this.parts.helperText.locator);\n if (helperTextExists) {\n return this.parts.helperText.getText();\n }\n }\n\n async isDisabled(): Promise<boolean> {\n const inputType = await this.getInputType();\n switch (inputType) {\n case 'singleLine':\n return this.parts.singlelineInput.isDisabled();\n case 'select':\n return this.parts.selectInput.isDisabled();\n case 'multiline':\n return this.parts.multilineInput.isDisabled();\n }\n }\n\n async isReadonly(): Promise<boolean> {\n const inputType = await this.getInputType();\n switch (inputType) {\n case 'singleLine':\n return this.parts.singlelineInput.isReadonly();\n case 'select':\n return this.interactor.hasCssClass(this.parts.selectInput.locator, 'MuiInputBase-readOnly');\n case 'multiline':\n return this.parts.multilineInput.isReadonly();\n }\n }\n\n get driverName(): string {\n return 'MuiV9TextFieldDriver';\n }\n}\n","import { IToggleDriver } from '@atomic-testing/core';\n\nimport { ButtonDriver } from './ButtonDriver';\n\nexport class ToggleButtonDriver extends ButtonDriver implements IToggleDriver {\n async isSelected(): Promise<boolean> {\n const val = await this.interactor.getAttribute(this.locator, 'aria-pressed');\n return val === 'true';\n }\n\n async setSelected(targetState: boolean): Promise<void> {\n const currentState = await this.isSelected();\n if (currentState !== targetState) {\n await this.interactor.click(this.locator);\n }\n }\n\n override get driverName() {\n return 'MuiV9ToggleButtonDriver';\n }\n}\n","import { byTagName, ComponentDriver, IInputDriver, listHelper, locatorUtil } from '@atomic-testing/core';\n\nimport { ToggleButtonDriver } from './ToggleButtonDriver';\n\nconst toggleButtonLocator = byTagName('button');\n\nexport class ToggleButtonGroupDriver extends ComponentDriver implements IInputDriver<readonly string[]> {\n protected itemLocator = locatorUtil.append(this.locator, toggleButtonLocator);\n /**\n * Get all the selected toggle buttons' values.\n * @returns\n */\n async getValue(): Promise<readonly string[]> {\n const result: string[] = [];\n for await (const itemDriver of listHelper.getListItemIterator(this, this.itemLocator, ToggleButtonDriver)) {\n const isSelected = await itemDriver.isSelected();\n if (isSelected) {\n const value = await itemDriver.getValue();\n if (value != null) {\n result.push(value);\n }\n }\n }\n return result;\n }\n\n /**\n * Toggle all the toggle buttons such that only those with value in the given array are selected.\n * @param value Always true\n * @returns\n */\n async setValue(value: readonly string[]): Promise<boolean> {\n const valueSet = new Set(value);\n for await (const itemDriver of listHelper.getListItemIterator(this, this.itemLocator, ToggleButtonDriver)) {\n const value = await itemDriver.getValue();\n await itemDriver.setSelected(valueSet.has(value!));\n }\n return true;\n }\n\n get driverName(): string {\n return 'MuiV9ToggleButtonGroupDriver';\n }\n}\n\n/**\n * A toggle button group driver that only allows a single selection.\n *\n * INTENTIONAL @ts-ignore comments below: This class intentionally narrows the return type\n * from `readonly string[]` to `string | null` for exclusive selection mode. TypeScript\n * correctly flags this as a type incompatibility because the subclass changes the interface\n * contract. However, this design is intentional as exclusive and multi-select toggle groups\n * have fundamentally different value semantics, and we want the type system to reflect\n * `string | null` for exclusive mode rather than forcing consumers to work with arrays.\n */\nexport class ExclusiveToggleButtonGroupDriver extends ToggleButtonGroupDriver implements IInputDriver<string | null> {\n // @ts-ignore - See class comment for explanation of intentional type narrowing\n async getValue(): Promise<string | null> {\n const values = await super.getValue();\n return values?.[0] ?? null;\n }\n\n // @ts-ignore - See class comment for explanation of intentional type narrowing\n async setValue(value: string | null): Promise<boolean> {\n if (value === null) {\n return super.setValue([]);\n } else {\n return super.setValue([value]);\n }\n }\n\n get driverName(): string {\n return 'MuiV9ExclusiveToggleButtonGroupDriver';\n }\n}\n","import { byRole, ComponentDriver, Optional, PartLocator } from '@atomic-testing/core';\n\n// MUI renders the tooltip into a portal outside this driver's subtree, so it is\n// addressed from the document root by its `role=\"tooltip\"`.\nconst tooltipLocator: PartLocator = byRole('tooltip', 'Root');\n\nconst defaultRevealTimeout = 250;\n\n/**\n * Driver for the Material UI v9 Tooltip component.\n *\n * The driver is rooted at the **trigger** element. MUI shows the tooltip on\n * hover/focus and renders it into a portal (a `role=\"tooltip\"` popper) outside the\n * trigger's subtree, so the text is read from the document root via\n * {@link tooltipLocator} after revealing it. The tooltip unmounts when not shown,\n * so presence of that element doubles as the visible state.\n *\n * Note: hover reveal depends on the tooltip's `enterDelay`; with a non-zero delay\n * the reveal is timer-bound. {@link getTitle} waits for the tooltip to appear.\n * @see https://mui.com/material-ui/react-tooltip/\n */\nexport class TooltipDriver extends ComponentDriver {\n /**\n * Reveal the tooltip by hovering its trigger, waiting until it is shown (or the\n * timeout elapses, e.g. when the trigger has no tooltip).\n */\n async show(timeoutMs: number = defaultRevealTimeout): Promise<void> {\n await this.interactor.hover(this.locator);\n await this.interactor.waitUntil({\n probeFn: () => this.isVisible(),\n terminateCondition: true,\n timeoutMs,\n });\n }\n\n /**\n * Hide the tooltip by moving the pointer off its trigger, waiting until it is gone.\n */\n async hide(timeoutMs: number = defaultRevealTimeout): Promise<void> {\n await this.interactor.mouseLeave(this.locator);\n await this.interactor.waitUntil({\n probeFn: () => this.isVisible(),\n terminateCondition: false,\n timeoutMs,\n });\n }\n\n /**\n * Whether a tooltip is currently shown.\n */\n async isVisible(): Promise<boolean> {\n if (!(await this.interactor.exists(tooltipLocator))) {\n return false;\n }\n return this.interactor.isVisible(tooltipLocator);\n }\n\n /**\n * Reveal the tooltip, read its text, then restore the un-hovered state. Returns\n * `undefined` when the trigger has no tooltip (none appears within the timeout).\n *\n * The hover is undone before returning so a subsequent read on a *different*\n * trigger isn't shadowed by this still-open tooltip: MUI renders all tooltips into\n * one portal and provides no per-trigger DOM link, and jsdom's synthetic hover does\n * not fire `mouseout` on the previously-hovered sibling.\n *\n * @param timeoutMs How long to wait for the tooltip to appear after hovering.\n */\n async getTitle(timeoutMs: number = defaultRevealTimeout): Promise<Optional<string>> {\n await this.show(timeoutMs);\n if (!(await this.interactor.exists(tooltipLocator))) {\n return undefined;\n }\n const text = (await this.interactor.getText(tooltipLocator))?.trim();\n await this.hide(timeoutMs);\n return text;\n }\n\n override get driverName(): string {\n return 'MuiV9TooltipDriver';\n }\n}\n"],"mappings":"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"}