d5-testing-library 1.3.0 → 1.4.0

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.
@@ -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
  }
@@ -125,6 +128,9 @@ var AbstractPage = class extends AbstractElement {
125
128
  // src/utils/actions.ts
126
129
  var click = async (webElement, driver) => {
127
130
  driver = driver ?? config().driver;
131
+ if (!await webElement.isDisplayed()) {
132
+ await driver.executeScript("arguments[0].scrollIntoView(true);", webElement);
133
+ }
128
134
  const actions = driver.actions({ async: true });
129
135
  await actions.move({ origin: webElement }).click().perform();
130
136
  };
@@ -137,6 +143,7 @@ var byTestIdCssSelector = (testId, element = "div") => {
137
143
  var byTestId = (testId, element = "div") => {
138
144
  return By2.css(byTestIdCssSelector(testId, element));
139
145
  };
146
+ var readonlyLocator = "readonly";
140
147
 
141
148
  // src/pageObjects/pages/LoginPage.ts
142
149
  var LOGIN_PATH = "/login";
@@ -219,6 +226,11 @@ var AbstractElementWithParent = class extends AbstractElement {
219
226
  }
220
227
  return `${this.parentCssSelector} ${this.elementCssSelector}`;
221
228
  }
229
+ async isReadonly() {
230
+ const fieldEl = await this.getElement();
231
+ const classSting = await fieldEl.getAttribute("class");
232
+ return classSting.includes(readonlyLocator);
233
+ }
222
234
  };
223
235
 
224
236
  // src/pageObjects/elements/SubsystemsPanel/SubsystemsPanelHeader.ts
@@ -244,7 +256,95 @@ var SubsystemsPanel = class extends AbstractElement {
244
256
  };
245
257
 
246
258
  // src/pageObjects/elements/Forms/AbstractForm.ts
259
+ import { By as By6 } from "selenium-webdriver";
260
+
261
+ // src/utils/createDataTestId.ts
262
+ function createDataTestId(formName, itemType, itemName) {
263
+ return `${formName}-${itemType}-${itemName}`;
264
+ }
265
+ function createFieldTestId(formName, itemName) {
266
+ return createDataTestId(formName, "form_field" /* FORM_FIELD */, itemName);
267
+ }
268
+ function createGroupTestId(formName, itemName) {
269
+ return createDataTestId(formName, "group" /* GROUP */, itemName);
270
+ }
271
+ function createFilterTestId(formName, itemName, layout) {
272
+ return createDataTestId(formName, "filter" /* FILTER */, itemName) + `-${layout}`;
273
+ }
274
+ function createDocFilterTestId(formName, itemName) {
275
+ return createFilterTestId(formName, itemName, "dock-panel-filter" /* DOCK_PANEL */);
276
+ }
277
+ function createLayoutFilterTestId(formName, itemName) {
278
+ return createFilterTestId(formName, itemName, "layout-filter" /* LAYOUT */);
279
+ }
280
+ function createTableId(formName) {
281
+ return `${"table" /* TABLE */}-${formName}`;
282
+ }
283
+ function createFormButtonTestId(formName, itemName) {
284
+ return createDataTestId(formName, "button" /* BUTTON */, itemName);
285
+ }
286
+
287
+ // src/utils/waitElementIsClickable.ts
288
+ async function waitElementIsClickable({
289
+ element,
290
+ timeout,
291
+ errorMessage,
292
+ driver
293
+ }) {
294
+ driver = driver ?? config().driver;
295
+ await wait(async () => {
296
+ const isDisabled = await element.getCssValue("pointer-events") === "none";
297
+ return await element.isDisplayed() && !isDisabled;
298
+ }, driver, errorMessage, timeout ?? config().timeout);
299
+ }
300
+
301
+ // src/pageObjects/elements/TableToolbar/AbstractButton.ts
302
+ var AbstractButton = class extends AbstractElementWithParent {
303
+ constructor(parentCssSelector, elementCssSelector, driver) {
304
+ super(parentCssSelector, elementCssSelector, driver);
305
+ }
306
+ async click() {
307
+ const button = await this.getElement();
308
+ await waitElementIsClickable({
309
+ element: button,
310
+ errorMessage: this.buttonNotDisplayedError(),
311
+ driver: this.driver
312
+ });
313
+ await click(button, this.driver);
314
+ }
315
+ async isDisabled() {
316
+ const button = await this.getElement();
317
+ return await button.getCssValue("pointer-events") === "none";
318
+ }
319
+ };
320
+
321
+ // src/pageObjects/elements/DXComponents/DXButton.ts
247
322
  import { By as By5 } from "selenium-webdriver";
323
+ var DXButton = class extends AbstractButton {
324
+ async getText() {
325
+ const classes = await this.getClasses();
326
+ if (!classes.includes("dx-button-has-text")) {
327
+ return null;
328
+ }
329
+ const el = await this.getElement();
330
+ const textEl = el.findElement(By5.className("dx-button-text"));
331
+ return await textEl.getText();
332
+ }
333
+ };
334
+
335
+ // src/pageObjects/elements/FormButton.ts
336
+ var FormButton = class extends DXButton {
337
+ name;
338
+ constructor(parentCssSelector, formName, name, driver) {
339
+ super(parentCssSelector, byTestIdCssSelector(createFormButtonTestId(formName, name)), driver);
340
+ this.name = name;
341
+ }
342
+ buttonNotDisplayedError() {
343
+ return `Form Button ${this.name} cannot be clicked. It is not displayed or it is disabled`;
344
+ }
345
+ };
346
+
347
+ // src/pageObjects/elements/Forms/AbstractForm.ts
248
348
  var AbstractForm = class extends AbstractPage {
249
349
  containerCssSelector = "";
250
350
  containerBy;
@@ -291,42 +391,22 @@ var AbstractForm = class extends AbstractPage {
291
391
  */
292
392
  async getTitleText() {
293
393
  if (await this.isModal()) {
294
- const titleEl2 = await this.driver.findElement(By5.css(`${this.popupContainerCssSelector} .popup-title`));
394
+ const titleEl2 = await this.driver.findElement(By6.css(`${this.popupContainerCssSelector} .popup-title`));
295
395
  return titleEl2.getText();
296
396
  }
297
- let titleEl = await this.driver.findElement(By5.className("main-toolbar-form-title"));
397
+ let titleEl = await this.driver.findElement(By6.className("main-toolbar-form-title"));
298
398
  return titleEl.getText();
299
399
  }
400
+ button(name) {
401
+ return new FormButton(this.containerCssSelector, this.formName, name, this.driver);
402
+ }
300
403
  };
301
404
 
302
405
  // src/pageObjects/elements/Forms/FormEdit.ts
303
- import { By as By12 } from "selenium-webdriver";
304
-
305
- // src/utils/createDataTestId.ts
306
- function createDataTestId(formName, itemType, itemName) {
307
- return `${formName}-${itemType}-${itemName}`;
308
- }
309
- function createFieldTestId(formName, itemName) {
310
- return createDataTestId(formName, "form_field" /* FORM_FIELD */, itemName);
311
- }
312
- function createGroupTestId(formName, itemName) {
313
- return createDataTestId(formName, "group" /* GROUP */, itemName);
314
- }
315
- function createFilterTestId(formName, itemName, layout) {
316
- return createDataTestId(formName, "filter" /* FILTER */, itemName) + `-${layout}`;
317
- }
318
- function createDocFilterTestId(formName, itemName) {
319
- return createFilterTestId(formName, itemName, "dock-panel-filter" /* DOCK_PANEL */);
320
- }
321
- function createLayoutFilterTestId(formName, itemName) {
322
- return createFilterTestId(formName, itemName, "layout-filter" /* LAYOUT */);
323
- }
324
- function createTableId(formName) {
325
- return `${"table" /* TABLE */}-${formName}`;
326
- }
406
+ import { By as By15 } from "selenium-webdriver";
327
407
 
328
408
  // src/pageObjects/elements/Editors/AbstractEditor.ts
329
- import { By as By6, Key } from "selenium-webdriver";
409
+ import { By as By7, Key } from "selenium-webdriver";
330
410
 
331
411
  // src/pageObjects/elements/Editors/ClearStrategy/InputClearStrategy.ts
332
412
  var InputClearStrategy = class {
@@ -346,7 +426,7 @@ var AbstractDXEditorWithInput = class extends AbstractElementWithParent {
346
426
  return `${this.getFullCssSelector()} .dx-texteditor-input`;
347
427
  }
348
428
  async getInputElement() {
349
- return this.driver.findElement(By6.css(this.getInputCssSelector()));
429
+ return this.driver.findElement(By7.css(this.getInputCssSelector()));
350
430
  }
351
431
  async getInputValue() {
352
432
  const inputEl = await this.getInputElement();
@@ -391,6 +471,22 @@ var NumberEditor = class extends AbstractDXEditorWithInput {
391
471
  }
392
472
  };
393
473
 
474
+ // src/pageObjects/elements/Editors/types.ts
475
+ var ControlClass = /* @__PURE__ */ ((ControlClass2) => {
476
+ ControlClass2["Text"] = "text-control";
477
+ ControlClass2["TextArea"] = "text-area-control";
478
+ ControlClass2["Number"] = "number-control";
479
+ ControlClass2["CheckBox"] = "check-box";
480
+ ControlClass2["Multiselect"] = "multi-select-control";
481
+ ControlClass2["Select"] = "select-control";
482
+ ControlClass2["Switch"] = "switch-control";
483
+ ControlClass2["Date"] = "date-control";
484
+ ControlClass2["SingleDateRange"] = "single-date-range-control";
485
+ ControlClass2["BooleanSelector"] = "buttons-group";
486
+ ControlClass2["ButtonGroup"] = "button-group-field";
487
+ return ControlClass2;
488
+ })(ControlClass || {});
489
+
394
490
  // src/pageObjects/AbstractFormElement.ts
395
491
  var AbstractFormElement = class extends AbstractElementWithParent {
396
492
  constructor(parentCssSelector, elementCssSelector, driver) {
@@ -418,20 +514,17 @@ var CheckBox = class extends AbstractElementWithParent {
418
514
  };
419
515
 
420
516
  // src/pageObjects/elements/Editors/SelectBoxEditor.ts
421
- import { By as By8, Key as Key2 } from "selenium-webdriver";
517
+ import { By as By9, Key as Key2 } from "selenium-webdriver";
422
518
 
423
519
  // src/utils/xpathHelper.ts
424
520
  var XPathHelper = class {
425
- static getRoleXpath(role) {
426
- return `//div[@role='${role}']`;
427
- }
428
521
  static getClassAndValueXpath(cssClass, value) {
429
- return `//div[contains(@class, '${cssClass}') and contains(.,'${value}')]`;
522
+ return `div[contains(@class, '${cssClass}') and contains(.,'${value}')]`;
430
523
  }
431
524
  };
432
525
 
433
526
  // src/pageObjects/elements/Editors/ClearStrategy/ClearButtonStrategy.ts
434
- import { By as By7 } from "selenium-webdriver";
527
+ import { By as By8 } from "selenium-webdriver";
435
528
  var DX_TEXTEDITOR_EMPTY = "dx-texteditor-empty";
436
529
  var DX_CLEAR_BUTTON_AREA = "dx-clear-button-area";
437
530
  var ClearButtonStrategy = class {
@@ -442,7 +535,7 @@ var ClearButtonStrategy = class {
442
535
  this._driver = driver;
443
536
  }
444
537
  async isEmptyEditorField() {
445
- const editorContainer = await this._driver.findElement(By7.css(this.editorContainerClass));
538
+ const editorContainer = await this._driver.findElement(By8.css(this.editorContainerClass));
446
539
  const classAttribute = await editorContainer.getAttribute("class");
447
540
  return classAttribute.includes(DX_TEXTEDITOR_EMPTY);
448
541
  }
@@ -451,18 +544,31 @@ var ClearButtonStrategy = class {
451
544
  throw new Error("This field is already empty");
452
545
  }
453
546
  const clearBtnSelector = `${this.editorContainerClass} .${DX_CLEAR_BUTTON_AREA}`;
454
- const clearBtn = await this._driver.findElement(By7.css(clearBtnSelector));
547
+ const clearBtn = await this._driver.findElement(By8.css(clearBtnSelector));
455
548
  await click(clearBtn, this._driver);
456
549
  }
457
550
  };
458
551
 
459
552
  // src/pageObjects/elements/Editors/SelectBoxEditor.ts
460
553
  var SELECT_BOX_OPTION_TEXT_CONTAINER_CLASS = "d5-multi-select-item";
461
- var SELECT_BOX_ELEMENT_ROLE = "option";
462
- var combinedValueXpath = (value) => `${XPathHelper.getRoleXpath(SELECT_BOX_ELEMENT_ROLE)}${XPathHelper.getClassAndValueXpath(
463
- SELECT_BOX_OPTION_TEXT_CONTAINER_CLASS,
464
- value
465
- )}`;
554
+ var combinedValueXpath = (value) => `//body/div[@id="root"]/div[contains(@class, "dx-overlay-wrapper")]//${XPathHelper.getClassAndValueXpath(SELECT_BOX_OPTION_TEXT_CONTAINER_CLASS, value)}`;
555
+ var dropDownOptionClick = async (optionValue, driver, delay = true) => {
556
+ const { implicit } = await driver.manage().getTimeouts();
557
+ let optElement = null;
558
+ const timeout = delay ? implicit : 200;
559
+ let err = null;
560
+ try {
561
+ await driver.manage().setTimeouts({ implicit: timeout });
562
+ optElement = await driver.findElement(By9.xpath(combinedValueXpath(optionValue)));
563
+ await click(optElement, driver);
564
+ } catch (e) {
565
+ err = new Error(`Item not found: "${optionValue}"`);
566
+ } finally {
567
+ await driver.manage().setTimeouts({ implicit });
568
+ }
569
+ if (err)
570
+ throw err;
571
+ };
466
572
  var SelectBoxEditor = class extends AbstractDXEditorWithInput {
467
573
  constructor(parentCssSelector, elementCssSelector, driver) {
468
574
  super(parentCssSelector, elementCssSelector, driver);
@@ -471,9 +577,12 @@ var SelectBoxEditor = class extends AbstractDXEditorWithInput {
471
577
  async setSelectInputValue(value) {
472
578
  const inputEl = await this.getInputElement();
473
579
  await click(inputEl, this.driver);
474
- await inputEl.sendKeys(value, Key2.ENTER);
475
- const optElement = await inputEl.findElement(By8.xpath(combinedValueXpath(value)));
476
- await click(optElement, this.driver);
580
+ try {
581
+ await dropDownOptionClick(value, this.driver, false);
582
+ } catch {
583
+ await inputEl.sendKeys(value, Key2.ENTER);
584
+ await dropDownOptionClick(value, this.driver);
585
+ }
477
586
  }
478
587
  async getValue() {
479
588
  const value = await super.getInputValue();
@@ -512,7 +621,7 @@ var SwitchEditor = class extends AbstractElementWithParent {
512
621
  };
513
622
 
514
623
  // src/pageObjects/elements/Editors/TagBox.ts
515
- import { By as By9 } from "selenium-webdriver";
624
+ import { By as By10 } from "selenium-webdriver";
516
625
  var TAGS_SELECTOR = ".dx-tag .tag-text";
517
626
  var DX_TAG_CONTAINER = "dx-tag-container";
518
627
  var DX_TEXTEDITOR_EMPTY2 = "dx-texteditor-empty";
@@ -533,31 +642,35 @@ var TagBox = class extends AbstractDXEditorWithInput {
533
642
  await this.confirmSelection();
534
643
  }
535
644
  async waitOptionSelection() {
536
- const option = await this.driver.findElement(By9.css(TAG_BOX_LIST_ITEM_SELECTOR));
645
+ const option = await this.driver.findElement(By10.css(TAG_BOX_LIST_ITEM_SELECTOR));
537
646
  await wait(() => option.isDisplayed(), this.driver);
538
647
  }
539
648
  async selectOption(inputEl, value, lastElement) {
540
- await inputEl.sendKeys(value);
541
- const optElement = await inputEl.findElement(By9.xpath(combinedValueXpath(value)));
542
- await click(optElement, this.driver);
649
+ try {
650
+ await dropDownOptionClick(value, this.driver, false);
651
+ } catch {
652
+ await inputEl.sendKeys(value);
653
+ await dropDownOptionClick(value, this.driver);
654
+ }
543
655
  await this.waitOptionSelection();
544
656
  if (value !== lastElement) {
545
657
  await inputEl.clear();
546
658
  }
547
659
  }
548
660
  async confirmSelection() {
549
- const btnOk = await this.driver.findElement(By9.css(BTN_OK_SELECTOR));
661
+ const btnOk = await this.driver.findElement(By10.css(BTN_OK_SELECTOR));
550
662
  await click(btnOk, this.driver);
551
663
  }
552
664
  async getTagBoxInputValue() {
553
665
  if (await this.isTagBoxEmpty()) {
554
666
  return [];
555
667
  }
556
- const tags = await this.driver.findElements(By9.css(`${this.getFullCssSelector()} .${DX_TAG_CONTAINER} ${TAGS_SELECTOR}`));
668
+ const tags = await this.driver.findElements(
669
+ By10.css(`${this.getFullCssSelector()} .${DX_TAG_CONTAINER} ${TAGS_SELECTOR}`)
670
+ );
557
671
  const values = [];
558
672
  for (const tag of tags) {
559
- const text = await tag.getText();
560
- values.push(text);
673
+ values.push(await tag.getAttribute("textContent"));
561
674
  }
562
675
  return values;
563
676
  }
@@ -582,24 +695,26 @@ var TagBox = class extends AbstractDXEditorWithInput {
582
695
  throw new Error(`The tag with the text: ${itemText} was not found`);
583
696
  }
584
697
  const clearBtnTestId = byTestIdCssSelector(`clear-button-${itemText}`);
585
- const clearBtn = await this.driver.findElement(By9.css(`${this.getFullCssSelector()} .${DX_TAG_CONTAINER} ${clearBtnTestId}`));
698
+ const clearBtn = await this.driver.findElement(
699
+ By10.css(`${this.getFullCssSelector()} .${DX_TAG_CONTAINER} ${clearBtnTestId}`)
700
+ );
586
701
  await click(clearBtn, this.driver);
587
702
  }
588
703
  };
589
704
 
590
705
  // src/pageObjects/elements/Editors/ButtonGroup.ts
591
- import { By as By10 } from "selenium-webdriver";
706
+ import { By as By11 } from "selenium-webdriver";
592
707
  var ITEM_CLASS = "dx-buttongroup-item";
593
708
  var SELECTED_CLASS = "dx-state-selected";
594
709
  var ButtonGroup = class extends AbstractElementWithParent {
595
710
  getItems() {
596
- return this.driver.findElements(By10.css(`${this.getFullCssSelector()} .${ITEM_CLASS}`));
711
+ return this.driver.findElements(By11.css(`${this.getFullCssSelector()} .${ITEM_CLASS}`));
597
712
  }
598
713
  getDataValue(el) {
599
714
  return el.getAttribute("data-value");
600
715
  }
601
716
  async getValue() {
602
- const selectedEl = await this.driver.findElement(By10.css(`${this.getFullCssSelector()} .${ITEM_CLASS}.${SELECTED_CLASS}`));
717
+ const selectedEl = await this.driver.findElement(By11.css(`${this.getFullCssSelector()} .${ITEM_CLASS}.${SELECTED_CLASS}`));
603
718
  return this.getDataValue(selectedEl);
604
719
  }
605
720
  async setValue(value) {
@@ -632,26 +747,67 @@ var BooleanSelector = class extends ButtonGroup {
632
747
  }
633
748
  };
634
749
 
635
- // src/pageObjects/elements/Editors/DateEditor.ts
636
- import { By as By11, Key as Key3 } from "selenium-webdriver";
637
- var DateEditor = class extends AbstractDXEditorWithInput {
750
+ // src/pageObjects/elements/Editors/Date/SingleDateEditor.ts
751
+ import { By as By13 } from "selenium-webdriver";
752
+
753
+ // src/pageObjects/elements/Editors/Date/BaseDateEditor.ts
754
+ import { By as By12, Key as Key3 } from "selenium-webdriver";
755
+
756
+ // src/pageObjects/elements/Editors/Date/utils.ts
757
+ var formatDMYDate = (date) => {
758
+ const [year, month, day] = date.toJSON().split("T")[0].split("-");
759
+ return `${day}${month}${year}`;
760
+ };
761
+
762
+ // src/pageObjects/elements/Editors/Date/BaseDateEditor.ts
763
+ var BTN_CALENDAR_POPOVER_OPEN_SELECTOR = "calendar-popover-open-button";
764
+ var BTN_CALENDAR_POPOVER_DATE_FROM_INPUT_SELECTOR = "DateRange__inputs-item--dateFrom";
765
+ var BTN_CALENDAR_POPOVER_DATE_TO_INPUT_SELECTOR = "DateRange__inputs-item--dateTo";
766
+ var BTN_SAVE_SELECTOR = "DateRange__button-save";
767
+ var BaseDateEditor = class extends AbstractDXEditorWithInput {
638
768
  constructor(parentCssSelector, elementCssSelector, driver) {
639
769
  super(parentCssSelector, elementCssSelector, driver);
640
770
  this.setClearStrategy(new InputClearStrategy());
641
771
  }
642
- async getDateElement() {
643
- return this.driver.findElement(By11.css(this.getFullCssSelector() + " .dx-dropdowneditor-input-wrapper input[type=hidden]"));
644
- }
645
772
  async setDateValue(value) {
646
- const dateEl = await this.getInputElement();
647
- const stringDate = value.toJSON().split("T")[0];
648
- const dateArr = stringDate.split("-");
649
- const [year, month, day] = dateArr;
650
- const keys = day + month + year;
651
- await click(dateEl, this.driver);
652
773
  const actions = this.driver.actions({ async: true });
653
- await actions.move({ origin: dateEl }).sendKeys(Key3.HOME).perform();
654
- await actions.move({ origin: dateEl }).sendKeys(keys, Key3.ENTER).perform();
774
+ const dateField = await this.driver.findElement(By12.css(`${this.getFullCssSelector()}`));
775
+ const dateFieldDataTestID = await this.getDataTestId();
776
+ const calendarPopoverSelector = byTestIdCssSelector(`${dateFieldDataTestID}-calendar-popover`);
777
+ const dateInputEl = await this.getInputElement();
778
+ await dateInputEl.clear();
779
+ if (Array.isArray(value)) {
780
+ const formattedDates = value.map(formatDMYDate);
781
+ const button = await dateField.findElement(By12.css(`.${BTN_CALENDAR_POPOVER_OPEN_SELECTOR}`));
782
+ await button.click();
783
+ const calendarPopoverElement = await this.driver.findElement(By12.css(calendarPopoverSelector));
784
+ const dateFromInput = await calendarPopoverElement.findElement(By12.css(`.${BTN_CALENDAR_POPOVER_DATE_FROM_INPUT_SELECTOR} .dx-texteditor-input`));
785
+ const dateToInput = await calendarPopoverElement.findElement(By12.css(`.${BTN_CALENDAR_POPOVER_DATE_TO_INPUT_SELECTOR} .dx-texteditor-input`));
786
+ await dateFromInput.click();
787
+ await dateFromInput.sendKeys(formattedDates[0]);
788
+ await dateToInput.click();
789
+ await actions.move({ origin: dateInputEl }).sendKeys(Key3.HOME).perform();
790
+ await dateToInput.sendKeys(formattedDates[1]);
791
+ await actions.move({ origin: dateInputEl }).sendKeys(Key3.ENTER).perform();
792
+ const btnOk = await this.driver.findElement(By12.css(`.${BTN_SAVE_SELECTOR}`));
793
+ await btnOk.click();
794
+ } else {
795
+ const formattedDate = formatDMYDate(value);
796
+ await click(dateInputEl, this.driver);
797
+ await actions.move({ origin: dateInputEl }).sendKeys(Key3.HOME).perform();
798
+ await actions.move({ origin: dateInputEl }).sendKeys(formattedDate, Key3.ENTER).perform();
799
+ }
800
+ }
801
+ };
802
+
803
+ // src/pageObjects/elements/Editors/Date/SingleDateEditor.ts
804
+ var SingleDateEditor = class extends BaseDateEditor {
805
+ constructor(parentCssSelector, elementCssSelector, driver) {
806
+ super(parentCssSelector, elementCssSelector, driver);
807
+ this.setClearStrategy(new InputClearStrategy());
808
+ }
809
+ async getDateElement() {
810
+ return this.driver.findElement(By13.css(this.getFullCssSelector() + " .dx-dropdowneditor-input-wrapper input[type=hidden]"));
655
811
  }
656
812
  async getDateValue() {
657
813
  const inputEl = await this.getDateElement();
@@ -669,27 +825,105 @@ var DateEditor = class extends AbstractDXEditorWithInput {
669
825
  }
670
826
  };
671
827
 
828
+ // src/pageObjects/elements/Editors/Date/DateRangeEditor.ts
829
+ import { By as By14 } from "selenium-webdriver";
830
+ var DateRangeEditor = class extends BaseDateEditor {
831
+ constructor(parentCssSelector, elementCssSelector, driver) {
832
+ super(parentCssSelector, elementCssSelector, driver);
833
+ this.setClearStrategy(new InputClearStrategy());
834
+ }
835
+ async getDateElement() {
836
+ return this.driver.findElement(By14.css(this.getFullCssSelector() + " .dx-texteditor-input"));
837
+ }
838
+ async getDateValue() {
839
+ const inputEl = await this.getDateElement();
840
+ const dateFromStr = await inputEl.getAttribute("datefrom");
841
+ const dateToStr = await inputEl.getAttribute("dateto");
842
+ const dateFrom = new Date(dateFromStr);
843
+ const dateTo = new Date(dateToStr);
844
+ return [dateFrom, dateTo];
845
+ }
846
+ async getValue() {
847
+ const values = await this.getDateValue();
848
+ return !values.length ? null : values;
849
+ }
850
+ setValue(value) {
851
+ if (typeof value === "object") {
852
+ return this.setDateValue(value);
853
+ }
854
+ throw new Error(`Value is incorrect. It should be Object`);
855
+ }
856
+ };
857
+
858
+ // src/pageObjects/elements/Editors/Date/DateEditor.ts
859
+ var DateEditor = class extends AbstractDXEditorWithInput {
860
+ editorInstance = null;
861
+ initPromise;
862
+ constructor(parentCssSelector, elementCssSelector, driver) {
863
+ super(parentCssSelector, elementCssSelector, driver);
864
+ this.initPromise = this.init(parentCssSelector, elementCssSelector, driver);
865
+ }
866
+ async init(parentCssSelector, elementCssSelector, driver) {
867
+ await this.updateEditorInstance(parentCssSelector, elementCssSelector, driver);
868
+ }
869
+ async updateEditorInstance(parentCssSelector, elementCssSelector, driver) {
870
+ const elementInstance = new AbstractFormElement(parentCssSelector, elementCssSelector, driver);
871
+ const classString = await elementInstance.getClasses();
872
+ switch (true) {
873
+ case classString.includes("date-control" /* Date */):
874
+ this.editorInstance = new SingleDateEditor(parentCssSelector, elementCssSelector, driver);
875
+ break;
876
+ case classString.includes("single-date-range-control" /* SingleDateRange */):
877
+ this.editorInstance = new DateRangeEditor(parentCssSelector, elementCssSelector, driver);
878
+ break;
879
+ default:
880
+ this.editorInstance = new SingleDateEditor(parentCssSelector, elementCssSelector, driver);
881
+ }
882
+ }
883
+ async ensureInitialized() {
884
+ if (!this.editorInstance) {
885
+ await this.initPromise;
886
+ }
887
+ }
888
+ async setValue(value) {
889
+ await this.ensureInitialized();
890
+ if (this.editorInstance) {
891
+ await this.editorInstance.setValue(value);
892
+ return await this.updateEditorInstance(this.parentCssSelector, this.elementCssSelector, this.driver);
893
+ }
894
+ throw new Error("Editor instance is not initialized.");
895
+ }
896
+ async getValue() {
897
+ await this.ensureInitialized();
898
+ if (this.editorInstance) {
899
+ return this.editorInstance.getValue();
900
+ }
901
+ throw new Error("Editor instance is not initialized.");
902
+ }
903
+ };
904
+
672
905
  // src/pageObjects/elements/Editors/editorFactory.ts
673
906
  var editorFactory = async (parentCssSelector, elementCssSelector, driver) => {
674
907
  const elementInstance = new AbstractFormElement(parentCssSelector, elementCssSelector, driver);
675
908
  const classSting = await elementInstance.getClasses();
676
- if (classSting.includes("text-control"))
909
+ if ((classSting.includes("text-control" /* Text */) || classSting.includes("text-area-control" /* TextArea */)) && !classSting.includes("single-date-range-control" /* SingleDateRange */))
677
910
  return new TextEditor(parentCssSelector, elementCssSelector, driver);
678
- if (classSting.includes("number-control"))
911
+ if (classSting.includes("number-control" /* Number */))
679
912
  return new NumberEditor(parentCssSelector, elementCssSelector, driver);
680
- if (classSting.includes("check-box"))
913
+ if (classSting.includes("check-box" /* CheckBox */))
681
914
  return new CheckBox(parentCssSelector, elementCssSelector, driver);
682
- if (classSting.includes("multi-select-control"))
915
+ if (classSting.includes("multi-select-control" /* Multiselect */))
683
916
  return new TagBox(parentCssSelector, elementCssSelector, driver);
684
- if (classSting.includes("select-control"))
917
+ if (classSting.includes("select-control" /* Select */))
685
918
  return new SelectBoxEditor(parentCssSelector, elementCssSelector, driver);
686
- if (classSting.includes("switch-control"))
919
+ if (classSting.includes("switch-control" /* Switch */))
687
920
  return new SwitchEditor(parentCssSelector, elementCssSelector, driver);
688
- if (classSting.includes("date-control"))
921
+ if (classSting.includes("date-control" /* Date */) || classSting.includes("single-date-range-control" /* SingleDateRange */)) {
689
922
  return new DateEditor(parentCssSelector, elementCssSelector, driver);
690
- if (classSting.includes("buttons-group"))
923
+ }
924
+ if (classSting.includes("buttons-group" /* BooleanSelector */))
691
925
  return new BooleanSelector(parentCssSelector, elementCssSelector, driver);
692
- if (classSting.includes("button-group-field"))
926
+ if (classSting.includes("button-group-field" /* ButtonGroup */))
693
927
  return new ButtonGroup(parentCssSelector, elementCssSelector, driver);
694
928
  throw new Error("Unknown type of editor. Please write ticket to the support");
695
929
  };
@@ -749,6 +983,16 @@ var AbstractEditor = class extends AbstractElementWithParent {
749
983
  }
750
984
  return this.editor.remove(itemText);
751
985
  }
986
+ /**
987
+ * Возвращает значение true|false в зависимости readOnly поле или нет
988
+ * @example
989
+ * expect(await formEdit.field('NumberFld').isReadonly()).toBe(true);
990
+ * expect(await formEdit.field('TextFld').isReadonly()).toBe(false);
991
+ */
992
+ async isReadonly() {
993
+ await this.initEditor();
994
+ return this.editor.isReadonly();
995
+ }
752
996
  };
753
997
 
754
998
  // src/pageObjects/elements/FormField.ts
@@ -807,7 +1051,8 @@ var FormGroup = class extends AbstractElementWithParent {
807
1051
 
808
1052
  // src/pageObjects/elements/Forms/FormEdit.ts
809
1053
  var FormEdit = class extends AbstractForm {
810
- saveButtonBy = By12.id("button-save");
1054
+ saveButtonBy = By15.id("button-save");
1055
+ closeButtonBy = By15.id("button-cancel");
811
1056
  constructor(driver) {
812
1057
  super(driver);
813
1058
  this.popupContainerCssSelector = `.popup .form-edit-${this.formName}`;
@@ -856,19 +1101,30 @@ var FormEdit = class extends AbstractForm {
856
1101
  await wait(async () => !await this.isSaveButtonDisabled(), this.driver, "Button is disabled");
857
1102
  await click(saveButton, this.driver);
858
1103
  }
1104
+ /**
1105
+ * Нажатие на кнопку Закрить
1106
+ * @example
1107
+ * const formEdit = new MyForm();
1108
+ * //...
1109
+ * await formEdit.closeButtonClick();
1110
+ */
1111
+ async closeButtonClick() {
1112
+ const closeButton = await this.driver.findElement(this.closeButtonBy);
1113
+ await click(closeButton, this.driver);
1114
+ }
859
1115
  };
860
1116
 
861
1117
  // src/pageObjects/elements/Table/Table.ts
862
- import { By as By17 } from "selenium-webdriver";
1118
+ import { By as By20 } from "selenium-webdriver";
863
1119
 
864
1120
  // src/pageObjects/elements/Table/elements/Row.ts
865
- import { By as By15 } from "selenium-webdriver";
1121
+ import { By as By18 } from "selenium-webdriver";
866
1122
 
867
1123
  // src/pageObjects/elements/Table/elements/Cell.ts
868
- import { By as By14 } from "selenium-webdriver";
1124
+ import { By as By17 } from "selenium-webdriver";
869
1125
 
870
1126
  // src/pageObjects/elements/Table/utils.ts
871
- import { By as By13 } from "selenium-webdriver";
1127
+ import { By as By16 } from "selenium-webdriver";
872
1128
  function getCssRowByIndexSelector(index) {
873
1129
  return `tr[aria-rowindex="${transformInputIndex(index)}"]`;
874
1130
  }
@@ -895,9 +1151,18 @@ var Cell = class extends AbstractElementWithParent {
895
1151
  this.elementCssSelector = getCssCellByIndexSelector(index);
896
1152
  }
897
1153
  async getBooleanValue(cellEl) {
898
- const booleanEl = await cellEl.findElement(By14.className("boolean-widget"));
1154
+ const booleanEl = await cellEl.findElement(By17.className("boolean-widget"));
899
1155
  return await booleanEl.getAttribute("aria-checked") === "true" ? 1 : 0;
900
1156
  }
1157
+ async getTagsValue(cellEl) {
1158
+ const tagsCssSelector = ".multiselect-container .multiselect-cell";
1159
+ const tags = await cellEl.findElements(By17.css(tagsCssSelector));
1160
+ const values = [];
1161
+ for (const tag of tags) {
1162
+ values.push(await tag.getAttribute("textContent"));
1163
+ }
1164
+ return values;
1165
+ }
901
1166
  async getElement() {
902
1167
  if (this._index == null) {
903
1168
  this.index = await this.getCellIndex();
@@ -907,9 +1172,10 @@ var Cell = class extends AbstractElementWithParent {
907
1172
  async getValue() {
908
1173
  const cellEl = await this.getElement();
909
1174
  const cellElClass = await cellEl.getAttribute("class");
910
- if (cellElClass.includes("boolean-column")) {
1175
+ if (cellElClass.includes("boolean-column" /* Boolean */))
911
1176
  return this.getBooleanValue(cellEl);
912
- }
1177
+ if (cellElClass.includes("tags-column" /* Tags */))
1178
+ return this.getTagsValue(cellEl);
913
1179
  return cellEl.getText();
914
1180
  }
915
1181
  getIndex() {
@@ -930,9 +1196,14 @@ var Row = class extends AbstractElementWithParent {
930
1196
  this.getColumnBy = getColumnBy;
931
1197
  }
932
1198
  _getCell({ index, name, title }) {
933
- return new Cell(this.getFullCssSelector(), () => {
934
- return this.getColumnBy({ title, name }).getIndex();
935
- }, index, this.driver);
1199
+ return new Cell(
1200
+ this.getFullCssSelector(),
1201
+ () => {
1202
+ return this.getColumnBy({ title, name }).getIndex();
1203
+ },
1204
+ index,
1205
+ this.driver
1206
+ );
936
1207
  }
937
1208
  getCellByIndex(index) {
938
1209
  return this._getCell({ index });
@@ -946,10 +1217,14 @@ var Row = class extends AbstractElementWithParent {
946
1217
  async select() {
947
1218
  const rowEl = await this.getElement();
948
1219
  await click(rowEl, this.driver);
949
- await wait(async () => {
950
- const classes = await this.getClasses();
951
- return classes.includes(DX_SELECTION_CLASS);
952
- }, this.driver, "Cannot select row");
1220
+ await wait(
1221
+ async () => {
1222
+ const classes = await this.getClasses();
1223
+ return classes.includes(DX_SELECTION_CLASS);
1224
+ },
1225
+ this.driver,
1226
+ "Cannot select row"
1227
+ );
953
1228
  }
954
1229
  async isSelected() {
955
1230
  const result = await this.getAttribute("aria-selected");
@@ -959,7 +1234,7 @@ var Row = class extends AbstractElementWithParent {
959
1234
  return this.index;
960
1235
  }
961
1236
  async getCells() {
962
- const cells = await this.driver.findElements(By15.css(`${this.getFullCssSelector()} td[role="gridcell"]`));
1237
+ const cells = await this.driver.findElements(By18.css(`${this.getFullCssSelector()} td[role="gridcell"]`));
963
1238
  const result = [];
964
1239
  cells.forEach((_, index) => {
965
1240
  const newCell = this.getCellByIndex(index);
@@ -969,14 +1244,22 @@ var Row = class extends AbstractElementWithParent {
969
1244
  }
970
1245
  async clickInlineButton(buttonClass) {
971
1246
  const FIXED_TABLE_CSS_SELECTOR = ".dx-fixed-columns .dx-datagrid-content.dx-datagrid-content-fixed";
972
- const buttonCssSelector = `.${DX_DATA_ROW_CLASS}[aria-rowindex="${transformInputIndex(this.index)}"] .${buttonClass}`;
973
- const button = await this.driver.findElement(By15.css(`${this.parentCssSelector} ${FIXED_TABLE_CSS_SELECTOR} ${buttonCssSelector}`));
1247
+ const buttonCssSelector = `.${DX_DATA_ROW_CLASS}[aria-rowindex="${transformInputIndex(
1248
+ this.index
1249
+ )}"] .${buttonClass}`;
1250
+ const button = await this.driver.findElement(
1251
+ By18.css(`${this.parentCssSelector} ${FIXED_TABLE_CSS_SELECTOR} ${buttonCssSelector}`)
1252
+ );
974
1253
  return click(button, this.driver);
975
1254
  }
976
1255
  async checkEditingMode(isEditing, msg) {
977
- await wait(async () => {
978
- return (await this.getClasses()).includes(DX_ROW_EDIT_CLASS) === isEditing;
979
- }, this.driver, msg);
1256
+ await wait(
1257
+ async () => {
1258
+ return (await this.getClasses()).includes(DX_ROW_EDIT_CLASS) === isEditing;
1259
+ },
1260
+ this.driver,
1261
+ msg
1262
+ );
980
1263
  }
981
1264
  async edit() {
982
1265
  await this.clickInlineButton("edit");
@@ -993,19 +1276,18 @@ var Row = class extends AbstractElementWithParent {
993
1276
  };
994
1277
 
995
1278
  // src/pageObjects/elements/Table/elements/Column.ts
996
- import { By as By16 } from "selenium-webdriver";
997
- var getHeaderCssSelector = () => {
998
- return ".dx-datagrid-headers .dx-datagrid-content:not(.dx-datagrid-content-fixed)";
999
- };
1279
+ import { By as By19 } from "selenium-webdriver";
1000
1280
  var Column = class extends AbstractElementWithParent {
1001
1281
  _index;
1002
1282
  _caption;
1003
1283
  _name;
1004
- constructor({ parentCssSelector, name, caption, index, driver }) {
1284
+ headerCssSelector;
1285
+ constructor({ parentCssSelector, headerCssSelector, name, caption, index, driver }) {
1005
1286
  super(parentCssSelector, "", driver);
1006
1287
  this._name = name;
1007
1288
  this.index = index;
1008
1289
  this._caption = caption;
1290
+ this.headerCssSelector = headerCssSelector;
1009
1291
  }
1010
1292
  set index(index) {
1011
1293
  this._index = index;
@@ -1019,7 +1301,9 @@ var Column = class extends AbstractElementWithParent {
1019
1301
  return super.getElement();
1020
1302
  }
1021
1303
  async getColumnHeaderIndexBy(cssSelector) {
1022
- const column = await this.driver.findElement(By16.css(`${this.parentCssSelector} ${getHeaderCssSelector()} ${cssSelector}`));
1304
+ const column = await this.driver.findElement(
1305
+ By19.css(`${this.parentCssSelector} ${this.headerCssSelector} ${cssSelector}`)
1306
+ );
1023
1307
  return transformOutputIndex(await column.getAttribute("aria-colindex"));
1024
1308
  }
1025
1309
  async getIndexByCaption() {
@@ -1051,9 +1335,11 @@ var Column = class extends AbstractElementWithParent {
1051
1335
  // src/pageObjects/elements/Table/Table.ts
1052
1336
  var Table = class extends AbstractElementWithParent {
1053
1337
  formName;
1054
- constructor(parentCssSelector, formName, driver) {
1338
+ headerCssSelector;
1339
+ constructor(parentCssSelector, headerCssSelector, formName, driver) {
1055
1340
  super(parentCssSelector, `#${createTableId(formName)}`, driver);
1056
1341
  this.formName = formName;
1342
+ this.headerCssSelector = headerCssSelector;
1057
1343
  }
1058
1344
  getColumnBy = (args) => {
1059
1345
  if (args.title) {
@@ -1074,6 +1360,7 @@ var Table = class extends AbstractElementWithParent {
1074
1360
  getColumnByTitle = (title) => {
1075
1361
  return new Column({
1076
1362
  parentCssSelector: this.getFullCssSelector(),
1363
+ headerCssSelector: this.headerCssSelector,
1077
1364
  caption: title,
1078
1365
  driver: this.driver
1079
1366
  });
@@ -1081,6 +1368,7 @@ var Table = class extends AbstractElementWithParent {
1081
1368
  getColumnByName = (name) => {
1082
1369
  return new Column({
1083
1370
  parentCssSelector: this.getFullCssSelector(),
1371
+ headerCssSelector: this.headerCssSelector,
1084
1372
  name,
1085
1373
  driver: this.driver
1086
1374
  });
@@ -1089,7 +1377,7 @@ var Table = class extends AbstractElementWithParent {
1089
1377
  return this.getRowByIndex(index).select();
1090
1378
  }
1091
1379
  async getRows() {
1092
- const rows = await this.driver.findElements(By17.css(`${this.getFullCssSelector()} .dx-row.dx-data-row`));
1380
+ const rows = await this.driver.findElements(By20.css(`${this.getFullCssSelector()} .dx-row.dx-data-row`));
1093
1381
  const result = [];
1094
1382
  rows.forEach((_, index) => {
1095
1383
  const newRow = new Row(this.getFullCssSelector(), index, this.driver, this.getColumnBy);
@@ -1098,7 +1386,9 @@ var Table = class extends AbstractElementWithParent {
1098
1386
  return result;
1099
1387
  }
1100
1388
  async getColumns() {
1101
- const columns = await this.driver.findElements(By17.css(`${this.getFullCssSelector()} ${getHeaderCssSelector()} td[role="columnheader"]`));
1389
+ const columns = await this.driver.findElements(
1390
+ By20.css(`${this.getFullCssSelector()} ${this.headerCssSelector} td[role="columnheader"]`)
1391
+ );
1102
1392
  const result = [];
1103
1393
  columns.forEach((_, index) => {
1104
1394
  const newCol = new Column({
@@ -1125,24 +1415,6 @@ var Table = class extends AbstractElementWithParent {
1125
1415
  }
1126
1416
  };
1127
1417
 
1128
- // src/pageObjects/elements/TableToolbar/AbstractButton.ts
1129
- var AbstractButton = class extends AbstractElementWithParent {
1130
- constructor(parentCssSelector, elementCssSelector, driver) {
1131
- super(parentCssSelector, elementCssSelector, driver);
1132
- }
1133
- async click() {
1134
- const button = await this.getElement();
1135
- await wait(async () => {
1136
- return await button.isDisplayed() && !await this.isDisabled();
1137
- }, this.driver, this.buttonNotDisplayedError());
1138
- await click(button, this.driver);
1139
- }
1140
- async isDisabled() {
1141
- const button = await this.getElement();
1142
- return await button.getCssValue("pointer-events") === "none";
1143
- }
1144
- };
1145
-
1146
1418
  // src/pageObjects/elements/TableToolbar/ToolbarGroupButton.ts
1147
1419
  var ToolbarGroupButton = class extends AbstractButton {
1148
1420
  name;
@@ -1168,16 +1440,97 @@ var ToolbarButton = class extends AbstractButton {
1168
1440
  }
1169
1441
  };
1170
1442
 
1443
+ // src/pageObjects/elements/TableToolbar/ToolbarMenu.ts
1444
+ import { By as By21 } from "selenium-webdriver";
1445
+
1446
+ // src/utils/typesUtil.ts
1447
+ var types = {
1448
+ "[object Array]": "array",
1449
+ "[object Date]": "date",
1450
+ "[object Object]": "object",
1451
+ "[object String]": "string",
1452
+ "[object Null]": "null"
1453
+ };
1454
+ var type = function(object) {
1455
+ const typeOfObject = Object.prototype.toString.call(object);
1456
+ return typeof object === "object" ? types[typeOfObject] || "object" : typeof object;
1457
+ };
1458
+ var isArray = function(value) {
1459
+ return type(value) === "array";
1460
+ };
1461
+ var isString = function(object) {
1462
+ return typeof object === "string";
1463
+ };
1464
+
1465
+ // src/pageObjects/elements/TableToolbar/ToolbarMenu.ts
1466
+ var SPINDOWN_CLASS = ".dx-icon-spindown";
1467
+ var buttonGroupItemSelector = (formName, name) => byTestIdCssSelector(`ftb-${formName}-${name}`);
1468
+ var getFullCssSelector = (formName, name) => `${buttonGroupItemSelector(formName, name)} ${SPINDOWN_CLASS}`;
1469
+ var buttonByTextXpath = (text) => `.//span[contains(@class, "dx-menu-item-text") and contains(text(), "${text}")]`;
1470
+ var ToolbarMenu = class extends AbstractElementWithParent {
1471
+ _formName;
1472
+ constructor(parentCssSelector, formName, name, driver) {
1473
+ super(parentCssSelector, getFullCssSelector(formName, name), driver);
1474
+ this._formName = formName;
1475
+ }
1476
+ async toggle() {
1477
+ const dropdown = await this.getElement();
1478
+ await click(dropdown, this.driver);
1479
+ }
1480
+ getCssSelectorToButton(name) {
1481
+ return byTestId(`ftb-${this._formName}-${name}`);
1482
+ }
1483
+ buttonNotDisplayedError(name) {
1484
+ return `Toolbar menu button ${name} cannot be clicked. It is not displayed or it is disabled`;
1485
+ }
1486
+ async goToButton(name, selector) {
1487
+ const toolbarMenuItem = this.driver.findElement(selector);
1488
+ await waitElementIsClickable({
1489
+ element: toolbarMenuItem,
1490
+ errorMessage: this.buttonNotDisplayedError(name),
1491
+ driver: this.driver
1492
+ });
1493
+ await click(toolbarMenuItem, this.driver);
1494
+ }
1495
+ async clickButton(name) {
1496
+ await this.toggle();
1497
+ if (isString(name)) {
1498
+ const selector = this.getCssSelectorToButton(name);
1499
+ await this.goToButton(name, selector);
1500
+ }
1501
+ if (isArray(name)) {
1502
+ for (let n of name) {
1503
+ const selector = this.getCssSelectorToButton(n);
1504
+ await this.goToButton(n, selector);
1505
+ }
1506
+ }
1507
+ }
1508
+ async clickButtonByTitle(title) {
1509
+ await this.toggle();
1510
+ if (isString(title)) {
1511
+ const selector = By21.xpath(buttonByTextXpath(title));
1512
+ await this.goToButton(title, selector);
1513
+ }
1514
+ if (isArray(title)) {
1515
+ for (let t of title) {
1516
+ const selector = By21.xpath(buttonByTextXpath(t));
1517
+ await this.goToButton(t, selector);
1518
+ }
1519
+ }
1520
+ }
1521
+ };
1522
+
1171
1523
  // src/pageObjects/elements/TableToolbar/ToolbarItem.ts
1172
1524
  var GROUP_BUTTON_CLASS = "toolbar-group-button";
1173
1525
  var toolbarItemSelector = (form, name) => byTestIdCssSelector(`ftb-${form}-${name}`);
1174
1526
  var ToolbarItem = class extends AbstractElementWithParent {
1175
1527
  _button;
1176
- // private _formName: string;
1528
+ _formName;
1177
1529
  _itemName;
1178
1530
  constructor(parentCssSelector, formName, itemName, driver) {
1179
1531
  super(parentCssSelector, toolbarItemSelector(formName, itemName), driver);
1180
1532
  this._itemName = itemName;
1533
+ this._formName = formName;
1181
1534
  }
1182
1535
  async init() {
1183
1536
  if (this._button)
@@ -1197,6 +1550,9 @@ var ToolbarItem = class extends AbstractElementWithParent {
1197
1550
  await this.init();
1198
1551
  return await this._button.isDisabled();
1199
1552
  }
1553
+ get menu() {
1554
+ return new ToolbarMenu(this.parentCssSelector, this._formName, this._itemName, this.driver);
1555
+ }
1200
1556
  };
1201
1557
 
1202
1558
  // src/pageObjects/elements/TableToolbar/FormToolbar.ts
@@ -1254,7 +1610,7 @@ var FormFilterField = class extends AbstractEditor {
1254
1610
  };
1255
1611
 
1256
1612
  // src/pageObjects/elements/Filters/FilterPanel.ts
1257
- import { By as By18 } from "selenium-webdriver";
1613
+ import { By as By22 } from "selenium-webdriver";
1258
1614
 
1259
1615
  // src/pageObjects/elements/Filters/PanelFilterField.ts
1260
1616
  var PanelFilterField = class extends AbstractEditor {
@@ -1309,7 +1665,7 @@ var FilterPanel = class extends AbstractElement {
1309
1665
  async filterPanelButtons() {
1310
1666
  const selector = `${this.elementCssSelector} ${FILTER_PANEL_SELECTOR} .filter-panel__buttons-panel .dx-button-text`;
1311
1667
  const el = await this.getElement();
1312
- return el.findElements(By18.css(selector));
1668
+ return el.findElements(By22.css(selector));
1313
1669
  }
1314
1670
  constructor(formName, driver) {
1315
1671
  super(driver, drawerSelector(formName));
@@ -1342,16 +1698,19 @@ var FilterPanel = class extends AbstractElement {
1342
1698
  await this.driver.sleep(300);
1343
1699
  }
1344
1700
  async close() {
1345
- const btn = await this.driver.findElement(By18.css(`${this.elementCssSelector} ${CLOSE_SELECTOR}`));
1701
+ const btn = await this.driver.findElement(By22.css(`${this.elementCssSelector} ${CLOSE_SELECTOR}`));
1346
1702
  await click(btn, this.driver);
1347
1703
  }
1348
1704
  };
1349
1705
 
1350
1706
  // src/pageObjects/elements/Forms/ListForm.ts
1707
+ var DATAGRID_HEADER_CSS_SELECTOR = ".dx-datagrid-headers .dx-datagrid-content:not(.dx-datagrid-content-fixed)";
1351
1708
  var ListForm = class extends AbstractForm {
1709
+ headerCssSelector;
1352
1710
  constructor(driver) {
1353
1711
  super(driver);
1354
1712
  this.popupContainerCssSelector = `.popup .form-inline-${this.formName}`;
1713
+ this.headerCssSelector = DATAGRID_HEADER_CSS_SELECTOR;
1355
1714
  }
1356
1715
  /**
1357
1716
  * Находит таблицу
@@ -1361,7 +1720,7 @@ var ListForm = class extends AbstractForm {
1361
1720
  * expect(listForm.table());
1362
1721
  */
1363
1722
  table() {
1364
- return new Table(this.containerCssSelector, this.formName, this.driver);
1723
+ return new Table(this.containerCssSelector, this.headerCssSelector, this.formName, this.driver);
1365
1724
  }
1366
1725
  /**
1367
1726
  * Находит группу на лист форме по имени
@@ -1406,8 +1765,67 @@ var ListForm = class extends AbstractForm {
1406
1765
  return new FilterPanel(this.formName, this.driver);
1407
1766
  }
1408
1767
  };
1768
+
1769
+ // src/pageObjects/elements/Forms/TreeView.ts
1770
+ var TREELIST_HEADER_CSS_SELECTOR = ".dx-treelist-headers .dx-treelist-content:not(.dx-datagrid-content-fixed)";
1771
+ var TreeView = class extends ListForm {
1772
+ constructor(driver) {
1773
+ super(driver);
1774
+ this.popupContainerCssSelector = `.popup .wrapper-tree-view-${this.formName}`;
1775
+ this.headerCssSelector = TREELIST_HEADER_CSS_SELECTOR;
1776
+ }
1777
+ };
1778
+
1779
+ // src/pageObjects/elements/Dialog.ts
1780
+ import { By as By23 } from "selenium-webdriver";
1781
+ var DIALOG_CLASS = ".d5-dialog";
1782
+ var DIALOG_TITLE_CLASS = ".dialog__title";
1783
+ var DIALOG_TEXT_CLASS = ".dialog__text";
1784
+ var DIALOG_BUTTONS_PANEL_CLASS = ".dialog__buttons-panel";
1785
+ var buttonByTextXpath2 = (text) => `.//span[contains(@class, "dx-button-text") and contains(text(), "${text}")]`;
1786
+ var DialogButton = class extends AbstractButton {
1787
+ text;
1788
+ constructor(parentCssSelector, text, driver) {
1789
+ super(parentCssSelector, "", driver);
1790
+ this.text = text;
1791
+ }
1792
+ async getElement() {
1793
+ const panel = await super.getElement();
1794
+ return panel.findElement(By23.xpath(buttonByTextXpath2(this.text)));
1795
+ }
1796
+ buttonNotDisplayedError() {
1797
+ return `Dialog button ${this.text} cannot be clicked. It is not displayed or it is disabled`;
1798
+ }
1799
+ };
1800
+ var Dialog = class extends AbstractElement {
1801
+ constructor(driver) {
1802
+ super(driver, DIALOG_CLASS);
1803
+ }
1804
+ get titleSelector() {
1805
+ return this.joinRelativeCssSelectors([DIALOG_CLASS, DIALOG_TITLE_CLASS]);
1806
+ }
1807
+ get textSelector() {
1808
+ return this.joinRelativeCssSelectors([DIALOG_CLASS, DIALOG_TEXT_CLASS]);
1809
+ }
1810
+ get buttonsSelector() {
1811
+ return this.joinRelativeCssSelectors([DIALOG_CLASS, DIALOG_BUTTONS_PANEL_CLASS]);
1812
+ }
1813
+ async title() {
1814
+ const el = await this.driver.findElement(By23.css(this.titleSelector));
1815
+ return await el.getText();
1816
+ }
1817
+ async text() {
1818
+ const el = await this.driver.findElement(By23.css(this.textSelector));
1819
+ return await el.getText();
1820
+ }
1821
+ button(text) {
1822
+ return new DialogButton(this.buttonsSelector, text, this.driver);
1823
+ }
1824
+ };
1409
1825
  export {
1410
1826
  AbstractPage,
1827
+ ControlClass,
1828
+ Dialog,
1411
1829
  FilterPanel,
1412
1830
  FormEdit,
1413
1831
  FormField,
@@ -1418,6 +1836,7 @@ export {
1418
1836
  PanelFilterField,
1419
1837
  SubsystemsPanel,
1420
1838
  TextEditor,
1839
+ TreeView,
1421
1840
  byTestId,
1422
1841
  byTestIdCssSelector,
1423
1842
  click,
@@ -1425,6 +1844,7 @@ export {
1425
1844
  createDriver,
1426
1845
  editorFactory,
1427
1846
  elementIsNotPresent,
1847
+ readonlyLocator,
1428
1848
  signIn,
1429
1849
  wait,
1430
1850
  waitElementIsVisible