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
|
@@ -512,6 +512,24 @@ var init_ClearButtonStrategy = __esm({
|
|
|
512
512
|
}
|
|
513
513
|
});
|
|
514
514
|
|
|
515
|
+
// src/utils/withCustomTimeouts.ts
|
|
516
|
+
async function withCustomTimeouts({ driver, timeout, callback }) {
|
|
517
|
+
const { implicit: defaultTimeout } = await driver.manage().getTimeouts();
|
|
518
|
+
try {
|
|
519
|
+
await driver.manage().setTimeouts({ implicit: timeout ?? defaultTimeout });
|
|
520
|
+
return await callback();
|
|
521
|
+
} finally {
|
|
522
|
+
await driver.manage().setTimeouts({ implicit: defaultTimeout });
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
var withCustomTimeouts_default;
|
|
526
|
+
var init_withCustomTimeouts = __esm({
|
|
527
|
+
"src/utils/withCustomTimeouts.ts"() {
|
|
528
|
+
"use strict";
|
|
529
|
+
withCustomTimeouts_default = withCustomTimeouts;
|
|
530
|
+
}
|
|
531
|
+
});
|
|
532
|
+
|
|
515
533
|
// src/pageObjects/elements/Editors/SelectBoxEditor.ts
|
|
516
534
|
var import_selenium_webdriver9, SELECT_BOX_OPTION_TEXT_CONTAINER_CLASS, combinedValueXpath, dropDownOptionClick, SelectBoxEditor;
|
|
517
535
|
var init_SelectBoxEditor = __esm({
|
|
@@ -522,21 +540,22 @@ var init_SelectBoxEditor = __esm({
|
|
|
522
540
|
init_xpathHelper();
|
|
523
541
|
init_actions();
|
|
524
542
|
init_ClearButtonStrategy();
|
|
543
|
+
init_withCustomTimeouts();
|
|
525
544
|
SELECT_BOX_OPTION_TEXT_CONTAINER_CLASS = "d5-multi-select-item";
|
|
526
545
|
combinedValueXpath = (value) => `//body/div[@id="root"]/div[contains(@class, "dx-overlay-wrapper")]//${XPathHelper.getClassAndValueXpath(SELECT_BOX_OPTION_TEXT_CONTAINER_CLASS, value)}`;
|
|
527
546
|
dropDownOptionClick = async (optionValue, driver, delay = true) => {
|
|
528
|
-
const { implicit } = await driver.manage().getTimeouts();
|
|
529
|
-
let optElement = null;
|
|
530
|
-
const timeout = delay ? implicit : 200;
|
|
531
547
|
let err = null;
|
|
532
548
|
try {
|
|
533
|
-
await
|
|
534
|
-
|
|
535
|
-
|
|
549
|
+
await withCustomTimeouts_default({
|
|
550
|
+
driver,
|
|
551
|
+
timeout: delay ? void 0 : 200,
|
|
552
|
+
callback: async () => {
|
|
553
|
+
let optElement = await driver.findElement(import_selenium_webdriver9.By.xpath(combinedValueXpath(optionValue)));
|
|
554
|
+
await click(optElement, driver);
|
|
555
|
+
}
|
|
556
|
+
});
|
|
536
557
|
} catch (e) {
|
|
537
558
|
err = new Error(`Item not found: "${optionValue}"`);
|
|
538
|
-
} finally {
|
|
539
|
-
await driver.manage().setTimeouts({ implicit });
|
|
540
559
|
}
|
|
541
560
|
if (err)
|
|
542
561
|
throw err;
|
|
@@ -602,7 +621,7 @@ var init_SwitchEditor = __esm({
|
|
|
602
621
|
});
|
|
603
622
|
|
|
604
623
|
// src/pageObjects/elements/Editors/TagBox.ts
|
|
605
|
-
var import_selenium_webdriver10, TAGS_SELECTOR, DX_TAG_CONTAINER, DX_TEXTEDITOR_EMPTY2, BTN_OK_SELECTOR,
|
|
624
|
+
var import_selenium_webdriver10, TAGS_SELECTOR, DX_TAG_CONTAINER, DX_TEXTEDITOR_EMPTY2, BTN_OK_SELECTOR, getSelectedOptionXpath, TagBox;
|
|
606
625
|
var init_TagBox = __esm({
|
|
607
626
|
"src/pageObjects/elements/Editors/TagBox.ts"() {
|
|
608
627
|
"use strict";
|
|
@@ -618,7 +637,7 @@ var init_TagBox = __esm({
|
|
|
618
637
|
DX_TAG_CONTAINER = "dx-tag-container";
|
|
619
638
|
DX_TEXTEDITOR_EMPTY2 = "dx-texteditor-empty";
|
|
620
639
|
BTN_OK_SELECTOR = ".dx-tagbox-popup-wrapper .dx-popup-bottom .dx-button.dx-popup-done";
|
|
621
|
-
|
|
640
|
+
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}")]`;
|
|
622
641
|
TagBox = class extends AbstractDXEditorWithInput {
|
|
623
642
|
constructor(parentCssSelector, elementCssSelector, driver) {
|
|
624
643
|
super(parentCssSelector, elementCssSelector, driver);
|
|
@@ -633,9 +652,15 @@ var init_TagBox = __esm({
|
|
|
633
652
|
}
|
|
634
653
|
await this.confirmSelection();
|
|
635
654
|
}
|
|
636
|
-
async waitOptionSelection() {
|
|
637
|
-
|
|
638
|
-
|
|
655
|
+
async waitOptionSelection(value) {
|
|
656
|
+
await safeWait(
|
|
657
|
+
async () => {
|
|
658
|
+
const elements = await this.driver.findElements(import_selenium_webdriver10.By.xpath(getSelectedOptionXpath(value)));
|
|
659
|
+
if (elements.length === 0) return false;
|
|
660
|
+
return await elements[0].isDisplayed();
|
|
661
|
+
},
|
|
662
|
+
this.driver
|
|
663
|
+
);
|
|
639
664
|
}
|
|
640
665
|
async selectOption(inputEl, value, lastElement) {
|
|
641
666
|
try {
|
|
@@ -644,7 +669,7 @@ var init_TagBox = __esm({
|
|
|
644
669
|
await inputEl.sendKeys(value);
|
|
645
670
|
await dropDownOptionClick(value, this.driver);
|
|
646
671
|
}
|
|
647
|
-
await this.waitOptionSelection();
|
|
672
|
+
await this.waitOptionSelection(value);
|
|
648
673
|
if (value !== lastElement) {
|
|
649
674
|
await inputEl.clear();
|
|
650
675
|
}
|
|
@@ -756,19 +781,30 @@ var init_BooleanSelector = __esm({
|
|
|
756
781
|
});
|
|
757
782
|
|
|
758
783
|
// src/pageObjects/elements/Editors/Date/utils.ts
|
|
759
|
-
var formatDMYDate;
|
|
784
|
+
var formatDMYDate, formatToDateTime;
|
|
760
785
|
var init_utils = __esm({
|
|
761
786
|
"src/pageObjects/elements/Editors/Date/utils.ts"() {
|
|
762
787
|
"use strict";
|
|
763
|
-
formatDMYDate = (date) => {
|
|
764
|
-
const [year, month, day] = date.
|
|
765
|
-
|
|
788
|
+
formatDMYDate = (date, isTimeAllowed = false) => {
|
|
789
|
+
const [year, month, day] = date.toISOString().split("T")[0].split("-");
|
|
790
|
+
if (!isTimeAllowed) {
|
|
791
|
+
return `${day}${month}${year}`;
|
|
792
|
+
}
|
|
793
|
+
const hours = String(date.getHours()).padStart(2, "0");
|
|
794
|
+
const minutes = String(date.getMinutes()).padStart(2, "0");
|
|
795
|
+
return `${day}${month}${year}${hours}${minutes}`;
|
|
796
|
+
};
|
|
797
|
+
formatToDateTime = (dateString) => {
|
|
798
|
+
const [datePart, timePart] = dateString.split("T");
|
|
799
|
+
const [year, month, day] = datePart.split("-").map(Number);
|
|
800
|
+
const [hours, minutes] = timePart.split(":").map(Number);
|
|
801
|
+
return new Date(year, month - 1, day, hours, minutes, 0, 0);
|
|
766
802
|
};
|
|
767
803
|
}
|
|
768
804
|
});
|
|
769
805
|
|
|
770
806
|
// src/pageObjects/elements/Editors/Date/BaseDateEditor.ts
|
|
771
|
-
var import_selenium_webdriver12, BTN_CALENDAR_POPOVER_OPEN_SELECTOR, BTN_CALENDAR_POPOVER_DATE_FROM_INPUT_SELECTOR, BTN_CALENDAR_POPOVER_DATE_TO_INPUT_SELECTOR, BTN_SAVE_SELECTOR, BaseDateEditor;
|
|
807
|
+
var import_selenium_webdriver12, BTN_CALENDAR_POPOVER_OPEN_SELECTOR, BTN_CALENDAR_POPOVER_DATE_FROM_INPUT_SELECTOR, BTN_CALENDAR_POPOVER_DATE_TO_INPUT_SELECTOR, BTN_SAVE_SELECTOR, DATETIME_ALLOWED_SELECTOR, BaseDateEditor;
|
|
772
808
|
var init_BaseDateEditor = __esm({
|
|
773
809
|
"src/pageObjects/elements/Editors/Date/BaseDateEditor.ts"() {
|
|
774
810
|
"use strict";
|
|
@@ -782,11 +818,17 @@ var init_BaseDateEditor = __esm({
|
|
|
782
818
|
BTN_CALENDAR_POPOVER_DATE_FROM_INPUT_SELECTOR = "DateRange__inputs-item--dateFrom";
|
|
783
819
|
BTN_CALENDAR_POPOVER_DATE_TO_INPUT_SELECTOR = "DateRange__inputs-item--dateTo";
|
|
784
820
|
BTN_SAVE_SELECTOR = "DateRange__button-save";
|
|
821
|
+
DATETIME_ALLOWED_SELECTOR = "dx-datebox-datetime";
|
|
785
822
|
BaseDateEditor = class extends AbstractDXEditorWithInput {
|
|
786
823
|
constructor(parentCssSelector, elementCssSelector, driver) {
|
|
787
824
|
super(parentCssSelector, elementCssSelector, driver);
|
|
788
825
|
this.setClearStrategy(new InputClearStrategy());
|
|
789
826
|
}
|
|
827
|
+
async getIsAllowedTime() {
|
|
828
|
+
const dateField = await this.driver.findElement(import_selenium_webdriver12.By.css(`${this.getFullCssSelector()}`));
|
|
829
|
+
const classString = await dateField.getAttribute("class");
|
|
830
|
+
return classString.includes(DATETIME_ALLOWED_SELECTOR);
|
|
831
|
+
}
|
|
790
832
|
async setArrayValue(value) {
|
|
791
833
|
const dateField = await this.driver.findElement(import_selenium_webdriver12.By.css(`${this.getFullCssSelector()}`));
|
|
792
834
|
const dateFieldDataTestID = await this.getDataTestId();
|
|
@@ -806,7 +848,8 @@ var init_BaseDateEditor = __esm({
|
|
|
806
848
|
}
|
|
807
849
|
async setSingleValue(value, inputEl) {
|
|
808
850
|
const actions = this.driver.actions({ async: true });
|
|
809
|
-
const
|
|
851
|
+
const isTimeAllowed = await this.getIsAllowedTime();
|
|
852
|
+
const formattedDate = formatDMYDate(value, isTimeAllowed);
|
|
810
853
|
await click(inputEl, this.driver);
|
|
811
854
|
await actions.move({ origin: inputEl }).sendKeys(import_selenium_webdriver12.Key.HOME).perform();
|
|
812
855
|
await actions.move({ origin: inputEl }).sendKeys(formattedDate, import_selenium_webdriver12.Key.ENTER).perform();
|
|
@@ -830,6 +873,7 @@ var init_SingleDateEditor = __esm({
|
|
|
830
873
|
import_selenium_webdriver13 = require("selenium-webdriver");
|
|
831
874
|
init_InputClearStrategy();
|
|
832
875
|
init_BaseDateEditor();
|
|
876
|
+
init_utils();
|
|
833
877
|
SingleDateEditor = class extends BaseDateEditor {
|
|
834
878
|
constructor(parentCssSelector, elementCssSelector, driver) {
|
|
835
879
|
super(parentCssSelector, elementCssSelector, driver);
|
|
@@ -844,6 +888,10 @@ var init_SingleDateEditor = __esm({
|
|
|
844
888
|
}
|
|
845
889
|
async getValue() {
|
|
846
890
|
const value = await this.getDateValue();
|
|
891
|
+
const isTimeAllowed = await this.getIsAllowedTime();
|
|
892
|
+
if (isTimeAllowed) {
|
|
893
|
+
return value == "" ? null : formatToDateTime(value);
|
|
894
|
+
}
|
|
847
895
|
return value == "" ? null : new Date(value);
|
|
848
896
|
}
|
|
849
897
|
setValue(value) {
|
|
@@ -941,7 +989,7 @@ var init_DateEditor = __esm({
|
|
|
941
989
|
});
|
|
942
990
|
|
|
943
991
|
// src/pageObjects/elements/Editors/HeaderFilterDictionary.ts
|
|
944
|
-
var import_selenium_webdriver15, TAGS_SELECTOR2, DX_TAG_CONTAINER2, DX_TEXTEDITOR_EMPTY3, CUSTOM_OPTION_LIST_SELECTOR, SELECT_BOX_OPTION_TEXT_CONTAINER_CLASS2,
|
|
992
|
+
var import_selenium_webdriver15, TAGS_SELECTOR2, DX_TAG_CONTAINER2, DX_TEXTEDITOR_EMPTY3, CUSTOM_OPTION_LIST_SELECTOR, SELECT_BOX_OPTION_TEXT_CONTAINER_CLASS2, TAG_BOX_LIST_ITEM_SELECTOR, combinedOptionHeaderFilterDictValueXpath, dropDownHeaderFilterDictionaryOptionClick, HeaderFilterDictionary;
|
|
945
993
|
var init_HeaderFilterDictionary = __esm({
|
|
946
994
|
"src/pageObjects/elements/Editors/HeaderFilterDictionary.ts"() {
|
|
947
995
|
"use strict";
|
|
@@ -951,29 +999,30 @@ var init_HeaderFilterDictionary = __esm({
|
|
|
951
999
|
init_locators();
|
|
952
1000
|
init_ClearButtonStrategy();
|
|
953
1001
|
init_fixElementStaleError();
|
|
1002
|
+
init_withCustomTimeouts();
|
|
954
1003
|
TAGS_SELECTOR2 = ".dx-tag .tag-text";
|
|
955
1004
|
DX_TAG_CONTAINER2 = "dx-tag-container";
|
|
956
1005
|
DX_TEXTEDITOR_EMPTY3 = "dx-texteditor-empty";
|
|
957
1006
|
CUSTOM_OPTION_LIST_SELECTOR = "custom-list";
|
|
958
1007
|
SELECT_BOX_OPTION_TEXT_CONTAINER_CLASS2 = "d5-multi-select-item";
|
|
959
|
-
|
|
1008
|
+
TAG_BOX_LIST_ITEM_SELECTOR = '.dx-overlay-wrapper .dx-list-item[aria-selected="true"]';
|
|
960
1009
|
combinedOptionHeaderFilterDictValueXpath = (value) => `//div[contains(@class, '${SELECT_BOX_OPTION_TEXT_CONTAINER_CLASS2}') and contains(text(), '${value}')]`;
|
|
961
1010
|
dropDownHeaderFilterDictionaryOptionClick = async (optionValue, driver, dataTEST = "", delay = true) => {
|
|
962
|
-
const { implicit } = await driver.manage().getTimeouts();
|
|
963
|
-
let optElement = null;
|
|
964
|
-
const timeout = delay ? implicit : 600;
|
|
965
1011
|
let err = null;
|
|
966
1012
|
try {
|
|
967
1013
|
const calendarPopoverSelector = byTestIdCssSelector(`${dataTEST}`);
|
|
968
|
-
await
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
1014
|
+
await withCustomTimeouts_default({
|
|
1015
|
+
driver,
|
|
1016
|
+
timeout: delay ? void 0 : 600,
|
|
1017
|
+
callback: async () => {
|
|
1018
|
+
const calendarPopoverElement = await driver.findElement(import_selenium_webdriver15.By.css(calendarPopoverSelector));
|
|
1019
|
+
const customOptionList = calendarPopoverElement.findElement(import_selenium_webdriver15.By.css(`.${CUSTOM_OPTION_LIST_SELECTOR}`));
|
|
1020
|
+
const optElement = await customOptionList.findElement(import_selenium_webdriver15.By.xpath(combinedOptionHeaderFilterDictValueXpath(optionValue)));
|
|
1021
|
+
await click(optElement, driver);
|
|
1022
|
+
}
|
|
1023
|
+
});
|
|
973
1024
|
} catch (e) {
|
|
974
1025
|
err = new Error(`Item not found: "${optionValue}"`);
|
|
975
|
-
} finally {
|
|
976
|
-
await driver.manage().setTimeouts({ implicit });
|
|
977
1026
|
}
|
|
978
1027
|
if (err)
|
|
979
1028
|
throw err;
|
|
@@ -992,7 +1041,7 @@ var init_HeaderFilterDictionary = __esm({
|
|
|
992
1041
|
}
|
|
993
1042
|
}
|
|
994
1043
|
async waitOptionSelection() {
|
|
995
|
-
await fixElementStaleError(import_selenium_webdriver15.By.css(
|
|
1044
|
+
await fixElementStaleError(import_selenium_webdriver15.By.css(TAG_BOX_LIST_ITEM_SELECTOR), this.driver);
|
|
996
1045
|
}
|
|
997
1046
|
async selectOption(inputEl, value, lastElement) {
|
|
998
1047
|
try {
|
|
@@ -1136,13 +1185,14 @@ var init_createDataTestId = __esm({
|
|
|
1136
1185
|
});
|
|
1137
1186
|
|
|
1138
1187
|
// src/pageObjects/elements/AbstractButton.ts
|
|
1139
|
-
var AbstractButton;
|
|
1188
|
+
var D5_BUTTON_IS_PRESSED, AbstractButton;
|
|
1140
1189
|
var init_AbstractButton = __esm({
|
|
1141
1190
|
"src/pageObjects/elements/AbstractButton.ts"() {
|
|
1142
1191
|
"use strict";
|
|
1143
1192
|
init_AbstractElementWithParent();
|
|
1144
1193
|
init_actions();
|
|
1145
1194
|
init_waitElementIsClickable();
|
|
1195
|
+
D5_BUTTON_IS_PRESSED = "d5-is-pressed";
|
|
1146
1196
|
AbstractButton = class extends AbstractElementWithParent {
|
|
1147
1197
|
constructor(parentCssSelector, elementCssSelector, driver) {
|
|
1148
1198
|
super(parentCssSelector, elementCssSelector, driver);
|
|
@@ -1168,6 +1218,15 @@ var init_AbstractButton = __esm({
|
|
|
1168
1218
|
return false;
|
|
1169
1219
|
}
|
|
1170
1220
|
}
|
|
1221
|
+
async isPressed() {
|
|
1222
|
+
try {
|
|
1223
|
+
const button = await this.getElement();
|
|
1224
|
+
const classAttribute = await button.getAttribute("class");
|
|
1225
|
+
return classAttribute.includes(D5_BUTTON_IS_PRESSED);
|
|
1226
|
+
} catch {
|
|
1227
|
+
return false;
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1171
1230
|
};
|
|
1172
1231
|
}
|
|
1173
1232
|
});
|
|
@@ -1467,6 +1526,7 @@ var init_AbstractForm = __esm({
|
|
|
1467
1526
|
init_AbstractPage();
|
|
1468
1527
|
init_FormButton();
|
|
1469
1528
|
init_FormGroup();
|
|
1529
|
+
init_waitElementIsVisible();
|
|
1470
1530
|
AbstractForm = class extends AbstractPage {
|
|
1471
1531
|
containerCssSelector = "";
|
|
1472
1532
|
_formName = "";
|
|
@@ -1491,7 +1551,15 @@ var init_AbstractForm = __esm({
|
|
|
1491
1551
|
async exists() {
|
|
1492
1552
|
try {
|
|
1493
1553
|
let elements = await this.driver.findElements(this.containerBy);
|
|
1494
|
-
|
|
1554
|
+
if (elements.length === 0) {
|
|
1555
|
+
return false;
|
|
1556
|
+
}
|
|
1557
|
+
await waitElementIsVisible_default({
|
|
1558
|
+
element: elements[0],
|
|
1559
|
+
errorMessage: "Element exists in DOM but is not visible",
|
|
1560
|
+
driver: this.driver
|
|
1561
|
+
});
|
|
1562
|
+
return true;
|
|
1495
1563
|
} catch (error) {
|
|
1496
1564
|
return false;
|
|
1497
1565
|
}
|
|
@@ -1594,7 +1662,7 @@ var init_Cell = __esm({
|
|
|
1594
1662
|
const [datePart, timePart] = value.split(", ");
|
|
1595
1663
|
const [day, month, year] = datePart.split(".").map(Number);
|
|
1596
1664
|
const [hours, minutes] = timePart.split(":").map(Number);
|
|
1597
|
-
return new Date(
|
|
1665
|
+
return new Date(year, month - 1, day, hours, minutes, 0, 0);
|
|
1598
1666
|
} else {
|
|
1599
1667
|
const [day, month, year] = value.split(".").map(Number);
|
|
1600
1668
|
return new Date(Date.UTC(year, month - 1, day));
|
|
@@ -1678,9 +1746,18 @@ var init_Row = __esm({
|
|
|
1678
1746
|
getCellByTitle(title) {
|
|
1679
1747
|
return this._getCell({ title });
|
|
1680
1748
|
}
|
|
1681
|
-
async select() {
|
|
1749
|
+
async select(preserve = false) {
|
|
1682
1750
|
await staleElementAction(async () => {
|
|
1683
1751
|
const rowEl = await this.getElement();
|
|
1752
|
+
const isSelected = (await this.getClasses()).includes(DX_SELECTION_CLASS);
|
|
1753
|
+
if (isSelected && !preserve) {
|
|
1754
|
+
await this.driver.actions({ async: true }).keyUp(import_selenium_webdriver22.Key.CONTROL).perform();
|
|
1755
|
+
}
|
|
1756
|
+
if (preserve && !isSelected) {
|
|
1757
|
+
await this.driver.actions({ async: true }).keyDown(import_selenium_webdriver22.Key.CONTROL).perform();
|
|
1758
|
+
await click(rowEl, this.driver);
|
|
1759
|
+
return;
|
|
1760
|
+
}
|
|
1684
1761
|
await click(rowEl, this.driver);
|
|
1685
1762
|
});
|
|
1686
1763
|
await safeWait(
|
|
@@ -2013,8 +2090,8 @@ var init_AbstractDropDownMenuList = __esm({
|
|
|
2013
2090
|
const menuItemElement = await fixElementStaleError(by, this.driver);
|
|
2014
2091
|
await click(menuItemElement, this.driver);
|
|
2015
2092
|
}
|
|
2016
|
-
async getElementByPath(
|
|
2017
|
-
let pathList = isString(
|
|
2093
|
+
async getElementByPath(path2, getBy, returnLastElement = false) {
|
|
2094
|
+
let pathList = isString(path2) ? [path2] : path2;
|
|
2018
2095
|
let result = null;
|
|
2019
2096
|
let index = 1;
|
|
2020
2097
|
for (let text of pathList) {
|
|
@@ -2086,7 +2163,7 @@ var init_DXContextMenuList = __esm({
|
|
|
2086
2163
|
async isVisible() {
|
|
2087
2164
|
try {
|
|
2088
2165
|
await waitElementIsVisible_default({
|
|
2089
|
-
element: await this.driver.findElement(import_selenium_webdriver24.By.css(`.dx-overlay-wrapper .dx-
|
|
2166
|
+
element: await this.driver.findElement(import_selenium_webdriver24.By.css(`.dx-overlay-wrapper .dx-context-menu`)),
|
|
2090
2167
|
driver: this.driver,
|
|
2091
2168
|
errorMessage: "Cannot find dropdown element"
|
|
2092
2169
|
});
|
|
@@ -2144,6 +2221,8 @@ var init_Table = __esm({
|
|
|
2144
2221
|
init_FormField();
|
|
2145
2222
|
init_ContextMenu();
|
|
2146
2223
|
init_actions();
|
|
2224
|
+
init_wait();
|
|
2225
|
+
init_withCustomTimeouts();
|
|
2147
2226
|
Table = class extends AbstractElementWithParent {
|
|
2148
2227
|
formName;
|
|
2149
2228
|
headerCssSelector;
|
|
@@ -2209,13 +2288,32 @@ var init_Table = __esm({
|
|
|
2209
2288
|
/**
|
|
2210
2289
|
* Вибрати рядок по індексу.
|
|
2211
2290
|
* @param index починається з 0
|
|
2291
|
+
* @param preserve boolean який изначає, чи повинні раніше вибрані рядки залишатися вибраними
|
|
2212
2292
|
*/
|
|
2213
|
-
selectRowByIndex(index) {
|
|
2214
|
-
return this.getRowByIndex(index).select();
|
|
2293
|
+
selectRowByIndex(index, preserve = false) {
|
|
2294
|
+
return this.getRowByIndex(index).select(preserve);
|
|
2215
2295
|
}
|
|
2216
|
-
|
|
2296
|
+
/**
|
|
2297
|
+
* Вибрати масив рядків по індексу.
|
|
2298
|
+
* @param indexes починається з 0
|
|
2299
|
+
*/
|
|
2300
|
+
async selectRowsByIndexes(indexes) {
|
|
2301
|
+
for (const index of indexes) {
|
|
2302
|
+
await this.selectRowByIndex(index, true);
|
|
2303
|
+
}
|
|
2304
|
+
}
|
|
2305
|
+
getRowElements(timeout) {
|
|
2217
2306
|
const rowsFullCssSelector = `${this.getFullCssSelector()} ${this.tableContentCssSelector} .dx-row.dx-data-row`;
|
|
2218
|
-
|
|
2307
|
+
return withCustomTimeouts_default({
|
|
2308
|
+
driver: this.driver,
|
|
2309
|
+
timeout,
|
|
2310
|
+
callback: () => {
|
|
2311
|
+
return this.driver.findElements(import_selenium_webdriver25.By.css(rowsFullCssSelector));
|
|
2312
|
+
}
|
|
2313
|
+
});
|
|
2314
|
+
}
|
|
2315
|
+
async getRows() {
|
|
2316
|
+
const rows = await this.getRowElements();
|
|
2219
2317
|
const result = [];
|
|
2220
2318
|
rows.forEach((_, index) => {
|
|
2221
2319
|
const newRow = new Row(
|
|
@@ -2301,6 +2399,72 @@ var init_Table = __esm({
|
|
|
2301
2399
|
await contextMenu(cellElement, this.driver);
|
|
2302
2400
|
});
|
|
2303
2401
|
}
|
|
2402
|
+
/**
|
|
2403
|
+
* Отримує значення комірки таблиці за ім'ям комірки та індексом рядка.
|
|
2404
|
+
*
|
|
2405
|
+
* @param {string} cellName - Ім'я комірки (поля) в таблиці
|
|
2406
|
+
* @param {number} rowIndex - Індекс рядка (починається з 0)
|
|
2407
|
+
* @throws {Error} Викидає помилку, якщо rowIndex не вказано
|
|
2408
|
+
* @returns {Promise<string>} Повертає значення комірки
|
|
2409
|
+
*
|
|
2410
|
+
* @example
|
|
2411
|
+
* const table = new Table(driver);
|
|
2412
|
+
*
|
|
2413
|
+
* // Отримання значення комірки 'Name' в першому рядку (індекс 0)
|
|
2414
|
+
* const cellValue = await table.getCellValueByCellName('Name', 0);
|
|
2415
|
+
* expect(cellValue).toBe('Очікуване значення');
|
|
2416
|
+
*/
|
|
2417
|
+
getCellValueByCellName(cellName, rowIndex) {
|
|
2418
|
+
if (rowIndex == null) {
|
|
2419
|
+
throw new Error("Error: getCellValue(): rowIndex is required");
|
|
2420
|
+
}
|
|
2421
|
+
const row = this.getRowByIndex(rowIndex);
|
|
2422
|
+
return row.getCell(cellName).getValue();
|
|
2423
|
+
}
|
|
2424
|
+
/**
|
|
2425
|
+
* Перевіряє, чи є таблиця порожньою (не містить жодного рядка з даними).
|
|
2426
|
+
*
|
|
2427
|
+
* @returns {Promise<boolean>} Повертає true, якщо таблиця порожня, false - якщо містить рядки
|
|
2428
|
+
*
|
|
2429
|
+
* @example
|
|
2430
|
+
* const table = new Table(driver);
|
|
2431
|
+
*
|
|
2432
|
+
* // Перевірка чи порожня таблиця
|
|
2433
|
+
* const empty = await table.isEmpty();
|
|
2434
|
+
* expect(empty).toBe(true);
|
|
2435
|
+
*/
|
|
2436
|
+
async isEmpty() {
|
|
2437
|
+
try {
|
|
2438
|
+
await this.waitRowsCount(0);
|
|
2439
|
+
return true;
|
|
2440
|
+
} catch {
|
|
2441
|
+
return false;
|
|
2442
|
+
}
|
|
2443
|
+
}
|
|
2444
|
+
/**
|
|
2445
|
+
* Очікує, поки кількість рядків у таблиці не стане рівною заданому значенню.
|
|
2446
|
+
* Використовується для синхронізації тестів з динамічним завантаженням даних.
|
|
2447
|
+
*
|
|
2448
|
+
* @param {number} count - Очікувана кількість рядків у таблиці
|
|
2449
|
+
* @returns {Promise<void>} Повертає Promise, який виконується, коли кількість рядків відповідає очікуваній
|
|
2450
|
+
* @throws {Error} Викидає помилку, якщо очікування перевищує тайм-аут
|
|
2451
|
+
*
|
|
2452
|
+
* @example
|
|
2453
|
+
* const table = new Table(driver);
|
|
2454
|
+
*
|
|
2455
|
+
* // Очікування, поки таблиця не стане порожньою
|
|
2456
|
+
* await table.waitRowsCount(0);
|
|
2457
|
+
*
|
|
2458
|
+
* // Очікування, поки в таблиці не з'явиться 5 рядків
|
|
2459
|
+
* await table.waitRowsCount(5);
|
|
2460
|
+
* console.log('Таблиця містить 5 рядків');
|
|
2461
|
+
*/
|
|
2462
|
+
async waitRowsCount(count) {
|
|
2463
|
+
await safeWait(async () => {
|
|
2464
|
+
const rows = await this.getRowElements(1e3);
|
|
2465
|
+
return rows.length === count;
|
|
2466
|
+
}, this.driver, `Rows count not equal: ${count}`);
|
|
2467
|
+
}
|
|
2304
2468
|
};
|
|
2305
2469
|
}
|
|
2306
2470
|
});
|
|
@@ -2567,6 +2731,14 @@ var init_ToolbarItem = __esm({
|
|
|
2567
2731
|
return false;
|
|
2568
2732
|
}
|
|
2569
2733
|
}
|
|
2734
|
+
async isPressed() {
|
|
2735
|
+
try {
|
|
2736
|
+
await this.init();
|
|
2737
|
+
return this._button.isPressed();
|
|
2738
|
+
} catch (error) {
|
|
2739
|
+
return false;
|
|
2740
|
+
}
|
|
2741
|
+
}
|
|
2570
2742
|
async getTitle() {
|
|
2571
2743
|
await this.init();
|
|
2572
2744
|
return await this._button.getTitle();
|
|
@@ -3020,7 +3192,7 @@ var init_ColumnFilter = __esm({
|
|
|
3020
3192
|
init_wait();
|
|
3021
3193
|
APPLY_SELECTOR = ".apply-button";
|
|
3022
3194
|
CANCEL_SELECTOR = ".cancel-button";
|
|
3023
|
-
HEADER_FILTER_ICON = ".
|
|
3195
|
+
HEADER_FILTER_ICON = ".indicators-container .filter-icon";
|
|
3024
3196
|
HEADER_FILTER_CONTAINER = ".header-filter";
|
|
3025
3197
|
HEADER_FILTER_BUTTONS = ".header-filter-buttons";
|
|
3026
3198
|
ColumnFilter = class extends AbstractElement {
|
|
@@ -3054,24 +3226,15 @@ var init_ColumnFilter = __esm({
|
|
|
3054
3226
|
const columnEl = await this._column.getElement();
|
|
3055
3227
|
const actions = this.driver.actions({ async: true });
|
|
3056
3228
|
await actions.move({ origin: columnEl }).perform();
|
|
3057
|
-
const
|
|
3058
|
-
let headerFilterIcon =
|
|
3229
|
+
const headerFilterIconBy = import_selenium_webdriver30.By.css(HEADER_FILTER_ICON);
|
|
3230
|
+
let headerFilterIcon = await columnEl.findElement(headerFilterIconBy);
|
|
3059
3231
|
await safeWait(
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
for (let element of elements) {
|
|
3063
|
-
if (await element.isDisplayed()) {
|
|
3064
|
-
headerFilterIcon = element;
|
|
3065
|
-
result = true;
|
|
3066
|
-
break;
|
|
3067
|
-
}
|
|
3068
|
-
}
|
|
3069
|
-
return result;
|
|
3232
|
+
() => {
|
|
3233
|
+
return headerFilterIcon.isDisplayed();
|
|
3070
3234
|
},
|
|
3071
3235
|
this.driver,
|
|
3072
3236
|
`HeaderFilter "${this._name}" is not visible`
|
|
3073
3237
|
);
|
|
3074
|
-
if (!headerFilterIcon) throw new Error(`HeaderFilter "${this._name}" is not visible`);
|
|
3075
3238
|
await click(headerFilterIcon, this.driver);
|
|
3076
3239
|
const filter = new HeaderFilterField("", this._formName, this._name, this.driver);
|
|
3077
3240
|
const filterEl = await filter.getElement();
|
|
@@ -3210,9 +3373,9 @@ var init_ListForm = __esm({
|
|
|
3210
3373
|
init_FormFilterField();
|
|
3211
3374
|
init_FilterPanel();
|
|
3212
3375
|
init_ColumnFilter();
|
|
3213
|
-
DATAGRID_HEADER_CSS_SELECTOR = ".dx-datagrid-headers .dx-datagrid-content
|
|
3214
|
-
DATAGRID_CONTENT_CSS_SELECTOR = ".dx-datagrid-content
|
|
3215
|
-
FIXED_DATAGRID_CONTENT_CSS_SELECTOR = ".dx-
|
|
3376
|
+
DATAGRID_HEADER_CSS_SELECTOR = ".dx-datagrid-headers .dx-datagrid-content .dx-datagrid-table.dx-datagrid-table-fixed";
|
|
3377
|
+
DATAGRID_CONTENT_CSS_SELECTOR = ".dx-datagrid-content .dx-datagrid-table.dx-datagrid-table-fixed";
|
|
3378
|
+
FIXED_DATAGRID_CONTENT_CSS_SELECTOR = ".dx-datagrid-sticky-columns .dx-datagrid-content .dx-datagrid-table.dx-datagrid-table-fixed";
|
|
3216
3379
|
CONTEXT_MENU_CSS_SELECTOR = ".dx-datagrid";
|
|
3217
3380
|
ListForm = class extends Form {
|
|
3218
3381
|
headerCssSelector;
|
|
@@ -3297,9 +3460,9 @@ var init_TreeView = __esm({
|
|
|
3297
3460
|
"src/pageObjects/elements/Forms/TreeView.ts"() {
|
|
3298
3461
|
"use strict";
|
|
3299
3462
|
init_ListForm();
|
|
3300
|
-
TREELIST_HEADER_CSS_SELECTOR = ".dx-treelist-headers .dx-treelist-content
|
|
3301
|
-
TREELIST_CONTENT_CSS_SELECTOR = ".dx-treelist-content
|
|
3302
|
-
FIXED_TREELIST_CONTENT_CSS_SELECTOR = ".dx-
|
|
3463
|
+
TREELIST_HEADER_CSS_SELECTOR = ".dx-treelist-headers .dx-treelist-content .dx-treelist-table.dx-treelist-table-fixed";
|
|
3464
|
+
TREELIST_CONTENT_CSS_SELECTOR = ".dx-treelist-content .dx-treelist-table.dx-treelist-table-fixed";
|
|
3465
|
+
FIXED_TREELIST_CONTENT_CSS_SELECTOR = ".dx-treelist-sticky-columns .dx-treelist-content .dx-treelist-table.dx-treelist-table-fixed";
|
|
3303
3466
|
TreeView = class extends ListForm {
|
|
3304
3467
|
constructor(driver) {
|
|
3305
3468
|
super(driver);
|
|
@@ -3600,6 +3763,9 @@ init_locators();
|
|
|
3600
3763
|
|
|
3601
3764
|
// src/utils/createDriver.ts
|
|
3602
3765
|
var import_selenium_webdriver4 = require("selenium-webdriver");
|
|
3766
|
+
var import_node_path = __toESM(require("path"));
|
|
3767
|
+
var import_node_fs = __toESM(require("fs"));
|
|
3768
|
+
var import_node_os = __toESM(require("os"));
|
|
3603
3769
|
init_config();
|
|
3604
3770
|
var import_chrome = __toESM(require("selenium-webdriver/chrome"));
|
|
3605
3771
|
var import_firefox = __toESM(require("selenium-webdriver/firefox"));
|
|
@@ -3607,7 +3773,15 @@ function chromeOptions(builder, options) {
|
|
|
3607
3773
|
const ChromeOptions = new import_chrome.default.Options();
|
|
3608
3774
|
if (options.headless) {
|
|
3609
3775
|
ChromeOptions.addArguments(`--headless=new`);
|
|
3776
|
+
ChromeOptions.addArguments(`--disable-gpu`);
|
|
3777
|
+
ChromeOptions.addArguments(`--disable-dev-shm-usage`);
|
|
3778
|
+
ChromeOptions.addArguments(`--window-size=1920,1080`);
|
|
3610
3779
|
}
|
|
3780
|
+
const userDataDir = import_node_path.default.join(import_node_os.default.tmpdir(), ".chrome-cache");
|
|
3781
|
+
if (!import_node_fs.default.existsSync(userDataDir)) {
|
|
3782
|
+
import_node_fs.default.mkdirSync(userDataDir, { recursive: true });
|
|
3783
|
+
}
|
|
3784
|
+
ChromeOptions.addArguments(`--user-data-dir=${userDataDir}`);
|
|
3611
3785
|
return builder.setChromeOptions(ChromeOptions);
|
|
3612
3786
|
}
|
|
3613
3787
|
function firefoxOptions(builder, options) {
|
|
@@ -3635,7 +3809,9 @@ var createDriver = async (browser) => {
|
|
|
3635
3809
|
const driver = await builder.build();
|
|
3636
3810
|
const manage = driver.manage();
|
|
3637
3811
|
await manage.setTimeouts({ implicit: config().timeout });
|
|
3638
|
-
|
|
3812
|
+
if (!headless) {
|
|
3813
|
+
await manage.window().maximize();
|
|
3814
|
+
}
|
|
3639
3815
|
return driver;
|
|
3640
3816
|
};
|
|
3641
3817
|
|