d5-testing-library 1.3.0 → 1.3.1

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.
@@ -31,6 +31,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  var src_exports = {};
32
32
  __export(src_exports, {
33
33
  AbstractPage: () => AbstractPage,
34
+ Dialog: () => Dialog,
34
35
  FilterPanel: () => FilterPanel,
35
36
  FormEdit: () => FormEdit,
36
37
  FormField: () => FormField,
@@ -48,6 +49,7 @@ __export(src_exports, {
48
49
  createDriver: () => createDriver,
49
50
  editorFactory: () => editorFactory,
50
51
  elementIsNotPresent: () => elementIsNotPresent,
52
+ readonlyLocator: () => readonlyLocator,
51
53
  signIn: () => signIn,
52
54
  wait: () => wait,
53
55
  waitElementIsVisible: () => waitElementIsVisible
@@ -129,6 +131,9 @@ var AbstractElement = class {
129
131
  getFullCssSelector() {
130
132
  return this.elementCssSelector;
131
133
  }
134
+ joinRelativeCssSelectors(selectors) {
135
+ return selectors.join(" ");
136
+ }
132
137
  async getElement() {
133
138
  return this.driver.findElement(import_selenium_webdriver2.By.css(this.getFullCssSelector()));
134
139
  }
@@ -193,6 +198,7 @@ var byTestIdCssSelector = (testId, element = "div") => {
193
198
  var byTestId = (testId, element = "div") => {
194
199
  return import_selenium_webdriver3.By.css(byTestIdCssSelector(testId, element));
195
200
  };
201
+ var readonlyLocator = "readonly";
196
202
 
197
203
  // src/pageObjects/pages/LoginPage.ts
198
204
  var LOGIN_PATH = "/login";
@@ -275,6 +281,11 @@ var AbstractElementWithParent = class extends AbstractElement {
275
281
  }
276
282
  return `${this.parentCssSelector} ${this.elementCssSelector}`;
277
283
  }
284
+ async isReadonly() {
285
+ const fieldEl = await this.getElement();
286
+ const classSting = await fieldEl.getAttribute("class");
287
+ return classSting.includes(readonlyLocator);
288
+ }
278
289
  };
279
290
 
280
291
  // src/pageObjects/elements/SubsystemsPanel/SubsystemsPanelHeader.ts
@@ -612,8 +623,7 @@ var TagBox = class extends AbstractDXEditorWithInput {
612
623
  const tags = await this.driver.findElements(import_selenium_webdriver11.By.css(`${this.getFullCssSelector()} .${DX_TAG_CONTAINER} ${TAGS_SELECTOR}`));
613
624
  const values = [];
614
625
  for (const tag of tags) {
615
- const text = await tag.getText();
616
- values.push(text);
626
+ values.push(await tag.getAttribute("textContent"));
617
627
  }
618
628
  return values;
619
629
  }
@@ -805,6 +815,16 @@ var AbstractEditor = class extends AbstractElementWithParent {
805
815
  }
806
816
  return this.editor.remove(itemText);
807
817
  }
818
+ /**
819
+ * Возвращает значение true|false в зависимости readOnly поле или нет
820
+ * @example
821
+ * expect(await formEdit.field('NumberFld').isReadonly()).toBe(true);
822
+ * expect(await formEdit.field('TextFld').isReadonly()).toBe(false);
823
+ */
824
+ async isReadonly() {
825
+ await this.initEditor();
826
+ return this.editor.isReadonly();
827
+ }
808
828
  };
809
829
 
810
830
  // src/pageObjects/elements/FormField.ts
@@ -864,6 +884,7 @@ var FormGroup = class extends AbstractElementWithParent {
864
884
  // src/pageObjects/elements/Forms/FormEdit.ts
865
885
  var FormEdit = class extends AbstractForm {
866
886
  saveButtonBy = import_selenium_webdriver14.By.id("button-save");
887
+ closeButtonBy = import_selenium_webdriver14.By.id("button-cancel");
867
888
  constructor(driver) {
868
889
  super(driver);
869
890
  this.popupContainerCssSelector = `.popup .form-edit-${this.formName}`;
@@ -912,6 +933,17 @@ var FormEdit = class extends AbstractForm {
912
933
  await wait(async () => !await this.isSaveButtonDisabled(), this.driver, "Button is disabled");
913
934
  await click(saveButton, this.driver);
914
935
  }
936
+ /**
937
+ * Нажатие на кнопку Закрить
938
+ * @example
939
+ * const formEdit = new MyForm();
940
+ * //...
941
+ * await formEdit.closeButtonClick();
942
+ */
943
+ async closeButtonClick() {
944
+ const closeButton = await this.driver.findElement(this.closeButtonBy);
945
+ await click(closeButton, this.driver);
946
+ }
915
947
  };
916
948
 
917
949
  // src/pageObjects/elements/Table/Table.ts
@@ -1224,16 +1256,95 @@ var ToolbarButton = class extends AbstractButton {
1224
1256
  }
1225
1257
  };
1226
1258
 
1259
+ // src/pageObjects/elements/TableToolbar/ToolbarMenu.ts
1260
+ var import_selenium_webdriver20 = require("selenium-webdriver");
1261
+
1262
+ // src/utils/typesUtil.ts
1263
+ var types = {
1264
+ "[object Array]": "array",
1265
+ "[object Date]": "date",
1266
+ "[object Object]": "object",
1267
+ "[object String]": "string",
1268
+ "[object Null]": "null"
1269
+ };
1270
+ var type = function(object) {
1271
+ const typeOfObject = Object.prototype.toString.call(object);
1272
+ return typeof object === "object" ? types[typeOfObject] || "object" : typeof object;
1273
+ };
1274
+ var isArray = function(value) {
1275
+ return type(value) === "array";
1276
+ };
1277
+ var isString = function(object) {
1278
+ return typeof object === "string";
1279
+ };
1280
+
1281
+ // src/pageObjects/elements/TableToolbar/ToolbarMenu.ts
1282
+ var SPINDOWN_CLASS = ".dx-icon-spindown";
1283
+ var buttonGroupItemSelector = (formName, name) => byTestIdCssSelector(`ftb-${formName}-${name}`);
1284
+ var getFullCssSelector = (formName, name) => `${buttonGroupItemSelector(formName, name)} ${SPINDOWN_CLASS}`;
1285
+ var buttonByTextXpath = (text) => `.//span[contains(@class, "dx-menu-item-text") and contains(text(), "${text}")]`;
1286
+ var ToolbarMenu = class extends AbstractElementWithParent {
1287
+ _formName;
1288
+ constructor(parentCssSelector, formName, name, driver) {
1289
+ super(parentCssSelector, getFullCssSelector(formName, name), driver);
1290
+ this._formName = formName;
1291
+ }
1292
+ async toggle() {
1293
+ const dropdown = await this.getElement();
1294
+ await dropdown.click();
1295
+ }
1296
+ getCssSelectorToButton(name) {
1297
+ return byTestId(`ftb-${this._formName}-${name}`);
1298
+ }
1299
+ buttonNotDisplayedError(name) {
1300
+ return `Toolbar menu button ${name} cannot be clicked. It is not displayed or it is disabled`;
1301
+ }
1302
+ async goToButton(name, selector) {
1303
+ const toolbarMenuItem = this.driver.findElement(selector);
1304
+ await wait(async () => {
1305
+ return await toolbarMenuItem.isDisplayed();
1306
+ }, this.driver, this.buttonNotDisplayedError(name));
1307
+ await click(toolbarMenuItem, this.driver);
1308
+ }
1309
+ async clickButton(name) {
1310
+ await this.toggle();
1311
+ if (isString(name)) {
1312
+ const selector = this.getCssSelectorToButton(name);
1313
+ await this.goToButton(name, selector);
1314
+ }
1315
+ if (isArray(name)) {
1316
+ for (let n of name) {
1317
+ const selector = this.getCssSelectorToButton(n);
1318
+ await this.goToButton(n, selector);
1319
+ }
1320
+ }
1321
+ }
1322
+ async clickButtonByTitle(title) {
1323
+ await this.toggle();
1324
+ if (isString(title)) {
1325
+ const selector = import_selenium_webdriver20.By.xpath(buttonByTextXpath(title));
1326
+ await this.goToButton(title, selector);
1327
+ }
1328
+ if (isArray(title)) {
1329
+ for (let t of title) {
1330
+ const selector = import_selenium_webdriver20.By.xpath(buttonByTextXpath(t));
1331
+ await this.goToButton(t, selector);
1332
+ }
1333
+ }
1334
+ }
1335
+ };
1336
+
1227
1337
  // src/pageObjects/elements/TableToolbar/ToolbarItem.ts
1228
1338
  var GROUP_BUTTON_CLASS = "toolbar-group-button";
1229
1339
  var toolbarItemSelector = (form, name) => byTestIdCssSelector(`ftb-${form}-${name}`);
1230
1340
  var ToolbarItem = class extends AbstractElementWithParent {
1231
1341
  _button;
1232
- // private _formName: string;
1342
+ _formName;
1233
1343
  _itemName;
1234
1344
  constructor(parentCssSelector, formName, itemName, driver) {
1235
1345
  super(parentCssSelector, toolbarItemSelector(formName, itemName), driver);
1236
1346
  this._itemName = itemName;
1347
+ this._formName = formName;
1237
1348
  }
1238
1349
  async init() {
1239
1350
  if (this._button)
@@ -1253,6 +1364,9 @@ var ToolbarItem = class extends AbstractElementWithParent {
1253
1364
  await this.init();
1254
1365
  return await this._button.isDisabled();
1255
1366
  }
1367
+ get menu() {
1368
+ return new ToolbarMenu(this.parentCssSelector, this._formName, this._itemName, this.driver);
1369
+ }
1256
1370
  };
1257
1371
 
1258
1372
  // src/pageObjects/elements/TableToolbar/FormToolbar.ts
@@ -1310,7 +1424,7 @@ var FormFilterField = class extends AbstractEditor {
1310
1424
  };
1311
1425
 
1312
1426
  // src/pageObjects/elements/Filters/FilterPanel.ts
1313
- var import_selenium_webdriver20 = require("selenium-webdriver");
1427
+ var import_selenium_webdriver21 = require("selenium-webdriver");
1314
1428
 
1315
1429
  // src/pageObjects/elements/Filters/PanelFilterField.ts
1316
1430
  var PanelFilterField = class extends AbstractEditor {
@@ -1365,7 +1479,7 @@ var FilterPanel = class extends AbstractElement {
1365
1479
  async filterPanelButtons() {
1366
1480
  const selector = `${this.elementCssSelector} ${FILTER_PANEL_SELECTOR} .filter-panel__buttons-panel .dx-button-text`;
1367
1481
  const el = await this.getElement();
1368
- return el.findElements(import_selenium_webdriver20.By.css(selector));
1482
+ return el.findElements(import_selenium_webdriver21.By.css(selector));
1369
1483
  }
1370
1484
  constructor(formName, driver) {
1371
1485
  super(driver, drawerSelector(formName));
@@ -1398,7 +1512,7 @@ var FilterPanel = class extends AbstractElement {
1398
1512
  await this.driver.sleep(300);
1399
1513
  }
1400
1514
  async close() {
1401
- const btn = await this.driver.findElement(import_selenium_webdriver20.By.css(`${this.elementCssSelector} ${CLOSE_SELECTOR}`));
1515
+ const btn = await this.driver.findElement(import_selenium_webdriver21.By.css(`${this.elementCssSelector} ${CLOSE_SELECTOR}`));
1402
1516
  await click(btn, this.driver);
1403
1517
  }
1404
1518
  };
@@ -1462,9 +1576,57 @@ var ListForm = class extends AbstractForm {
1462
1576
  return new FilterPanel(this.formName, this.driver);
1463
1577
  }
1464
1578
  };
1579
+
1580
+ // src/pageObjects/elements/Dialog.ts
1581
+ var import_selenium_webdriver22 = require("selenium-webdriver");
1582
+ var DIALOG_CLASS = ".d5-dialog";
1583
+ var DIALOG_TITLE_CLASS = ".dialog__title";
1584
+ var DIALOG_TEXT_CLASS = ".dialog__text";
1585
+ var DIALOG_BUTTONS_PANEL_CLASS = ".dialog__buttons-panel";
1586
+ var buttonByTextXpath2 = (text) => `.//span[contains(@class, "dx-button-text") and contains(text(), "${text}")]`;
1587
+ var DialogButton = class extends AbstractButton {
1588
+ text;
1589
+ constructor(parentCssSelector, text, driver) {
1590
+ super(parentCssSelector, "", driver);
1591
+ this.text = text;
1592
+ }
1593
+ async getElement() {
1594
+ const panel = await super.getElement();
1595
+ return panel.findElement(import_selenium_webdriver22.By.xpath(buttonByTextXpath2(this.text)));
1596
+ }
1597
+ buttonNotDisplayedError() {
1598
+ return `Dialog button ${this.text} cannot be clicked. It is not displayed or it is disabled`;
1599
+ }
1600
+ };
1601
+ var Dialog = class extends AbstractElement {
1602
+ constructor(driver) {
1603
+ super(driver, DIALOG_CLASS);
1604
+ }
1605
+ get titleSelector() {
1606
+ return this.joinRelativeCssSelectors([DIALOG_CLASS, DIALOG_TITLE_CLASS]);
1607
+ }
1608
+ get textSelector() {
1609
+ return this.joinRelativeCssSelectors([DIALOG_CLASS, DIALOG_TEXT_CLASS]);
1610
+ }
1611
+ get buttonsSelector() {
1612
+ return this.joinRelativeCssSelectors([DIALOG_CLASS, DIALOG_BUTTONS_PANEL_CLASS]);
1613
+ }
1614
+ async title() {
1615
+ const el = await this.driver.findElement(import_selenium_webdriver22.By.css(this.titleSelector));
1616
+ return await el.getText();
1617
+ }
1618
+ async text() {
1619
+ const el = await this.driver.findElement(import_selenium_webdriver22.By.css(this.textSelector));
1620
+ return await el.getText();
1621
+ }
1622
+ button(text) {
1623
+ return new DialogButton(this.buttonsSelector, text, this.driver);
1624
+ }
1625
+ };
1465
1626
  // Annotate the CommonJS export names for ESM import in node:
1466
1627
  0 && (module.exports = {
1467
1628
  AbstractPage,
1629
+ Dialog,
1468
1630
  FilterPanel,
1469
1631
  FormEdit,
1470
1632
  FormField,
@@ -1482,6 +1644,7 @@ var ListForm = class extends AbstractForm {
1482
1644
  createDriver,
1483
1645
  editorFactory,
1484
1646
  elementIsNotPresent,
1647
+ readonlyLocator,
1485
1648
  signIn,
1486
1649
  wait,
1487
1650
  waitElementIsVisible
@@ -20,6 +20,7 @@ declare abstract class AbstractElement {
20
20
  protected elementCssSelector: string;
21
21
  protected constructor(driver?: WebDriver, elementCssSelector?: string);
22
22
  protected getFullCssSelector(): string;
23
+ protected joinRelativeCssSelectors(selectors: string[]): string;
23
24
  getElement(): Promise<WebElement>;
24
25
  getAttribute(attr: string): Promise<string>;
25
26
  getClasses(): Promise<string>;
@@ -59,6 +60,7 @@ declare const byTestIdCssSelector: (testId: string, element?: string) => string;
59
60
  * @returns {By} - The By locator object.
60
61
  */
61
62
  declare const byTestId: (testId: string, element?: string) => By;
63
+ declare const readonlyLocator = "readonly";
62
64
 
63
65
  /**
64
66
  * Creates a WebDriver instance for the specified browser.
@@ -155,6 +157,7 @@ declare abstract class AbstractElementWithParent extends AbstractElement {
155
157
  protected parentCssSelector: string;
156
158
  constructor(parentCssSelector: string, elementCssSelector: string, driver?: WebDriver);
157
159
  protected getFullCssSelector(): string;
160
+ isReadonly(): Promise<boolean>;
158
161
  }
159
162
 
160
163
  interface Editor {
@@ -162,6 +165,7 @@ interface Editor {
162
165
  getValue(): Promise<any>;
163
166
  remove?(itemText: string): Promise<void>;
164
167
  clear?(): Promise<void>;
168
+ isReadonly?(): Promise<boolean>;
165
169
  }
166
170
 
167
171
  interface ClearStrategy {
@@ -224,6 +228,13 @@ declare class AbstractEditor extends AbstractElementWithParent implements Editor
224
228
  * await formEdit.field('TagBox').remove('test');
225
229
  */
226
230
  remove(itemText: string): Promise<void>;
231
+ /**
232
+ * Возвращает значение true|false в зависимости readOnly поле или нет
233
+ * @example
234
+ * expect(await formEdit.field('NumberFld').isReadonly()).toBe(true);
235
+ * expect(await formEdit.field('TextFld').isReadonly()).toBe(false);
236
+ */
237
+ isReadonly(): Promise<boolean>;
227
238
  }
228
239
 
229
240
  declare class FormField extends AbstractEditor {
@@ -248,6 +259,7 @@ declare class FormGroup extends AbstractElementWithParent implements Group {
248
259
 
249
260
  declare abstract class FormEdit extends AbstractForm {
250
261
  saveButtonBy: By;
262
+ closeButtonBy: By;
251
263
  protected constructor(driver?: WebDriver);
252
264
  /**
253
265
  * Находит поле формы редактирования по имени
@@ -281,20 +293,47 @@ declare abstract class FormEdit extends AbstractForm {
281
293
  * await formEdit.saveButtonClick();
282
294
  */
283
295
  saveButtonClick(): Promise<void>;
296
+ /**
297
+ * Нажатие на кнопку Закрить
298
+ * @example
299
+ * const formEdit = new MyForm();
300
+ * //...
301
+ * await formEdit.closeButtonClick();
302
+ */
303
+ closeButtonClick(): Promise<void>;
284
304
  }
285
305
 
286
306
  interface Button {
287
307
  click(): Promise<void>;
288
308
  isDisabled(): Promise<boolean>;
289
309
  }
310
+ declare abstract class AbstractButton extends AbstractElementWithParent implements Button {
311
+ protected constructor(parentCssSelector: string, elementCssSelector: string, driver?: WebDriver);
312
+ protected abstract buttonNotDisplayedError(): string;
313
+ click(): Promise<void>;
314
+ isDisabled(): Promise<boolean>;
315
+ }
316
+
317
+ declare class ToolbarMenu extends AbstractElementWithParent {
318
+ private readonly _formName;
319
+ constructor(parentCssSelector: string, formName: string, name: string, driver?: WebDriver);
320
+ protected toggle(): Promise<void>;
321
+ protected getCssSelectorToButton(name: string): By;
322
+ protected buttonNotDisplayedError(name: string): string;
323
+ protected goToButton(name: string, selector: By): Promise<void>;
324
+ clickButton(name: string | string[]): Promise<void>;
325
+ clickButtonByTitle(title: string | string[]): Promise<void>;
326
+ }
290
327
 
291
328
  declare class ToolbarItem extends AbstractElementWithParent implements Button {
292
329
  private _button;
293
- private _itemName;
330
+ private readonly _formName;
331
+ private readonly _itemName;
294
332
  constructor(parentCssSelector: string, formName: string, itemName: string, driver?: WebDriver);
295
333
  private init;
296
334
  click(): Promise<void>;
297
335
  isDisabled(): Promise<boolean>;
336
+ get menu(): ToolbarMenu;
298
337
  }
299
338
 
300
339
  declare class Cell extends AbstractElementWithParent {
@@ -500,4 +539,20 @@ declare abstract class ListForm extends AbstractForm {
500
539
  get filterPanel(): FilterPanel;
501
540
  }
502
541
 
503
- export { AbstractPage, Editor, FilterPanel, FormEdit, FormField, FormFilterField, ListForm, LoginPage, NumberEditor, PanelFilterField, SubsystemsPanel, TextEditor, byTestId, byTestIdCssSelector, click, config, createDriver, editorFactory, elementIsNotPresent, signIn, wait, waitElementIsVisible };
542
+ declare class DialogButton extends AbstractButton implements Button {
543
+ private readonly text;
544
+ constructor(parentCssSelector: string, text: string, driver?: WebDriver);
545
+ getElement(): Promise<WebElement>;
546
+ protected buttonNotDisplayedError(): string;
547
+ }
548
+ declare class Dialog extends AbstractElement {
549
+ constructor(driver?: WebDriver);
550
+ private get titleSelector();
551
+ private get textSelector();
552
+ private get buttonsSelector();
553
+ title(): Promise<string>;
554
+ text(): Promise<string>;
555
+ button(text: string): DialogButton;
556
+ }
557
+
558
+ export { AbstractPage, Dialog, Editor, FilterPanel, FormEdit, FormField, FormFilterField, ListForm, LoginPage, NumberEditor, PanelFilterField, SubsystemsPanel, TextEditor, byTestId, byTestIdCssSelector, click, config, createDriver, editorFactory, elementIsNotPresent, readonlyLocator, signIn, wait, waitElementIsVisible };
@@ -73,6 +73,9 @@ var AbstractElement = class {
73
73
  getFullCssSelector() {
74
74
  return this.elementCssSelector;
75
75
  }
76
+ joinRelativeCssSelectors(selectors) {
77
+ return selectors.join(" ");
78
+ }
76
79
  async getElement() {
77
80
  return this.driver.findElement(By.css(this.getFullCssSelector()));
78
81
  }
@@ -137,6 +140,7 @@ var byTestIdCssSelector = (testId, element = "div") => {
137
140
  var byTestId = (testId, element = "div") => {
138
141
  return By2.css(byTestIdCssSelector(testId, element));
139
142
  };
143
+ var readonlyLocator = "readonly";
140
144
 
141
145
  // src/pageObjects/pages/LoginPage.ts
142
146
  var LOGIN_PATH = "/login";
@@ -219,6 +223,11 @@ var AbstractElementWithParent = class extends AbstractElement {
219
223
  }
220
224
  return `${this.parentCssSelector} ${this.elementCssSelector}`;
221
225
  }
226
+ async isReadonly() {
227
+ const fieldEl = await this.getElement();
228
+ const classSting = await fieldEl.getAttribute("class");
229
+ return classSting.includes(readonlyLocator);
230
+ }
222
231
  };
223
232
 
224
233
  // src/pageObjects/elements/SubsystemsPanel/SubsystemsPanelHeader.ts
@@ -556,8 +565,7 @@ var TagBox = class extends AbstractDXEditorWithInput {
556
565
  const tags = await this.driver.findElements(By9.css(`${this.getFullCssSelector()} .${DX_TAG_CONTAINER} ${TAGS_SELECTOR}`));
557
566
  const values = [];
558
567
  for (const tag of tags) {
559
- const text = await tag.getText();
560
- values.push(text);
568
+ values.push(await tag.getAttribute("textContent"));
561
569
  }
562
570
  return values;
563
571
  }
@@ -749,6 +757,16 @@ var AbstractEditor = class extends AbstractElementWithParent {
749
757
  }
750
758
  return this.editor.remove(itemText);
751
759
  }
760
+ /**
761
+ * Возвращает значение true|false в зависимости readOnly поле или нет
762
+ * @example
763
+ * expect(await formEdit.field('NumberFld').isReadonly()).toBe(true);
764
+ * expect(await formEdit.field('TextFld').isReadonly()).toBe(false);
765
+ */
766
+ async isReadonly() {
767
+ await this.initEditor();
768
+ return this.editor.isReadonly();
769
+ }
752
770
  };
753
771
 
754
772
  // src/pageObjects/elements/FormField.ts
@@ -808,6 +826,7 @@ var FormGroup = class extends AbstractElementWithParent {
808
826
  // src/pageObjects/elements/Forms/FormEdit.ts
809
827
  var FormEdit = class extends AbstractForm {
810
828
  saveButtonBy = By12.id("button-save");
829
+ closeButtonBy = By12.id("button-cancel");
811
830
  constructor(driver) {
812
831
  super(driver);
813
832
  this.popupContainerCssSelector = `.popup .form-edit-${this.formName}`;
@@ -856,6 +875,17 @@ var FormEdit = class extends AbstractForm {
856
875
  await wait(async () => !await this.isSaveButtonDisabled(), this.driver, "Button is disabled");
857
876
  await click(saveButton, this.driver);
858
877
  }
878
+ /**
879
+ * Нажатие на кнопку Закрить
880
+ * @example
881
+ * const formEdit = new MyForm();
882
+ * //...
883
+ * await formEdit.closeButtonClick();
884
+ */
885
+ async closeButtonClick() {
886
+ const closeButton = await this.driver.findElement(this.closeButtonBy);
887
+ await click(closeButton, this.driver);
888
+ }
859
889
  };
860
890
 
861
891
  // src/pageObjects/elements/Table/Table.ts
@@ -1168,16 +1198,95 @@ var ToolbarButton = class extends AbstractButton {
1168
1198
  }
1169
1199
  };
1170
1200
 
1201
+ // src/pageObjects/elements/TableToolbar/ToolbarMenu.ts
1202
+ import { By as By18 } from "selenium-webdriver";
1203
+
1204
+ // src/utils/typesUtil.ts
1205
+ var types = {
1206
+ "[object Array]": "array",
1207
+ "[object Date]": "date",
1208
+ "[object Object]": "object",
1209
+ "[object String]": "string",
1210
+ "[object Null]": "null"
1211
+ };
1212
+ var type = function(object) {
1213
+ const typeOfObject = Object.prototype.toString.call(object);
1214
+ return typeof object === "object" ? types[typeOfObject] || "object" : typeof object;
1215
+ };
1216
+ var isArray = function(value) {
1217
+ return type(value) === "array";
1218
+ };
1219
+ var isString = function(object) {
1220
+ return typeof object === "string";
1221
+ };
1222
+
1223
+ // src/pageObjects/elements/TableToolbar/ToolbarMenu.ts
1224
+ var SPINDOWN_CLASS = ".dx-icon-spindown";
1225
+ var buttonGroupItemSelector = (formName, name) => byTestIdCssSelector(`ftb-${formName}-${name}`);
1226
+ var getFullCssSelector = (formName, name) => `${buttonGroupItemSelector(formName, name)} ${SPINDOWN_CLASS}`;
1227
+ var buttonByTextXpath = (text) => `.//span[contains(@class, "dx-menu-item-text") and contains(text(), "${text}")]`;
1228
+ var ToolbarMenu = class extends AbstractElementWithParent {
1229
+ _formName;
1230
+ constructor(parentCssSelector, formName, name, driver) {
1231
+ super(parentCssSelector, getFullCssSelector(formName, name), driver);
1232
+ this._formName = formName;
1233
+ }
1234
+ async toggle() {
1235
+ const dropdown = await this.getElement();
1236
+ await dropdown.click();
1237
+ }
1238
+ getCssSelectorToButton(name) {
1239
+ return byTestId(`ftb-${this._formName}-${name}`);
1240
+ }
1241
+ buttonNotDisplayedError(name) {
1242
+ return `Toolbar menu button ${name} cannot be clicked. It is not displayed or it is disabled`;
1243
+ }
1244
+ async goToButton(name, selector) {
1245
+ const toolbarMenuItem = this.driver.findElement(selector);
1246
+ await wait(async () => {
1247
+ return await toolbarMenuItem.isDisplayed();
1248
+ }, this.driver, this.buttonNotDisplayedError(name));
1249
+ await click(toolbarMenuItem, this.driver);
1250
+ }
1251
+ async clickButton(name) {
1252
+ await this.toggle();
1253
+ if (isString(name)) {
1254
+ const selector = this.getCssSelectorToButton(name);
1255
+ await this.goToButton(name, selector);
1256
+ }
1257
+ if (isArray(name)) {
1258
+ for (let n of name) {
1259
+ const selector = this.getCssSelectorToButton(n);
1260
+ await this.goToButton(n, selector);
1261
+ }
1262
+ }
1263
+ }
1264
+ async clickButtonByTitle(title) {
1265
+ await this.toggle();
1266
+ if (isString(title)) {
1267
+ const selector = By18.xpath(buttonByTextXpath(title));
1268
+ await this.goToButton(title, selector);
1269
+ }
1270
+ if (isArray(title)) {
1271
+ for (let t of title) {
1272
+ const selector = By18.xpath(buttonByTextXpath(t));
1273
+ await this.goToButton(t, selector);
1274
+ }
1275
+ }
1276
+ }
1277
+ };
1278
+
1171
1279
  // src/pageObjects/elements/TableToolbar/ToolbarItem.ts
1172
1280
  var GROUP_BUTTON_CLASS = "toolbar-group-button";
1173
1281
  var toolbarItemSelector = (form, name) => byTestIdCssSelector(`ftb-${form}-${name}`);
1174
1282
  var ToolbarItem = class extends AbstractElementWithParent {
1175
1283
  _button;
1176
- // private _formName: string;
1284
+ _formName;
1177
1285
  _itemName;
1178
1286
  constructor(parentCssSelector, formName, itemName, driver) {
1179
1287
  super(parentCssSelector, toolbarItemSelector(formName, itemName), driver);
1180
1288
  this._itemName = itemName;
1289
+ this._formName = formName;
1181
1290
  }
1182
1291
  async init() {
1183
1292
  if (this._button)
@@ -1197,6 +1306,9 @@ var ToolbarItem = class extends AbstractElementWithParent {
1197
1306
  await this.init();
1198
1307
  return await this._button.isDisabled();
1199
1308
  }
1309
+ get menu() {
1310
+ return new ToolbarMenu(this.parentCssSelector, this._formName, this._itemName, this.driver);
1311
+ }
1200
1312
  };
1201
1313
 
1202
1314
  // src/pageObjects/elements/TableToolbar/FormToolbar.ts
@@ -1254,7 +1366,7 @@ var FormFilterField = class extends AbstractEditor {
1254
1366
  };
1255
1367
 
1256
1368
  // src/pageObjects/elements/Filters/FilterPanel.ts
1257
- import { By as By18 } from "selenium-webdriver";
1369
+ import { By as By19 } from "selenium-webdriver";
1258
1370
 
1259
1371
  // src/pageObjects/elements/Filters/PanelFilterField.ts
1260
1372
  var PanelFilterField = class extends AbstractEditor {
@@ -1309,7 +1421,7 @@ var FilterPanel = class extends AbstractElement {
1309
1421
  async filterPanelButtons() {
1310
1422
  const selector = `${this.elementCssSelector} ${FILTER_PANEL_SELECTOR} .filter-panel__buttons-panel .dx-button-text`;
1311
1423
  const el = await this.getElement();
1312
- return el.findElements(By18.css(selector));
1424
+ return el.findElements(By19.css(selector));
1313
1425
  }
1314
1426
  constructor(formName, driver) {
1315
1427
  super(driver, drawerSelector(formName));
@@ -1342,7 +1454,7 @@ var FilterPanel = class extends AbstractElement {
1342
1454
  await this.driver.sleep(300);
1343
1455
  }
1344
1456
  async close() {
1345
- const btn = await this.driver.findElement(By18.css(`${this.elementCssSelector} ${CLOSE_SELECTOR}`));
1457
+ const btn = await this.driver.findElement(By19.css(`${this.elementCssSelector} ${CLOSE_SELECTOR}`));
1346
1458
  await click(btn, this.driver);
1347
1459
  }
1348
1460
  };
@@ -1406,8 +1518,56 @@ var ListForm = class extends AbstractForm {
1406
1518
  return new FilterPanel(this.formName, this.driver);
1407
1519
  }
1408
1520
  };
1521
+
1522
+ // src/pageObjects/elements/Dialog.ts
1523
+ import { By as By20 } from "selenium-webdriver";
1524
+ var DIALOG_CLASS = ".d5-dialog";
1525
+ var DIALOG_TITLE_CLASS = ".dialog__title";
1526
+ var DIALOG_TEXT_CLASS = ".dialog__text";
1527
+ var DIALOG_BUTTONS_PANEL_CLASS = ".dialog__buttons-panel";
1528
+ var buttonByTextXpath2 = (text) => `.//span[contains(@class, "dx-button-text") and contains(text(), "${text}")]`;
1529
+ var DialogButton = class extends AbstractButton {
1530
+ text;
1531
+ constructor(parentCssSelector, text, driver) {
1532
+ super(parentCssSelector, "", driver);
1533
+ this.text = text;
1534
+ }
1535
+ async getElement() {
1536
+ const panel = await super.getElement();
1537
+ return panel.findElement(By20.xpath(buttonByTextXpath2(this.text)));
1538
+ }
1539
+ buttonNotDisplayedError() {
1540
+ return `Dialog button ${this.text} cannot be clicked. It is not displayed or it is disabled`;
1541
+ }
1542
+ };
1543
+ var Dialog = class extends AbstractElement {
1544
+ constructor(driver) {
1545
+ super(driver, DIALOG_CLASS);
1546
+ }
1547
+ get titleSelector() {
1548
+ return this.joinRelativeCssSelectors([DIALOG_CLASS, DIALOG_TITLE_CLASS]);
1549
+ }
1550
+ get textSelector() {
1551
+ return this.joinRelativeCssSelectors([DIALOG_CLASS, DIALOG_TEXT_CLASS]);
1552
+ }
1553
+ get buttonsSelector() {
1554
+ return this.joinRelativeCssSelectors([DIALOG_CLASS, DIALOG_BUTTONS_PANEL_CLASS]);
1555
+ }
1556
+ async title() {
1557
+ const el = await this.driver.findElement(By20.css(this.titleSelector));
1558
+ return await el.getText();
1559
+ }
1560
+ async text() {
1561
+ const el = await this.driver.findElement(By20.css(this.textSelector));
1562
+ return await el.getText();
1563
+ }
1564
+ button(text) {
1565
+ return new DialogButton(this.buttonsSelector, text, this.driver);
1566
+ }
1567
+ };
1409
1568
  export {
1410
1569
  AbstractPage,
1570
+ Dialog,
1411
1571
  FilterPanel,
1412
1572
  FormEdit,
1413
1573
  FormField,
@@ -1425,6 +1585,7 @@ export {
1425
1585
  createDriver,
1426
1586
  editorFactory,
1427
1587
  elementIsNotPresent,
1588
+ readonlyLocator,
1428
1589
  signIn,
1429
1590
  wait,
1430
1591
  waitElementIsVisible
@@ -73,6 +73,9 @@ var AbstractElement = class {
73
73
  getFullCssSelector() {
74
74
  return this.elementCssSelector;
75
75
  }
76
+ joinRelativeCssSelectors(selectors) {
77
+ return selectors.join(" ");
78
+ }
76
79
  async getElement() {
77
80
  return this.driver.findElement(By.css(this.getFullCssSelector()));
78
81
  }
@@ -137,6 +140,7 @@ var byTestIdCssSelector = (testId, element = "div") => {
137
140
  var byTestId = (testId, element = "div") => {
138
141
  return By2.css(byTestIdCssSelector(testId, element));
139
142
  };
143
+ var readonlyLocator = "readonly";
140
144
 
141
145
  // src/pageObjects/pages/LoginPage.ts
142
146
  var LOGIN_PATH = "/login";
@@ -219,6 +223,11 @@ var AbstractElementWithParent = class extends AbstractElement {
219
223
  }
220
224
  return `${this.parentCssSelector} ${this.elementCssSelector}`;
221
225
  }
226
+ async isReadonly() {
227
+ const fieldEl = await this.getElement();
228
+ const classSting = await fieldEl.getAttribute("class");
229
+ return classSting.includes(readonlyLocator);
230
+ }
222
231
  };
223
232
 
224
233
  // src/pageObjects/elements/SubsystemsPanel/SubsystemsPanelHeader.ts
@@ -556,8 +565,7 @@ var TagBox = class extends AbstractDXEditorWithInput {
556
565
  const tags = await this.driver.findElements(By9.css(`${this.getFullCssSelector()} .${DX_TAG_CONTAINER} ${TAGS_SELECTOR}`));
557
566
  const values = [];
558
567
  for (const tag of tags) {
559
- const text = await tag.getText();
560
- values.push(text);
568
+ values.push(await tag.getAttribute("textContent"));
561
569
  }
562
570
  return values;
563
571
  }
@@ -749,6 +757,16 @@ var AbstractEditor = class extends AbstractElementWithParent {
749
757
  }
750
758
  return this.editor.remove(itemText);
751
759
  }
760
+ /**
761
+ * Возвращает значение true|false в зависимости readOnly поле или нет
762
+ * @example
763
+ * expect(await formEdit.field('NumberFld').isReadonly()).toBe(true);
764
+ * expect(await formEdit.field('TextFld').isReadonly()).toBe(false);
765
+ */
766
+ async isReadonly() {
767
+ await this.initEditor();
768
+ return this.editor.isReadonly();
769
+ }
752
770
  };
753
771
 
754
772
  // src/pageObjects/elements/FormField.ts
@@ -808,6 +826,7 @@ var FormGroup = class extends AbstractElementWithParent {
808
826
  // src/pageObjects/elements/Forms/FormEdit.ts
809
827
  var FormEdit = class extends AbstractForm {
810
828
  saveButtonBy = By12.id("button-save");
829
+ closeButtonBy = By12.id("button-cancel");
811
830
  constructor(driver) {
812
831
  super(driver);
813
832
  this.popupContainerCssSelector = `.popup .form-edit-${this.formName}`;
@@ -856,6 +875,17 @@ var FormEdit = class extends AbstractForm {
856
875
  await wait(async () => !await this.isSaveButtonDisabled(), this.driver, "Button is disabled");
857
876
  await click(saveButton, this.driver);
858
877
  }
878
+ /**
879
+ * Нажатие на кнопку Закрить
880
+ * @example
881
+ * const formEdit = new MyForm();
882
+ * //...
883
+ * await formEdit.closeButtonClick();
884
+ */
885
+ async closeButtonClick() {
886
+ const closeButton = await this.driver.findElement(this.closeButtonBy);
887
+ await click(closeButton, this.driver);
888
+ }
859
889
  };
860
890
 
861
891
  // src/pageObjects/elements/Table/Table.ts
@@ -1168,16 +1198,95 @@ var ToolbarButton = class extends AbstractButton {
1168
1198
  }
1169
1199
  };
1170
1200
 
1201
+ // src/pageObjects/elements/TableToolbar/ToolbarMenu.ts
1202
+ import { By as By18 } from "selenium-webdriver";
1203
+
1204
+ // src/utils/typesUtil.ts
1205
+ var types = {
1206
+ "[object Array]": "array",
1207
+ "[object Date]": "date",
1208
+ "[object Object]": "object",
1209
+ "[object String]": "string",
1210
+ "[object Null]": "null"
1211
+ };
1212
+ var type = function(object) {
1213
+ const typeOfObject = Object.prototype.toString.call(object);
1214
+ return typeof object === "object" ? types[typeOfObject] || "object" : typeof object;
1215
+ };
1216
+ var isArray = function(value) {
1217
+ return type(value) === "array";
1218
+ };
1219
+ var isString = function(object) {
1220
+ return typeof object === "string";
1221
+ };
1222
+
1223
+ // src/pageObjects/elements/TableToolbar/ToolbarMenu.ts
1224
+ var SPINDOWN_CLASS = ".dx-icon-spindown";
1225
+ var buttonGroupItemSelector = (formName, name) => byTestIdCssSelector(`ftb-${formName}-${name}`);
1226
+ var getFullCssSelector = (formName, name) => `${buttonGroupItemSelector(formName, name)} ${SPINDOWN_CLASS}`;
1227
+ var buttonByTextXpath = (text) => `.//span[contains(@class, "dx-menu-item-text") and contains(text(), "${text}")]`;
1228
+ var ToolbarMenu = class extends AbstractElementWithParent {
1229
+ _formName;
1230
+ constructor(parentCssSelector, formName, name, driver) {
1231
+ super(parentCssSelector, getFullCssSelector(formName, name), driver);
1232
+ this._formName = formName;
1233
+ }
1234
+ async toggle() {
1235
+ const dropdown = await this.getElement();
1236
+ await dropdown.click();
1237
+ }
1238
+ getCssSelectorToButton(name) {
1239
+ return byTestId(`ftb-${this._formName}-${name}`);
1240
+ }
1241
+ buttonNotDisplayedError(name) {
1242
+ return `Toolbar menu button ${name} cannot be clicked. It is not displayed or it is disabled`;
1243
+ }
1244
+ async goToButton(name, selector) {
1245
+ const toolbarMenuItem = this.driver.findElement(selector);
1246
+ await wait(async () => {
1247
+ return await toolbarMenuItem.isDisplayed();
1248
+ }, this.driver, this.buttonNotDisplayedError(name));
1249
+ await click(toolbarMenuItem, this.driver);
1250
+ }
1251
+ async clickButton(name) {
1252
+ await this.toggle();
1253
+ if (isString(name)) {
1254
+ const selector = this.getCssSelectorToButton(name);
1255
+ await this.goToButton(name, selector);
1256
+ }
1257
+ if (isArray(name)) {
1258
+ for (let n of name) {
1259
+ const selector = this.getCssSelectorToButton(n);
1260
+ await this.goToButton(n, selector);
1261
+ }
1262
+ }
1263
+ }
1264
+ async clickButtonByTitle(title) {
1265
+ await this.toggle();
1266
+ if (isString(title)) {
1267
+ const selector = By18.xpath(buttonByTextXpath(title));
1268
+ await this.goToButton(title, selector);
1269
+ }
1270
+ if (isArray(title)) {
1271
+ for (let t of title) {
1272
+ const selector = By18.xpath(buttonByTextXpath(t));
1273
+ await this.goToButton(t, selector);
1274
+ }
1275
+ }
1276
+ }
1277
+ };
1278
+
1171
1279
  // src/pageObjects/elements/TableToolbar/ToolbarItem.ts
1172
1280
  var GROUP_BUTTON_CLASS = "toolbar-group-button";
1173
1281
  var toolbarItemSelector = (form, name) => byTestIdCssSelector(`ftb-${form}-${name}`);
1174
1282
  var ToolbarItem = class extends AbstractElementWithParent {
1175
1283
  _button;
1176
- // private _formName: string;
1284
+ _formName;
1177
1285
  _itemName;
1178
1286
  constructor(parentCssSelector, formName, itemName, driver) {
1179
1287
  super(parentCssSelector, toolbarItemSelector(formName, itemName), driver);
1180
1288
  this._itemName = itemName;
1289
+ this._formName = formName;
1181
1290
  }
1182
1291
  async init() {
1183
1292
  if (this._button)
@@ -1197,6 +1306,9 @@ var ToolbarItem = class extends AbstractElementWithParent {
1197
1306
  await this.init();
1198
1307
  return await this._button.isDisabled();
1199
1308
  }
1309
+ get menu() {
1310
+ return new ToolbarMenu(this.parentCssSelector, this._formName, this._itemName, this.driver);
1311
+ }
1200
1312
  };
1201
1313
 
1202
1314
  // src/pageObjects/elements/TableToolbar/FormToolbar.ts
@@ -1254,7 +1366,7 @@ var FormFilterField = class extends AbstractEditor {
1254
1366
  };
1255
1367
 
1256
1368
  // src/pageObjects/elements/Filters/FilterPanel.ts
1257
- import { By as By18 } from "selenium-webdriver";
1369
+ import { By as By19 } from "selenium-webdriver";
1258
1370
 
1259
1371
  // src/pageObjects/elements/Filters/PanelFilterField.ts
1260
1372
  var PanelFilterField = class extends AbstractEditor {
@@ -1309,7 +1421,7 @@ var FilterPanel = class extends AbstractElement {
1309
1421
  async filterPanelButtons() {
1310
1422
  const selector = `${this.elementCssSelector} ${FILTER_PANEL_SELECTOR} .filter-panel__buttons-panel .dx-button-text`;
1311
1423
  const el = await this.getElement();
1312
- return el.findElements(By18.css(selector));
1424
+ return el.findElements(By19.css(selector));
1313
1425
  }
1314
1426
  constructor(formName, driver) {
1315
1427
  super(driver, drawerSelector(formName));
@@ -1342,7 +1454,7 @@ var FilterPanel = class extends AbstractElement {
1342
1454
  await this.driver.sleep(300);
1343
1455
  }
1344
1456
  async close() {
1345
- const btn = await this.driver.findElement(By18.css(`${this.elementCssSelector} ${CLOSE_SELECTOR}`));
1457
+ const btn = await this.driver.findElement(By19.css(`${this.elementCssSelector} ${CLOSE_SELECTOR}`));
1346
1458
  await click(btn, this.driver);
1347
1459
  }
1348
1460
  };
@@ -1406,8 +1518,56 @@ var ListForm = class extends AbstractForm {
1406
1518
  return new FilterPanel(this.formName, this.driver);
1407
1519
  }
1408
1520
  };
1521
+
1522
+ // src/pageObjects/elements/Dialog.ts
1523
+ import { By as By20 } from "selenium-webdriver";
1524
+ var DIALOG_CLASS = ".d5-dialog";
1525
+ var DIALOG_TITLE_CLASS = ".dialog__title";
1526
+ var DIALOG_TEXT_CLASS = ".dialog__text";
1527
+ var DIALOG_BUTTONS_PANEL_CLASS = ".dialog__buttons-panel";
1528
+ var buttonByTextXpath2 = (text) => `.//span[contains(@class, "dx-button-text") and contains(text(), "${text}")]`;
1529
+ var DialogButton = class extends AbstractButton {
1530
+ text;
1531
+ constructor(parentCssSelector, text, driver) {
1532
+ super(parentCssSelector, "", driver);
1533
+ this.text = text;
1534
+ }
1535
+ async getElement() {
1536
+ const panel = await super.getElement();
1537
+ return panel.findElement(By20.xpath(buttonByTextXpath2(this.text)));
1538
+ }
1539
+ buttonNotDisplayedError() {
1540
+ return `Dialog button ${this.text} cannot be clicked. It is not displayed or it is disabled`;
1541
+ }
1542
+ };
1543
+ var Dialog = class extends AbstractElement {
1544
+ constructor(driver) {
1545
+ super(driver, DIALOG_CLASS);
1546
+ }
1547
+ get titleSelector() {
1548
+ return this.joinRelativeCssSelectors([DIALOG_CLASS, DIALOG_TITLE_CLASS]);
1549
+ }
1550
+ get textSelector() {
1551
+ return this.joinRelativeCssSelectors([DIALOG_CLASS, DIALOG_TEXT_CLASS]);
1552
+ }
1553
+ get buttonsSelector() {
1554
+ return this.joinRelativeCssSelectors([DIALOG_CLASS, DIALOG_BUTTONS_PANEL_CLASS]);
1555
+ }
1556
+ async title() {
1557
+ const el = await this.driver.findElement(By20.css(this.titleSelector));
1558
+ return await el.getText();
1559
+ }
1560
+ async text() {
1561
+ const el = await this.driver.findElement(By20.css(this.textSelector));
1562
+ return await el.getText();
1563
+ }
1564
+ button(text) {
1565
+ return new DialogButton(this.buttonsSelector, text, this.driver);
1566
+ }
1567
+ };
1409
1568
  export {
1410
1569
  AbstractPage,
1570
+ Dialog,
1411
1571
  FilterPanel,
1412
1572
  FormEdit,
1413
1573
  FormField,
@@ -1425,6 +1585,7 @@ export {
1425
1585
  createDriver,
1426
1586
  editorFactory,
1427
1587
  elementIsNotPresent,
1588
+ readonlyLocator,
1428
1589
  signIn,
1429
1590
  wait,
1430
1591
  waitElementIsVisible
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "d5-testing-library",
3
- "version": "1.3.0",
3
+ "version": "1.3.1",
4
4
  "description": "e2e testing D5 projects",
5
5
  "main": "dist/cjs/d5-testing-library.cjs",
6
6
  "module": "dist/d5-testing-library.legacy-esm.js",