d5-testing-library 1.0.4 → 1.0.5
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.
|
@@ -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,6 +39,7 @@ __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,
|
|
@@ -38,6 +49,25 @@ __export(src_exports, {
|
|
|
38
49
|
module.exports = __toCommonJS(src_exports);
|
|
39
50
|
|
|
40
51
|
// src/config.ts
|
|
52
|
+
var process = __toESM(require("process"));
|
|
53
|
+
var driversMap = /* @__PURE__ */ new Map();
|
|
54
|
+
var createConfigProxy = (config2) => {
|
|
55
|
+
return new Proxy(config2, {
|
|
56
|
+
get(_target, prop) {
|
|
57
|
+
if (prop === "driver") {
|
|
58
|
+
return driversMap.get(process.pid);
|
|
59
|
+
}
|
|
60
|
+
return Reflect.get(...arguments);
|
|
61
|
+
},
|
|
62
|
+
set(_target, prop, value) {
|
|
63
|
+
if (prop === "driver") {
|
|
64
|
+
driversMap.set(process.pid, value);
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
return Reflect.set(...arguments);
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
};
|
|
41
71
|
var Config = class _Config {
|
|
42
72
|
static instance;
|
|
43
73
|
appConfig;
|
|
@@ -49,7 +79,7 @@ var Config = class _Config {
|
|
|
49
79
|
}
|
|
50
80
|
config = (cfg) => {
|
|
51
81
|
if (!cfg)
|
|
52
|
-
return this.appConfig;
|
|
82
|
+
return createConfigProxy(this.appConfig);
|
|
53
83
|
this.appConfig = cfg;
|
|
54
84
|
};
|
|
55
85
|
};
|
|
@@ -120,6 +150,9 @@ var elementIsNotPresent = function elementIsNotPresent2(locator) {
|
|
|
120
150
|
});
|
|
121
151
|
};
|
|
122
152
|
|
|
153
|
+
// src/utils/waitElementIsVisible.ts
|
|
154
|
+
var import_selenium_webdriver4 = require("selenium-webdriver");
|
|
155
|
+
|
|
123
156
|
// src/pageObjects/AbstractElementWithParent.ts
|
|
124
157
|
var AbstractElementWithParent = class extends AbstractElement {
|
|
125
158
|
getParentElement;
|
|
@@ -144,9 +177,9 @@ var SubsystemsPanelHeader = class extends AbstractElementWithParent {
|
|
|
144
177
|
};
|
|
145
178
|
|
|
146
179
|
// src/pageObjects/elements/SubsystemsPanel/SubsystemsPanel.ts
|
|
147
|
-
var
|
|
180
|
+
var import_selenium_webdriver5 = require("selenium-webdriver");
|
|
148
181
|
var SubsystemsPanel = class extends AbstractElement {
|
|
149
|
-
panelBy =
|
|
182
|
+
panelBy = import_selenium_webdriver5.By.id("aside");
|
|
150
183
|
header;
|
|
151
184
|
constructor(driver) {
|
|
152
185
|
super(driver);
|
|
@@ -161,7 +194,7 @@ var SubsystemsPanel = class extends AbstractElement {
|
|
|
161
194
|
};
|
|
162
195
|
|
|
163
196
|
// src/pageObjects/elements/Forms/AbstractForm.ts
|
|
164
|
-
var
|
|
197
|
+
var import_selenium_webdriver6 = require("selenium-webdriver");
|
|
165
198
|
var AbstractForm = class extends AbstractPage {
|
|
166
199
|
containerBy;
|
|
167
200
|
popupContainerBy;
|
|
@@ -206,20 +239,20 @@ var AbstractForm = class extends AbstractPage {
|
|
|
206
239
|
async getTitleText() {
|
|
207
240
|
if (await this.isModal()) {
|
|
208
241
|
const popupEl = await this.driver.findElement(this.popupContainerBy);
|
|
209
|
-
const titleEl2 = await popupEl.findElement(
|
|
242
|
+
const titleEl2 = await popupEl.findElement(import_selenium_webdriver6.By.className("popup-title"));
|
|
210
243
|
return titleEl2.getText();
|
|
211
244
|
}
|
|
212
245
|
let container = await this.getContainerElement();
|
|
213
|
-
let titleEl = await container.findElement(
|
|
246
|
+
let titleEl = await container.findElement(import_selenium_webdriver6.By.className("form-toolbar-name-container"));
|
|
214
247
|
return titleEl.getText();
|
|
215
248
|
}
|
|
216
249
|
};
|
|
217
250
|
|
|
218
251
|
// src/pageObjects/elements/Forms/FormEdit.ts
|
|
219
|
-
var
|
|
252
|
+
var import_selenium_webdriver9 = require("selenium-webdriver");
|
|
220
253
|
|
|
221
254
|
// src/pageObjects/elements/Editors/AbstractEditor.ts
|
|
222
|
-
var
|
|
255
|
+
var import_selenium_webdriver7 = require("selenium-webdriver");
|
|
223
256
|
|
|
224
257
|
// src/pageObjects/AbstractFormElement.ts
|
|
225
258
|
var AbstractFormElement = class extends AbstractElementWithParent {
|
|
@@ -233,7 +266,7 @@ var AbstractFormElement = class extends AbstractElementWithParent {
|
|
|
233
266
|
var AbstractDXEditorWithInput = class extends AbstractFormElement {
|
|
234
267
|
async getInputElement() {
|
|
235
268
|
const controlEl = await this.getElement();
|
|
236
|
-
return controlEl.findElement(
|
|
269
|
+
return controlEl.findElement(import_selenium_webdriver7.By.className("dx-texteditor-input"));
|
|
237
270
|
}
|
|
238
271
|
async getInputValue() {
|
|
239
272
|
const inputEl = await this.getInputElement();
|
|
@@ -241,8 +274,8 @@ var AbstractDXEditorWithInput = class extends AbstractFormElement {
|
|
|
241
274
|
}
|
|
242
275
|
async setInputValue(value) {
|
|
243
276
|
const inputEl = await this.getInputElement();
|
|
244
|
-
await inputEl.
|
|
245
|
-
await inputEl.sendKeys(value,
|
|
277
|
+
await click(inputEl, this.driver);
|
|
278
|
+
await inputEl.sendKeys(value, import_selenium_webdriver7.Key.ENTER);
|
|
246
279
|
}
|
|
247
280
|
};
|
|
248
281
|
|
|
@@ -282,13 +315,13 @@ var CheckBox = class extends AbstractFormElement {
|
|
|
282
315
|
const inputEl = await this.getElement();
|
|
283
316
|
const currentValue = await this.getValue();
|
|
284
317
|
if (currentValue !== value) {
|
|
285
|
-
await inputEl.
|
|
318
|
+
await click(inputEl, this.driver);
|
|
286
319
|
}
|
|
287
320
|
}
|
|
288
321
|
};
|
|
289
322
|
|
|
290
323
|
// src/pageObjects/elements/Editors/SelectBoxEditor.ts
|
|
291
|
-
var
|
|
324
|
+
var import_selenium_webdriver8 = require("selenium-webdriver");
|
|
292
325
|
|
|
293
326
|
// src/utils/xpathHelper.ts
|
|
294
327
|
var XPathHelper = class {
|
|
@@ -306,13 +339,13 @@ var SELECT_BOX_ELEMENT_ROLE = "option";
|
|
|
306
339
|
var SelectBoxEditor = class extends AbstractDXEditorWithInput {
|
|
307
340
|
async setSelectInputValue(value) {
|
|
308
341
|
const inputEl = await this.getInputElement();
|
|
309
|
-
await inputEl.
|
|
310
|
-
await inputEl.sendKeys(value,
|
|
342
|
+
await click(inputEl, this.driver);
|
|
343
|
+
await inputEl.sendKeys(value, import_selenium_webdriver8.Key.ENTER);
|
|
311
344
|
const combinedValueXpath = XPathHelper.getRoleXpath(SELECT_BOX_ELEMENT_ROLE) + XPathHelper.getClassAndValueXpath(SELECT_BOX_OPTION_TEXT_CONTAINER_CLASS, value);
|
|
312
345
|
await this.driver.wait(async () => {
|
|
313
346
|
try {
|
|
314
|
-
const optElement = await inputEl.findElement(
|
|
315
|
-
await optElement.
|
|
347
|
+
const optElement = await inputEl.findElement(import_selenium_webdriver8.By.xpath(combinedValueXpath));
|
|
348
|
+
await click(optElement, this.driver);
|
|
316
349
|
return true;
|
|
317
350
|
} catch (e) {
|
|
318
351
|
return false;
|
|
@@ -346,7 +379,7 @@ var SwitchEditor = class extends AbstractFormElement {
|
|
|
346
379
|
const inputEl = await this.getElement();
|
|
347
380
|
const currentValue = await this.getValue();
|
|
348
381
|
if (currentValue !== value) {
|
|
349
|
-
await inputEl.
|
|
382
|
+
await click(inputEl, this.driver);
|
|
350
383
|
await this.driver.wait(async () => {
|
|
351
384
|
const updatedValue = await this.getValue();
|
|
352
385
|
return updatedValue !== currentValue;
|
|
@@ -420,10 +453,10 @@ var FormField = class extends AbstractElementWithParent {
|
|
|
420
453
|
|
|
421
454
|
// src/pageObjects/elements/Forms/FormEdit.ts
|
|
422
455
|
var FormEdit = class extends AbstractForm {
|
|
423
|
-
saveButtonBy =
|
|
456
|
+
saveButtonBy = import_selenium_webdriver9.By.id("button-save");
|
|
424
457
|
constructor(driver) {
|
|
425
458
|
super(driver);
|
|
426
|
-
this.popupContainerBy =
|
|
459
|
+
this.popupContainerBy = import_selenium_webdriver9.By.className(`popup form-edit-${this.formName}`);
|
|
427
460
|
}
|
|
428
461
|
/**
|
|
429
462
|
* Находит поле формы редактирования по имени
|
|
@@ -443,41 +476,41 @@ var FormEdit = class extends AbstractForm {
|
|
|
443
476
|
* await formEdit.saveButtonClick();
|
|
444
477
|
*/
|
|
445
478
|
async saveButtonClick() {
|
|
446
|
-
await this.driver.findElement(this.saveButtonBy).
|
|
479
|
+
await click(await this.driver.findElement(this.saveButtonBy), this.driver);
|
|
447
480
|
}
|
|
448
481
|
};
|
|
449
482
|
|
|
450
483
|
// src/pageObjects/elements/Forms/ListForm.ts
|
|
451
|
-
var
|
|
484
|
+
var import_selenium_webdriver15 = require("selenium-webdriver");
|
|
452
485
|
|
|
453
486
|
// src/pageObjects/elements/Table/Table.ts
|
|
454
|
-
var
|
|
487
|
+
var import_selenium_webdriver12 = require("selenium-webdriver");
|
|
455
488
|
|
|
456
489
|
// src/pageObjects/elements/Table/utils.ts
|
|
457
|
-
var
|
|
490
|
+
var import_selenium_webdriver10 = require("selenium-webdriver");
|
|
458
491
|
var getRowPathByIndex = (index) => {
|
|
459
|
-
return
|
|
492
|
+
return import_selenium_webdriver10.By.css(`tr[aria-rowindex="${transformInputIndex(index)}"]`);
|
|
460
493
|
};
|
|
461
494
|
var getColumnPathByIndex = (index) => {
|
|
462
|
-
return
|
|
495
|
+
return import_selenium_webdriver10.By.css(`td[aria-colindex="${transformInputIndex(index)}"]`);
|
|
463
496
|
};
|
|
464
497
|
var getColumnPathByCaption = (caption) => {
|
|
465
|
-
return
|
|
498
|
+
return import_selenium_webdriver10.By.css(`td[role="columnheader"][aria-label="Column ${caption}"]`);
|
|
466
499
|
};
|
|
467
500
|
var getCellPathByIndex = (index) => {
|
|
468
|
-
return
|
|
501
|
+
return import_selenium_webdriver10.By.css(`td[role="gridcell"][aria-colindex="${transformInputIndex(index)}"]`);
|
|
469
502
|
};
|
|
470
503
|
var transformInputIndex = (index) => index + 1;
|
|
471
504
|
var transformOutputIndex = (index) => +index - 1;
|
|
472
505
|
|
|
473
506
|
// src/pageObjects/elements/Table/elements/Row.ts
|
|
474
|
-
var
|
|
507
|
+
var import_selenium_webdriver11 = require("selenium-webdriver");
|
|
475
508
|
|
|
476
509
|
// src/pageObjects/elements/Table/elements/Cell.ts
|
|
477
510
|
var Cell = class extends AbstractElementWithParent {
|
|
478
511
|
index;
|
|
479
|
-
constructor(
|
|
480
|
-
super(
|
|
512
|
+
constructor(rowEl, index, driver) {
|
|
513
|
+
super(() => Promise.resolve(rowEl), driver);
|
|
481
514
|
this.index = index;
|
|
482
515
|
this.elementBy = getCellPathByIndex(index);
|
|
483
516
|
}
|
|
@@ -491,6 +524,8 @@ var Cell = class extends AbstractElementWithParent {
|
|
|
491
524
|
};
|
|
492
525
|
|
|
493
526
|
// src/pageObjects/elements/Table/elements/Row.ts
|
|
527
|
+
var DX_SELECTION_CLASS = "dx-selection";
|
|
528
|
+
var DX_ROW_EDIT_CLASS = "dx-edit-row";
|
|
494
529
|
var Row = class extends AbstractElementWithParent {
|
|
495
530
|
index;
|
|
496
531
|
getColumnByCaption;
|
|
@@ -500,14 +535,11 @@ var Row = class extends AbstractElementWithParent {
|
|
|
500
535
|
this.elementBy = getRowPathByIndex(index);
|
|
501
536
|
this.getColumnByCaption = getColumnByCaption;
|
|
502
537
|
}
|
|
503
|
-
getRowElement = () => {
|
|
504
|
-
return this.driver.findElement(this.elementBy);
|
|
505
|
-
};
|
|
506
538
|
async getCellByIndex(index) {
|
|
507
539
|
const rowEl = await this.getElement();
|
|
508
540
|
const cell = rowEl.findElement(getCellPathByIndex(index));
|
|
509
541
|
if (cell) {
|
|
510
|
-
return new Cell(
|
|
542
|
+
return new Cell(rowEl, index, this.driver);
|
|
511
543
|
}
|
|
512
544
|
throw new Error(`Cannot find cell by index: ${index}`);
|
|
513
545
|
}
|
|
@@ -521,7 +553,13 @@ var Row = class extends AbstractElementWithParent {
|
|
|
521
553
|
}
|
|
522
554
|
async select() {
|
|
523
555
|
const rowEl = await this.getElement();
|
|
524
|
-
await rowEl.
|
|
556
|
+
await click(rowEl, this.driver);
|
|
557
|
+
await this.driver.wait(async () => {
|
|
558
|
+
const classes = await rowEl.getAttribute("class");
|
|
559
|
+
if (!classes.includes(DX_SELECTION_CLASS))
|
|
560
|
+
throw new Error("Cannot select row");
|
|
561
|
+
return true;
|
|
562
|
+
}, 500);
|
|
525
563
|
}
|
|
526
564
|
async isSelected() {
|
|
527
565
|
const rowEl = await this.getElement();
|
|
@@ -533,34 +571,34 @@ var Row = class extends AbstractElementWithParent {
|
|
|
533
571
|
}
|
|
534
572
|
async getCells() {
|
|
535
573
|
const rowEl = await this.getElement();
|
|
536
|
-
const cells = await rowEl.findElements(
|
|
574
|
+
const cells = await rowEl.findElements(import_selenium_webdriver11.By.css(`td[role="gridcell"]`));
|
|
537
575
|
const result = [];
|
|
538
576
|
cells.forEach((_, index) => {
|
|
539
|
-
const newCell = new Cell(
|
|
577
|
+
const newCell = new Cell(rowEl, index, this.driver);
|
|
540
578
|
result.push(newCell);
|
|
541
579
|
});
|
|
542
580
|
return result;
|
|
543
581
|
}
|
|
544
582
|
async clickInlineButton(rowClass, buttonClass) {
|
|
545
|
-
const fixedTable = await this.getParentElement().findElement(
|
|
546
|
-
|
|
583
|
+
const fixedTable = (await this.getParentElement()).findElement(
|
|
584
|
+
import_selenium_webdriver11.By.css(".dx-fixed-columns .dx-datagrid-content.dx-datagrid-content-fixed")
|
|
547
585
|
);
|
|
548
|
-
const rowEl = await fixedTable.findElement(
|
|
549
|
-
const button = await rowEl.findElement(
|
|
586
|
+
const rowEl = await fixedTable.findElement(import_selenium_webdriver11.By.className(rowClass));
|
|
587
|
+
const button = await rowEl.findElement(import_selenium_webdriver11.By.className(buttonClass));
|
|
550
588
|
if (button) {
|
|
551
|
-
return button.
|
|
589
|
+
return click(button, this.driver);
|
|
552
590
|
}
|
|
553
591
|
throw new Error(`Cannot find ${buttonClass} button`);
|
|
554
592
|
}
|
|
555
593
|
async edit() {
|
|
556
594
|
await this.select();
|
|
557
|
-
return this.clickInlineButton(
|
|
595
|
+
return this.clickInlineButton(DX_SELECTION_CLASS, "edit");
|
|
558
596
|
}
|
|
559
597
|
async save() {
|
|
560
|
-
return this.clickInlineButton(
|
|
598
|
+
return this.clickInlineButton(DX_ROW_EDIT_CLASS, "save");
|
|
561
599
|
}
|
|
562
600
|
async cancel() {
|
|
563
|
-
return this.clickInlineButton(
|
|
601
|
+
return this.clickInlineButton(DX_ROW_EDIT_CLASS, "cancel");
|
|
564
602
|
}
|
|
565
603
|
};
|
|
566
604
|
|
|
@@ -583,17 +621,19 @@ var Column = class extends AbstractElementWithParent {
|
|
|
583
621
|
|
|
584
622
|
// src/pageObjects/elements/Table/Table.ts
|
|
585
623
|
var Table = class extends AbstractElementWithParent {
|
|
624
|
+
formName;
|
|
586
625
|
constructor(getParentElement, formName, driver) {
|
|
587
626
|
super(getParentElement, driver);
|
|
588
|
-
this.elementBy =
|
|
627
|
+
this.elementBy = import_selenium_webdriver12.By.id(createTableId(formName));
|
|
628
|
+
this.formName = formName;
|
|
589
629
|
}
|
|
590
630
|
async getHeaderElement() {
|
|
591
631
|
const parentEl = await this.getElement();
|
|
592
|
-
return parentEl.findElement(
|
|
632
|
+
return parentEl.findElement(import_selenium_webdriver12.By.className("dx-header-row"));
|
|
593
633
|
}
|
|
594
634
|
async getDataGrid() {
|
|
595
635
|
const parentEl = await this.getElement();
|
|
596
|
-
return parentEl.findElement(
|
|
636
|
+
return parentEl.findElement(import_selenium_webdriver12.By.css(`div[role="grid"]`));
|
|
597
637
|
}
|
|
598
638
|
getTableElement = () => {
|
|
599
639
|
return this.driver.findElement(this.elementBy);
|
|
@@ -633,7 +673,7 @@ var Table = class extends AbstractElementWithParent {
|
|
|
633
673
|
}
|
|
634
674
|
async getRows() {
|
|
635
675
|
const gridContainer = await this.getDataGrid();
|
|
636
|
-
const rows = await gridContainer.findElements(
|
|
676
|
+
const rows = await gridContainer.findElements(import_selenium_webdriver12.By.className("dx-row dx-data-row"));
|
|
637
677
|
const result = [];
|
|
638
678
|
rows.forEach((_, index) => {
|
|
639
679
|
const newRow = new Row(this.getTableElement, index, this.driver, this.getColumnByCaption.bind(this));
|
|
@@ -643,7 +683,7 @@ var Table = class extends AbstractElementWithParent {
|
|
|
643
683
|
}
|
|
644
684
|
async getColumns() {
|
|
645
685
|
const headerContainer = await this.getHeaderElement();
|
|
646
|
-
const columns = await headerContainer.findElements(
|
|
686
|
+
const columns = await headerContainer.findElements(import_selenium_webdriver12.By.css(`td[role="columnheader"]`));
|
|
647
687
|
const result = [];
|
|
648
688
|
columns.forEach((_, index) => {
|
|
649
689
|
const newCol = new Column(this.getTableElement, index, this.driver);
|
|
@@ -651,25 +691,35 @@ var Table = class extends AbstractElementWithParent {
|
|
|
651
691
|
});
|
|
652
692
|
return result;
|
|
653
693
|
}
|
|
654
|
-
|
|
694
|
+
element() {
|
|
655
695
|
return this.getElement();
|
|
656
696
|
}
|
|
697
|
+
/**
|
|
698
|
+
* Находит поле когда форма находится в состоянии редактирования
|
|
699
|
+
* @example
|
|
700
|
+
* const form = new MyForm();
|
|
701
|
+
* //...
|
|
702
|
+
* expect(await form.field('Name').getValue()).toBe('test value');
|
|
703
|
+
*/
|
|
704
|
+
field(name) {
|
|
705
|
+
return new FormField(this.getElement, this.formName, name, this.driver);
|
|
706
|
+
}
|
|
657
707
|
};
|
|
658
708
|
|
|
659
709
|
// src/pageObjects/elements/TableToolbar/TableToolbar.ts
|
|
660
|
-
var
|
|
710
|
+
var import_selenium_webdriver14 = require("selenium-webdriver");
|
|
661
711
|
|
|
662
712
|
// src/pageObjects/elements/TableToolbar/TableToolbarButton.ts
|
|
663
|
-
var
|
|
713
|
+
var import_selenium_webdriver13 = require("selenium-webdriver");
|
|
664
714
|
var TOOLBAR_BUTTON_CLASS = "toolbar-button";
|
|
665
715
|
var TableToolbarButton = class extends AbstractElementWithParent {
|
|
666
716
|
constructor(getParentElement, name, driver) {
|
|
667
717
|
super(getParentElement, driver);
|
|
668
|
-
this.elementBy =
|
|
718
|
+
this.elementBy = import_selenium_webdriver13.By.id(`${TOOLBAR_BUTTON_CLASS}-${name}`);
|
|
669
719
|
}
|
|
670
720
|
async click() {
|
|
671
721
|
const button = await this.getElement();
|
|
672
|
-
return button.
|
|
722
|
+
return click(button, this.driver);
|
|
673
723
|
}
|
|
674
724
|
async isDisabled() {
|
|
675
725
|
const button = await this.getElement();
|
|
@@ -683,14 +733,14 @@ var TABLE_TOOLBAR_CLASS = "d5-table-toolbar";
|
|
|
683
733
|
var TableToolbar = class extends AbstractElementWithParent {
|
|
684
734
|
constructor(getParentElement, formName, driver) {
|
|
685
735
|
super(getParentElement, driver);
|
|
686
|
-
this.elementBy =
|
|
736
|
+
this.elementBy = import_selenium_webdriver14.By.id(`${TABLE_TOOLBAR_CLASS}-${formName}`);
|
|
687
737
|
}
|
|
688
738
|
getTableToolbarElement = () => {
|
|
689
739
|
return this.driver.findElement(this.elementBy);
|
|
690
740
|
};
|
|
691
741
|
async button(name) {
|
|
692
742
|
const toolbar = await this.getTableToolbarElement();
|
|
693
|
-
const button = await toolbar.findElement(
|
|
743
|
+
const button = await toolbar.findElement(import_selenium_webdriver14.By.id(`${TOOLBAR_BUTTON_CLASS}-${name}`));
|
|
694
744
|
if (button) {
|
|
695
745
|
return new TableToolbarButton(this.getTableToolbarElement, name, this.driver);
|
|
696
746
|
}
|
|
@@ -702,7 +752,7 @@ var TableToolbar = class extends AbstractElementWithParent {
|
|
|
702
752
|
var ListForm = class extends AbstractForm {
|
|
703
753
|
constructor(driver) {
|
|
704
754
|
super(driver);
|
|
705
|
-
this.popupContainerBy =
|
|
755
|
+
this.popupContainerBy = import_selenium_webdriver15.By.className(`popup form-inline-${this.formName}`);
|
|
706
756
|
}
|
|
707
757
|
/**
|
|
708
758
|
* Находит таблицу
|
|
@@ -737,6 +787,13 @@ async function signIn(driver) {
|
|
|
737
787
|
return webDriver;
|
|
738
788
|
}
|
|
739
789
|
|
|
790
|
+
// src/utils/actions.ts
|
|
791
|
+
var click = async (webElement, driver) => {
|
|
792
|
+
driver = driver ?? config().driver;
|
|
793
|
+
const actions = driver.actions({ async: true });
|
|
794
|
+
await actions.move({ origin: webElement }).click().perform();
|
|
795
|
+
};
|
|
796
|
+
|
|
740
797
|
// src/pageObjects/pages/LoginPage.ts
|
|
741
798
|
var LOGIN_PATH = "/login";
|
|
742
799
|
var LoginPage = class extends AbstractPage {
|
|
@@ -753,7 +810,7 @@ var LoginPage = class extends AbstractPage {
|
|
|
753
810
|
await this.driver.findElement(this.passwordField).sendKeys(password);
|
|
754
811
|
}
|
|
755
812
|
async clickLoginButton() {
|
|
756
|
-
await this.driver.findElement(this.loginButton).
|
|
813
|
+
await click(await this.driver.findElement(this.loginButton), this.driver);
|
|
757
814
|
}
|
|
758
815
|
async loginWith(username, password) {
|
|
759
816
|
await this.enterUsername(username);
|
|
@@ -775,6 +832,7 @@ var LoginPage = class extends AbstractPage {
|
|
|
775
832
|
SubsystemsPanel,
|
|
776
833
|
TextEditor,
|
|
777
834
|
byTestId,
|
|
835
|
+
click,
|
|
778
836
|
config,
|
|
779
837
|
createDriver,
|
|
780
838
|
editorFactory,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as selenium_webdriver from 'selenium-webdriver';
|
|
2
|
-
import { WebDriver, Browser, By, Condition, WebElementPromise } from 'selenium-webdriver';
|
|
2
|
+
import { WebDriver, Browser, By, Condition, WebElement, WebElementPromise } from 'selenium-webdriver';
|
|
3
3
|
|
|
4
4
|
type DriverType = typeof Browser;
|
|
5
5
|
type BrowserList = DriverType[keyof DriverType];
|
|
@@ -66,6 +66,15 @@ declare const elementIsNotPresent: (locator: By) => Condition<boolean>;
|
|
|
66
66
|
|
|
67
67
|
declare function signIn(driver?: WebDriver): Promise<WebDriver>;
|
|
68
68
|
|
|
69
|
+
/**
|
|
70
|
+
* Clicks on a specified web element.
|
|
71
|
+
*
|
|
72
|
+
* @param {WebElement} webElement - The web element to click on.
|
|
73
|
+
* @param {WebDriver} [driver] - The web driver instance to use. If not provided, the default driver from the configuration is used.
|
|
74
|
+
* @returns {Promise<void>} A promise that resolves when the click action is complete.
|
|
75
|
+
*/
|
|
76
|
+
declare const click: (webElement: WebElement, driver?: WebDriver) => Promise<void>;
|
|
77
|
+
|
|
69
78
|
declare class SubsystemsPanel extends AbstractElement {
|
|
70
79
|
private panelBy;
|
|
71
80
|
private header;
|
|
@@ -101,10 +110,10 @@ declare abstract class AbstractForm extends AbstractPage {
|
|
|
101
110
|
}
|
|
102
111
|
|
|
103
112
|
declare abstract class AbstractElementWithParent extends AbstractElement {
|
|
104
|
-
protected getParentElement: () =>
|
|
113
|
+
protected getParentElement: () => Promise<WebElement>;
|
|
105
114
|
protected elementBy: By;
|
|
106
|
-
constructor(getParentElement: () =>
|
|
107
|
-
getElement(): Promise<
|
|
115
|
+
constructor(getParentElement: () => Promise<WebElement>, driver?: WebDriver);
|
|
116
|
+
getElement(): Promise<WebElement>;
|
|
108
117
|
}
|
|
109
118
|
|
|
110
119
|
interface Editor {
|
|
@@ -113,7 +122,7 @@ interface Editor {
|
|
|
113
122
|
}
|
|
114
123
|
|
|
115
124
|
declare class AbstractFormElement extends AbstractElementWithParent {
|
|
116
|
-
constructor(getParentElement: () =>
|
|
125
|
+
constructor(getParentElement: () => Promise<WebElement>, elementBy: By, driver?: WebDriver);
|
|
117
126
|
}
|
|
118
127
|
|
|
119
128
|
declare abstract class AbstractDXEditorWithInput extends AbstractFormElement implements Editor {
|
|
@@ -134,11 +143,11 @@ declare class NumberEditor extends AbstractDXEditorWithInput {
|
|
|
134
143
|
setValue(value: any): Promise<void>;
|
|
135
144
|
}
|
|
136
145
|
|
|
137
|
-
declare const editorFactory: (getParentElement: () =>
|
|
146
|
+
declare const editorFactory: (getParentElement: () => Promise<WebElement>, elementBy: By, driver?: WebDriver) => Promise<Editor>;
|
|
138
147
|
|
|
139
148
|
declare class FormField extends AbstractElementWithParent implements Editor {
|
|
140
149
|
editor: Editor;
|
|
141
|
-
constructor(getParentElement: () =>
|
|
150
|
+
constructor(getParentElement: () => Promise<WebElement>, formName: string, name: string, driver?: WebDriver);
|
|
142
151
|
private initEditor;
|
|
143
152
|
/**
|
|
144
153
|
* Возвращает значение в поле
|
|
@@ -185,7 +194,7 @@ declare class TableToolbarButton extends AbstractElementWithParent {
|
|
|
185
194
|
|
|
186
195
|
declare class Cell extends AbstractElementWithParent {
|
|
187
196
|
index: number;
|
|
188
|
-
constructor(
|
|
197
|
+
constructor(rowEl: WebElement, index: number, driver?: WebDriver);
|
|
189
198
|
getValue(): Promise<string>;
|
|
190
199
|
getIndex(): number;
|
|
191
200
|
}
|
|
@@ -201,7 +210,6 @@ declare class Row extends AbstractElementWithParent {
|
|
|
201
210
|
index: number;
|
|
202
211
|
protected getColumnByCaption: (caption: string) => Promise<Column>;
|
|
203
212
|
constructor(getParentElement: () => WebElementPromise, index: number, driver?: WebDriver, getColumnByCaption?: (caption: string) => Promise<Column>);
|
|
204
|
-
protected getRowElement: () => WebElementPromise;
|
|
205
213
|
getCellByIndex(index: number): Promise<Cell>;
|
|
206
214
|
getCell(caption: string): Promise<Cell>;
|
|
207
215
|
select(): Promise<void>;
|
|
@@ -215,6 +223,7 @@ declare class Row extends AbstractElementWithParent {
|
|
|
215
223
|
}
|
|
216
224
|
|
|
217
225
|
declare class Table extends AbstractElementWithParent {
|
|
226
|
+
protected formName: string;
|
|
218
227
|
constructor(getParentElement: () => WebElementPromise, formName: string, driver?: WebDriver);
|
|
219
228
|
protected getHeaderElement(): Promise<selenium_webdriver.WebElement>;
|
|
220
229
|
protected getDataGrid(): Promise<selenium_webdriver.WebElement>;
|
|
@@ -226,6 +235,14 @@ declare class Table extends AbstractElementWithParent {
|
|
|
226
235
|
getRows(): Promise<Row[]>;
|
|
227
236
|
getColumns(): Promise<Column[]>;
|
|
228
237
|
element(): Promise<selenium_webdriver.WebElement>;
|
|
238
|
+
/**
|
|
239
|
+
* Находит поле когда форма находится в состоянии редактирования
|
|
240
|
+
* @example
|
|
241
|
+
* const form = new MyForm();
|
|
242
|
+
* //...
|
|
243
|
+
* expect(await form.field('Name').getValue()).toBe('test value');
|
|
244
|
+
*/
|
|
245
|
+
field(name: string): FormField;
|
|
229
246
|
}
|
|
230
247
|
|
|
231
248
|
declare abstract class ListForm extends AbstractForm {
|
|
@@ -248,4 +265,4 @@ declare abstract class ListForm extends AbstractForm {
|
|
|
248
265
|
toolbarButton(name: string): Promise<TableToolbarButton>;
|
|
249
266
|
}
|
|
250
267
|
|
|
251
|
-
export { AbstractPage, Editor, FormEdit, FormField, ListForm, LoginPage, NumberEditor, SubsystemsPanel, TextEditor, byTestId, config, createDriver, editorFactory, elementIsNotPresent, signIn };
|
|
268
|
+
export { AbstractPage, Editor, FormEdit, FormField, ListForm, LoginPage, NumberEditor, SubsystemsPanel, TextEditor, byTestId, click, config, createDriver, editorFactory, elementIsNotPresent, signIn };
|
|
@@ -1,4 +1,23 @@
|
|
|
1
1
|
// src/config.ts
|
|
2
|
+
import * as process from "node:process";
|
|
3
|
+
var driversMap = /* @__PURE__ */ new Map();
|
|
4
|
+
var createConfigProxy = (config2) => {
|
|
5
|
+
return new Proxy(config2, {
|
|
6
|
+
get(_target, prop) {
|
|
7
|
+
if (prop === "driver") {
|
|
8
|
+
return driversMap.get(process.pid);
|
|
9
|
+
}
|
|
10
|
+
return Reflect.get(...arguments);
|
|
11
|
+
},
|
|
12
|
+
set(_target, prop, value) {
|
|
13
|
+
if (prop === "driver") {
|
|
14
|
+
driversMap.set(process.pid, value);
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
return Reflect.set(...arguments);
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
};
|
|
2
21
|
var Config = class _Config {
|
|
3
22
|
static instance;
|
|
4
23
|
appConfig;
|
|
@@ -10,7 +29,7 @@ var Config = class _Config {
|
|
|
10
29
|
}
|
|
11
30
|
config = (cfg) => {
|
|
12
31
|
if (!cfg)
|
|
13
|
-
return this.appConfig;
|
|
32
|
+
return createConfigProxy(this.appConfig);
|
|
14
33
|
this.appConfig = cfg;
|
|
15
34
|
};
|
|
16
35
|
};
|
|
@@ -81,6 +100,9 @@ var elementIsNotPresent = function elementIsNotPresent2(locator) {
|
|
|
81
100
|
});
|
|
82
101
|
};
|
|
83
102
|
|
|
103
|
+
// src/utils/waitElementIsVisible.ts
|
|
104
|
+
import { until } from "selenium-webdriver";
|
|
105
|
+
|
|
84
106
|
// src/pageObjects/AbstractElementWithParent.ts
|
|
85
107
|
var AbstractElementWithParent = class extends AbstractElement {
|
|
86
108
|
getParentElement;
|
|
@@ -202,7 +224,7 @@ var AbstractDXEditorWithInput = class extends AbstractFormElement {
|
|
|
202
224
|
}
|
|
203
225
|
async setInputValue(value) {
|
|
204
226
|
const inputEl = await this.getInputElement();
|
|
205
|
-
await inputEl.
|
|
227
|
+
await click(inputEl, this.driver);
|
|
206
228
|
await inputEl.sendKeys(value, Key.ENTER);
|
|
207
229
|
}
|
|
208
230
|
};
|
|
@@ -243,7 +265,7 @@ var CheckBox = class extends AbstractFormElement {
|
|
|
243
265
|
const inputEl = await this.getElement();
|
|
244
266
|
const currentValue = await this.getValue();
|
|
245
267
|
if (currentValue !== value) {
|
|
246
|
-
await inputEl.
|
|
268
|
+
await click(inputEl, this.driver);
|
|
247
269
|
}
|
|
248
270
|
}
|
|
249
271
|
};
|
|
@@ -267,13 +289,13 @@ var SELECT_BOX_ELEMENT_ROLE = "option";
|
|
|
267
289
|
var SelectBoxEditor = class extends AbstractDXEditorWithInput {
|
|
268
290
|
async setSelectInputValue(value) {
|
|
269
291
|
const inputEl = await this.getInputElement();
|
|
270
|
-
await inputEl.
|
|
292
|
+
await click(inputEl, this.driver);
|
|
271
293
|
await inputEl.sendKeys(value, Key2.ENTER);
|
|
272
294
|
const combinedValueXpath = XPathHelper.getRoleXpath(SELECT_BOX_ELEMENT_ROLE) + XPathHelper.getClassAndValueXpath(SELECT_BOX_OPTION_TEXT_CONTAINER_CLASS, value);
|
|
273
295
|
await this.driver.wait(async () => {
|
|
274
296
|
try {
|
|
275
297
|
const optElement = await inputEl.findElement(By6.xpath(combinedValueXpath));
|
|
276
|
-
await optElement.
|
|
298
|
+
await click(optElement, this.driver);
|
|
277
299
|
return true;
|
|
278
300
|
} catch (e) {
|
|
279
301
|
return false;
|
|
@@ -307,7 +329,7 @@ var SwitchEditor = class extends AbstractFormElement {
|
|
|
307
329
|
const inputEl = await this.getElement();
|
|
308
330
|
const currentValue = await this.getValue();
|
|
309
331
|
if (currentValue !== value) {
|
|
310
|
-
await inputEl.
|
|
332
|
+
await click(inputEl, this.driver);
|
|
311
333
|
await this.driver.wait(async () => {
|
|
312
334
|
const updatedValue = await this.getValue();
|
|
313
335
|
return updatedValue !== currentValue;
|
|
@@ -404,7 +426,7 @@ var FormEdit = class extends AbstractForm {
|
|
|
404
426
|
* await formEdit.saveButtonClick();
|
|
405
427
|
*/
|
|
406
428
|
async saveButtonClick() {
|
|
407
|
-
await this.driver.findElement(this.saveButtonBy).
|
|
429
|
+
await click(await this.driver.findElement(this.saveButtonBy), this.driver);
|
|
408
430
|
}
|
|
409
431
|
};
|
|
410
432
|
|
|
@@ -417,16 +439,16 @@ import { By as By10 } from "selenium-webdriver";
|
|
|
417
439
|
// src/pageObjects/elements/Table/utils.ts
|
|
418
440
|
import { By as By8 } from "selenium-webdriver";
|
|
419
441
|
var getRowPathByIndex = (index) => {
|
|
420
|
-
return By8.
|
|
442
|
+
return By8.css(`tr[aria-rowindex="${transformInputIndex(index)}"]`);
|
|
421
443
|
};
|
|
422
444
|
var getColumnPathByIndex = (index) => {
|
|
423
|
-
return By8.
|
|
445
|
+
return By8.css(`td[aria-colindex="${transformInputIndex(index)}"]`);
|
|
424
446
|
};
|
|
425
447
|
var getColumnPathByCaption = (caption) => {
|
|
426
|
-
return By8.
|
|
448
|
+
return By8.css(`td[role="columnheader"][aria-label="Column ${caption}"]`);
|
|
427
449
|
};
|
|
428
450
|
var getCellPathByIndex = (index) => {
|
|
429
|
-
return By8.
|
|
451
|
+
return By8.css(`td[role="gridcell"][aria-colindex="${transformInputIndex(index)}"]`);
|
|
430
452
|
};
|
|
431
453
|
var transformInputIndex = (index) => index + 1;
|
|
432
454
|
var transformOutputIndex = (index) => +index - 1;
|
|
@@ -437,8 +459,8 @@ import { By as By9 } from "selenium-webdriver";
|
|
|
437
459
|
// src/pageObjects/elements/Table/elements/Cell.ts
|
|
438
460
|
var Cell = class extends AbstractElementWithParent {
|
|
439
461
|
index;
|
|
440
|
-
constructor(
|
|
441
|
-
super(
|
|
462
|
+
constructor(rowEl, index, driver) {
|
|
463
|
+
super(() => Promise.resolve(rowEl), driver);
|
|
442
464
|
this.index = index;
|
|
443
465
|
this.elementBy = getCellPathByIndex(index);
|
|
444
466
|
}
|
|
@@ -452,6 +474,8 @@ var Cell = class extends AbstractElementWithParent {
|
|
|
452
474
|
};
|
|
453
475
|
|
|
454
476
|
// src/pageObjects/elements/Table/elements/Row.ts
|
|
477
|
+
var DX_SELECTION_CLASS = "dx-selection";
|
|
478
|
+
var DX_ROW_EDIT_CLASS = "dx-edit-row";
|
|
455
479
|
var Row = class extends AbstractElementWithParent {
|
|
456
480
|
index;
|
|
457
481
|
getColumnByCaption;
|
|
@@ -461,14 +485,11 @@ var Row = class extends AbstractElementWithParent {
|
|
|
461
485
|
this.elementBy = getRowPathByIndex(index);
|
|
462
486
|
this.getColumnByCaption = getColumnByCaption;
|
|
463
487
|
}
|
|
464
|
-
getRowElement = () => {
|
|
465
|
-
return this.driver.findElement(this.elementBy);
|
|
466
|
-
};
|
|
467
488
|
async getCellByIndex(index) {
|
|
468
489
|
const rowEl = await this.getElement();
|
|
469
490
|
const cell = rowEl.findElement(getCellPathByIndex(index));
|
|
470
491
|
if (cell) {
|
|
471
|
-
return new Cell(
|
|
492
|
+
return new Cell(rowEl, index, this.driver);
|
|
472
493
|
}
|
|
473
494
|
throw new Error(`Cannot find cell by index: ${index}`);
|
|
474
495
|
}
|
|
@@ -482,7 +503,13 @@ var Row = class extends AbstractElementWithParent {
|
|
|
482
503
|
}
|
|
483
504
|
async select() {
|
|
484
505
|
const rowEl = await this.getElement();
|
|
485
|
-
await rowEl.
|
|
506
|
+
await click(rowEl, this.driver);
|
|
507
|
+
await this.driver.wait(async () => {
|
|
508
|
+
const classes = await rowEl.getAttribute("class");
|
|
509
|
+
if (!classes.includes(DX_SELECTION_CLASS))
|
|
510
|
+
throw new Error("Cannot select row");
|
|
511
|
+
return true;
|
|
512
|
+
}, 500);
|
|
486
513
|
}
|
|
487
514
|
async isSelected() {
|
|
488
515
|
const rowEl = await this.getElement();
|
|
@@ -497,31 +524,31 @@ var Row = class extends AbstractElementWithParent {
|
|
|
497
524
|
const cells = await rowEl.findElements(By9.css(`td[role="gridcell"]`));
|
|
498
525
|
const result = [];
|
|
499
526
|
cells.forEach((_, index) => {
|
|
500
|
-
const newCell = new Cell(
|
|
527
|
+
const newCell = new Cell(rowEl, index, this.driver);
|
|
501
528
|
result.push(newCell);
|
|
502
529
|
});
|
|
503
530
|
return result;
|
|
504
531
|
}
|
|
505
532
|
async clickInlineButton(rowClass, buttonClass) {
|
|
506
|
-
const fixedTable = await this.getParentElement().findElement(
|
|
533
|
+
const fixedTable = (await this.getParentElement()).findElement(
|
|
507
534
|
By9.css(".dx-fixed-columns .dx-datagrid-content.dx-datagrid-content-fixed")
|
|
508
535
|
);
|
|
509
536
|
const rowEl = await fixedTable.findElement(By9.className(rowClass));
|
|
510
537
|
const button = await rowEl.findElement(By9.className(buttonClass));
|
|
511
538
|
if (button) {
|
|
512
|
-
return button.
|
|
539
|
+
return click(button, this.driver);
|
|
513
540
|
}
|
|
514
541
|
throw new Error(`Cannot find ${buttonClass} button`);
|
|
515
542
|
}
|
|
516
543
|
async edit() {
|
|
517
544
|
await this.select();
|
|
518
|
-
return this.clickInlineButton(
|
|
545
|
+
return this.clickInlineButton(DX_SELECTION_CLASS, "edit");
|
|
519
546
|
}
|
|
520
547
|
async save() {
|
|
521
|
-
return this.clickInlineButton(
|
|
548
|
+
return this.clickInlineButton(DX_ROW_EDIT_CLASS, "save");
|
|
522
549
|
}
|
|
523
550
|
async cancel() {
|
|
524
|
-
return this.clickInlineButton(
|
|
551
|
+
return this.clickInlineButton(DX_ROW_EDIT_CLASS, "cancel");
|
|
525
552
|
}
|
|
526
553
|
};
|
|
527
554
|
|
|
@@ -544,9 +571,11 @@ var Column = class extends AbstractElementWithParent {
|
|
|
544
571
|
|
|
545
572
|
// src/pageObjects/elements/Table/Table.ts
|
|
546
573
|
var Table = class extends AbstractElementWithParent {
|
|
574
|
+
formName;
|
|
547
575
|
constructor(getParentElement, formName, driver) {
|
|
548
576
|
super(getParentElement, driver);
|
|
549
577
|
this.elementBy = By10.id(createTableId(formName));
|
|
578
|
+
this.formName = formName;
|
|
550
579
|
}
|
|
551
580
|
async getHeaderElement() {
|
|
552
581
|
const parentEl = await this.getElement();
|
|
@@ -612,9 +641,19 @@ var Table = class extends AbstractElementWithParent {
|
|
|
612
641
|
});
|
|
613
642
|
return result;
|
|
614
643
|
}
|
|
615
|
-
|
|
644
|
+
element() {
|
|
616
645
|
return this.getElement();
|
|
617
646
|
}
|
|
647
|
+
/**
|
|
648
|
+
* Находит поле когда форма находится в состоянии редактирования
|
|
649
|
+
* @example
|
|
650
|
+
* const form = new MyForm();
|
|
651
|
+
* //...
|
|
652
|
+
* expect(await form.field('Name').getValue()).toBe('test value');
|
|
653
|
+
*/
|
|
654
|
+
field(name) {
|
|
655
|
+
return new FormField(this.getElement, this.formName, name, this.driver);
|
|
656
|
+
}
|
|
618
657
|
};
|
|
619
658
|
|
|
620
659
|
// src/pageObjects/elements/TableToolbar/TableToolbar.ts
|
|
@@ -630,7 +669,7 @@ var TableToolbarButton = class extends AbstractElementWithParent {
|
|
|
630
669
|
}
|
|
631
670
|
async click() {
|
|
632
671
|
const button = await this.getElement();
|
|
633
|
-
return button.
|
|
672
|
+
return click(button, this.driver);
|
|
634
673
|
}
|
|
635
674
|
async isDisabled() {
|
|
636
675
|
const button = await this.getElement();
|
|
@@ -698,6 +737,13 @@ async function signIn(driver) {
|
|
|
698
737
|
return webDriver;
|
|
699
738
|
}
|
|
700
739
|
|
|
740
|
+
// src/utils/actions.ts
|
|
741
|
+
var click = async (webElement, driver) => {
|
|
742
|
+
driver = driver ?? config().driver;
|
|
743
|
+
const actions = driver.actions({ async: true });
|
|
744
|
+
await actions.move({ origin: webElement }).click().perform();
|
|
745
|
+
};
|
|
746
|
+
|
|
701
747
|
// src/pageObjects/pages/LoginPage.ts
|
|
702
748
|
var LOGIN_PATH = "/login";
|
|
703
749
|
var LoginPage = class extends AbstractPage {
|
|
@@ -714,7 +760,7 @@ var LoginPage = class extends AbstractPage {
|
|
|
714
760
|
await this.driver.findElement(this.passwordField).sendKeys(password);
|
|
715
761
|
}
|
|
716
762
|
async clickLoginButton() {
|
|
717
|
-
await this.driver.findElement(this.loginButton).
|
|
763
|
+
await click(await this.driver.findElement(this.loginButton), this.driver);
|
|
718
764
|
}
|
|
719
765
|
async loginWith(username, password) {
|
|
720
766
|
await this.enterUsername(username);
|
|
@@ -735,6 +781,7 @@ export {
|
|
|
735
781
|
SubsystemsPanel,
|
|
736
782
|
TextEditor,
|
|
737
783
|
byTestId,
|
|
784
|
+
click,
|
|
738
785
|
config,
|
|
739
786
|
createDriver,
|
|
740
787
|
editorFactory,
|
|
@@ -1,4 +1,23 @@
|
|
|
1
1
|
// src/config.ts
|
|
2
|
+
import * as process from "node:process";
|
|
3
|
+
var driversMap = /* @__PURE__ */ new Map();
|
|
4
|
+
var createConfigProxy = (config2) => {
|
|
5
|
+
return new Proxy(config2, {
|
|
6
|
+
get(_target, prop) {
|
|
7
|
+
if (prop === "driver") {
|
|
8
|
+
return driversMap.get(process.pid);
|
|
9
|
+
}
|
|
10
|
+
return Reflect.get(...arguments);
|
|
11
|
+
},
|
|
12
|
+
set(_target, prop, value) {
|
|
13
|
+
if (prop === "driver") {
|
|
14
|
+
driversMap.set(process.pid, value);
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
return Reflect.set(...arguments);
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
};
|
|
2
21
|
var Config = class _Config {
|
|
3
22
|
static instance;
|
|
4
23
|
appConfig;
|
|
@@ -10,7 +29,7 @@ var Config = class _Config {
|
|
|
10
29
|
}
|
|
11
30
|
config = (cfg) => {
|
|
12
31
|
if (!cfg)
|
|
13
|
-
return this.appConfig;
|
|
32
|
+
return createConfigProxy(this.appConfig);
|
|
14
33
|
this.appConfig = cfg;
|
|
15
34
|
};
|
|
16
35
|
};
|
|
@@ -81,6 +100,9 @@ var elementIsNotPresent = function elementIsNotPresent2(locator) {
|
|
|
81
100
|
});
|
|
82
101
|
};
|
|
83
102
|
|
|
103
|
+
// src/utils/waitElementIsVisible.ts
|
|
104
|
+
import { until } from "selenium-webdriver";
|
|
105
|
+
|
|
84
106
|
// src/pageObjects/AbstractElementWithParent.ts
|
|
85
107
|
var AbstractElementWithParent = class extends AbstractElement {
|
|
86
108
|
getParentElement;
|
|
@@ -202,7 +224,7 @@ var AbstractDXEditorWithInput = class extends AbstractFormElement {
|
|
|
202
224
|
}
|
|
203
225
|
async setInputValue(value) {
|
|
204
226
|
const inputEl = await this.getInputElement();
|
|
205
|
-
await inputEl.
|
|
227
|
+
await click(inputEl, this.driver);
|
|
206
228
|
await inputEl.sendKeys(value, Key.ENTER);
|
|
207
229
|
}
|
|
208
230
|
};
|
|
@@ -243,7 +265,7 @@ var CheckBox = class extends AbstractFormElement {
|
|
|
243
265
|
const inputEl = await this.getElement();
|
|
244
266
|
const currentValue = await this.getValue();
|
|
245
267
|
if (currentValue !== value) {
|
|
246
|
-
await inputEl.
|
|
268
|
+
await click(inputEl, this.driver);
|
|
247
269
|
}
|
|
248
270
|
}
|
|
249
271
|
};
|
|
@@ -267,13 +289,13 @@ var SELECT_BOX_ELEMENT_ROLE = "option";
|
|
|
267
289
|
var SelectBoxEditor = class extends AbstractDXEditorWithInput {
|
|
268
290
|
async setSelectInputValue(value) {
|
|
269
291
|
const inputEl = await this.getInputElement();
|
|
270
|
-
await inputEl.
|
|
292
|
+
await click(inputEl, this.driver);
|
|
271
293
|
await inputEl.sendKeys(value, Key2.ENTER);
|
|
272
294
|
const combinedValueXpath = XPathHelper.getRoleXpath(SELECT_BOX_ELEMENT_ROLE) + XPathHelper.getClassAndValueXpath(SELECT_BOX_OPTION_TEXT_CONTAINER_CLASS, value);
|
|
273
295
|
await this.driver.wait(async () => {
|
|
274
296
|
try {
|
|
275
297
|
const optElement = await inputEl.findElement(By6.xpath(combinedValueXpath));
|
|
276
|
-
await optElement.
|
|
298
|
+
await click(optElement, this.driver);
|
|
277
299
|
return true;
|
|
278
300
|
} catch (e) {
|
|
279
301
|
return false;
|
|
@@ -307,7 +329,7 @@ var SwitchEditor = class extends AbstractFormElement {
|
|
|
307
329
|
const inputEl = await this.getElement();
|
|
308
330
|
const currentValue = await this.getValue();
|
|
309
331
|
if (currentValue !== value) {
|
|
310
|
-
await inputEl.
|
|
332
|
+
await click(inputEl, this.driver);
|
|
311
333
|
await this.driver.wait(async () => {
|
|
312
334
|
const updatedValue = await this.getValue();
|
|
313
335
|
return updatedValue !== currentValue;
|
|
@@ -404,7 +426,7 @@ var FormEdit = class extends AbstractForm {
|
|
|
404
426
|
* await formEdit.saveButtonClick();
|
|
405
427
|
*/
|
|
406
428
|
async saveButtonClick() {
|
|
407
|
-
await this.driver.findElement(this.saveButtonBy).
|
|
429
|
+
await click(await this.driver.findElement(this.saveButtonBy), this.driver);
|
|
408
430
|
}
|
|
409
431
|
};
|
|
410
432
|
|
|
@@ -417,16 +439,16 @@ import { By as By10 } from "selenium-webdriver";
|
|
|
417
439
|
// src/pageObjects/elements/Table/utils.ts
|
|
418
440
|
import { By as By8 } from "selenium-webdriver";
|
|
419
441
|
var getRowPathByIndex = (index) => {
|
|
420
|
-
return By8.
|
|
442
|
+
return By8.css(`tr[aria-rowindex="${transformInputIndex(index)}"]`);
|
|
421
443
|
};
|
|
422
444
|
var getColumnPathByIndex = (index) => {
|
|
423
|
-
return By8.
|
|
445
|
+
return By8.css(`td[aria-colindex="${transformInputIndex(index)}"]`);
|
|
424
446
|
};
|
|
425
447
|
var getColumnPathByCaption = (caption) => {
|
|
426
|
-
return By8.
|
|
448
|
+
return By8.css(`td[role="columnheader"][aria-label="Column ${caption}"]`);
|
|
427
449
|
};
|
|
428
450
|
var getCellPathByIndex = (index) => {
|
|
429
|
-
return By8.
|
|
451
|
+
return By8.css(`td[role="gridcell"][aria-colindex="${transformInputIndex(index)}"]`);
|
|
430
452
|
};
|
|
431
453
|
var transformInputIndex = (index) => index + 1;
|
|
432
454
|
var transformOutputIndex = (index) => +index - 1;
|
|
@@ -437,8 +459,8 @@ import { By as By9 } from "selenium-webdriver";
|
|
|
437
459
|
// src/pageObjects/elements/Table/elements/Cell.ts
|
|
438
460
|
var Cell = class extends AbstractElementWithParent {
|
|
439
461
|
index;
|
|
440
|
-
constructor(
|
|
441
|
-
super(
|
|
462
|
+
constructor(rowEl, index, driver) {
|
|
463
|
+
super(() => Promise.resolve(rowEl), driver);
|
|
442
464
|
this.index = index;
|
|
443
465
|
this.elementBy = getCellPathByIndex(index);
|
|
444
466
|
}
|
|
@@ -452,6 +474,8 @@ var Cell = class extends AbstractElementWithParent {
|
|
|
452
474
|
};
|
|
453
475
|
|
|
454
476
|
// src/pageObjects/elements/Table/elements/Row.ts
|
|
477
|
+
var DX_SELECTION_CLASS = "dx-selection";
|
|
478
|
+
var DX_ROW_EDIT_CLASS = "dx-edit-row";
|
|
455
479
|
var Row = class extends AbstractElementWithParent {
|
|
456
480
|
index;
|
|
457
481
|
getColumnByCaption;
|
|
@@ -461,14 +485,11 @@ var Row = class extends AbstractElementWithParent {
|
|
|
461
485
|
this.elementBy = getRowPathByIndex(index);
|
|
462
486
|
this.getColumnByCaption = getColumnByCaption;
|
|
463
487
|
}
|
|
464
|
-
getRowElement = () => {
|
|
465
|
-
return this.driver.findElement(this.elementBy);
|
|
466
|
-
};
|
|
467
488
|
async getCellByIndex(index) {
|
|
468
489
|
const rowEl = await this.getElement();
|
|
469
490
|
const cell = rowEl.findElement(getCellPathByIndex(index));
|
|
470
491
|
if (cell) {
|
|
471
|
-
return new Cell(
|
|
492
|
+
return new Cell(rowEl, index, this.driver);
|
|
472
493
|
}
|
|
473
494
|
throw new Error(`Cannot find cell by index: ${index}`);
|
|
474
495
|
}
|
|
@@ -482,7 +503,13 @@ var Row = class extends AbstractElementWithParent {
|
|
|
482
503
|
}
|
|
483
504
|
async select() {
|
|
484
505
|
const rowEl = await this.getElement();
|
|
485
|
-
await rowEl.
|
|
506
|
+
await click(rowEl, this.driver);
|
|
507
|
+
await this.driver.wait(async () => {
|
|
508
|
+
const classes = await rowEl.getAttribute("class");
|
|
509
|
+
if (!classes.includes(DX_SELECTION_CLASS))
|
|
510
|
+
throw new Error("Cannot select row");
|
|
511
|
+
return true;
|
|
512
|
+
}, 500);
|
|
486
513
|
}
|
|
487
514
|
async isSelected() {
|
|
488
515
|
const rowEl = await this.getElement();
|
|
@@ -497,31 +524,31 @@ var Row = class extends AbstractElementWithParent {
|
|
|
497
524
|
const cells = await rowEl.findElements(By9.css(`td[role="gridcell"]`));
|
|
498
525
|
const result = [];
|
|
499
526
|
cells.forEach((_, index) => {
|
|
500
|
-
const newCell = new Cell(
|
|
527
|
+
const newCell = new Cell(rowEl, index, this.driver);
|
|
501
528
|
result.push(newCell);
|
|
502
529
|
});
|
|
503
530
|
return result;
|
|
504
531
|
}
|
|
505
532
|
async clickInlineButton(rowClass, buttonClass) {
|
|
506
|
-
const fixedTable = await this.getParentElement().findElement(
|
|
533
|
+
const fixedTable = (await this.getParentElement()).findElement(
|
|
507
534
|
By9.css(".dx-fixed-columns .dx-datagrid-content.dx-datagrid-content-fixed")
|
|
508
535
|
);
|
|
509
536
|
const rowEl = await fixedTable.findElement(By9.className(rowClass));
|
|
510
537
|
const button = await rowEl.findElement(By9.className(buttonClass));
|
|
511
538
|
if (button) {
|
|
512
|
-
return button.
|
|
539
|
+
return click(button, this.driver);
|
|
513
540
|
}
|
|
514
541
|
throw new Error(`Cannot find ${buttonClass} button`);
|
|
515
542
|
}
|
|
516
543
|
async edit() {
|
|
517
544
|
await this.select();
|
|
518
|
-
return this.clickInlineButton(
|
|
545
|
+
return this.clickInlineButton(DX_SELECTION_CLASS, "edit");
|
|
519
546
|
}
|
|
520
547
|
async save() {
|
|
521
|
-
return this.clickInlineButton(
|
|
548
|
+
return this.clickInlineButton(DX_ROW_EDIT_CLASS, "save");
|
|
522
549
|
}
|
|
523
550
|
async cancel() {
|
|
524
|
-
return this.clickInlineButton(
|
|
551
|
+
return this.clickInlineButton(DX_ROW_EDIT_CLASS, "cancel");
|
|
525
552
|
}
|
|
526
553
|
};
|
|
527
554
|
|
|
@@ -544,9 +571,11 @@ var Column = class extends AbstractElementWithParent {
|
|
|
544
571
|
|
|
545
572
|
// src/pageObjects/elements/Table/Table.ts
|
|
546
573
|
var Table = class extends AbstractElementWithParent {
|
|
574
|
+
formName;
|
|
547
575
|
constructor(getParentElement, formName, driver) {
|
|
548
576
|
super(getParentElement, driver);
|
|
549
577
|
this.elementBy = By10.id(createTableId(formName));
|
|
578
|
+
this.formName = formName;
|
|
550
579
|
}
|
|
551
580
|
async getHeaderElement() {
|
|
552
581
|
const parentEl = await this.getElement();
|
|
@@ -612,9 +641,19 @@ var Table = class extends AbstractElementWithParent {
|
|
|
612
641
|
});
|
|
613
642
|
return result;
|
|
614
643
|
}
|
|
615
|
-
|
|
644
|
+
element() {
|
|
616
645
|
return this.getElement();
|
|
617
646
|
}
|
|
647
|
+
/**
|
|
648
|
+
* Находит поле когда форма находится в состоянии редактирования
|
|
649
|
+
* @example
|
|
650
|
+
* const form = new MyForm();
|
|
651
|
+
* //...
|
|
652
|
+
* expect(await form.field('Name').getValue()).toBe('test value');
|
|
653
|
+
*/
|
|
654
|
+
field(name) {
|
|
655
|
+
return new FormField(this.getElement, this.formName, name, this.driver);
|
|
656
|
+
}
|
|
618
657
|
};
|
|
619
658
|
|
|
620
659
|
// src/pageObjects/elements/TableToolbar/TableToolbar.ts
|
|
@@ -630,7 +669,7 @@ var TableToolbarButton = class extends AbstractElementWithParent {
|
|
|
630
669
|
}
|
|
631
670
|
async click() {
|
|
632
671
|
const button = await this.getElement();
|
|
633
|
-
return button.
|
|
672
|
+
return click(button, this.driver);
|
|
634
673
|
}
|
|
635
674
|
async isDisabled() {
|
|
636
675
|
const button = await this.getElement();
|
|
@@ -698,6 +737,13 @@ async function signIn(driver) {
|
|
|
698
737
|
return webDriver;
|
|
699
738
|
}
|
|
700
739
|
|
|
740
|
+
// src/utils/actions.ts
|
|
741
|
+
var click = async (webElement, driver) => {
|
|
742
|
+
driver = driver ?? config().driver;
|
|
743
|
+
const actions = driver.actions({ async: true });
|
|
744
|
+
await actions.move({ origin: webElement }).click().perform();
|
|
745
|
+
};
|
|
746
|
+
|
|
701
747
|
// src/pageObjects/pages/LoginPage.ts
|
|
702
748
|
var LOGIN_PATH = "/login";
|
|
703
749
|
var LoginPage = class extends AbstractPage {
|
|
@@ -714,7 +760,7 @@ var LoginPage = class extends AbstractPage {
|
|
|
714
760
|
await this.driver.findElement(this.passwordField).sendKeys(password);
|
|
715
761
|
}
|
|
716
762
|
async clickLoginButton() {
|
|
717
|
-
await this.driver.findElement(this.loginButton).
|
|
763
|
+
await click(await this.driver.findElement(this.loginButton), this.driver);
|
|
718
764
|
}
|
|
719
765
|
async loginWith(username, password) {
|
|
720
766
|
await this.enterUsername(username);
|
|
@@ -735,6 +781,7 @@ export {
|
|
|
735
781
|
SubsystemsPanel,
|
|
736
782
|
TextEditor,
|
|
737
783
|
byTestId,
|
|
784
|
+
click,
|
|
738
785
|
config,
|
|
739
786
|
createDriver,
|
|
740
787
|
editorFactory,
|