UNPKG

@atomic-testing/component-driver-html

Version:
1 lines 20 kB
{"version":3,"file":"index.mjs","names":["option?: ClickOption","option?: HoverOption","selected: boolean","value: string[]","values: readonly string[]","value: string","selected: boolean","locator: PartLocator","interactor: Interactor","option?: Partial<IComponentDriverOption>","_value: string | null","value: string | null","value: Nullable<ValueT>","selectedValues: string[]","labels: readonly string[]","values: string[]","label: string | readonly string[]","isMultiple?: boolean","locator: PartLocator","interactor: Interactor","option?: Partial<IComponentDriverOption>","value: string | null"],"sources":["../src/components/HTMLAnchorDriver.ts","../src/components/HTMLButtonDriver.ts","../src/components/HTMLCheckboxDriver.ts","../src/components/HTMLCheckboxGroupDriver.ts","../src/components/HTMLElementDriver.ts","../src/components/HTMLHiddenInputDriver.ts","../src/components/HTMLOptionDriver.ts","../src/components/HTMLRadioButtonGroupDriver.ts","../src/components/HTMLSelectDriver.ts","../src/components/HTMLTextInputDriver.ts","../src/components/HTMLTextAreaDriver.ts"],"sourcesContent":["import {\n ClickOption,\n ComponentDriver,\n HoverOption,\n IClickableDriver,\n IMouseInteractableDriver,\n Optional,\n} from '@atomic-testing/core';\n\nexport class HTMLAnchorDriver extends ComponentDriver<{}> implements IClickableDriver, IMouseInteractableDriver {\n /**\n * Trigger a click on the anchor element.\n */\n async click(option?: ClickOption): Promise<void> {\n await this.interactor.click(this.locator, option);\n }\n\n /**\n * Hover over the anchor element.\n */\n async hover(option?: HoverOption): Promise<void> {\n await this.interactor.hover(this.locator, option);\n }\n\n /**\n * Retrieve the link's `href` attribute.\n */\n async getHref(): Promise<Optional<string>> {\n return this.interactor.getAttribute(this.locator, 'href');\n }\n\n /**\n * Retrieve the link's `target` attribute.\n */\n async getTarget(): Promise<Optional<string>> {\n return this.interactor.getAttribute(this.locator, 'target');\n }\n\n /**\n * Identifier for this driver.\n */\n get driverName(): string {\n return 'HTMLAnchorDriver';\n }\n}\n","import { ComponentDriver, IClickableDriver, IMouseInteractableDriver } from '@atomic-testing/core';\n\nexport class HTMLButtonDriver extends ComponentDriver<{}> implements IClickableDriver, IMouseInteractableDriver {\n /**\n * Check if the button element is disabled.\n *\n * @returns A promise that resolves to `true` when the underlying\n * `disabled` attribute is present.\n */\n isDisabled(): Promise<boolean> {\n return this.interactor.isDisabled(this.locator);\n }\n\n /**\n * Identifier for this driver. Primarily used by debugging utilities.\n */\n get driverName(): string {\n return 'HTMLButtonDriver';\n }\n}\n","import { ComponentDriver, IFormFieldDriver, IToggleDriver } from '@atomic-testing/core';\n\nexport class HTMLCheckboxDriver extends ComponentDriver<{}> implements IFormFieldDriver<string | null>, IToggleDriver {\n /**\n * Read the checkbox value attribute.\n *\n * @returns The value assigned to the checkbox or `null` when the attribute is\n * not present.\n */\n async getValue(): Promise<string | null> {\n const value = await this.interactor.getAttribute(this.locator, 'value');\n return value ?? null;\n }\n\n /**\n * Determine if the checkbox is currently checked.\n */\n async isSelected(): Promise<boolean> {\n const isChecked = await this.interactor.isChecked(this.locator);\n return isChecked;\n }\n\n /**\n * Change the checked state of the checkbox.\n *\n * @param selected Desired checked state.\n */\n async setSelected(selected: boolean): Promise<void> {\n const currentSelected = await this.isSelected();\n if (currentSelected !== selected) {\n await this.interactor.click(this.locator);\n }\n }\n\n /**\n * Check whether the checkbox element is disabled.\n */\n isDisabled(): Promise<boolean> {\n return this.interactor.isDisabled(this.locator);\n }\n\n /**\n * Check whether the checkbox is read only.\n */\n isReadonly(): Promise<boolean> {\n return this.interactor.isReadonly(this.locator);\n }\n\n /**\n * Identifier for this driver.\n */\n get driverName(): string {\n return 'HTMLCheckboxDriver';\n }\n}\n","import { byValue, collectionUtil, ComponentDriver, IInputDriver, locatorUtil } from '@atomic-testing/core';\n\nimport { HTMLCheckboxDriver } from './HTMLCheckboxDriver';\n\nexport class HTMLCheckboxGroupDriver extends ComponentDriver<{}> implements IInputDriver<readonly string[]> {\n /**\n * Retrieve the list of values currently selected within the group.\n *\n * Iterates over every checkbox rather than relying on a CSS selector so that\n * an empty selection does not cause a driver error.\n */\n async getValue(): Promise<readonly string[]> {\n const availableValues = await this.interactor.getAttribute(this.locator, 'value', true);\n const value: string[] = [];\n for (const val of availableValues) {\n const itemLocator = byValue(val, 'Same');\n const locator = locatorUtil.append(this.locator, itemLocator);\n const isChecked = await this.interactor.isChecked(locator);\n if (isChecked) {\n value.push(val);\n }\n }\n return value;\n }\n\n /**\n * Select or deselect checkboxes so that their combined values equal the\n * provided list.\n *\n * @param values Values that should be selected after the operation.\n * @returns Always resolves to `true` once the selection has been adjusted.\n */\n async setValue(values: readonly string[]): Promise<boolean> {\n const currentValues = await this.getValue();\n const { toAdd, toRemove } = collectionUtil.getDifference<string>(currentValues, values);\n for (const val of toAdd) {\n await this.setSelectedByValue(val, true);\n }\n\n for (const val of toRemove) {\n await this.setSelectedByValue(val, false);\n }\n return true;\n }\n\n /**\n * Helper used by {@link setValue} to change the checked state of a checkbox\n * with a specific value.\n */\n protected async setSelectedByValue(value: string, selected: boolean): Promise<void> {\n const itemLocator = byValue(value, 'Same');\n const locator = locatorUtil.append(this.locator, itemLocator);\n const checkBoxDriver = new HTMLCheckboxDriver(locator, this.interactor);\n await checkBoxDriver.setSelected(selected);\n }\n\n /**\n * Identifier for this driver.\n */\n get driverName(): string {\n return 'HTMLCheckboxGroupDriver';\n }\n}\n","import { ComponentDriver } from '@atomic-testing/core';\n\n/**\n * Generic HTML element driver for non-interactive elements\n */\nexport class HTMLElementDriver extends ComponentDriver<{}> {\n /**\n * Identifier for this driver.\n */\n get driverName(): string {\n return 'HTMLElementDriver';\n }\n}\n","import { ComponentDriver, IComponentDriverOption, IInputDriver, Interactor, PartLocator } from '@atomic-testing/core';\n\nexport class HTMLHiddenInputDriver extends ComponentDriver<{}> implements IInputDriver<string | null> {\n /**\n * Create a driver for a hidden input element.\n */\n constructor(locator: PartLocator, interactor: Interactor, option?: Partial<IComponentDriverOption>) {\n super(locator, interactor, {\n ...option,\n parts: {},\n });\n }\n\n /**\n * Retrieve the value attribute of the hidden input.\n */\n async getValue(): Promise<string | null> {\n const value = await this.interactor.getAttribute(this.locator, 'value');\n return value ?? null;\n }\n\n /**\n * Setting the value of a hidden input is not supported.\n */\n setValue(_value: string | null): Promise<boolean> {\n // Setting value of a hidden input should not be part of user interaction\n throw new Error('Not implemented');\n }\n\n /**\n * Identifier for this driver.\n */\n get driverName(): string {\n return 'HTMLHiddenInput';\n }\n}\n","import { ComponentDriver } from '@atomic-testing/core';\n\nexport class HTMLOptionDriver extends ComponentDriver {\n /**\n * Text content of the option element.\n */\n async label(): Promise<string | null> {\n const label = await this.getText();\n return label?.trim() || null;\n }\n\n /**\n * Value attribute for the option element.\n *\n * When no explicit value is set, the trimmed label is returned.\n */\n async value(): Promise<string | null> {\n const val = (await this.interactor.getAttribute(this.locator, 'value')) ?? (await this.label());\n return val?.trim() || null;\n }\n\n /**\n * Identifier for this driver.\n */\n get driverName(): string {\n return 'HTMLOptionDriver';\n }\n}\n","import { byChecked, byValue, ComponentDriver, IInputDriver, locatorUtil } from '@atomic-testing/core';\n\nexport class HTMLRadioButtonGroupDriver extends ComponentDriver<{}> implements IInputDriver<string | null> {\n /**\n * Get the value of the currently selected radio button in the group.\n */\n async getValue(): Promise<string | null> {\n const checkedLocator = byChecked(true);\n const locator = locatorUtil.append(this.locator, checkedLocator);\n const value = await this.interactor.getAttribute(locator, 'value');\n return value ?? null;\n }\n\n /**\n * Select the radio button with the specified value.\n *\n * @param value Value attribute of the radio button to select.\n */\n async setValue(value: string | null): Promise<boolean> {\n if (value == null) {\n throw new Error('Cannot be done');\n }\n const valueLocator = byValue(value, 'Same');\n const locator = locatorUtil.append(this.locator, valueLocator);\n await this.interactor.click(locator);\n return true;\n }\n\n /**\n * Identifier for this driver.\n */\n get driverName(): string {\n throw 'HTMLRadioButtonGroupDriver';\n }\n}\n","import {\n byTagName,\n collectionUtil,\n ComponentDriver,\n IInputDriver,\n listHelper,\n locatorUtil,\n Nullable,\n} from '@atomic-testing/core';\n\nimport { HTMLOptionDriver } from './HTMLOptionDriver';\n\ntype ValueT = string | readonly string[];\nconst optionLocator = byTagName('option');\n\nexport class HTMLSelectDriver extends ComponentDriver<{}> implements IInputDriver<Nullable<ValueT>> {\n /**\n * Determine whether the select element allows multiple selections.\n */\n async isMultiple(): Promise<boolean> {\n const multiple = await this.interactor.getAttribute(this.locator, 'multiple');\n return multiple != null;\n }\n\n /**\n * Get the current value(s) of the select element.\n *\n * @returns `null` when nothing is selected, otherwise the selected value or\n * array of values depending on the `multiple` attribute.\n */\n async getValue(): Promise<Nullable<ValueT>> {\n const isMultiple = await this.isMultiple();\n const values = await this.interactor.getSelectValues(this.locator);\n const returnedValue = isMultiple ? values : values?.[0];\n return returnedValue ?? null;\n }\n\n /**\n * Select one or more options based on their value attribute.\n *\n * @param value Value or list of values to select. Use `null` to clear the\n * selection.\n */\n async setValue(value: Nullable<ValueT>): Promise<boolean> {\n let selectedValues: string[] = [];\n if (value != null) {\n selectedValues = Array.isArray(value) ? value : [value];\n }\n await this.interactor.selectOptionValue(this.locator, selectedValues);\n return true;\n }\n\n /**\n * Resolve option values from their visible labels.\n */\n async getValuesByLabels(labels: readonly string[]): Promise<readonly string[]> {\n const labelSet = new Set(labels);\n const values: string[] = [];\n const itemLocatorBase = locatorUtil.append(this.locator, optionLocator);\n for await (const item of listHelper.getListItemIterator(this, itemLocatorBase, HTMLOptionDriver)) {\n const label = await item.label();\n const value = await item.value();\n if (label != null && labelSet.has(label) && value != null) {\n values.push(value);\n }\n }\n return values;\n }\n\n /**\n * Select option(s) using their labels rather than values.\n */\n async selectByLabel(label: string | readonly string[]): Promise<void> {\n const labels = collectionUtil.toArray(label);\n const values = await this.getValuesByLabels(labels);\n await this.setValue(values);\n }\n\n async getSelectedLabel(isMultiple: true): Promise<readonly string[] | null>;\n async getSelectedLabel(isMultiple: false): Promise<string | null>;\n async getSelectedLabel(): Promise<string | null>;\n /**\n * Retrieve the label text for the currently selected option(s).\n */\n async getSelectedLabel(isMultiple?: boolean) {\n if (await this.exists()) {\n const labels = await this.interactor.getSelectLabels(this.locator);\n if (isMultiple) {\n return labels;\n }\n return labels![0] ?? null;\n }\n return null;\n }\n\n /**\n * Check whether the select element is disabled.\n */\n isDisabled(): Promise<boolean> {\n return this.interactor.isDisabled(this.locator);\n }\n\n /**\n * Check whether the select element is read only.\n */\n isReadonly(): Promise<boolean> {\n return this.interactor.isReadonly(this.locator);\n }\n\n /**\n * Identifier for this driver.\n */\n get driverName(): string {\n return 'HTMLSelectDriver';\n }\n}\n","import { ComponentDriver, IComponentDriverOption, IInputDriver, Interactor, PartLocator } from '@atomic-testing/core';\n\nexport class HTMLTextInputDriver extends ComponentDriver<{}> implements IInputDriver<string | null> {\n /**\n * Create a text input driver.\n */\n constructor(locator: PartLocator, interactor: Interactor, option?: Partial<IComponentDriverOption>) {\n super(locator, interactor, {\n ...option,\n parts: {},\n });\n }\n\n /**\n * Read the value of the input element.\n */\n async getValue(): Promise<string | null> {\n const value = await this.interactor.getInputValue(this.locator);\n return value ?? null;\n }\n\n /**\n * Set the value of the input, if the input is date, the value should be in the format of 'yyyy-MM-dd'.\n * If the input is time, the value should be in the format of 'HH:mm:'.\n * If the input is datetime-local, the value should be in the format of 'yyyy-MM-ddTHH:mm'.\n * @param value Value to be set.\n * @returns\n */\n async setValue(value: string | null): Promise<boolean> {\n await this.interactor.enterText(this.locator, value ?? '');\n return true;\n }\n\n /**\n * Check whether the text input is disabled.\n */\n isDisabled(): Promise<boolean> {\n return this.interactor.isDisabled(this.locator);\n }\n\n /**\n * Check whether the text input is read only.\n */\n isReadonly(): Promise<boolean> {\n return this.interactor.isReadonly(this.locator);\n }\n\n /**\n * Identifier for this driver.\n */\n get driverName(): string {\n return 'HTMLTextInput';\n }\n}\n","import { HTMLTextInputDriver } from './HTMLTextInputDriver';\n\nexport class HTMLTextAreaDriver extends HTMLTextInputDriver {\n /**\n * Identifier for this driver.\n */\n override get driverName(): string {\n return 'HTMLTextArea';\n }\n}\n"],"mappings":"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"}