d5-testing-library 1.9.0-alpha.1 → 1.9.0-alpha.11

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.
@@ -0,0 +1,7 @@
1
+ import {
2
+ FormEdit
3
+ } from "./chunk-IL7WDMOX.mjs";
4
+ import "./chunk-BVVGX5JV.mjs";
5
+ export {
6
+ FormEdit as default
7
+ };
@@ -0,0 +1,7 @@
1
+ import {
2
+ ListForm
3
+ } from "./chunk-TUQMPYW7.mjs";
4
+ import "./chunk-BVVGX5JV.mjs";
5
+ export {
6
+ ListForm as default
7
+ };
@@ -0,0 +1,8 @@
1
+ import {
2
+ TreeView
3
+ } from "./chunk-EMZGYTYY.mjs";
4
+ import "./chunk-TUQMPYW7.mjs";
5
+ import "./chunk-BVVGX5JV.mjs";
6
+ export {
7
+ TreeView as default
8
+ };
@@ -427,7 +427,7 @@ var TAGS_SELECTOR = ".dx-tag .tag-text";
427
427
  var DX_TAG_CONTAINER = "dx-tag-container";
428
428
  var DX_TEXTEDITOR_EMPTY2 = "dx-texteditor-empty";
429
429
  var BTN_OK_SELECTOR = ".dx-tagbox-popup-wrapper .dx-popup-bottom .dx-button.dx-popup-done";
430
- var TAG_BOX_LIST_ITEM_SELECTOR = '.dx-tagbox-popup-wrapper .dx-list-item[aria-selected="true"]';
430
+ 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
431
  var TagBox = class extends AbstractDXEditorWithInput {
432
432
  constructor(parentCssSelector, elementCssSelector, driver) {
433
433
  super(parentCssSelector, elementCssSelector, driver);
@@ -442,9 +442,15 @@ var TagBox = class extends AbstractDXEditorWithInput {
442
442
  }
443
443
  await this.confirmSelection();
444
444
  }
445
- async waitOptionSelection() {
446
- const option = await fixElementStaleError(By6.css(TAG_BOX_LIST_ITEM_SELECTOR), this.driver);
447
- await safeWait(() => option.isDisplayed(), this.driver);
445
+ async waitOptionSelection(value) {
446
+ await safeWait(
447
+ async () => {
448
+ const elements = await this.driver.findElements(By6.xpath(getSelectedOptionXpath(value)));
449
+ if (elements.length === 0) return false;
450
+ return await elements[0].isDisplayed();
451
+ },
452
+ this.driver
453
+ );
448
454
  }
449
455
  async selectOption(inputEl, value, lastElement) {
450
456
  try {
@@ -453,7 +459,7 @@ var TagBox = class extends AbstractDXEditorWithInput {
453
459
  await inputEl.sendKeys(value);
454
460
  await dropDownOptionClick(value, this.driver);
455
461
  }
456
- await this.waitOptionSelection();
462
+ await this.waitOptionSelection(value);
457
463
  if (value !== lastElement) {
458
464
  await inputEl.clear();
459
465
  }
@@ -699,7 +705,7 @@ var DX_TAG_CONTAINER2 = "dx-tag-container";
699
705
  var DX_TEXTEDITOR_EMPTY3 = "dx-texteditor-empty";
700
706
  var CUSTOM_OPTION_LIST_SELECTOR = "custom-list";
701
707
  var SELECT_BOX_OPTION_TEXT_CONTAINER_CLASS2 = "d5-multi-select-item";
702
- var TAG_BOX_LIST_ITEM_SELECTOR2 = '.dx-overlay-wrapper .dx-list-item[aria-selected="true"]';
708
+ var TAG_BOX_LIST_ITEM_SELECTOR = '.dx-overlay-wrapper .dx-list-item[aria-selected="true"]';
703
709
  var combinedOptionHeaderFilterDictValueXpath = (value) => `//div[contains(@class, '${SELECT_BOX_OPTION_TEXT_CONTAINER_CLASS2}') and contains(text(), '${value}')]`;
704
710
  var dropDownHeaderFilterDictionaryOptionClick = async (optionValue, driver, dataTEST = "", delay = true) => {
705
711
  const { implicit } = await driver.manage().getTimeouts();
@@ -735,7 +741,7 @@ var HeaderFilterDictionary = class extends AbstractDXEditorWithInput {
735
741
  }
736
742
  }
737
743
  async waitOptionSelection() {
738
- await fixElementStaleError(By11.css(TAG_BOX_LIST_ITEM_SELECTOR2), this.driver);
744
+ await fixElementStaleError(By11.css(TAG_BOX_LIST_ITEM_SELECTOR), this.driver);
739
745
  }
740
746
  async selectOption(inputEl, value, lastElement) {
741
747
  try {
@@ -974,6 +980,7 @@ var FormField = class extends AbstractEditor {
974
980
  import { By as By15 } from "selenium-webdriver";
975
981
 
976
982
  // src/pageObjects/elements/AbstractButton.ts
983
+ var D5_BUTTON_IS_PRESSED = "d5-is-pressed";
977
984
  var AbstractButton = class extends AbstractElementWithParent {
978
985
  constructor(parentCssSelector, elementCssSelector, driver) {
979
986
  super(parentCssSelector, elementCssSelector, driver);
@@ -999,6 +1006,15 @@ var AbstractButton = class extends AbstractElementWithParent {
999
1006
  return false;
1000
1007
  }
1001
1008
  }
1009
+ async isPressed() {
1010
+ try {
1011
+ const button = await this.getElement();
1012
+ const classAttribute = await button.getAttribute("class");
1013
+ return classAttribute.includes(D5_BUTTON_IS_PRESSED);
1014
+ } catch {
1015
+ return false;
1016
+ }
1017
+ }
1002
1018
  };
1003
1019
 
1004
1020
  // src/pageObjects/elements/DXComponents/DXButton.ts
@@ -1236,7 +1252,15 @@ var AbstractForm = class extends AbstractPage {
1236
1252
  async exists() {
1237
1253
  try {
1238
1254
  let elements = await this.driver.findElements(this.containerBy);
1239
- return elements.length > 0;
1255
+ if (elements.length === 0) {
1256
+ return false;
1257
+ }
1258
+ await waitElementIsVisible_default({
1259
+ element: elements[0],
1260
+ errorMessage: "Element exists in DOM but is not visible",
1261
+ driver: this.driver
1262
+ });
1263
+ return true;
1240
1264
  } catch (error) {
1241
1265
  return false;
1242
1266
  }
@@ -1270,15 +1294,15 @@ async function classDependencyInjector(formType) {
1270
1294
  let SubFormFactoryClass;
1271
1295
  switch (formType) {
1272
1296
  case "1" /* LIST */:
1273
- SubFormFactoryClass = (await import("./ListForm-MXGUBMWS.mjs")).default;
1297
+ SubFormFactoryClass = (await import("./ListForm-ZXNRKZ6M.mjs")).default;
1274
1298
  break;
1275
1299
  case "3" /* TREE */:
1276
- SubFormFactoryClass = (await import("./TreeView-VZBOZCFW.mjs")).default;
1300
+ SubFormFactoryClass = (await import("./TreeView-MHMEFMAT.mjs")).default;
1277
1301
  break;
1278
1302
  case "2" /* EDIT */:
1279
1303
  case "99" /* FREE_FORM */:
1280
1304
  case "4" /* REPORT */:
1281
- SubFormFactoryClass = (await import("./FormEdit-QNZOB7PA.mjs")).default;
1305
+ SubFormFactoryClass = (await import("./FormEdit-NTNY3YFF.mjs")).default;
1282
1306
  break;
1283
1307
  default:
1284
1308
  throw new Error(`Unsupported form type ${formType}`);
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  ListForm
3
- } from "./chunk-S62QEWWA.mjs";
3
+ } from "./chunk-TUQMPYW7.mjs";
4
4
 
5
5
  // src/pageObjects/elements/Forms/TreeView.ts
6
- var TREELIST_HEADER_CSS_SELECTOR = ".dx-treelist-headers .dx-treelist-content:not(.dx-datagrid-content-fixed)";
7
- var TREELIST_CONTENT_CSS_SELECTOR = ".dx-treelist-content:not(.dx-datagrid-content-fixed)";
8
- var FIXED_TREELIST_CONTENT_CSS_SELECTOR = ".dx-fixed-columns .dx-treelist-content.dx-treelist-content-fixed";
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);
@@ -3,7 +3,7 @@ import {
3
3
  FormField,
4
4
  click,
5
5
  safeWait
6
- } from "./chunk-32KSAOFJ.mjs";
6
+ } from "./chunk-BVVGX5JV.mjs";
7
7
 
8
8
  // src/pageObjects/elements/Forms/FormEdit.ts
9
9
  import { By } from "selenium-webdriver";
@@ -18,13 +18,13 @@ import {
18
18
  staleElementAction,
19
19
  waitElementIsClickable_default,
20
20
  waitElementIsVisible_default
21
- } from "./chunk-32KSAOFJ.mjs";
21
+ } from "./chunk-BVVGX5JV.mjs";
22
22
 
23
23
  // src/pageObjects/elements/Table/Table.ts
24
24
  import { By as By6 } from "selenium-webdriver";
25
25
 
26
26
  // src/pageObjects/elements/Table/elements/Row.ts
27
- import { By as By3 } from "selenium-webdriver";
27
+ import { By as By3, Key } from "selenium-webdriver";
28
28
 
29
29
  // src/pageObjects/elements/Table/elements/Cell.ts
30
30
  import { By as By2 } from "selenium-webdriver";
@@ -153,9 +153,18 @@ var Row = class extends AbstractElementWithParent {
153
153
  getCellByTitle(title) {
154
154
  return this._getCell({ title });
155
155
  }
156
- async select() {
156
+ async select(preserve = false) {
157
157
  await staleElementAction(async () => {
158
158
  const rowEl = await this.getElement();
159
+ const isSelected = (await this.getClasses()).includes(DX_SELECTION_CLASS);
160
+ if (isSelected && !preserve) {
161
+ await this.driver.actions({ async: true }).keyUp(Key.CONTROL).perform();
162
+ }
163
+ if (preserve && !isSelected) {
164
+ await this.driver.actions({ async: true }).keyDown(Key.CONTROL).perform();
165
+ await click(rowEl, this.driver);
166
+ return;
167
+ }
159
168
  await click(rowEl, this.driver);
160
169
  });
161
170
  await safeWait(
@@ -366,7 +375,7 @@ var DXContextMenuList = class extends AbstractDropDownMenuList {
366
375
  async isVisible() {
367
376
  try {
368
377
  await waitElementIsVisible_default({
369
- element: await this.driver.findElement(By5.css(`.dx-overlay-wrapper .dx-contextmenu`)),
378
+ element: await this.driver.findElement(By5.css(`.dx-overlay-wrapper .dx-context-menu`)),
370
379
  driver: this.driver,
371
380
  errorMessage: "Cannot find dropdown element"
372
381
  });
@@ -467,9 +476,19 @@ var Table = class extends AbstractElementWithParent {
467
476
  /**
468
477
  * Вибрати рядок по індексу.
469
478
  * @param index починається з 0
479
+ * @param preserve boolean який изначає, чи повинні раніше вибрані рядки залишатися вибраними
480
+ */
481
+ selectRowByIndex(index, preserve = false) {
482
+ return this.getRowByIndex(index).select(preserve);
483
+ }
484
+ /**
485
+ * Вибрати масив рядків по індексу.
486
+ * @param indexes починається з 0
470
487
  */
471
- selectRowByIndex(index) {
472
- return this.getRowByIndex(index).select();
488
+ async selectRowsByIndexes(indexes) {
489
+ for (const index of indexes) {
490
+ await this.selectRowByIndex(index, true);
491
+ }
473
492
  }
474
493
  async getRows() {
475
494
  const rowsFullCssSelector = `${this.getFullCssSelector()} ${this.tableContentCssSelector} .dx-row.dx-data-row`;
@@ -559,6 +578,36 @@ var Table = class extends AbstractElementWithParent {
559
578
  await contextMenu(cellElement, this.driver);
560
579
  });
561
580
  }
581
+ /**
582
+ * Отримує значення комірки таблиці за ім'ям комірки та індексом рядка.
583
+ *
584
+ * @param {string} cellName - Ім'я комірки (поля) в таблиці
585
+ * @param {number} rowIndex - Індекс рядка (починається з 0)
586
+ * @throws {Error} Викидає помилку, якщо rowIndex не вказано
587
+ * @returns {Promise<string>} Повертає значення комірки
588
+ *
589
+ * @example
590
+ * const table = new Table(driver);
591
+ *
592
+ * // Отримання значення комірки 'Name' в першому рядку (індекс 0)
593
+ * const cellValue = await table.getCellValueByCellName('Name', 0);
594
+ * expect(cellValue).toBe('Очікуване значення');
595
+ */
596
+ getCellValueByCellName(cellName, rowIndex) {
597
+ if (rowIndex == null) {
598
+ throw new Error("Error: getCellValue(): rowIndex is required");
599
+ }
600
+ const row = this.getRowByIndex(rowIndex);
601
+ return row.getCell(cellName).getValue();
602
+ }
603
+ async waitRowsCount(count) {
604
+ await safeWait(async () => {
605
+ if (count === 0) {
606
+ }
607
+ const rows = await this.getRows();
608
+ return rows.length === count;
609
+ }, this.driver, `Rows count not equal: ${count}`);
610
+ }
562
611
  };
563
612
 
564
613
  // src/pageObjects/elements/TableToolbar/ToolbarGroupButton.ts
@@ -776,6 +825,14 @@ var ToolbarItem = class extends AbstractElementWithParent {
776
825
  return false;
777
826
  }
778
827
  }
828
+ async isPressed() {
829
+ try {
830
+ await this.init();
831
+ return this._button.isPressed();
832
+ } catch (error) {
833
+ return false;
834
+ }
835
+ }
779
836
  async getTitle() {
780
837
  await this.init();
781
838
  return await this._button.getTitle();
@@ -1335,9 +1392,9 @@ var ColumnFilter = class extends AbstractElement {
1335
1392
  };
1336
1393
 
1337
1394
  // src/pageObjects/elements/Forms/ListForm.ts
1338
- var DATAGRID_HEADER_CSS_SELECTOR = ".dx-datagrid-headers .dx-datagrid-content:not(.dx-datagrid-content-fixed)";
1339
- var DATAGRID_CONTENT_CSS_SELECTOR = ".dx-datagrid-content:not(.dx-datagrid-content-fixed)";
1340
- var FIXED_DATAGRID_CONTENT_CSS_SELECTOR = ".dx-fixed-columns .dx-datagrid-content.dx-datagrid-content-fixed";
1395
+ var DATAGRID_HEADER_CSS_SELECTOR = ".dx-datagrid-headers .dx-datagrid-content .dx-datagrid-table.dx-datagrid-table-fixed";
1396
+ var DATAGRID_CONTENT_CSS_SELECTOR = ".dx-datagrid-content .dx-datagrid-table.dx-datagrid-table-fixed";
1397
+ var FIXED_DATAGRID_CONTENT_CSS_SELECTOR = ".dx-datagrid-sticky-columns .dx-datagrid-content .dx-datagrid-table.dx-datagrid-table-fixed";
1341
1398
  var CONTEXT_MENU_CSS_SELECTOR = ".dx-datagrid";
1342
1399
  var ListForm = class extends Form {
1343
1400
  headerCssSelector;
@@ -602,7 +602,7 @@ var init_SwitchEditor = __esm({
602
602
  });
603
603
 
604
604
  // src/pageObjects/elements/Editors/TagBox.ts
605
- var import_selenium_webdriver10, TAGS_SELECTOR, DX_TAG_CONTAINER, DX_TEXTEDITOR_EMPTY2, BTN_OK_SELECTOR, TAG_BOX_LIST_ITEM_SELECTOR, TagBox;
605
+ var import_selenium_webdriver10, TAGS_SELECTOR, DX_TAG_CONTAINER, DX_TEXTEDITOR_EMPTY2, BTN_OK_SELECTOR, getSelectedOptionXpath, TagBox;
606
606
  var init_TagBox = __esm({
607
607
  "src/pageObjects/elements/Editors/TagBox.ts"() {
608
608
  "use strict";
@@ -618,7 +618,7 @@ var init_TagBox = __esm({
618
618
  DX_TAG_CONTAINER = "dx-tag-container";
619
619
  DX_TEXTEDITOR_EMPTY2 = "dx-texteditor-empty";
620
620
  BTN_OK_SELECTOR = ".dx-tagbox-popup-wrapper .dx-popup-bottom .dx-button.dx-popup-done";
621
- TAG_BOX_LIST_ITEM_SELECTOR = '.dx-tagbox-popup-wrapper .dx-list-item[aria-selected="true"]';
621
+ 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
622
  TagBox = class extends AbstractDXEditorWithInput {
623
623
  constructor(parentCssSelector, elementCssSelector, driver) {
624
624
  super(parentCssSelector, elementCssSelector, driver);
@@ -633,9 +633,15 @@ var init_TagBox = __esm({
633
633
  }
634
634
  await this.confirmSelection();
635
635
  }
636
- async waitOptionSelection() {
637
- const option = await fixElementStaleError(import_selenium_webdriver10.By.css(TAG_BOX_LIST_ITEM_SELECTOR), this.driver);
638
- await safeWait(() => option.isDisplayed(), this.driver);
636
+ async waitOptionSelection(value) {
637
+ await safeWait(
638
+ async () => {
639
+ const elements = await this.driver.findElements(import_selenium_webdriver10.By.xpath(getSelectedOptionXpath(value)));
640
+ if (elements.length === 0) return false;
641
+ return await elements[0].isDisplayed();
642
+ },
643
+ this.driver
644
+ );
639
645
  }
640
646
  async selectOption(inputEl, value, lastElement) {
641
647
  try {
@@ -644,7 +650,7 @@ var init_TagBox = __esm({
644
650
  await inputEl.sendKeys(value);
645
651
  await dropDownOptionClick(value, this.driver);
646
652
  }
647
- await this.waitOptionSelection();
653
+ await this.waitOptionSelection(value);
648
654
  if (value !== lastElement) {
649
655
  await inputEl.clear();
650
656
  }
@@ -941,7 +947,7 @@ var init_DateEditor = __esm({
941
947
  });
942
948
 
943
949
  // 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, TAG_BOX_LIST_ITEM_SELECTOR2, combinedOptionHeaderFilterDictValueXpath, dropDownHeaderFilterDictionaryOptionClick, HeaderFilterDictionary;
950
+ 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
951
  var init_HeaderFilterDictionary = __esm({
946
952
  "src/pageObjects/elements/Editors/HeaderFilterDictionary.ts"() {
947
953
  "use strict";
@@ -956,7 +962,7 @@ var init_HeaderFilterDictionary = __esm({
956
962
  DX_TEXTEDITOR_EMPTY3 = "dx-texteditor-empty";
957
963
  CUSTOM_OPTION_LIST_SELECTOR = "custom-list";
958
964
  SELECT_BOX_OPTION_TEXT_CONTAINER_CLASS2 = "d5-multi-select-item";
959
- TAG_BOX_LIST_ITEM_SELECTOR2 = '.dx-overlay-wrapper .dx-list-item[aria-selected="true"]';
965
+ TAG_BOX_LIST_ITEM_SELECTOR = '.dx-overlay-wrapper .dx-list-item[aria-selected="true"]';
960
966
  combinedOptionHeaderFilterDictValueXpath = (value) => `//div[contains(@class, '${SELECT_BOX_OPTION_TEXT_CONTAINER_CLASS2}') and contains(text(), '${value}')]`;
961
967
  dropDownHeaderFilterDictionaryOptionClick = async (optionValue, driver, dataTEST = "", delay = true) => {
962
968
  const { implicit } = await driver.manage().getTimeouts();
@@ -992,7 +998,7 @@ var init_HeaderFilterDictionary = __esm({
992
998
  }
993
999
  }
994
1000
  async waitOptionSelection() {
995
- await fixElementStaleError(import_selenium_webdriver15.By.css(TAG_BOX_LIST_ITEM_SELECTOR2), this.driver);
1001
+ await fixElementStaleError(import_selenium_webdriver15.By.css(TAG_BOX_LIST_ITEM_SELECTOR), this.driver);
996
1002
  }
997
1003
  async selectOption(inputEl, value, lastElement) {
998
1004
  try {
@@ -1136,13 +1142,14 @@ var init_createDataTestId = __esm({
1136
1142
  });
1137
1143
 
1138
1144
  // src/pageObjects/elements/AbstractButton.ts
1139
- var AbstractButton;
1145
+ var D5_BUTTON_IS_PRESSED, AbstractButton;
1140
1146
  var init_AbstractButton = __esm({
1141
1147
  "src/pageObjects/elements/AbstractButton.ts"() {
1142
1148
  "use strict";
1143
1149
  init_AbstractElementWithParent();
1144
1150
  init_actions();
1145
1151
  init_waitElementIsClickable();
1152
+ D5_BUTTON_IS_PRESSED = "d5-is-pressed";
1146
1153
  AbstractButton = class extends AbstractElementWithParent {
1147
1154
  constructor(parentCssSelector, elementCssSelector, driver) {
1148
1155
  super(parentCssSelector, elementCssSelector, driver);
@@ -1168,6 +1175,15 @@ var init_AbstractButton = __esm({
1168
1175
  return false;
1169
1176
  }
1170
1177
  }
1178
+ async isPressed() {
1179
+ try {
1180
+ const button = await this.getElement();
1181
+ const classAttribute = await button.getAttribute("class");
1182
+ return classAttribute.includes(D5_BUTTON_IS_PRESSED);
1183
+ } catch {
1184
+ return false;
1185
+ }
1186
+ }
1171
1187
  };
1172
1188
  }
1173
1189
  });
@@ -1467,6 +1483,7 @@ var init_AbstractForm = __esm({
1467
1483
  init_AbstractPage();
1468
1484
  init_FormButton();
1469
1485
  init_FormGroup();
1486
+ init_waitElementIsVisible();
1470
1487
  AbstractForm = class extends AbstractPage {
1471
1488
  containerCssSelector = "";
1472
1489
  _formName = "";
@@ -1491,7 +1508,15 @@ var init_AbstractForm = __esm({
1491
1508
  async exists() {
1492
1509
  try {
1493
1510
  let elements = await this.driver.findElements(this.containerBy);
1494
- return elements.length > 0;
1511
+ if (elements.length === 0) {
1512
+ return false;
1513
+ }
1514
+ await waitElementIsVisible_default({
1515
+ element: elements[0],
1516
+ errorMessage: "Element exists in DOM but is not visible",
1517
+ driver: this.driver
1518
+ });
1519
+ return true;
1495
1520
  } catch (error) {
1496
1521
  return false;
1497
1522
  }
@@ -1678,9 +1703,18 @@ var init_Row = __esm({
1678
1703
  getCellByTitle(title) {
1679
1704
  return this._getCell({ title });
1680
1705
  }
1681
- async select() {
1706
+ async select(preserve = false) {
1682
1707
  await staleElementAction(async () => {
1683
1708
  const rowEl = await this.getElement();
1709
+ const isSelected = (await this.getClasses()).includes(DX_SELECTION_CLASS);
1710
+ if (isSelected && !preserve) {
1711
+ await this.driver.actions({ async: true }).keyUp(import_selenium_webdriver22.Key.CONTROL).perform();
1712
+ }
1713
+ if (preserve && !isSelected) {
1714
+ await this.driver.actions({ async: true }).keyDown(import_selenium_webdriver22.Key.CONTROL).perform();
1715
+ await click(rowEl, this.driver);
1716
+ return;
1717
+ }
1684
1718
  await click(rowEl, this.driver);
1685
1719
  });
1686
1720
  await safeWait(
@@ -2013,8 +2047,8 @@ var init_AbstractDropDownMenuList = __esm({
2013
2047
  const menuItemElement = await fixElementStaleError(by, this.driver);
2014
2048
  await click(menuItemElement, this.driver);
2015
2049
  }
2016
- async getElementByPath(path, getBy, returnLastElement = false) {
2017
- let pathList = isString(path) ? [path] : path;
2050
+ async getElementByPath(path2, getBy, returnLastElement = false) {
2051
+ let pathList = isString(path2) ? [path2] : path2;
2018
2052
  let result = null;
2019
2053
  let index = 1;
2020
2054
  for (let text of pathList) {
@@ -2086,7 +2120,7 @@ var init_DXContextMenuList = __esm({
2086
2120
  async isVisible() {
2087
2121
  try {
2088
2122
  await waitElementIsVisible_default({
2089
- element: await this.driver.findElement(import_selenium_webdriver24.By.css(`.dx-overlay-wrapper .dx-contextmenu`)),
2123
+ element: await this.driver.findElement(import_selenium_webdriver24.By.css(`.dx-overlay-wrapper .dx-context-menu`)),
2090
2124
  driver: this.driver,
2091
2125
  errorMessage: "Cannot find dropdown element"
2092
2126
  });
@@ -2144,6 +2178,7 @@ var init_Table = __esm({
2144
2178
  init_FormField();
2145
2179
  init_ContextMenu();
2146
2180
  init_actions();
2181
+ init_wait();
2147
2182
  Table = class extends AbstractElementWithParent {
2148
2183
  formName;
2149
2184
  headerCssSelector;
@@ -2209,9 +2244,19 @@ var init_Table = __esm({
2209
2244
  /**
2210
2245
  * Вибрати рядок по індексу.
2211
2246
  * @param index починається з 0
2247
+ * @param preserve boolean який изначає, чи повинні раніше вибрані рядки залишатися вибраними
2212
2248
  */
2213
- selectRowByIndex(index) {
2214
- return this.getRowByIndex(index).select();
2249
+ selectRowByIndex(index, preserve = false) {
2250
+ return this.getRowByIndex(index).select(preserve);
2251
+ }
2252
+ /**
2253
+ * Вибрати масив рядків по індексу.
2254
+ * @param indexes починається з 0
2255
+ */
2256
+ async selectRowsByIndexes(indexes) {
2257
+ for (const index of indexes) {
2258
+ await this.selectRowByIndex(index, true);
2259
+ }
2215
2260
  }
2216
2261
  async getRows() {
2217
2262
  const rowsFullCssSelector = `${this.getFullCssSelector()} ${this.tableContentCssSelector} .dx-row.dx-data-row`;
@@ -2301,6 +2346,36 @@ var init_Table = __esm({
2301
2346
  await contextMenu(cellElement, this.driver);
2302
2347
  });
2303
2348
  }
2349
+ /**
2350
+ * Отримує значення комірки таблиці за ім'ям комірки та індексом рядка.
2351
+ *
2352
+ * @param {string} cellName - Ім'я комірки (поля) в таблиці
2353
+ * @param {number} rowIndex - Індекс рядка (починається з 0)
2354
+ * @throws {Error} Викидає помилку, якщо rowIndex не вказано
2355
+ * @returns {Promise<string>} Повертає значення комірки
2356
+ *
2357
+ * @example
2358
+ * const table = new Table(driver);
2359
+ *
2360
+ * // Отримання значення комірки 'Name' в першому рядку (індекс 0)
2361
+ * const cellValue = await table.getCellValueByCellName('Name', 0);
2362
+ * expect(cellValue).toBe('Очікуване значення');
2363
+ */
2364
+ getCellValueByCellName(cellName, rowIndex) {
2365
+ if (rowIndex == null) {
2366
+ throw new Error("Error: getCellValue(): rowIndex is required");
2367
+ }
2368
+ const row = this.getRowByIndex(rowIndex);
2369
+ return row.getCell(cellName).getValue();
2370
+ }
2371
+ async waitRowsCount(count) {
2372
+ await safeWait(async () => {
2373
+ if (count === 0) {
2374
+ }
2375
+ const rows = await this.getRows();
2376
+ return rows.length === count;
2377
+ }, this.driver, `Rows count not equal: ${count}`);
2378
+ }
2304
2379
  };
2305
2380
  }
2306
2381
  });
@@ -2567,6 +2642,14 @@ var init_ToolbarItem = __esm({
2567
2642
  return false;
2568
2643
  }
2569
2644
  }
2645
+ async isPressed() {
2646
+ try {
2647
+ await this.init();
2648
+ return this._button.isPressed();
2649
+ } catch (error) {
2650
+ return false;
2651
+ }
2652
+ }
2570
2653
  async getTitle() {
2571
2654
  await this.init();
2572
2655
  return await this._button.getTitle();
@@ -3210,9 +3293,9 @@ var init_ListForm = __esm({
3210
3293
  init_FormFilterField();
3211
3294
  init_FilterPanel();
3212
3295
  init_ColumnFilter();
3213
- DATAGRID_HEADER_CSS_SELECTOR = ".dx-datagrid-headers .dx-datagrid-content:not(.dx-datagrid-content-fixed)";
3214
- DATAGRID_CONTENT_CSS_SELECTOR = ".dx-datagrid-content:not(.dx-datagrid-content-fixed)";
3215
- FIXED_DATAGRID_CONTENT_CSS_SELECTOR = ".dx-fixed-columns .dx-datagrid-content.dx-datagrid-content-fixed";
3296
+ DATAGRID_HEADER_CSS_SELECTOR = ".dx-datagrid-headers .dx-datagrid-content .dx-datagrid-table.dx-datagrid-table-fixed";
3297
+ DATAGRID_CONTENT_CSS_SELECTOR = ".dx-datagrid-content .dx-datagrid-table.dx-datagrid-table-fixed";
3298
+ FIXED_DATAGRID_CONTENT_CSS_SELECTOR = ".dx-datagrid-sticky-columns .dx-datagrid-content .dx-datagrid-table.dx-datagrid-table-fixed";
3216
3299
  CONTEXT_MENU_CSS_SELECTOR = ".dx-datagrid";
3217
3300
  ListForm = class extends Form {
3218
3301
  headerCssSelector;
@@ -3297,9 +3380,9 @@ var init_TreeView = __esm({
3297
3380
  "src/pageObjects/elements/Forms/TreeView.ts"() {
3298
3381
  "use strict";
3299
3382
  init_ListForm();
3300
- TREELIST_HEADER_CSS_SELECTOR = ".dx-treelist-headers .dx-treelist-content:not(.dx-datagrid-content-fixed)";
3301
- TREELIST_CONTENT_CSS_SELECTOR = ".dx-treelist-content:not(.dx-datagrid-content-fixed)";
3302
- FIXED_TREELIST_CONTENT_CSS_SELECTOR = ".dx-fixed-columns .dx-treelist-content.dx-treelist-content-fixed";
3383
+ TREELIST_HEADER_CSS_SELECTOR = ".dx-treelist-headers .dx-treelist-content .dx-treelist-table.dx-treelist-table-fixed";
3384
+ TREELIST_CONTENT_CSS_SELECTOR = ".dx-treelist-content .dx-treelist-table.dx-treelist-table-fixed";
3385
+ FIXED_TREELIST_CONTENT_CSS_SELECTOR = ".dx-treelist-sticky-columns .dx-treelist-content .dx-treelist-table.dx-treelist-table-fixed";
3303
3386
  TreeView = class extends ListForm {
3304
3387
  constructor(driver) {
3305
3388
  super(driver);
@@ -3600,6 +3683,8 @@ init_locators();
3600
3683
 
3601
3684
  // src/utils/createDriver.ts
3602
3685
  var import_selenium_webdriver4 = require("selenium-webdriver");
3686
+ var import_node_path = __toESM(require("path"));
3687
+ var import_node_fs = __toESM(require("fs"));
3603
3688
  init_config();
3604
3689
  var import_chrome = __toESM(require("selenium-webdriver/chrome"));
3605
3690
  var import_firefox = __toESM(require("selenium-webdriver/firefox"));
@@ -3607,7 +3692,14 @@ function chromeOptions(builder, options) {
3607
3692
  const ChromeOptions = new import_chrome.default.Options();
3608
3693
  if (options.headless) {
3609
3694
  ChromeOptions.addArguments(`--headless=new`);
3695
+ ChromeOptions.addArguments(`--disable-gpu`);
3696
+ ChromeOptions.addArguments(`--disable-dev-shm-usage`);
3697
+ }
3698
+ const userDataDir = import_node_path.default.resolve("./.chrome-cache");
3699
+ if (!import_node_fs.default.existsSync(userDataDir)) {
3700
+ import_node_fs.default.mkdirSync(userDataDir, { recursive: true });
3610
3701
  }
3702
+ ChromeOptions.addArguments(`--user-data-dir=${userDataDir}`);
3611
3703
  return builder.setChromeOptions(ChromeOptions);
3612
3704
  }
3613
3705
  function firefoxOptions(builder, options) {