@dynatrace/strato-components-testing 1.18.0 → 3.1.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/esm/jest/index.js +102 -3
- package/esm/jest/index.js.map +2 -2
- package/esm/jest/mocks/create-mock-element.js +81 -0
- package/esm/jest/mocks/create-mock-element.js.map +7 -0
- package/esm/jest/mocks/create-range-mock.js +28 -0
- package/esm/jest/mocks/create-range-mock.js.map +7 -0
- package/esm/jest/mocks/crypto-mock.js +20 -0
- package/esm/jest/mocks/crypto-mock.js.map +7 -0
- package/esm/jest/mocks/dom-rect-mock.js.map +2 -2
- package/esm/jest/mocks/element-from-point-mock.js +12 -0
- package/esm/jest/mocks/element-from-point-mock.js.map +7 -0
- package/esm/jest/mocks/fetch-mock.js +20 -0
- package/esm/jest/mocks/fetch-mock.js.map +7 -0
- package/esm/jest/mocks/framer-motion-mock.js +59 -0
- package/esm/jest/mocks/framer-motion-mock.js.map +7 -0
- package/esm/jest/mocks/intersection-observer-mock.js +40 -0
- package/esm/jest/mocks/intersection-observer-mock.js.map +7 -0
- package/esm/jest/mocks/match-media-mock.js +27 -0
- package/esm/jest/mocks/match-media-mock.js.map +7 -0
- package/esm/jest/mocks/offset-height-mock.js +21 -0
- package/esm/jest/mocks/offset-height-mock.js.map +7 -0
- package/esm/jest/mocks/offset-width-mock.js +21 -0
- package/esm/jest/mocks/offset-width-mock.js.map +7 -0
- package/esm/jest/mocks/pointer-event-mock.js +24 -0
- package/esm/jest/mocks/pointer-event-mock.js.map +7 -0
- package/esm/jest/mocks/screen-size-mock.js +16 -0
- package/esm/jest/mocks/screen-size-mock.js.map +7 -0
- package/esm/jest/mocks/scroll-into-view-mock.js +16 -0
- package/esm/jest/mocks/scroll-into-view-mock.js.map +7 -0
- package/esm/jest/mocks/streamdown.mock.js +8 -0
- package/esm/jest/mocks/streamdown.mock.js.map +7 -0
- package/esm/jest/mocks/table-virtualization-mock.js +87 -0
- package/esm/jest/mocks/table-virtualization-mock.js.map +7 -0
- package/esm/jest/mocks/virtualization-mock.js +155 -0
- package/esm/jest/mocks/virtualization-mock.js.map +7 -0
- package/esm/jest/preset/jest-preset.js +2 -1
- package/esm/jest/preset/jest-preset.js.map +2 -2
- package/esm/jest/setup/index.js +51 -0
- package/esm/jest/setup/index.js.map +2 -2
- package/esm/jest/testing-helpers/filters/filter-field.js +424 -0
- package/esm/jest/testing-helpers/filters/filter-field.js.map +7 -0
- package/esm/jest/testing-helpers/forms/base-input.js +32 -0
- package/esm/jest/testing-helpers/forms/base-input.js.map +7 -0
- package/esm/jest/testing-helpers/forms/password-input.js +29 -0
- package/esm/jest/testing-helpers/forms/password-input.js.map +7 -0
- package/esm/jest/testing-helpers/forms/search-input.js +27 -0
- package/esm/jest/testing-helpers/forms/search-input.js.map +7 -0
- package/esm/jest/testing-helpers/forms/select.js +131 -0
- package/esm/jest/testing-helpers/forms/select.js.map +7 -0
- package/esm/jest/testing-helpers/forms/text-input.js +24 -0
- package/esm/jest/testing-helpers/forms/text-input.js.map +7 -0
- package/esm/jest/testing-helpers/tables/datatable.js +794 -0
- package/esm/jest/testing-helpers/tables/datatable.js.map +7 -0
- package/esm/jest/testing-helpers/utils/isFakeTimersEnabled.js +9 -0
- package/esm/jest/testing-helpers/utils/isFakeTimersEnabled.js.map +7 -0
- package/esm/jest/testing-helpers/utils/setup-user-event.js +15 -0
- package/esm/jest/testing-helpers/utils/setup-user-event.js.map +7 -0
- package/jest/index.d.ts +22 -1
- package/jest/index.js +54 -3
- package/jest/mocks/create-mock-element.d.ts +15 -0
- package/jest/mocks/create-mock-element.js +99 -0
- package/jest/mocks/create-range-mock.d.ts +11 -0
- package/jest/mocks/create-range-mock.js +46 -0
- package/jest/mocks/crypto-mock.d.ts +12 -0
- package/jest/mocks/crypto-mock.js +48 -0
- package/jest/mocks/dom-rect-mock.d.ts +1 -0
- package/jest/mocks/element-from-point-mock.d.ts +11 -0
- package/jest/{setup.js → mocks/element-from-point-mock.js} +10 -16
- package/jest/mocks/fetch-mock.d.ts +10 -0
- package/jest/mocks/fetch-mock.js +38 -0
- package/jest/mocks/framer-motion-mock.d.ts +18 -0
- package/jest/mocks/framer-motion-mock.js +75 -0
- package/jest/mocks/intersection-observer-mock.d.ts +11 -0
- package/jest/mocks/intersection-observer-mock.js +58 -0
- package/jest/mocks/match-media-mock.d.ts +11 -0
- package/jest/mocks/match-media-mock.js +45 -0
- package/jest/mocks/offset-height-mock.d.ts +10 -0
- package/jest/mocks/offset-height-mock.js +39 -0
- package/jest/mocks/offset-width-mock.d.ts +10 -0
- package/jest/mocks/offset-width-mock.js +39 -0
- package/jest/mocks/pointer-event-mock.d.ts +10 -0
- package/jest/mocks/pointer-event-mock.js +42 -0
- package/jest/mocks/screen-size-mock.d.ts +10 -0
- package/jest/mocks/screen-size-mock.js +34 -0
- package/jest/mocks/scroll-into-view-mock.d.ts +10 -0
- package/jest/mocks/scroll-into-view-mock.js +34 -0
- package/jest/mocks/streamdown.mock.d.ts +2 -0
- package/jest/mocks/streamdown.mock.js +26 -0
- package/jest/mocks/table-virtualization-mock.d.ts +15 -0
- package/jest/mocks/table-virtualization-mock.js +102 -0
- package/jest/mocks/virtualization-mock.d.ts +9 -0
- package/jest/mocks/virtualization-mock.js +170 -0
- package/jest/preset/jest-preset.d.ts +2 -3
- package/jest/preset/jest-preset.js +2 -1
- package/jest/setup/index.js +27 -0
- package/jest/testing-helpers/filters/filter-field.d.ts +109 -0
- package/jest/testing-helpers/filters/filter-field.js +436 -0
- package/jest/testing-helpers/forms/base-input.d.ts +17 -0
- package/jest/testing-helpers/forms/base-input.js +50 -0
- package/jest/testing-helpers/forms/password-input.d.ts +16 -0
- package/jest/testing-helpers/forms/password-input.js +47 -0
- package/jest/testing-helpers/forms/search-input.d.ts +20 -0
- package/jest/testing-helpers/forms/search-input.js +45 -0
- package/jest/testing-helpers/forms/select.d.ts +65 -0
- package/jest/testing-helpers/forms/select.js +159 -0
- package/jest/testing-helpers/forms/text-input.d.ts +19 -0
- package/jest/testing-helpers/forms/text-input.js +42 -0
- package/jest/testing-helpers/tables/datatable.d.ts +239 -0
- package/jest/testing-helpers/tables/datatable.js +812 -0
- package/jest/testing-helpers/utils/isFakeTimersEnabled.d.ts +5 -0
- package/jest/testing-helpers/utils/isFakeTimersEnabled.js +27 -0
- package/jest/testing-helpers/utils/setup-user-event.d.ts +6 -0
- package/jest/testing-helpers/utils/setup-user-event.js +43 -0
- package/package.json +12 -3
- package/esm/jest/setup.js +0 -24
- package/esm/jest/setup.js.map +0 -7
- package/jest/setup.d.ts +0 -14
|
@@ -0,0 +1,436 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
var filter_field_exports = {};
|
|
19
|
+
__export(filter_field_exports, {
|
|
20
|
+
FilterFieldHelper: () => FilterFieldHelper,
|
|
21
|
+
FilterFieldPinnedAndRecentSuggestionBase: () => FilterFieldPinnedAndRecentSuggestionBase,
|
|
22
|
+
FilterFieldPinnedSuggestion: () => FilterFieldPinnedSuggestion,
|
|
23
|
+
FilterFieldRecentSuggestion: () => FilterFieldRecentSuggestion,
|
|
24
|
+
getFilterFieldHelper: () => getFilterFieldHelper
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(filter_field_exports);
|
|
27
|
+
var import_react = require("@testing-library/react");
|
|
28
|
+
var import_user_event = require("@testing-library/user-event");
|
|
29
|
+
var import_isFakeTimersEnabled = require("../utils/isFakeTimersEnabled.js");
|
|
30
|
+
var import_setup_user_event = require("../utils/setup-user-event.js");
|
|
31
|
+
class FilterFieldPinnedAndRecentSuggestionBase {
|
|
32
|
+
constructor(suggestionRoot) {
|
|
33
|
+
this.suggestionRoot = suggestionRoot;
|
|
34
|
+
}
|
|
35
|
+
get pinButtonElement() {
|
|
36
|
+
return this.suggestionRoot.querySelector(
|
|
37
|
+
"button[aria-checked]"
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Receives the value of the suggestion that would be applied.
|
|
42
|
+
*/
|
|
43
|
+
get value() {
|
|
44
|
+
return this.suggestionRoot.childNodes.item(1).textContent;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Returns if the current suggestion is currently pinned or not.
|
|
48
|
+
*/
|
|
49
|
+
get pinned() {
|
|
50
|
+
if (this.pinButtonElement) {
|
|
51
|
+
return this.pinButtonElement.getAttribute("aria-checked") === "true";
|
|
52
|
+
}
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Applies the suggestion to the filter field.
|
|
57
|
+
*/
|
|
58
|
+
async apply() {
|
|
59
|
+
await (0, import_setup_user_event.setupUserEvent)({
|
|
60
|
+
pointerEventsCheck: import_user_event.PointerEventsCheckLevel.Never
|
|
61
|
+
}).click(this.suggestionRoot);
|
|
62
|
+
}
|
|
63
|
+
get pinEnabled() {
|
|
64
|
+
if (this.pinButtonElement) {
|
|
65
|
+
return this.pinButtonElement.getAttribute("aria-disabled") === "false";
|
|
66
|
+
}
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Allows the suggestion to be pinned if not pinned already.
|
|
71
|
+
*/
|
|
72
|
+
async pin() {
|
|
73
|
+
if (this.pinned === true) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
if (this.pinButtonElement) {
|
|
77
|
+
await (0, import_setup_user_event.setupUserEvent)({
|
|
78
|
+
pointerEventsCheck: import_user_event.PointerEventsCheckLevel.Never
|
|
79
|
+
}).click(this.pinButtonElement);
|
|
80
|
+
if ((0, import_isFakeTimersEnabled.isFakeTimersEnabled)()) {
|
|
81
|
+
await (0, import_react.act)(async () => {
|
|
82
|
+
jest.runOnlyPendingTimers();
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Allows the suggestion to be unpinned if not unpinned already.
|
|
89
|
+
*/
|
|
90
|
+
async unpin() {
|
|
91
|
+
if (this.pinned === false) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
if (this.pinButtonElement) {
|
|
95
|
+
await (0, import_setup_user_event.setupUserEvent)({
|
|
96
|
+
pointerEventsCheck: import_user_event.PointerEventsCheckLevel.Never
|
|
97
|
+
}).click(this.pinButtonElement);
|
|
98
|
+
if ((0, import_isFakeTimersEnabled.isFakeTimersEnabled)()) {
|
|
99
|
+
await (0, import_react.act)(async () => {
|
|
100
|
+
jest.runOnlyPendingTimers();
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
class FilterFieldPinnedSuggestion extends FilterFieldPinnedAndRecentSuggestionBase {
|
|
107
|
+
/**
|
|
108
|
+
* Receives the value of the suggestion that would be applied.
|
|
109
|
+
*/
|
|
110
|
+
get value() {
|
|
111
|
+
return this.suggestionRoot.childNodes.item(0).textContent;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
class FilterFieldRecentSuggestion extends FilterFieldPinnedAndRecentSuggestionBase {
|
|
115
|
+
/**
|
|
116
|
+
* Receives the value of the suggestion that would be applied.
|
|
117
|
+
*/
|
|
118
|
+
get value() {
|
|
119
|
+
return this.suggestionRoot.querySelector('[role="option"]')?.childNodes.item(0).textContent ?? null;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Receives time offset indicating when the filter statement has last been used.
|
|
123
|
+
*/
|
|
124
|
+
get lastUsed() {
|
|
125
|
+
return this.suggestionRoot.querySelector('[role="option"]')?.childNodes.item(1).textContent ?? null;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
class FilterFieldHelper {
|
|
129
|
+
constructor(dataTestId) {
|
|
130
|
+
this.dataTestId = dataTestId;
|
|
131
|
+
}
|
|
132
|
+
get filterFieldWrapper() {
|
|
133
|
+
return import_react.screen.getByTestId(this.dataTestId);
|
|
134
|
+
}
|
|
135
|
+
get editorView() {
|
|
136
|
+
return this.filterFieldWrapper.querySelector(
|
|
137
|
+
".cm-content"
|
|
138
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
139
|
+
)?.cmTile.view;
|
|
140
|
+
}
|
|
141
|
+
get inputElement() {
|
|
142
|
+
return (0, import_react.within)(this.filterFieldWrapper).getAllByRole(
|
|
143
|
+
"textbox",
|
|
144
|
+
{ hidden: true }
|
|
145
|
+
)[1];
|
|
146
|
+
}
|
|
147
|
+
get filterFieldElement() {
|
|
148
|
+
return (0, import_react.within)(this.filterFieldWrapper).getByRole(
|
|
149
|
+
"textbox",
|
|
150
|
+
{
|
|
151
|
+
name: "Filter field",
|
|
152
|
+
hidden: true
|
|
153
|
+
}
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
get placeholderElement() {
|
|
157
|
+
return this.filterFieldWrapper.querySelector(".cm-placeholder");
|
|
158
|
+
}
|
|
159
|
+
get suggestionsContainer() {
|
|
160
|
+
return import_react.screen.queryByTestId(`filterfield-suggestions-${this.dataTestId}`);
|
|
161
|
+
}
|
|
162
|
+
/** Returns the value of the native text input. */
|
|
163
|
+
get value() {
|
|
164
|
+
return this.inputElement.value;
|
|
165
|
+
}
|
|
166
|
+
/** Returns the value of the filter field. */
|
|
167
|
+
get filterFieldValue() {
|
|
168
|
+
return this.filterFieldElement.textContent || "";
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* The placeholder text shown in the filter field.
|
|
172
|
+
* Undefined if the placeholder is currently not rendered.
|
|
173
|
+
*/
|
|
174
|
+
get placeholder() {
|
|
175
|
+
return this.placeholderElement?.textContent || void 0;
|
|
176
|
+
}
|
|
177
|
+
/** Focus the filter field if not already focused. */
|
|
178
|
+
async focus() {
|
|
179
|
+
if (!this.filterFieldWrapper.contains(document.activeElement)) {
|
|
180
|
+
await (0, import_react.act)(async () => {
|
|
181
|
+
this.inputElement.focus();
|
|
182
|
+
});
|
|
183
|
+
expect(
|
|
184
|
+
this.filterFieldWrapper.contains(document.activeElement)
|
|
185
|
+
).toBeTruthy();
|
|
186
|
+
if ((0, import_isFakeTimersEnabled.isFakeTimersEnabled)()) {
|
|
187
|
+
await (0, import_react.act)(async () => {
|
|
188
|
+
jest.runOnlyPendingTimers();
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
/** Blur the filter field by tabbing out of it. */
|
|
194
|
+
async blur() {
|
|
195
|
+
await (0, import_react.act)(async () => {
|
|
196
|
+
this.filterFieldElement.blur();
|
|
197
|
+
});
|
|
198
|
+
if ((0, import_isFakeTimersEnabled.isFakeTimersEnabled)()) {
|
|
199
|
+
await (0, import_react.act)(async () => {
|
|
200
|
+
jest.runOnlyPendingTimers();
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
/** Fill a provided value into the filter field. */
|
|
205
|
+
async type(text, cursorIndex) {
|
|
206
|
+
const regEx = new RegExp(text, "g");
|
|
207
|
+
const matches = this.value.match(regEx);
|
|
208
|
+
await this.moveCursorTo(cursorIndex ?? -1);
|
|
209
|
+
await (0, import_setup_user_event.setupUserEvent)({
|
|
210
|
+
pointerEventsCheck: import_user_event.PointerEventsCheckLevel.Never
|
|
211
|
+
}).keyboard(text);
|
|
212
|
+
await (0, import_react.waitFor)(() => {
|
|
213
|
+
expect(this.value.match(regEx) ?? []).toHaveLength(
|
|
214
|
+
(matches?.length ?? 0) + 1
|
|
215
|
+
);
|
|
216
|
+
});
|
|
217
|
+
if ((0, import_isFakeTimersEnabled.isFakeTimersEnabled)()) {
|
|
218
|
+
await (0, import_react.act)(async () => {
|
|
219
|
+
jest.runOnlyPendingTimers();
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
/** Clears the filter field value. */
|
|
224
|
+
async clear() {
|
|
225
|
+
if (this.value !== "") {
|
|
226
|
+
await (0, import_setup_user_event.setupUserEvent)({
|
|
227
|
+
pointerEventsCheck: import_user_event.PointerEventsCheckLevel.Never
|
|
228
|
+
}).click(
|
|
229
|
+
await (0, import_react.within)(this.filterFieldWrapper).findByRole("button", {
|
|
230
|
+
name: "Clear filter",
|
|
231
|
+
hidden: true
|
|
232
|
+
})
|
|
233
|
+
);
|
|
234
|
+
if ((0, import_isFakeTimersEnabled.isFakeTimersEnabled)()) {
|
|
235
|
+
await (0, import_react.act)(async () => {
|
|
236
|
+
jest.runOnlyPendingTimers();
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Moves the cursor to the given index.
|
|
243
|
+
* -1 moves to the end of the input.
|
|
244
|
+
*/
|
|
245
|
+
async moveCursorTo(index) {
|
|
246
|
+
const user = (0, import_setup_user_event.setupUserEvent)({
|
|
247
|
+
pointerEventsCheck: import_user_event.PointerEventsCheckLevel.Never
|
|
248
|
+
});
|
|
249
|
+
if (index === -1) {
|
|
250
|
+
await (0, import_react.act)(async () => {
|
|
251
|
+
await this.focus();
|
|
252
|
+
});
|
|
253
|
+
await user.keyboard("{PageDown}");
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
if (!this.editorView) {
|
|
257
|
+
console.warn("FilterField editor could not be found. Panic now.");
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
await (0, import_react.act)(async () => {
|
|
261
|
+
await this.focus();
|
|
262
|
+
this.editorView.dispatch({
|
|
263
|
+
selection: {
|
|
264
|
+
anchor: Math.min(index, this.editorView.state.doc.length)
|
|
265
|
+
}
|
|
266
|
+
});
|
|
267
|
+
});
|
|
268
|
+
if ((0, import_isFakeTimersEnabled.isFakeTimersEnabled)()) {
|
|
269
|
+
await (0, import_react.act)(async () => {
|
|
270
|
+
jest.runOnlyPendingTimers();
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
/** Open the suggestions overlay with the keyboard shortcut. */
|
|
275
|
+
async openSuggestions() {
|
|
276
|
+
await (0, import_react.act)(async () => {
|
|
277
|
+
await this.focus();
|
|
278
|
+
});
|
|
279
|
+
await (0, import_setup_user_event.setupUserEvent)({
|
|
280
|
+
pointerEventsCheck: import_user_event.PointerEventsCheckLevel.Never
|
|
281
|
+
}).keyboard("{Control>}{Space}{/Control}");
|
|
282
|
+
await (0, import_react.waitFor)(
|
|
283
|
+
async () => expect(this.suggestionsContainer).toBeInTheDocument()
|
|
284
|
+
);
|
|
285
|
+
if ((0, import_isFakeTimersEnabled.isFakeTimersEnabled)()) {
|
|
286
|
+
await (0, import_react.act)(async () => {
|
|
287
|
+
jest.runOnlyPendingTimers();
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Close the suggestions overlay using the `Escape` key.
|
|
293
|
+
* If the filter field is focused, the focus will stay in the filter field.
|
|
294
|
+
*/
|
|
295
|
+
async closeSuggestions() {
|
|
296
|
+
await (0, import_react.act)(async () => {
|
|
297
|
+
await this.focus();
|
|
298
|
+
});
|
|
299
|
+
await (0, import_setup_user_event.setupUserEvent)({
|
|
300
|
+
pointerEventsCheck: import_user_event.PointerEventsCheckLevel.Never
|
|
301
|
+
}).keyboard("{Escape}");
|
|
302
|
+
if (this.suggestionsContainer !== null) {
|
|
303
|
+
await (0, import_react.waitForElementToBeRemoved)(() => this.suggestionsContainer);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
/** Apply the suggestion with the given text. */
|
|
307
|
+
async applySuggestion(queryString) {
|
|
308
|
+
await (0, import_react.act)(async () => {
|
|
309
|
+
await this.focus();
|
|
310
|
+
});
|
|
311
|
+
await (0, import_react.waitFor)(() => {
|
|
312
|
+
expect(this.suggestionsContainer).toBeInTheDocument();
|
|
313
|
+
});
|
|
314
|
+
if (!this.suggestionsContainer) {
|
|
315
|
+
console.warn(
|
|
316
|
+
"The filter field suggestions overlay seems to be closed. Make sure to open it before applying a suggestion."
|
|
317
|
+
);
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
const showMore = (0, import_react.within)(this.suggestionsContainer).queryByRole("option", {
|
|
321
|
+
name: "Show more"
|
|
322
|
+
});
|
|
323
|
+
if (showMore) {
|
|
324
|
+
await (0, import_setup_user_event.setupUserEvent)({
|
|
325
|
+
pointerEventsCheck: import_user_event.PointerEventsCheckLevel.Never
|
|
326
|
+
}).click(showMore);
|
|
327
|
+
}
|
|
328
|
+
let suggestions = (0, import_react.within)(this.suggestionsContainer).queryAllByTestId(
|
|
329
|
+
queryString,
|
|
330
|
+
{ exact: true }
|
|
331
|
+
);
|
|
332
|
+
if (suggestions.length > 0) {
|
|
333
|
+
suggestions = suggestions.reduce((acc, container) => {
|
|
334
|
+
const suggestion = (0, import_react.within)(container).queryByRole("option");
|
|
335
|
+
if (suggestion) {
|
|
336
|
+
acc.push(suggestion);
|
|
337
|
+
}
|
|
338
|
+
return acc;
|
|
339
|
+
}, []);
|
|
340
|
+
}
|
|
341
|
+
if (suggestions.length === 0) {
|
|
342
|
+
suggestions.push(
|
|
343
|
+
...(0, import_react.within)(this.suggestionsContainer).queryAllByText(
|
|
344
|
+
(_, element) => element?.getAttribute("role") === "option" && // The replace is needed to ignore non-breaking spaces
|
|
345
|
+
element.firstElementChild?.textContent?.replace(/\s+/g, " ") === queryString.replace(/\s+/g, " ")
|
|
346
|
+
)
|
|
347
|
+
);
|
|
348
|
+
}
|
|
349
|
+
if (suggestions.length === 0) {
|
|
350
|
+
console.warn(
|
|
351
|
+
`Could not query a suggestion with the given queryString '${queryString}' (trying queryByTestId and queryByText).`
|
|
352
|
+
);
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
if (suggestions.length > 1) {
|
|
356
|
+
console.warn(
|
|
357
|
+
"Found multiple suggestions with the given testId. Will apply the first one"
|
|
358
|
+
);
|
|
359
|
+
}
|
|
360
|
+
await (0, import_setup_user_event.setupUserEvent)({
|
|
361
|
+
pointerEventsCheck: import_user_event.PointerEventsCheckLevel.Never
|
|
362
|
+
}).click(suggestions[0]);
|
|
363
|
+
}
|
|
364
|
+
/** Get recent suggestions */
|
|
365
|
+
async getRecentSuggestions() {
|
|
366
|
+
if (this.suggestionsContainer) {
|
|
367
|
+
const recentGroup = (0, import_react.within)(this.suggestionsContainer).getByRole("group", {
|
|
368
|
+
name: "Recently used filters"
|
|
369
|
+
});
|
|
370
|
+
const suggestions = (0, import_react.within)(recentGroup).getAllByRole(
|
|
371
|
+
"group",
|
|
372
|
+
{
|
|
373
|
+
hidden: true,
|
|
374
|
+
name(_accessibleName, element) {
|
|
375
|
+
return element.getAttribute(
|
|
376
|
+
"data-strato-filter-field-virtual-focus-type"
|
|
377
|
+
) === "recent-suggestion";
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
);
|
|
381
|
+
return suggestions.map((el) => new FilterFieldRecentSuggestion(el));
|
|
382
|
+
}
|
|
383
|
+
return [];
|
|
384
|
+
}
|
|
385
|
+
/** Get pinned suggestions */
|
|
386
|
+
async getPinnedSuggestions() {
|
|
387
|
+
if (this.suggestionsContainer) {
|
|
388
|
+
try {
|
|
389
|
+
await (0, import_react.waitFor)(
|
|
390
|
+
() => import_react.screen.getByRole("group", {
|
|
391
|
+
name: "Pinned filters",
|
|
392
|
+
hidden: true,
|
|
393
|
+
suggest: false
|
|
394
|
+
})
|
|
395
|
+
);
|
|
396
|
+
const pinnedGroup = (0, import_react.within)(this.suggestionsContainer).getByRole(
|
|
397
|
+
"group",
|
|
398
|
+
{
|
|
399
|
+
name: "Pinned filters",
|
|
400
|
+
hidden: true
|
|
401
|
+
}
|
|
402
|
+
);
|
|
403
|
+
const suggestions = (0, import_react.within)(pinnedGroup).getAllByRole(
|
|
404
|
+
"group",
|
|
405
|
+
{
|
|
406
|
+
hidden: true,
|
|
407
|
+
name(_accessibleName, element) {
|
|
408
|
+
return element.getAttribute(
|
|
409
|
+
"data-strato-filter-field-virtual-focus-type"
|
|
410
|
+
) === "pinned-suggestion";
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
);
|
|
414
|
+
return suggestions.map((el) => new FilterFieldPinnedSuggestion(el));
|
|
415
|
+
} catch {
|
|
416
|
+
return [];
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
return [];
|
|
420
|
+
}
|
|
421
|
+
/** Paste text at the current cursor position */
|
|
422
|
+
async paste(text, cursorIndex) {
|
|
423
|
+
await this.moveCursorTo(cursorIndex ?? -1);
|
|
424
|
+
await (0, import_setup_user_event.setupUserEvent)({
|
|
425
|
+
pointerEventsCheck: import_user_event.PointerEventsCheckLevel.Never
|
|
426
|
+
}).paste(text);
|
|
427
|
+
if ((0, import_isFakeTimersEnabled.isFakeTimersEnabled)()) {
|
|
428
|
+
await (0, import_react.act)(async () => {
|
|
429
|
+
jest.runOnlyPendingTimers();
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
function getFilterFieldHelper(dataTestId) {
|
|
435
|
+
return new FilterFieldHelper(dataTestId);
|
|
436
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helper class for interacting with the text input
|
|
3
|
+
* @public
|
|
4
|
+
*/
|
|
5
|
+
export declare class BaseInputHelper {
|
|
6
|
+
protected dataTestId: string;
|
|
7
|
+
protected get inputWrapper(): HTMLElement;
|
|
8
|
+
protected get inputElement(): HTMLInputElement;
|
|
9
|
+
constructor(dataTestId: string);
|
|
10
|
+
/** Returns the value of the native input element. */
|
|
11
|
+
get value(): string;
|
|
12
|
+
focus(): void;
|
|
13
|
+
/** Fill a provided value into the text input. */
|
|
14
|
+
type(text: string): Promise<void>;
|
|
15
|
+
/** Clears the text input value. */
|
|
16
|
+
clear(): Promise<void>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
var base_input_exports = {};
|
|
19
|
+
__export(base_input_exports, {
|
|
20
|
+
BaseInputHelper: () => BaseInputHelper
|
|
21
|
+
});
|
|
22
|
+
module.exports = __toCommonJS(base_input_exports);
|
|
23
|
+
var import_react = require("@testing-library/react");
|
|
24
|
+
var import_setup_user_event = require("../utils/setup-user-event.js");
|
|
25
|
+
class BaseInputHelper {
|
|
26
|
+
constructor(dataTestId) {
|
|
27
|
+
this.dataTestId = dataTestId;
|
|
28
|
+
}
|
|
29
|
+
get inputWrapper() {
|
|
30
|
+
return import_react.screen.getByTestId(this.dataTestId);
|
|
31
|
+
}
|
|
32
|
+
get inputElement() {
|
|
33
|
+
return (0, import_react.within)(this.inputWrapper).getByRole("textbox", { hidden: true });
|
|
34
|
+
}
|
|
35
|
+
/** Returns the value of the native input element. */
|
|
36
|
+
get value() {
|
|
37
|
+
return this.inputElement.value;
|
|
38
|
+
}
|
|
39
|
+
focus() {
|
|
40
|
+
this.inputElement.focus();
|
|
41
|
+
}
|
|
42
|
+
/** Fill a provided value into the text input. */
|
|
43
|
+
async type(text) {
|
|
44
|
+
await (0, import_setup_user_event.setupUserEvent)().type(this.inputElement, text);
|
|
45
|
+
}
|
|
46
|
+
/** Clears the text input value. */
|
|
47
|
+
async clear() {
|
|
48
|
+
await (0, import_setup_user_event.setupUserEvent)().clear(this.inputElement);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { BaseInputHelper } from './base-input.js';
|
|
2
|
+
/**
|
|
3
|
+
* Helper class for interacting with the text input
|
|
4
|
+
* @public
|
|
5
|
+
*/
|
|
6
|
+
export declare class PasswordInputHelper extends BaseInputHelper {
|
|
7
|
+
showPassword(): Promise<void>;
|
|
8
|
+
hidePassword(): Promise<void>;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Helper function that returns the password input element with its testing utilities.
|
|
12
|
+
* @public
|
|
13
|
+
*/
|
|
14
|
+
export declare function getPasswordInputHelper(
|
|
15
|
+
/** The accessible test id used to locate the password input wrapper. */
|
|
16
|
+
dataTestId: string): PasswordInputHelper;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
var password_input_exports = {};
|
|
19
|
+
__export(password_input_exports, {
|
|
20
|
+
PasswordInputHelper: () => PasswordInputHelper,
|
|
21
|
+
getPasswordInputHelper: () => getPasswordInputHelper
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(password_input_exports);
|
|
24
|
+
var import_react = require("@testing-library/react");
|
|
25
|
+
var import_base_input = require("./base-input.js");
|
|
26
|
+
var import_setup_user_event = require("../utils/setup-user-event.js");
|
|
27
|
+
class PasswordInputHelper extends import_base_input.BaseInputHelper {
|
|
28
|
+
async showPassword() {
|
|
29
|
+
if (this.inputElement.getAttribute("type") === "password") {
|
|
30
|
+
const passwordButton = (0, import_react.within)(this.inputWrapper).getByRole("button", {
|
|
31
|
+
hidden: true
|
|
32
|
+
});
|
|
33
|
+
await (0, import_setup_user_event.setupUserEvent)().click(passwordButton);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
async hidePassword() {
|
|
37
|
+
if (this.inputElement.getAttribute("type") === "text") {
|
|
38
|
+
const passwordButton = (0, import_react.within)(this.inputWrapper).getByRole("button", {
|
|
39
|
+
hidden: true
|
|
40
|
+
});
|
|
41
|
+
await (0, import_setup_user_event.setupUserEvent)().click(passwordButton);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function getPasswordInputHelper(dataTestId) {
|
|
46
|
+
return new PasswordInputHelper(dataTestId);
|
|
47
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { BaseInputHelper } from './base-input.js';
|
|
2
|
+
/**
|
|
3
|
+
* Helper class for interacting with the search input
|
|
4
|
+
* @public
|
|
5
|
+
*/
|
|
6
|
+
export declare class SearchInputHelper extends BaseInputHelper {
|
|
7
|
+
protected get inputElement(): HTMLInputElement;
|
|
8
|
+
/**
|
|
9
|
+
* Helper that will let you call a specific suffix button
|
|
10
|
+
* within the SearchInput component.
|
|
11
|
+
*/
|
|
12
|
+
clickButton(name: string): Promise<void>;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Helper function that returns the search input element with its testing utilities.
|
|
16
|
+
* @public
|
|
17
|
+
*/
|
|
18
|
+
export declare function getSearchInputHelper(
|
|
19
|
+
/** The accessible test id used to locate the input wrapper. */
|
|
20
|
+
dataTestId: string): SearchInputHelper;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
var search_input_exports = {};
|
|
19
|
+
__export(search_input_exports, {
|
|
20
|
+
SearchInputHelper: () => SearchInputHelper,
|
|
21
|
+
getSearchInputHelper: () => getSearchInputHelper
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(search_input_exports);
|
|
24
|
+
var import_react = require("@testing-library/react");
|
|
25
|
+
var import_base_input = require("./base-input.js");
|
|
26
|
+
var import_setup_user_event = require("../utils/setup-user-event.js");
|
|
27
|
+
class SearchInputHelper extends import_base_input.BaseInputHelper {
|
|
28
|
+
get inputElement() {
|
|
29
|
+
return (0, import_react.within)(this.inputWrapper).getByRole("searchbox", { hidden: true });
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Helper that will let you call a specific suffix button
|
|
33
|
+
* within the SearchInput component.
|
|
34
|
+
*/
|
|
35
|
+
async clickButton(name) {
|
|
36
|
+
const button = (0, import_react.within)(this.inputWrapper).getByRole("button", {
|
|
37
|
+
hidden: true,
|
|
38
|
+
name
|
|
39
|
+
});
|
|
40
|
+
await (0, import_setup_user_event.setupUserEvent)().click(button);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function getSearchInputHelper(dataTestId) {
|
|
44
|
+
return new SearchInputHelper(dataTestId);
|
|
45
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helper class for interacting with the select.
|
|
3
|
+
* @public
|
|
4
|
+
*/
|
|
5
|
+
export declare class SelectTestingHelper {
|
|
6
|
+
protected dataTestId: string;
|
|
7
|
+
constructor(dataTestId: string);
|
|
8
|
+
/**
|
|
9
|
+
* Gets the root element of the select.
|
|
10
|
+
*/
|
|
11
|
+
get element(): HTMLDivElement;
|
|
12
|
+
/**
|
|
13
|
+
* Gets the trigger element of the select.
|
|
14
|
+
*/
|
|
15
|
+
get trigger(): HTMLDivElement;
|
|
16
|
+
/**
|
|
17
|
+
* Gets the text value of the trigger display value of the select.
|
|
18
|
+
*/
|
|
19
|
+
get displayValue(): string;
|
|
20
|
+
/**
|
|
21
|
+
* Gets the overlay (content) of the select.
|
|
22
|
+
*/
|
|
23
|
+
get overlay(): HTMLDivElement;
|
|
24
|
+
/**
|
|
25
|
+
* Gets the text value of the select filter in the overlay.
|
|
26
|
+
*/
|
|
27
|
+
get filterValue(): string;
|
|
28
|
+
/**
|
|
29
|
+
* Gets the currently selected option(s).
|
|
30
|
+
*/
|
|
31
|
+
get selectedOptions(): Array<string>;
|
|
32
|
+
/**
|
|
33
|
+
* Gets the open state of the select overlay.
|
|
34
|
+
*/
|
|
35
|
+
get openState(): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Gets the option with the corresponding label.
|
|
38
|
+
*/
|
|
39
|
+
getOption(label: string): HTMLOptionElement;
|
|
40
|
+
/**
|
|
41
|
+
* Selects the option with the corresponding label.
|
|
42
|
+
*/
|
|
43
|
+
selectOption(label: string): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* Opens the select overlay.
|
|
46
|
+
*/
|
|
47
|
+
open(): Promise<void>;
|
|
48
|
+
/**
|
|
49
|
+
* Closes the select overlay.
|
|
50
|
+
*/
|
|
51
|
+
close(): Promise<void>;
|
|
52
|
+
/**
|
|
53
|
+
* Types in the filter of the select.
|
|
54
|
+
*/
|
|
55
|
+
typeInFilter(text: string): Promise<void>;
|
|
56
|
+
/**
|
|
57
|
+
* Clears the filter / search of the select overlay.
|
|
58
|
+
*/
|
|
59
|
+
clearFilter(): Promise<void>;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Helper function that returns the select element with its testing utilities.
|
|
63
|
+
* @public
|
|
64
|
+
*/
|
|
65
|
+
export declare function getSelectTestingHelper(dataTestId: string): SelectTestingHelper;
|