d5-testing-library 1.8.0-alpha.13 → 1.8.0-alpha.16

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.
@@ -213,7 +213,7 @@ var init_waitElementIsVisible = __esm({
213
213
  });
214
214
 
215
215
  // src/utils/actions.ts
216
- var click;
216
+ var click, contextMenu;
217
217
  var init_actions = __esm({
218
218
  "src/utils/actions.ts"() {
219
219
  "use strict";
@@ -226,6 +226,14 @@ var init_actions = __esm({
226
226
  const actions = driver.actions({ async: true });
227
227
  await actions.move({ origin: webElement }).click().perform();
228
228
  };
229
+ contextMenu = async (webElement, driver) => {
230
+ driver = driver ?? config().driver;
231
+ if (!await webElement.isDisplayed()) {
232
+ await driver.executeScript("arguments[0].scrollIntoView(true);", webElement);
233
+ }
234
+ const actions = driver.actions({ async: true });
235
+ await actions.move({ origin: webElement }).contextClick().perform();
236
+ };
229
237
  }
230
238
  });
231
239
 
@@ -757,37 +765,44 @@ var init_BaseDateEditor = __esm({
757
765
  super(parentCssSelector, elementCssSelector, driver);
758
766
  this.setClearStrategy(new InputClearStrategy());
759
767
  }
760
- async setDateValue(value) {
768
+ async setArrayValue(value) {
761
769
  const actions = this.driver.actions({ async: true });
762
770
  const dateField = await this.driver.findElement(import_selenium_webdriver12.By.css(`${this.getFullCssSelector()}`));
771
+ const dateInputEl = await this.getInputElement();
763
772
  const dateFieldDataTestID = await this.getDataTestId();
764
- const calendarPopoverSelector = byTestIdCssSelector(`${dateFieldDataTestID}-calendar-popover`);
773
+ const formattedDates = value.map(formatDMYDate);
774
+ const button = await dateField.findElement(import_selenium_webdriver12.By.css(`.${BTN_CALENDAR_POPOVER_OPEN_SELECTOR}`));
775
+ await click(button, this.driver);
776
+ const calendarPopoverElement = await this.driver.findElement(import_selenium_webdriver12.By.css(byTestIdCssSelector(`${dateFieldDataTestID}-calendar-popover`)));
777
+ const dateFromInput = await calendarPopoverElement.findElement(
778
+ import_selenium_webdriver12.By.css(`.${BTN_CALENDAR_POPOVER_DATE_FROM_INPUT_SELECTOR} .dx-texteditor-input`)
779
+ );
780
+ const dateToInput = await calendarPopoverElement.findElement(
781
+ import_selenium_webdriver12.By.css(`.${BTN_CALENDAR_POPOVER_DATE_TO_INPUT_SELECTOR} .dx-texteditor-input`)
782
+ );
783
+ await click(dateFromInput, this.driver);
784
+ await dateFromInput.sendKeys(formattedDates[0]);
785
+ await click(dateToInput, this.driver);
786
+ await actions.move({ origin: dateInputEl }).sendKeys(import_selenium_webdriver12.Key.HOME).perform();
787
+ await dateToInput.sendKeys(formattedDates[1]);
788
+ await actions.move({ origin: dateInputEl }).sendKeys(import_selenium_webdriver12.Key.ENTER).perform();
789
+ const btnOk = await this.driver.findElement(import_selenium_webdriver12.By.css(`.${BTN_SAVE_SELECTOR}`));
790
+ await click(btnOk, this.driver);
791
+ }
792
+ async setSingleValue(value) {
793
+ const actions = this.driver.actions({ async: true });
794
+ const formattedDate = formatDMYDate(value);
765
795
  const dateInputEl = await this.getInputElement();
766
- await dateInputEl.clear();
796
+ await click(dateInputEl, this.driver);
797
+ await actions.move({ origin: dateInputEl }).sendKeys(import_selenium_webdriver12.Key.HOME).perform();
798
+ await actions.move({ origin: dateInputEl }).sendKeys(formattedDate, import_selenium_webdriver12.Key.ENTER).perform();
799
+ }
800
+ async setDateValue(value) {
801
+ await this.clear();
767
802
  if (Array.isArray(value)) {
768
- const formattedDates = value.map(formatDMYDate);
769
- const button = await dateField.findElement(import_selenium_webdriver12.By.css(`.${BTN_CALENDAR_POPOVER_OPEN_SELECTOR}`));
770
- await button.click();
771
- const calendarPopoverElement = await this.driver.findElement(import_selenium_webdriver12.By.css(calendarPopoverSelector));
772
- const dateFromInput = await calendarPopoverElement.findElement(
773
- import_selenium_webdriver12.By.css(`.${BTN_CALENDAR_POPOVER_DATE_FROM_INPUT_SELECTOR} .dx-texteditor-input`)
774
- );
775
- const dateToInput = await calendarPopoverElement.findElement(
776
- import_selenium_webdriver12.By.css(`.${BTN_CALENDAR_POPOVER_DATE_TO_INPUT_SELECTOR} .dx-texteditor-input`)
777
- );
778
- await dateFromInput.click();
779
- await dateFromInput.sendKeys(formattedDates[0]);
780
- await dateToInput.click();
781
- await actions.move({ origin: dateInputEl }).sendKeys(import_selenium_webdriver12.Key.HOME).perform();
782
- await dateToInput.sendKeys(formattedDates[1]);
783
- await actions.move({ origin: dateInputEl }).sendKeys(import_selenium_webdriver12.Key.ENTER).perform();
784
- const btnOk = await this.driver.findElement(import_selenium_webdriver12.By.css(`.${BTN_SAVE_SELECTOR}`));
785
- await btnOk.click();
803
+ await this.setArrayValue(value);
786
804
  } else {
787
- const formattedDate = formatDMYDate(value);
788
- await click(dateInputEl, this.driver);
789
- await actions.move({ origin: dateInputEl }).sendKeys(import_selenium_webdriver12.Key.HOME).perform();
790
- await actions.move({ origin: dateInputEl }).sendKeys(formattedDate, import_selenium_webdriver12.Key.ENTER).perform();
805
+ await this.setSingleValue(value);
791
806
  }
792
807
  }
793
808
  };
@@ -878,15 +893,14 @@ var init_DateEditor = __esm({
878
893
  init_types();
879
894
  DateEditor = class extends AbstractDXEditorWithInput {
880
895
  editorInstance = null;
881
- initPromise;
882
- constructor(parentCssSelector, elementCssSelector, driver) {
883
- super(parentCssSelector, elementCssSelector, driver);
884
- this.initPromise = this.init(parentCssSelector, elementCssSelector, driver);
885
- }
886
- async init(parentCssSelector, elementCssSelector, driver) {
887
- await this.updateEditorInstance(parentCssSelector, elementCssSelector, driver);
896
+ async init() {
897
+ if (this.editorInstance) {
898
+ return this.editorInstance;
899
+ }
900
+ await this.setEditorInstance();
888
901
  }
889
- async updateEditorInstance(parentCssSelector, elementCssSelector, driver) {
902
+ async setEditorInstance() {
903
+ const { parentCssSelector, elementCssSelector, driver } = this;
890
904
  const elementInstance = new AbstractFormElement(parentCssSelector, elementCssSelector, driver);
891
905
  const classString = await elementInstance.getClasses();
892
906
  switch (true) {
@@ -900,25 +914,14 @@ var init_DateEditor = __esm({
900
914
  this.editorInstance = new SingleDateEditor(parentCssSelector, elementCssSelector, driver);
901
915
  }
902
916
  }
903
- async ensureInitialized() {
904
- if (!this.editorInstance) {
905
- await this.initPromise;
906
- }
907
- }
908
917
  async setValue(value) {
909
- await this.ensureInitialized();
910
- if (this.editorInstance) {
911
- await this.editorInstance.setValue(value);
912
- return await this.updateEditorInstance(this.parentCssSelector, this.elementCssSelector, this.driver);
913
- }
914
- throw new Error("Editor instance is not initialized.");
918
+ await this.init();
919
+ await this.editorInstance.setValue(value);
920
+ await this.setEditorInstance();
915
921
  }
916
922
  async getValue() {
917
- await this.ensureInitialized();
918
- if (this.editorInstance) {
919
- return this.editorInstance.getValue();
920
- }
921
- throw new Error("Editor instance is not initialized.");
923
+ await this.init();
924
+ return this.editorInstance.getValue();
922
925
  }
923
926
  };
924
927
  }
@@ -1125,40 +1128,44 @@ var init_createDataTestId = __esm({
1125
1128
 
1126
1129
  // src/utils/waitElementIsClickable.ts
1127
1130
  async function waitElementIsClickable({
1128
- element,
1129
1131
  timeout,
1130
1132
  errorMessage,
1131
- driver
1133
+ driver,
1134
+ ...rest
1132
1135
  }) {
1133
1136
  driver = driver ?? config().driver;
1134
1137
  await wait(async () => {
1135
- const isDisabled = await element.getCssValue("pointer-events") === "none";
1136
- return await element.isDisplayed() && !isDisabled;
1138
+ const searchedElement = "by" in rest ? await fixElementStaleError(rest.by, driver) : rest.element;
1139
+ const isDisabled = await searchedElement.getCssValue("pointer-events") === "none";
1140
+ return await searchedElement.isDisplayed() && !isDisabled;
1137
1141
  }, driver, errorMessage, timeout ?? config().timeout);
1138
1142
  }
1143
+ var waitElementIsClickable_default;
1139
1144
  var init_waitElementIsClickable = __esm({
1140
1145
  "src/utils/waitElementIsClickable.ts"() {
1141
1146
  "use strict";
1142
1147
  init_config();
1143
1148
  init_wait();
1149
+ init_fixElementStaleError();
1150
+ waitElementIsClickable_default = waitElementIsClickable;
1144
1151
  }
1145
1152
  });
1146
1153
 
1147
- // src/pageObjects/elements/TableToolbar/AbstractButton.ts
1154
+ // src/pageObjects/elements/AbstractButton.ts
1148
1155
  var AbstractButton;
1149
1156
  var init_AbstractButton = __esm({
1150
- "src/pageObjects/elements/TableToolbar/AbstractButton.ts"() {
1157
+ "src/pageObjects/elements/AbstractButton.ts"() {
1151
1158
  "use strict";
1159
+ init_AbstractElementWithParent();
1152
1160
  init_actions();
1153
1161
  init_waitElementIsClickable();
1154
- init_AbstractElementWithParent();
1155
1162
  AbstractButton = class extends AbstractElementWithParent {
1156
1163
  constructor(parentCssSelector, elementCssSelector, driver) {
1157
1164
  super(parentCssSelector, elementCssSelector, driver);
1158
1165
  }
1159
1166
  async click() {
1160
1167
  const button = await this.getElement();
1161
- await waitElementIsClickable({
1168
+ await waitElementIsClickable_default({
1162
1169
  element: button,
1163
1170
  errorMessage: this.buttonNotDisplayedError(),
1164
1171
  driver: this.driver
@@ -1658,6 +1665,13 @@ var init_Row = __esm({
1658
1665
  index;
1659
1666
  getColumnBy;
1660
1667
  fixedTableContentCssSelector;
1668
+ /**
1669
+ * @param parentCssSelector
1670
+ * @param fixedTableContentCssSelector
1671
+ * @param index починається з 0 (в getCssRowByIndexSelector додається +1)
1672
+ * @param driver
1673
+ * @param getColumnBy
1674
+ */
1661
1675
  constructor(parentCssSelector, fixedTableContentCssSelector, index, driver, getColumnBy) {
1662
1676
  super(parentCssSelector, getCssRowByIndexSelector(index), driver);
1663
1677
  this.index = index;
@@ -1831,7 +1845,7 @@ var init_EditorButton = __esm({
1831
1845
  }
1832
1846
  async click() {
1833
1847
  const button = await this.getElement();
1834
- await waitElementIsClickable({
1848
+ await waitElementIsClickable_default({
1835
1849
  element: button,
1836
1850
  errorMessage: this.buttonNotDisplayedError(),
1837
1851
  driver: this.driver
@@ -1952,26 +1966,190 @@ var init_FormField = __esm({
1952
1966
  }
1953
1967
  });
1954
1968
 
1969
+ // src/utils/typesUtil.ts
1970
+ var types, type, isArray, isString;
1971
+ var init_typesUtil = __esm({
1972
+ "src/utils/typesUtil.ts"() {
1973
+ "use strict";
1974
+ types = {
1975
+ "[object Array]": "array",
1976
+ "[object Date]": "date",
1977
+ "[object Object]": "object",
1978
+ "[object String]": "string",
1979
+ "[object Null]": "null"
1980
+ };
1981
+ type = function(object) {
1982
+ const typeOfObject = Object.prototype.toString.call(object);
1983
+ return typeof object === "object" ? types[typeOfObject] || "object" : typeof object;
1984
+ };
1985
+ isArray = function(value) {
1986
+ return type(value) === "array";
1987
+ };
1988
+ isString = function(object) {
1989
+ return typeof object === "string";
1990
+ };
1991
+ }
1992
+ });
1993
+
1994
+ // src/pageObjects/elements/AbstractDropDownMenuList.ts
1995
+ var AbstractDropDownMenuList;
1996
+ var init_AbstractDropDownMenuList = __esm({
1997
+ "src/pageObjects/elements/AbstractDropDownMenuList.ts"() {
1998
+ "use strict";
1999
+ init_AbstractElementWithParent();
2000
+ init_actions();
2001
+ init_waitElementIsClickable();
2002
+ init_fixElementStaleError();
2003
+ init_typesUtil();
2004
+ AbstractDropDownMenuList = class extends AbstractElementWithParent {
2005
+ buttonNotDisplayedError(name) {
2006
+ return `Menu button ${name} cannot be clicked. It is not displayed or it is disabled`;
2007
+ }
2008
+ async clickItemBy(errorMessage, by) {
2009
+ await waitElementIsClickable_default({
2010
+ errorMessage,
2011
+ driver: this.driver,
2012
+ by
2013
+ });
2014
+ const menuItemElement = await fixElementStaleError(by, this.driver);
2015
+ await click(menuItemElement, this.driver);
2016
+ }
2017
+ async clickItemByPath(path, getBy) {
2018
+ let pathList = isString(path) ? [path] : path;
2019
+ for (let text of pathList) {
2020
+ await this.clickItemBy(this.buttonNotDisplayedError(text), getBy(text));
2021
+ }
2022
+ }
2023
+ clickButton(name) {
2024
+ return this.clickItemByPath(name, this.getButtonNameBy.bind(this));
2025
+ }
2026
+ clickButtonByTitle(title) {
2027
+ return this.clickItemByPath(title, this.getButtonTitleBy.bind(this));
2028
+ }
2029
+ isVisible() {
2030
+ return Promise.resolve(true);
2031
+ }
2032
+ };
2033
+ }
2034
+ });
2035
+
2036
+ // src/utils/cssToXPath.ts
2037
+ function cssClassesToXPath(classNames) {
2038
+ const classNamesList = classNames.split(".").filter((className) => !!className);
2039
+ const chained = classNamesList.map((className) => `contains(@class, "${className}")`).join(" and ");
2040
+ return `[${chained}]`;
2041
+ }
2042
+ var init_cssToXPath = __esm({
2043
+ "src/utils/cssToXPath.ts"() {
2044
+ "use strict";
2045
+ }
2046
+ });
2047
+
2048
+ // src/pageObjects/elements/DXContextMenuList.ts
2049
+ var import_selenium_webdriver24, CONTEXT_MENU_CLASS, CONTEXT_MENU_ITEM_TEXT_CLASS, DXContextMenuList;
2050
+ var init_DXContextMenuList = __esm({
2051
+ "src/pageObjects/elements/DXContextMenuList.ts"() {
2052
+ "use strict";
2053
+ init_AbstractDropDownMenuList();
2054
+ import_selenium_webdriver24 = require("selenium-webdriver");
2055
+ init_cssToXPath();
2056
+ init_waitElementIsVisible();
2057
+ CONTEXT_MENU_CLASS = "dx-context-menu";
2058
+ CONTEXT_MENU_ITEM_TEXT_CLASS = "dx-menu-item-text";
2059
+ DXContextMenuList = class extends AbstractDropDownMenuList {
2060
+ /**
2061
+ * @param parentCssSelector
2062
+ * @param classNames - Список класів. Починається з крапки
2063
+ * @param driver
2064
+ */
2065
+ constructor(parentCssSelector, classNames, driver) {
2066
+ super(parentCssSelector, `.${CONTEXT_MENU_CLASS}${classNames}`, driver);
2067
+ }
2068
+ getButtonTitleBy(title) {
2069
+ const buttonByTextXpath2 = (text) => `//span[contains(@class, "${CONTEXT_MENU_ITEM_TEXT_CLASS}") and contains(text(), "${text}")]`;
2070
+ const xpath = "//div" + cssClassesToXPath(this.elementCssSelector) + buttonByTextXpath2(title);
2071
+ return import_selenium_webdriver24.By.xpath(xpath);
2072
+ }
2073
+ async isVisible() {
2074
+ try {
2075
+ await waitElementIsVisible({
2076
+ element: await this.driver.findElement(import_selenium_webdriver24.By.css(`.dx-overlay-wrapper .dx-contextmenu`)),
2077
+ driver: this.driver,
2078
+ errorMessage: "Cannot find dropdown element"
2079
+ });
2080
+ } catch {
2081
+ return false;
2082
+ }
2083
+ }
2084
+ };
2085
+ }
2086
+ });
2087
+
2088
+ // src/pageObjects/elements/Table/elements/ContextMenu.ts
2089
+ var ContextMenu;
2090
+ var init_ContextMenu = __esm({
2091
+ "src/pageObjects/elements/Table/elements/ContextMenu.ts"() {
2092
+ "use strict";
2093
+ init_DXContextMenuList();
2094
+ init_locators();
2095
+ ContextMenu = class extends DXContextMenuList {
2096
+ _formName;
2097
+ _initFn;
2098
+ constructor(cssClass, formName, driver) {
2099
+ super("", cssClass, driver);
2100
+ this._formName = formName;
2101
+ }
2102
+ setInit(cb) {
2103
+ this._initFn = cb;
2104
+ return this;
2105
+ }
2106
+ getButtonNameBy(name) {
2107
+ return byTestId(`cm-${this._formName}-${name}`);
2108
+ }
2109
+ async clickButtonByTitle(title) {
2110
+ await this._initFn?.();
2111
+ await super.clickButtonByTitle(title);
2112
+ }
2113
+ async clickButton(name) {
2114
+ await this._initFn?.();
2115
+ await super.clickButton(name);
2116
+ }
2117
+ };
2118
+ }
2119
+ });
2120
+
1955
2121
  // src/pageObjects/elements/Table/Table.ts
1956
- var import_selenium_webdriver24, Table;
2122
+ var import_selenium_webdriver25, Table;
1957
2123
  var init_Table = __esm({
1958
2124
  "src/pageObjects/elements/Table/Table.ts"() {
1959
2125
  "use strict";
1960
- import_selenium_webdriver24 = require("selenium-webdriver");
2126
+ import_selenium_webdriver25 = require("selenium-webdriver");
1961
2127
  init_createDataTestId();
1962
2128
  init_AbstractElementWithParent();
1963
2129
  init_Row();
1964
2130
  init_Column();
1965
2131
  init_FormField();
2132
+ init_ContextMenu();
2133
+ init_actions();
1966
2134
  Table = class extends AbstractElementWithParent {
1967
2135
  formName;
1968
2136
  headerCssSelector;
2137
+ contextMenuCssSelector;
1969
2138
  fixedTableContentCssSelector;
1970
2139
  tableContentCssSelector;
1971
- constructor(parentCssSelector, headerCssSelector, tableContentCssSelector, fixedTableContentCssSelector, formName, driver) {
2140
+ constructor({
2141
+ parentCssSelector,
2142
+ contextMenuCssSelector,
2143
+ tableContentCssSelector,
2144
+ headerCssSelector,
2145
+ fixedTableContentCssSelector,
2146
+ formName,
2147
+ driver
2148
+ }) {
1972
2149
  super(parentCssSelector, `#${createTableId(formName)}`, driver);
1973
2150
  this.formName = formName;
1974
2151
  this.headerCssSelector = headerCssSelector;
2152
+ this.contextMenuCssSelector = contextMenuCssSelector;
1975
2153
  this.fixedTableContentCssSelector = fixedTableContentCssSelector;
1976
2154
  this.tableContentCssSelector = tableContentCssSelector;
1977
2155
  }
@@ -1981,10 +2159,18 @@ var init_Table = __esm({
1981
2159
  }
1982
2160
  return this.getColumnByName(args.name);
1983
2161
  };
2162
+ /**
2163
+ * Отримати рядок по індексу.
2164
+ * @param index починається з 0
2165
+ */
1984
2166
  getRowByIndex(index) {
1985
2167
  return new Row(this.getFullCssSelector(), this.fixedTableContentCssSelector, index, this.driver, this.getColumnBy);
1986
2168
  }
2169
+ /**
2170
+ * @param index починається з 0
2171
+ */
1987
2172
  getColumnByIndex(index) {
2173
+ this.getRowByIndex(index);
1988
2174
  return new Column({
1989
2175
  parentCssSelector: this.getFullCssSelector(),
1990
2176
  driver: this.driver,
@@ -2007,12 +2193,16 @@ var init_Table = __esm({
2007
2193
  driver: this.driver
2008
2194
  });
2009
2195
  };
2196
+ /**
2197
+ * Вибрати рядок по індексу.
2198
+ * @param index починається з 0
2199
+ */
2010
2200
  selectRowByIndex(index) {
2011
2201
  return this.getRowByIndex(index).select();
2012
2202
  }
2013
2203
  async getRows() {
2014
2204
  const rowsFullCssSelector = `${this.getFullCssSelector()} ${this.tableContentCssSelector} .dx-row.dx-data-row`;
2015
- const rows = await this.driver.findElements(import_selenium_webdriver24.By.css(rowsFullCssSelector));
2205
+ const rows = await this.driver.findElements(import_selenium_webdriver25.By.css(rowsFullCssSelector));
2016
2206
  const result = [];
2017
2207
  rows.forEach((_, index) => {
2018
2208
  const newRow = new Row(
@@ -2028,7 +2218,7 @@ var init_Table = __esm({
2028
2218
  }
2029
2219
  async getColumns() {
2030
2220
  const columns = await this.driver.findElements(
2031
- import_selenium_webdriver24.By.css(`${this.getFullCssSelector()} ${this.headerCssSelector} td[role="columnheader"] .header-template-text`)
2221
+ import_selenium_webdriver25.By.css(`${this.getFullCssSelector()} ${this.headerCssSelector} td[role="columnheader"] .header-template-text`)
2032
2222
  );
2033
2223
  const result = [];
2034
2224
  columns.forEach((_, index) => {
@@ -2054,6 +2244,50 @@ var init_Table = __esm({
2054
2244
  field(name) {
2055
2245
  return new FormField(this.getFullCssSelector(), this.formName, name, this.driver);
2056
2246
  }
2247
+ /**
2248
+ * Возвращает список строк которые выделены
2249
+ * @returns Row[]
2250
+ * @example
2251
+ * const form = new MyForm();
2252
+ * //...
2253
+ * await form.getSelectedRows();
2254
+ */
2255
+ async getSelectedRows() {
2256
+ const rows = await this.getRows();
2257
+ let result = [];
2258
+ for (const row of rows) {
2259
+ if (await row.isSelected()) {
2260
+ }
2261
+ result.push(row);
2262
+ }
2263
+ return result;
2264
+ }
2265
+ /**
2266
+ * Вызывает контекстное меню в области с данными.
2267
+ * @param fieldName - имя поля
2268
+ * @param [rowIndex] - индекс строки. Если значение не передано, то по умолчанию контекстное меню будет вызвано на первой выделенной строке.
2269
+ * @throws {Error} Если нет выделенных строк, то выбросит исключение.
2270
+ * @example
2271
+ * const form = new MyForm();
2272
+ * //...
2273
+ * await form.contextMenu('FieldName').clickButton('OpenFormButton');
2274
+ * // or
2275
+ * await form.contextMenu('FieldName', 3).clickButton(['Group', 'ButtonInGroup']);
2276
+ */
2277
+ contextMenu(fieldName, rowIndex) {
2278
+ return new ContextMenu(this.contextMenuCssSelector, this.formName, this.driver).setInit(async () => {
2279
+ let row;
2280
+ if (rowIndex != null) {
2281
+ row = this.getRowByIndex(rowIndex);
2282
+ } else {
2283
+ [row] = await this.getSelectedRows();
2284
+ }
2285
+ if (!row)
2286
+ throw new Error("No row available row for context menu");
2287
+ const cellElement = await row.getCell(fieldName).getElement();
2288
+ await contextMenu(cellElement, this.driver);
2289
+ });
2290
+ }
2057
2291
  };
2058
2292
  }
2059
2293
  });
@@ -2097,103 +2331,73 @@ var init_ToolbarButton = __esm({
2097
2331
  }
2098
2332
  });
2099
2333
 
2100
- // src/utils/typesUtil.ts
2101
- var types, type, isArray, isString;
2102
- var init_typesUtil = __esm({
2103
- "src/utils/typesUtil.ts"() {
2334
+ // src/pageObjects/elements/AbstractDropDownMenuButton.ts
2335
+ var AbstractDropDownMenuButton;
2336
+ var init_AbstractDropDownMenuButton = __esm({
2337
+ "src/pageObjects/elements/AbstractDropDownMenuButton.ts"() {
2104
2338
  "use strict";
2105
- types = {
2106
- "[object Array]": "array",
2107
- "[object Date]": "date",
2108
- "[object Object]": "object",
2109
- "[object String]": "string",
2110
- "[object Null]": "null"
2111
- };
2112
- type = function(object) {
2113
- const typeOfObject = Object.prototype.toString.call(object);
2114
- return typeof object === "object" ? types[typeOfObject] || "object" : typeof object;
2115
- };
2116
- isArray = function(value) {
2117
- return type(value) === "array";
2118
- };
2119
- isString = function(object) {
2120
- return typeof object === "string";
2339
+ init_AbstractElementWithParent();
2340
+ init_actions();
2341
+ AbstractDropDownMenuButton = class extends AbstractElementWithParent {
2342
+ _list;
2343
+ constructor(parentCssSelector, elementCssSelector, list, driver) {
2344
+ super(parentCssSelector, elementCssSelector, driver);
2345
+ this._list = list;
2346
+ }
2347
+ async openDropdownMenu() {
2348
+ const dropdown = await this.getElement();
2349
+ await click(dropdown, this.driver);
2350
+ await this._list.isVisible();
2351
+ }
2352
+ async clickButton(name) {
2353
+ await this.openDropdownMenu();
2354
+ await this._list.clickButton(name);
2355
+ }
2356
+ async clickButtonByTitle(title) {
2357
+ await this.openDropdownMenu();
2358
+ await this._list.clickButtonByTitle(title);
2359
+ }
2121
2360
  };
2122
2361
  }
2123
2362
  });
2124
2363
 
2125
2364
  // src/pageObjects/elements/TableToolbar/ToolbarMenu.ts
2126
- var import_selenium_webdriver25, SPINDOWN_CLASS, CONTEXT_MENU_CLASS, buttonGroupItemSelector, getFullCssSelector, buttonByTextXpath, ToolbarMenu;
2365
+ var SPINDOWN_CLASS, buttonGroupItemSelector, getFullCssSelector, ToolbarMenuList, ToolbarMenu;
2127
2366
  var init_ToolbarMenu = __esm({
2128
2367
  "src/pageObjects/elements/TableToolbar/ToolbarMenu.ts"() {
2129
2368
  "use strict";
2130
- import_selenium_webdriver25 = require("selenium-webdriver");
2131
2369
  init_typesUtil();
2132
- init_AbstractElementWithParent();
2133
2370
  init_locators();
2134
- init_actions();
2135
- init_waitElementIsClickable();
2136
- init_fixElementStaleError();
2137
- init_wait();
2371
+ init_AbstractDropDownMenuButton();
2372
+ init_DXContextMenuList();
2138
2373
  SPINDOWN_CLASS = ".dx-icon-spindown";
2139
- CONTEXT_MENU_CLASS = "dx-context-menu";
2140
2374
  buttonGroupItemSelector = (formName, name) => byTestIdCssSelector(`ftb-${formName}-${name}`);
2141
2375
  getFullCssSelector = (formName, name) => `${buttonGroupItemSelector(formName, name)} ${SPINDOWN_CLASS}`;
2142
- buttonByTextXpath = (text) => `//div[contains(@class, '${CONTEXT_MENU_CLASS}')]//span[contains(@class, 'dx-menu-item-text') and text()='${text}']`;
2143
- ToolbarMenu = class extends AbstractElementWithParent {
2376
+ ToolbarMenuList = class extends DXContextMenuList {
2144
2377
  _formName;
2145
- constructor(parentCssSelector, formName, name, driver) {
2146
- super(parentCssSelector, getFullCssSelector(formName, name), driver);
2378
+ constructor(parentCssSelector, elementCssSelector, formName, driver) {
2379
+ super(parentCssSelector, elementCssSelector, driver);
2147
2380
  this._formName = formName;
2148
2381
  }
2149
- async openDropdownMenu() {
2150
- await wait(
2151
- async () => {
2152
- const dropdown = await this.getElement();
2153
- await click(dropdown, this.driver);
2154
- try {
2155
- const contextMenu = this.driver.findElement(import_selenium_webdriver25.By.css(`.dx-overlay-wrapper .${CONTEXT_MENU_CLASS}`));
2156
- return await contextMenu.isDisplayed() && await contextMenu.isEnabled();
2157
- } catch (_) {
2158
- return false;
2159
- }
2160
- },
2161
- this.driver,
2162
- `Cannot find dropdown element`
2163
- );
2164
- }
2165
- getCssSelectorToButton(name) {
2382
+ getButtonNameBy(name) {
2166
2383
  return byTestId(`ftb-${this._formName}-${name}`);
2167
2384
  }
2168
- buttonNotDisplayedError(name) {
2169
- return `Toolbar menu button ${name} cannot be clicked. It is not displayed or it is disabled`;
2170
- }
2171
- async goToButton(name, by) {
2172
- const toolbarMenuItem = await fixElementStaleError(by, this.driver);
2173
- await waitElementIsClickable({
2174
- element: toolbarMenuItem,
2175
- errorMessage: this.buttonNotDisplayedError(name),
2176
- driver: this.driver
2177
- });
2178
- await click(toolbarMenuItem, this.driver);
2385
+ };
2386
+ ToolbarMenu = class extends AbstractDropDownMenuButton {
2387
+ constructor(parentCssSelector, formName, name, driver) {
2388
+ const fullSelector = getFullCssSelector(formName, name);
2389
+ const list = new ToolbarMenuList(parentCssSelector, ".toolbar-dropdown-context-menu", formName, driver);
2390
+ super(parentCssSelector, fullSelector, list, driver);
2179
2391
  }
2180
2392
  async clickButton(name) {
2181
- await this.openDropdownMenu();
2182
2393
  if (!isString(name) && !isArray(name))
2183
2394
  throw new Error(`"name" must be a string or array of string`);
2184
- let lName = isString(name) ? [name] : name;
2185
- for (let n of lName) {
2186
- await this.goToButton(n, this.getCssSelectorToButton(n));
2187
- }
2395
+ await super.clickButton(name);
2188
2396
  }
2189
2397
  async clickButtonByTitle(title) {
2190
- await this.openDropdownMenu();
2191
2398
  if (!isString(title) && !isArray(title))
2192
2399
  throw new Error(`"title" must be a string or array of string`);
2193
- let lTitle = isString(title) ? [title] : title;
2194
- for (let t of lTitle) {
2195
- await this.goToButton(t, import_selenium_webdriver25.By.xpath(buttonByTextXpath(t)));
2196
- }
2400
+ await super.clickButtonByTitle(title);
2197
2401
  }
2198
2402
  };
2199
2403
  }
@@ -2314,7 +2518,7 @@ var init_FilterOperation = __esm({
2314
2518
  }
2315
2519
  async initOperationWidget() {
2316
2520
  const widgetButtonEl = await this.getElement();
2317
- await waitElementIsClickable({
2521
+ await waitElementIsClickable_default({
2318
2522
  element: widgetButtonEl,
2319
2523
  errorMessage: "Widget operation is not clickable",
2320
2524
  driver: this.driver
@@ -2873,7 +3077,7 @@ var ListForm_exports = {};
2873
3077
  __export(ListForm_exports, {
2874
3078
  default: () => ListForm
2875
3079
  });
2876
- var DATAGRID_HEADER_CSS_SELECTOR, DATAGRID_CONTENT_CSS_SELECTOR, FIXED_DATAGRID_CONTENT_CSS_SELECTOR, ListForm;
3080
+ var DATAGRID_HEADER_CSS_SELECTOR, DATAGRID_CONTENT_CSS_SELECTOR, FIXED_DATAGRID_CONTENT_CSS_SELECTOR, CONTEXT_MENU_CSS_SELECTOR, ListForm;
2877
3081
  var init_ListForm = __esm({
2878
3082
  "src/pageObjects/elements/Forms/ListForm.ts"() {
2879
3083
  "use strict";
@@ -2886,16 +3090,19 @@ var init_ListForm = __esm({
2886
3090
  DATAGRID_HEADER_CSS_SELECTOR = ".dx-datagrid-headers .dx-datagrid-content:not(.dx-datagrid-content-fixed)";
2887
3091
  DATAGRID_CONTENT_CSS_SELECTOR = ".dx-datagrid-content:not(.dx-datagrid-content-fixed)";
2888
3092
  FIXED_DATAGRID_CONTENT_CSS_SELECTOR = ".dx-fixed-columns .dx-datagrid-content.dx-datagrid-content-fixed";
3093
+ CONTEXT_MENU_CSS_SELECTOR = ".dx-datagrid";
2889
3094
  ListForm = class extends Form {
2890
3095
  headerCssSelector;
2891
3096
  fixedTableContentCssSelector;
2892
3097
  tableContentCssSelector;
3098
+ contextMenuCssSelector;
2893
3099
  constructor(driver) {
2894
3100
  super(driver);
2895
3101
  this.popupContainerCssSelector = `.popup.form-inline-${this.formName}`;
2896
3102
  this.headerCssSelector = DATAGRID_HEADER_CSS_SELECTOR;
2897
3103
  this.fixedTableContentCssSelector = FIXED_DATAGRID_CONTENT_CSS_SELECTOR;
2898
3104
  this.tableContentCssSelector = DATAGRID_CONTENT_CSS_SELECTOR;
3105
+ this.contextMenuCssSelector = CONTEXT_MENU_CSS_SELECTOR;
2899
3106
  }
2900
3107
  /**
2901
3108
  * Находит таблицу
@@ -2906,12 +3113,15 @@ var init_ListForm = __esm({
2906
3113
  */
2907
3114
  table() {
2908
3115
  return new Table(
2909
- this.containerCssSelector,
2910
- this.headerCssSelector,
2911
- this.tableContentCssSelector,
2912
- this.fixedTableContentCssSelector,
2913
- this.formName,
2914
- this.driver
3116
+ {
3117
+ parentCssSelector: this.containerCssSelector,
3118
+ headerCssSelector: this.headerCssSelector,
3119
+ fixedTableContentCssSelector: this.fixedTableContentCssSelector,
3120
+ formName: this.formName,
3121
+ driver: this.driver,
3122
+ contextMenuCssSelector: this.contextMenuCssSelector,
3123
+ tableContentCssSelector: this.tableContentCssSelector
3124
+ }
2915
3125
  );
2916
3126
  }
2917
3127
  /**
@@ -2970,9 +3180,10 @@ var init_TreeView = __esm({
2970
3180
  TreeView = class extends ListForm {
2971
3181
  constructor(driver) {
2972
3182
  super(driver);
2973
- this.popupContainerCssSelector = `.popup.wrapper-tree-view-${this.formName}`;
3183
+ this.popupContainerCssSelector = `.popup.tree-view-${this.formName}`;
2974
3184
  this.headerCssSelector = TREELIST_HEADER_CSS_SELECTOR;
2975
3185
  this.fixedTableContentCssSelector = FIXED_TREELIST_CONTENT_CSS_SELECTOR;
3186
+ this.contextMenuCssSelector = ".dx-treelist-container";
2976
3187
  this.tableContentCssSelector = TREELIST_CONTENT_CSS_SELECTOR;
2977
3188
  }
2978
3189
  };
@@ -3044,6 +3255,11 @@ var init_Form = __esm({
3044
3255
  async getTitleText() {
3045
3256
  if (await this.isModal()) {
3046
3257
  const titleEl2 = await this.driver.findElement(import_selenium_webdriver29.By.css(`${this.popupContainerCssSelector} .popup-title`));
3258
+ await waitElementIsVisible({
3259
+ element: titleEl2,
3260
+ driver: this.driver,
3261
+ errorMessage: `Form title element is not visible`
3262
+ });
3047
3263
  return titleEl2.getText();
3048
3264
  }
3049
3265
  let titleEl = await this.driver.findElement(import_selenium_webdriver29.By.className("main-toolbar-form-title"));
@@ -3190,6 +3406,7 @@ __export(src_exports, {
3190
3406
  byTestIdCssSelector: () => byTestIdCssSelector,
3191
3407
  click: () => click,
3192
3408
  config: () => config,
3409
+ contextMenu: () => contextMenu,
3193
3410
  createDriver: () => createDriver,
3194
3411
  editorFactory: () => editorFactory,
3195
3412
  elementIsNotPresent: () => elementIsNotPresent,
@@ -3477,7 +3694,7 @@ var DIALOG_CLASS = ".d5-dialog";
3477
3694
  var DIALOG_TITLE_CLASS = ".dialog__title";
3478
3695
  var DIALOG_TEXT_CLASS = ".dialog__text";
3479
3696
  var DIALOG_BUTTONS_PANEL_CLASS = ".dialog__buttons-panel";
3480
- var buttonByTextXpath2 = (text) => `.//span[contains(@class, "dx-button-text") and contains(text(), "${text}")]`;
3697
+ var buttonByTextXpath = (text) => `.//span[contains(@class, "dx-button-text") and contains(text(), "${text}")]`;
3481
3698
  var DialogButton = class extends AbstractButton {
3482
3699
  text;
3483
3700
  constructor(parentCssSelector, text, driver) {
@@ -3486,7 +3703,7 @@ var DialogButton = class extends AbstractButton {
3486
3703
  }
3487
3704
  async getElement() {
3488
3705
  const panel = await super.getElement();
3489
- return panel.findElement(import_selenium_webdriver31.By.xpath(buttonByTextXpath2(this.text)));
3706
+ return panel.findElement(import_selenium_webdriver31.By.xpath(buttonByTextXpath(this.text)));
3490
3707
  }
3491
3708
  buttonNotDisplayedError() {
3492
3709
  return `Dialog button ${this.text} cannot be clicked. It is not displayed or it is disabled`;
@@ -3538,6 +3755,7 @@ var Dialog = class extends AbstractElement {
3538
3755
  byTestIdCssSelector,
3539
3756
  click,
3540
3757
  config,
3758
+ contextMenu,
3541
3759
  createDriver,
3542
3760
  editorFactory,
3543
3761
  elementIsNotPresent,