@elastic/eui-test-helpers 1.4.0 → 1.5.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.
Files changed (51) hide show
  1. package/README.md +4 -0
  2. package/lib/cjs/components/basic_table/selectors.d.ts +17 -0
  3. package/lib/cjs/components/basic_table/selectors.js +31 -0
  4. package/lib/cjs/components/drag_and_drop/selectors.d.ts +15 -0
  5. package/lib/cjs/components/drag_and_drop/selectors.js +29 -0
  6. package/lib/cjs/components/filter_button/selectors.d.ts +16 -0
  7. package/lib/cjs/components/filter_button/selectors.js +30 -0
  8. package/lib/cjs/components/form/range/selectors.d.ts +11 -0
  9. package/lib/cjs/components/form/range/selectors.js +25 -0
  10. package/lib/cjs/index.d.ts +4 -0
  11. package/lib/cjs/index.js +29 -1
  12. package/lib/cjs/playwright/components/basic_table/object.d.ts +50 -0
  13. package/lib/cjs/playwright/components/basic_table/object.js +93 -0
  14. package/lib/cjs/playwright/components/drag_and_drop/object.d.ts +21 -0
  15. package/lib/cjs/playwright/components/drag_and_drop/object.js +48 -0
  16. package/lib/cjs/playwright/components/filter_button/object.d.ts +31 -0
  17. package/lib/cjs/playwright/components/filter_button/object.js +51 -0
  18. package/lib/cjs/playwright/components/form/range/object.d.ts +25 -0
  19. package/lib/cjs/playwright/components/form/range/object.js +48 -0
  20. package/lib/esm/components/basic_table/selectors.d.ts +17 -0
  21. package/lib/esm/components/basic_table/selectors.js +25 -0
  22. package/lib/esm/components/basic_table/selectors.js.map +1 -0
  23. package/lib/esm/components/drag_and_drop/selectors.d.ts +15 -0
  24. package/lib/esm/components/drag_and_drop/selectors.js +23 -0
  25. package/lib/esm/components/drag_and_drop/selectors.js.map +1 -0
  26. package/lib/esm/components/filter_button/selectors.d.ts +16 -0
  27. package/lib/esm/components/filter_button/selectors.js +24 -0
  28. package/lib/esm/components/filter_button/selectors.js.map +1 -0
  29. package/lib/esm/components/form/range/selectors.d.ts +11 -0
  30. package/lib/esm/components/form/range/selectors.js +19 -0
  31. package/lib/esm/components/form/range/selectors.js.map +1 -0
  32. package/lib/esm/index.d.ts +4 -0
  33. package/lib/esm/index.js +4 -0
  34. package/lib/esm/index.js.map +1 -1
  35. package/lib/esm/playwright/components/basic_table/object.d.ts +50 -0
  36. package/lib/esm/playwright/components/basic_table/object.js +76 -0
  37. package/lib/esm/playwright/components/basic_table/object.js.map +1 -0
  38. package/lib/esm/playwright/components/drag_and_drop/object.d.ts +21 -0
  39. package/lib/esm/playwright/components/drag_and_drop/object.js +40 -0
  40. package/lib/esm/playwright/components/drag_and_drop/object.js.map +1 -0
  41. package/lib/esm/playwright/components/filter_button/object.d.ts +31 -0
  42. package/lib/esm/playwright/components/filter_button/object.js +43 -0
  43. package/lib/esm/playwright/components/filter_button/object.js.map +1 -0
  44. package/lib/esm/playwright/components/form/range/object.d.ts +25 -0
  45. package/lib/esm/playwright/components/form/range/object.js +39 -0
  46. package/lib/esm/playwright/components/form/range/object.js.map +1 -0
  47. package/package.json +1 -1
  48. package/src/components/basic_table/README.md +30 -0
  49. package/src/components/drag_and_drop/README.md +23 -0
  50. package/src/components/filter_button/README.md +29 -0
  51. package/src/components/form/range/README.md +31 -0
@@ -0,0 +1,25 @@
1
+ /*
2
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3
+ * or more contributor license agreements. Licensed under the Elastic License
4
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
5
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
6
+ * Side Public License, v 1.
7
+ */
8
+ /**
9
+ * Stable selectors for
10
+ * {@link https://eui.elastic.co/docs/components/tabular-content/tables/|EuiBasicTable}
11
+ * (also covers `EuiInMemoryTable`, which renders a `EuiBasicTable` underneath).
12
+ * `*_SELECTOR` values are CSS.
13
+ */
14
+ export const EuiBasicTableSelectors = {
15
+ /** Root element (the `.euiBasicTable` container carrying the consumer's `data-test-subj`). */
16
+ ROOT_SELECTOR: '.euiBasicTable',
17
+ /** A data row. Also matches EUI's own empty/error message row — callers must exclude those. */
18
+ ROW_SELECTOR: '.euiTableRow',
19
+ /**
20
+ * A field-data column's header cell. `%s` is the column's `field`. EUI appends a
21
+ * positional index (`tableHeaderCell_<field>_<index>`), so this is a prefix match.
22
+ */
23
+ HEADER_CELL_SELECTOR_PREFIX: 'tableHeaderCell_',
24
+ };
25
+ //# sourceMappingURL=selectors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selectors.js","sourceRoot":"","sources":["../../../../src/components/basic_table/selectors.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,8FAA8F;IAC9F,aAAa,EAAE,gBAAgB;IAE/B,+FAA+F;IAC/F,YAAY,EAAE,cAAc;IAE5B;;;OAGG;IACH,2BAA2B,EAAE,kBAAkB;CAChD,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Stable selectors for
3
+ * {@link https://eui.elastic.co/docs/components/drag-and-drop/|EuiDraggable}.
4
+ * `*_SELECTOR` values are CSS.
5
+ */
6
+ export declare const EuiDraggableSelectors: {
7
+ /**
8
+ * Attribute `@hello-pangea/dnd` (which `EuiDraggable` wraps) spreads onto an
9
+ * enabled drag handle. Used to verify `testSubj` actually points at a handle,
10
+ * not a fixed EUI class — the handle markup itself is consumer-defined.
11
+ */
12
+ HANDLE_SELECTOR: string;
13
+ /** Attribute `@hello-pangea/dnd` spreads onto every draggable item wrapper, enabled or not. */
14
+ ITEM_SELECTOR: string;
15
+ };
@@ -0,0 +1,23 @@
1
+ /*
2
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3
+ * or more contributor license agreements. Licensed under the Elastic License
4
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
5
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
6
+ * Side Public License, v 1.
7
+ */
8
+ /**
9
+ * Stable selectors for
10
+ * {@link https://eui.elastic.co/docs/components/drag-and-drop/|EuiDraggable}.
11
+ * `*_SELECTOR` values are CSS.
12
+ */
13
+ export const EuiDraggableSelectors = {
14
+ /**
15
+ * Attribute `@hello-pangea/dnd` (which `EuiDraggable` wraps) spreads onto an
16
+ * enabled drag handle. Used to verify `testSubj` actually points at a handle,
17
+ * not a fixed EUI class — the handle markup itself is consumer-defined.
18
+ */
19
+ HANDLE_SELECTOR: '[data-rfd-drag-handle-draggable-id]',
20
+ /** Attribute `@hello-pangea/dnd` spreads onto every draggable item wrapper, enabled or not. */
21
+ ITEM_SELECTOR: '[data-rfd-draggable-id]',
22
+ };
23
+ //# sourceMappingURL=selectors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selectors.js","sourceRoot":"","sources":["../../../../src/components/drag_and_drop/selectors.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;GAIG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC;;;;OAIG;IACH,eAAe,EAAE,qCAAqC;IAEtD,+FAA+F;IAC/F,aAAa,EAAE,yBAAyB;CACzC,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Stable selectors for
3
+ * {@link https://eui.elastic.co/docs/components/forms/filter-group/|EuiFilterButton}.
4
+ * `*_SELECTOR` values are CSS, `*_CLASS` values are class names to check for
5
+ * membership (e.g. via `toHaveClass`).
6
+ */
7
+ export declare const EuiFilterButtonSelectors: {
8
+ /** Root element (the button itself carries the consumer's `data-test-subj`). */
9
+ ROOT_SELECTOR: string;
10
+ /** The notification badge, present only when `numFilters` or `numActiveFilters` is set. */
11
+ NOTIFICATION_SELECTOR: string;
12
+ /** Set when `hasActiveFilters` is true. */
13
+ HAS_ACTIVE_FILTERS_CLASS: string;
14
+ /** Set when `isSelected` is true (e.g. a popover-toggle button while its popover is open). */
15
+ IS_SELECTED_CLASS: string;
16
+ };
@@ -0,0 +1,24 @@
1
+ /*
2
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3
+ * or more contributor license agreements. Licensed under the Elastic License
4
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
5
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
6
+ * Side Public License, v 1.
7
+ */
8
+ /**
9
+ * Stable selectors for
10
+ * {@link https://eui.elastic.co/docs/components/forms/filter-group/|EuiFilterButton}.
11
+ * `*_SELECTOR` values are CSS, `*_CLASS` values are class names to check for
12
+ * membership (e.g. via `toHaveClass`).
13
+ */
14
+ export const EuiFilterButtonSelectors = {
15
+ /** Root element (the button itself carries the consumer's `data-test-subj`). */
16
+ ROOT_SELECTOR: '.euiFilterButton',
17
+ /** The notification badge, present only when `numFilters` or `numActiveFilters` is set. */
18
+ NOTIFICATION_SELECTOR: '.euiFilterButton__notification',
19
+ /** Set when `hasActiveFilters` is true. */
20
+ HAS_ACTIVE_FILTERS_CLASS: 'euiFilterButton-hasActiveFilters',
21
+ /** Set when `isSelected` is true (e.g. a popover-toggle button while its popover is open). */
22
+ IS_SELECTED_CLASS: 'euiFilterButton-isSelected',
23
+ };
24
+ //# sourceMappingURL=selectors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selectors.js","sourceRoot":"","sources":["../../../../src/components/filter_button/selectors.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACtC,gFAAgF;IAChF,aAAa,EAAE,kBAAkB;IAEjC,2FAA2F;IAC3F,qBAAqB,EAAE,gCAAgC;IAEvD,2CAA2C;IAC3C,wBAAwB,EAAE,kCAAkC;IAE5D,8FAA8F;IAC9F,iBAAiB,EAAE,4BAA4B;CAChD,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Stable selectors for
3
+ * {@link https://eui.elastic.co/docs/components/forms/range-controls/|EuiRange}
4
+ * and `EuiDualRange`. `*_SELECTOR` values are CSS.
5
+ */
6
+ export declare const EuiRangeSelectors: {
7
+ /** The native `<input type="range">` element that carries the actual value. */
8
+ SLIDER_SELECTOR: string;
9
+ /** The visible number input, rendered on a plain `EuiRange` with `showInput`. See the package README for why it can share `data-test-subj` with {@link SLIDER_SELECTOR}. */
10
+ NUMBER_INPUT_SELECTOR: string;
11
+ };
@@ -0,0 +1,19 @@
1
+ /*
2
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3
+ * or more contributor license agreements. Licensed under the Elastic License
4
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
5
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
6
+ * Side Public License, v 1.
7
+ */
8
+ /**
9
+ * Stable selectors for
10
+ * {@link https://eui.elastic.co/docs/components/forms/range-controls/|EuiRange}
11
+ * and `EuiDualRange`. `*_SELECTOR` values are CSS.
12
+ */
13
+ export const EuiRangeSelectors = {
14
+ /** The native `<input type="range">` element that carries the actual value. */
15
+ SLIDER_SELECTOR: '.euiRangeSlider',
16
+ /** The visible number input, rendered on a plain `EuiRange` with `showInput`. See the package README for why it can share `data-test-subj` with {@link SLIDER_SELECTOR}. */
17
+ NUMBER_INPUT_SELECTOR: '.euiRangeInput',
18
+ };
19
+ //# sourceMappingURL=selectors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selectors.js","sourceRoot":"","sources":["../../../../../src/components/form/range/selectors.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;GAIG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,+EAA+E;IAC/E,eAAe,EAAE,iBAAiB;IAElC,4KAA4K;IAC5K,qBAAqB,EAAE,gBAAgB;CACxC,CAAC"}
@@ -4,3 +4,7 @@ export { EuiDataGridObject } from './playwright/components/datagrid/object';
4
4
  export { EuiSuperSelectObject } from './playwright/components/form/super_select/object';
5
5
  export { EuiGlobalToastListObject } from './playwright/components/toast/object';
6
6
  export { EuiSelectableObject } from './playwright/components/selectable/object';
7
+ export { EuiDraggableObject } from './playwright/components/drag_and_drop/object';
8
+ export { EuiFilterButtonObject } from './playwright/components/filter_button/object';
9
+ export { EuiRangeObject } from './playwright/components/form/range/object';
10
+ export { EuiBasicTableObject } from './playwright/components/basic_table/object';
package/lib/esm/index.js CHANGED
@@ -11,4 +11,8 @@ export { EuiDataGridObject } from './playwright/components/datagrid/object';
11
11
  export { EuiSuperSelectObject } from './playwright/components/form/super_select/object';
12
12
  export { EuiGlobalToastListObject } from './playwright/components/toast/object';
13
13
  export { EuiSelectableObject } from './playwright/components/selectable/object';
14
+ export { EuiDraggableObject } from './playwright/components/drag_and_drop/object';
15
+ export { EuiFilterButtonObject } from './playwright/components/filter_button/object';
16
+ export { EuiRangeObject } from './playwright/components/form/range/object';
17
+ export { EuiBasicTableObject } from './playwright/components/basic_table/object';
14
18
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,UAAU,EAAoB,MAAM,0BAA0B,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAC;AAC7E,OAAO,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAC;AAC5E,OAAO,EAAE,oBAAoB,EAAE,MAAM,kDAAkD,CAAC;AACxF,OAAO,EAAE,wBAAwB,EAAE,MAAM,sCAAsC,CAAC;AAChF,OAAO,EAAE,mBAAmB,EAAE,MAAM,2CAA2C,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,UAAU,EAAoB,MAAM,0BAA0B,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAC;AAC7E,OAAO,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAC;AAC5E,OAAO,EAAE,oBAAoB,EAAE,MAAM,kDAAkD,CAAC;AACxF,OAAO,EAAE,wBAAwB,EAAE,MAAM,sCAAsC,CAAC;AAChF,OAAO,EAAE,mBAAmB,EAAE,MAAM,2CAA2C,CAAC;AAChF,OAAO,EAAE,kBAAkB,EAAE,MAAM,8CAA8C,CAAC;AAClF,OAAO,EAAE,qBAAqB,EAAE,MAAM,8CAA8C,CAAC;AACrF,OAAO,EAAE,cAAc,EAAE,MAAM,2CAA2C,CAAC;AAC3E,OAAO,EAAE,mBAAmB,EAAE,MAAM,4CAA4C,CAAC"}
@@ -0,0 +1,50 @@
1
+ import type { Locator } from '@playwright/test';
2
+ import { BaseObject, type ObjectScope } from '../../base_object';
3
+ /**
4
+ * Playwright Component Object for {@link
5
+ * https://eui.elastic.co/docs/components/tabular-content/tables/ EuiBasicTable}
6
+ * (also covers `EuiInMemoryTable`, which renders a `EuiBasicTable` underneath and
7
+ * passes the `data-test-subj` straight through — there is no separate object for it).
8
+ *
9
+ * `testSubj` must match the `data-test-subj` set by the consumer on the
10
+ * `<EuiBasicTable>`/`<EuiInMemoryTable>` (EUI spreads it onto the `.euiBasicTable`
11
+ * root). See the package README for what's deliberately excluded from v1.
12
+ */
13
+ export declare class EuiBasicTableObject extends BaseObject {
14
+ constructor(scope: ObjectScope, testSubj: string);
15
+ /**
16
+ * The table's data rows, as a `Locator` so callers keep Playwright auto-retry
17
+ * for count and content assertions (e.g. `expect(table.rows).toHaveCount(3)`).
18
+ *
19
+ * Excludes EUI's own "no items found" (and error-message) row: when the table
20
+ * is empty, EUI still renders a single `.euiTableRow` whose one cell spans
21
+ * every column (`colSpan` on `EuiTableRowCell`, the `td[colspan]` HTML
22
+ * attribute). Real data rows don't set `colspan` on their cells, so filtering
23
+ * it out is what keeps `toHaveCount(0)` correct on an empty table instead of
24
+ * reading `1`.
25
+ */
26
+ get rows(): Locator;
27
+ /**
28
+ * The cells of the given field-data column, one per row, as a `Locator` for
29
+ * retrying content/count assertions (e.g.
30
+ * `expect(await table.cells('status')).toHaveText(['Running'])`).
31
+ *
32
+ * Resolves the column's position from EUI's own header cell
33
+ * (`tableHeaderCell_<field>_<index>`, matched exactly so a column named e.g.
34
+ * `status` doesn't also match a `status_detail` header) via its native
35
+ * `cellIndex`, then reads the cell at that position in every row — the same
36
+ * positional alignment EUI itself relies on, so it holds regardless of a
37
+ * leading selection-checkbox column. Matches both `<td>` and `<th>`: EUI
38
+ * renders the `rowHeader` column's body cell as a `<th scope="row">` for
39
+ * accessibility, not a `<td>`. Throws if no column with that `field` is
40
+ * rendered.
41
+ *
42
+ * EUI generates a computed column's header test-subj from its `name` using
43
+ * this exact same `tableHeaderCell_<name>_<index>` shape (there's no `field`
44
+ * to key on), so a computed column whose `name` happens to equal another
45
+ * column's `field` can resolve ambiguously — this method can't distinguish
46
+ * the two from the DOM alone. Not expected in practice; call it out if you
47
+ * hit it.
48
+ */
49
+ cells(field: string): Promise<Locator>;
50
+ }
@@ -0,0 +1,76 @@
1
+ /*
2
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3
+ * or more contributor license agreements. Licensed under the Elastic License
4
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
5
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
6
+ * Side Public License, v 1.
7
+ */
8
+ import { BaseObject } from '../../base_object';
9
+ import { EuiBasicTableSelectors } from '../../../components/basic_table/selectors';
10
+ /**
11
+ * Playwright Component Object for {@link
12
+ * https://eui.elastic.co/docs/components/tabular-content/tables/ EuiBasicTable}
13
+ * (also covers `EuiInMemoryTable`, which renders a `EuiBasicTable` underneath and
14
+ * passes the `data-test-subj` straight through — there is no separate object for it).
15
+ *
16
+ * `testSubj` must match the `data-test-subj` set by the consumer on the
17
+ * `<EuiBasicTable>`/`<EuiInMemoryTable>` (EUI spreads it onto the `.euiBasicTable`
18
+ * root). See the package README for what's deliberately excluded from v1.
19
+ */
20
+ export class EuiBasicTableObject extends BaseObject {
21
+ constructor(scope, testSubj) {
22
+ super(scope, testSubj, EuiBasicTableSelectors.ROOT_SELECTOR);
23
+ }
24
+ /**
25
+ * The table's data rows, as a `Locator` so callers keep Playwright auto-retry
26
+ * for count and content assertions (e.g. `expect(table.rows).toHaveCount(3)`).
27
+ *
28
+ * Excludes EUI's own "no items found" (and error-message) row: when the table
29
+ * is empty, EUI still renders a single `.euiTableRow` whose one cell spans
30
+ * every column (`colSpan` on `EuiTableRowCell`, the `td[colspan]` HTML
31
+ * attribute). Real data rows don't set `colspan` on their cells, so filtering
32
+ * it out is what keeps `toHaveCount(0)` correct on an empty table instead of
33
+ * reading `1`.
34
+ */
35
+ get rows() {
36
+ return this.root
37
+ .locator(EuiBasicTableSelectors.ROW_SELECTOR)
38
+ .filter({ hasNot: this.root.page().locator('td[colspan]') });
39
+ }
40
+ /**
41
+ * The cells of the given field-data column, one per row, as a `Locator` for
42
+ * retrying content/count assertions (e.g.
43
+ * `expect(await table.cells('status')).toHaveText(['Running'])`).
44
+ *
45
+ * Resolves the column's position from EUI's own header cell
46
+ * (`tableHeaderCell_<field>_<index>`, matched exactly so a column named e.g.
47
+ * `status` doesn't also match a `status_detail` header) via its native
48
+ * `cellIndex`, then reads the cell at that position in every row — the same
49
+ * positional alignment EUI itself relies on, so it holds regardless of a
50
+ * leading selection-checkbox column. Matches both `<td>` and `<th>`: EUI
51
+ * renders the `rowHeader` column's body cell as a `<th scope="row">` for
52
+ * accessibility, not a `<td>`. Throws if no column with that `field` is
53
+ * rendered.
54
+ *
55
+ * EUI generates a computed column's header test-subj from its `name` using
56
+ * this exact same `tableHeaderCell_<name>_<index>` shape (there's no `field`
57
+ * to key on), so a computed column whose `name` happens to equal another
58
+ * column's `field` can resolve ambiguously — this method can't distinguish
59
+ * the two from the DOM alone. Not expected in practice; call it out if you
60
+ * hit it.
61
+ */
62
+ async cells(field) {
63
+ const escaped = field.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
64
+ const cellIndex = await this.root.evaluate((tableEl, { prefix, pattern, field: originalField }) => {
65
+ const regex = new RegExp(`^${prefix}${pattern}_\\d+$`);
66
+ const headers = Array.from(tableEl.querySelectorAll('thead th, thead td'));
67
+ const header = headers.find((el) => regex.test(el.getAttribute('data-test-subj') ?? ''));
68
+ if (!header) {
69
+ throw new Error(`EuiBasicTableObject.cells: no column with field "${originalField}" found in this table's header.`);
70
+ }
71
+ return header.cellIndex;
72
+ }, { prefix: EuiBasicTableSelectors.HEADER_CELL_SELECTOR_PREFIX, pattern: escaped, field });
73
+ return this.rows.locator(`:is(td, th):nth-child(${cellIndex + 1})`);
74
+ }
75
+ }
76
+ //# sourceMappingURL=object.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"object.js","sourceRoot":"","sources":["../../../../../src/playwright/components/basic_table/object.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EAAE,UAAU,EAAoB,MAAM,mBAAmB,CAAC;AACjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,2CAA2C,CAAC;AAEnF;;;;;;;;;GASG;AACH,MAAM,OAAO,mBAAoB,SAAQ,UAAU;IACjD,YAAY,KAAkB,EAAE,QAAgB;QAC9C,KAAK,CAAC,KAAK,EAAE,QAAQ,EAAE,sBAAsB,CAAC,aAAa,CAAC,CAAC;IAC/D,CAAC;IAED;;;;;;;;;;OAUG;IACH,IAAW,IAAI;QACb,OAAO,IAAI,CAAC,IAAI;aACb,OAAO,CAAC,sBAAsB,CAAC,YAAY,CAAC;aAC5C,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;IACjE,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,KAAK,CAAC,KAAK,CAAC,KAAa;QACvB,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;QAC7D,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CACxC,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE,EAAE;YACrD,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,IAAI,MAAM,GAAG,OAAO,QAAQ,CAAC,CAAC;YACvD,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,oBAAoB,CAAC,CAAC,CAAC;YAC3E,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CACjC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC,CAChB,CAAC;YACtC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,IAAI,KAAK,CACb,oDAAoD,aAAa,iCAAiC,CACnG,CAAC;YACJ,CAAC;YACD,OAAO,MAAM,CAAC,SAAS,CAAC;QAC1B,CAAC,EACD,EAAE,MAAM,EAAE,sBAAsB,CAAC,2BAA2B,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CACxF,CAAC;QACF,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,yBAAyB,SAAS,GAAG,CAAC,GAAG,CAAC,CAAC;IACtE,CAAC;CACF"}
@@ -0,0 +1,21 @@
1
+ import { BaseObject, type ObjectScope } from '../../base_object';
2
+ /**
3
+ * Playwright Component Object for a keyboard-reorderable {@link
4
+ * https://eui.elastic.co/docs/components/drag-and-drop/ EuiDraggable} item.
5
+ *
6
+ * `testSubj` must be set on the item's own drag handle — with the default
7
+ * `customDragHandle={false}` that's the `EuiDraggable` item itself; with a
8
+ * custom handle it's that inner element instead. See the package README for
9
+ * details, the component-type guard, and why there's no settle-wait after a
10
+ * reorder.
11
+ */
12
+ export declare class EuiDraggableObject extends BaseObject {
13
+ constructor(scope: ObjectScope, testSubj: string);
14
+ /**
15
+ * Reorders the item via keyboard: focus the handle, lift it (`Space`),
16
+ * move it `steps` positions (`ArrowDown` for positive, `ArrowUp` for
17
+ * negative), drop it (`Space`). Keyboard lift, not a simulated mouse drag —
18
+ * `@hello-pangea/dnd`'s own accessible interaction.
19
+ */
20
+ reorder(steps: number): Promise<void>;
21
+ }
@@ -0,0 +1,40 @@
1
+ /*
2
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3
+ * or more contributor license agreements. Licensed under the Elastic License
4
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
5
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
6
+ * Side Public License, v 1.
7
+ */
8
+ import { BaseObject } from '../../base_object';
9
+ import { EuiDraggableSelectors } from '../../../components/drag_and_drop/selectors';
10
+ /**
11
+ * Playwright Component Object for a keyboard-reorderable {@link
12
+ * https://eui.elastic.co/docs/components/drag-and-drop/ EuiDraggable} item.
13
+ *
14
+ * `testSubj` must be set on the item's own drag handle — with the default
15
+ * `customDragHandle={false}` that's the `EuiDraggable` item itself; with a
16
+ * custom handle it's that inner element instead. See the package README for
17
+ * details, the component-type guard, and why there's no settle-wait after a
18
+ * reorder.
19
+ */
20
+ export class EuiDraggableObject extends BaseObject {
21
+ constructor(scope, testSubj) {
22
+ super(scope, testSubj, EuiDraggableSelectors.HANDLE_SELECTOR);
23
+ }
24
+ /**
25
+ * Reorders the item via keyboard: focus the handle, lift it (`Space`),
26
+ * move it `steps` positions (`ArrowDown` for positive, `ArrowUp` for
27
+ * negative), drop it (`Space`). Keyboard lift, not a simulated mouse drag —
28
+ * `@hello-pangea/dnd`'s own accessible interaction.
29
+ */
30
+ async reorder(steps) {
31
+ await this.root.focus();
32
+ await this.root.press('Space');
33
+ const key = steps > 0 ? 'ArrowDown' : 'ArrowUp';
34
+ for (let i = 0; i < Math.abs(steps); i++) {
35
+ await this.root.press(key);
36
+ }
37
+ await this.root.press('Space');
38
+ }
39
+ }
40
+ //# sourceMappingURL=object.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"object.js","sourceRoot":"","sources":["../../../../../src/playwright/components/drag_and_drop/object.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,UAAU,EAAoB,MAAM,mBAAmB,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,6CAA6C,CAAC;AAEpF;;;;;;;;;GASG;AACH,MAAM,OAAO,kBAAmB,SAAQ,UAAU;IAChD,YAAY,KAAkB,EAAE,QAAgB;QAC9C,KAAK,CAAC,KAAK,EAAE,QAAQ,EAAE,qBAAqB,CAAC,eAAe,CAAC,CAAC;IAChE,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,OAAO,CAAC,KAAa;QACzB,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QACxB,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC/B,MAAM,GAAG,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC;QAChD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YACzC,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC7B,CAAC;QACD,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACjC,CAAC;CACF"}
@@ -0,0 +1,31 @@
1
+ import type { Locator } from '@playwright/test';
2
+ import { BaseObject, type ObjectScope } from '../../base_object';
3
+ /**
4
+ * Playwright Component Object for {@link
5
+ * https://eui.elastic.co/docs/components/forms/filter-group/ EuiFilterButton}.
6
+ *
7
+ * `testSubj` must match the `data-test-subj` set by the consumer on the
8
+ * `<EuiFilterButton>` (EUI spreads it onto the button itself). Deliberately
9
+ * does not own opening/closing a popover triggered by the button — `EuiPopover`
10
+ * already sets `aria-expanded`/`aria-controls` on its toggle synchronously
11
+ * itself, so drive that from the test directly. It also does not own reading
12
+ * or selecting options inside that popover — when the popover content is an
13
+ * `EuiSelectable`, use {@link EuiSelectableObject} scoped to it instead.
14
+ */
15
+ export declare class EuiFilterButtonObject extends BaseObject {
16
+ constructor(scope: ObjectScope, testSubj: string);
17
+ /**
18
+ * The notification badge showing the available/active filter count, as a
19
+ * `Locator` so callers keep Playwright auto-retry for its text
20
+ * (e.g. `expect(filterButton.notificationBadge).toHaveText('2')`). Only
21
+ * present when the consumer passes `numFilters` or `numActiveFilters` —
22
+ * absent otherwise, so assert presence first if that is in question.
23
+ *
24
+ * For the button's own active/selected state, assert directly on
25
+ * {@link BaseObject.locator} rather than through a dedicated method — both
26
+ * are synchronous CSS classes EUI sets on the root
27
+ * (`euiFilterButton-hasActiveFilters`, `euiFilterButton-isSelected`), e.g.
28
+ * `expect(filterButton.locator).toHaveClass(/euiFilterButton-hasActiveFilters/)`.
29
+ */
30
+ get notificationBadge(): Locator;
31
+ }
@@ -0,0 +1,43 @@
1
+ /*
2
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3
+ * or more contributor license agreements. Licensed under the Elastic License
4
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
5
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
6
+ * Side Public License, v 1.
7
+ */
8
+ import { BaseObject } from '../../base_object';
9
+ import { EuiFilterButtonSelectors } from '../../../components/filter_button/selectors';
10
+ /**
11
+ * Playwright Component Object for {@link
12
+ * https://eui.elastic.co/docs/components/forms/filter-group/ EuiFilterButton}.
13
+ *
14
+ * `testSubj` must match the `data-test-subj` set by the consumer on the
15
+ * `<EuiFilterButton>` (EUI spreads it onto the button itself). Deliberately
16
+ * does not own opening/closing a popover triggered by the button — `EuiPopover`
17
+ * already sets `aria-expanded`/`aria-controls` on its toggle synchronously
18
+ * itself, so drive that from the test directly. It also does not own reading
19
+ * or selecting options inside that popover — when the popover content is an
20
+ * `EuiSelectable`, use {@link EuiSelectableObject} scoped to it instead.
21
+ */
22
+ export class EuiFilterButtonObject extends BaseObject {
23
+ constructor(scope, testSubj) {
24
+ super(scope, testSubj, EuiFilterButtonSelectors.ROOT_SELECTOR);
25
+ }
26
+ /**
27
+ * The notification badge showing the available/active filter count, as a
28
+ * `Locator` so callers keep Playwright auto-retry for its text
29
+ * (e.g. `expect(filterButton.notificationBadge).toHaveText('2')`). Only
30
+ * present when the consumer passes `numFilters` or `numActiveFilters` —
31
+ * absent otherwise, so assert presence first if that is in question.
32
+ *
33
+ * For the button's own active/selected state, assert directly on
34
+ * {@link BaseObject.locator} rather than through a dedicated method — both
35
+ * are synchronous CSS classes EUI sets on the root
36
+ * (`euiFilterButton-hasActiveFilters`, `euiFilterButton-isSelected`), e.g.
37
+ * `expect(filterButton.locator).toHaveClass(/euiFilterButton-hasActiveFilters/)`.
38
+ */
39
+ get notificationBadge() {
40
+ return this.root.locator(EuiFilterButtonSelectors.NOTIFICATION_SELECTOR);
41
+ }
42
+ }
43
+ //# sourceMappingURL=object.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"object.js","sourceRoot":"","sources":["../../../../../src/playwright/components/filter_button/object.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EAAE,UAAU,EAAoB,MAAM,mBAAmB,CAAC;AACjE,OAAO,EAAE,wBAAwB,EAAE,MAAM,6CAA6C,CAAC;AAEvF;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,qBAAsB,SAAQ,UAAU;IACnD,YAAY,KAAkB,EAAE,QAAgB;QAC9C,KAAK,CAAC,KAAK,EAAE,QAAQ,EAAE,wBAAwB,CAAC,aAAa,CAAC,CAAC;IACjE,CAAC;IAED;;;;;;;;;;;;OAYG;IACH,IAAW,iBAAiB;QAC1B,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,wBAAwB,CAAC,qBAAqB,CAAC,CAAC;IAC3E,CAAC;CACF"}
@@ -0,0 +1,25 @@
1
+ import type { Locator } from '@playwright/test';
2
+ import { BaseObject, type ObjectScope } from '../../../base_object';
3
+ /**
4
+ * Playwright Component Object for {@link
5
+ * https://eui.elastic.co/docs/components/forms/range-controls/ EuiRange} and
6
+ * `EuiDualRange`.
7
+ *
8
+ * `testSubj` must match the `data-test-subj` set by the consumer on the
9
+ * `<EuiRange>`/`<EuiDualRange>`. See the package README for why `slider` and
10
+ * `numberInput` disambiguate by class, and what this does not cover.
11
+ */
12
+ export declare class EuiRangeObject extends BaseObject {
13
+ constructor(scope: ObjectScope, testSubj: string);
14
+ /**
15
+ * The native range slider input. Resolves to exactly one element once
16
+ * mounted. With `showInput="inputWithPopover"`, it lives inside the
17
+ * popover panel and is not mounted until the popover opens.
18
+ */
19
+ get slider(): Locator;
20
+ /**
21
+ * The visible number input, present only with `showInput`. Resolves to
22
+ * zero elements otherwise.
23
+ */
24
+ get numberInput(): Locator;
25
+ }
@@ -0,0 +1,39 @@
1
+ /*
2
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3
+ * or more contributor license agreements. Licensed under the Elastic License
4
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
5
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
6
+ * Side Public License, v 1.
7
+ */
8
+ import { BaseObject } from '../../../base_object';
9
+ import { EuiRangeSelectors } from '../../../../components/form/range/selectors';
10
+ /**
11
+ * Playwright Component Object for {@link
12
+ * https://eui.elastic.co/docs/components/forms/range-controls/ EuiRange} and
13
+ * `EuiDualRange`.
14
+ *
15
+ * `testSubj` must match the `data-test-subj` set by the consumer on the
16
+ * `<EuiRange>`/`<EuiDualRange>`. See the package README for why `slider` and
17
+ * `numberInput` disambiguate by class, and what this does not cover.
18
+ */
19
+ export class EuiRangeObject extends BaseObject {
20
+ constructor(scope, testSubj) {
21
+ super(scope, testSubj, EuiRangeSelectors.SLIDER_SELECTOR);
22
+ }
23
+ /**
24
+ * The native range slider input. Resolves to exactly one element once
25
+ * mounted. With `showInput="inputWithPopover"`, it lives inside the
26
+ * popover panel and is not mounted until the popover opens.
27
+ */
28
+ get slider() {
29
+ return this.root.and(this.scope.locator(EuiRangeSelectors.SLIDER_SELECTOR));
30
+ }
31
+ /**
32
+ * The visible number input, present only with `showInput`. Resolves to
33
+ * zero elements otherwise.
34
+ */
35
+ get numberInput() {
36
+ return this.root.and(this.scope.locator(EuiRangeSelectors.NUMBER_INPUT_SELECTOR));
37
+ }
38
+ }
39
+ //# sourceMappingURL=object.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"object.js","sourceRoot":"","sources":["../../../../../../src/playwright/components/form/range/object.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EAAE,UAAU,EAAoB,MAAM,sBAAsB,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,6CAA6C,CAAC;AAEhF;;;;;;;;GAQG;AACH,MAAM,OAAO,cAAe,SAAQ,UAAU;IAC5C,YAAY,KAAkB,EAAE,QAAgB;QAC9C,KAAK,CAAC,KAAK,EAAE,QAAQ,EAAE,iBAAiB,CAAC,eAAe,CAAC,CAAC;IAC5D,CAAC;IAED;;;;OAIG;IACH,IAAW,MAAM;QACf,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,iBAAiB,CAAC,eAAe,CAAC,CAAC,CAAC;IAC9E,CAAC;IAED;;;OAGG;IACH,IAAW,WAAW;QACpB,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,iBAAiB,CAAC,qBAAqB,CAAC,CAAC,CAAC;IACpF,CAAC;CACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elastic/eui-test-helpers",
3
- "version": "1.4.0",
3
+ "version": "1.5.0",
4
4
  "description": "A library of EUI test helpers for RTL, Cypress and Scout",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "repository": {
@@ -0,0 +1,30 @@
1
+ # EuiBasicTableObject
2
+
3
+ Playwright Component Object for [EuiBasicTable](https://eui.elastic.co/docs/components/tabular-content/tables/). Also covers `EuiInMemoryTable`, which renders a `EuiBasicTable` underneath and passes the `data-test-subj` straight through — there is no separate object for it.
4
+
5
+ ## Usage
6
+
7
+ ```ts
8
+ import { EuiBasicTableObject } from '@elastic/eui-test-helpers';
9
+
10
+ const table = new EuiBasicTableObject(page, 'myTable');
11
+ expect(await table.rows).toHaveCount(3);
12
+ expect(await table.cells('status')).toHaveText(['Running', 'Finished', 'Archived']);
13
+ ```
14
+
15
+ Set `data-test-subj` on the `<EuiBasicTable>`/`<EuiInMemoryTable>` (EUI spreads it onto the `.euiBasicTable` root, which the component-type guard verifies).
16
+
17
+ ## API
18
+
19
+ | Member | Description |
20
+ |---|---|
21
+ | `rows` | `Locator` for the table's data rows, excluding EUI's own "no items found"/error-message row. |
22
+ | `cells(field)` | `Locator` for a field-data column's cells across all rows, resolved from EUI's own header `data-test-subj`. |
23
+
24
+ `rows` excludes EUI's empty/error message row by filtering out any row whose cell carries a `colspan` — real data rows don't set one, EUI's own placeholder row always does (it spans every column).
25
+
26
+ `cells(field)` resolves the column's position from the header cell EUI renders as `tableHeaderCell_<field>_<index>` (matched exactly, so a column named `status` won't also match a `status_detail` header), then reads the cell at that position in every row. This holds regardless of a leading selection-checkbox column, since the checkbox column is a real cell in both the header and body rows, and it matches both `<td>` and `<th>` since EUI renders a `rowHeader` column's body cell as `<th scope="row">`. Throws if no column with that `field` is rendered.
27
+
28
+ ## Deliberately excluded
29
+
30
+ Row actions (consumer-supplied popovers/buttons), sorting, and pagination are not covered. They are either app-specific wiring rather than EUI-internal DOM knowledge, or had no evidenced consumer need at the time this was written. Open an issue with a concrete use case if you need one of them.
@@ -0,0 +1,23 @@
1
+ # EuiDraggableObject
2
+
3
+ Playwright Component Object for [EuiDraggable](https://eui.elastic.co/docs/components/drag-and-drop/), keyboard-reordering items instead of simulating a mouse drag.
4
+
5
+ ## Usage
6
+
7
+ ```ts
8
+ import { EuiDraggableObject } from '@elastic/eui-test-helpers';
9
+
10
+ const item = new EuiDraggableObject(page, 'myItemDragHandle');
11
+ await item.reorder(2); // move 2 positions later
12
+ await item.reorder(-1); // move 1 position earlier
13
+ ```
14
+
15
+ Set `data-test-subj` on the item's own drag handle — the element EUI's `provided.dragHandleProps` are spread onto. With the default `customDragHandle={false}`, that's the `<EuiDraggable>` item itself (as in the usage example above and the `Playground` story), since EUI spreads `dragHandleProps` onto the same element as `draggableProps` in that case. Only with a `customDragHandle` does the handle become a distinct inner element, and `data-test-subj` must move there instead. The component-type guard checks for the `data-rfd-drag-handle-draggable-id` attribute `@hello-pangea/dnd` spreads onto an *enabled* handle, since the handle markup itself is consumer-defined, not a fixed EUI class. A disabled draggable's handle lacks that attribute, so pointing this object at one throws the same "wrong component" error as pointing it at a non-handle element — a disabled item can't be reordered either way.
16
+
17
+ ## API
18
+
19
+ | Member | Description |
20
+ |---|---|
21
+ | `reorder(steps)` | Focuses the handle, lifts it, moves it `steps` positions (`ArrowDown` for positive, `ArrowUp` for negative), drops it. |
22
+
23
+ `reorder` drives `EuiDraggable` (which wraps `@hello-pangea/dnd`) via its keyboard interaction — the library's own accessible alternative to a mouse drag, and one that doesn't require simulating drag events. It does not wait for a settle signal after dropping: EUI doesn't expose a synchronous, stable one (the `euiDraggable--isDragging` class some consumers checked for hasn't existed since this styling moved to Emotion — that check was always a no-op). Assert the resulting order with a retrying `expect`, which settles on its own.