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.
- package/dist/cjs/d5-testing-library.cjs +558 -134
- package/dist/d5-testing-library.d.ts +102 -14
- package/dist/d5-testing-library.legacy-esm.js +553 -133
- package/dist/d5-testing-library.mjs +553 -133
- package/package.json +1 -1
|
@@ -31,6 +31,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
var src_exports = {};
|
|
32
32
|
__export(src_exports, {
|
|
33
33
|
AbstractPage: () => AbstractPage,
|
|
34
|
+
ControlClass: () => ControlClass,
|
|
35
|
+
Dialog: () => Dialog,
|
|
34
36
|
FilterPanel: () => FilterPanel,
|
|
35
37
|
FormEdit: () => FormEdit,
|
|
36
38
|
FormField: () => FormField,
|
|
@@ -41,6 +43,7 @@ __export(src_exports, {
|
|
|
41
43
|
PanelFilterField: () => PanelFilterField,
|
|
42
44
|
SubsystemsPanel: () => SubsystemsPanel,
|
|
43
45
|
TextEditor: () => TextEditor,
|
|
46
|
+
TreeView: () => TreeView,
|
|
44
47
|
byTestId: () => byTestId,
|
|
45
48
|
byTestIdCssSelector: () => byTestIdCssSelector,
|
|
46
49
|
click: () => click,
|
|
@@ -48,6 +51,7 @@ __export(src_exports, {
|
|
|
48
51
|
createDriver: () => createDriver,
|
|
49
52
|
editorFactory: () => editorFactory,
|
|
50
53
|
elementIsNotPresent: () => elementIsNotPresent,
|
|
54
|
+
readonlyLocator: () => readonlyLocator,
|
|
51
55
|
signIn: () => signIn,
|
|
52
56
|
wait: () => wait,
|
|
53
57
|
waitElementIsVisible: () => waitElementIsVisible
|
|
@@ -129,6 +133,9 @@ var AbstractElement = class {
|
|
|
129
133
|
getFullCssSelector() {
|
|
130
134
|
return this.elementCssSelector;
|
|
131
135
|
}
|
|
136
|
+
joinRelativeCssSelectors(selectors) {
|
|
137
|
+
return selectors.join(" ");
|
|
138
|
+
}
|
|
132
139
|
async getElement() {
|
|
133
140
|
return this.driver.findElement(import_selenium_webdriver2.By.css(this.getFullCssSelector()));
|
|
134
141
|
}
|
|
@@ -181,6 +188,9 @@ var AbstractPage = class extends AbstractElement {
|
|
|
181
188
|
// src/utils/actions.ts
|
|
182
189
|
var click = async (webElement, driver) => {
|
|
183
190
|
driver = driver ?? config().driver;
|
|
191
|
+
if (!await webElement.isDisplayed()) {
|
|
192
|
+
await driver.executeScript("arguments[0].scrollIntoView(true);", webElement);
|
|
193
|
+
}
|
|
184
194
|
const actions = driver.actions({ async: true });
|
|
185
195
|
await actions.move({ origin: webElement }).click().perform();
|
|
186
196
|
};
|
|
@@ -193,6 +203,7 @@ var byTestIdCssSelector = (testId, element = "div") => {
|
|
|
193
203
|
var byTestId = (testId, element = "div") => {
|
|
194
204
|
return import_selenium_webdriver3.By.css(byTestIdCssSelector(testId, element));
|
|
195
205
|
};
|
|
206
|
+
var readonlyLocator = "readonly";
|
|
196
207
|
|
|
197
208
|
// src/pageObjects/pages/LoginPage.ts
|
|
198
209
|
var LOGIN_PATH = "/login";
|
|
@@ -275,6 +286,11 @@ var AbstractElementWithParent = class extends AbstractElement {
|
|
|
275
286
|
}
|
|
276
287
|
return `${this.parentCssSelector} ${this.elementCssSelector}`;
|
|
277
288
|
}
|
|
289
|
+
async isReadonly() {
|
|
290
|
+
const fieldEl = await this.getElement();
|
|
291
|
+
const classSting = await fieldEl.getAttribute("class");
|
|
292
|
+
return classSting.includes(readonlyLocator);
|
|
293
|
+
}
|
|
278
294
|
};
|
|
279
295
|
|
|
280
296
|
// src/pageObjects/elements/SubsystemsPanel/SubsystemsPanelHeader.ts
|
|
@@ -300,7 +316,95 @@ var SubsystemsPanel = class extends AbstractElement {
|
|
|
300
316
|
};
|
|
301
317
|
|
|
302
318
|
// src/pageObjects/elements/Forms/AbstractForm.ts
|
|
319
|
+
var import_selenium_webdriver8 = require("selenium-webdriver");
|
|
320
|
+
|
|
321
|
+
// src/utils/createDataTestId.ts
|
|
322
|
+
function createDataTestId(formName, itemType, itemName) {
|
|
323
|
+
return `${formName}-${itemType}-${itemName}`;
|
|
324
|
+
}
|
|
325
|
+
function createFieldTestId(formName, itemName) {
|
|
326
|
+
return createDataTestId(formName, "form_field" /* FORM_FIELD */, itemName);
|
|
327
|
+
}
|
|
328
|
+
function createGroupTestId(formName, itemName) {
|
|
329
|
+
return createDataTestId(formName, "group" /* GROUP */, itemName);
|
|
330
|
+
}
|
|
331
|
+
function createFilterTestId(formName, itemName, layout) {
|
|
332
|
+
return createDataTestId(formName, "filter" /* FILTER */, itemName) + `-${layout}`;
|
|
333
|
+
}
|
|
334
|
+
function createDocFilterTestId(formName, itemName) {
|
|
335
|
+
return createFilterTestId(formName, itemName, "dock-panel-filter" /* DOCK_PANEL */);
|
|
336
|
+
}
|
|
337
|
+
function createLayoutFilterTestId(formName, itemName) {
|
|
338
|
+
return createFilterTestId(formName, itemName, "layout-filter" /* LAYOUT */);
|
|
339
|
+
}
|
|
340
|
+
function createTableId(formName) {
|
|
341
|
+
return `${"table" /* TABLE */}-${formName}`;
|
|
342
|
+
}
|
|
343
|
+
function createFormButtonTestId(formName, itemName) {
|
|
344
|
+
return createDataTestId(formName, "button" /* BUTTON */, itemName);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// src/utils/waitElementIsClickable.ts
|
|
348
|
+
async function waitElementIsClickable({
|
|
349
|
+
element,
|
|
350
|
+
timeout,
|
|
351
|
+
errorMessage,
|
|
352
|
+
driver
|
|
353
|
+
}) {
|
|
354
|
+
driver = driver ?? config().driver;
|
|
355
|
+
await wait(async () => {
|
|
356
|
+
const isDisabled = await element.getCssValue("pointer-events") === "none";
|
|
357
|
+
return await element.isDisplayed() && !isDisabled;
|
|
358
|
+
}, driver, errorMessage, timeout ?? config().timeout);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
// src/pageObjects/elements/TableToolbar/AbstractButton.ts
|
|
362
|
+
var AbstractButton = class extends AbstractElementWithParent {
|
|
363
|
+
constructor(parentCssSelector, elementCssSelector, driver) {
|
|
364
|
+
super(parentCssSelector, elementCssSelector, driver);
|
|
365
|
+
}
|
|
366
|
+
async click() {
|
|
367
|
+
const button = await this.getElement();
|
|
368
|
+
await waitElementIsClickable({
|
|
369
|
+
element: button,
|
|
370
|
+
errorMessage: this.buttonNotDisplayedError(),
|
|
371
|
+
driver: this.driver
|
|
372
|
+
});
|
|
373
|
+
await click(button, this.driver);
|
|
374
|
+
}
|
|
375
|
+
async isDisabled() {
|
|
376
|
+
const button = await this.getElement();
|
|
377
|
+
return await button.getCssValue("pointer-events") === "none";
|
|
378
|
+
}
|
|
379
|
+
};
|
|
380
|
+
|
|
381
|
+
// src/pageObjects/elements/DXComponents/DXButton.ts
|
|
303
382
|
var import_selenium_webdriver7 = require("selenium-webdriver");
|
|
383
|
+
var DXButton = class extends AbstractButton {
|
|
384
|
+
async getText() {
|
|
385
|
+
const classes = await this.getClasses();
|
|
386
|
+
if (!classes.includes("dx-button-has-text")) {
|
|
387
|
+
return null;
|
|
388
|
+
}
|
|
389
|
+
const el = await this.getElement();
|
|
390
|
+
const textEl = el.findElement(import_selenium_webdriver7.By.className("dx-button-text"));
|
|
391
|
+
return await textEl.getText();
|
|
392
|
+
}
|
|
393
|
+
};
|
|
394
|
+
|
|
395
|
+
// src/pageObjects/elements/FormButton.ts
|
|
396
|
+
var FormButton = class extends DXButton {
|
|
397
|
+
name;
|
|
398
|
+
constructor(parentCssSelector, formName, name, driver) {
|
|
399
|
+
super(parentCssSelector, byTestIdCssSelector(createFormButtonTestId(formName, name)), driver);
|
|
400
|
+
this.name = name;
|
|
401
|
+
}
|
|
402
|
+
buttonNotDisplayedError() {
|
|
403
|
+
return `Form Button ${this.name} cannot be clicked. It is not displayed or it is disabled`;
|
|
404
|
+
}
|
|
405
|
+
};
|
|
406
|
+
|
|
407
|
+
// src/pageObjects/elements/Forms/AbstractForm.ts
|
|
304
408
|
var AbstractForm = class extends AbstractPage {
|
|
305
409
|
containerCssSelector = "";
|
|
306
410
|
containerBy;
|
|
@@ -347,42 +451,22 @@ var AbstractForm = class extends AbstractPage {
|
|
|
347
451
|
*/
|
|
348
452
|
async getTitleText() {
|
|
349
453
|
if (await this.isModal()) {
|
|
350
|
-
const titleEl2 = await this.driver.findElement(
|
|
454
|
+
const titleEl2 = await this.driver.findElement(import_selenium_webdriver8.By.css(`${this.popupContainerCssSelector} .popup-title`));
|
|
351
455
|
return titleEl2.getText();
|
|
352
456
|
}
|
|
353
|
-
let titleEl = await this.driver.findElement(
|
|
457
|
+
let titleEl = await this.driver.findElement(import_selenium_webdriver8.By.className("main-toolbar-form-title"));
|
|
354
458
|
return titleEl.getText();
|
|
355
459
|
}
|
|
460
|
+
button(name) {
|
|
461
|
+
return new FormButton(this.containerCssSelector, this.formName, name, this.driver);
|
|
462
|
+
}
|
|
356
463
|
};
|
|
357
464
|
|
|
358
465
|
// src/pageObjects/elements/Forms/FormEdit.ts
|
|
359
|
-
var
|
|
360
|
-
|
|
361
|
-
// src/utils/createDataTestId.ts
|
|
362
|
-
function createDataTestId(formName, itemType, itemName) {
|
|
363
|
-
return `${formName}-${itemType}-${itemName}`;
|
|
364
|
-
}
|
|
365
|
-
function createFieldTestId(formName, itemName) {
|
|
366
|
-
return createDataTestId(formName, "form_field" /* FORM_FIELD */, itemName);
|
|
367
|
-
}
|
|
368
|
-
function createGroupTestId(formName, itemName) {
|
|
369
|
-
return createDataTestId(formName, "group" /* GROUP */, itemName);
|
|
370
|
-
}
|
|
371
|
-
function createFilterTestId(formName, itemName, layout) {
|
|
372
|
-
return createDataTestId(formName, "filter" /* FILTER */, itemName) + `-${layout}`;
|
|
373
|
-
}
|
|
374
|
-
function createDocFilterTestId(formName, itemName) {
|
|
375
|
-
return createFilterTestId(formName, itemName, "dock-panel-filter" /* DOCK_PANEL */);
|
|
376
|
-
}
|
|
377
|
-
function createLayoutFilterTestId(formName, itemName) {
|
|
378
|
-
return createFilterTestId(formName, itemName, "layout-filter" /* LAYOUT */);
|
|
379
|
-
}
|
|
380
|
-
function createTableId(formName) {
|
|
381
|
-
return `${"table" /* TABLE */}-${formName}`;
|
|
382
|
-
}
|
|
466
|
+
var import_selenium_webdriver17 = require("selenium-webdriver");
|
|
383
467
|
|
|
384
468
|
// src/pageObjects/elements/Editors/AbstractEditor.ts
|
|
385
|
-
var
|
|
469
|
+
var import_selenium_webdriver9 = require("selenium-webdriver");
|
|
386
470
|
|
|
387
471
|
// src/pageObjects/elements/Editors/ClearStrategy/InputClearStrategy.ts
|
|
388
472
|
var InputClearStrategy = class {
|
|
@@ -402,7 +486,7 @@ var AbstractDXEditorWithInput = class extends AbstractElementWithParent {
|
|
|
402
486
|
return `${this.getFullCssSelector()} .dx-texteditor-input`;
|
|
403
487
|
}
|
|
404
488
|
async getInputElement() {
|
|
405
|
-
return this.driver.findElement(
|
|
489
|
+
return this.driver.findElement(import_selenium_webdriver9.By.css(this.getInputCssSelector()));
|
|
406
490
|
}
|
|
407
491
|
async getInputValue() {
|
|
408
492
|
const inputEl = await this.getInputElement();
|
|
@@ -411,7 +495,7 @@ var AbstractDXEditorWithInput = class extends AbstractElementWithParent {
|
|
|
411
495
|
async setInputValue(value) {
|
|
412
496
|
const inputEl = await this.getInputElement();
|
|
413
497
|
await click(inputEl, this.driver);
|
|
414
|
-
await inputEl.sendKeys(value,
|
|
498
|
+
await inputEl.sendKeys(value, import_selenium_webdriver9.Key.ENTER);
|
|
415
499
|
}
|
|
416
500
|
async clear() {
|
|
417
501
|
await this.clearStrategy.clear(this);
|
|
@@ -447,6 +531,22 @@ var NumberEditor = class extends AbstractDXEditorWithInput {
|
|
|
447
531
|
}
|
|
448
532
|
};
|
|
449
533
|
|
|
534
|
+
// src/pageObjects/elements/Editors/types.ts
|
|
535
|
+
var ControlClass = /* @__PURE__ */ ((ControlClass2) => {
|
|
536
|
+
ControlClass2["Text"] = "text-control";
|
|
537
|
+
ControlClass2["TextArea"] = "text-area-control";
|
|
538
|
+
ControlClass2["Number"] = "number-control";
|
|
539
|
+
ControlClass2["CheckBox"] = "check-box";
|
|
540
|
+
ControlClass2["Multiselect"] = "multi-select-control";
|
|
541
|
+
ControlClass2["Select"] = "select-control";
|
|
542
|
+
ControlClass2["Switch"] = "switch-control";
|
|
543
|
+
ControlClass2["Date"] = "date-control";
|
|
544
|
+
ControlClass2["SingleDateRange"] = "single-date-range-control";
|
|
545
|
+
ControlClass2["BooleanSelector"] = "buttons-group";
|
|
546
|
+
ControlClass2["ButtonGroup"] = "button-group-field";
|
|
547
|
+
return ControlClass2;
|
|
548
|
+
})(ControlClass || {});
|
|
549
|
+
|
|
450
550
|
// src/pageObjects/AbstractFormElement.ts
|
|
451
551
|
var AbstractFormElement = class extends AbstractElementWithParent {
|
|
452
552
|
constructor(parentCssSelector, elementCssSelector, driver) {
|
|
@@ -474,20 +574,17 @@ var CheckBox = class extends AbstractElementWithParent {
|
|
|
474
574
|
};
|
|
475
575
|
|
|
476
576
|
// src/pageObjects/elements/Editors/SelectBoxEditor.ts
|
|
477
|
-
var
|
|
577
|
+
var import_selenium_webdriver11 = require("selenium-webdriver");
|
|
478
578
|
|
|
479
579
|
// src/utils/xpathHelper.ts
|
|
480
580
|
var XPathHelper = class {
|
|
481
|
-
static getRoleXpath(role) {
|
|
482
|
-
return `//div[@role='${role}']`;
|
|
483
|
-
}
|
|
484
581
|
static getClassAndValueXpath(cssClass, value) {
|
|
485
|
-
return
|
|
582
|
+
return `div[contains(@class, '${cssClass}') and contains(.,'${value}')]`;
|
|
486
583
|
}
|
|
487
584
|
};
|
|
488
585
|
|
|
489
586
|
// src/pageObjects/elements/Editors/ClearStrategy/ClearButtonStrategy.ts
|
|
490
|
-
var
|
|
587
|
+
var import_selenium_webdriver10 = require("selenium-webdriver");
|
|
491
588
|
var DX_TEXTEDITOR_EMPTY = "dx-texteditor-empty";
|
|
492
589
|
var DX_CLEAR_BUTTON_AREA = "dx-clear-button-area";
|
|
493
590
|
var ClearButtonStrategy = class {
|
|
@@ -498,7 +595,7 @@ var ClearButtonStrategy = class {
|
|
|
498
595
|
this._driver = driver;
|
|
499
596
|
}
|
|
500
597
|
async isEmptyEditorField() {
|
|
501
|
-
const editorContainer = await this._driver.findElement(
|
|
598
|
+
const editorContainer = await this._driver.findElement(import_selenium_webdriver10.By.css(this.editorContainerClass));
|
|
502
599
|
const classAttribute = await editorContainer.getAttribute("class");
|
|
503
600
|
return classAttribute.includes(DX_TEXTEDITOR_EMPTY);
|
|
504
601
|
}
|
|
@@ -507,18 +604,31 @@ var ClearButtonStrategy = class {
|
|
|
507
604
|
throw new Error("This field is already empty");
|
|
508
605
|
}
|
|
509
606
|
const clearBtnSelector = `${this.editorContainerClass} .${DX_CLEAR_BUTTON_AREA}`;
|
|
510
|
-
const clearBtn = await this._driver.findElement(
|
|
607
|
+
const clearBtn = await this._driver.findElement(import_selenium_webdriver10.By.css(clearBtnSelector));
|
|
511
608
|
await click(clearBtn, this._driver);
|
|
512
609
|
}
|
|
513
610
|
};
|
|
514
611
|
|
|
515
612
|
// src/pageObjects/elements/Editors/SelectBoxEditor.ts
|
|
516
613
|
var SELECT_BOX_OPTION_TEXT_CONTAINER_CLASS = "d5-multi-select-item";
|
|
517
|
-
var
|
|
518
|
-
var
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
614
|
+
var combinedValueXpath = (value) => `//body/div[@id="root"]/div[contains(@class, "dx-overlay-wrapper")]//${XPathHelper.getClassAndValueXpath(SELECT_BOX_OPTION_TEXT_CONTAINER_CLASS, value)}`;
|
|
615
|
+
var dropDownOptionClick = async (optionValue, driver, delay = true) => {
|
|
616
|
+
const { implicit } = await driver.manage().getTimeouts();
|
|
617
|
+
let optElement = null;
|
|
618
|
+
const timeout = delay ? implicit : 200;
|
|
619
|
+
let err = null;
|
|
620
|
+
try {
|
|
621
|
+
await driver.manage().setTimeouts({ implicit: timeout });
|
|
622
|
+
optElement = await driver.findElement(import_selenium_webdriver11.By.xpath(combinedValueXpath(optionValue)));
|
|
623
|
+
await click(optElement, driver);
|
|
624
|
+
} catch (e) {
|
|
625
|
+
err = new Error(`Item not found: "${optionValue}"`);
|
|
626
|
+
} finally {
|
|
627
|
+
await driver.manage().setTimeouts({ implicit });
|
|
628
|
+
}
|
|
629
|
+
if (err)
|
|
630
|
+
throw err;
|
|
631
|
+
};
|
|
522
632
|
var SelectBoxEditor = class extends AbstractDXEditorWithInput {
|
|
523
633
|
constructor(parentCssSelector, elementCssSelector, driver) {
|
|
524
634
|
super(parentCssSelector, elementCssSelector, driver);
|
|
@@ -527,9 +637,12 @@ var SelectBoxEditor = class extends AbstractDXEditorWithInput {
|
|
|
527
637
|
async setSelectInputValue(value) {
|
|
528
638
|
const inputEl = await this.getInputElement();
|
|
529
639
|
await click(inputEl, this.driver);
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
640
|
+
try {
|
|
641
|
+
await dropDownOptionClick(value, this.driver, false);
|
|
642
|
+
} catch {
|
|
643
|
+
await inputEl.sendKeys(value, import_selenium_webdriver11.Key.ENTER);
|
|
644
|
+
await dropDownOptionClick(value, this.driver);
|
|
645
|
+
}
|
|
533
646
|
}
|
|
534
647
|
async getValue() {
|
|
535
648
|
const value = await super.getInputValue();
|
|
@@ -568,7 +681,7 @@ var SwitchEditor = class extends AbstractElementWithParent {
|
|
|
568
681
|
};
|
|
569
682
|
|
|
570
683
|
// src/pageObjects/elements/Editors/TagBox.ts
|
|
571
|
-
var
|
|
684
|
+
var import_selenium_webdriver12 = require("selenium-webdriver");
|
|
572
685
|
var TAGS_SELECTOR = ".dx-tag .tag-text";
|
|
573
686
|
var DX_TAG_CONTAINER = "dx-tag-container";
|
|
574
687
|
var DX_TEXTEDITOR_EMPTY2 = "dx-texteditor-empty";
|
|
@@ -589,31 +702,35 @@ var TagBox = class extends AbstractDXEditorWithInput {
|
|
|
589
702
|
await this.confirmSelection();
|
|
590
703
|
}
|
|
591
704
|
async waitOptionSelection() {
|
|
592
|
-
const option = await this.driver.findElement(
|
|
705
|
+
const option = await this.driver.findElement(import_selenium_webdriver12.By.css(TAG_BOX_LIST_ITEM_SELECTOR));
|
|
593
706
|
await wait(() => option.isDisplayed(), this.driver);
|
|
594
707
|
}
|
|
595
708
|
async selectOption(inputEl, value, lastElement) {
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
709
|
+
try {
|
|
710
|
+
await dropDownOptionClick(value, this.driver, false);
|
|
711
|
+
} catch {
|
|
712
|
+
await inputEl.sendKeys(value);
|
|
713
|
+
await dropDownOptionClick(value, this.driver);
|
|
714
|
+
}
|
|
599
715
|
await this.waitOptionSelection();
|
|
600
716
|
if (value !== lastElement) {
|
|
601
717
|
await inputEl.clear();
|
|
602
718
|
}
|
|
603
719
|
}
|
|
604
720
|
async confirmSelection() {
|
|
605
|
-
const btnOk = await this.driver.findElement(
|
|
721
|
+
const btnOk = await this.driver.findElement(import_selenium_webdriver12.By.css(BTN_OK_SELECTOR));
|
|
606
722
|
await click(btnOk, this.driver);
|
|
607
723
|
}
|
|
608
724
|
async getTagBoxInputValue() {
|
|
609
725
|
if (await this.isTagBoxEmpty()) {
|
|
610
726
|
return [];
|
|
611
727
|
}
|
|
612
|
-
const tags = await this.driver.findElements(
|
|
728
|
+
const tags = await this.driver.findElements(
|
|
729
|
+
import_selenium_webdriver12.By.css(`${this.getFullCssSelector()} .${DX_TAG_CONTAINER} ${TAGS_SELECTOR}`)
|
|
730
|
+
);
|
|
613
731
|
const values = [];
|
|
614
732
|
for (const tag of tags) {
|
|
615
|
-
|
|
616
|
-
values.push(text);
|
|
733
|
+
values.push(await tag.getAttribute("textContent"));
|
|
617
734
|
}
|
|
618
735
|
return values;
|
|
619
736
|
}
|
|
@@ -638,24 +755,26 @@ var TagBox = class extends AbstractDXEditorWithInput {
|
|
|
638
755
|
throw new Error(`The tag with the text: ${itemText} was not found`);
|
|
639
756
|
}
|
|
640
757
|
const clearBtnTestId = byTestIdCssSelector(`clear-button-${itemText}`);
|
|
641
|
-
const clearBtn = await this.driver.findElement(
|
|
758
|
+
const clearBtn = await this.driver.findElement(
|
|
759
|
+
import_selenium_webdriver12.By.css(`${this.getFullCssSelector()} .${DX_TAG_CONTAINER} ${clearBtnTestId}`)
|
|
760
|
+
);
|
|
642
761
|
await click(clearBtn, this.driver);
|
|
643
762
|
}
|
|
644
763
|
};
|
|
645
764
|
|
|
646
765
|
// src/pageObjects/elements/Editors/ButtonGroup.ts
|
|
647
|
-
var
|
|
766
|
+
var import_selenium_webdriver13 = require("selenium-webdriver");
|
|
648
767
|
var ITEM_CLASS = "dx-buttongroup-item";
|
|
649
768
|
var SELECTED_CLASS = "dx-state-selected";
|
|
650
769
|
var ButtonGroup = class extends AbstractElementWithParent {
|
|
651
770
|
getItems() {
|
|
652
|
-
return this.driver.findElements(
|
|
771
|
+
return this.driver.findElements(import_selenium_webdriver13.By.css(`${this.getFullCssSelector()} .${ITEM_CLASS}`));
|
|
653
772
|
}
|
|
654
773
|
getDataValue(el) {
|
|
655
774
|
return el.getAttribute("data-value");
|
|
656
775
|
}
|
|
657
776
|
async getValue() {
|
|
658
|
-
const selectedEl = await this.driver.findElement(
|
|
777
|
+
const selectedEl = await this.driver.findElement(import_selenium_webdriver13.By.css(`${this.getFullCssSelector()} .${ITEM_CLASS}.${SELECTED_CLASS}`));
|
|
659
778
|
return this.getDataValue(selectedEl);
|
|
660
779
|
}
|
|
661
780
|
async setValue(value) {
|
|
@@ -688,26 +807,67 @@ var BooleanSelector = class extends ButtonGroup {
|
|
|
688
807
|
}
|
|
689
808
|
};
|
|
690
809
|
|
|
691
|
-
// src/pageObjects/elements/Editors/
|
|
692
|
-
var
|
|
693
|
-
|
|
810
|
+
// src/pageObjects/elements/Editors/Date/SingleDateEditor.ts
|
|
811
|
+
var import_selenium_webdriver15 = require("selenium-webdriver");
|
|
812
|
+
|
|
813
|
+
// src/pageObjects/elements/Editors/Date/BaseDateEditor.ts
|
|
814
|
+
var import_selenium_webdriver14 = require("selenium-webdriver");
|
|
815
|
+
|
|
816
|
+
// src/pageObjects/elements/Editors/Date/utils.ts
|
|
817
|
+
var formatDMYDate = (date) => {
|
|
818
|
+
const [year, month, day] = date.toJSON().split("T")[0].split("-");
|
|
819
|
+
return `${day}${month}${year}`;
|
|
820
|
+
};
|
|
821
|
+
|
|
822
|
+
// src/pageObjects/elements/Editors/Date/BaseDateEditor.ts
|
|
823
|
+
var BTN_CALENDAR_POPOVER_OPEN_SELECTOR = "calendar-popover-open-button";
|
|
824
|
+
var BTN_CALENDAR_POPOVER_DATE_FROM_INPUT_SELECTOR = "DateRange__inputs-item--dateFrom";
|
|
825
|
+
var BTN_CALENDAR_POPOVER_DATE_TO_INPUT_SELECTOR = "DateRange__inputs-item--dateTo";
|
|
826
|
+
var BTN_SAVE_SELECTOR = "DateRange__button-save";
|
|
827
|
+
var BaseDateEditor = class extends AbstractDXEditorWithInput {
|
|
694
828
|
constructor(parentCssSelector, elementCssSelector, driver) {
|
|
695
829
|
super(parentCssSelector, elementCssSelector, driver);
|
|
696
830
|
this.setClearStrategy(new InputClearStrategy());
|
|
697
831
|
}
|
|
698
|
-
async getDateElement() {
|
|
699
|
-
return this.driver.findElement(import_selenium_webdriver13.By.css(this.getFullCssSelector() + " .dx-dropdowneditor-input-wrapper input[type=hidden]"));
|
|
700
|
-
}
|
|
701
832
|
async setDateValue(value) {
|
|
702
|
-
const dateEl = await this.getInputElement();
|
|
703
|
-
const stringDate = value.toJSON().split("T")[0];
|
|
704
|
-
const dateArr = stringDate.split("-");
|
|
705
|
-
const [year, month, day] = dateArr;
|
|
706
|
-
const keys = day + month + year;
|
|
707
|
-
await click(dateEl, this.driver);
|
|
708
833
|
const actions = this.driver.actions({ async: true });
|
|
709
|
-
|
|
710
|
-
|
|
834
|
+
const dateField = await this.driver.findElement(import_selenium_webdriver14.By.css(`${this.getFullCssSelector()}`));
|
|
835
|
+
const dateFieldDataTestID = await this.getDataTestId();
|
|
836
|
+
const calendarPopoverSelector = byTestIdCssSelector(`${dateFieldDataTestID}-calendar-popover`);
|
|
837
|
+
const dateInputEl = await this.getInputElement();
|
|
838
|
+
await dateInputEl.clear();
|
|
839
|
+
if (Array.isArray(value)) {
|
|
840
|
+
const formattedDates = value.map(formatDMYDate);
|
|
841
|
+
const button = await dateField.findElement(import_selenium_webdriver14.By.css(`.${BTN_CALENDAR_POPOVER_OPEN_SELECTOR}`));
|
|
842
|
+
await button.click();
|
|
843
|
+
const calendarPopoverElement = await this.driver.findElement(import_selenium_webdriver14.By.css(calendarPopoverSelector));
|
|
844
|
+
const dateFromInput = await calendarPopoverElement.findElement(import_selenium_webdriver14.By.css(`.${BTN_CALENDAR_POPOVER_DATE_FROM_INPUT_SELECTOR} .dx-texteditor-input`));
|
|
845
|
+
const dateToInput = await calendarPopoverElement.findElement(import_selenium_webdriver14.By.css(`.${BTN_CALENDAR_POPOVER_DATE_TO_INPUT_SELECTOR} .dx-texteditor-input`));
|
|
846
|
+
await dateFromInput.click();
|
|
847
|
+
await dateFromInput.sendKeys(formattedDates[0]);
|
|
848
|
+
await dateToInput.click();
|
|
849
|
+
await actions.move({ origin: dateInputEl }).sendKeys(import_selenium_webdriver14.Key.HOME).perform();
|
|
850
|
+
await dateToInput.sendKeys(formattedDates[1]);
|
|
851
|
+
await actions.move({ origin: dateInputEl }).sendKeys(import_selenium_webdriver14.Key.ENTER).perform();
|
|
852
|
+
const btnOk = await this.driver.findElement(import_selenium_webdriver14.By.css(`.${BTN_SAVE_SELECTOR}`));
|
|
853
|
+
await btnOk.click();
|
|
854
|
+
} else {
|
|
855
|
+
const formattedDate = formatDMYDate(value);
|
|
856
|
+
await click(dateInputEl, this.driver);
|
|
857
|
+
await actions.move({ origin: dateInputEl }).sendKeys(import_selenium_webdriver14.Key.HOME).perform();
|
|
858
|
+
await actions.move({ origin: dateInputEl }).sendKeys(formattedDate, import_selenium_webdriver14.Key.ENTER).perform();
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
};
|
|
862
|
+
|
|
863
|
+
// src/pageObjects/elements/Editors/Date/SingleDateEditor.ts
|
|
864
|
+
var SingleDateEditor = class extends BaseDateEditor {
|
|
865
|
+
constructor(parentCssSelector, elementCssSelector, driver) {
|
|
866
|
+
super(parentCssSelector, elementCssSelector, driver);
|
|
867
|
+
this.setClearStrategy(new InputClearStrategy());
|
|
868
|
+
}
|
|
869
|
+
async getDateElement() {
|
|
870
|
+
return this.driver.findElement(import_selenium_webdriver15.By.css(this.getFullCssSelector() + " .dx-dropdowneditor-input-wrapper input[type=hidden]"));
|
|
711
871
|
}
|
|
712
872
|
async getDateValue() {
|
|
713
873
|
const inputEl = await this.getDateElement();
|
|
@@ -725,27 +885,105 @@ var DateEditor = class extends AbstractDXEditorWithInput {
|
|
|
725
885
|
}
|
|
726
886
|
};
|
|
727
887
|
|
|
888
|
+
// src/pageObjects/elements/Editors/Date/DateRangeEditor.ts
|
|
889
|
+
var import_selenium_webdriver16 = require("selenium-webdriver");
|
|
890
|
+
var DateRangeEditor = class extends BaseDateEditor {
|
|
891
|
+
constructor(parentCssSelector, elementCssSelector, driver) {
|
|
892
|
+
super(parentCssSelector, elementCssSelector, driver);
|
|
893
|
+
this.setClearStrategy(new InputClearStrategy());
|
|
894
|
+
}
|
|
895
|
+
async getDateElement() {
|
|
896
|
+
return this.driver.findElement(import_selenium_webdriver16.By.css(this.getFullCssSelector() + " .dx-texteditor-input"));
|
|
897
|
+
}
|
|
898
|
+
async getDateValue() {
|
|
899
|
+
const inputEl = await this.getDateElement();
|
|
900
|
+
const dateFromStr = await inputEl.getAttribute("datefrom");
|
|
901
|
+
const dateToStr = await inputEl.getAttribute("dateto");
|
|
902
|
+
const dateFrom = new Date(dateFromStr);
|
|
903
|
+
const dateTo = new Date(dateToStr);
|
|
904
|
+
return [dateFrom, dateTo];
|
|
905
|
+
}
|
|
906
|
+
async getValue() {
|
|
907
|
+
const values = await this.getDateValue();
|
|
908
|
+
return !values.length ? null : values;
|
|
909
|
+
}
|
|
910
|
+
setValue(value) {
|
|
911
|
+
if (typeof value === "object") {
|
|
912
|
+
return this.setDateValue(value);
|
|
913
|
+
}
|
|
914
|
+
throw new Error(`Value is incorrect. It should be Object`);
|
|
915
|
+
}
|
|
916
|
+
};
|
|
917
|
+
|
|
918
|
+
// src/pageObjects/elements/Editors/Date/DateEditor.ts
|
|
919
|
+
var DateEditor = class extends AbstractDXEditorWithInput {
|
|
920
|
+
editorInstance = null;
|
|
921
|
+
initPromise;
|
|
922
|
+
constructor(parentCssSelector, elementCssSelector, driver) {
|
|
923
|
+
super(parentCssSelector, elementCssSelector, driver);
|
|
924
|
+
this.initPromise = this.init(parentCssSelector, elementCssSelector, driver);
|
|
925
|
+
}
|
|
926
|
+
async init(parentCssSelector, elementCssSelector, driver) {
|
|
927
|
+
await this.updateEditorInstance(parentCssSelector, elementCssSelector, driver);
|
|
928
|
+
}
|
|
929
|
+
async updateEditorInstance(parentCssSelector, elementCssSelector, driver) {
|
|
930
|
+
const elementInstance = new AbstractFormElement(parentCssSelector, elementCssSelector, driver);
|
|
931
|
+
const classString = await elementInstance.getClasses();
|
|
932
|
+
switch (true) {
|
|
933
|
+
case classString.includes("date-control" /* Date */):
|
|
934
|
+
this.editorInstance = new SingleDateEditor(parentCssSelector, elementCssSelector, driver);
|
|
935
|
+
break;
|
|
936
|
+
case classString.includes("single-date-range-control" /* SingleDateRange */):
|
|
937
|
+
this.editorInstance = new DateRangeEditor(parentCssSelector, elementCssSelector, driver);
|
|
938
|
+
break;
|
|
939
|
+
default:
|
|
940
|
+
this.editorInstance = new SingleDateEditor(parentCssSelector, elementCssSelector, driver);
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
async ensureInitialized() {
|
|
944
|
+
if (!this.editorInstance) {
|
|
945
|
+
await this.initPromise;
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
async setValue(value) {
|
|
949
|
+
await this.ensureInitialized();
|
|
950
|
+
if (this.editorInstance) {
|
|
951
|
+
await this.editorInstance.setValue(value);
|
|
952
|
+
return await this.updateEditorInstance(this.parentCssSelector, this.elementCssSelector, this.driver);
|
|
953
|
+
}
|
|
954
|
+
throw new Error("Editor instance is not initialized.");
|
|
955
|
+
}
|
|
956
|
+
async getValue() {
|
|
957
|
+
await this.ensureInitialized();
|
|
958
|
+
if (this.editorInstance) {
|
|
959
|
+
return this.editorInstance.getValue();
|
|
960
|
+
}
|
|
961
|
+
throw new Error("Editor instance is not initialized.");
|
|
962
|
+
}
|
|
963
|
+
};
|
|
964
|
+
|
|
728
965
|
// src/pageObjects/elements/Editors/editorFactory.ts
|
|
729
966
|
var editorFactory = async (parentCssSelector, elementCssSelector, driver) => {
|
|
730
967
|
const elementInstance = new AbstractFormElement(parentCssSelector, elementCssSelector, driver);
|
|
731
968
|
const classSting = await elementInstance.getClasses();
|
|
732
|
-
if (classSting.includes("text-control"))
|
|
969
|
+
if ((classSting.includes("text-control" /* Text */) || classSting.includes("text-area-control" /* TextArea */)) && !classSting.includes("single-date-range-control" /* SingleDateRange */))
|
|
733
970
|
return new TextEditor(parentCssSelector, elementCssSelector, driver);
|
|
734
|
-
if (classSting.includes("number-control"))
|
|
971
|
+
if (classSting.includes("number-control" /* Number */))
|
|
735
972
|
return new NumberEditor(parentCssSelector, elementCssSelector, driver);
|
|
736
|
-
if (classSting.includes("check-box"))
|
|
973
|
+
if (classSting.includes("check-box" /* CheckBox */))
|
|
737
974
|
return new CheckBox(parentCssSelector, elementCssSelector, driver);
|
|
738
|
-
if (classSting.includes("multi-select-control"))
|
|
975
|
+
if (classSting.includes("multi-select-control" /* Multiselect */))
|
|
739
976
|
return new TagBox(parentCssSelector, elementCssSelector, driver);
|
|
740
|
-
if (classSting.includes("select-control"))
|
|
977
|
+
if (classSting.includes("select-control" /* Select */))
|
|
741
978
|
return new SelectBoxEditor(parentCssSelector, elementCssSelector, driver);
|
|
742
|
-
if (classSting.includes("switch-control"))
|
|
979
|
+
if (classSting.includes("switch-control" /* Switch */))
|
|
743
980
|
return new SwitchEditor(parentCssSelector, elementCssSelector, driver);
|
|
744
|
-
if (classSting.includes("date-control"))
|
|
981
|
+
if (classSting.includes("date-control" /* Date */) || classSting.includes("single-date-range-control" /* SingleDateRange */)) {
|
|
745
982
|
return new DateEditor(parentCssSelector, elementCssSelector, driver);
|
|
746
|
-
|
|
983
|
+
}
|
|
984
|
+
if (classSting.includes("buttons-group" /* BooleanSelector */))
|
|
747
985
|
return new BooleanSelector(parentCssSelector, elementCssSelector, driver);
|
|
748
|
-
if (classSting.includes("button-group-field"))
|
|
986
|
+
if (classSting.includes("button-group-field" /* ButtonGroup */))
|
|
749
987
|
return new ButtonGroup(parentCssSelector, elementCssSelector, driver);
|
|
750
988
|
throw new Error("Unknown type of editor. Please write ticket to the support");
|
|
751
989
|
};
|
|
@@ -805,6 +1043,16 @@ var AbstractEditor = class extends AbstractElementWithParent {
|
|
|
805
1043
|
}
|
|
806
1044
|
return this.editor.remove(itemText);
|
|
807
1045
|
}
|
|
1046
|
+
/**
|
|
1047
|
+
* Возвращает значение true|false в зависимости readOnly поле или нет
|
|
1048
|
+
* @example
|
|
1049
|
+
* expect(await formEdit.field('NumberFld').isReadonly()).toBe(true);
|
|
1050
|
+
* expect(await formEdit.field('TextFld').isReadonly()).toBe(false);
|
|
1051
|
+
*/
|
|
1052
|
+
async isReadonly() {
|
|
1053
|
+
await this.initEditor();
|
|
1054
|
+
return this.editor.isReadonly();
|
|
1055
|
+
}
|
|
808
1056
|
};
|
|
809
1057
|
|
|
810
1058
|
// src/pageObjects/elements/FormField.ts
|
|
@@ -863,7 +1111,8 @@ var FormGroup = class extends AbstractElementWithParent {
|
|
|
863
1111
|
|
|
864
1112
|
// src/pageObjects/elements/Forms/FormEdit.ts
|
|
865
1113
|
var FormEdit = class extends AbstractForm {
|
|
866
|
-
saveButtonBy =
|
|
1114
|
+
saveButtonBy = import_selenium_webdriver17.By.id("button-save");
|
|
1115
|
+
closeButtonBy = import_selenium_webdriver17.By.id("button-cancel");
|
|
867
1116
|
constructor(driver) {
|
|
868
1117
|
super(driver);
|
|
869
1118
|
this.popupContainerCssSelector = `.popup .form-edit-${this.formName}`;
|
|
@@ -912,19 +1161,30 @@ var FormEdit = class extends AbstractForm {
|
|
|
912
1161
|
await wait(async () => !await this.isSaveButtonDisabled(), this.driver, "Button is disabled");
|
|
913
1162
|
await click(saveButton, this.driver);
|
|
914
1163
|
}
|
|
1164
|
+
/**
|
|
1165
|
+
* Нажатие на кнопку Закрить
|
|
1166
|
+
* @example
|
|
1167
|
+
* const formEdit = new MyForm();
|
|
1168
|
+
* //...
|
|
1169
|
+
* await formEdit.closeButtonClick();
|
|
1170
|
+
*/
|
|
1171
|
+
async closeButtonClick() {
|
|
1172
|
+
const closeButton = await this.driver.findElement(this.closeButtonBy);
|
|
1173
|
+
await click(closeButton, this.driver);
|
|
1174
|
+
}
|
|
915
1175
|
};
|
|
916
1176
|
|
|
917
1177
|
// src/pageObjects/elements/Table/Table.ts
|
|
918
|
-
var
|
|
1178
|
+
var import_selenium_webdriver22 = require("selenium-webdriver");
|
|
919
1179
|
|
|
920
1180
|
// src/pageObjects/elements/Table/elements/Row.ts
|
|
921
|
-
var
|
|
1181
|
+
var import_selenium_webdriver20 = require("selenium-webdriver");
|
|
922
1182
|
|
|
923
1183
|
// src/pageObjects/elements/Table/elements/Cell.ts
|
|
924
|
-
var
|
|
1184
|
+
var import_selenium_webdriver19 = require("selenium-webdriver");
|
|
925
1185
|
|
|
926
1186
|
// src/pageObjects/elements/Table/utils.ts
|
|
927
|
-
var
|
|
1187
|
+
var import_selenium_webdriver18 = require("selenium-webdriver");
|
|
928
1188
|
function getCssRowByIndexSelector(index) {
|
|
929
1189
|
return `tr[aria-rowindex="${transformInputIndex(index)}"]`;
|
|
930
1190
|
}
|
|
@@ -951,9 +1211,18 @@ var Cell = class extends AbstractElementWithParent {
|
|
|
951
1211
|
this.elementCssSelector = getCssCellByIndexSelector(index);
|
|
952
1212
|
}
|
|
953
1213
|
async getBooleanValue(cellEl) {
|
|
954
|
-
const booleanEl = await cellEl.findElement(
|
|
1214
|
+
const booleanEl = await cellEl.findElement(import_selenium_webdriver19.By.className("boolean-widget"));
|
|
955
1215
|
return await booleanEl.getAttribute("aria-checked") === "true" ? 1 : 0;
|
|
956
1216
|
}
|
|
1217
|
+
async getTagsValue(cellEl) {
|
|
1218
|
+
const tagsCssSelector = ".multiselect-container .multiselect-cell";
|
|
1219
|
+
const tags = await cellEl.findElements(import_selenium_webdriver19.By.css(tagsCssSelector));
|
|
1220
|
+
const values = [];
|
|
1221
|
+
for (const tag of tags) {
|
|
1222
|
+
values.push(await tag.getAttribute("textContent"));
|
|
1223
|
+
}
|
|
1224
|
+
return values;
|
|
1225
|
+
}
|
|
957
1226
|
async getElement() {
|
|
958
1227
|
if (this._index == null) {
|
|
959
1228
|
this.index = await this.getCellIndex();
|
|
@@ -963,9 +1232,10 @@ var Cell = class extends AbstractElementWithParent {
|
|
|
963
1232
|
async getValue() {
|
|
964
1233
|
const cellEl = await this.getElement();
|
|
965
1234
|
const cellElClass = await cellEl.getAttribute("class");
|
|
966
|
-
if (cellElClass.includes("boolean-column"))
|
|
1235
|
+
if (cellElClass.includes("boolean-column" /* Boolean */))
|
|
967
1236
|
return this.getBooleanValue(cellEl);
|
|
968
|
-
|
|
1237
|
+
if (cellElClass.includes("tags-column" /* Tags */))
|
|
1238
|
+
return this.getTagsValue(cellEl);
|
|
969
1239
|
return cellEl.getText();
|
|
970
1240
|
}
|
|
971
1241
|
getIndex() {
|
|
@@ -986,9 +1256,14 @@ var Row = class extends AbstractElementWithParent {
|
|
|
986
1256
|
this.getColumnBy = getColumnBy;
|
|
987
1257
|
}
|
|
988
1258
|
_getCell({ index, name, title }) {
|
|
989
|
-
return new Cell(
|
|
990
|
-
|
|
991
|
-
|
|
1259
|
+
return new Cell(
|
|
1260
|
+
this.getFullCssSelector(),
|
|
1261
|
+
() => {
|
|
1262
|
+
return this.getColumnBy({ title, name }).getIndex();
|
|
1263
|
+
},
|
|
1264
|
+
index,
|
|
1265
|
+
this.driver
|
|
1266
|
+
);
|
|
992
1267
|
}
|
|
993
1268
|
getCellByIndex(index) {
|
|
994
1269
|
return this._getCell({ index });
|
|
@@ -1002,10 +1277,14 @@ var Row = class extends AbstractElementWithParent {
|
|
|
1002
1277
|
async select() {
|
|
1003
1278
|
const rowEl = await this.getElement();
|
|
1004
1279
|
await click(rowEl, this.driver);
|
|
1005
|
-
await wait(
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1280
|
+
await wait(
|
|
1281
|
+
async () => {
|
|
1282
|
+
const classes = await this.getClasses();
|
|
1283
|
+
return classes.includes(DX_SELECTION_CLASS);
|
|
1284
|
+
},
|
|
1285
|
+
this.driver,
|
|
1286
|
+
"Cannot select row"
|
|
1287
|
+
);
|
|
1009
1288
|
}
|
|
1010
1289
|
async isSelected() {
|
|
1011
1290
|
const result = await this.getAttribute("aria-selected");
|
|
@@ -1015,7 +1294,7 @@ var Row = class extends AbstractElementWithParent {
|
|
|
1015
1294
|
return this.index;
|
|
1016
1295
|
}
|
|
1017
1296
|
async getCells() {
|
|
1018
|
-
const cells = await this.driver.findElements(
|
|
1297
|
+
const cells = await this.driver.findElements(import_selenium_webdriver20.By.css(`${this.getFullCssSelector()} td[role="gridcell"]`));
|
|
1019
1298
|
const result = [];
|
|
1020
1299
|
cells.forEach((_, index) => {
|
|
1021
1300
|
const newCell = this.getCellByIndex(index);
|
|
@@ -1025,14 +1304,22 @@ var Row = class extends AbstractElementWithParent {
|
|
|
1025
1304
|
}
|
|
1026
1305
|
async clickInlineButton(buttonClass) {
|
|
1027
1306
|
const FIXED_TABLE_CSS_SELECTOR = ".dx-fixed-columns .dx-datagrid-content.dx-datagrid-content-fixed";
|
|
1028
|
-
const buttonCssSelector = `.${DX_DATA_ROW_CLASS}[aria-rowindex="${transformInputIndex(
|
|
1029
|
-
|
|
1307
|
+
const buttonCssSelector = `.${DX_DATA_ROW_CLASS}[aria-rowindex="${transformInputIndex(
|
|
1308
|
+
this.index
|
|
1309
|
+
)}"] .${buttonClass}`;
|
|
1310
|
+
const button = await this.driver.findElement(
|
|
1311
|
+
import_selenium_webdriver20.By.css(`${this.parentCssSelector} ${FIXED_TABLE_CSS_SELECTOR} ${buttonCssSelector}`)
|
|
1312
|
+
);
|
|
1030
1313
|
return click(button, this.driver);
|
|
1031
1314
|
}
|
|
1032
1315
|
async checkEditingMode(isEditing, msg) {
|
|
1033
|
-
await wait(
|
|
1034
|
-
|
|
1035
|
-
|
|
1316
|
+
await wait(
|
|
1317
|
+
async () => {
|
|
1318
|
+
return (await this.getClasses()).includes(DX_ROW_EDIT_CLASS) === isEditing;
|
|
1319
|
+
},
|
|
1320
|
+
this.driver,
|
|
1321
|
+
msg
|
|
1322
|
+
);
|
|
1036
1323
|
}
|
|
1037
1324
|
async edit() {
|
|
1038
1325
|
await this.clickInlineButton("edit");
|
|
@@ -1049,19 +1336,18 @@ var Row = class extends AbstractElementWithParent {
|
|
|
1049
1336
|
};
|
|
1050
1337
|
|
|
1051
1338
|
// src/pageObjects/elements/Table/elements/Column.ts
|
|
1052
|
-
var
|
|
1053
|
-
var getHeaderCssSelector = () => {
|
|
1054
|
-
return ".dx-datagrid-headers .dx-datagrid-content:not(.dx-datagrid-content-fixed)";
|
|
1055
|
-
};
|
|
1339
|
+
var import_selenium_webdriver21 = require("selenium-webdriver");
|
|
1056
1340
|
var Column = class extends AbstractElementWithParent {
|
|
1057
1341
|
_index;
|
|
1058
1342
|
_caption;
|
|
1059
1343
|
_name;
|
|
1060
|
-
|
|
1344
|
+
headerCssSelector;
|
|
1345
|
+
constructor({ parentCssSelector, headerCssSelector, name, caption, index, driver }) {
|
|
1061
1346
|
super(parentCssSelector, "", driver);
|
|
1062
1347
|
this._name = name;
|
|
1063
1348
|
this.index = index;
|
|
1064
1349
|
this._caption = caption;
|
|
1350
|
+
this.headerCssSelector = headerCssSelector;
|
|
1065
1351
|
}
|
|
1066
1352
|
set index(index) {
|
|
1067
1353
|
this._index = index;
|
|
@@ -1075,7 +1361,9 @@ var Column = class extends AbstractElementWithParent {
|
|
|
1075
1361
|
return super.getElement();
|
|
1076
1362
|
}
|
|
1077
1363
|
async getColumnHeaderIndexBy(cssSelector) {
|
|
1078
|
-
const column = await this.driver.findElement(
|
|
1364
|
+
const column = await this.driver.findElement(
|
|
1365
|
+
import_selenium_webdriver21.By.css(`${this.parentCssSelector} ${this.headerCssSelector} ${cssSelector}`)
|
|
1366
|
+
);
|
|
1079
1367
|
return transformOutputIndex(await column.getAttribute("aria-colindex"));
|
|
1080
1368
|
}
|
|
1081
1369
|
async getIndexByCaption() {
|
|
@@ -1107,9 +1395,11 @@ var Column = class extends AbstractElementWithParent {
|
|
|
1107
1395
|
// src/pageObjects/elements/Table/Table.ts
|
|
1108
1396
|
var Table = class extends AbstractElementWithParent {
|
|
1109
1397
|
formName;
|
|
1110
|
-
|
|
1398
|
+
headerCssSelector;
|
|
1399
|
+
constructor(parentCssSelector, headerCssSelector, formName, driver) {
|
|
1111
1400
|
super(parentCssSelector, `#${createTableId(formName)}`, driver);
|
|
1112
1401
|
this.formName = formName;
|
|
1402
|
+
this.headerCssSelector = headerCssSelector;
|
|
1113
1403
|
}
|
|
1114
1404
|
getColumnBy = (args) => {
|
|
1115
1405
|
if (args.title) {
|
|
@@ -1130,6 +1420,7 @@ var Table = class extends AbstractElementWithParent {
|
|
|
1130
1420
|
getColumnByTitle = (title) => {
|
|
1131
1421
|
return new Column({
|
|
1132
1422
|
parentCssSelector: this.getFullCssSelector(),
|
|
1423
|
+
headerCssSelector: this.headerCssSelector,
|
|
1133
1424
|
caption: title,
|
|
1134
1425
|
driver: this.driver
|
|
1135
1426
|
});
|
|
@@ -1137,6 +1428,7 @@ var Table = class extends AbstractElementWithParent {
|
|
|
1137
1428
|
getColumnByName = (name) => {
|
|
1138
1429
|
return new Column({
|
|
1139
1430
|
parentCssSelector: this.getFullCssSelector(),
|
|
1431
|
+
headerCssSelector: this.headerCssSelector,
|
|
1140
1432
|
name,
|
|
1141
1433
|
driver: this.driver
|
|
1142
1434
|
});
|
|
@@ -1145,7 +1437,7 @@ var Table = class extends AbstractElementWithParent {
|
|
|
1145
1437
|
return this.getRowByIndex(index).select();
|
|
1146
1438
|
}
|
|
1147
1439
|
async getRows() {
|
|
1148
|
-
const rows = await this.driver.findElements(
|
|
1440
|
+
const rows = await this.driver.findElements(import_selenium_webdriver22.By.css(`${this.getFullCssSelector()} .dx-row.dx-data-row`));
|
|
1149
1441
|
const result = [];
|
|
1150
1442
|
rows.forEach((_, index) => {
|
|
1151
1443
|
const newRow = new Row(this.getFullCssSelector(), index, this.driver, this.getColumnBy);
|
|
@@ -1154,7 +1446,9 @@ var Table = class extends AbstractElementWithParent {
|
|
|
1154
1446
|
return result;
|
|
1155
1447
|
}
|
|
1156
1448
|
async getColumns() {
|
|
1157
|
-
const columns = await this.driver.findElements(
|
|
1449
|
+
const columns = await this.driver.findElements(
|
|
1450
|
+
import_selenium_webdriver22.By.css(`${this.getFullCssSelector()} ${this.headerCssSelector} td[role="columnheader"]`)
|
|
1451
|
+
);
|
|
1158
1452
|
const result = [];
|
|
1159
1453
|
columns.forEach((_, index) => {
|
|
1160
1454
|
const newCol = new Column({
|
|
@@ -1181,24 +1475,6 @@ var Table = class extends AbstractElementWithParent {
|
|
|
1181
1475
|
}
|
|
1182
1476
|
};
|
|
1183
1477
|
|
|
1184
|
-
// src/pageObjects/elements/TableToolbar/AbstractButton.ts
|
|
1185
|
-
var AbstractButton = class extends AbstractElementWithParent {
|
|
1186
|
-
constructor(parentCssSelector, elementCssSelector, driver) {
|
|
1187
|
-
super(parentCssSelector, elementCssSelector, driver);
|
|
1188
|
-
}
|
|
1189
|
-
async click() {
|
|
1190
|
-
const button = await this.getElement();
|
|
1191
|
-
await wait(async () => {
|
|
1192
|
-
return await button.isDisplayed() && !await this.isDisabled();
|
|
1193
|
-
}, this.driver, this.buttonNotDisplayedError());
|
|
1194
|
-
await click(button, this.driver);
|
|
1195
|
-
}
|
|
1196
|
-
async isDisabled() {
|
|
1197
|
-
const button = await this.getElement();
|
|
1198
|
-
return await button.getCssValue("pointer-events") === "none";
|
|
1199
|
-
}
|
|
1200
|
-
};
|
|
1201
|
-
|
|
1202
1478
|
// src/pageObjects/elements/TableToolbar/ToolbarGroupButton.ts
|
|
1203
1479
|
var ToolbarGroupButton = class extends AbstractButton {
|
|
1204
1480
|
name;
|
|
@@ -1224,16 +1500,97 @@ var ToolbarButton = class extends AbstractButton {
|
|
|
1224
1500
|
}
|
|
1225
1501
|
};
|
|
1226
1502
|
|
|
1503
|
+
// src/pageObjects/elements/TableToolbar/ToolbarMenu.ts
|
|
1504
|
+
var import_selenium_webdriver23 = require("selenium-webdriver");
|
|
1505
|
+
|
|
1506
|
+
// src/utils/typesUtil.ts
|
|
1507
|
+
var types = {
|
|
1508
|
+
"[object Array]": "array",
|
|
1509
|
+
"[object Date]": "date",
|
|
1510
|
+
"[object Object]": "object",
|
|
1511
|
+
"[object String]": "string",
|
|
1512
|
+
"[object Null]": "null"
|
|
1513
|
+
};
|
|
1514
|
+
var type = function(object) {
|
|
1515
|
+
const typeOfObject = Object.prototype.toString.call(object);
|
|
1516
|
+
return typeof object === "object" ? types[typeOfObject] || "object" : typeof object;
|
|
1517
|
+
};
|
|
1518
|
+
var isArray = function(value) {
|
|
1519
|
+
return type(value) === "array";
|
|
1520
|
+
};
|
|
1521
|
+
var isString = function(object) {
|
|
1522
|
+
return typeof object === "string";
|
|
1523
|
+
};
|
|
1524
|
+
|
|
1525
|
+
// src/pageObjects/elements/TableToolbar/ToolbarMenu.ts
|
|
1526
|
+
var SPINDOWN_CLASS = ".dx-icon-spindown";
|
|
1527
|
+
var buttonGroupItemSelector = (formName, name) => byTestIdCssSelector(`ftb-${formName}-${name}`);
|
|
1528
|
+
var getFullCssSelector = (formName, name) => `${buttonGroupItemSelector(formName, name)} ${SPINDOWN_CLASS}`;
|
|
1529
|
+
var buttonByTextXpath = (text) => `.//span[contains(@class, "dx-menu-item-text") and contains(text(), "${text}")]`;
|
|
1530
|
+
var ToolbarMenu = class extends AbstractElementWithParent {
|
|
1531
|
+
_formName;
|
|
1532
|
+
constructor(parentCssSelector, formName, name, driver) {
|
|
1533
|
+
super(parentCssSelector, getFullCssSelector(formName, name), driver);
|
|
1534
|
+
this._formName = formName;
|
|
1535
|
+
}
|
|
1536
|
+
async toggle() {
|
|
1537
|
+
const dropdown = await this.getElement();
|
|
1538
|
+
await click(dropdown, this.driver);
|
|
1539
|
+
}
|
|
1540
|
+
getCssSelectorToButton(name) {
|
|
1541
|
+
return byTestId(`ftb-${this._formName}-${name}`);
|
|
1542
|
+
}
|
|
1543
|
+
buttonNotDisplayedError(name) {
|
|
1544
|
+
return `Toolbar menu button ${name} cannot be clicked. It is not displayed or it is disabled`;
|
|
1545
|
+
}
|
|
1546
|
+
async goToButton(name, selector) {
|
|
1547
|
+
const toolbarMenuItem = this.driver.findElement(selector);
|
|
1548
|
+
await waitElementIsClickable({
|
|
1549
|
+
element: toolbarMenuItem,
|
|
1550
|
+
errorMessage: this.buttonNotDisplayedError(name),
|
|
1551
|
+
driver: this.driver
|
|
1552
|
+
});
|
|
1553
|
+
await click(toolbarMenuItem, this.driver);
|
|
1554
|
+
}
|
|
1555
|
+
async clickButton(name) {
|
|
1556
|
+
await this.toggle();
|
|
1557
|
+
if (isString(name)) {
|
|
1558
|
+
const selector = this.getCssSelectorToButton(name);
|
|
1559
|
+
await this.goToButton(name, selector);
|
|
1560
|
+
}
|
|
1561
|
+
if (isArray(name)) {
|
|
1562
|
+
for (let n of name) {
|
|
1563
|
+
const selector = this.getCssSelectorToButton(n);
|
|
1564
|
+
await this.goToButton(n, selector);
|
|
1565
|
+
}
|
|
1566
|
+
}
|
|
1567
|
+
}
|
|
1568
|
+
async clickButtonByTitle(title) {
|
|
1569
|
+
await this.toggle();
|
|
1570
|
+
if (isString(title)) {
|
|
1571
|
+
const selector = import_selenium_webdriver23.By.xpath(buttonByTextXpath(title));
|
|
1572
|
+
await this.goToButton(title, selector);
|
|
1573
|
+
}
|
|
1574
|
+
if (isArray(title)) {
|
|
1575
|
+
for (let t of title) {
|
|
1576
|
+
const selector = import_selenium_webdriver23.By.xpath(buttonByTextXpath(t));
|
|
1577
|
+
await this.goToButton(t, selector);
|
|
1578
|
+
}
|
|
1579
|
+
}
|
|
1580
|
+
}
|
|
1581
|
+
};
|
|
1582
|
+
|
|
1227
1583
|
// src/pageObjects/elements/TableToolbar/ToolbarItem.ts
|
|
1228
1584
|
var GROUP_BUTTON_CLASS = "toolbar-group-button";
|
|
1229
1585
|
var toolbarItemSelector = (form, name) => byTestIdCssSelector(`ftb-${form}-${name}`);
|
|
1230
1586
|
var ToolbarItem = class extends AbstractElementWithParent {
|
|
1231
1587
|
_button;
|
|
1232
|
-
|
|
1588
|
+
_formName;
|
|
1233
1589
|
_itemName;
|
|
1234
1590
|
constructor(parentCssSelector, formName, itemName, driver) {
|
|
1235
1591
|
super(parentCssSelector, toolbarItemSelector(formName, itemName), driver);
|
|
1236
1592
|
this._itemName = itemName;
|
|
1593
|
+
this._formName = formName;
|
|
1237
1594
|
}
|
|
1238
1595
|
async init() {
|
|
1239
1596
|
if (this._button)
|
|
@@ -1253,6 +1610,9 @@ var ToolbarItem = class extends AbstractElementWithParent {
|
|
|
1253
1610
|
await this.init();
|
|
1254
1611
|
return await this._button.isDisabled();
|
|
1255
1612
|
}
|
|
1613
|
+
get menu() {
|
|
1614
|
+
return new ToolbarMenu(this.parentCssSelector, this._formName, this._itemName, this.driver);
|
|
1615
|
+
}
|
|
1256
1616
|
};
|
|
1257
1617
|
|
|
1258
1618
|
// src/pageObjects/elements/TableToolbar/FormToolbar.ts
|
|
@@ -1310,7 +1670,7 @@ var FormFilterField = class extends AbstractEditor {
|
|
|
1310
1670
|
};
|
|
1311
1671
|
|
|
1312
1672
|
// src/pageObjects/elements/Filters/FilterPanel.ts
|
|
1313
|
-
var
|
|
1673
|
+
var import_selenium_webdriver24 = require("selenium-webdriver");
|
|
1314
1674
|
|
|
1315
1675
|
// src/pageObjects/elements/Filters/PanelFilterField.ts
|
|
1316
1676
|
var PanelFilterField = class extends AbstractEditor {
|
|
@@ -1365,7 +1725,7 @@ var FilterPanel = class extends AbstractElement {
|
|
|
1365
1725
|
async filterPanelButtons() {
|
|
1366
1726
|
const selector = `${this.elementCssSelector} ${FILTER_PANEL_SELECTOR} .filter-panel__buttons-panel .dx-button-text`;
|
|
1367
1727
|
const el = await this.getElement();
|
|
1368
|
-
return el.findElements(
|
|
1728
|
+
return el.findElements(import_selenium_webdriver24.By.css(selector));
|
|
1369
1729
|
}
|
|
1370
1730
|
constructor(formName, driver) {
|
|
1371
1731
|
super(driver, drawerSelector(formName));
|
|
@@ -1398,16 +1758,19 @@ var FilterPanel = class extends AbstractElement {
|
|
|
1398
1758
|
await this.driver.sleep(300);
|
|
1399
1759
|
}
|
|
1400
1760
|
async close() {
|
|
1401
|
-
const btn = await this.driver.findElement(
|
|
1761
|
+
const btn = await this.driver.findElement(import_selenium_webdriver24.By.css(`${this.elementCssSelector} ${CLOSE_SELECTOR}`));
|
|
1402
1762
|
await click(btn, this.driver);
|
|
1403
1763
|
}
|
|
1404
1764
|
};
|
|
1405
1765
|
|
|
1406
1766
|
// src/pageObjects/elements/Forms/ListForm.ts
|
|
1767
|
+
var DATAGRID_HEADER_CSS_SELECTOR = ".dx-datagrid-headers .dx-datagrid-content:not(.dx-datagrid-content-fixed)";
|
|
1407
1768
|
var ListForm = class extends AbstractForm {
|
|
1769
|
+
headerCssSelector;
|
|
1408
1770
|
constructor(driver) {
|
|
1409
1771
|
super(driver);
|
|
1410
1772
|
this.popupContainerCssSelector = `.popup .form-inline-${this.formName}`;
|
|
1773
|
+
this.headerCssSelector = DATAGRID_HEADER_CSS_SELECTOR;
|
|
1411
1774
|
}
|
|
1412
1775
|
/**
|
|
1413
1776
|
* Находит таблицу
|
|
@@ -1417,7 +1780,7 @@ var ListForm = class extends AbstractForm {
|
|
|
1417
1780
|
* expect(listForm.table());
|
|
1418
1781
|
*/
|
|
1419
1782
|
table() {
|
|
1420
|
-
return new Table(this.containerCssSelector, this.formName, this.driver);
|
|
1783
|
+
return new Table(this.containerCssSelector, this.headerCssSelector, this.formName, this.driver);
|
|
1421
1784
|
}
|
|
1422
1785
|
/**
|
|
1423
1786
|
* Находит группу на лист форме по имени
|
|
@@ -1462,9 +1825,68 @@ var ListForm = class extends AbstractForm {
|
|
|
1462
1825
|
return new FilterPanel(this.formName, this.driver);
|
|
1463
1826
|
}
|
|
1464
1827
|
};
|
|
1828
|
+
|
|
1829
|
+
// src/pageObjects/elements/Forms/TreeView.ts
|
|
1830
|
+
var TREELIST_HEADER_CSS_SELECTOR = ".dx-treelist-headers .dx-treelist-content:not(.dx-datagrid-content-fixed)";
|
|
1831
|
+
var TreeView = class extends ListForm {
|
|
1832
|
+
constructor(driver) {
|
|
1833
|
+
super(driver);
|
|
1834
|
+
this.popupContainerCssSelector = `.popup .wrapper-tree-view-${this.formName}`;
|
|
1835
|
+
this.headerCssSelector = TREELIST_HEADER_CSS_SELECTOR;
|
|
1836
|
+
}
|
|
1837
|
+
};
|
|
1838
|
+
|
|
1839
|
+
// src/pageObjects/elements/Dialog.ts
|
|
1840
|
+
var import_selenium_webdriver25 = require("selenium-webdriver");
|
|
1841
|
+
var DIALOG_CLASS = ".d5-dialog";
|
|
1842
|
+
var DIALOG_TITLE_CLASS = ".dialog__title";
|
|
1843
|
+
var DIALOG_TEXT_CLASS = ".dialog__text";
|
|
1844
|
+
var DIALOG_BUTTONS_PANEL_CLASS = ".dialog__buttons-panel";
|
|
1845
|
+
var buttonByTextXpath2 = (text) => `.//span[contains(@class, "dx-button-text") and contains(text(), "${text}")]`;
|
|
1846
|
+
var DialogButton = class extends AbstractButton {
|
|
1847
|
+
text;
|
|
1848
|
+
constructor(parentCssSelector, text, driver) {
|
|
1849
|
+
super(parentCssSelector, "", driver);
|
|
1850
|
+
this.text = text;
|
|
1851
|
+
}
|
|
1852
|
+
async getElement() {
|
|
1853
|
+
const panel = await super.getElement();
|
|
1854
|
+
return panel.findElement(import_selenium_webdriver25.By.xpath(buttonByTextXpath2(this.text)));
|
|
1855
|
+
}
|
|
1856
|
+
buttonNotDisplayedError() {
|
|
1857
|
+
return `Dialog button ${this.text} cannot be clicked. It is not displayed or it is disabled`;
|
|
1858
|
+
}
|
|
1859
|
+
};
|
|
1860
|
+
var Dialog = class extends AbstractElement {
|
|
1861
|
+
constructor(driver) {
|
|
1862
|
+
super(driver, DIALOG_CLASS);
|
|
1863
|
+
}
|
|
1864
|
+
get titleSelector() {
|
|
1865
|
+
return this.joinRelativeCssSelectors([DIALOG_CLASS, DIALOG_TITLE_CLASS]);
|
|
1866
|
+
}
|
|
1867
|
+
get textSelector() {
|
|
1868
|
+
return this.joinRelativeCssSelectors([DIALOG_CLASS, DIALOG_TEXT_CLASS]);
|
|
1869
|
+
}
|
|
1870
|
+
get buttonsSelector() {
|
|
1871
|
+
return this.joinRelativeCssSelectors([DIALOG_CLASS, DIALOG_BUTTONS_PANEL_CLASS]);
|
|
1872
|
+
}
|
|
1873
|
+
async title() {
|
|
1874
|
+
const el = await this.driver.findElement(import_selenium_webdriver25.By.css(this.titleSelector));
|
|
1875
|
+
return await el.getText();
|
|
1876
|
+
}
|
|
1877
|
+
async text() {
|
|
1878
|
+
const el = await this.driver.findElement(import_selenium_webdriver25.By.css(this.textSelector));
|
|
1879
|
+
return await el.getText();
|
|
1880
|
+
}
|
|
1881
|
+
button(text) {
|
|
1882
|
+
return new DialogButton(this.buttonsSelector, text, this.driver);
|
|
1883
|
+
}
|
|
1884
|
+
};
|
|
1465
1885
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1466
1886
|
0 && (module.exports = {
|
|
1467
1887
|
AbstractPage,
|
|
1888
|
+
ControlClass,
|
|
1889
|
+
Dialog,
|
|
1468
1890
|
FilterPanel,
|
|
1469
1891
|
FormEdit,
|
|
1470
1892
|
FormField,
|
|
@@ -1475,6 +1897,7 @@ var ListForm = class extends AbstractForm {
|
|
|
1475
1897
|
PanelFilterField,
|
|
1476
1898
|
SubsystemsPanel,
|
|
1477
1899
|
TextEditor,
|
|
1900
|
+
TreeView,
|
|
1478
1901
|
byTestId,
|
|
1479
1902
|
byTestIdCssSelector,
|
|
1480
1903
|
click,
|
|
@@ -1482,6 +1905,7 @@ var ListForm = class extends AbstractForm {
|
|
|
1482
1905
|
createDriver,
|
|
1483
1906
|
editorFactory,
|
|
1484
1907
|
elementIsNotPresent,
|
|
1908
|
+
readonlyLocator,
|
|
1485
1909
|
signIn,
|
|
1486
1910
|
wait,
|
|
1487
1911
|
waitElementIsVisible
|