d5-testing-library 1.9.0-alpha.2 → 1.9.0-alpha.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/FormEdit-WMDPDBSI.mjs +7 -0
- package/dist/ListForm-AXEPFADV.mjs +7 -0
- package/dist/TreeView-PNY6V55D.mjs +8 -0
- package/dist/{chunk-XGIXXZD6.mjs → chunk-6TK257AJ.mjs} +1 -1
- package/dist/{chunk-S62QEWWA.mjs → chunk-ATHAW2ZF.mjs} +121 -27
- package/dist/{chunk-75FRHQCI.mjs → chunk-I5A2CSDF.mjs} +4 -4
- package/dist/{chunk-32KSAOFJ.mjs → chunk-NO3PBR34.mjs} +92 -33
- package/dist/cjs/d5-testing-library.cjs +241 -65
- package/dist/cjs/d5-testing-library.d.ts +60 -2
- package/dist/d5-testing-library.d.mts +60 -2
- package/dist/d5-testing-library.legacy-esm.js +18 -5
- package/dist/d5-testing-library.mjs +18 -5
- package/package.json +7 -7
- package/dist/FormEdit-QNZOB7PA.mjs +0 -7
- package/dist/ListForm-MXGUBMWS.mjs +0 -7
- package/dist/TreeView-VZBOZCFW.mjs +0 -8
package/README.md
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//
|
|
@@ -17,14 +17,15 @@ import {
|
|
|
17
17
|
safeWait,
|
|
18
18
|
staleElementAction,
|
|
19
19
|
waitElementIsClickable_default,
|
|
20
|
-
waitElementIsVisible_default
|
|
21
|
-
|
|
20
|
+
waitElementIsVisible_default,
|
|
21
|
+
withCustomTimeouts_default
|
|
22
|
+
} from "./chunk-NO3PBR34.mjs";
|
|
22
23
|
|
|
23
24
|
// src/pageObjects/elements/Table/Table.ts
|
|
24
25
|
import { By as By6 } from "selenium-webdriver";
|
|
25
26
|
|
|
26
27
|
// src/pageObjects/elements/Table/elements/Row.ts
|
|
27
|
-
import { By as By3 } from "selenium-webdriver";
|
|
28
|
+
import { By as By3, Key } from "selenium-webdriver";
|
|
28
29
|
|
|
29
30
|
// src/pageObjects/elements/Table/elements/Cell.ts
|
|
30
31
|
import { By as By2 } from "selenium-webdriver";
|
|
@@ -82,7 +83,7 @@ var Cell = class extends AbstractElementWithParent {
|
|
|
82
83
|
const [datePart, timePart] = value.split(", ");
|
|
83
84
|
const [day, month, year] = datePart.split(".").map(Number);
|
|
84
85
|
const [hours, minutes] = timePart.split(":").map(Number);
|
|
85
|
-
return new Date(
|
|
86
|
+
return new Date(year, month - 1, day, hours, minutes, 0, 0);
|
|
86
87
|
} else {
|
|
87
88
|
const [day, month, year] = value.split(".").map(Number);
|
|
88
89
|
return new Date(Date.UTC(year, month - 1, day));
|
|
@@ -153,9 +154,18 @@ var Row = class extends AbstractElementWithParent {
|
|
|
153
154
|
getCellByTitle(title) {
|
|
154
155
|
return this._getCell({ title });
|
|
155
156
|
}
|
|
156
|
-
async select() {
|
|
157
|
+
async select(preserve = false) {
|
|
157
158
|
await staleElementAction(async () => {
|
|
158
159
|
const rowEl = await this.getElement();
|
|
160
|
+
const isSelected = (await this.getClasses()).includes(DX_SELECTION_CLASS);
|
|
161
|
+
if (isSelected && !preserve) {
|
|
162
|
+
await this.driver.actions({ async: true }).keyUp(Key.CONTROL).perform();
|
|
163
|
+
}
|
|
164
|
+
if (preserve && !isSelected) {
|
|
165
|
+
await this.driver.actions({ async: true }).keyDown(Key.CONTROL).perform();
|
|
166
|
+
await click(rowEl, this.driver);
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
159
169
|
await click(rowEl, this.driver);
|
|
160
170
|
});
|
|
161
171
|
await safeWait(
|
|
@@ -366,7 +376,7 @@ var DXContextMenuList = class extends AbstractDropDownMenuList {
|
|
|
366
376
|
async isVisible() {
|
|
367
377
|
try {
|
|
368
378
|
await waitElementIsVisible_default({
|
|
369
|
-
element: await this.driver.findElement(By5.css(`.dx-overlay-wrapper .dx-
|
|
379
|
+
element: await this.driver.findElement(By5.css(`.dx-overlay-wrapper .dx-context-menu`)),
|
|
370
380
|
driver: this.driver,
|
|
371
381
|
errorMessage: "Cannot find dropdown element"
|
|
372
382
|
});
|
|
@@ -467,13 +477,32 @@ var Table = class extends AbstractElementWithParent {
|
|
|
467
477
|
/**
|
|
468
478
|
* Вибрати рядок по індексу.
|
|
469
479
|
* @param index починається з 0
|
|
480
|
+
* @param preserve boolean який изначає, чи повинні раніше вибрані рядки залишатися вибраними
|
|
470
481
|
*/
|
|
471
|
-
selectRowByIndex(index) {
|
|
472
|
-
return this.getRowByIndex(index).select();
|
|
482
|
+
selectRowByIndex(index, preserve = false) {
|
|
483
|
+
return this.getRowByIndex(index).select(preserve);
|
|
473
484
|
}
|
|
474
|
-
|
|
485
|
+
/**
|
|
486
|
+
* Вибрати масив рядків по індексу.
|
|
487
|
+
* @param indexes починається з 0
|
|
488
|
+
*/
|
|
489
|
+
async selectRowsByIndexes(indexes) {
|
|
490
|
+
for (const index of indexes) {
|
|
491
|
+
await this.selectRowByIndex(index, true);
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
getRowElements(timeout) {
|
|
475
495
|
const rowsFullCssSelector = `${this.getFullCssSelector()} ${this.tableContentCssSelector} .dx-row.dx-data-row`;
|
|
476
|
-
|
|
496
|
+
return withCustomTimeouts_default({
|
|
497
|
+
driver: this.driver,
|
|
498
|
+
timeout,
|
|
499
|
+
callback: () => {
|
|
500
|
+
return this.driver.findElements(By6.css(rowsFullCssSelector));
|
|
501
|
+
}
|
|
502
|
+
});
|
|
503
|
+
}
|
|
504
|
+
async getRows() {
|
|
505
|
+
const rows = await this.getRowElements();
|
|
477
506
|
const result = [];
|
|
478
507
|
rows.forEach((_, index) => {
|
|
479
508
|
const newRow = new Row(
|
|
@@ -559,6 +588,72 @@ var Table = class extends AbstractElementWithParent {
|
|
|
559
588
|
await contextMenu(cellElement, this.driver);
|
|
560
589
|
});
|
|
561
590
|
}
|
|
591
|
+
/**
|
|
592
|
+
* Отримує значення комірки таблиці за ім'ям комірки та індексом рядка.
|
|
593
|
+
*
|
|
594
|
+
* @param {string} cellName - Ім'я комірки (поля) в таблиці
|
|
595
|
+
* @param {number} rowIndex - Індекс рядка (починається з 0)
|
|
596
|
+
* @throws {Error} Викидає помилку, якщо rowIndex не вказано
|
|
597
|
+
* @returns {Promise<string>} Повертає значення комірки
|
|
598
|
+
*
|
|
599
|
+
* @example
|
|
600
|
+
* const table = new Table(driver);
|
|
601
|
+
*
|
|
602
|
+
* // Отримання значення комірки 'Name' в першому рядку (індекс 0)
|
|
603
|
+
* const cellValue = await table.getCellValueByCellName('Name', 0);
|
|
604
|
+
* expect(cellValue).toBe('Очікуване значення');
|
|
605
|
+
*/
|
|
606
|
+
getCellValueByCellName(cellName, rowIndex) {
|
|
607
|
+
if (rowIndex == null) {
|
|
608
|
+
throw new Error("Error: getCellValue(): rowIndex is required");
|
|
609
|
+
}
|
|
610
|
+
const row = this.getRowByIndex(rowIndex);
|
|
611
|
+
return row.getCell(cellName).getValue();
|
|
612
|
+
}
|
|
613
|
+
/**
|
|
614
|
+
* Перевіряє, чи є таблиця порожньою (не містить жодного рядка з даними).
|
|
615
|
+
*
|
|
616
|
+
* @returns {Promise<boolean>} Повертає true, якщо таблиця порожня, false - якщо містить рядки
|
|
617
|
+
*
|
|
618
|
+
* @example
|
|
619
|
+
* const table = new Table(driver);
|
|
620
|
+
*
|
|
621
|
+
* // Перевірка чи порожня таблиця
|
|
622
|
+
* const empty = await table.isEmpty();
|
|
623
|
+
* expect(empty).toBe(true);
|
|
624
|
+
*/
|
|
625
|
+
async isEmpty() {
|
|
626
|
+
try {
|
|
627
|
+
await this.waitRowsCount(0);
|
|
628
|
+
return true;
|
|
629
|
+
} catch {
|
|
630
|
+
return false;
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
/**
|
|
634
|
+
* Очікує, поки кількість рядків у таблиці не стане рівною заданому значенню.
|
|
635
|
+
* Використовується для синхронізації тестів з динамічним завантаженням даних.
|
|
636
|
+
*
|
|
637
|
+
* @param {number} count - Очікувана кількість рядків у таблиці
|
|
638
|
+
* @returns {Promise<void>} Повертає Promise, який виконується, коли кількість рядків відповідає очікуваній
|
|
639
|
+
* @throws {Error} Викидає помилку, якщо очікування перевищує тайм-аут
|
|
640
|
+
*
|
|
641
|
+
* @example
|
|
642
|
+
* const table = new Table(driver);
|
|
643
|
+
*
|
|
644
|
+
* // Очікування, поки таблиця не стане порожньою
|
|
645
|
+
* await table.waitRowsCount(0);
|
|
646
|
+
*
|
|
647
|
+
* // Очікування, поки в таблиці не з'явиться 5 рядків
|
|
648
|
+
* await table.waitRowsCount(5);
|
|
649
|
+
* console.log('Таблиця містить 5 рядків');
|
|
650
|
+
*/
|
|
651
|
+
async waitRowsCount(count) {
|
|
652
|
+
await safeWait(async () => {
|
|
653
|
+
const rows = await this.getRowElements(1e3);
|
|
654
|
+
return rows.length === count;
|
|
655
|
+
}, this.driver, `Rows count not equal: ${count}`);
|
|
656
|
+
}
|
|
562
657
|
};
|
|
563
658
|
|
|
564
659
|
// src/pageObjects/elements/TableToolbar/ToolbarGroupButton.ts
|
|
@@ -776,6 +871,14 @@ var ToolbarItem = class extends AbstractElementWithParent {
|
|
|
776
871
|
return false;
|
|
777
872
|
}
|
|
778
873
|
}
|
|
874
|
+
async isPressed() {
|
|
875
|
+
try {
|
|
876
|
+
await this.init();
|
|
877
|
+
return this._button.isPressed();
|
|
878
|
+
} catch (error) {
|
|
879
|
+
return false;
|
|
880
|
+
}
|
|
881
|
+
}
|
|
779
882
|
async getTitle() {
|
|
780
883
|
await this.init();
|
|
781
884
|
return await this._button.getTitle();
|
|
@@ -1161,7 +1264,7 @@ var HeaderFilterField = class extends AbstractEditor {
|
|
|
1161
1264
|
// src/pageObjects/elements/Filters/ColumnFilter.ts
|
|
1162
1265
|
var APPLY_SELECTOR = ".apply-button";
|
|
1163
1266
|
var CANCEL_SELECTOR = ".cancel-button";
|
|
1164
|
-
var HEADER_FILTER_ICON = ".
|
|
1267
|
+
var HEADER_FILTER_ICON = ".indicators-container .filter-icon";
|
|
1165
1268
|
var HEADER_FILTER_CONTAINER = ".header-filter";
|
|
1166
1269
|
var HEADER_FILTER_BUTTONS = ".header-filter-buttons";
|
|
1167
1270
|
var ColumnFilter = class extends AbstractElement {
|
|
@@ -1195,24 +1298,15 @@ var ColumnFilter = class extends AbstractElement {
|
|
|
1195
1298
|
const columnEl = await this._column.getElement();
|
|
1196
1299
|
const actions = this.driver.actions({ async: true });
|
|
1197
1300
|
await actions.move({ origin: columnEl }).perform();
|
|
1198
|
-
const
|
|
1199
|
-
let headerFilterIcon =
|
|
1301
|
+
const headerFilterIconBy = By11.css(HEADER_FILTER_ICON);
|
|
1302
|
+
let headerFilterIcon = await columnEl.findElement(headerFilterIconBy);
|
|
1200
1303
|
await safeWait(
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
for (let element of elements) {
|
|
1204
|
-
if (await element.isDisplayed()) {
|
|
1205
|
-
headerFilterIcon = element;
|
|
1206
|
-
result = true;
|
|
1207
|
-
break;
|
|
1208
|
-
}
|
|
1209
|
-
}
|
|
1210
|
-
return result;
|
|
1304
|
+
() => {
|
|
1305
|
+
return headerFilterIcon.isDisplayed();
|
|
1211
1306
|
},
|
|
1212
1307
|
this.driver,
|
|
1213
1308
|
`HeaderFilter "${this._name}" is not visible`
|
|
1214
1309
|
);
|
|
1215
|
-
if (!headerFilterIcon) throw new Error(`HeaderFilter "${this._name}" is not visible`);
|
|
1216
1310
|
await click(headerFilterIcon, this.driver);
|
|
1217
1311
|
const filter = new HeaderFilterField("", this._formName, this._name, this.driver);
|
|
1218
1312
|
const filterEl = await filter.getElement();
|
|
@@ -1335,9 +1429,9 @@ var ColumnFilter = class extends AbstractElement {
|
|
|
1335
1429
|
};
|
|
1336
1430
|
|
|
1337
1431
|
// src/pageObjects/elements/Forms/ListForm.ts
|
|
1338
|
-
var DATAGRID_HEADER_CSS_SELECTOR = ".dx-datagrid-headers .dx-datagrid-content
|
|
1339
|
-
var DATAGRID_CONTENT_CSS_SELECTOR = ".dx-datagrid-content
|
|
1340
|
-
var FIXED_DATAGRID_CONTENT_CSS_SELECTOR = ".dx-
|
|
1432
|
+
var DATAGRID_HEADER_CSS_SELECTOR = ".dx-datagrid-headers .dx-datagrid-content .dx-datagrid-table.dx-datagrid-table-fixed";
|
|
1433
|
+
var DATAGRID_CONTENT_CSS_SELECTOR = ".dx-datagrid-content .dx-datagrid-table.dx-datagrid-table-fixed";
|
|
1434
|
+
var FIXED_DATAGRID_CONTENT_CSS_SELECTOR = ".dx-datagrid-sticky-columns .dx-datagrid-content .dx-datagrid-table.dx-datagrid-table-fixed";
|
|
1341
1435
|
var CONTEXT_MENU_CSS_SELECTOR = ".dx-datagrid";
|
|
1342
1436
|
var ListForm = class extends Form {
|
|
1343
1437
|
headerCssSelector;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ListForm
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-ATHAW2ZF.mjs";
|
|
4
4
|
|
|
5
5
|
// src/pageObjects/elements/Forms/TreeView.ts
|
|
6
|
-
var TREELIST_HEADER_CSS_SELECTOR = ".dx-treelist-headers .dx-treelist-content
|
|
7
|
-
var TREELIST_CONTENT_CSS_SELECTOR = ".dx-treelist-content
|
|
8
|
-
var FIXED_TREELIST_CONTENT_CSS_SELECTOR = ".dx-
|
|
6
|
+
var TREELIST_HEADER_CSS_SELECTOR = ".dx-treelist-headers .dx-treelist-content .dx-treelist-table.dx-treelist-table-fixed";
|
|
7
|
+
var TREELIST_CONTENT_CSS_SELECTOR = ".dx-treelist-content .dx-treelist-table.dx-treelist-table-fixed";
|
|
8
|
+
var FIXED_TREELIST_CONTENT_CSS_SELECTOR = ".dx-treelist-sticky-columns .dx-treelist-content .dx-treelist-table.dx-treelist-table-fixed";
|
|
9
9
|
var TreeView = class extends ListForm {
|
|
10
10
|
constructor(driver) {
|
|
11
11
|
super(driver);
|
|
@@ -352,22 +352,34 @@ var ClearButtonStrategy = class {
|
|
|
352
352
|
}
|
|
353
353
|
};
|
|
354
354
|
|
|
355
|
+
// src/utils/withCustomTimeouts.ts
|
|
356
|
+
async function withCustomTimeouts({ driver, timeout, callback }) {
|
|
357
|
+
const { implicit: defaultTimeout } = await driver.manage().getTimeouts();
|
|
358
|
+
try {
|
|
359
|
+
await driver.manage().setTimeouts({ implicit: timeout ?? defaultTimeout });
|
|
360
|
+
return await callback();
|
|
361
|
+
} finally {
|
|
362
|
+
await driver.manage().setTimeouts({ implicit: defaultTimeout });
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
var withCustomTimeouts_default = withCustomTimeouts;
|
|
366
|
+
|
|
355
367
|
// src/pageObjects/elements/Editors/SelectBoxEditor.ts
|
|
356
368
|
var SELECT_BOX_OPTION_TEXT_CONTAINER_CLASS = "d5-multi-select-item";
|
|
357
369
|
var combinedValueXpath = (value) => `//body/div[@id="root"]/div[contains(@class, "dx-overlay-wrapper")]//${XPathHelper.getClassAndValueXpath(SELECT_BOX_OPTION_TEXT_CONTAINER_CLASS, value)}`;
|
|
358
370
|
var dropDownOptionClick = async (optionValue, driver, delay = true) => {
|
|
359
|
-
const { implicit } = await driver.manage().getTimeouts();
|
|
360
|
-
let optElement = null;
|
|
361
|
-
const timeout = delay ? implicit : 200;
|
|
362
371
|
let err = null;
|
|
363
372
|
try {
|
|
364
|
-
await
|
|
365
|
-
|
|
366
|
-
|
|
373
|
+
await withCustomTimeouts_default({
|
|
374
|
+
driver,
|
|
375
|
+
timeout: delay ? void 0 : 200,
|
|
376
|
+
callback: async () => {
|
|
377
|
+
let optElement = await driver.findElement(By5.xpath(combinedValueXpath(optionValue)));
|
|
378
|
+
await click(optElement, driver);
|
|
379
|
+
}
|
|
380
|
+
});
|
|
367
381
|
} catch (e) {
|
|
368
382
|
err = new Error(`Item not found: "${optionValue}"`);
|
|
369
|
-
} finally {
|
|
370
|
-
await driver.manage().setTimeouts({ implicit });
|
|
371
383
|
}
|
|
372
384
|
if (err)
|
|
373
385
|
throw err;
|
|
@@ -427,7 +439,7 @@ var TAGS_SELECTOR = ".dx-tag .tag-text";
|
|
|
427
439
|
var DX_TAG_CONTAINER = "dx-tag-container";
|
|
428
440
|
var DX_TEXTEDITOR_EMPTY2 = "dx-texteditor-empty";
|
|
429
441
|
var BTN_OK_SELECTOR = ".dx-tagbox-popup-wrapper .dx-popup-bottom .dx-button.dx-popup-done";
|
|
430
|
-
var
|
|
442
|
+
var getSelectedOptionXpath = (value) => `//body/div[@id="root"]/div[contains(@class, "dx-overlay-wrapper")]//div[contains(@class, 'dx-list-item') and @aria-selected="true"]//div[contains(., "${value}")]`;
|
|
431
443
|
var TagBox = class extends AbstractDXEditorWithInput {
|
|
432
444
|
constructor(parentCssSelector, elementCssSelector, driver) {
|
|
433
445
|
super(parentCssSelector, elementCssSelector, driver);
|
|
@@ -442,9 +454,15 @@ var TagBox = class extends AbstractDXEditorWithInput {
|
|
|
442
454
|
}
|
|
443
455
|
await this.confirmSelection();
|
|
444
456
|
}
|
|
445
|
-
async waitOptionSelection() {
|
|
446
|
-
|
|
447
|
-
|
|
457
|
+
async waitOptionSelection(value) {
|
|
458
|
+
await safeWait(
|
|
459
|
+
async () => {
|
|
460
|
+
const elements = await this.driver.findElements(By6.xpath(getSelectedOptionXpath(value)));
|
|
461
|
+
if (elements.length === 0) return false;
|
|
462
|
+
return await elements[0].isDisplayed();
|
|
463
|
+
},
|
|
464
|
+
this.driver
|
|
465
|
+
);
|
|
448
466
|
}
|
|
449
467
|
async selectOption(inputEl, value, lastElement) {
|
|
450
468
|
try {
|
|
@@ -453,7 +471,7 @@ var TagBox = class extends AbstractDXEditorWithInput {
|
|
|
453
471
|
await inputEl.sendKeys(value);
|
|
454
472
|
await dropDownOptionClick(value, this.driver);
|
|
455
473
|
}
|
|
456
|
-
await this.waitOptionSelection();
|
|
474
|
+
await this.waitOptionSelection(value);
|
|
457
475
|
if (value !== lastElement) {
|
|
458
476
|
await inputEl.clear();
|
|
459
477
|
}
|
|
@@ -554,9 +572,20 @@ import { By as By9 } from "selenium-webdriver";
|
|
|
554
572
|
import { By as By8, Key as Key3 } from "selenium-webdriver";
|
|
555
573
|
|
|
556
574
|
// src/pageObjects/elements/Editors/Date/utils.ts
|
|
557
|
-
var formatDMYDate = (date) => {
|
|
558
|
-
const [year, month, day] = date.
|
|
559
|
-
|
|
575
|
+
var formatDMYDate = (date, isTimeAllowed = false) => {
|
|
576
|
+
const [year, month, day] = date.toISOString().split("T")[0].split("-");
|
|
577
|
+
if (!isTimeAllowed) {
|
|
578
|
+
return `${day}${month}${year}`;
|
|
579
|
+
}
|
|
580
|
+
const hours = String(date.getHours()).padStart(2, "0");
|
|
581
|
+
const minutes = String(date.getMinutes()).padStart(2, "0");
|
|
582
|
+
return `${day}${month}${year}${hours}${minutes}`;
|
|
583
|
+
};
|
|
584
|
+
var formatToDateTime = (dateString) => {
|
|
585
|
+
const [datePart, timePart] = dateString.split("T");
|
|
586
|
+
const [year, month, day] = datePart.split("-").map(Number);
|
|
587
|
+
const [hours, minutes] = timePart.split(":").map(Number);
|
|
588
|
+
return new Date(year, month - 1, day, hours, minutes, 0, 0);
|
|
560
589
|
};
|
|
561
590
|
|
|
562
591
|
// src/pageObjects/elements/Editors/Date/BaseDateEditor.ts
|
|
@@ -564,11 +593,17 @@ var BTN_CALENDAR_POPOVER_OPEN_SELECTOR = "calendar-popover-open-button";
|
|
|
564
593
|
var BTN_CALENDAR_POPOVER_DATE_FROM_INPUT_SELECTOR = "DateRange__inputs-item--dateFrom";
|
|
565
594
|
var BTN_CALENDAR_POPOVER_DATE_TO_INPUT_SELECTOR = "DateRange__inputs-item--dateTo";
|
|
566
595
|
var BTN_SAVE_SELECTOR = "DateRange__button-save";
|
|
596
|
+
var DATETIME_ALLOWED_SELECTOR = "dx-datebox-datetime";
|
|
567
597
|
var BaseDateEditor = class extends AbstractDXEditorWithInput {
|
|
568
598
|
constructor(parentCssSelector, elementCssSelector, driver) {
|
|
569
599
|
super(parentCssSelector, elementCssSelector, driver);
|
|
570
600
|
this.setClearStrategy(new InputClearStrategy());
|
|
571
601
|
}
|
|
602
|
+
async getIsAllowedTime() {
|
|
603
|
+
const dateField = await this.driver.findElement(By8.css(`${this.getFullCssSelector()}`));
|
|
604
|
+
const classString = await dateField.getAttribute("class");
|
|
605
|
+
return classString.includes(DATETIME_ALLOWED_SELECTOR);
|
|
606
|
+
}
|
|
572
607
|
async setArrayValue(value) {
|
|
573
608
|
const dateField = await this.driver.findElement(By8.css(`${this.getFullCssSelector()}`));
|
|
574
609
|
const dateFieldDataTestID = await this.getDataTestId();
|
|
@@ -588,7 +623,8 @@ var BaseDateEditor = class extends AbstractDXEditorWithInput {
|
|
|
588
623
|
}
|
|
589
624
|
async setSingleValue(value, inputEl) {
|
|
590
625
|
const actions = this.driver.actions({ async: true });
|
|
591
|
-
const
|
|
626
|
+
const isTimeAllowed = await this.getIsAllowedTime();
|
|
627
|
+
const formattedDate = formatDMYDate(value, isTimeAllowed);
|
|
592
628
|
await click(inputEl, this.driver);
|
|
593
629
|
await actions.move({ origin: inputEl }).sendKeys(Key3.HOME).perform();
|
|
594
630
|
await actions.move({ origin: inputEl }).sendKeys(formattedDate, Key3.ENTER).perform();
|
|
@@ -617,6 +653,10 @@ var SingleDateEditor = class extends BaseDateEditor {
|
|
|
617
653
|
}
|
|
618
654
|
async getValue() {
|
|
619
655
|
const value = await this.getDateValue();
|
|
656
|
+
const isTimeAllowed = await this.getIsAllowedTime();
|
|
657
|
+
if (isTimeAllowed) {
|
|
658
|
+
return value == "" ? null : formatToDateTime(value);
|
|
659
|
+
}
|
|
620
660
|
return value == "" ? null : new Date(value);
|
|
621
661
|
}
|
|
622
662
|
setValue(value) {
|
|
@@ -699,24 +739,24 @@ var DX_TAG_CONTAINER2 = "dx-tag-container";
|
|
|
699
739
|
var DX_TEXTEDITOR_EMPTY3 = "dx-texteditor-empty";
|
|
700
740
|
var CUSTOM_OPTION_LIST_SELECTOR = "custom-list";
|
|
701
741
|
var SELECT_BOX_OPTION_TEXT_CONTAINER_CLASS2 = "d5-multi-select-item";
|
|
702
|
-
var
|
|
742
|
+
var TAG_BOX_LIST_ITEM_SELECTOR = '.dx-overlay-wrapper .dx-list-item[aria-selected="true"]';
|
|
703
743
|
var combinedOptionHeaderFilterDictValueXpath = (value) => `//div[contains(@class, '${SELECT_BOX_OPTION_TEXT_CONTAINER_CLASS2}') and contains(text(), '${value}')]`;
|
|
704
744
|
var dropDownHeaderFilterDictionaryOptionClick = async (optionValue, driver, dataTEST = "", delay = true) => {
|
|
705
|
-
const { implicit } = await driver.manage().getTimeouts();
|
|
706
|
-
let optElement = null;
|
|
707
|
-
const timeout = delay ? implicit : 600;
|
|
708
745
|
let err = null;
|
|
709
746
|
try {
|
|
710
747
|
const calendarPopoverSelector = byTestIdCssSelector(`${dataTEST}`);
|
|
711
|
-
await
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
748
|
+
await withCustomTimeouts_default({
|
|
749
|
+
driver,
|
|
750
|
+
timeout: delay ? void 0 : 600,
|
|
751
|
+
callback: async () => {
|
|
752
|
+
const calendarPopoverElement = await driver.findElement(By11.css(calendarPopoverSelector));
|
|
753
|
+
const customOptionList = calendarPopoverElement.findElement(By11.css(`.${CUSTOM_OPTION_LIST_SELECTOR}`));
|
|
754
|
+
const optElement = await customOptionList.findElement(By11.xpath(combinedOptionHeaderFilterDictValueXpath(optionValue)));
|
|
755
|
+
await click(optElement, driver);
|
|
756
|
+
}
|
|
757
|
+
});
|
|
716
758
|
} catch (e) {
|
|
717
759
|
err = new Error(`Item not found: "${optionValue}"`);
|
|
718
|
-
} finally {
|
|
719
|
-
await driver.manage().setTimeouts({ implicit });
|
|
720
760
|
}
|
|
721
761
|
if (err)
|
|
722
762
|
throw err;
|
|
@@ -735,7 +775,7 @@ var HeaderFilterDictionary = class extends AbstractDXEditorWithInput {
|
|
|
735
775
|
}
|
|
736
776
|
}
|
|
737
777
|
async waitOptionSelection() {
|
|
738
|
-
await fixElementStaleError(By11.css(
|
|
778
|
+
await fixElementStaleError(By11.css(TAG_BOX_LIST_ITEM_SELECTOR), this.driver);
|
|
739
779
|
}
|
|
740
780
|
async selectOption(inputEl, value, lastElement) {
|
|
741
781
|
try {
|
|
@@ -974,6 +1014,7 @@ var FormField = class extends AbstractEditor {
|
|
|
974
1014
|
import { By as By15 } from "selenium-webdriver";
|
|
975
1015
|
|
|
976
1016
|
// src/pageObjects/elements/AbstractButton.ts
|
|
1017
|
+
var D5_BUTTON_IS_PRESSED = "d5-is-pressed";
|
|
977
1018
|
var AbstractButton = class extends AbstractElementWithParent {
|
|
978
1019
|
constructor(parentCssSelector, elementCssSelector, driver) {
|
|
979
1020
|
super(parentCssSelector, elementCssSelector, driver);
|
|
@@ -999,6 +1040,15 @@ var AbstractButton = class extends AbstractElementWithParent {
|
|
|
999
1040
|
return false;
|
|
1000
1041
|
}
|
|
1001
1042
|
}
|
|
1043
|
+
async isPressed() {
|
|
1044
|
+
try {
|
|
1045
|
+
const button = await this.getElement();
|
|
1046
|
+
const classAttribute = await button.getAttribute("class");
|
|
1047
|
+
return classAttribute.includes(D5_BUTTON_IS_PRESSED);
|
|
1048
|
+
} catch {
|
|
1049
|
+
return false;
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1002
1052
|
};
|
|
1003
1053
|
|
|
1004
1054
|
// src/pageObjects/elements/DXComponents/DXButton.ts
|
|
@@ -1236,7 +1286,15 @@ var AbstractForm = class extends AbstractPage {
|
|
|
1236
1286
|
async exists() {
|
|
1237
1287
|
try {
|
|
1238
1288
|
let elements = await this.driver.findElements(this.containerBy);
|
|
1239
|
-
|
|
1289
|
+
if (elements.length === 0) {
|
|
1290
|
+
return false;
|
|
1291
|
+
}
|
|
1292
|
+
await waitElementIsVisible_default({
|
|
1293
|
+
element: elements[0],
|
|
1294
|
+
errorMessage: "Element exists in DOM but is not visible",
|
|
1295
|
+
driver: this.driver
|
|
1296
|
+
});
|
|
1297
|
+
return true;
|
|
1240
1298
|
} catch (error) {
|
|
1241
1299
|
return false;
|
|
1242
1300
|
}
|
|
@@ -1270,15 +1328,15 @@ async function classDependencyInjector(formType) {
|
|
|
1270
1328
|
let SubFormFactoryClass;
|
|
1271
1329
|
switch (formType) {
|
|
1272
1330
|
case "1" /* LIST */:
|
|
1273
|
-
SubFormFactoryClass = (await import("./ListForm-
|
|
1331
|
+
SubFormFactoryClass = (await import("./ListForm-AXEPFADV.mjs")).default;
|
|
1274
1332
|
break;
|
|
1275
1333
|
case "3" /* TREE */:
|
|
1276
|
-
SubFormFactoryClass = (await import("./TreeView-
|
|
1334
|
+
SubFormFactoryClass = (await import("./TreeView-PNY6V55D.mjs")).default;
|
|
1277
1335
|
break;
|
|
1278
1336
|
case "2" /* EDIT */:
|
|
1279
1337
|
case "99" /* FREE_FORM */:
|
|
1280
1338
|
case "4" /* REPORT */:
|
|
1281
|
-
SubFormFactoryClass = (await import("./FormEdit-
|
|
1339
|
+
SubFormFactoryClass = (await import("./FormEdit-WMDPDBSI.mjs")).default;
|
|
1282
1340
|
break;
|
|
1283
1341
|
default:
|
|
1284
1342
|
throw new Error(`Unsupported form type ${formType}`);
|
|
@@ -1377,6 +1435,7 @@ export {
|
|
|
1377
1435
|
NumberEditor,
|
|
1378
1436
|
ControlClass,
|
|
1379
1437
|
DX_CLEAR_BUTTON_AREA,
|
|
1438
|
+
withCustomTimeouts_default,
|
|
1380
1439
|
editorFactory,
|
|
1381
1440
|
createDocFilterTestId,
|
|
1382
1441
|
createHeaderFilterTestId,
|