@atomic-testing/component-driver-mui-v9 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +76 -0
- package/dist/index.cjs +2439 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1391 -0
- package/dist/index.d.mts +1391 -0
- package/dist/index.mjs +2386 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +48 -0
- package/src/components/AccordionDriver.ts +109 -0
- package/src/components/AlertDriver.ts +74 -0
- package/src/components/AutoCompleteDriver.ts +151 -0
- package/src/components/AvatarDriver.ts +51 -0
- package/src/components/AvatarGroupDriver.ts +79 -0
- package/src/components/BadgeDriver.ts +43 -0
- package/src/components/BottomNavigationActionDriver.ts +23 -0
- package/src/components/BottomNavigationDriver.ts +138 -0
- package/src/components/ButtonDriver.ts +16 -0
- package/src/components/CheckboxDriver.ts +98 -0
- package/src/components/ChipDriver.ts +53 -0
- package/src/components/DialogDriver.ts +122 -0
- package/src/components/DrawerDriver.ts +90 -0
- package/src/components/FabDriver.ts +11 -0
- package/src/components/InputDriver.ts +112 -0
- package/src/components/ListDriver.ts +42 -0
- package/src/components/ListItemDriver.ts +34 -0
- package/src/components/MenuDriver.ts +65 -0
- package/src/components/MenuItemDriver.ts +15 -0
- package/src/components/OverlayDriver.ts +98 -0
- package/src/components/PaginationDriver.ts +117 -0
- package/src/components/ProgressDriver.ts +78 -0
- package/src/components/RadioDriver.ts +63 -0
- package/src/components/RadioGroupDriver.ts +129 -0
- package/src/components/RatingDriver.ts +121 -0
- package/src/components/SelectDriver.ts +223 -0
- package/src/components/SliderDriver.ts +109 -0
- package/src/components/SnackbarDriver.ts +68 -0
- package/src/components/SpeedDialDriver.ts +83 -0
- package/src/components/StepperDriver.ts +109 -0
- package/src/components/SwitchDriver.ts +62 -0
- package/src/components/TabDriver.ts +39 -0
- package/src/components/TableCellDriver.ts +14 -0
- package/src/components/TableDriver.ts +148 -0
- package/src/components/TablePaginationDriver.ts +110 -0
- package/src/components/TableRowDriver.ts +79 -0
- package/src/components/TabsDriver.ts +133 -0
- package/src/components/TextFieldDriver.ts +155 -0
- package/src/components/ToggleButtonDriver.ts +21 -0
- package/src/components/ToggleButtonGroupDriver.ts +75 -0
- package/src/components/TooltipDriver.ts +82 -0
- package/src/errors/MenuItemDisabledError.ts +17 -0
- package/src/errors/MenuItemNotFoundError.ts +17 -0
- package/src/index.ts +52 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { byTagName, ComponentDriver, IInputDriver, listHelper, locatorUtil } from '@atomic-testing/core';
|
|
2
|
+
|
|
3
|
+
import { ToggleButtonDriver } from './ToggleButtonDriver';
|
|
4
|
+
|
|
5
|
+
const toggleButtonLocator = byTagName('button');
|
|
6
|
+
|
|
7
|
+
export class ToggleButtonGroupDriver extends ComponentDriver implements IInputDriver<readonly string[]> {
|
|
8
|
+
protected itemLocator = locatorUtil.append(this.locator, toggleButtonLocator);
|
|
9
|
+
/**
|
|
10
|
+
* Get all the selected toggle buttons' values.
|
|
11
|
+
* @returns
|
|
12
|
+
*/
|
|
13
|
+
async getValue(): Promise<readonly string[]> {
|
|
14
|
+
const result: string[] = [];
|
|
15
|
+
for await (const itemDriver of listHelper.getListItemIterator(this, this.itemLocator, ToggleButtonDriver)) {
|
|
16
|
+
const isSelected = await itemDriver.isSelected();
|
|
17
|
+
if (isSelected) {
|
|
18
|
+
const value = await itemDriver.getValue();
|
|
19
|
+
if (value != null) {
|
|
20
|
+
result.push(value);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return result;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Toggle all the toggle buttons such that only those with value in the given array are selected.
|
|
29
|
+
* @param value Always true
|
|
30
|
+
* @returns
|
|
31
|
+
*/
|
|
32
|
+
async setValue(value: readonly string[]): Promise<boolean> {
|
|
33
|
+
const valueSet = new Set(value);
|
|
34
|
+
for await (const itemDriver of listHelper.getListItemIterator(this, this.itemLocator, ToggleButtonDriver)) {
|
|
35
|
+
const value = await itemDriver.getValue();
|
|
36
|
+
await itemDriver.setSelected(valueSet.has(value!));
|
|
37
|
+
}
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
get driverName(): string {
|
|
42
|
+
return 'MuiV9ToggleButtonGroupDriver';
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* A toggle button group driver that only allows a single selection.
|
|
48
|
+
*
|
|
49
|
+
* INTENTIONAL @ts-ignore comments below: This class intentionally narrows the return type
|
|
50
|
+
* from `readonly string[]` to `string | null` for exclusive selection mode. TypeScript
|
|
51
|
+
* correctly flags this as a type incompatibility because the subclass changes the interface
|
|
52
|
+
* contract. However, this design is intentional as exclusive and multi-select toggle groups
|
|
53
|
+
* have fundamentally different value semantics, and we want the type system to reflect
|
|
54
|
+
* `string | null` for exclusive mode rather than forcing consumers to work with arrays.
|
|
55
|
+
*/
|
|
56
|
+
export class ExclusiveToggleButtonGroupDriver extends ToggleButtonGroupDriver implements IInputDriver<string | null> {
|
|
57
|
+
// @ts-ignore - See class comment for explanation of intentional type narrowing
|
|
58
|
+
async getValue(): Promise<string | null> {
|
|
59
|
+
const values = await super.getValue();
|
|
60
|
+
return values?.[0] ?? null;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// @ts-ignore - See class comment for explanation of intentional type narrowing
|
|
64
|
+
async setValue(value: string | null): Promise<boolean> {
|
|
65
|
+
if (value === null) {
|
|
66
|
+
return super.setValue([]);
|
|
67
|
+
} else {
|
|
68
|
+
return super.setValue([value]);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
get driverName(): string {
|
|
73
|
+
return 'MuiV9ExclusiveToggleButtonGroupDriver';
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { byRole, ComponentDriver, Optional, PartLocator } from '@atomic-testing/core';
|
|
2
|
+
|
|
3
|
+
// MUI renders the tooltip into a portal outside this driver's subtree, so it is
|
|
4
|
+
// addressed from the document root by its `role="tooltip"`.
|
|
5
|
+
const tooltipLocator: PartLocator = byRole('tooltip', 'Root');
|
|
6
|
+
|
|
7
|
+
const defaultRevealTimeout = 250;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Driver for the Material UI v9 Tooltip component.
|
|
11
|
+
*
|
|
12
|
+
* The driver is rooted at the **trigger** element. MUI shows the tooltip on
|
|
13
|
+
* hover/focus and renders it into a portal (a `role="tooltip"` popper) outside the
|
|
14
|
+
* trigger's subtree, so the text is read from the document root via
|
|
15
|
+
* {@link tooltipLocator} after revealing it. The tooltip unmounts when not shown,
|
|
16
|
+
* so presence of that element doubles as the visible state.
|
|
17
|
+
*
|
|
18
|
+
* Note: hover reveal depends on the tooltip's `enterDelay`; with a non-zero delay
|
|
19
|
+
* the reveal is timer-bound. {@link getTitle} waits for the tooltip to appear.
|
|
20
|
+
* @see https://mui.com/material-ui/react-tooltip/
|
|
21
|
+
*/
|
|
22
|
+
export class TooltipDriver extends ComponentDriver {
|
|
23
|
+
/**
|
|
24
|
+
* Reveal the tooltip by hovering its trigger, waiting until it is shown (or the
|
|
25
|
+
* timeout elapses, e.g. when the trigger has no tooltip).
|
|
26
|
+
*/
|
|
27
|
+
async show(timeoutMs: number = defaultRevealTimeout): Promise<void> {
|
|
28
|
+
await this.interactor.hover(this.locator);
|
|
29
|
+
await this.interactor.waitUntil({
|
|
30
|
+
probeFn: () => this.isVisible(),
|
|
31
|
+
terminateCondition: true,
|
|
32
|
+
timeoutMs,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Hide the tooltip by moving the pointer off its trigger, waiting until it is gone.
|
|
38
|
+
*/
|
|
39
|
+
async hide(timeoutMs: number = defaultRevealTimeout): Promise<void> {
|
|
40
|
+
await this.interactor.mouseLeave(this.locator);
|
|
41
|
+
await this.interactor.waitUntil({
|
|
42
|
+
probeFn: () => this.isVisible(),
|
|
43
|
+
terminateCondition: false,
|
|
44
|
+
timeoutMs,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Whether a tooltip is currently shown.
|
|
50
|
+
*/
|
|
51
|
+
async isVisible(): Promise<boolean> {
|
|
52
|
+
if (!(await this.interactor.exists(tooltipLocator))) {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
return this.interactor.isVisible(tooltipLocator);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Reveal the tooltip, read its text, then restore the un-hovered state. Returns
|
|
60
|
+
* `undefined` when the trigger has no tooltip (none appears within the timeout).
|
|
61
|
+
*
|
|
62
|
+
* The hover is undone before returning so a subsequent read on a *different*
|
|
63
|
+
* trigger isn't shadowed by this still-open tooltip: MUI renders all tooltips into
|
|
64
|
+
* one portal and provides no per-trigger DOM link, and jsdom's synthetic hover does
|
|
65
|
+
* not fire `mouseout` on the previously-hovered sibling.
|
|
66
|
+
*
|
|
67
|
+
* @param timeoutMs How long to wait for the tooltip to appear after hovering.
|
|
68
|
+
*/
|
|
69
|
+
async getTitle(timeoutMs: number = defaultRevealTimeout): Promise<Optional<string>> {
|
|
70
|
+
await this.show(timeoutMs);
|
|
71
|
+
if (!(await this.interactor.exists(tooltipLocator))) {
|
|
72
|
+
return undefined;
|
|
73
|
+
}
|
|
74
|
+
const text = (await this.interactor.getText(tooltipLocator))?.trim();
|
|
75
|
+
await this.hide(timeoutMs);
|
|
76
|
+
return text;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
override get driverName(): string {
|
|
80
|
+
return 'MuiV9TooltipDriver';
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ComponentDriver, ErrorBase } from '@atomic-testing/core';
|
|
2
|
+
|
|
3
|
+
export const MenuItemDisabledErrorId = 'MenuItemDisabledError';
|
|
4
|
+
|
|
5
|
+
function getErrorMessage(label: string): string {
|
|
6
|
+
return `The menu item with label: ${label} is disabled`;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export class MenuItemDisabledError extends ErrorBase {
|
|
10
|
+
constructor(
|
|
11
|
+
public readonly label: string,
|
|
12
|
+
public readonly driver: ComponentDriver<any>
|
|
13
|
+
) {
|
|
14
|
+
super(getErrorMessage(label), driver);
|
|
15
|
+
this.name = MenuItemDisabledErrorId;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ComponentDriver, ErrorBase } from '@atomic-testing/core';
|
|
2
|
+
|
|
3
|
+
export const MenuItemNotFoundErrorId = 'MenuItemNotFoundError';
|
|
4
|
+
|
|
5
|
+
function getErrorMessage(label: string): string {
|
|
6
|
+
return `Cannot find menu item with label: ${label}`;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export class MenuItemNotFoundError extends ErrorBase {
|
|
10
|
+
constructor(
|
|
11
|
+
public readonly label: string,
|
|
12
|
+
public readonly driver: ComponentDriver<any>
|
|
13
|
+
) {
|
|
14
|
+
super(getErrorMessage(label), driver);
|
|
15
|
+
this.name = MenuItemNotFoundErrorId;
|
|
16
|
+
}
|
|
17
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export { AccordionDriver } from './components/AccordionDriver';
|
|
2
|
+
export { AlertDriver } from './components/AlertDriver';
|
|
3
|
+
export { AvatarDriver } from './components/AvatarDriver';
|
|
4
|
+
export { AvatarGroupDriver, defaultAvatarGroupDriverOption } from './components/AvatarGroupDriver';
|
|
5
|
+
export { AutoCompleteDriver, defaultAutoCompleteDriverOption } from './components/AutoCompleteDriver';
|
|
6
|
+
export type {
|
|
7
|
+
AutoCompleteDriverOption,
|
|
8
|
+
AutoCompleteDriverSpecificOption,
|
|
9
|
+
AutoCompleteMatchType,
|
|
10
|
+
} from './components/AutoCompleteDriver';
|
|
11
|
+
export { BadgeDriver } from './components/BadgeDriver';
|
|
12
|
+
export { BottomNavigationActionDriver } from './components/BottomNavigationActionDriver';
|
|
13
|
+
export type { BottomNavigationActionInfo } from './components/BottomNavigationDriver';
|
|
14
|
+
export { BottomNavigationDriver } from './components/BottomNavigationDriver';
|
|
15
|
+
export { ButtonDriver } from './components/ButtonDriver';
|
|
16
|
+
export { CheckboxDriver } from './components/CheckboxDriver';
|
|
17
|
+
export { ChipDriver } from './components/ChipDriver';
|
|
18
|
+
export { DialogDriver } from './components/DialogDriver';
|
|
19
|
+
export type { DrawerAnchor } from './components/DrawerDriver';
|
|
20
|
+
export { drawerParts, DrawerDriver } from './components/DrawerDriver';
|
|
21
|
+
export { FabDriver } from './components/FabDriver';
|
|
22
|
+
export { OverlayDriver } from './components/OverlayDriver';
|
|
23
|
+
export { InputDriver } from './components/InputDriver';
|
|
24
|
+
export { ListDriver } from './components/ListDriver';
|
|
25
|
+
export { ListItemDriver } from './components/ListItemDriver';
|
|
26
|
+
export { MenuDriver } from './components/MenuDriver';
|
|
27
|
+
export { MenuItemDriver } from './components/MenuItemDriver';
|
|
28
|
+
export { PaginationDriver } from './components/PaginationDriver';
|
|
29
|
+
export { ProgressDriver } from './components/ProgressDriver';
|
|
30
|
+
export { RadioDriver } from './components/RadioDriver';
|
|
31
|
+
export { defaultRadioGroupDriverOption, RadioGroupDriver } from './components/RadioGroupDriver';
|
|
32
|
+
export { RatingDriver } from './components/RatingDriver';
|
|
33
|
+
export { SelectDriver } from './components/SelectDriver';
|
|
34
|
+
export { SliderDriver } from './components/SliderDriver';
|
|
35
|
+
export { SnackbarDriver } from './components/SnackbarDriver';
|
|
36
|
+
export { SpeedDialDriver } from './components/SpeedDialDriver';
|
|
37
|
+
export type { StepInfo } from './components/StepperDriver';
|
|
38
|
+
export { StepperDriver } from './components/StepperDriver';
|
|
39
|
+
export { SwitchDriver } from './components/SwitchDriver';
|
|
40
|
+
export { TableCellDriver } from './components/TableCellDriver';
|
|
41
|
+
export type { TableSortDirection } from './components/TableDriver';
|
|
42
|
+
export { defaultTableDriverOption, TableDriver } from './components/TableDriver';
|
|
43
|
+
export { defaultTableRowDriverOption, TableRowDriver } from './components/TableRowDriver';
|
|
44
|
+
export { TablePaginationDriver } from './components/TablePaginationDriver';
|
|
45
|
+
export { TabDriver } from './components/TabDriver';
|
|
46
|
+
export { defaultTabsDriverOption, TabsDriver } from './components/TabsDriver';
|
|
47
|
+
export { TextFieldDriver } from './components/TextFieldDriver';
|
|
48
|
+
export { ToggleButtonDriver } from './components/ToggleButtonDriver';
|
|
49
|
+
export { ExclusiveToggleButtonGroupDriver, ToggleButtonGroupDriver } from './components/ToggleButtonGroupDriver';
|
|
50
|
+
export { TooltipDriver } from './components/TooltipDriver';
|
|
51
|
+
export { MenuItemDisabledError, MenuItemDisabledErrorId } from './errors/MenuItemDisabledError';
|
|
52
|
+
export { MenuItemNotFoundError, MenuItemNotFoundErrorId } from './errors/MenuItemNotFoundError';
|