@elastic/eui-test-helpers 2.1.0 → 2.2.0-snapshot.1793244789306
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/README.md +6 -0
- package/lib/cjs/components/call_out/selectors.d.ts +22 -0
- package/lib/cjs/components/call_out/selectors.js +36 -0
- package/lib/cjs/components/form/field_search/selectors.d.ts +11 -0
- package/lib/cjs/components/form/field_search/selectors.js +25 -0
- package/lib/cjs/components/pagination/selectors.d.ts +21 -0
- package/lib/cjs/components/pagination/selectors.js +35 -0
- package/lib/cjs/components/search_bar/selectors.d.ts +11 -0
- package/lib/cjs/components/search_bar/selectors.js +25 -0
- package/lib/cjs/components/side_nav/selectors.d.ts +21 -0
- package/lib/cjs/components/side_nav/selectors.js +35 -0
- package/lib/cjs/components/table/selectors.d.ts +15 -0
- package/lib/cjs/components/table/selectors.js +29 -0
- package/lib/cjs/index.d.ts +6 -0
- package/lib/cjs/index.js +66 -24
- package/lib/cjs/playwright/components/basic_table/object.d.ts +7 -12
- package/lib/cjs/playwright/components/basic_table/object.js +7 -13
- package/lib/cjs/playwright/components/call_out/object.d.ts +36 -0
- package/lib/cjs/playwright/components/call_out/object.js +84 -0
- package/lib/cjs/playwright/components/form/field_search/object.d.ts +21 -0
- package/lib/cjs/playwright/components/form/field_search/object.js +51 -0
- package/lib/cjs/playwright/components/pagination/object.d.ts +37 -0
- package/lib/cjs/playwright/components/pagination/object.js +121 -0
- package/lib/cjs/playwright/components/search_bar/object.d.ts +12 -0
- package/lib/cjs/playwright/components/search_bar/object.js +26 -0
- package/lib/cjs/playwright/components/side_nav/object.d.ts +34 -0
- package/lib/cjs/playwright/components/side_nav/object.js +84 -0
- package/lib/cjs/playwright/components/table/object.d.ts +28 -0
- package/lib/cjs/playwright/components/table/object.js +57 -0
- package/lib/cjs/selectors.d.ts +42 -0
- package/lib/cjs/selectors.js +42 -30
- package/lib/esm/components/call_out/selectors.d.ts +22 -0
- package/lib/esm/components/call_out/selectors.js +30 -0
- package/lib/esm/components/call_out/selectors.js.map +1 -0
- package/lib/esm/components/form/field_search/selectors.d.ts +11 -0
- package/lib/esm/components/form/field_search/selectors.js +19 -0
- package/lib/esm/components/form/field_search/selectors.js.map +1 -0
- package/lib/esm/components/pagination/selectors.d.ts +21 -0
- package/lib/esm/components/pagination/selectors.js +29 -0
- package/lib/esm/components/pagination/selectors.js.map +1 -0
- package/lib/esm/components/search_bar/selectors.d.ts +11 -0
- package/lib/esm/components/search_bar/selectors.js +19 -0
- package/lib/esm/components/search_bar/selectors.js.map +1 -0
- package/lib/esm/components/side_nav/selectors.d.ts +21 -0
- package/lib/esm/components/side_nav/selectors.js +29 -0
- package/lib/esm/components/side_nav/selectors.js.map +1 -0
- package/lib/esm/components/table/selectors.d.ts +15 -0
- package/lib/esm/components/table/selectors.js +23 -0
- package/lib/esm/components/table/selectors.js.map +1 -0
- package/lib/esm/index.d.ts +6 -0
- package/lib/esm/index.js +6 -0
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/playwright/components/basic_table/object.d.ts +7 -12
- package/lib/esm/playwright/components/basic_table/object.js +7 -15
- package/lib/esm/playwright/components/basic_table/object.js.map +1 -1
- package/lib/esm/playwright/components/call_out/object.d.ts +36 -0
- package/lib/esm/playwright/components/call_out/object.js +72 -0
- package/lib/esm/playwright/components/call_out/object.js.map +1 -0
- package/lib/esm/playwright/components/form/field_search/object.d.ts +21 -0
- package/lib/esm/playwright/components/form/field_search/object.js +41 -0
- package/lib/esm/playwright/components/form/field_search/object.js.map +1 -0
- package/lib/esm/playwright/components/pagination/object.d.ts +37 -0
- package/lib/esm/playwright/components/pagination/object.js +118 -0
- package/lib/esm/playwright/components/pagination/object.js.map +1 -0
- package/lib/esm/playwright/components/search_bar/object.d.ts +12 -0
- package/lib/esm/playwright/components/search_bar/object.js +20 -0
- package/lib/esm/playwright/components/search_bar/object.js.map +1 -0
- package/lib/esm/playwright/components/side_nav/object.d.ts +34 -0
- package/lib/esm/playwright/components/side_nav/object.js +76 -0
- package/lib/esm/playwright/components/side_nav/object.js.map +1 -0
- package/lib/esm/playwright/components/table/object.d.ts +28 -0
- package/lib/esm/playwright/components/table/object.js +46 -0
- package/lib/esm/playwright/components/table/object.js.map +1 -0
- package/lib/esm/selectors.d.ts +42 -0
- package/lib/esm/selectors.js +12 -0
- package/lib/esm/selectors.js.map +1 -1
- package/package.json +3 -2
- package/src/components/basic_table/README.md +1 -0
- package/src/components/call_out/README.md +29 -0
- package/src/components/form/field_search/README.md +29 -0
- package/src/components/pagination/README.md +31 -0
- package/src/components/search_bar/README.md +18 -0
- package/src/components/side_nav/README.md +31 -0
- package/src/components/table/README.md +31 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.EuiCallOutObject = void 0;
|
|
7
|
+
var _base_object = require("../../base_object");
|
|
8
|
+
var _selectors = require("../../../components/call_out/selectors");
|
|
9
|
+
/*
|
|
10
|
+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
11
|
+
* or more contributor license agreements. Licensed under the Elastic License
|
|
12
|
+
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
|
13
|
+
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
|
14
|
+
* Side Public License, v 1.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Playwright Component Object for {@link
|
|
19
|
+
* https://eui.elastic.co/docs/components/display/callout/ EuiCallOut}.
|
|
20
|
+
*
|
|
21
|
+
* `testSubj` must be set on `EuiCallOut` itself. EUI puts it on the panel
|
|
22
|
+
* root and derives `<subj>__message`, `<subj>__content` and
|
|
23
|
+
* `<subj>__actions` for the inner blocks, which the token based root lookup
|
|
24
|
+
* does not confuse with the root.
|
|
25
|
+
*/
|
|
26
|
+
class EuiCallOutObject extends _base_object.BaseObject {
|
|
27
|
+
constructor(scope, testSubj) {
|
|
28
|
+
super(scope, testSubj, _selectors.EuiCallOutSelectors.ROOT_SELECTOR);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** The call out element itself, see {@link panel}. */
|
|
32
|
+
get locator() {
|
|
33
|
+
return this.panel;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** The title text, or an empty string when the call out has no title. */
|
|
37
|
+
async getTitle() {
|
|
38
|
+
return this.textOf(this.panel.locator(_selectors.EuiCallOutSelectors.TITLE_SELECTOR));
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** The `text` block, or an empty string when the call out has none. */
|
|
42
|
+
async getText() {
|
|
43
|
+
return this.textOf(this.panel.locator(_selectors.EuiCallOutSelectors.TEXT_SELECTOR));
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** The color variant: `primary`, `success`, `warning` or `danger`. */
|
|
47
|
+
async getColor() {
|
|
48
|
+
const className = (await this.panel.getAttribute('class')) ?? '';
|
|
49
|
+
const match = className.match(new RegExp(`\\b${_selectors.EuiCallOutSelectors.COLOR_CLASS_PREFIX}([a-z]+)`));
|
|
50
|
+
if (!match) {
|
|
51
|
+
throw new Error(`EuiCallOut "${this.testSubj}" has no color class, is it an EuiCallOut?`);
|
|
52
|
+
}
|
|
53
|
+
return match[1];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** The dismiss button. Resolves to zero elements without `onDismiss`. */
|
|
57
|
+
get dismissButton() {
|
|
58
|
+
return this.panel.locator(_selectors.EuiCallOutSelectors.DISMISS_BUTTON_SELECTOR).first();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* The root narrowed to the call out element. A multi token subj such as
|
|
63
|
+
* `notice shared` also matches the derived `notice shared__message` block
|
|
64
|
+
* by token, so the class keeps lookups on the panel itself.
|
|
65
|
+
*/
|
|
66
|
+
get panel() {
|
|
67
|
+
return this.root.and(this.scope.locator(_selectors.EuiCallOutSelectors.ROOT_SELECTOR));
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Click the dismiss button. What happens next is up to the consumer's
|
|
72
|
+
* `onDismiss`, usually unmounting the call out, so nothing is asserted.
|
|
73
|
+
*/
|
|
74
|
+
async dismiss() {
|
|
75
|
+
await this.dismissButton.click();
|
|
76
|
+
}
|
|
77
|
+
async textOf(element) {
|
|
78
|
+
if ((await element.count()) === 0) {
|
|
79
|
+
return '';
|
|
80
|
+
}
|
|
81
|
+
return element.first().innerText();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
exports.EuiCallOutObject = EuiCallOutObject;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { BaseObject, type ObjectScope } from '../../../base_object';
|
|
2
|
+
/**
|
|
3
|
+
* Playwright Component Object for {@link
|
|
4
|
+
* https://eui.elastic.co/docs/components/forms/search-and-filter/search/ EuiFieldSearch}.
|
|
5
|
+
*
|
|
6
|
+
* `testSubj` must be set on `EuiFieldSearch` itself, EUI spreads it onto
|
|
7
|
+
* the `<input>`. `EuiSearchBar` renders this input for its box, see
|
|
8
|
+
* `EuiSearchBarObject`.
|
|
9
|
+
*/
|
|
10
|
+
export declare class EuiFieldSearchObject extends BaseObject {
|
|
11
|
+
constructor(scope: ObjectScope, testSubj: string, componentSelector?: string);
|
|
12
|
+
/**
|
|
13
|
+
* Replace the text and submit it with Enter, which triggers `onSearch` for
|
|
14
|
+
* both the incremental and the plain variant.
|
|
15
|
+
*/
|
|
16
|
+
setQuery(text: string): Promise<void>;
|
|
17
|
+
/** The current text of the input. */
|
|
18
|
+
getQuery(): Promise<string>;
|
|
19
|
+
/** Empty the input and submit, so `onSearch` receives an empty query. */
|
|
20
|
+
clear(): Promise<void>;
|
|
21
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.EuiFieldSearchObject = void 0;
|
|
7
|
+
var _test = require("@playwright/test");
|
|
8
|
+
var _base_object = require("../../../base_object");
|
|
9
|
+
var _selectors = require("../../../../components/form/field_search/selectors");
|
|
10
|
+
/*
|
|
11
|
+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
12
|
+
* or more contributor license agreements. Licensed under the Elastic License
|
|
13
|
+
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
|
14
|
+
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
|
15
|
+
* Side Public License, v 1.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Playwright Component Object for {@link
|
|
20
|
+
* https://eui.elastic.co/docs/components/forms/search-and-filter/search/ EuiFieldSearch}.
|
|
21
|
+
*
|
|
22
|
+
* `testSubj` must be set on `EuiFieldSearch` itself, EUI spreads it onto
|
|
23
|
+
* the `<input>`. `EuiSearchBar` renders this input for its box, see
|
|
24
|
+
* `EuiSearchBarObject`.
|
|
25
|
+
*/
|
|
26
|
+
class EuiFieldSearchObject extends _base_object.BaseObject {
|
|
27
|
+
constructor(scope, testSubj, componentSelector = _selectors.EuiFieldSearchSelectors.ROOT_SELECTOR) {
|
|
28
|
+
super(scope, testSubj, componentSelector);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Replace the text and submit it with Enter, which triggers `onSearch` for
|
|
33
|
+
* both the incremental and the plain variant.
|
|
34
|
+
*/
|
|
35
|
+
async setQuery(text) {
|
|
36
|
+
await this.root.fill(text);
|
|
37
|
+
await (0, _test.expect)(this.root).toHaveValue(text);
|
|
38
|
+
await this.root.press('Enter');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** The current text of the input. */
|
|
42
|
+
async getQuery() {
|
|
43
|
+
return this.root.inputValue();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** Empty the input and submit, so `onSearch` receives an empty query. */
|
|
47
|
+
async clear() {
|
|
48
|
+
await this.setQuery('');
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
exports.EuiFieldSearchObject = EuiFieldSearchObject;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { BaseObject, type ObjectScope } from '../../base_object';
|
|
2
|
+
/**
|
|
3
|
+
* Playwright Component Object for {@link
|
|
4
|
+
* https://eui.elastic.co/docs/components/navigation/pagination/ EuiPagination}.
|
|
5
|
+
*
|
|
6
|
+
* `testSubj` must be set on `EuiPagination` itself, EUI spreads it onto the
|
|
7
|
+
* `<nav>`. Page indexes are 0-based, matching EUI's `activePage` and the
|
|
8
|
+
* `pagination-button-<index>` test subjs. Covers the numbered and the
|
|
9
|
+
* compressed variant.
|
|
10
|
+
*/
|
|
11
|
+
export declare class EuiPaginationObject extends BaseObject {
|
|
12
|
+
constructor(scope: ObjectScope, testSubj: string);
|
|
13
|
+
/** The 0-based index of the active page. */
|
|
14
|
+
getActivePage(): Promise<number>;
|
|
15
|
+
/** The total number of pages. */
|
|
16
|
+
getPageCount(): Promise<number>;
|
|
17
|
+
/**
|
|
18
|
+
* Go to the page at the 0-based `index` and wait for it to become active.
|
|
19
|
+
* Clicks the page button when EUI renders it, otherwise steps through
|
|
20
|
+
* next or previous until it does. A no-op if already active. Throws if
|
|
21
|
+
* `index` is not a page, or the page never becomes active.
|
|
22
|
+
*/
|
|
23
|
+
goToPage(index: number): Promise<void>;
|
|
24
|
+
/** Click the next arrow and wait for the active page to advance. */
|
|
25
|
+
next(): Promise<void>;
|
|
26
|
+
/** Click the previous arrow and wait for the active page to go back. */
|
|
27
|
+
previous(): Promise<void>;
|
|
28
|
+
private pageButton;
|
|
29
|
+
private arrow;
|
|
30
|
+
private isCompressed;
|
|
31
|
+
/**
|
|
32
|
+
* The compressed "page of total" numbers as [page, total]. Translations may
|
|
33
|
+
* order the two the other way round, and the page is never above the total,
|
|
34
|
+
* so the smaller one is the page.
|
|
35
|
+
*/
|
|
36
|
+
private compressedNumbers;
|
|
37
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.EuiPaginationObject = void 0;
|
|
7
|
+
var _test = require("@playwright/test");
|
|
8
|
+
var _base_object = require("../../base_object");
|
|
9
|
+
var _selectors = require("../../../components/pagination/selectors");
|
|
10
|
+
/*
|
|
11
|
+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
12
|
+
* or more contributor license agreements. Licensed under the Elastic License
|
|
13
|
+
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
|
14
|
+
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
|
15
|
+
* Side Public License, v 1.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Playwright Component Object for {@link
|
|
20
|
+
* https://eui.elastic.co/docs/components/navigation/pagination/ EuiPagination}.
|
|
21
|
+
*
|
|
22
|
+
* `testSubj` must be set on `EuiPagination` itself, EUI spreads it onto the
|
|
23
|
+
* `<nav>`. Page indexes are 0-based, matching EUI's `activePage` and the
|
|
24
|
+
* `pagination-button-<index>` test subjs. Covers the numbered and the
|
|
25
|
+
* compressed variant.
|
|
26
|
+
*/
|
|
27
|
+
class EuiPaginationObject extends _base_object.BaseObject {
|
|
28
|
+
constructor(scope, testSubj) {
|
|
29
|
+
super(scope, testSubj, _selectors.EuiPaginationSelectors.ROOT_SELECTOR);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** The 0-based index of the active page. */
|
|
33
|
+
async getActivePage() {
|
|
34
|
+
if (await this.isCompressed()) {
|
|
35
|
+
const [page] = await this.compressedNumbers();
|
|
36
|
+
return page - 1;
|
|
37
|
+
}
|
|
38
|
+
const text = await this.root.locator(_selectors.EuiPaginationSelectors.ACTIVE_PAGE_BUTTON_SELECTOR).innerText();
|
|
39
|
+
return Number(text) - 1;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** The total number of pages. */
|
|
43
|
+
async getPageCount() {
|
|
44
|
+
if (await this.isCompressed()) {
|
|
45
|
+
const [, total] = await this.compressedNumbers();
|
|
46
|
+
return total;
|
|
47
|
+
}
|
|
48
|
+
// EUI always renders the last page's button, so its label is the count.
|
|
49
|
+
return Number(await this.root.locator(_selectors.EuiPaginationSelectors.PAGE_BUTTON_SELECTOR).last().innerText());
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Go to the page at the 0-based `index` and wait for it to become active.
|
|
54
|
+
* Clicks the page button when EUI renders it, otherwise steps through
|
|
55
|
+
* next or previous until it does. A no-op if already active. Throws if
|
|
56
|
+
* `index` is not a page, or the page never becomes active.
|
|
57
|
+
*/
|
|
58
|
+
async goToPage(index) {
|
|
59
|
+
const pageCount = await this.getPageCount();
|
|
60
|
+
if (!Number.isInteger(index) || index < 0 || index >= pageCount) {
|
|
61
|
+
throw new Error(`EuiPagination "${this.testSubj}" has ${pageCount} pages, page index ${index} is out of range.`);
|
|
62
|
+
}
|
|
63
|
+
for (let step = 0; step < pageCount; step++) {
|
|
64
|
+
const active = await this.getActivePage();
|
|
65
|
+
if (active === index) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const button = this.pageButton(index);
|
|
69
|
+
if ((await button.count()) > 0) {
|
|
70
|
+
await button.click();
|
|
71
|
+
} else if (index > active) {
|
|
72
|
+
await this.arrow(_selectors.EuiPaginationSelectors.NEXT_BUTTON_TEST_SUBJ).click();
|
|
73
|
+
} else {
|
|
74
|
+
await this.arrow(_selectors.EuiPaginationSelectors.PREVIOUS_BUTTON_TEST_SUBJ).click();
|
|
75
|
+
}
|
|
76
|
+
await _test.expect.poll(() => this.getActivePage()).not.toBe(active);
|
|
77
|
+
}
|
|
78
|
+
if ((await this.getActivePage()) !== index) {
|
|
79
|
+
throw new Error(`EuiPagination "${this.testSubj}" did not reach page index ${index} after ${pageCount} steps.`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/** Click the next arrow and wait for the active page to advance. */
|
|
84
|
+
async next() {
|
|
85
|
+
const active = await this.getActivePage();
|
|
86
|
+
await this.arrow(_selectors.EuiPaginationSelectors.NEXT_BUTTON_TEST_SUBJ).click();
|
|
87
|
+
await _test.expect.poll(() => this.getActivePage()).toBe(active + 1);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** Click the previous arrow and wait for the active page to go back. */
|
|
91
|
+
async previous() {
|
|
92
|
+
const active = await this.getActivePage();
|
|
93
|
+
await this.arrow(_selectors.EuiPaginationSelectors.PREVIOUS_BUTTON_TEST_SUBJ).click();
|
|
94
|
+
await _test.expect.poll(() => this.getActivePage()).toBe(active - 1);
|
|
95
|
+
}
|
|
96
|
+
pageButton(index) {
|
|
97
|
+
return this.root.getByTestId(`${_selectors.EuiPaginationSelectors.PAGE_BUTTON_TEST_SUBJ_PREFIX}${index}`);
|
|
98
|
+
}
|
|
99
|
+
arrow(testSubj) {
|
|
100
|
+
return this.root.getByTestId(testSubj);
|
|
101
|
+
}
|
|
102
|
+
async isCompressed() {
|
|
103
|
+
// count() does not wait, so make sure the nav has rendered first.
|
|
104
|
+
await this.root.waitFor({
|
|
105
|
+
state: 'visible'
|
|
106
|
+
});
|
|
107
|
+
return (await this.root.locator(_selectors.EuiPaginationSelectors.COMPRESSED_TEXT_SELECTOR).count()) > 0;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* The compressed "page of total" numbers as [page, total]. Translations may
|
|
112
|
+
* order the two the other way round, and the page is never above the total,
|
|
113
|
+
* so the smaller one is the page.
|
|
114
|
+
*/
|
|
115
|
+
async compressedNumbers() {
|
|
116
|
+
const texts = await this.root.locator(_selectors.EuiPaginationSelectors.COMPRESSED_TEXT_SELECTOR).locator('span').allInnerTexts();
|
|
117
|
+
const numbers = texts.map(Number);
|
|
118
|
+
return [Math.min(...numbers), Math.max(...numbers)];
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
exports.EuiPaginationObject = EuiPaginationObject;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { EuiFieldSearchObject } from '../form/field_search/object';
|
|
2
|
+
/**
|
|
3
|
+
* Playwright Component Object for {@link
|
|
4
|
+
* https://eui.elastic.co/docs/components/forms/search-and-filter/search-bar/ EuiSearchBar}.
|
|
5
|
+
*
|
|
6
|
+
* The search bar has no root of its own, the consumer's `data-test-subj` is
|
|
7
|
+
* passed through the `box` prop onto the `EuiFieldSearch` input. So this is
|
|
8
|
+
* the field search object under the component's own name. Set
|
|
9
|
+
* `box={{ 'data-test-subj': 'mySearchBar' }}` and construct with that subj.
|
|
10
|
+
*/
|
|
11
|
+
export declare class EuiSearchBarObject extends EuiFieldSearchObject {
|
|
12
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.EuiSearchBarObject = void 0;
|
|
7
|
+
var _object = require("../form/field_search/object");
|
|
8
|
+
/*
|
|
9
|
+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
10
|
+
* or more contributor license agreements. Licensed under the Elastic License
|
|
11
|
+
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
|
12
|
+
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
|
13
|
+
* Side Public License, v 1.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Playwright Component Object for {@link
|
|
18
|
+
* https://eui.elastic.co/docs/components/forms/search-and-filter/search-bar/ EuiSearchBar}.
|
|
19
|
+
*
|
|
20
|
+
* The search bar has no root of its own, the consumer's `data-test-subj` is
|
|
21
|
+
* passed through the `box` prop onto the `EuiFieldSearch` input. So this is
|
|
22
|
+
* the field search object under the component's own name. Set
|
|
23
|
+
* `box={{ 'data-test-subj': 'mySearchBar' }}` and construct with that subj.
|
|
24
|
+
*/
|
|
25
|
+
class EuiSearchBarObject extends _object.EuiFieldSearchObject {}
|
|
26
|
+
exports.EuiSearchBarObject = EuiSearchBarObject;
|
|
@@ -0,0 +1,34 @@
|
|
|
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/navigation/side-nav/ EuiSideNav}.
|
|
6
|
+
*
|
|
7
|
+
* `testSubj` must be set on `EuiSideNav` itself, EUI spreads it onto the
|
|
8
|
+
* `<nav>`. Items are addressed by their exact label. Closed branches are
|
|
9
|
+
* not in the DOM, expand their parent first.
|
|
10
|
+
*/
|
|
11
|
+
export declare class EuiSideNavObject extends BaseObject {
|
|
12
|
+
constructor(scope: ObjectScope, testSubj: string);
|
|
13
|
+
/** The labels of every rendered item, in document order. */
|
|
14
|
+
getItems(): Promise<string[]>;
|
|
15
|
+
/**
|
|
16
|
+
* The clickable element of the item with exactly this label. Matches the
|
|
17
|
+
* label span, so icon text does not interfere, then climbs to its button.
|
|
18
|
+
* Chained from `root`, so it stays in the root's frame.
|
|
19
|
+
*/
|
|
20
|
+
item(label: string): Locator;
|
|
21
|
+
/**
|
|
22
|
+
* Click the item with this label. Selection is owned by the consumer
|
|
23
|
+
* (usually a route change), so nothing is asserted afterwards.
|
|
24
|
+
*/
|
|
25
|
+
select(label: string): Promise<void>;
|
|
26
|
+
/** The label of the selected item, or null when none is selected. */
|
|
27
|
+
getSelected(): Promise<string | null>;
|
|
28
|
+
/**
|
|
29
|
+
* Expand an accordion item (one with children and no link or click
|
|
30
|
+
* handler) and wait for its children to render. A no-op if already open.
|
|
31
|
+
*/
|
|
32
|
+
expand(label: string): Promise<void>;
|
|
33
|
+
private isOpen;
|
|
34
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.EuiSideNavObject = void 0;
|
|
7
|
+
var _test = require("@playwright/test");
|
|
8
|
+
var _base_object = require("../../base_object");
|
|
9
|
+
var _selectors = require("../../../components/side_nav/selectors");
|
|
10
|
+
/*
|
|
11
|
+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
12
|
+
* or more contributor license agreements. Licensed under the Elastic License
|
|
13
|
+
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
|
14
|
+
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
|
15
|
+
* Side Public License, v 1.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Playwright Component Object for {@link
|
|
20
|
+
* https://eui.elastic.co/docs/components/navigation/side-nav/ EuiSideNav}.
|
|
21
|
+
*
|
|
22
|
+
* `testSubj` must be set on `EuiSideNav` itself, EUI spreads it onto the
|
|
23
|
+
* `<nav>`. Items are addressed by their exact label. Closed branches are
|
|
24
|
+
* not in the DOM, expand their parent first.
|
|
25
|
+
*/
|
|
26
|
+
class EuiSideNavObject extends _base_object.BaseObject {
|
|
27
|
+
constructor(scope, testSubj) {
|
|
28
|
+
super(scope, testSubj, _selectors.EuiSideNavSelectors.ROOT_SELECTOR);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** The labels of every rendered item, in document order. */
|
|
32
|
+
async getItems() {
|
|
33
|
+
return this.root.locator(_selectors.EuiSideNavSelectors.ITEM_LABEL_SELECTOR).allInnerTexts();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* The clickable element of the item with exactly this label. Matches the
|
|
38
|
+
* label span, so icon text does not interfere, then climbs to its button.
|
|
39
|
+
* Chained from `root`, so it stays in the root's frame.
|
|
40
|
+
*/
|
|
41
|
+
item(label) {
|
|
42
|
+
return this.root.locator(_selectors.EuiSideNavSelectors.ITEM_LABEL_SELECTOR).filter({
|
|
43
|
+
hasText: new RegExp(`^${escapeRegExp(label)}$`)
|
|
44
|
+
}).locator(ITEM_BUTTON_ANCESTOR_XPATH);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Click the item with this label. Selection is owned by the consumer
|
|
49
|
+
* (usually a route change), so nothing is asserted afterwards.
|
|
50
|
+
*/
|
|
51
|
+
async select(label) {
|
|
52
|
+
await this.item(label).click();
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** The label of the selected item, or null when none is selected. */
|
|
56
|
+
async getSelected() {
|
|
57
|
+
const selected = this.root.locator(_selectors.EuiSideNavSelectors.SELECTED_ITEM_BUTTON_SELECTOR).locator(_selectors.EuiSideNavSelectors.ITEM_LABEL_SELECTOR);
|
|
58
|
+
if ((await selected.count()) === 0) {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
return selected.first().innerText();
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Expand an accordion item (one with children and no link or click
|
|
66
|
+
* handler) and wait for its children to render. A no-op if already open.
|
|
67
|
+
*/
|
|
68
|
+
async expand(label) {
|
|
69
|
+
const button = this.item(label);
|
|
70
|
+
if (await this.isOpen(button)) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
await button.click();
|
|
74
|
+
await _test.expect.poll(() => this.isOpen(button)).toBe(true);
|
|
75
|
+
}
|
|
76
|
+
isOpen(button) {
|
|
77
|
+
return button.evaluate((el, openClass) => el.matches(openClass), _selectors.EuiSideNavSelectors.OPEN_ITEM_BUTTON_SELECTOR);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** Nearest ancestor carrying the exact `euiSideNavItemButton` class token. */
|
|
82
|
+
exports.EuiSideNavObject = EuiSideNavObject;
|
|
83
|
+
const ITEM_BUTTON_ANCESTOR_XPATH = "xpath=ancestor::*[contains(concat(' ', normalize-space(@class), ' '), ' euiSideNavItemButton ')][1]";
|
|
84
|
+
const escapeRegExp = text => text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
@@ -0,0 +1,28 @@
|
|
|
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/ EuiTable},
|
|
6
|
+
* the low level table built from `EuiTableHeader`, `EuiTableRow` and
|
|
7
|
+
* `EuiTableRowCell`. `EuiBasicTableObject` extends this for the
|
|
8
|
+
* `EuiBasicTable` and `EuiInMemoryTable` wrappers.
|
|
9
|
+
*
|
|
10
|
+
* `testSubj` must be set on `EuiTable` itself, EUI spreads it onto the
|
|
11
|
+
* `<table>`. Columns are addressed by position since a plain table has no
|
|
12
|
+
* field names.
|
|
13
|
+
*/
|
|
14
|
+
export declare class EuiTableObject extends BaseObject {
|
|
15
|
+
constructor(scope: ObjectScope, testSubj: string, componentSelector?: string);
|
|
16
|
+
/** The body rows. */
|
|
17
|
+
get rows(): Locator;
|
|
18
|
+
/** The header cells, in column order. */
|
|
19
|
+
get headerCells(): Locator;
|
|
20
|
+
/**
|
|
21
|
+
* The cells of one column across all body rows, by 0-based position.
|
|
22
|
+
* Direct children only, so a table nested in a cell is not matched. Matches
|
|
23
|
+
* both `<td>` and `<th>`, EUI renders a row header cell as `<th scope="row">`.
|
|
24
|
+
*/
|
|
25
|
+
column(index: number): Locator;
|
|
26
|
+
/** One body cell by 0-based row and column position. */
|
|
27
|
+
cell(row: number, column: number): Locator;
|
|
28
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.EuiTableObject = void 0;
|
|
7
|
+
var _base_object = require("../../base_object");
|
|
8
|
+
var _selectors = require("../../../components/table/selectors");
|
|
9
|
+
/*
|
|
10
|
+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
11
|
+
* or more contributor license agreements. Licensed under the Elastic License
|
|
12
|
+
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
|
13
|
+
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
|
14
|
+
* Side Public License, v 1.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Playwright Component Object for {@link
|
|
19
|
+
* https://eui.elastic.co/docs/components/tabular-content/tables/ EuiTable},
|
|
20
|
+
* the low level table built from `EuiTableHeader`, `EuiTableRow` and
|
|
21
|
+
* `EuiTableRowCell`. `EuiBasicTableObject` extends this for the
|
|
22
|
+
* `EuiBasicTable` and `EuiInMemoryTable` wrappers.
|
|
23
|
+
*
|
|
24
|
+
* `testSubj` must be set on `EuiTable` itself, EUI spreads it onto the
|
|
25
|
+
* `<table>`. Columns are addressed by position since a plain table has no
|
|
26
|
+
* field names.
|
|
27
|
+
*/
|
|
28
|
+
class EuiTableObject extends _base_object.BaseObject {
|
|
29
|
+
constructor(scope, testSubj, componentSelector = _selectors.EuiTableSelectors.ROOT_SELECTOR) {
|
|
30
|
+
super(scope, testSubj, componentSelector);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** The body rows. */
|
|
34
|
+
get rows() {
|
|
35
|
+
return this.root.locator(_selectors.EuiTableSelectors.ROW_SELECTOR);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** The header cells, in column order. */
|
|
39
|
+
get headerCells() {
|
|
40
|
+
return this.root.locator(_selectors.EuiTableSelectors.HEADER_CELL_SELECTOR);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* The cells of one column across all body rows, by 0-based position.
|
|
45
|
+
* Direct children only, so a table nested in a cell is not matched. Matches
|
|
46
|
+
* both `<td>` and `<th>`, EUI renders a row header cell as `<th scope="row">`.
|
|
47
|
+
*/
|
|
48
|
+
column(index) {
|
|
49
|
+
return this.rows.locator(`> :is(td, th):nth-child(${index + 1})`);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** One body cell by 0-based row and column position. */
|
|
53
|
+
cell(row, column) {
|
|
54
|
+
return this.rows.nth(row).locator(`> :is(td, th):nth-child(${column + 1})`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
exports.EuiTableObject = EuiTableObject;
|
package/lib/cjs/selectors.d.ts
CHANGED
|
@@ -15,6 +15,14 @@ export declare const selectors: {
|
|
|
15
15
|
ROW_SELECTOR: string;
|
|
16
16
|
HEADER_CELL_SELECTOR_PREFIX: string;
|
|
17
17
|
};
|
|
18
|
+
readonly callOut: {
|
|
19
|
+
ROOT_SELECTOR: string;
|
|
20
|
+
TITLE_SELECTOR: string;
|
|
21
|
+
TEXT_SELECTOR: string;
|
|
22
|
+
COLOR_CLASS_PREFIX: string;
|
|
23
|
+
DISMISS_BUTTON_TEST_SUBJ: string;
|
|
24
|
+
DISMISS_BUTTON_SELECTOR: string;
|
|
25
|
+
};
|
|
18
26
|
readonly colorPicker: {
|
|
19
27
|
ANCHOR_TEST_SUBJ: string;
|
|
20
28
|
ANCHOR_SELECTOR: string;
|
|
@@ -57,6 +65,10 @@ export declare const selectors: {
|
|
|
57
65
|
HANDLE_SELECTOR: string;
|
|
58
66
|
ITEM_SELECTOR: string;
|
|
59
67
|
};
|
|
68
|
+
readonly fieldSearch: {
|
|
69
|
+
ROOT_SELECTOR: string;
|
|
70
|
+
CLEAR_BUTTON_TEST_SUBJ: string;
|
|
71
|
+
};
|
|
60
72
|
readonly filterButton: {
|
|
61
73
|
ROOT_SELECTOR: string;
|
|
62
74
|
NOTIFICATION_SELECTOR: string;
|
|
@@ -71,6 +83,17 @@ export declare const selectors: {
|
|
|
71
83
|
ROOT_SELECTOR: string;
|
|
72
84
|
CLOSE_BUTTON_SELECTOR: string;
|
|
73
85
|
};
|
|
86
|
+
readonly pagination: {
|
|
87
|
+
ROOT_SELECTOR: string;
|
|
88
|
+
PAGE_BUTTON_SELECTOR: string;
|
|
89
|
+
ACTIVE_PAGE_BUTTON_SELECTOR: string;
|
|
90
|
+
COMPRESSED_TEXT_SELECTOR: string;
|
|
91
|
+
PAGE_BUTTON_TEST_SUBJ_PREFIX: string;
|
|
92
|
+
FIRST_BUTTON_TEST_SUBJ: string;
|
|
93
|
+
PREVIOUS_BUTTON_TEST_SUBJ: string;
|
|
94
|
+
NEXT_BUTTON_TEST_SUBJ: string;
|
|
95
|
+
LAST_BUTTON_TEST_SUBJ: string;
|
|
96
|
+
};
|
|
74
97
|
readonly popover: {
|
|
75
98
|
TOGGLE_SELECTOR: string;
|
|
76
99
|
panelFor: (id: string) => string;
|
|
@@ -79,10 +102,23 @@ export declare const selectors: {
|
|
|
79
102
|
SLIDER_SELECTOR: string;
|
|
80
103
|
NUMBER_INPUT_SELECTOR: string;
|
|
81
104
|
};
|
|
105
|
+
readonly searchBar: {
|
|
106
|
+
SEARCH_HOLDER_SELECTOR: string;
|
|
107
|
+
FILTERS_HOLDER_SELECTOR: string;
|
|
108
|
+
};
|
|
82
109
|
readonly selectable: {
|
|
83
110
|
ROOT_SELECTOR: string;
|
|
84
111
|
SEARCH_SELECTOR: string;
|
|
85
112
|
};
|
|
113
|
+
readonly sideNav: {
|
|
114
|
+
ROOT_SELECTOR: string;
|
|
115
|
+
ITEM_SELECTOR: string;
|
|
116
|
+
ITEM_BUTTON_SELECTOR: string;
|
|
117
|
+
SELECTED_ITEM_BUTTON_SELECTOR: string;
|
|
118
|
+
OPEN_ITEM_BUTTON_SELECTOR: string;
|
|
119
|
+
ITEM_LABEL_SELECTOR: string;
|
|
120
|
+
CHILD_ITEMS_SELECTOR: string;
|
|
121
|
+
};
|
|
86
122
|
readonly superSelect: {
|
|
87
123
|
ROOT_SELECTOR: string;
|
|
88
124
|
WRAPPER_SELECTOR: string;
|
|
@@ -90,6 +126,12 @@ export declare const selectors: {
|
|
|
90
126
|
HIDDEN_INPUT_SELECTOR: string;
|
|
91
127
|
optionByValue: (value: string) => string;
|
|
92
128
|
};
|
|
129
|
+
readonly table: {
|
|
130
|
+
ROOT_SELECTOR: string;
|
|
131
|
+
ROW_SELECTOR: string;
|
|
132
|
+
ROW_CELL_SELECTOR: string;
|
|
133
|
+
HEADER_CELL_SELECTOR: string;
|
|
134
|
+
};
|
|
93
135
|
readonly globalToastList: {
|
|
94
136
|
ROOT_SELECTOR: string;
|
|
95
137
|
TOAST_SELECTOR: string;
|