d5-testing-library 1.8.0-alpha.12 → 1.8.0-alpha.14
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/FormEdit-6DS2QEWW.mjs +7 -0
- package/dist/ListForm-MS7U6ME7.mjs +7 -0
- package/dist/TreeView-DGKYMM67.mjs +8 -0
- package/dist/{chunk-NAFA4MCF.mjs → chunk-I42Z72TQ.mjs} +66 -60
- package/dist/{chunk-HPGRT5LR.mjs → chunk-JLEBXO5Q.mjs} +240 -64
- package/dist/{chunk-WZAU5CMO.mjs → chunk-SR3FJAYB.mjs} +1 -1
- package/dist/{chunk-LNBAZKTC.mjs → chunk-WYLPCDA5.mjs} +2 -1
- package/dist/cjs/d5-testing-library.cjs +370 -131
- package/dist/d5-testing-library.d.ts +98 -11
- package/dist/d5-testing-library.legacy-esm.js +18 -4
- package/dist/d5-testing-library.mjs +18 -4
- package/package.json +18 -6
- package/dist/FormEdit-WIXYJKA7.mjs +0 -7
- package/dist/ListForm-3HJGPSX3.mjs +0 -7
- package/dist/TreeView-NDBZ6ZAP.mjs +0 -8
|
@@ -150,6 +150,14 @@ var click = async (webElement, driver) => {
|
|
|
150
150
|
const actions = driver.actions({ async: true });
|
|
151
151
|
await actions.move({ origin: webElement }).click().perform();
|
|
152
152
|
};
|
|
153
|
+
var contextMenu = async (webElement, driver) => {
|
|
154
|
+
driver = driver ?? config().driver;
|
|
155
|
+
if (!await webElement.isDisplayed()) {
|
|
156
|
+
await driver.executeScript("arguments[0].scrollIntoView(true);", webElement);
|
|
157
|
+
}
|
|
158
|
+
const actions = driver.actions({ async: true });
|
|
159
|
+
await actions.move({ origin: webElement }).contextClick().perform();
|
|
160
|
+
};
|
|
153
161
|
|
|
154
162
|
// src/utils/locators.ts
|
|
155
163
|
import { By as By2 } from "selenium-webdriver";
|
|
@@ -548,37 +556,44 @@ var BaseDateEditor = class extends AbstractDXEditorWithInput {
|
|
|
548
556
|
super(parentCssSelector, elementCssSelector, driver);
|
|
549
557
|
this.setClearStrategy(new InputClearStrategy());
|
|
550
558
|
}
|
|
551
|
-
async
|
|
559
|
+
async setArrayValue(value) {
|
|
552
560
|
const actions = this.driver.actions({ async: true });
|
|
553
561
|
const dateField = await this.driver.findElement(By8.css(`${this.getFullCssSelector()}`));
|
|
562
|
+
const dateInputEl = await this.getInputElement();
|
|
554
563
|
const dateFieldDataTestID = await this.getDataTestId();
|
|
555
|
-
const
|
|
564
|
+
const formattedDates = value.map(formatDMYDate);
|
|
565
|
+
const button = await dateField.findElement(By8.css(`.${BTN_CALENDAR_POPOVER_OPEN_SELECTOR}`));
|
|
566
|
+
await click(button, this.driver);
|
|
567
|
+
const calendarPopoverElement = await this.driver.findElement(By8.css(byTestIdCssSelector(`${dateFieldDataTestID}-calendar-popover`)));
|
|
568
|
+
const dateFromInput = await calendarPopoverElement.findElement(
|
|
569
|
+
By8.css(`.${BTN_CALENDAR_POPOVER_DATE_FROM_INPUT_SELECTOR} .dx-texteditor-input`)
|
|
570
|
+
);
|
|
571
|
+
const dateToInput = await calendarPopoverElement.findElement(
|
|
572
|
+
By8.css(`.${BTN_CALENDAR_POPOVER_DATE_TO_INPUT_SELECTOR} .dx-texteditor-input`)
|
|
573
|
+
);
|
|
574
|
+
await click(dateFromInput, this.driver);
|
|
575
|
+
await dateFromInput.sendKeys(formattedDates[0]);
|
|
576
|
+
await click(dateToInput, this.driver);
|
|
577
|
+
await actions.move({ origin: dateInputEl }).sendKeys(Key3.HOME).perform();
|
|
578
|
+
await dateToInput.sendKeys(formattedDates[1]);
|
|
579
|
+
await actions.move({ origin: dateInputEl }).sendKeys(Key3.ENTER).perform();
|
|
580
|
+
const btnOk = await this.driver.findElement(By8.css(`.${BTN_SAVE_SELECTOR}`));
|
|
581
|
+
await click(btnOk, this.driver);
|
|
582
|
+
}
|
|
583
|
+
async setSingleValue(value) {
|
|
584
|
+
const actions = this.driver.actions({ async: true });
|
|
585
|
+
const formattedDate = formatDMYDate(value);
|
|
556
586
|
const dateInputEl = await this.getInputElement();
|
|
557
|
-
await dateInputEl.
|
|
587
|
+
await click(dateInputEl, this.driver);
|
|
588
|
+
await actions.move({ origin: dateInputEl }).sendKeys(Key3.HOME).perform();
|
|
589
|
+
await actions.move({ origin: dateInputEl }).sendKeys(formattedDate, Key3.ENTER).perform();
|
|
590
|
+
}
|
|
591
|
+
async setDateValue(value) {
|
|
592
|
+
await this.clear();
|
|
558
593
|
if (Array.isArray(value)) {
|
|
559
|
-
|
|
560
|
-
const button = await dateField.findElement(By8.css(`.${BTN_CALENDAR_POPOVER_OPEN_SELECTOR}`));
|
|
561
|
-
await button.click();
|
|
562
|
-
const calendarPopoverElement = await this.driver.findElement(By8.css(calendarPopoverSelector));
|
|
563
|
-
const dateFromInput = await calendarPopoverElement.findElement(
|
|
564
|
-
By8.css(`.${BTN_CALENDAR_POPOVER_DATE_FROM_INPUT_SELECTOR} .dx-texteditor-input`)
|
|
565
|
-
);
|
|
566
|
-
const dateToInput = await calendarPopoverElement.findElement(
|
|
567
|
-
By8.css(`.${BTN_CALENDAR_POPOVER_DATE_TO_INPUT_SELECTOR} .dx-texteditor-input`)
|
|
568
|
-
);
|
|
569
|
-
await dateFromInput.click();
|
|
570
|
-
await dateFromInput.sendKeys(formattedDates[0]);
|
|
571
|
-
await dateToInput.click();
|
|
572
|
-
await actions.move({ origin: dateInputEl }).sendKeys(Key3.HOME).perform();
|
|
573
|
-
await dateToInput.sendKeys(formattedDates[1]);
|
|
574
|
-
await actions.move({ origin: dateInputEl }).sendKeys(Key3.ENTER).perform();
|
|
575
|
-
const btnOk = await this.driver.findElement(By8.css(`.${BTN_SAVE_SELECTOR}`));
|
|
576
|
-
await btnOk.click();
|
|
594
|
+
await this.setArrayValue(value);
|
|
577
595
|
} else {
|
|
578
|
-
|
|
579
|
-
await click(dateInputEl, this.driver);
|
|
580
|
-
await actions.move({ origin: dateInputEl }).sendKeys(Key3.HOME).perform();
|
|
581
|
-
await actions.move({ origin: dateInputEl }).sendKeys(formattedDate, Key3.ENTER).perform();
|
|
596
|
+
await this.setSingleValue(value);
|
|
582
597
|
}
|
|
583
598
|
}
|
|
584
599
|
};
|
|
@@ -641,15 +656,14 @@ var DateRangeEditor = class extends BaseDateEditor {
|
|
|
641
656
|
// src/pageObjects/elements/Editors/Date/DateEditor.ts
|
|
642
657
|
var DateEditor = class extends AbstractDXEditorWithInput {
|
|
643
658
|
editorInstance = null;
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
async init(parentCssSelector, elementCssSelector, driver) {
|
|
650
|
-
await this.updateEditorInstance(parentCssSelector, elementCssSelector, driver);
|
|
659
|
+
async init() {
|
|
660
|
+
if (this.editorInstance) {
|
|
661
|
+
return this.editorInstance;
|
|
662
|
+
}
|
|
663
|
+
await this.setEditorInstance();
|
|
651
664
|
}
|
|
652
|
-
async
|
|
665
|
+
async setEditorInstance() {
|
|
666
|
+
const { parentCssSelector, elementCssSelector, driver } = this;
|
|
653
667
|
const elementInstance = new AbstractFormElement(parentCssSelector, elementCssSelector, driver);
|
|
654
668
|
const classString = await elementInstance.getClasses();
|
|
655
669
|
switch (true) {
|
|
@@ -663,25 +677,14 @@ var DateEditor = class extends AbstractDXEditorWithInput {
|
|
|
663
677
|
this.editorInstance = new SingleDateEditor(parentCssSelector, elementCssSelector, driver);
|
|
664
678
|
}
|
|
665
679
|
}
|
|
666
|
-
async ensureInitialized() {
|
|
667
|
-
if (!this.editorInstance) {
|
|
668
|
-
await this.initPromise;
|
|
669
|
-
}
|
|
670
|
-
}
|
|
671
680
|
async setValue(value) {
|
|
672
|
-
await this.
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
return await this.updateEditorInstance(this.parentCssSelector, this.elementCssSelector, this.driver);
|
|
676
|
-
}
|
|
677
|
-
throw new Error("Editor instance is not initialized.");
|
|
681
|
+
await this.init();
|
|
682
|
+
await this.editorInstance.setValue(value);
|
|
683
|
+
await this.setEditorInstance();
|
|
678
684
|
}
|
|
679
685
|
async getValue() {
|
|
680
|
-
await this.
|
|
681
|
-
|
|
682
|
-
return this.editorInstance.getValue();
|
|
683
|
-
}
|
|
684
|
-
throw new Error("Editor instance is not initialized.");
|
|
686
|
+
await this.init();
|
|
687
|
+
return this.editorInstance.getValue();
|
|
685
688
|
}
|
|
686
689
|
};
|
|
687
690
|
|
|
@@ -841,17 +844,19 @@ function createEditorButtonTestId(itemName) {
|
|
|
841
844
|
|
|
842
845
|
// src/utils/waitElementIsClickable.ts
|
|
843
846
|
async function waitElementIsClickable({
|
|
844
|
-
element,
|
|
845
847
|
timeout,
|
|
846
848
|
errorMessage,
|
|
847
|
-
driver
|
|
849
|
+
driver,
|
|
850
|
+
...rest
|
|
848
851
|
}) {
|
|
849
852
|
driver = driver ?? config().driver;
|
|
850
853
|
await wait(async () => {
|
|
851
|
-
const
|
|
852
|
-
|
|
854
|
+
const searchedElement = "by" in rest ? await fixElementStaleError(rest.by, driver) : rest.element;
|
|
855
|
+
const isDisabled = await searchedElement.getCssValue("pointer-events") === "none";
|
|
856
|
+
return await searchedElement.isDisplayed() && !isDisabled;
|
|
853
857
|
}, driver, errorMessage, timeout ?? config().timeout);
|
|
854
858
|
}
|
|
859
|
+
var waitElementIsClickable_default = waitElementIsClickable;
|
|
855
860
|
|
|
856
861
|
// src/pageObjects/elements/EditorButton.ts
|
|
857
862
|
var EditorButton = class extends AbstractElementWithParent {
|
|
@@ -865,7 +870,7 @@ var EditorButton = class extends AbstractElementWithParent {
|
|
|
865
870
|
}
|
|
866
871
|
async click() {
|
|
867
872
|
const button = await this.getElement();
|
|
868
|
-
await
|
|
873
|
+
await waitElementIsClickable_default({
|
|
869
874
|
element: button,
|
|
870
875
|
errorMessage: this.buttonNotDisplayedError(),
|
|
871
876
|
driver: this.driver
|
|
@@ -969,14 +974,14 @@ var FormField = class extends AbstractEditor {
|
|
|
969
974
|
// src/pageObjects/elements/Forms/Form.ts
|
|
970
975
|
import { By as By15 } from "selenium-webdriver";
|
|
971
976
|
|
|
972
|
-
// src/pageObjects/elements/
|
|
977
|
+
// src/pageObjects/elements/AbstractButton.ts
|
|
973
978
|
var AbstractButton = class extends AbstractElementWithParent {
|
|
974
979
|
constructor(parentCssSelector, elementCssSelector, driver) {
|
|
975
980
|
super(parentCssSelector, elementCssSelector, driver);
|
|
976
981
|
}
|
|
977
982
|
async click() {
|
|
978
983
|
const button = await this.getElement();
|
|
979
|
-
await
|
|
984
|
+
await waitElementIsClickable_default({
|
|
980
985
|
element: button,
|
|
981
986
|
errorMessage: this.buttonNotDisplayedError(),
|
|
982
987
|
driver: this.driver
|
|
@@ -1259,15 +1264,15 @@ async function classDependencyInjector(formType) {
|
|
|
1259
1264
|
let SubFormFactoryClass;
|
|
1260
1265
|
switch (formType) {
|
|
1261
1266
|
case "1" /* LIST */:
|
|
1262
|
-
SubFormFactoryClass = (await import("./ListForm-
|
|
1267
|
+
SubFormFactoryClass = (await import("./ListForm-MS7U6ME7.mjs")).default;
|
|
1263
1268
|
break;
|
|
1264
1269
|
case "3" /* TREE */:
|
|
1265
|
-
SubFormFactoryClass = (await import("./TreeView-
|
|
1270
|
+
SubFormFactoryClass = (await import("./TreeView-DGKYMM67.mjs")).default;
|
|
1266
1271
|
break;
|
|
1267
1272
|
case "2" /* EDIT */:
|
|
1268
1273
|
case "99" /* FREE_FORM */:
|
|
1269
1274
|
case "4" /* REPORT */:
|
|
1270
|
-
SubFormFactoryClass = (await import("./FormEdit-
|
|
1275
|
+
SubFormFactoryClass = (await import("./FormEdit-6DS2QEWW.mjs")).default;
|
|
1271
1276
|
break;
|
|
1272
1277
|
default:
|
|
1273
1278
|
throw new Error(`Unsupported form type ${formType}`);
|
|
@@ -1349,6 +1354,7 @@ export {
|
|
|
1349
1354
|
wait,
|
|
1350
1355
|
waitElementIsVisible,
|
|
1351
1356
|
click,
|
|
1357
|
+
contextMenu,
|
|
1352
1358
|
byTestIdCssSelector,
|
|
1353
1359
|
byTestId,
|
|
1354
1360
|
readonlyLocator,
|
|
@@ -1363,7 +1369,7 @@ export {
|
|
|
1363
1369
|
createLayoutFilterTestId,
|
|
1364
1370
|
createTableId,
|
|
1365
1371
|
createSubSystemTestId,
|
|
1366
|
-
|
|
1372
|
+
waitElementIsClickable_default,
|
|
1367
1373
|
AbstractButton,
|
|
1368
1374
|
AbstractEditor,
|
|
1369
1375
|
FormField,
|
|
@@ -8,18 +8,19 @@ import {
|
|
|
8
8
|
byTestId,
|
|
9
9
|
byTestIdCssSelector,
|
|
10
10
|
click,
|
|
11
|
+
contextMenu,
|
|
11
12
|
createDocFilterTestId,
|
|
12
13
|
createHeaderFilterTestId,
|
|
13
14
|
createLayoutFilterTestId,
|
|
14
15
|
createTableId,
|
|
15
16
|
fixElementStaleError,
|
|
16
17
|
wait,
|
|
17
|
-
|
|
18
|
+
waitElementIsClickable_default,
|
|
18
19
|
waitElementIsVisible
|
|
19
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-I42Z72TQ.mjs";
|
|
20
21
|
|
|
21
22
|
// src/pageObjects/elements/Table/Table.ts
|
|
22
|
-
import { By as
|
|
23
|
+
import { By as By6 } from "selenium-webdriver";
|
|
23
24
|
|
|
24
25
|
// src/pageObjects/elements/Table/elements/Row.ts
|
|
25
26
|
import { By as By3 } from "selenium-webdriver";
|
|
@@ -124,6 +125,13 @@ var Row = class extends AbstractElementWithParent {
|
|
|
124
125
|
index;
|
|
125
126
|
getColumnBy;
|
|
126
127
|
fixedTableContentCssSelector;
|
|
128
|
+
/**
|
|
129
|
+
* @param parentCssSelector
|
|
130
|
+
* @param fixedTableContentCssSelector
|
|
131
|
+
* @param index починається з 0 (в getCssRowByIndexSelector додається +1)
|
|
132
|
+
* @param driver
|
|
133
|
+
* @param getColumnBy
|
|
134
|
+
*/
|
|
127
135
|
constructor(parentCssSelector, fixedTableContentCssSelector, index, driver, getColumnBy) {
|
|
128
136
|
super(parentCssSelector, getCssRowByIndexSelector(index), driver);
|
|
129
137
|
this.index = index;
|
|
@@ -265,16 +273,141 @@ var Column = class extends AbstractElementWithParent {
|
|
|
265
273
|
}
|
|
266
274
|
};
|
|
267
275
|
|
|
276
|
+
// src/utils/typesUtil.ts
|
|
277
|
+
var types = {
|
|
278
|
+
"[object Array]": "array",
|
|
279
|
+
"[object Date]": "date",
|
|
280
|
+
"[object Object]": "object",
|
|
281
|
+
"[object String]": "string",
|
|
282
|
+
"[object Null]": "null"
|
|
283
|
+
};
|
|
284
|
+
var type = function(object) {
|
|
285
|
+
const typeOfObject = Object.prototype.toString.call(object);
|
|
286
|
+
return typeof object === "object" ? types[typeOfObject] || "object" : typeof object;
|
|
287
|
+
};
|
|
288
|
+
var isArray = function(value) {
|
|
289
|
+
return type(value) === "array";
|
|
290
|
+
};
|
|
291
|
+
var isString = function(object) {
|
|
292
|
+
return typeof object === "string";
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
// src/pageObjects/elements/AbstractDropDownMenuList.ts
|
|
296
|
+
var AbstractDropDownMenuList = class extends AbstractElementWithParent {
|
|
297
|
+
buttonNotDisplayedError(name) {
|
|
298
|
+
return `Menu button ${name} cannot be clicked. It is not displayed or it is disabled`;
|
|
299
|
+
}
|
|
300
|
+
async clickItemBy(errorMessage, by) {
|
|
301
|
+
await waitElementIsClickable_default({
|
|
302
|
+
errorMessage,
|
|
303
|
+
driver: this.driver,
|
|
304
|
+
by
|
|
305
|
+
});
|
|
306
|
+
const menuItemElement = await fixElementStaleError(by, this.driver);
|
|
307
|
+
await click(menuItemElement, this.driver);
|
|
308
|
+
}
|
|
309
|
+
async clickItemByPath(path, getBy) {
|
|
310
|
+
let pathList = isString(path) ? [path] : path;
|
|
311
|
+
for (let text of pathList) {
|
|
312
|
+
await this.clickItemBy(this.buttonNotDisplayedError(text), getBy(text));
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
clickButton(name) {
|
|
316
|
+
return this.clickItemByPath(name, this.getButtonNameBy.bind(this));
|
|
317
|
+
}
|
|
318
|
+
clickButtonByTitle(title) {
|
|
319
|
+
return this.clickItemByPath(title, this.getButtonTitleBy.bind(this));
|
|
320
|
+
}
|
|
321
|
+
isVisible() {
|
|
322
|
+
return Promise.resolve(true);
|
|
323
|
+
}
|
|
324
|
+
};
|
|
325
|
+
|
|
326
|
+
// src/pageObjects/elements/DXContextMenuList.ts
|
|
327
|
+
import { By as By5 } from "selenium-webdriver";
|
|
328
|
+
|
|
329
|
+
// src/utils/cssToXPath.ts
|
|
330
|
+
function cssClassesToXPath(classNames) {
|
|
331
|
+
const classNamesList = classNames.split(".").filter((className) => !!className);
|
|
332
|
+
const chained = classNamesList.map((className) => `contains(@class, "${className}")`).join(" and ");
|
|
333
|
+
return `[${chained}]`;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// src/pageObjects/elements/DXContextMenuList.ts
|
|
337
|
+
var CONTEXT_MENU_CLASS = "dx-context-menu";
|
|
338
|
+
var CONTEXT_MENU_ITEM_TEXT_CLASS = "dx-menu-item-text";
|
|
339
|
+
var DXContextMenuList = class extends AbstractDropDownMenuList {
|
|
340
|
+
/**
|
|
341
|
+
* @param parentCssSelector
|
|
342
|
+
* @param classNames - Список класів. Починається з крапки
|
|
343
|
+
* @param driver
|
|
344
|
+
*/
|
|
345
|
+
constructor(parentCssSelector, classNames, driver) {
|
|
346
|
+
super(parentCssSelector, `.${CONTEXT_MENU_CLASS}${classNames}`, driver);
|
|
347
|
+
}
|
|
348
|
+
getButtonTitleBy(title) {
|
|
349
|
+
const buttonByTextXpath = (text) => `//span[contains(@class, "${CONTEXT_MENU_ITEM_TEXT_CLASS}") and contains(text(), "${text}")]`;
|
|
350
|
+
const xpath = "//div" + cssClassesToXPath(this.elementCssSelector) + buttonByTextXpath(title);
|
|
351
|
+
return By5.xpath(xpath);
|
|
352
|
+
}
|
|
353
|
+
async isVisible() {
|
|
354
|
+
try {
|
|
355
|
+
await waitElementIsVisible({
|
|
356
|
+
element: await this.driver.findElement(By5.css(`.dx-overlay-wrapper .dx-contextmenu`)),
|
|
357
|
+
driver: this.driver,
|
|
358
|
+
errorMessage: "Cannot find dropdown element"
|
|
359
|
+
});
|
|
360
|
+
} catch {
|
|
361
|
+
return false;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
};
|
|
365
|
+
|
|
366
|
+
// src/pageObjects/elements/Table/elements/ContextMenu.ts
|
|
367
|
+
var ContextMenu = class extends DXContextMenuList {
|
|
368
|
+
_formName;
|
|
369
|
+
_initFn;
|
|
370
|
+
constructor(cssClass, formName, driver) {
|
|
371
|
+
super("", cssClass, driver);
|
|
372
|
+
this._formName = formName;
|
|
373
|
+
}
|
|
374
|
+
setInit(cb) {
|
|
375
|
+
this._initFn = cb;
|
|
376
|
+
return this;
|
|
377
|
+
}
|
|
378
|
+
getButtonNameBy(name) {
|
|
379
|
+
return byTestId(`cm-${this._formName}-${name}`);
|
|
380
|
+
}
|
|
381
|
+
async clickButtonByTitle(title) {
|
|
382
|
+
await this._initFn?.();
|
|
383
|
+
await super.clickButtonByTitle(title);
|
|
384
|
+
}
|
|
385
|
+
async clickButton(name) {
|
|
386
|
+
await this._initFn?.();
|
|
387
|
+
await super.clickButton(name);
|
|
388
|
+
}
|
|
389
|
+
};
|
|
390
|
+
|
|
268
391
|
// src/pageObjects/elements/Table/Table.ts
|
|
269
392
|
var Table = class extends AbstractElementWithParent {
|
|
270
393
|
formName;
|
|
271
394
|
headerCssSelector;
|
|
395
|
+
contextMenuCssSelector;
|
|
272
396
|
fixedTableContentCssSelector;
|
|
273
397
|
tableContentCssSelector;
|
|
274
|
-
constructor(
|
|
398
|
+
constructor({
|
|
399
|
+
parentCssSelector,
|
|
400
|
+
contextMenuCssSelector,
|
|
401
|
+
tableContentCssSelector,
|
|
402
|
+
headerCssSelector,
|
|
403
|
+
fixedTableContentCssSelector,
|
|
404
|
+
formName,
|
|
405
|
+
driver
|
|
406
|
+
}) {
|
|
275
407
|
super(parentCssSelector, `#${createTableId(formName)}`, driver);
|
|
276
408
|
this.formName = formName;
|
|
277
409
|
this.headerCssSelector = headerCssSelector;
|
|
410
|
+
this.contextMenuCssSelector = contextMenuCssSelector;
|
|
278
411
|
this.fixedTableContentCssSelector = fixedTableContentCssSelector;
|
|
279
412
|
this.tableContentCssSelector = tableContentCssSelector;
|
|
280
413
|
}
|
|
@@ -284,10 +417,18 @@ var Table = class extends AbstractElementWithParent {
|
|
|
284
417
|
}
|
|
285
418
|
return this.getColumnByName(args.name);
|
|
286
419
|
};
|
|
420
|
+
/**
|
|
421
|
+
* Отримати рядок по індексу.
|
|
422
|
+
* @param index починається з 0
|
|
423
|
+
*/
|
|
287
424
|
getRowByIndex(index) {
|
|
288
425
|
return new Row(this.getFullCssSelector(), this.fixedTableContentCssSelector, index, this.driver, this.getColumnBy);
|
|
289
426
|
}
|
|
427
|
+
/**
|
|
428
|
+
* @param index починається з 0
|
|
429
|
+
*/
|
|
290
430
|
getColumnByIndex(index) {
|
|
431
|
+
this.getRowByIndex(index);
|
|
291
432
|
return new Column({
|
|
292
433
|
parentCssSelector: this.getFullCssSelector(),
|
|
293
434
|
driver: this.driver,
|
|
@@ -310,12 +451,16 @@ var Table = class extends AbstractElementWithParent {
|
|
|
310
451
|
driver: this.driver
|
|
311
452
|
});
|
|
312
453
|
};
|
|
454
|
+
/**
|
|
455
|
+
* Вибрати рядок по індексу.
|
|
456
|
+
* @param index починається з 0
|
|
457
|
+
*/
|
|
313
458
|
selectRowByIndex(index) {
|
|
314
459
|
return this.getRowByIndex(index).select();
|
|
315
460
|
}
|
|
316
461
|
async getRows() {
|
|
317
462
|
const rowsFullCssSelector = `${this.getFullCssSelector()} ${this.tableContentCssSelector} .dx-row.dx-data-row`;
|
|
318
|
-
const rows = await this.driver.findElements(
|
|
463
|
+
const rows = await this.driver.findElements(By6.css(rowsFullCssSelector));
|
|
319
464
|
const result = [];
|
|
320
465
|
rows.forEach((_, index) => {
|
|
321
466
|
const newRow = new Row(
|
|
@@ -331,7 +476,7 @@ var Table = class extends AbstractElementWithParent {
|
|
|
331
476
|
}
|
|
332
477
|
async getColumns() {
|
|
333
478
|
const columns = await this.driver.findElements(
|
|
334
|
-
|
|
479
|
+
By6.css(`${this.getFullCssSelector()} ${this.headerCssSelector} td[role="columnheader"] .header-template-text`)
|
|
335
480
|
);
|
|
336
481
|
const result = [];
|
|
337
482
|
columns.forEach((_, index) => {
|
|
@@ -357,6 +502,50 @@ var Table = class extends AbstractElementWithParent {
|
|
|
357
502
|
field(name) {
|
|
358
503
|
return new FormField(this.getFullCssSelector(), this.formName, name, this.driver);
|
|
359
504
|
}
|
|
505
|
+
/**
|
|
506
|
+
* Возвращает список строк которые выделены
|
|
507
|
+
* @returns Row[]
|
|
508
|
+
* @example
|
|
509
|
+
* const form = new MyForm();
|
|
510
|
+
* //...
|
|
511
|
+
* await form.getSelectedRows();
|
|
512
|
+
*/
|
|
513
|
+
async getSelectedRows() {
|
|
514
|
+
const rows = await this.getRows();
|
|
515
|
+
let result = [];
|
|
516
|
+
for (const row of rows) {
|
|
517
|
+
if (await row.isSelected()) {
|
|
518
|
+
}
|
|
519
|
+
result.push(row);
|
|
520
|
+
}
|
|
521
|
+
return result;
|
|
522
|
+
}
|
|
523
|
+
/**
|
|
524
|
+
* Вызывает контекстное меню в области с данными.
|
|
525
|
+
* @param fieldName - имя поля
|
|
526
|
+
* @param [rowIndex] - индекс строки. Если значение не передано, то по умолчанию контекстное меню будет вызвано на первой выделенной строке.
|
|
527
|
+
* @throws {Error} Если нет выделенных строк, то выбросит исключение.
|
|
528
|
+
* @example
|
|
529
|
+
* const form = new MyForm();
|
|
530
|
+
* //...
|
|
531
|
+
* await form.contextMenu('FieldName').clickButton('OpenFormButton');
|
|
532
|
+
* // or
|
|
533
|
+
* await form.contextMenu('FieldName', 3).clickButton(['Group', 'ButtonInGroup']);
|
|
534
|
+
*/
|
|
535
|
+
contextMenu(fieldName, rowIndex) {
|
|
536
|
+
return new ContextMenu(this.contextMenuCssSelector, this.formName, this.driver).setInit(async () => {
|
|
537
|
+
let row;
|
|
538
|
+
if (rowIndex != null) {
|
|
539
|
+
row = this.getRowByIndex(rowIndex);
|
|
540
|
+
} else {
|
|
541
|
+
[row] = await this.getSelectedRows();
|
|
542
|
+
}
|
|
543
|
+
if (!row)
|
|
544
|
+
throw new Error("No row available row for context menu");
|
|
545
|
+
const cellElement = await row.getCell(fieldName).getElement();
|
|
546
|
+
await contextMenu(cellElement, this.driver);
|
|
547
|
+
});
|
|
548
|
+
}
|
|
360
549
|
};
|
|
361
550
|
|
|
362
551
|
// src/pageObjects/elements/TableToolbar/ToolbarGroupButton.ts
|
|
@@ -384,76 +573,57 @@ var ToolbarButton = class extends AbstractButton {
|
|
|
384
573
|
}
|
|
385
574
|
};
|
|
386
575
|
|
|
387
|
-
// src/pageObjects/elements/
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
576
|
+
// src/pageObjects/elements/AbstractDropDownMenuButton.ts
|
|
577
|
+
var AbstractDropDownMenuButton = class extends AbstractElementWithParent {
|
|
578
|
+
_list;
|
|
579
|
+
constructor(parentCssSelector, elementCssSelector, list, driver) {
|
|
580
|
+
super(parentCssSelector, elementCssSelector, driver);
|
|
581
|
+
this._list = list;
|
|
582
|
+
}
|
|
583
|
+
async openDropdownMenu() {
|
|
584
|
+
const dropdown = await this.getElement();
|
|
585
|
+
await click(dropdown, this.driver);
|
|
586
|
+
await this._list.isVisible();
|
|
587
|
+
}
|
|
588
|
+
async clickButton(name) {
|
|
589
|
+
await this.openDropdownMenu();
|
|
590
|
+
await this._list.clickButton(name);
|
|
591
|
+
}
|
|
592
|
+
async clickButtonByTitle(title) {
|
|
593
|
+
await this.openDropdownMenu();
|
|
594
|
+
await this._list.clickButtonByTitle(title);
|
|
595
|
+
}
|
|
407
596
|
};
|
|
408
597
|
|
|
409
598
|
// src/pageObjects/elements/TableToolbar/ToolbarMenu.ts
|
|
410
599
|
var SPINDOWN_CLASS = ".dx-icon-spindown";
|
|
411
|
-
var CONTEXT_MENU_CLASS = "dx-context-menu";
|
|
412
600
|
var buttonGroupItemSelector = (formName, name) => byTestIdCssSelector(`ftb-${formName}-${name}`);
|
|
413
601
|
var getFullCssSelector = (formName, name) => `${buttonGroupItemSelector(formName, name)} ${SPINDOWN_CLASS}`;
|
|
414
|
-
var
|
|
415
|
-
var ToolbarMenu = class extends AbstractElementWithParent {
|
|
602
|
+
var ToolbarMenuList = class extends DXContextMenuList {
|
|
416
603
|
_formName;
|
|
417
|
-
constructor(parentCssSelector,
|
|
418
|
-
super(parentCssSelector,
|
|
604
|
+
constructor(parentCssSelector, elementCssSelector, formName, driver) {
|
|
605
|
+
super(parentCssSelector, elementCssSelector, driver);
|
|
419
606
|
this._formName = formName;
|
|
420
607
|
}
|
|
421
|
-
|
|
422
|
-
const dropdown = await this.getElement();
|
|
423
|
-
await click(dropdown, this.driver);
|
|
424
|
-
}
|
|
425
|
-
getCssSelectorToButton(name) {
|
|
608
|
+
getButtonNameBy(name) {
|
|
426
609
|
return byTestId(`ftb-${this._formName}-${name}`);
|
|
427
610
|
}
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
const
|
|
433
|
-
|
|
434
|
-
element: toolbarMenuItem,
|
|
435
|
-
errorMessage: this.buttonNotDisplayedError(name),
|
|
436
|
-
driver: this.driver
|
|
437
|
-
});
|
|
438
|
-
await click(toolbarMenuItem, this.driver);
|
|
611
|
+
};
|
|
612
|
+
var ToolbarMenu = class extends AbstractDropDownMenuButton {
|
|
613
|
+
constructor(parentCssSelector, formName, name, driver) {
|
|
614
|
+
const fullSelector = getFullCssSelector(formName, name);
|
|
615
|
+
const list = new ToolbarMenuList(parentCssSelector, ".toolbar-dropdown-context-menu", formName, driver);
|
|
616
|
+
super(parentCssSelector, fullSelector, list, driver);
|
|
439
617
|
}
|
|
440
618
|
async clickButton(name) {
|
|
441
|
-
await this.openDropdownMenu();
|
|
442
619
|
if (!isString(name) && !isArray(name))
|
|
443
620
|
throw new Error(`"name" must be a string or array of string`);
|
|
444
|
-
|
|
445
|
-
for (let n of lName) {
|
|
446
|
-
await this.goToButton(n, this.getCssSelectorToButton(n));
|
|
447
|
-
}
|
|
621
|
+
await super.clickButton(name);
|
|
448
622
|
}
|
|
449
623
|
async clickButtonByTitle(title) {
|
|
450
|
-
await this.openDropdownMenu();
|
|
451
624
|
if (!isString(title) && !isArray(title))
|
|
452
625
|
throw new Error(`"title" must be a string or array of string`);
|
|
453
|
-
|
|
454
|
-
for (let t of lTitle) {
|
|
455
|
-
await this.goToButton(t, By6.xpath(buttonByTextXpath(t)));
|
|
456
|
-
}
|
|
626
|
+
await super.clickButtonByTitle(title);
|
|
457
627
|
}
|
|
458
628
|
};
|
|
459
629
|
|
|
@@ -542,7 +712,7 @@ var FilterOperation = class extends AbstractElementWithParent {
|
|
|
542
712
|
}
|
|
543
713
|
async initOperationWidget() {
|
|
544
714
|
const widgetButtonEl = await this.getElement();
|
|
545
|
-
await
|
|
715
|
+
await waitElementIsClickable_default({
|
|
546
716
|
element: widgetButtonEl,
|
|
547
717
|
errorMessage: "Widget operation is not clickable",
|
|
548
718
|
driver: this.driver
|
|
@@ -1051,16 +1221,19 @@ var ColumnFilter = class extends AbstractElement {
|
|
|
1051
1221
|
var DATAGRID_HEADER_CSS_SELECTOR = ".dx-datagrid-headers .dx-datagrid-content:not(.dx-datagrid-content-fixed)";
|
|
1052
1222
|
var DATAGRID_CONTENT_CSS_SELECTOR = ".dx-datagrid-content:not(.dx-datagrid-content-fixed)";
|
|
1053
1223
|
var FIXED_DATAGRID_CONTENT_CSS_SELECTOR = ".dx-fixed-columns .dx-datagrid-content.dx-datagrid-content-fixed";
|
|
1224
|
+
var CONTEXT_MENU_CSS_SELECTOR = ".dx-datagrid";
|
|
1054
1225
|
var ListForm = class extends Form {
|
|
1055
1226
|
headerCssSelector;
|
|
1056
1227
|
fixedTableContentCssSelector;
|
|
1057
1228
|
tableContentCssSelector;
|
|
1229
|
+
contextMenuCssSelector;
|
|
1058
1230
|
constructor(driver) {
|
|
1059
1231
|
super(driver);
|
|
1060
1232
|
this.popupContainerCssSelector = `.popup.form-inline-${this.formName}`;
|
|
1061
1233
|
this.headerCssSelector = DATAGRID_HEADER_CSS_SELECTOR;
|
|
1062
1234
|
this.fixedTableContentCssSelector = FIXED_DATAGRID_CONTENT_CSS_SELECTOR;
|
|
1063
1235
|
this.tableContentCssSelector = DATAGRID_CONTENT_CSS_SELECTOR;
|
|
1236
|
+
this.contextMenuCssSelector = CONTEXT_MENU_CSS_SELECTOR;
|
|
1064
1237
|
}
|
|
1065
1238
|
/**
|
|
1066
1239
|
* Находит таблицу
|
|
@@ -1071,12 +1244,15 @@ var ListForm = class extends Form {
|
|
|
1071
1244
|
*/
|
|
1072
1245
|
table() {
|
|
1073
1246
|
return new Table(
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1247
|
+
{
|
|
1248
|
+
parentCssSelector: this.containerCssSelector,
|
|
1249
|
+
headerCssSelector: this.headerCssSelector,
|
|
1250
|
+
fixedTableContentCssSelector: this.fixedTableContentCssSelector,
|
|
1251
|
+
formName: this.formName,
|
|
1252
|
+
driver: this.driver,
|
|
1253
|
+
contextMenuCssSelector: this.contextMenuCssSelector,
|
|
1254
|
+
tableContentCssSelector: this.tableContentCssSelector
|
|
1255
|
+
}
|
|
1080
1256
|
);
|
|
1081
1257
|
}
|
|
1082
1258
|
/**
|