d5-testing-library 1.0.4 → 1.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/dist/cjs/d5-testing-library.cjs +524 -86
- package/dist/d5-testing-library.d.ts +122 -19
- package/dist/d5-testing-library.legacy-esm.js +502 -76
- package/dist/d5-testing-library.mjs +502 -76
- package/package.json +1 -1
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
8
|
var __export = (target, all) => {
|
|
7
9
|
for (var name in all)
|
|
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
17
|
}
|
|
16
18
|
return to;
|
|
17
19
|
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
18
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
29
|
|
|
20
30
|
// src/index.ts
|
|
@@ -29,15 +39,36 @@ __export(src_exports, {
|
|
|
29
39
|
SubsystemsPanel: () => SubsystemsPanel,
|
|
30
40
|
TextEditor: () => TextEditor,
|
|
31
41
|
byTestId: () => byTestId,
|
|
42
|
+
click: () => click,
|
|
32
43
|
config: () => config,
|
|
33
44
|
createDriver: () => createDriver,
|
|
34
45
|
editorFactory: () => editorFactory,
|
|
35
46
|
elementIsNotPresent: () => elementIsNotPresent,
|
|
36
|
-
signIn: () => signIn
|
|
47
|
+
signIn: () => signIn,
|
|
48
|
+
waitElementIsVisible: () => waitElementIsVisible
|
|
37
49
|
});
|
|
38
50
|
module.exports = __toCommonJS(src_exports);
|
|
39
51
|
|
|
40
52
|
// src/config.ts
|
|
53
|
+
var process = __toESM(require("process"));
|
|
54
|
+
var driversMap = /* @__PURE__ */ new Map();
|
|
55
|
+
var createConfigProxy = (config2) => {
|
|
56
|
+
return new Proxy(config2, {
|
|
57
|
+
get(_target, prop) {
|
|
58
|
+
if (prop === "driver") {
|
|
59
|
+
return driversMap.get(process.pid);
|
|
60
|
+
}
|
|
61
|
+
return Reflect.get(...arguments);
|
|
62
|
+
},
|
|
63
|
+
set(_target, prop, value) {
|
|
64
|
+
if (prop === "driver") {
|
|
65
|
+
driversMap.set(process.pid, value);
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
return Reflect.set(...arguments);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
};
|
|
41
72
|
var Config = class _Config {
|
|
42
73
|
static instance;
|
|
43
74
|
appConfig;
|
|
@@ -49,7 +80,7 @@ var Config = class _Config {
|
|
|
49
80
|
}
|
|
50
81
|
config = (cfg) => {
|
|
51
82
|
if (!cfg)
|
|
52
|
-
return this.appConfig;
|
|
83
|
+
return createConfigProxy(this.appConfig);
|
|
53
84
|
this.appConfig = cfg;
|
|
54
85
|
};
|
|
55
86
|
};
|
|
@@ -98,7 +129,7 @@ var AbstractPage = class extends AbstractElement {
|
|
|
98
129
|
// src/utils/locators.ts
|
|
99
130
|
var import_selenium_webdriver = require("selenium-webdriver");
|
|
100
131
|
var byTestId = (testId, element = "div") => {
|
|
101
|
-
return import_selenium_webdriver.By.css(`${element}[data-testid
|
|
132
|
+
return import_selenium_webdriver.By.css(`${element}[data-testid="${testId}"]`);
|
|
102
133
|
};
|
|
103
134
|
|
|
104
135
|
// src/utils/createDriver.ts
|
|
@@ -120,6 +151,14 @@ var elementIsNotPresent = function elementIsNotPresent2(locator) {
|
|
|
120
151
|
});
|
|
121
152
|
};
|
|
122
153
|
|
|
154
|
+
// src/utils/waitElementIsVisible.ts
|
|
155
|
+
var import_selenium_webdriver4 = require("selenium-webdriver");
|
|
156
|
+
async function waitElementIsVisible({ element, timeout, errorMessage, driver }) {
|
|
157
|
+
driver = driver ?? config().driver;
|
|
158
|
+
const condition = import_selenium_webdriver4.until.elementIsVisible(element);
|
|
159
|
+
await driver.wait(condition.fn, timeout ?? 1e4, errorMessage ?? condition.description());
|
|
160
|
+
}
|
|
161
|
+
|
|
123
162
|
// src/pageObjects/AbstractElementWithParent.ts
|
|
124
163
|
var AbstractElementWithParent = class extends AbstractElement {
|
|
125
164
|
getParentElement;
|
|
@@ -130,7 +169,23 @@ var AbstractElementWithParent = class extends AbstractElement {
|
|
|
130
169
|
}
|
|
131
170
|
async getElement() {
|
|
132
171
|
const parentEl = await this.getParentElement();
|
|
133
|
-
|
|
172
|
+
await waitElementIsVisible({
|
|
173
|
+
element: parentEl,
|
|
174
|
+
driver: this.driver
|
|
175
|
+
});
|
|
176
|
+
const el = await parentEl.findElement(this.elementBy);
|
|
177
|
+
await waitElementIsVisible({
|
|
178
|
+
element: el,
|
|
179
|
+
driver: this.driver
|
|
180
|
+
});
|
|
181
|
+
return el;
|
|
182
|
+
}
|
|
183
|
+
async getAttribute(attr) {
|
|
184
|
+
const el = await this.getElement();
|
|
185
|
+
return await el.getAttribute(attr);
|
|
186
|
+
}
|
|
187
|
+
async getClasses() {
|
|
188
|
+
return await this.getAttribute("class");
|
|
134
189
|
}
|
|
135
190
|
};
|
|
136
191
|
|
|
@@ -144,9 +199,9 @@ var SubsystemsPanelHeader = class extends AbstractElementWithParent {
|
|
|
144
199
|
};
|
|
145
200
|
|
|
146
201
|
// src/pageObjects/elements/SubsystemsPanel/SubsystemsPanel.ts
|
|
147
|
-
var
|
|
202
|
+
var import_selenium_webdriver5 = require("selenium-webdriver");
|
|
148
203
|
var SubsystemsPanel = class extends AbstractElement {
|
|
149
|
-
panelBy =
|
|
204
|
+
panelBy = import_selenium_webdriver5.By.id("aside");
|
|
150
205
|
header;
|
|
151
206
|
constructor(driver) {
|
|
152
207
|
super(driver);
|
|
@@ -161,7 +216,7 @@ var SubsystemsPanel = class extends AbstractElement {
|
|
|
161
216
|
};
|
|
162
217
|
|
|
163
218
|
// src/pageObjects/elements/Forms/AbstractForm.ts
|
|
164
|
-
var
|
|
219
|
+
var import_selenium_webdriver6 = require("selenium-webdriver");
|
|
165
220
|
var AbstractForm = class extends AbstractPage {
|
|
166
221
|
containerBy;
|
|
167
222
|
popupContainerBy;
|
|
@@ -206,20 +261,20 @@ var AbstractForm = class extends AbstractPage {
|
|
|
206
261
|
async getTitleText() {
|
|
207
262
|
if (await this.isModal()) {
|
|
208
263
|
const popupEl = await this.driver.findElement(this.popupContainerBy);
|
|
209
|
-
const titleEl2 = await popupEl.findElement(
|
|
264
|
+
const titleEl2 = await popupEl.findElement(import_selenium_webdriver6.By.className("popup-title"));
|
|
210
265
|
return titleEl2.getText();
|
|
211
266
|
}
|
|
212
267
|
let container = await this.getContainerElement();
|
|
213
|
-
let titleEl = await container.findElement(
|
|
268
|
+
let titleEl = await container.findElement(import_selenium_webdriver6.By.className("form-toolbar-name-container"));
|
|
214
269
|
return titleEl.getText();
|
|
215
270
|
}
|
|
216
271
|
};
|
|
217
272
|
|
|
218
273
|
// src/pageObjects/elements/Forms/FormEdit.ts
|
|
219
|
-
var
|
|
274
|
+
var import_selenium_webdriver13 = require("selenium-webdriver");
|
|
220
275
|
|
|
221
276
|
// src/pageObjects/elements/Editors/AbstractEditor.ts
|
|
222
|
-
var
|
|
277
|
+
var import_selenium_webdriver7 = require("selenium-webdriver");
|
|
223
278
|
|
|
224
279
|
// src/pageObjects/AbstractFormElement.ts
|
|
225
280
|
var AbstractFormElement = class extends AbstractElementWithParent {
|
|
@@ -229,11 +284,23 @@ var AbstractFormElement = class extends AbstractElementWithParent {
|
|
|
229
284
|
}
|
|
230
285
|
};
|
|
231
286
|
|
|
287
|
+
// src/pageObjects/elements/Editors/ClearStrategy/InputClearStrategy.ts
|
|
288
|
+
var InputClearStrategy = class {
|
|
289
|
+
async clear(editor) {
|
|
290
|
+
const inputEl = await editor.getInputElement();
|
|
291
|
+
await inputEl.clear();
|
|
292
|
+
}
|
|
293
|
+
};
|
|
294
|
+
|
|
232
295
|
// src/pageObjects/elements/Editors/AbstractEditor.ts
|
|
233
296
|
var AbstractDXEditorWithInput = class extends AbstractFormElement {
|
|
297
|
+
clearStrategy = new InputClearStrategy();
|
|
298
|
+
setClearStrategy(strategy) {
|
|
299
|
+
this.clearStrategy = strategy;
|
|
300
|
+
}
|
|
234
301
|
async getInputElement() {
|
|
235
302
|
const controlEl = await this.getElement();
|
|
236
|
-
return controlEl.findElement(
|
|
303
|
+
return controlEl.findElement(import_selenium_webdriver7.By.className("dx-texteditor-input"));
|
|
237
304
|
}
|
|
238
305
|
async getInputValue() {
|
|
239
306
|
const inputEl = await this.getInputElement();
|
|
@@ -241,13 +308,20 @@ var AbstractDXEditorWithInput = class extends AbstractFormElement {
|
|
|
241
308
|
}
|
|
242
309
|
async setInputValue(value) {
|
|
243
310
|
const inputEl = await this.getInputElement();
|
|
244
|
-
await inputEl.
|
|
245
|
-
await inputEl.sendKeys(value,
|
|
311
|
+
await click(inputEl, this.driver);
|
|
312
|
+
await inputEl.sendKeys(value, import_selenium_webdriver7.Key.ENTER);
|
|
313
|
+
}
|
|
314
|
+
async clear() {
|
|
315
|
+
await this.clearStrategy.clear(this);
|
|
246
316
|
}
|
|
247
317
|
};
|
|
248
318
|
|
|
249
319
|
// src/pageObjects/elements/Editors/TextEditor.ts
|
|
250
320
|
var TextEditor = class extends AbstractDXEditorWithInput {
|
|
321
|
+
constructor(getParentElement, elementBy, driver) {
|
|
322
|
+
super(getParentElement, elementBy, driver);
|
|
323
|
+
this.setClearStrategy(new InputClearStrategy());
|
|
324
|
+
}
|
|
251
325
|
getValue() {
|
|
252
326
|
return this.getInputValue();
|
|
253
327
|
}
|
|
@@ -258,6 +332,10 @@ var TextEditor = class extends AbstractDXEditorWithInput {
|
|
|
258
332
|
|
|
259
333
|
// src/pageObjects/elements/Editors/NumberEditor.ts
|
|
260
334
|
var NumberEditor = class extends AbstractDXEditorWithInput {
|
|
335
|
+
constructor(getParentElement, elementBy, driver) {
|
|
336
|
+
super(getParentElement, elementBy, driver);
|
|
337
|
+
this.setClearStrategy(new InputClearStrategy());
|
|
338
|
+
}
|
|
261
339
|
async getValue() {
|
|
262
340
|
const value = await super.getInputValue();
|
|
263
341
|
return value == "" ? null : Number.parseFloat(value);
|
|
@@ -273,22 +351,22 @@ var CheckBox = class extends AbstractFormElement {
|
|
|
273
351
|
const inputEl = await this.getElement();
|
|
274
352
|
const result = await inputEl.getAttribute("aria-checked");
|
|
275
353
|
if (result === "true")
|
|
276
|
-
return
|
|
354
|
+
return 1;
|
|
277
355
|
if (result === "false")
|
|
278
|
-
return
|
|
279
|
-
return
|
|
356
|
+
return 0;
|
|
357
|
+
return null;
|
|
280
358
|
}
|
|
281
359
|
async setValue(value) {
|
|
282
360
|
const inputEl = await this.getElement();
|
|
283
361
|
const currentValue = await this.getValue();
|
|
284
362
|
if (currentValue !== value) {
|
|
285
|
-
await inputEl.
|
|
363
|
+
await click(inputEl, this.driver);
|
|
286
364
|
}
|
|
287
365
|
}
|
|
288
366
|
};
|
|
289
367
|
|
|
290
368
|
// src/pageObjects/elements/Editors/SelectBoxEditor.ts
|
|
291
|
-
var
|
|
369
|
+
var import_selenium_webdriver9 = require("selenium-webdriver");
|
|
292
370
|
|
|
293
371
|
// src/utils/xpathHelper.ts
|
|
294
372
|
var XPathHelper = class {
|
|
@@ -300,19 +378,53 @@ var XPathHelper = class {
|
|
|
300
378
|
}
|
|
301
379
|
};
|
|
302
380
|
|
|
381
|
+
// src/pageObjects/elements/Editors/ClearStrategy/ClearButtonStrategy.ts
|
|
382
|
+
var import_selenium_webdriver8 = require("selenium-webdriver");
|
|
383
|
+
var DX_TEXTEDITOR_EMPTY = "dx-texteditor-empty";
|
|
384
|
+
var DX_CLEAR_BUTTON_AREA = "dx-clear-button-area";
|
|
385
|
+
var ClearButtonStrategy = class {
|
|
386
|
+
editorContainerClass;
|
|
387
|
+
constructor(editorContainerClass) {
|
|
388
|
+
this.editorContainerClass = editorContainerClass;
|
|
389
|
+
}
|
|
390
|
+
async isEmptyEditorField(editor) {
|
|
391
|
+
const parentEl = await editor.getParentElement();
|
|
392
|
+
const editorContainer = await parentEl.findElement(import_selenium_webdriver8.By.className(this.editorContainerClass));
|
|
393
|
+
const classAttribute = await editorContainer.getAttribute("class");
|
|
394
|
+
return classAttribute.includes(DX_TEXTEDITOR_EMPTY);
|
|
395
|
+
}
|
|
396
|
+
async clear(editor) {
|
|
397
|
+
if (await this.isEmptyEditorField(editor)) {
|
|
398
|
+
throw new Error("This field is already empty");
|
|
399
|
+
}
|
|
400
|
+
const clearBtnSelector = `.${this.editorContainerClass} .${DX_CLEAR_BUTTON_AREA}`;
|
|
401
|
+
const parentEl = await editor.getParentElement();
|
|
402
|
+
const clearBtn = await parentEl.findElement(import_selenium_webdriver8.By.css(clearBtnSelector));
|
|
403
|
+
await click(clearBtn, editor.driver);
|
|
404
|
+
}
|
|
405
|
+
};
|
|
406
|
+
|
|
303
407
|
// src/pageObjects/elements/Editors/SelectBoxEditor.ts
|
|
304
408
|
var SELECT_BOX_OPTION_TEXT_CONTAINER_CLASS = "d5-multi-select-item";
|
|
305
409
|
var SELECT_BOX_ELEMENT_ROLE = "option";
|
|
410
|
+
var combinedValueXpath = (value) => `${XPathHelper.getRoleXpath(SELECT_BOX_ELEMENT_ROLE)}${XPathHelper.getClassAndValueXpath(
|
|
411
|
+
SELECT_BOX_OPTION_TEXT_CONTAINER_CLASS,
|
|
412
|
+
value
|
|
413
|
+
)}`;
|
|
414
|
+
var DX_SELECTBOX = "dx-selectbox";
|
|
306
415
|
var SelectBoxEditor = class extends AbstractDXEditorWithInput {
|
|
416
|
+
constructor(getParentElement, elementBy, driver) {
|
|
417
|
+
super(getParentElement, elementBy, driver);
|
|
418
|
+
this.setClearStrategy(new ClearButtonStrategy(DX_SELECTBOX));
|
|
419
|
+
}
|
|
307
420
|
async setSelectInputValue(value) {
|
|
308
421
|
const inputEl = await this.getInputElement();
|
|
309
|
-
await inputEl.
|
|
310
|
-
await inputEl.sendKeys(value,
|
|
311
|
-
const combinedValueXpath = XPathHelper.getRoleXpath(SELECT_BOX_ELEMENT_ROLE) + XPathHelper.getClassAndValueXpath(SELECT_BOX_OPTION_TEXT_CONTAINER_CLASS, value);
|
|
422
|
+
await click(inputEl, this.driver);
|
|
423
|
+
await inputEl.sendKeys(value, import_selenium_webdriver9.Key.ENTER);
|
|
312
424
|
await this.driver.wait(async () => {
|
|
313
425
|
try {
|
|
314
|
-
const optElement = await inputEl.findElement(
|
|
315
|
-
await optElement.
|
|
426
|
+
const optElement = await inputEl.findElement(import_selenium_webdriver9.By.xpath(combinedValueXpath(value)));
|
|
427
|
+
await click(optElement, this.driver);
|
|
316
428
|
return true;
|
|
317
429
|
} catch (e) {
|
|
318
430
|
return false;
|
|
@@ -337,7 +449,7 @@ var SwitchEditor = class extends AbstractFormElement {
|
|
|
337
449
|
return 1;
|
|
338
450
|
if (result === "OFF")
|
|
339
451
|
return 0;
|
|
340
|
-
return
|
|
452
|
+
return null;
|
|
341
453
|
}
|
|
342
454
|
async setValue(value) {
|
|
343
455
|
if (value !== 0 && value !== 1) {
|
|
@@ -346,7 +458,7 @@ var SwitchEditor = class extends AbstractFormElement {
|
|
|
346
458
|
const inputEl = await this.getElement();
|
|
347
459
|
const currentValue = await this.getValue();
|
|
348
460
|
if (currentValue !== value) {
|
|
349
|
-
await inputEl.
|
|
461
|
+
await click(inputEl, this.driver);
|
|
350
462
|
await this.driver.wait(async () => {
|
|
351
463
|
const updatedValue = await this.getValue();
|
|
352
464
|
return updatedValue !== currentValue;
|
|
@@ -355,21 +467,205 @@ var SwitchEditor = class extends AbstractFormElement {
|
|
|
355
467
|
}
|
|
356
468
|
};
|
|
357
469
|
|
|
470
|
+
// src/pageObjects/elements/Editors/TagBox.ts
|
|
471
|
+
var import_selenium_webdriver10 = require("selenium-webdriver");
|
|
472
|
+
var TAGS_SELECTOR = ".dx-tag .tag-text";
|
|
473
|
+
var DX_TAG_CONTAINER = "dx-tag-container";
|
|
474
|
+
var DX_TAGBOX = "dx-tagbox";
|
|
475
|
+
var DX_TEXTEDITOR_EMPTY2 = "dx-texteditor-empty";
|
|
476
|
+
var BTN_OK_SELECTOR = ".dx-tagbox-popup-wrapper .dx-popup-bottom .dx-button.dx-popup-done";
|
|
477
|
+
var TagBox = class extends AbstractDXEditorWithInput {
|
|
478
|
+
constructor(getParentElement, elementBy, driver) {
|
|
479
|
+
super(getParentElement, elementBy, driver);
|
|
480
|
+
this.setClearStrategy(new ClearButtonStrategy(DX_TAGBOX));
|
|
481
|
+
}
|
|
482
|
+
async setTagBoxInputValue(values) {
|
|
483
|
+
const lastElement = values[values.length - 1];
|
|
484
|
+
const inputEl = await this.getInputElement();
|
|
485
|
+
await inputEl.click();
|
|
486
|
+
for (const value of values) {
|
|
487
|
+
await this.selectOption(inputEl, value, lastElement);
|
|
488
|
+
}
|
|
489
|
+
await this.confirmSelection();
|
|
490
|
+
}
|
|
491
|
+
async selectOption(inputEl, value, lastElement) {
|
|
492
|
+
await inputEl.sendKeys(value);
|
|
493
|
+
await this.driver.wait(async () => {
|
|
494
|
+
try {
|
|
495
|
+
const optElement = await inputEl.findElement(import_selenium_webdriver10.By.xpath(combinedValueXpath(value)));
|
|
496
|
+
await click(optElement, this.driver);
|
|
497
|
+
return true;
|
|
498
|
+
} catch (e) {
|
|
499
|
+
return false;
|
|
500
|
+
}
|
|
501
|
+
});
|
|
502
|
+
if (value !== lastElement) {
|
|
503
|
+
await inputEl.clear();
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
async confirmSelection() {
|
|
507
|
+
const inputEl = await this.getInputElement();
|
|
508
|
+
const option = await inputEl.findElement(import_selenium_webdriver10.By.xpath(XPathHelper.getRoleXpath(SELECT_BOX_ELEMENT_ROLE)));
|
|
509
|
+
const btnOk = await this.driver.findElement(import_selenium_webdriver10.By.css(BTN_OK_SELECTOR));
|
|
510
|
+
await this.driver.wait(async () => {
|
|
511
|
+
return await option.getAttribute("aria-selected") === "true";
|
|
512
|
+
});
|
|
513
|
+
await click(btnOk, this.driver);
|
|
514
|
+
}
|
|
515
|
+
async getTagBoxInputValue() {
|
|
516
|
+
if (await this.isTagBoxEmpty()) {
|
|
517
|
+
return [];
|
|
518
|
+
}
|
|
519
|
+
const parentEl = await this.getParentElement();
|
|
520
|
+
const inputEl = await parentEl.findElement(import_selenium_webdriver10.By.className(DX_TAG_CONTAINER));
|
|
521
|
+
const tags = await inputEl.findElements(import_selenium_webdriver10.By.css(TAGS_SELECTOR));
|
|
522
|
+
const values = [];
|
|
523
|
+
for (const tag of tags) {
|
|
524
|
+
const text = await tag.getText();
|
|
525
|
+
values.push(text);
|
|
526
|
+
}
|
|
527
|
+
return values;
|
|
528
|
+
}
|
|
529
|
+
async isTagBoxEmpty() {
|
|
530
|
+
const parentEl = await this.getParentElement();
|
|
531
|
+
const tagboxContainer = await parentEl.findElement(import_selenium_webdriver10.By.className(DX_TAGBOX));
|
|
532
|
+
const classAttribute = await tagboxContainer.getAttribute("class");
|
|
533
|
+
return classAttribute.includes(DX_TEXTEDITOR_EMPTY2);
|
|
534
|
+
}
|
|
535
|
+
async getValue() {
|
|
536
|
+
const value = await this.getTagBoxInputValue();
|
|
537
|
+
return value.length ? value : null;
|
|
538
|
+
}
|
|
539
|
+
async setValue(values) {
|
|
540
|
+
if (!Array.isArray(values)) {
|
|
541
|
+
throw new Error("The provided value is not an array");
|
|
542
|
+
}
|
|
543
|
+
await this.setTagBoxInputValue(values);
|
|
544
|
+
}
|
|
545
|
+
async remove(itemText) {
|
|
546
|
+
const tagValues = await this.getValue();
|
|
547
|
+
const tagExists = tagValues.includes(itemText);
|
|
548
|
+
if (!tagExists) {
|
|
549
|
+
throw new Error(`The tag with the text: ${itemText} was not found`);
|
|
550
|
+
}
|
|
551
|
+
const parentEl = await this.getParentElement();
|
|
552
|
+
const inputEl = await parentEl.findElement(import_selenium_webdriver10.By.className(DX_TAG_CONTAINER));
|
|
553
|
+
const clearBtnTestId = byTestId(`clear-button-${itemText}`);
|
|
554
|
+
const clearBtn = await inputEl.findElement(clearBtnTestId);
|
|
555
|
+
await click(clearBtn, this.driver);
|
|
556
|
+
}
|
|
557
|
+
};
|
|
558
|
+
|
|
559
|
+
// src/pageObjects/elements/Editors/ButtonGroup.ts
|
|
560
|
+
var import_selenium_webdriver11 = require("selenium-webdriver");
|
|
561
|
+
var ITEM_CLASS = "dx-buttongroup-item";
|
|
562
|
+
var SELECTED_CLASS = "dx-state-selected";
|
|
563
|
+
var ButtonGroup = class extends AbstractFormElement {
|
|
564
|
+
async getItems() {
|
|
565
|
+
return (await this.getElement()).findElements(import_selenium_webdriver11.By.className(ITEM_CLASS));
|
|
566
|
+
}
|
|
567
|
+
getDataValue(el) {
|
|
568
|
+
return el.getAttribute("data-value");
|
|
569
|
+
}
|
|
570
|
+
async getValue() {
|
|
571
|
+
const inputEl = await this.getElement();
|
|
572
|
+
const selectedEl = await inputEl.findElement(import_selenium_webdriver11.By.className(`${ITEM_CLASS} ${SELECTED_CLASS}`));
|
|
573
|
+
return this.getDataValue(selectedEl);
|
|
574
|
+
}
|
|
575
|
+
async setValue(value) {
|
|
576
|
+
const items = await this.getItems();
|
|
577
|
+
let buttonEl = void 0;
|
|
578
|
+
for (const item of items) {
|
|
579
|
+
const text = await this.getDataValue(item);
|
|
580
|
+
if (text == value) {
|
|
581
|
+
buttonEl = item;
|
|
582
|
+
break;
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
if (!buttonEl)
|
|
586
|
+
throw new Error(`Cannot find item in button group with text: ${value}`);
|
|
587
|
+
await click(buttonEl, this.driver);
|
|
588
|
+
}
|
|
589
|
+
};
|
|
590
|
+
|
|
591
|
+
// src/pageObjects/elements/Editors/BooleanSelector.ts
|
|
592
|
+
var BooleanSelector = class extends ButtonGroup {
|
|
593
|
+
// @ts-ignore
|
|
594
|
+
async getValue() {
|
|
595
|
+
const value = await super.getValue();
|
|
596
|
+
return value === "null" ? null : value === "1" ? 1 : 0;
|
|
597
|
+
}
|
|
598
|
+
// @ts-ignore
|
|
599
|
+
async setValue(value) {
|
|
600
|
+
const val = value == null ? "null" : value ? "1" : "0";
|
|
601
|
+
await super.setValue(val);
|
|
602
|
+
}
|
|
603
|
+
};
|
|
604
|
+
|
|
605
|
+
// src/pageObjects/elements/Editors/DateEditor.ts
|
|
606
|
+
var import_selenium_webdriver12 = require("selenium-webdriver");
|
|
607
|
+
var DateEditor = class extends AbstractDXEditorWithInput {
|
|
608
|
+
constructor(getParentElement, elementBy, driver) {
|
|
609
|
+
super(getParentElement, elementBy, driver);
|
|
610
|
+
this.setClearStrategy(new InputClearStrategy());
|
|
611
|
+
}
|
|
612
|
+
async getControlElement() {
|
|
613
|
+
const controlEl = await this.getElement();
|
|
614
|
+
return controlEl.findElement(import_selenium_webdriver12.By.className("dx-dropdowneditor-input-wrapper"));
|
|
615
|
+
}
|
|
616
|
+
async getDateElement() {
|
|
617
|
+
const controlEl = await this.getControlElement();
|
|
618
|
+
return controlEl.findElement(import_selenium_webdriver12.By.css("input[type=hidden]"));
|
|
619
|
+
}
|
|
620
|
+
async setDateValue(value) {
|
|
621
|
+
const dateEl = await this.getInputElement();
|
|
622
|
+
const stringDate = value.toJSON().split("T")[0];
|
|
623
|
+
const dateArr = stringDate.split("-");
|
|
624
|
+
const [year, month, day] = dateArr;
|
|
625
|
+
const keys = day + month + year;
|
|
626
|
+
await click(dateEl, this.driver);
|
|
627
|
+
const actions = this.driver.actions({ async: true });
|
|
628
|
+
await actions.move({ origin: dateEl }).sendKeys(import_selenium_webdriver12.Key.HOME).perform();
|
|
629
|
+
await actions.move({ origin: dateEl }).sendKeys(keys, import_selenium_webdriver12.Key.ENTER).perform();
|
|
630
|
+
}
|
|
631
|
+
async getDateValue() {
|
|
632
|
+
const inputEl = await this.getDateElement();
|
|
633
|
+
return inputEl.getAttribute("value");
|
|
634
|
+
}
|
|
635
|
+
async getValue() {
|
|
636
|
+
const value = await this.getDateValue();
|
|
637
|
+
return value == "" ? null : new Date(value);
|
|
638
|
+
}
|
|
639
|
+
setValue(value) {
|
|
640
|
+
if (typeof value === "object") {
|
|
641
|
+
return this.setDateValue(value);
|
|
642
|
+
}
|
|
643
|
+
throw new Error(`Value is incorrect. It should be Object`);
|
|
644
|
+
}
|
|
645
|
+
};
|
|
646
|
+
|
|
358
647
|
// src/pageObjects/elements/Editors/editorFactory.ts
|
|
359
648
|
var editorFactory = async (getParentElement, elementBy, driver) => {
|
|
360
649
|
const elementInstance = new AbstractFormElement(getParentElement, elementBy, driver);
|
|
361
|
-
const
|
|
362
|
-
const classSting = await element.getAttribute("class");
|
|
650
|
+
const classSting = await elementInstance.getClasses();
|
|
363
651
|
if (classSting.includes("text-control"))
|
|
364
652
|
return new TextEditor(getParentElement, elementBy, driver);
|
|
365
653
|
if (classSting.includes("number-control"))
|
|
366
654
|
return new NumberEditor(getParentElement, elementBy, driver);
|
|
367
655
|
if (classSting.includes("check-box"))
|
|
368
656
|
return new CheckBox(getParentElement, elementBy, driver);
|
|
657
|
+
if (classSting.includes("multi-select-control"))
|
|
658
|
+
return new TagBox(getParentElement, elementBy, driver);
|
|
369
659
|
if (classSting.includes("select-control"))
|
|
370
660
|
return new SelectBoxEditor(getParentElement, elementBy, driver);
|
|
371
661
|
if (classSting.includes("switch-control"))
|
|
372
662
|
return new SwitchEditor(getParentElement, elementBy, driver);
|
|
663
|
+
if (classSting.includes("date-control"))
|
|
664
|
+
return new DateEditor(getParentElement, elementBy, driver);
|
|
665
|
+
if (classSting.includes("buttons-group"))
|
|
666
|
+
return new BooleanSelector(getParentElement, elementBy, driver);
|
|
667
|
+
if (classSting.includes("button-group-field"))
|
|
668
|
+
return new ButtonGroup(getParentElement, elementBy, driver);
|
|
373
669
|
throw new Error("Unknown type of editor. Please write ticket to the support");
|
|
374
670
|
};
|
|
375
671
|
|
|
@@ -380,6 +676,9 @@ function createDataTestId(formName, itemType, itemName) {
|
|
|
380
676
|
function createFieldTestId(formName, itemName) {
|
|
381
677
|
return createDataTestId(formName, "form_field" /* FORM_FIELD */, itemName);
|
|
382
678
|
}
|
|
679
|
+
function createGroupTestId(formName, itemName) {
|
|
680
|
+
return createDataTestId(formName, "group" /* GROUP */, itemName);
|
|
681
|
+
}
|
|
383
682
|
function createTableId(formName) {
|
|
384
683
|
return `${"table" /* TABLE */}-${formName}`;
|
|
385
684
|
}
|
|
@@ -416,14 +715,82 @@ var FormField = class extends AbstractElementWithParent {
|
|
|
416
715
|
await this.initEditor();
|
|
417
716
|
return this.editor.setValue(value);
|
|
418
717
|
}
|
|
718
|
+
/**
|
|
719
|
+
* Очищает значение в поле
|
|
720
|
+
* @example
|
|
721
|
+
* await formEdit.field('NumberFld').clear();
|
|
722
|
+
*/
|
|
723
|
+
async clear() {
|
|
724
|
+
await this.initEditor();
|
|
725
|
+
if (!this.editor.clear) {
|
|
726
|
+
throw new Error("The clear method is not available for this field type.");
|
|
727
|
+
}
|
|
728
|
+
return this.editor.clear();
|
|
729
|
+
}
|
|
730
|
+
/**
|
|
731
|
+
* Удаляет тег по переданному тексту
|
|
732
|
+
* @example
|
|
733
|
+
* await formEdit.field('TagBox').remove('test');
|
|
734
|
+
*/
|
|
735
|
+
async remove(itemText) {
|
|
736
|
+
await this.initEditor();
|
|
737
|
+
if (!this.editor.remove) {
|
|
738
|
+
throw new Error("This method is only available for the TagBox field.");
|
|
739
|
+
}
|
|
740
|
+
return this.editor.remove(itemText);
|
|
741
|
+
}
|
|
742
|
+
};
|
|
743
|
+
|
|
744
|
+
// src/pageObjects/elements/Groups/AbstractGroup.ts
|
|
745
|
+
var AbstractDXGroup = class extends AbstractFormElement {
|
|
746
|
+
};
|
|
747
|
+
|
|
748
|
+
// src/pageObjects/elements/Groups/Panel.ts
|
|
749
|
+
var Panel = class extends AbstractDXGroup {
|
|
750
|
+
async isDisplayed() {
|
|
751
|
+
const groupElement = await this.getElement();
|
|
752
|
+
return await groupElement.isDisplayed();
|
|
753
|
+
}
|
|
754
|
+
};
|
|
755
|
+
|
|
756
|
+
// src/pageObjects/elements/Groups/groupFactory.ts
|
|
757
|
+
var groupFactory = async (getParentElement, elementBy, driver) => {
|
|
758
|
+
const elementInstance = new AbstractFormElement(getParentElement, elementBy, driver);
|
|
759
|
+
const classSting = await elementInstance.getClasses();
|
|
760
|
+
if (classSting.includes("panel-group"))
|
|
761
|
+
return new Panel(getParentElement, elementBy, driver);
|
|
762
|
+
throw new Error("Unknown type of group. Please write ticket to the support");
|
|
763
|
+
};
|
|
764
|
+
|
|
765
|
+
// src/pageObjects/elements/FormGroup.ts
|
|
766
|
+
var FormGroup = class extends AbstractElementWithParent {
|
|
767
|
+
editor;
|
|
768
|
+
constructor(getParentElement, formName, name, driver) {
|
|
769
|
+
super(getParentElement, driver);
|
|
770
|
+
this.elementBy = byTestId(createGroupTestId(formName, name));
|
|
771
|
+
}
|
|
772
|
+
async initEditor() {
|
|
773
|
+
if (!this.editor) {
|
|
774
|
+
this.editor = await groupFactory(this.getParentElement, this.elementBy, this.driver);
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
/**
|
|
778
|
+
* Возвращает булевое значение доступна ли группа
|
|
779
|
+
* @example
|
|
780
|
+
* expect(await tableList.group('MainSuperPanel').isDisplayed();
|
|
781
|
+
*/
|
|
782
|
+
async isDisplayed() {
|
|
783
|
+
await this.initEditor();
|
|
784
|
+
return this.editor.isDisplayed();
|
|
785
|
+
}
|
|
419
786
|
};
|
|
420
787
|
|
|
421
788
|
// src/pageObjects/elements/Forms/FormEdit.ts
|
|
422
789
|
var FormEdit = class extends AbstractForm {
|
|
423
|
-
saveButtonBy =
|
|
790
|
+
saveButtonBy = import_selenium_webdriver13.By.id("button-save");
|
|
424
791
|
constructor(driver) {
|
|
425
792
|
super(driver);
|
|
426
|
-
this.popupContainerBy =
|
|
793
|
+
this.popupContainerBy = import_selenium_webdriver13.By.className(`popup form-edit-${this.formName}`);
|
|
427
794
|
}
|
|
428
795
|
/**
|
|
429
796
|
* Находит поле формы редактирования по имени
|
|
@@ -435,6 +802,28 @@ var FormEdit = class extends AbstractForm {
|
|
|
435
802
|
field(name) {
|
|
436
803
|
return new FormField(this.getContainerElement, this.formName, name, this.driver);
|
|
437
804
|
}
|
|
805
|
+
/**
|
|
806
|
+
* Проверяет не отключена ли кнопка Сохранить
|
|
807
|
+
* @example
|
|
808
|
+
* const formEdit = new MyForm();
|
|
809
|
+
* //...
|
|
810
|
+
* await formEdit.isSaveButtonDisabled();
|
|
811
|
+
*/
|
|
812
|
+
async isSaveButtonDisabled() {
|
|
813
|
+
const saveButton = await this.driver.findElement(this.saveButtonBy);
|
|
814
|
+
const result = await saveButton.getAttribute("aria-disabled");
|
|
815
|
+
return result === "true";
|
|
816
|
+
}
|
|
817
|
+
/**
|
|
818
|
+
* Находит группу формы редактирования по имени
|
|
819
|
+
* @example
|
|
820
|
+
* const formEdit = new MyForm();
|
|
821
|
+
* //...
|
|
822
|
+
* expect(await formEdit.group('Name');
|
|
823
|
+
*/
|
|
824
|
+
group(name) {
|
|
825
|
+
return new FormGroup(this.getContainerElement, this.formName, name, this.driver);
|
|
826
|
+
}
|
|
438
827
|
/**
|
|
439
828
|
* Нажатие на кнопку Сохранить
|
|
440
829
|
* @example
|
|
@@ -443,41 +832,42 @@ var FormEdit = class extends AbstractForm {
|
|
|
443
832
|
* await formEdit.saveButtonClick();
|
|
444
833
|
*/
|
|
445
834
|
async saveButtonClick() {
|
|
446
|
-
await this.driver.findElement(this.saveButtonBy)
|
|
835
|
+
const saveButton = await this.driver.findElement(this.saveButtonBy);
|
|
836
|
+
await this.driver.wait(async () => !await this.isSaveButtonDisabled(), void 0, "Button is disabled");
|
|
837
|
+
await click(saveButton, this.driver);
|
|
447
838
|
}
|
|
448
839
|
};
|
|
449
840
|
|
|
450
841
|
// src/pageObjects/elements/Forms/ListForm.ts
|
|
451
|
-
var
|
|
842
|
+
var import_selenium_webdriver19 = require("selenium-webdriver");
|
|
452
843
|
|
|
453
844
|
// src/pageObjects/elements/Table/Table.ts
|
|
454
|
-
var
|
|
845
|
+
var import_selenium_webdriver16 = require("selenium-webdriver");
|
|
455
846
|
|
|
456
847
|
// src/pageObjects/elements/Table/utils.ts
|
|
457
|
-
var
|
|
848
|
+
var import_selenium_webdriver14 = require("selenium-webdriver");
|
|
458
849
|
var getRowPathByIndex = (index) => {
|
|
459
|
-
return
|
|
850
|
+
return import_selenium_webdriver14.By.css(`tr[aria-rowindex="${transformInputIndex(index)}"]`);
|
|
460
851
|
};
|
|
852
|
+
var getColumnByIndexCssSelector = (columnIndex) => `td[aria-colindex="${transformInputIndex(columnIndex)}"]`;
|
|
461
853
|
var getColumnPathByIndex = (index) => {
|
|
462
|
-
return
|
|
463
|
-
};
|
|
464
|
-
var getColumnPathByCaption = (caption) => {
|
|
465
|
-
return import_selenium_webdriver9.By.xpath(`//td[@role="columnheader"][@aria-label="Column ${caption}"]`);
|
|
854
|
+
return import_selenium_webdriver14.By.css(getColumnByIndexCssSelector(index));
|
|
466
855
|
};
|
|
856
|
+
var getColumnByCaptionCssSelector = (caption) => `td[role="columnheader"][aria-label="Column ${caption}"]`;
|
|
467
857
|
var getCellPathByIndex = (index) => {
|
|
468
|
-
return
|
|
858
|
+
return import_selenium_webdriver14.By.css(`td[role="gridcell"][aria-colindex="${transformInputIndex(index)}"]`);
|
|
469
859
|
};
|
|
470
860
|
var transformInputIndex = (index) => index + 1;
|
|
471
861
|
var transformOutputIndex = (index) => +index - 1;
|
|
472
862
|
|
|
473
863
|
// src/pageObjects/elements/Table/elements/Row.ts
|
|
474
|
-
var
|
|
864
|
+
var import_selenium_webdriver15 = require("selenium-webdriver");
|
|
475
865
|
|
|
476
866
|
// src/pageObjects/elements/Table/elements/Cell.ts
|
|
477
867
|
var Cell = class extends AbstractElementWithParent {
|
|
478
868
|
index;
|
|
479
|
-
constructor(
|
|
480
|
-
super(
|
|
869
|
+
constructor(rowEl, index, driver) {
|
|
870
|
+
super(() => Promise.resolve(rowEl), driver);
|
|
481
871
|
this.index = index;
|
|
482
872
|
this.elementBy = getCellPathByIndex(index);
|
|
483
873
|
}
|
|
@@ -491,6 +881,9 @@ var Cell = class extends AbstractElementWithParent {
|
|
|
491
881
|
};
|
|
492
882
|
|
|
493
883
|
// src/pageObjects/elements/Table/elements/Row.ts
|
|
884
|
+
var DX_SELECTION_CLASS = "dx-selection";
|
|
885
|
+
var DX_ROW_EDIT_CLASS = "dx-edit-row";
|
|
886
|
+
var DX_DATA_ROW_CLASS = "dx-data-row";
|
|
494
887
|
var Row = class extends AbstractElementWithParent {
|
|
495
888
|
index;
|
|
496
889
|
getColumnByCaption;
|
|
@@ -500,14 +893,11 @@ var Row = class extends AbstractElementWithParent {
|
|
|
500
893
|
this.elementBy = getRowPathByIndex(index);
|
|
501
894
|
this.getColumnByCaption = getColumnByCaption;
|
|
502
895
|
}
|
|
503
|
-
getRowElement = () => {
|
|
504
|
-
return this.driver.findElement(this.elementBy);
|
|
505
|
-
};
|
|
506
896
|
async getCellByIndex(index) {
|
|
507
897
|
const rowEl = await this.getElement();
|
|
508
898
|
const cell = rowEl.findElement(getCellPathByIndex(index));
|
|
509
899
|
if (cell) {
|
|
510
|
-
return new Cell(
|
|
900
|
+
return new Cell(rowEl, index, this.driver);
|
|
511
901
|
}
|
|
512
902
|
throw new Error(`Cannot find cell by index: ${index}`);
|
|
513
903
|
}
|
|
@@ -521,7 +911,11 @@ var Row = class extends AbstractElementWithParent {
|
|
|
521
911
|
}
|
|
522
912
|
async select() {
|
|
523
913
|
const rowEl = await this.getElement();
|
|
524
|
-
await rowEl.
|
|
914
|
+
await click(rowEl, this.driver);
|
|
915
|
+
await this.driver.wait(async () => {
|
|
916
|
+
const classes = await rowEl.getAttribute("class");
|
|
917
|
+
return classes.includes(DX_SELECTION_CLASS);
|
|
918
|
+
}, 500, "Cannot select row");
|
|
525
919
|
}
|
|
526
920
|
async isSelected() {
|
|
527
921
|
const rowEl = await this.getElement();
|
|
@@ -533,34 +927,38 @@ var Row = class extends AbstractElementWithParent {
|
|
|
533
927
|
}
|
|
534
928
|
async getCells() {
|
|
535
929
|
const rowEl = await this.getElement();
|
|
536
|
-
const cells = await rowEl.findElements(
|
|
930
|
+
const cells = await rowEl.findElements(import_selenium_webdriver15.By.css(`td[role="gridcell"]`));
|
|
537
931
|
const result = [];
|
|
538
932
|
cells.forEach((_, index) => {
|
|
539
|
-
const newCell = new Cell(
|
|
933
|
+
const newCell = new Cell(rowEl, index, this.driver);
|
|
540
934
|
result.push(newCell);
|
|
541
935
|
});
|
|
542
936
|
return result;
|
|
543
937
|
}
|
|
544
|
-
async clickInlineButton(
|
|
545
|
-
const
|
|
546
|
-
|
|
938
|
+
async clickInlineButton(buttonClass) {
|
|
939
|
+
const FIXED_TABLE_CSS_SELECTOR = ".dx-fixed-columns .dx-datagrid-content.dx-datagrid-content-fixed";
|
|
940
|
+
const buttonCssSelector = `.${DX_DATA_ROW_CLASS}[aria-rowindex="${transformInputIndex(this.index)}"] .${buttonClass}`;
|
|
941
|
+
const button = (await this.getParentElement()).findElement(
|
|
942
|
+
import_selenium_webdriver15.By.css(`${FIXED_TABLE_CSS_SELECTOR} ${buttonCssSelector}`)
|
|
547
943
|
);
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
944
|
+
return click(button, this.driver);
|
|
945
|
+
}
|
|
946
|
+
async checkEditingMode(isEditing, msg) {
|
|
947
|
+
await this.driver.wait(async () => {
|
|
948
|
+
return (await this.getClasses()).includes(DX_ROW_EDIT_CLASS) === isEditing;
|
|
949
|
+
}, 2e3, msg);
|
|
554
950
|
}
|
|
555
951
|
async edit() {
|
|
556
|
-
await this.
|
|
557
|
-
|
|
952
|
+
await this.clickInlineButton("edit");
|
|
953
|
+
await this.checkEditingMode(true, "Row did not switch to edit mode");
|
|
558
954
|
}
|
|
559
955
|
async save() {
|
|
560
|
-
|
|
956
|
+
await this.clickInlineButton("save");
|
|
957
|
+
await this.checkEditingMode(false, "Row did not saved");
|
|
561
958
|
}
|
|
562
959
|
async cancel() {
|
|
563
|
-
|
|
960
|
+
await this.clickInlineButton("cancel");
|
|
961
|
+
await this.checkEditingMode(false, "Row did not switch to normal mode");
|
|
564
962
|
}
|
|
565
963
|
};
|
|
566
964
|
|
|
@@ -583,20 +981,21 @@ var Column = class extends AbstractElementWithParent {
|
|
|
583
981
|
|
|
584
982
|
// src/pageObjects/elements/Table/Table.ts
|
|
585
983
|
var Table = class extends AbstractElementWithParent {
|
|
984
|
+
formName;
|
|
586
985
|
constructor(getParentElement, formName, driver) {
|
|
587
986
|
super(getParentElement, driver);
|
|
588
|
-
this.elementBy =
|
|
987
|
+
this.elementBy = import_selenium_webdriver16.By.id(createTableId(formName));
|
|
988
|
+
this.formName = formName;
|
|
589
989
|
}
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
return parentEl.findElement(import_selenium_webdriver11.By.className("dx-header-row"));
|
|
990
|
+
getHeaderCssSelector() {
|
|
991
|
+
return ".dx-datagrid-headers .dx-datagrid-content:not(.dx-datagrid-content-fixed)";
|
|
593
992
|
}
|
|
594
993
|
async getDataGrid() {
|
|
595
994
|
const parentEl = await this.getElement();
|
|
596
|
-
return parentEl.findElement(
|
|
995
|
+
return parentEl.findElement(import_selenium_webdriver16.By.css(`div[role="grid"]`));
|
|
597
996
|
}
|
|
598
997
|
getTableElement = () => {
|
|
599
|
-
return this.
|
|
998
|
+
return this.getElement();
|
|
600
999
|
};
|
|
601
1000
|
async getRowByIndex(index) {
|
|
602
1001
|
const gridContainer = await this.getDataGrid();
|
|
@@ -607,16 +1006,14 @@ var Table = class extends AbstractElementWithParent {
|
|
|
607
1006
|
throw new Error(`Cannot find row by index: ${index}`);
|
|
608
1007
|
}
|
|
609
1008
|
async getColumnByIndex(index) {
|
|
610
|
-
const
|
|
611
|
-
const column = await headerContainer.findElement(getColumnPathByIndex(index));
|
|
1009
|
+
const column = await (await this.getElement()).findElement(import_selenium_webdriver16.By.css(`${this.getHeaderCssSelector()} ${getColumnByIndexCssSelector(index)}`));
|
|
612
1010
|
if (column) {
|
|
613
1011
|
return new Column(this.getTableElement, index, this.driver);
|
|
614
1012
|
}
|
|
615
1013
|
throw new Error(`Cannot find column by index: ${index}`);
|
|
616
1014
|
}
|
|
617
1015
|
async getColumnByCaption(caption) {
|
|
618
|
-
const
|
|
619
|
-
const column = await headerContainer.findElement(getColumnPathByCaption(caption));
|
|
1016
|
+
const column = await (await this.getElement()).findElement(import_selenium_webdriver16.By.css(`${this.getHeaderCssSelector()} ${getColumnByCaptionCssSelector(caption)}`));
|
|
620
1017
|
if (column) {
|
|
621
1018
|
const index = await column.getAttribute("aria-colindex");
|
|
622
1019
|
return new Column(this.getTableElement, transformOutputIndex(index), this.driver);
|
|
@@ -633,7 +1030,7 @@ var Table = class extends AbstractElementWithParent {
|
|
|
633
1030
|
}
|
|
634
1031
|
async getRows() {
|
|
635
1032
|
const gridContainer = await this.getDataGrid();
|
|
636
|
-
const rows = await gridContainer.findElements(
|
|
1033
|
+
const rows = await gridContainer.findElements(import_selenium_webdriver16.By.className("dx-row dx-data-row"));
|
|
637
1034
|
const result = [];
|
|
638
1035
|
rows.forEach((_, index) => {
|
|
639
1036
|
const newRow = new Row(this.getTableElement, index, this.driver, this.getColumnByCaption.bind(this));
|
|
@@ -642,8 +1039,7 @@ var Table = class extends AbstractElementWithParent {
|
|
|
642
1039
|
return result;
|
|
643
1040
|
}
|
|
644
1041
|
async getColumns() {
|
|
645
|
-
const
|
|
646
|
-
const columns = await headerContainer.findElements(import_selenium_webdriver11.By.css(`td[role="columnheader"]`));
|
|
1042
|
+
const columns = await (await this.getElement()).findElements(import_selenium_webdriver16.By.css(`${this.getHeaderCssSelector()} td[role="columnheader"]`));
|
|
647
1043
|
const result = [];
|
|
648
1044
|
columns.forEach((_, index) => {
|
|
649
1045
|
const newCol = new Column(this.getTableElement, index, this.driver);
|
|
@@ -651,25 +1047,40 @@ var Table = class extends AbstractElementWithParent {
|
|
|
651
1047
|
});
|
|
652
1048
|
return result;
|
|
653
1049
|
}
|
|
654
|
-
|
|
1050
|
+
element() {
|
|
655
1051
|
return this.getElement();
|
|
656
1052
|
}
|
|
1053
|
+
/**
|
|
1054
|
+
* Находит поле когда форма находится в состоянии редактирования
|
|
1055
|
+
* @example
|
|
1056
|
+
* const form = new MyForm();
|
|
1057
|
+
* //...
|
|
1058
|
+
* expect(await form.field('Name').getValue()).toBe('test value');
|
|
1059
|
+
*/
|
|
1060
|
+
field(name) {
|
|
1061
|
+
return new FormField(this.getTableElement, this.formName, name, this.driver);
|
|
1062
|
+
}
|
|
657
1063
|
};
|
|
658
1064
|
|
|
659
1065
|
// src/pageObjects/elements/TableToolbar/TableToolbar.ts
|
|
660
|
-
var
|
|
1066
|
+
var import_selenium_webdriver18 = require("selenium-webdriver");
|
|
661
1067
|
|
|
662
1068
|
// src/pageObjects/elements/TableToolbar/TableToolbarButton.ts
|
|
663
|
-
var
|
|
1069
|
+
var import_selenium_webdriver17 = require("selenium-webdriver");
|
|
664
1070
|
var TOOLBAR_BUTTON_CLASS = "toolbar-button";
|
|
665
1071
|
var TableToolbarButton = class extends AbstractElementWithParent {
|
|
1072
|
+
name;
|
|
666
1073
|
constructor(getParentElement, name, driver) {
|
|
667
1074
|
super(getParentElement, driver);
|
|
668
|
-
this.
|
|
1075
|
+
this.name = name;
|
|
1076
|
+
this.elementBy = import_selenium_webdriver17.By.id(`${TOOLBAR_BUTTON_CLASS}-${name}`);
|
|
669
1077
|
}
|
|
670
1078
|
async click() {
|
|
671
1079
|
const button = await this.getElement();
|
|
672
|
-
|
|
1080
|
+
await this.driver.wait(async () => {
|
|
1081
|
+
return await button.isDisplayed() && !await this.isDisabled();
|
|
1082
|
+
}, 1e3, `Button ${this.name} cannot be clicked. It is not displayed or it is disabled`);
|
|
1083
|
+
return click(button, this.driver);
|
|
673
1084
|
}
|
|
674
1085
|
async isDisabled() {
|
|
675
1086
|
const button = await this.getElement();
|
|
@@ -683,14 +1094,14 @@ var TABLE_TOOLBAR_CLASS = "d5-table-toolbar";
|
|
|
683
1094
|
var TableToolbar = class extends AbstractElementWithParent {
|
|
684
1095
|
constructor(getParentElement, formName, driver) {
|
|
685
1096
|
super(getParentElement, driver);
|
|
686
|
-
this.elementBy =
|
|
1097
|
+
this.elementBy = import_selenium_webdriver18.By.id(`${TABLE_TOOLBAR_CLASS}-${formName}`);
|
|
687
1098
|
}
|
|
688
1099
|
getTableToolbarElement = () => {
|
|
689
1100
|
return this.driver.findElement(this.elementBy);
|
|
690
1101
|
};
|
|
691
1102
|
async button(name) {
|
|
692
1103
|
const toolbar = await this.getTableToolbarElement();
|
|
693
|
-
const button = await toolbar.findElement(
|
|
1104
|
+
const button = await toolbar.findElement(import_selenium_webdriver18.By.id(`${TOOLBAR_BUTTON_CLASS}-${name}`));
|
|
694
1105
|
if (button) {
|
|
695
1106
|
return new TableToolbarButton(this.getTableToolbarElement, name, this.driver);
|
|
696
1107
|
}
|
|
@@ -702,7 +1113,7 @@ var TableToolbar = class extends AbstractElementWithParent {
|
|
|
702
1113
|
var ListForm = class extends AbstractForm {
|
|
703
1114
|
constructor(driver) {
|
|
704
1115
|
super(driver);
|
|
705
|
-
this.popupContainerBy =
|
|
1116
|
+
this.popupContainerBy = import_selenium_webdriver19.By.className(`popup form-inline-${this.formName}`);
|
|
706
1117
|
}
|
|
707
1118
|
/**
|
|
708
1119
|
* Находит таблицу
|
|
@@ -714,6 +1125,16 @@ var ListForm = class extends AbstractForm {
|
|
|
714
1125
|
table() {
|
|
715
1126
|
return new Table(this.getContainerElement, this.formName, this.driver);
|
|
716
1127
|
}
|
|
1128
|
+
/**
|
|
1129
|
+
* Находит группу на лист форме по имени
|
|
1130
|
+
* @example
|
|
1131
|
+
* const formEdit = new MyForm();
|
|
1132
|
+
* //...
|
|
1133
|
+
* expect(await formEdit.group('Name');
|
|
1134
|
+
*/
|
|
1135
|
+
group(name) {
|
|
1136
|
+
return new FormGroup(this.getContainerElement, this.formName, name, this.driver);
|
|
1137
|
+
}
|
|
717
1138
|
/**
|
|
718
1139
|
* Находит таблицу
|
|
719
1140
|
* @example
|
|
@@ -737,12 +1158,27 @@ async function signIn(driver) {
|
|
|
737
1158
|
return webDriver;
|
|
738
1159
|
}
|
|
739
1160
|
|
|
1161
|
+
// src/utils/actions.ts
|
|
1162
|
+
var click = async (webElement, driver) => {
|
|
1163
|
+
driver = driver ?? config().driver;
|
|
1164
|
+
const actions = driver.actions({ async: true });
|
|
1165
|
+
await actions.move({ origin: webElement }).click().perform();
|
|
1166
|
+
};
|
|
1167
|
+
|
|
740
1168
|
// src/pageObjects/pages/LoginPage.ts
|
|
741
1169
|
var LOGIN_PATH = "/login";
|
|
742
1170
|
var LoginPage = class extends AbstractPage {
|
|
743
1171
|
usernameField = byTestId("loginField", "input");
|
|
744
1172
|
passwordField = byTestId("passwordField", "input");
|
|
745
1173
|
loginButton = byTestId("loginButton");
|
|
1174
|
+
async locate() {
|
|
1175
|
+
await super.locate();
|
|
1176
|
+
const login = await this.driver.findElement(this.usernameField);
|
|
1177
|
+
await waitElementIsVisible({
|
|
1178
|
+
element: login,
|
|
1179
|
+
driver: this.driver
|
|
1180
|
+
});
|
|
1181
|
+
}
|
|
746
1182
|
get path() {
|
|
747
1183
|
return LOGIN_PATH;
|
|
748
1184
|
}
|
|
@@ -753,7 +1189,7 @@ var LoginPage = class extends AbstractPage {
|
|
|
753
1189
|
await this.driver.findElement(this.passwordField).sendKeys(password);
|
|
754
1190
|
}
|
|
755
1191
|
async clickLoginButton() {
|
|
756
|
-
await this.driver.findElement(this.loginButton).
|
|
1192
|
+
await click(await this.driver.findElement(this.loginButton), this.driver);
|
|
757
1193
|
}
|
|
758
1194
|
async loginWith(username, password) {
|
|
759
1195
|
await this.enterUsername(username);
|
|
@@ -775,9 +1211,11 @@ var LoginPage = class extends AbstractPage {
|
|
|
775
1211
|
SubsystemsPanel,
|
|
776
1212
|
TextEditor,
|
|
777
1213
|
byTestId,
|
|
1214
|
+
click,
|
|
778
1215
|
config,
|
|
779
1216
|
createDriver,
|
|
780
1217
|
editorFactory,
|
|
781
1218
|
elementIsNotPresent,
|
|
782
|
-
signIn
|
|
1219
|
+
signIn,
|
|
1220
|
+
waitElementIsVisible
|
|
783
1221
|
});
|