@atomic-testing/component-driver-mui-v6
Version:
Atomic Testing Component driver to help drive Material UI V6 components
1,262 lines (1,235 loc) • 39.2 kB
JavaScript
//#region rolldown:runtime
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
key = keys[i];
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
get: ((k) => from[k]).bind(null, key),
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
});
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
value: mod,
enumerable: true
}) : target, mod));
//#endregion
const __atomic_testing_component_driver_html = __toESM(require("@atomic-testing/component-driver-html"));
const __atomic_testing_core = __toESM(require("@atomic-testing/core"));
//#region src/components/AccordionDriver.ts
const parts$13 = {
disclosure: {
locator: (0, __atomic_testing_core.byCssClass)("MuiAccordionSummary-root"),
driver: __atomic_testing_component_driver_html.HTMLElementDriver
},
summary: {
locator: (0, __atomic_testing_core.byCssClass)("MuiAccordionSummary-content"),
driver: __atomic_testing_component_driver_html.HTMLElementDriver
},
content: {
locator: (0, __atomic_testing_core.byRole)("region"),
driver: __atomic_testing_component_driver_html.HTMLElementDriver
}
};
/**
* Driver for Material UI v6 Accordion component.
* @see https://mui.com/material-ui/react-accordion/
*/
var AccordionDriver = class extends __atomic_testing_core.ComponentDriver {
constructor(locator, interactor, option) {
super(locator, interactor, {
...option,
parts: parts$13
});
}
/**
* Get the title/summary of the accordion.
* @returns The title/summary of the accordion.
*/
async getSummary() {
const title = await this.parts.summary.getText();
return title ?? null;
}
/**
* Whether the accordion is expanded.
* @returns True if the accordion is expanded, false if collapsed.
*/
async isExpanded() {
await this.enforcePartExistence("disclosure");
const expanded = await this.parts.disclosure.getAttribute("aria-expanded");
return expanded === "true";
}
/**
* Whether the accordion is disabled.
* @returns True if the accordion is disabled, false if enabled.
*/
async isDisabled() {
await this.enforcePartExistence("disclosure");
const disabled = await this.parts.disclosure.getAttribute("disabled");
return disabled != null;
}
/**
* Expand the accordion.
*/
async expand() {
const expanded = await this.isExpanded();
if (!expanded) {
await this.parts.disclosure.click();
await __atomic_testing_core.timingUtil.waitUntil({
probeFn: () => this.isExpanded(),
terminateCondition: true,
timeoutMs: 1e3
});
}
}
/**
* Collapse the accordion.
*/
async collapse() {
const expanded = await this.isExpanded();
if (expanded) {
await this.parts.disclosure.click();
await __atomic_testing_core.timingUtil.waitUntil({
probeFn: () => this.isExpanded(),
terminateCondition: false,
timeoutMs: 1e3
});
}
}
get driverName() {
return "MuiV6AccordionDriver";
}
};
//#endregion
//#region src/components/AlertDriver.ts
const parts$12 = {
title: {
locator: (0, __atomic_testing_core.byCssClass)("MuiAlertTitle-root"),
driver: __atomic_testing_component_driver_html.HTMLElementDriver
},
message: {
locator: (0, __atomic_testing_core.byCssClass)("MuiAlert-message"),
driver: __atomic_testing_component_driver_html.HTMLElementDriver
}
};
const alertSeverityEvaluators = [
{
value: "error",
pattern: /MuiAlert-.*Error/
},
{
value: "warning",
pattern: /MuiAlert-.*Warning/
},
{
value: "info",
pattern: /MuiAlert-.*Info/
},
{
value: "success",
pattern: /MuiAlert-.*Success/
}
];
/**
* Driver for Material UI v6 Alert component.
* @see https://mui.com/material-ui/react-alert/
*/
var AlertDriver = class extends __atomic_testing_core.ContainerDriver {
constructor(locator, interactor, option) {
super(locator, interactor, {
...option,
parts: parts$12,
content: option?.content ?? {}
});
}
async getTitle() {
const title = await this.parts.title.getText();
return title ?? null;
}
async getMessage() {
const message = await this.parts.message.getText();
return message ?? null;
}
async getSeverity() {
const cssClassString = await this.interactor.getAttribute(this.locator, "class");
if (cssClassString != null) {
const cssClasses = cssClassString.split(/\s+/);
for (const cssClassName of cssClasses) for (const evaluator of alertSeverityEvaluators) if (evaluator.pattern.test(cssClassName)) return evaluator.value;
}
return null;
}
get driverName() {
return "MuiV6AlertDriver";
}
};
//#endregion
//#region src/components/AutoCompleteDriver.ts
const parts$11 = {
input: {
locator: (0, __atomic_testing_core.byRole)("combobox"),
driver: __atomic_testing_component_driver_html.HTMLTextInputDriver
},
dropdown: {
locator: (0, __atomic_testing_core.byLinkedElement)("Root").onLinkedElement((0, __atomic_testing_core.byRole)("combobox")).extractAttribute("aria-controls").toMatchMyAttribute("id"),
driver: __atomic_testing_component_driver_html.HTMLElementDriver
}
};
const optionLocator$1 = (0, __atomic_testing_core.byRole)("option");
const defaultAutoCompleteDriverOption = { matchType: "exact" };
var AutoCompleteDriver = class extends __atomic_testing_core.ComponentDriver {
_option = {};
constructor(locator, interactor, option) {
super(locator, interactor, {
...option,
parts: parts$11
});
this._option = option ?? {};
}
/**
* Get the display of the autocomplete
*/
async getValue() {
const value = await this.parts.input.getValue();
return value ?? null;
}
/**
* Set the value of the autocomplete, how selection happens
* depends on the option assigned to AutoCompleteDriver
* By default, when the option has matchType set to exact, only option with matching text would be selected
* When the option has matchType set to first-available, the first option would be selected regardless of the text
*
* Option of auto complete can be set at the time of part definition, for example
* ```
* {
* myAutoComplete: {
* locator: byCssSelector('my-auto-complete'),
* driver: AutoCompleteDriver,
* option: {
* matchType: 'first-available',
* },
* },
* }
* ```
*
* @param value
* @returns
*/
async setValue(value) {
await this.parts.input.setValue(value ?? "");
if (value === null) return true;
const option = __atomic_testing_core.locatorUtil.append(this.parts.dropdown.locator, optionLocator$1);
let index = 0;
const matchType = this._option?.matchType ?? defaultAutoCompleteDriverOption.matchType;
for await (const optionDriver of __atomic_testing_core.listHelper.getListItemIterator(this, option, __atomic_testing_component_driver_html.HTMLButtonDriver)) {
const optionValue = await optionDriver.getText();
const isMatched = matchType === "exact" && optionValue?.trim() === value || matchType === "first-available" && index === 0;
if (isMatched) {
await optionDriver.click();
return true;
}
index++;
}
return false;
}
async isDisabled() {
return this.parts.input.isDisabled();
}
async isReadonly() {
return this.parts.input.isReadonly();
}
get driverName() {
return "MuiV6AutoCompleteDriver";
}
};
//#endregion
//#region src/components/BadgeDriver.ts
const parts$10 = { contentDisplay: {
locator: (0, __atomic_testing_core.byCssClass)("MuiBadge-badge"),
driver: __atomic_testing_component_driver_html.HTMLElementDriver
} };
/**
* Driver for Material UI v6 Badge component.
* @see https://mui.com/material-ui/react-badge/
*/
var BadgeDriver = class extends __atomic_testing_core.ComponentDriver {
constructor(locator, interactor, option) {
super(locator, interactor, {
...option,
parts: parts$10
});
}
/**
* Get the content of the badge.
* @returns The content of the badge.
*/
async getContent() {
await this.enforcePartExistence("contentDisplay");
const content = await this.parts.contentDisplay.getText();
return content ?? null;
}
get driverName() {
return "MuiV6BadgeDriver";
}
};
//#endregion
//#region src/components/ButtonDriver.ts
/**
* Driver for Material UI v6 Button component.
* @see https://mui.com/material-ui/react-button/
*/
var ButtonDriver = class extends __atomic_testing_component_driver_html.HTMLButtonDriver {
async getValue() {
const val = await this.interactor.getAttribute(this.locator, "value");
return val ?? null;
}
get driverName() {
return "MuiV6ButtonDriver";
}
};
//#endregion
//#region src/components/CheckboxDriver.ts
const checkboxPart = { checkbox: {
locator: (0, __atomic_testing_core.byTagName)("input"),
driver: __atomic_testing_component_driver_html.HTMLCheckboxDriver
} };
var CheckboxDriver = class extends __atomic_testing_core.ComponentDriver {
constructor(locator, interactor, option) {
super(locator, interactor, {
...option,
parts: checkboxPart
});
}
isSelected() {
return this.parts.checkbox.isSelected();
}
async setSelected(selected) {
const isIndeterminate = await this.isIndeterminate();
if (isIndeterminate && selected === false) await this.parts.checkbox.setSelected(true);
await this.parts.checkbox.setSelected(selected);
}
getValue() {
return this.parts.checkbox.getValue();
}
async isIndeterminate() {
const indeterminate = await this.interactor.getAttribute(this.parts.checkbox.locator, "data-indeterminate");
return indeterminate === "true";
}
isDisabled() {
return this.parts.checkbox.isDisabled();
}
isReadonly() {
return this.parts.checkbox.isReadonly();
}
get driverName() {
return "MuiV6CheckboxDriver";
}
};
//#endregion
//#region src/components/ChipDriver.ts
const parts$9 = {
contentDisplay: {
locator: (0, __atomic_testing_core.byCssClass)("MuiChip-label"),
driver: __atomic_testing_component_driver_html.HTMLElementDriver
},
removeButton: {
locator: (0, __atomic_testing_core.byDataTestId)("CancelIcon"),
driver: __atomic_testing_component_driver_html.HTMLElementDriver
}
};
/**
* Driver for Material UI v6 Chip component.
* @see https://mui.com/material-ui/react-chip/
*/
var ChipDriver = class extends __atomic_testing_core.ComponentDriver {
constructor(locator, interactor, option) {
super(locator, interactor, {
...option,
parts: parts$9
});
}
/**
* Get the label content of the chip.
* @returns The label text content of the chip.
*/
async getLabel() {
await this.enforcePartExistence("contentDisplay");
const content = await this.parts.contentDisplay.getText();
return content ?? null;
}
async clickRemove() {
await this.enforcePartExistence("removeButton");
await this.parts.removeButton.click();
}
get driverName() {
return "MuiV6ChipDriver";
}
};
//#endregion
//#region src/components/DialogDriver.ts
const parts$8 = {
title: {
locator: (0, __atomic_testing_core.byCssClass)("MuiDialogTitle-root"),
driver: __atomic_testing_component_driver_html.HTMLElementDriver
},
dialogContainer: {
locator: (0, __atomic_testing_core.byRole)("presentation"),
driver: __atomic_testing_component_driver_html.HTMLElementDriver
}
};
const dialogRootLocator = (0, __atomic_testing_core.byRole)("presentation", "Root");
const defaultTransitionDuration = 250;
var DialogDriver = class extends __atomic_testing_core.ContainerDriver {
constructor(locator, interactor, option) {
super(locator, interactor, {
...option,
parts: parts$8,
content: option?.content ?? {}
});
}
overriddenParentLocator() {
return dialogRootLocator;
}
overrideLocatorRelativePosition() {
return "Same";
}
async getTitle() {
await this.enforcePartExistence("title");
const title = await this.parts.title.getText();
return title ?? null;
}
/**
* Wait for dialog to open
* @param timeoutMs
* @returns true open has performed successfully
*/
async waitForOpen(timeoutMs = defaultTransitionDuration) {
const isOpened = await this.interactor.waitUntil({
probeFn: () => this.isOpen(),
terminateCondition: true,
timeoutMs
});
return isOpened === true;
}
/**
* Wait for dialog to close
* @param timeoutMs
* @returns true open has performed successfully
*/
async waitForClose(timeoutMs = defaultTransitionDuration) {
const isOpened = await this.interactor.waitUntil({
probeFn: () => this.isOpen(),
terminateCondition: false,
timeoutMs
});
return isOpened === false;
}
/**
* Check if the dialog box is open. Caution, because of animation, upon an open/close action is performed
* use waitForOpen() or waitForClose() before using isOpen() would result a more accurate open state of the dialog
* @returns true if dialog box is open
*/
async isOpen() {
const exists = await this.exists();
if (!exists) return false;
const isVisible = await this.interactor.isVisible(this.parts.dialogContainer.locator);
return isVisible;
}
get driverName() {
return "MuiV6DialogDriver";
}
};
//#endregion
//#region src/components/FabDriver.ts
/**
* Driver for Material UI v6 Floating Action Button component.
* @see https://mui.com/material-ui/react-floating-action-button/
*/
var FabDriver = class extends ButtonDriver {
get driverName() {
return "MuiV6FabDriver";
}
};
//#endregion
//#region src/components/InputDriver.ts
const parts$7 = {
singlelineInput: {
locator: (0, __atomic_testing_core.byCssSelector)("input:not([aria-hidden])"),
driver: __atomic_testing_component_driver_html.HTMLTextInputDriver
},
multilineInput: {
locator: (0, __atomic_testing_core.byCssSelector)("textarea:not([aria-hidden])"),
driver: __atomic_testing_component_driver_html.HTMLTextInputDriver
}
};
/**
* A driver for the Material UI v6 Input, FilledInput, OutlinedInput, and StandardInput components.
*/
var InputDriver = class extends __atomic_testing_core.ComponentDriver {
constructor(locator, interactor, option) {
super(locator, interactor, {
...option,
parts: parts$7
});
}
async getInputType() {
const textInputExists = await this.interactor.exists(this.parts.singlelineInput.locator);
if (textInputExists) return "singleLine";
const multilineExists = await this.interactor.exists(this.parts.multilineInput.locator);
if (multilineExists) return "multiline";
throw new Error("Unable to determine input type in TextFieldInput");
}
/**
* Retrieve the current value of the input element, handling both single line
* and multiline configurations.
*/
async getValue() {
const inputType = await this.getInputType();
switch (inputType) {
case "singleLine": return this.parts.singlelineInput.getValue();
case "multiline": return this.parts.multilineInput.getValue();
}
}
/**
* Set the value of the underlying input element.
*
* @param value The text to assign to the input.
*/
async setValue(value) {
const inputType = await this.getInputType();
switch (inputType) {
case "singleLine": return this.parts.singlelineInput.setValue(value);
case "multiline": return this.parts.multilineInput.setValue(value);
}
}
/**
* Determine whether the input element is disabled.
*/
async isDisabled() {
const inputType = await this.getInputType();
switch (inputType) {
case "singleLine": return this.parts.singlelineInput.isDisabled();
case "multiline": return this.parts.multilineInput.isDisabled();
}
}
/**
* Determine whether the input element is read only.
*/
async isReadonly() {
const inputType = await this.getInputType();
switch (inputType) {
case "singleLine": return this.parts.singlelineInput.isReadonly();
case "multiline": return this.parts.multilineInput.isReadonly();
}
}
/**
* Identifier for this driver.
*/
get driverName() {
return "MuiV6InputDriver";
}
};
//#endregion
//#region src/errors/MenuItemDisabledError.ts
const MenuItemDisabledErrorId = "MenuItemDisabledError";
function getErrorMessage$1(label) {
return `The menu item with label: ${label} is disabled`;
}
var MenuItemDisabledError = class extends __atomic_testing_core.ErrorBase {
constructor(label, driver) {
super(getErrorMessage$1(label), driver);
this.label = label;
this.driver = driver;
this.name = MenuItemDisabledErrorId;
}
};
//#endregion
//#region src/components/ListItemDriver.ts
/**
* @internal
*/
var ListItemDriver = class extends __atomic_testing_core.ComponentDriver {
async label() {
const label = await this.getText();
return label?.trim() || null;
}
async isSelected() {
return await this.interactor.hasCssClass(this.locator, "Mui-selected");
}
async isDisabled() {
const disabledVal = await this.interactor.getAttribute(this.locator, "aria-disabled");
return disabledVal === "true";
}
async click() {
if (await this.isDisabled()) {
const label = await this.label();
throw new MenuItemDisabledError(label ?? "", this);
}
await this.interactor.click(this.locator);
}
get driverName() {
return "MuiV6ListItemDriver";
}
};
//#endregion
//#region src/components/ListDriver.ts
const defaultListDriverOption = {
itemClass: ListItemDriver,
itemLocator: (0, __atomic_testing_core.byRole)("option")
};
var ListDriver = class extends __atomic_testing_core.ListComponentDriver {
constructor(locator, interactor, option = defaultListDriverOption) {
super(locator, interactor, option);
}
async getSelected() {
for await (const item of __atomic_testing_core.listHelper.getListItemIterator(this, this.getItemLocator(), ListItemDriver)) if (await item.isSelected()) return item;
return null;
}
get driverName() {
return "MuiV6ListDriver";
}
};
//#endregion
//#region src/errors/MenuItemNotFoundError.ts
const MenuItemNotFoundErrorId = "MenuItemNotFoundError";
function getErrorMessage(label) {
return `Cannot find menu item with label: ${label}`;
}
var MenuItemNotFoundError = class extends __atomic_testing_core.ErrorBase {
constructor(label, driver) {
super(getErrorMessage(label), driver);
this.label = label;
this.driver = driver;
this.name = MenuItemNotFoundErrorId;
}
};
//#endregion
//#region src/components/MenuItemDriver.ts
/**
* @internal
*/
var MenuItemDriver = class extends ListItemDriver {
async value() {
const value = await this.interactor.getAttribute(this.locator, "data-value");
return value ?? null;
}
get driverName() {
return "MuiV6MenuItemDriver";
}
};
//#endregion
//#region src/components/MenuDriver.ts
const parts$6 = { menu: {
locator: (0, __atomic_testing_core.byRole)("menu"),
driver: __atomic_testing_component_driver_html.HTMLElementDriver
} };
const menuRootLocator = (0, __atomic_testing_core.byRole)("presentation", "Root");
const menuItemLocator = (0, __atomic_testing_core.byRole)("menuitem");
var MenuDriver = class extends __atomic_testing_core.ComponentDriver {
constructor(locator, interactor, option) {
super(locator, interactor, {
...option,
parts: parts$6
});
}
overriddenParentLocator() {
return menuRootLocator;
}
overrideLocatorRelativePosition() {
return "Same";
}
async getMenuItemByLabel(label) {
for await (const item of __atomic_testing_core.listHelper.getListItemIterator(this, menuItemLocator, MenuItemDriver)) {
const itemLabel = await item.label();
if (itemLabel === label) return item;
}
return null;
}
async selectByLabel(label) {
const item = await this.getMenuItemByLabel(label);
if (item) await item.click();
else throw new MenuItemNotFoundError(label, this);
}
get driverName() {
return "MuiV6MenuDriver";
}
};
//#endregion
//#region src/components/ProgressDriver.ts
const parts$5 = { choices: {
locator: (0, __atomic_testing_core.byInputType)("radio"),
driver: __atomic_testing_component_driver_html.HTMLRadioButtonGroupDriver
} };
var ProgressDriver = class extends __atomic_testing_core.ComponentDriver {
constructor(locator, interactor, option) {
super(locator, interactor, {
...option,
parts: parts$5
});
}
async getValue() {
const rawValue = await this.getAttribute("aria-valuenow");
const numValue = Number(rawValue);
if (rawValue == null || isNaN(numValue)) return null;
return Number(rawValue);
}
async getType() {
const cssClasses = await this.getAttribute("class");
if (cssClasses?.includes("MuiCircularProgress-root")) return "circular";
return "linear";
}
async isDeterminate() {
const val = await this.getValue();
return val != null;
}
async setValue(value) {
const currentValue = await this.getValue();
if (value === currentValue) return true;
const valueToClick = value == null ? currentValue : value;
const targetLocator = __atomic_testing_core.locatorUtil.append(this.parts.choices.locator, (0, __atomic_testing_core.byValue)(valueToClick.toString(), "Same"));
const targetExists = await this.interactor.exists(targetLocator);
if (targetExists) {
const id = await this.interactor.getAttribute(targetLocator, "id");
const labelLocator = __atomic_testing_core.locatorUtil.append(this.locator, (0, __atomic_testing_core.byCssSelector)(`label[for="${id}"]`));
await this.interactor.click(labelLocator);
}
return targetExists;
}
get driverName() {
return "MuiV6ProgressDriver";
}
};
//#endregion
//#region src/components/RatingDriver.ts
const parts$4 = { choices: {
locator: (0, __atomic_testing_core.byInputType)("radio"),
driver: __atomic_testing_component_driver_html.HTMLRadioButtonGroupDriver
} };
var RatingDriver = class extends __atomic_testing_core.ComponentDriver {
constructor(locator, interactor, option) {
super(locator, interactor, {
...option,
parts: parts$4
});
}
async getValue() {
await this.enforcePartExistence("choices");
const value = await this.parts.choices.getValue();
if (value == null) return null;
return parseFloat(value);
}
async setValue(value) {
const currentValue = await this.getValue();
if (value === currentValue) return true;
const valueToClick = value == null ? currentValue : value;
const targetLocator = __atomic_testing_core.locatorUtil.append(this.parts.choices.locator, (0, __atomic_testing_core.byValue)(valueToClick.toString(), "Same"));
const targetExists = await this.interactor.exists(targetLocator);
if (targetExists) {
const id = await this.interactor.getAttribute(targetLocator, "id");
const labelLocator = __atomic_testing_core.locatorUtil.append(this.locator, (0, __atomic_testing_core.byCssSelector)(`label[for="${id}"]`));
await this.interactor.click(labelLocator);
}
return targetExists;
}
get driverName() {
return "MuiV6RatingDriver";
}
};
//#endregion
//#region src/components/SelectDriver.ts
const selectPart = {
trigger: {
locator: (0, __atomic_testing_core.byRole)("combobox"),
driver: __atomic_testing_component_driver_html.HTMLButtonDriver
},
dropdown: {
locator: (0, __atomic_testing_core.byCssSelector)("[role=presentation] [role=listbox]", "Root"),
driver: __atomic_testing_component_driver_html.HTMLElementDriver
},
input: {
locator: (0, __atomic_testing_core.byTagName)("input"),
driver: __atomic_testing_component_driver_html.HTMLTextInputDriver
},
nativeSelect: {
locator: (0, __atomic_testing_core.byTagName)("select"),
driver: __atomic_testing_component_driver_html.HTMLSelectDriver
}
};
const optionLocator = (0, __atomic_testing_core.byRole)("option");
var SelectDriver = class extends __atomic_testing_core.ComponentDriver {
constructor(locator, interactor, option) {
super(locator, interactor, {
...option,
parts: selectPart
});
}
async isNative() {
const nativeSelectExists = await this.interactor.exists(this.parts.nativeSelect.locator);
return Promise.resolve(nativeSelectExists);
}
async getValue() {
const isNative = await this.isNative();
if (isNative) {
const val = await this.parts.nativeSelect.getValue();
return val;
}
await this.enforcePartExistence("input");
const value = await this.parts.input.getValue();
return value ?? null;
}
async setValue(value) {
let success = false;
const isNative = await this.isNative();
if (isNative) {
success = await this.parts.nativeSelect.setValue(value);
return success;
}
await this.openDropdown();
await this.enforcePartExistence("dropdown");
const optionSelector = (0, __atomic_testing_core.byAttribute)("data-value", value);
const optionLocator$2 = __atomic_testing_core.locatorUtil.append(this.parts.dropdown.locator, optionSelector);
const optionExists = await this.interactor.exists(optionLocator$2);
if (optionExists) {
await this.interactor.click(optionLocator$2);
success = true;
}
return success;
}
/**
* Select menu item by its label, if it exists
* Limitation, this method will not work if the dropdown is a native select.
* @param label
* @returns
*/
async getMenuItemByLabel(label, option) {
if (!option?.skipDropdownCheck) await this.openDropdown();
for await (const item of __atomic_testing_core.listHelper.getListItemIterator(this, optionLocator, MenuItemDriver)) {
const itemLabel = await item.label();
if (itemLabel === label) return item;
}
return null;
}
/**
* Selects an option by its label
* @param label
* @returns
*/
async selectByLabel(label) {
const isNative = await this.isNative();
if (isNative) {
await this.parts.nativeSelect.selectByLabel(label);
return;
}
await this.enforcePartExistence("trigger");
await this.parts.trigger.click();
await this.enforcePartExistence("dropdown");
const item = await this.getMenuItemByLabel(label, { skipDropdownCheck: true });
if (item) await item.click();
else throw new MenuItemNotFoundError(label, this);
}
async getSelectedLabel() {
const isNative = await this.isNative();
if (isNative) return await this.parts.nativeSelect.getSelectedLabel();
await this.enforcePartExistence("trigger");
const label = await this.parts.trigger.getText();
return label ?? null;
}
async exists() {
const triggerExists = await this.interactor.exists(this.parts.trigger.locator);
if (triggerExists) return true;
const nativeExists = await this.interactor.exists(this.parts.nativeSelect.locator);
return nativeExists;
}
/**
* 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
* @returns For native dropdown it is always true. For custom dropdown, it is true if the dropdown is open.
*/
async isDropdownOpen() {
const isNative = await this.isNative();
if (isNative) return true;
else return this.parts.dropdown.exists();
}
async openDropdown() {
const isOpen = await this.isDropdownOpen();
if (isOpen) return;
await this.parts.trigger.click();
}
async closeDropdown() {
const isOpen = await this.isDropdownOpen();
if (!isOpen) return;
await this.parts.trigger.click();
}
async isDisabled() {
const isNative = await this.isNative();
if (isNative) return this.parts.nativeSelect.isDisabled();
else {
await this.enforcePartExistence("trigger");
const isDisabled = await this.interactor.getAttribute(this.parts.trigger.locator, "aria-disabled");
return isDisabled === "true";
}
}
async isReadonly() {
const isNative = await this.isNative();
if (isNative) return this.parts.nativeSelect.isReadonly();
else return false;
}
get driverName() {
return "MuiV6SelectDriver";
}
};
//#endregion
//#region src/components/SliderDriver.ts
const parts$3 = { input: {
locator: (0, __atomic_testing_core.byCssSelector)("input[type=\"range\"][data-index=\"0\"]"),
driver: __atomic_testing_component_driver_html.HTMLTextInputDriver
} };
var SliderDriver = class extends __atomic_testing_core.ComponentDriver {
constructor(locator, interactor, option) {
super(locator, interactor, {
...option,
parts: parts$3
});
}
/**
* Return the first occurrence of the Slider input
* @returns
*/
async getValue() {
const values = await this.getRangeValues(1);
return values[0];
}
/**
* Set slider's range value. Do not use as it will throw an error
* @param values
* @see https://github.com/atomic-testing/atomic-testing/issues/73
*/
async setValue(value) {
const success = await this.setRangeValues([value]);
return success;
}
async getRangeValues(count) {
await this.enforcePartExistence("input");
const result = [];
let index = 0;
let done = false;
while (!done) {
const locator = __atomic_testing_core.locatorUtil.append(this.locator, this.getInputLocator(index));
const exists = await this.interactor.exists(locator);
if (exists) {
index++;
done = count != null && index >= count;
const value = await this.interactor.getAttribute(locator, "value");
result.push(parseFloat(value));
} else done = true;
}
return result;
}
getInputLocator(index) {
return (0, __atomic_testing_core.byCssSelector)(`input[type="range"][data-index="${index}"]`);
}
/**
* Set slider's range values. Do not use as it will throw an error
* @param values
* @see https://github.com/atomic-testing/atomic-testing/issues/73
*/
async setRangeValues(_values) {
await this.enforcePartExistence("input");
throw new Error("setRangeValue is not supported.");
}
async isDisabled() {
await this.enforcePartExistence("input");
const disabled = await this.parts.input.isDisabled();
return disabled;
}
get driverName() {
return "MuiV6SliderDriver";
}
};
//#endregion
//#region src/components/SnackbarDriver.ts
const parts$2 = {
contentDisplay: {
locator: (0, __atomic_testing_core.byCssClass)("MuiSnackbarContent-message"),
driver: __atomic_testing_component_driver_html.HTMLElementDriver
},
actionArea: {
locator: (0, __atomic_testing_core.byCssClass)("MuiSnackbarContent-action"),
driver: __atomic_testing_component_driver_html.HTMLElementDriver
}
};
/**
* Driver for Material UI v6 Snackbar component.
* @see https://mui.com/material-ui/react-snackbar/
*/
var SnackbarDriver = class extends __atomic_testing_core.ComponentDriver {
constructor(locator, interactor, option) {
super(locator, interactor, {
...option,
parts: parts$2
});
}
/**
* Get the label content of the snackbar.
* @returns The label text content of the snackbar.
*/
async getLabel() {
await this.enforcePartExistence("contentDisplay");
const content = await this.parts.contentDisplay.getText();
return content ?? null;
}
/**
* Get a driver instance of a component in the action area of the snackbar.
* @param locator
* @param driverClass
* @returns
*/
async getActionComponent(locator, driverClass) {
await this.enforcePartExistence("actionArea");
const componentLocator = __atomic_testing_core.locatorUtil.append(this.parts.actionArea.locator, locator);
const exists = await this.interactor.exists(componentLocator);
if (exists) return new driverClass(componentLocator, this.interactor, this.commutableOption);
return null;
}
get driverName() {
return "MuiV6SnackbarDriver";
}
};
//#endregion
//#region src/components/SwitchDriver.ts
const parts$1 = { input: {
locator: (0, __atomic_testing_core.byAttribute)("type", "checkbox"),
driver: __atomic_testing_component_driver_html.HTMLCheckboxDriver
} };
var SwitchDriver = class extends __atomic_testing_core.ComponentDriver {
constructor(locator, interactor, option) {
super(locator, interactor, {
...option,
parts: parts$1
});
}
async exists() {
return this.interactor.exists(this.parts.input.locator);
}
async isSelected() {
await this.enforcePartExistence("input");
return this.parts.input.isSelected();
}
async setSelected(selected) {
await this.enforcePartExistence("input");
await this.parts.input.setSelected(selected);
}
async getValue() {
await this.enforcePartExistence("input");
return this.parts.input.getValue();
}
async isDisabled() {
await this.enforcePartExistence("input");
return this.parts.input.isDisabled();
}
async isReadonly() {
return Promise.resolve(false);
}
get driverName() {
return "MuiV6SwitchDriver";
}
};
//#endregion
//#region src/components/TextFieldDriver.ts
const parts = {
label: {
locator: (0, __atomic_testing_core.byCssSelector)(">label"),
driver: __atomic_testing_component_driver_html.HTMLElementDriver
},
helperText: {
locator: (0, __atomic_testing_core.byCssSelector)(">p"),
driver: __atomic_testing_component_driver_html.HTMLElementDriver
},
singlelineInput: {
locator: (0, __atomic_testing_core.byCssSelector)("input:not([aria-hidden])"),
driver: __atomic_testing_component_driver_html.HTMLTextInputDriver
},
multilineInput: {
locator: (0, __atomic_testing_core.byCssSelector)("textarea:not([aria-hidden])"),
driver: __atomic_testing_component_driver_html.HTMLTextInputDriver
},
selectInput: {
locator: (0, __atomic_testing_core.byCssSelector)(">div"),
driver: SelectDriver
},
richSelectInputDetect: {
locator: (0, __atomic_testing_core.byRole)("combobox"),
driver: __atomic_testing_component_driver_html.HTMLElementDriver
},
nativeSelectInputDetect: {
locator: (0, __atomic_testing_core.byTagName)("SELECT"),
driver: __atomic_testing_component_driver_html.HTMLElementDriver
}
};
/**
* A driver for the Material UI v6 TextField component with single line or multiline text input.
*/
var TextFieldDriver = class extends __atomic_testing_core.ComponentDriver {
constructor(locator, interactor, option) {
super(locator, interactor, {
...option,
parts
});
}
async getInputType() {
const result = await Promise.all([
this.parts.singlelineInput.exists(),
this.parts.richSelectInputDetect.exists(),
this.parts.nativeSelectInputDetect.exists(),
this.parts.multilineInput.exists()
]).then(([singlelineExists, richSelectExists, nativeSelectExists, multilineExists]) => {
if (singlelineExists) return "singleLine";
if (richSelectExists || nativeSelectExists) return "select";
if (multilineExists) return "multiline";
throw new Error("Unable to determine input type in TextFieldInput");
});
return result;
}
async getValue() {
const inputType = await this.getInputType();
switch (inputType) {
case "singleLine": return this.parts.singlelineInput.getValue();
case "select": return this.parts.selectInput.getValue();
case "multiline": return this.parts.multilineInput.getValue();
}
}
async setValue(value) {
const inputType = await this.getInputType();
switch (inputType) {
case "singleLine": return this.parts.singlelineInput.setValue(value);
case "select": return this.parts.selectInput.setValue(value);
case "multiline": return this.parts.multilineInput.setValue(value);
}
}
async getLabel() {
return this.parts.label.getText();
}
async getHelperText() {
const helperTextExists = await this.interactor.exists(this.parts.helperText.locator);
if (helperTextExists) return this.parts.helperText.getText();
}
async isDisabled() {
const inputType = await this.getInputType();
switch (inputType) {
case "singleLine": return this.parts.singlelineInput.isDisabled();
case "select": return this.parts.selectInput.isDisabled();
case "multiline": return this.parts.multilineInput.isDisabled();
}
}
async isReadonly() {
const inputType = await this.getInputType();
switch (inputType) {
case "singleLine": return this.parts.singlelineInput.isReadonly();
case "select": return this.interactor.hasCssClass(this.parts.selectInput.locator, "MuiInputBase-readOnly");
case "multiline": return this.parts.multilineInput.isReadonly();
}
}
get driverName() {
return "MuiV6TextFieldDriver";
}
};
//#endregion
//#region src/components/ToggleButtonDriver.ts
var ToggleButtonDriver = class extends ButtonDriver {
async isSelected() {
const val = await this.interactor.getAttribute(this.locator, "aria-pressed");
return val === "true";
}
async setSelected(targetState) {
const currentState = await this.isSelected();
if (currentState !== targetState) await this.interactor.click(this.locator);
}
get driverName() {
return "MuiV6ToggleButtonDriver";
}
};
//#endregion
//#region src/components/ToggleButtonGroupDriver.ts
const toggleButtonLocator = (0, __atomic_testing_core.byTagName)("button");
var ToggleButtonGroupDriver = class extends __atomic_testing_core.ComponentDriver {
itemLocator = __atomic_testing_core.locatorUtil.append(this.locator, toggleButtonLocator);
/**
* Get all the selected toggle buttons' values.
* @returns
*/
async getValue() {
const result = [];
for await (const itemDriver of __atomic_testing_core.listHelper.getListItemIterator(this, this.itemLocator, ToggleButtonDriver)) {
const isSelected = await itemDriver.isSelected();
if (isSelected) {
const value = await itemDriver.getValue();
if (value != null) result.push(value);
}
}
return result;
}
/**
* Toggle all the toggle buttons such that only those with value in the given array are selected.
* @param value Always true
* @returns
*/
async setValue(value) {
const valueSet = new Set(value);
for await (const itemDriver of __atomic_testing_core.listHelper.getListItemIterator(this, this.itemLocator, ToggleButtonDriver)) {
const value$1 = await itemDriver.getValue();
await itemDriver.setSelected(valueSet.has(value$1));
}
return true;
}
get driverName() {
return "MuiV6ToggleButtonGroupDriver";
}
};
var ExclusiveToggleButtonGroupDriver = class extends ToggleButtonGroupDriver {
async getValue() {
const values = await super.getValue();
return values?.[0] ?? null;
}
async setValue(value) {
if (value === null) return super.setValue([]);
else return super.setValue([value]);
}
get driverName() {
return "MuiV6ExclusiveToggleButtonGroupDriver";
}
};
//#endregion
exports.AccordionDriver = AccordionDriver;
exports.AlertDriver = AlertDriver;
exports.AutoCompleteDriver = AutoCompleteDriver;
exports.BadgeDriver = BadgeDriver;
exports.ButtonDriver = ButtonDriver;
exports.CheckboxDriver = CheckboxDriver;
exports.ChipDriver = ChipDriver;
exports.DialogDriver = DialogDriver;
exports.ExclusiveToggleButtonGroupDriver = ExclusiveToggleButtonGroupDriver;
exports.FabDriver = FabDriver;
exports.InputDriver = InputDriver;
exports.ListDriver = ListDriver;
exports.ListItemDriver = ListItemDriver;
exports.MenuDriver = MenuDriver;
exports.MenuItemDisabledError = MenuItemDisabledError;
exports.MenuItemDisabledErrorId = MenuItemDisabledErrorId;
exports.MenuItemDriver = MenuItemDriver;
exports.MenuItemNotFoundError = MenuItemNotFoundError;
exports.MenuItemNotFoundErrorId = MenuItemNotFoundErrorId;
exports.ProgressDriver = ProgressDriver;
exports.RatingDriver = RatingDriver;
exports.SelectDriver = SelectDriver;
exports.SliderDriver = SliderDriver;
exports.SnackbarDriver = SnackbarDriver;
exports.SwitchDriver = SwitchDriver;
exports.TextFieldDriver = TextFieldDriver;
exports.ToggleButtonDriver = ToggleButtonDriver;
exports.ToggleButtonGroupDriver = ToggleButtonGroupDriver;
exports.defaultAutoCompleteDriverOption = defaultAutoCompleteDriverOption;
//# sourceMappingURL=index.js.map