d5-testing-library 1.8.0-alpha.2 → 1.8.0-alpha.21
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-GTZISTTI.mjs +7 -0
- package/dist/ListForm-EM7E4ZMM.mjs +7 -0
- package/dist/TreeView-F2XF44N2.mjs +8 -0
- package/dist/chunk-LMFYREYI.mjs +22 -0
- package/dist/{chunk-ZT3B7BQ2.mjs → chunk-MV63JF3H.mjs} +261 -79
- package/dist/{chunk-LTHDA5XH.mjs → chunk-PMZQRKUZ.mjs} +363 -75
- package/dist/{chunk-H3M6VBPP.mjs → chunk-WDYVVF7O.mjs} +16 -7
- package/dist/cjs/d5-testing-library.cjs +786 -216
- package/dist/d5-testing-library.d.ts +188 -21
- package/dist/d5-testing-library.legacy-esm.js +29 -13
- package/dist/d5-testing-library.mjs +29 -13
- package/package.json +18 -6
- package/dist/FormEdit-PRX4TB67.mjs +0 -7
- package/dist/ListForm-N6QNZXQE.mjs +0 -7
- package/dist/TreeView-JOHAYS2S.mjs +0 -8
- package/dist/chunk-4PUDCQM6.mjs +0 -17
|
@@ -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-MV63JF3H.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";
|
|
@@ -65,7 +66,31 @@ var Cell = class extends AbstractElementWithParent {
|
|
|
65
66
|
for (const tag of tags) {
|
|
66
67
|
values.push(await tag.getAttribute("textContent"));
|
|
67
68
|
}
|
|
68
|
-
return values;
|
|
69
|
+
return values.length ? values : null;
|
|
70
|
+
}
|
|
71
|
+
async getNumberValue(cellEl) {
|
|
72
|
+
const value = (await cellEl.getText()).trim();
|
|
73
|
+
return value == "" ? null : Number.parseFloat(value);
|
|
74
|
+
}
|
|
75
|
+
async getDateValue(cellEl, cellElClass) {
|
|
76
|
+
const value = (await cellEl.getText()).trim();
|
|
77
|
+
if (value === "")
|
|
78
|
+
return null;
|
|
79
|
+
const isWithTime = cellElClass.includes("with-time");
|
|
80
|
+
try {
|
|
81
|
+
if (isWithTime) {
|
|
82
|
+
const [datePart, timePart] = value.split(", ");
|
|
83
|
+
const [day, month, year] = datePart.split(".").map(Number);
|
|
84
|
+
const [hours, minutes] = timePart.split(":").map(Number);
|
|
85
|
+
return new Date(Date.UTC(year, month - 1, day, hours, minutes));
|
|
86
|
+
} else {
|
|
87
|
+
const [day, month, year] = value.split(".").map(Number);
|
|
88
|
+
return new Date(Date.UTC(year, month - 1, day));
|
|
89
|
+
}
|
|
90
|
+
} catch (error) {
|
|
91
|
+
console.error(`Error parsing date value "${value}":`, error);
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
69
94
|
}
|
|
70
95
|
async getElement() {
|
|
71
96
|
if (this._index == null) {
|
|
@@ -80,7 +105,12 @@ var Cell = class extends AbstractElementWithParent {
|
|
|
80
105
|
return this.getBooleanValue(cellEl);
|
|
81
106
|
if (cellElClass.includes("tags-column" /* Tags */))
|
|
82
107
|
return this.getTagsValue(cellEl);
|
|
83
|
-
|
|
108
|
+
if (cellElClass.includes("number-column" /* Number */))
|
|
109
|
+
return this.getNumberValue(cellEl);
|
|
110
|
+
if (cellElClass.includes("date-column" /* Date */))
|
|
111
|
+
return this.getDateValue(cellEl, cellElClass);
|
|
112
|
+
const cellText = await cellEl.getText();
|
|
113
|
+
return cellText == "" ? null : cellText;
|
|
84
114
|
}
|
|
85
115
|
getIndex() {
|
|
86
116
|
return this._index;
|
|
@@ -94,10 +124,19 @@ var DX_DATA_ROW_CLASS = "dx-data-row";
|
|
|
94
124
|
var Row = class extends AbstractElementWithParent {
|
|
95
125
|
index;
|
|
96
126
|
getColumnBy;
|
|
97
|
-
|
|
127
|
+
fixedTableContentCssSelector;
|
|
128
|
+
/**
|
|
129
|
+
* @param parentCssSelector
|
|
130
|
+
* @param fixedTableContentCssSelector
|
|
131
|
+
* @param index починається з 0 (в getCssRowByIndexSelector додається +1)
|
|
132
|
+
* @param driver
|
|
133
|
+
* @param getColumnBy
|
|
134
|
+
*/
|
|
135
|
+
constructor(parentCssSelector, fixedTableContentCssSelector, index, driver, getColumnBy) {
|
|
98
136
|
super(parentCssSelector, getCssRowByIndexSelector(index), driver);
|
|
99
137
|
this.index = index;
|
|
100
138
|
this.getColumnBy = getColumnBy;
|
|
139
|
+
this.fixedTableContentCssSelector = fixedTableContentCssSelector;
|
|
101
140
|
}
|
|
102
141
|
_getCell({ index, name, title }) {
|
|
103
142
|
return new Cell(
|
|
@@ -147,12 +186,11 @@ var Row = class extends AbstractElementWithParent {
|
|
|
147
186
|
return result;
|
|
148
187
|
}
|
|
149
188
|
async clickInlineButton(buttonClass) {
|
|
150
|
-
const FIXED_TABLE_CSS_SELECTOR = ".dx-fixed-columns .dx-datagrid-content.dx-datagrid-content-fixed";
|
|
151
189
|
const buttonCssSelector = `.${DX_DATA_ROW_CLASS}[aria-rowindex="${transformInputIndex(
|
|
152
190
|
this.index
|
|
153
191
|
)}"] .${buttonClass}`;
|
|
154
192
|
const button = await fixElementStaleError(
|
|
155
|
-
By3.css(`${this.parentCssSelector} ${
|
|
193
|
+
By3.css(`${this.parentCssSelector} ${this.fixedTableContentCssSelector} ${buttonCssSelector}`),
|
|
156
194
|
this.driver
|
|
157
195
|
);
|
|
158
196
|
return click(button, this.driver);
|
|
@@ -235,14 +273,144 @@ var Column = class extends AbstractElementWithParent {
|
|
|
235
273
|
}
|
|
236
274
|
};
|
|
237
275
|
|
|
276
|
+
// src/utils/typesUtil.ts
|
|
277
|
+
import { isObject } from "selenium-webdriver/lib/util";
|
|
278
|
+
var types = {
|
|
279
|
+
"[object Array]": "array",
|
|
280
|
+
"[object Date]": "date",
|
|
281
|
+
"[object Object]": "object",
|
|
282
|
+
"[object String]": "string",
|
|
283
|
+
"[object Null]": "null"
|
|
284
|
+
};
|
|
285
|
+
var type = function(object) {
|
|
286
|
+
const typeOfObject = Object.prototype.toString.call(object);
|
|
287
|
+
return typeof object === "object" ? types[typeOfObject] || "object" : typeof object;
|
|
288
|
+
};
|
|
289
|
+
var isArray = function(value) {
|
|
290
|
+
return type(value) === "array";
|
|
291
|
+
};
|
|
292
|
+
var isString = function(object) {
|
|
293
|
+
return typeof object === "string";
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
// src/pageObjects/elements/AbstractDropDownMenuList.ts
|
|
297
|
+
var AbstractDropDownMenuList = class extends AbstractElementWithParent {
|
|
298
|
+
buttonNotDisplayedError(name) {
|
|
299
|
+
return `Menu button ${name} cannot be clicked. It is not displayed or it is disabled`;
|
|
300
|
+
}
|
|
301
|
+
async clickItemBy(errorMessage, by) {
|
|
302
|
+
await waitElementIsClickable_default({
|
|
303
|
+
errorMessage,
|
|
304
|
+
driver: this.driver,
|
|
305
|
+
by
|
|
306
|
+
});
|
|
307
|
+
const menuItemElement = await fixElementStaleError(by, this.driver);
|
|
308
|
+
await click(menuItemElement, this.driver);
|
|
309
|
+
}
|
|
310
|
+
async clickItemByPath(path, getBy) {
|
|
311
|
+
let pathList = isString(path) ? [path] : path;
|
|
312
|
+
for (let text of pathList) {
|
|
313
|
+
await this.clickItemBy(this.buttonNotDisplayedError(text), getBy(text));
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
clickButton(name) {
|
|
317
|
+
return this.clickItemByPath(name, this.getButtonNameBy.bind(this));
|
|
318
|
+
}
|
|
319
|
+
clickButtonByTitle(title) {
|
|
320
|
+
return this.clickItemByPath(title, this.getButtonTitleBy.bind(this));
|
|
321
|
+
}
|
|
322
|
+
isVisible() {
|
|
323
|
+
return Promise.resolve(true);
|
|
324
|
+
}
|
|
325
|
+
};
|
|
326
|
+
|
|
327
|
+
// src/pageObjects/elements/DXContextMenuList.ts
|
|
328
|
+
import { By as By5 } from "selenium-webdriver";
|
|
329
|
+
|
|
330
|
+
// src/utils/cssToXPath.ts
|
|
331
|
+
function cssClassesToXPath(classNames) {
|
|
332
|
+
const classNamesList = classNames.split(".").filter((className) => !!className);
|
|
333
|
+
const chained = classNamesList.map((className) => `contains(@class, "${className}")`).join(" and ");
|
|
334
|
+
return `[${chained}]`;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
// src/pageObjects/elements/DXContextMenuList.ts
|
|
338
|
+
var CONTEXT_MENU_CLASS = "dx-context-menu";
|
|
339
|
+
var CONTEXT_MENU_ITEM_TEXT_CLASS = "dx-menu-item-text";
|
|
340
|
+
var DXContextMenuList = class extends AbstractDropDownMenuList {
|
|
341
|
+
/**
|
|
342
|
+
* @param parentCssSelector
|
|
343
|
+
* @param classNames - Список класів. Починається з крапки
|
|
344
|
+
* @param driver
|
|
345
|
+
*/
|
|
346
|
+
constructor(parentCssSelector, classNames, driver) {
|
|
347
|
+
super(parentCssSelector, `.${CONTEXT_MENU_CLASS}${classNames}`, driver);
|
|
348
|
+
}
|
|
349
|
+
getButtonTitleBy(title) {
|
|
350
|
+
const buttonByTextXpath = (text) => `//span[contains(@class, "${CONTEXT_MENU_ITEM_TEXT_CLASS}") and contains(text(), "${text}")]`;
|
|
351
|
+
const xpath = "//div" + cssClassesToXPath(this.elementCssSelector) + buttonByTextXpath(title);
|
|
352
|
+
return By5.xpath(xpath);
|
|
353
|
+
}
|
|
354
|
+
async isVisible() {
|
|
355
|
+
try {
|
|
356
|
+
await waitElementIsVisible({
|
|
357
|
+
element: await this.driver.findElement(By5.css(`.dx-overlay-wrapper .dx-contextmenu`)),
|
|
358
|
+
driver: this.driver,
|
|
359
|
+
errorMessage: "Cannot find dropdown element"
|
|
360
|
+
});
|
|
361
|
+
} catch {
|
|
362
|
+
return false;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
};
|
|
366
|
+
|
|
367
|
+
// src/pageObjects/elements/Table/elements/ContextMenu.ts
|
|
368
|
+
var ContextMenu = class extends DXContextMenuList {
|
|
369
|
+
_formName;
|
|
370
|
+
_initFn;
|
|
371
|
+
constructor(cssClass, formName, driver) {
|
|
372
|
+
super("", cssClass, driver);
|
|
373
|
+
this._formName = formName;
|
|
374
|
+
}
|
|
375
|
+
setInit(cb) {
|
|
376
|
+
this._initFn = cb;
|
|
377
|
+
return this;
|
|
378
|
+
}
|
|
379
|
+
getButtonNameBy(name) {
|
|
380
|
+
return byTestId(`cm-${this._formName}-${name}`);
|
|
381
|
+
}
|
|
382
|
+
async clickButtonByTitle(title) {
|
|
383
|
+
await this._initFn?.();
|
|
384
|
+
await super.clickButtonByTitle(title);
|
|
385
|
+
}
|
|
386
|
+
async clickButton(name) {
|
|
387
|
+
await this._initFn?.();
|
|
388
|
+
await super.clickButton(name);
|
|
389
|
+
}
|
|
390
|
+
};
|
|
391
|
+
|
|
238
392
|
// src/pageObjects/elements/Table/Table.ts
|
|
239
393
|
var Table = class extends AbstractElementWithParent {
|
|
240
394
|
formName;
|
|
241
395
|
headerCssSelector;
|
|
242
|
-
|
|
396
|
+
contextMenuCssSelector;
|
|
397
|
+
fixedTableContentCssSelector;
|
|
398
|
+
tableContentCssSelector;
|
|
399
|
+
constructor({
|
|
400
|
+
parentCssSelector,
|
|
401
|
+
contextMenuCssSelector,
|
|
402
|
+
tableContentCssSelector,
|
|
403
|
+
headerCssSelector,
|
|
404
|
+
fixedTableContentCssSelector,
|
|
405
|
+
formName,
|
|
406
|
+
driver
|
|
407
|
+
}) {
|
|
243
408
|
super(parentCssSelector, `#${createTableId(formName)}`, driver);
|
|
244
409
|
this.formName = formName;
|
|
245
410
|
this.headerCssSelector = headerCssSelector;
|
|
411
|
+
this.contextMenuCssSelector = contextMenuCssSelector;
|
|
412
|
+
this.fixedTableContentCssSelector = fixedTableContentCssSelector;
|
|
413
|
+
this.tableContentCssSelector = tableContentCssSelector;
|
|
246
414
|
}
|
|
247
415
|
getColumnBy = (args) => {
|
|
248
416
|
if (args.title) {
|
|
@@ -250,10 +418,18 @@ var Table = class extends AbstractElementWithParent {
|
|
|
250
418
|
}
|
|
251
419
|
return this.getColumnByName(args.name);
|
|
252
420
|
};
|
|
421
|
+
/**
|
|
422
|
+
* Отримати рядок по індексу.
|
|
423
|
+
* @param index починається з 0
|
|
424
|
+
*/
|
|
253
425
|
getRowByIndex(index) {
|
|
254
|
-
return new Row(this.getFullCssSelector(), index, this.driver, this.getColumnBy);
|
|
426
|
+
return new Row(this.getFullCssSelector(), this.fixedTableContentCssSelector, index, this.driver, this.getColumnBy);
|
|
255
427
|
}
|
|
428
|
+
/**
|
|
429
|
+
* @param index починається з 0
|
|
430
|
+
*/
|
|
256
431
|
getColumnByIndex(index) {
|
|
432
|
+
this.getRowByIndex(index);
|
|
257
433
|
return new Column({
|
|
258
434
|
parentCssSelector: this.getFullCssSelector(),
|
|
259
435
|
driver: this.driver,
|
|
@@ -276,21 +452,32 @@ var Table = class extends AbstractElementWithParent {
|
|
|
276
452
|
driver: this.driver
|
|
277
453
|
});
|
|
278
454
|
};
|
|
455
|
+
/**
|
|
456
|
+
* Вибрати рядок по індексу.
|
|
457
|
+
* @param index починається з 0
|
|
458
|
+
*/
|
|
279
459
|
selectRowByIndex(index) {
|
|
280
460
|
return this.getRowByIndex(index).select();
|
|
281
461
|
}
|
|
282
462
|
async getRows() {
|
|
283
|
-
const
|
|
463
|
+
const rowsFullCssSelector = `${this.getFullCssSelector()} ${this.tableContentCssSelector} .dx-row.dx-data-row`;
|
|
464
|
+
const rows = await this.driver.findElements(By6.css(rowsFullCssSelector));
|
|
284
465
|
const result = [];
|
|
285
466
|
rows.forEach((_, index) => {
|
|
286
|
-
const newRow = new Row(
|
|
467
|
+
const newRow = new Row(
|
|
468
|
+
this.getFullCssSelector(),
|
|
469
|
+
this.fixedTableContentCssSelector,
|
|
470
|
+
index,
|
|
471
|
+
this.driver,
|
|
472
|
+
this.getColumnBy
|
|
473
|
+
);
|
|
287
474
|
result.push(newRow);
|
|
288
475
|
});
|
|
289
476
|
return result;
|
|
290
477
|
}
|
|
291
478
|
async getColumns() {
|
|
292
479
|
const columns = await this.driver.findElements(
|
|
293
|
-
|
|
480
|
+
By6.css(`${this.getFullCssSelector()} ${this.headerCssSelector} td[role="columnheader"] .header-template-text`)
|
|
294
481
|
);
|
|
295
482
|
const result = [];
|
|
296
483
|
columns.forEach((_, index) => {
|
|
@@ -316,6 +503,50 @@ var Table = class extends AbstractElementWithParent {
|
|
|
316
503
|
field(name) {
|
|
317
504
|
return new FormField(this.getFullCssSelector(), this.formName, name, this.driver);
|
|
318
505
|
}
|
|
506
|
+
/**
|
|
507
|
+
* Возвращает список строк которые выделены
|
|
508
|
+
* @returns Row[]
|
|
509
|
+
* @example
|
|
510
|
+
* const form = new MyForm();
|
|
511
|
+
* //...
|
|
512
|
+
* await form.getSelectedRows();
|
|
513
|
+
*/
|
|
514
|
+
async getSelectedRows() {
|
|
515
|
+
const rows = await this.getRows();
|
|
516
|
+
let result = [];
|
|
517
|
+
for (const row of rows) {
|
|
518
|
+
if (await row.isSelected()) {
|
|
519
|
+
}
|
|
520
|
+
result.push(row);
|
|
521
|
+
}
|
|
522
|
+
return result;
|
|
523
|
+
}
|
|
524
|
+
/**
|
|
525
|
+
* Вызывает контекстное меню в области с данными.
|
|
526
|
+
* @param fieldName - имя поля
|
|
527
|
+
* @param [rowIndex] - индекс строки. Если значение не передано, то по умолчанию контекстное меню будет вызвано на первой выделенной строке.
|
|
528
|
+
* @throws {Error} Если нет выделенных строк, то выбросит исключение.
|
|
529
|
+
* @example
|
|
530
|
+
* const form = new MyForm();
|
|
531
|
+
* //...
|
|
532
|
+
* await form.contextMenu('FieldName').clickButton('OpenFormButton');
|
|
533
|
+
* // or
|
|
534
|
+
* await form.contextMenu('FieldName', 3).clickButton(['Group', 'ButtonInGroup']);
|
|
535
|
+
*/
|
|
536
|
+
contextMenu(fieldName, rowIndex) {
|
|
537
|
+
return new ContextMenu(this.contextMenuCssSelector, this.formName, this.driver).setInit(async () => {
|
|
538
|
+
let row;
|
|
539
|
+
if (rowIndex != null) {
|
|
540
|
+
row = this.getRowByIndex(rowIndex);
|
|
541
|
+
} else {
|
|
542
|
+
[row] = await this.getSelectedRows();
|
|
543
|
+
}
|
|
544
|
+
if (!row)
|
|
545
|
+
throw new Error("No row available row for context menu");
|
|
546
|
+
const cellElement = await row.getCell(fieldName).getElement();
|
|
547
|
+
await contextMenu(cellElement, this.driver);
|
|
548
|
+
});
|
|
549
|
+
}
|
|
319
550
|
};
|
|
320
551
|
|
|
321
552
|
// src/pageObjects/elements/TableToolbar/ToolbarGroupButton.ts
|
|
@@ -343,75 +574,57 @@ var ToolbarButton = class extends AbstractButton {
|
|
|
343
574
|
}
|
|
344
575
|
};
|
|
345
576
|
|
|
346
|
-
// src/pageObjects/elements/
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
577
|
+
// src/pageObjects/elements/AbstractDropDownMenuButton.ts
|
|
578
|
+
var AbstractDropDownMenuButton = class extends AbstractElementWithParent {
|
|
579
|
+
_list;
|
|
580
|
+
constructor(parentCssSelector, elementCssSelector, list, driver) {
|
|
581
|
+
super(parentCssSelector, elementCssSelector, driver);
|
|
582
|
+
this._list = list;
|
|
583
|
+
}
|
|
584
|
+
async openDropdownMenu() {
|
|
585
|
+
const dropdown = await this.getElement();
|
|
586
|
+
await click(dropdown, this.driver);
|
|
587
|
+
await this._list.isVisible();
|
|
588
|
+
}
|
|
589
|
+
async clickButton(name) {
|
|
590
|
+
await this.openDropdownMenu();
|
|
591
|
+
await this._list.clickButton(name);
|
|
592
|
+
}
|
|
593
|
+
async clickButtonByTitle(title) {
|
|
594
|
+
await this.openDropdownMenu();
|
|
595
|
+
await this._list.clickButtonByTitle(title);
|
|
596
|
+
}
|
|
366
597
|
};
|
|
367
598
|
|
|
368
599
|
// src/pageObjects/elements/TableToolbar/ToolbarMenu.ts
|
|
369
600
|
var SPINDOWN_CLASS = ".dx-icon-spindown";
|
|
370
601
|
var buttonGroupItemSelector = (formName, name) => byTestIdCssSelector(`ftb-${formName}-${name}`);
|
|
371
602
|
var getFullCssSelector = (formName, name) => `${buttonGroupItemSelector(formName, name)} ${SPINDOWN_CLASS}`;
|
|
372
|
-
var
|
|
373
|
-
var ToolbarMenu = class extends AbstractElementWithParent {
|
|
603
|
+
var ToolbarMenuList = class extends DXContextMenuList {
|
|
374
604
|
_formName;
|
|
375
|
-
constructor(parentCssSelector,
|
|
376
|
-
super(parentCssSelector,
|
|
605
|
+
constructor(parentCssSelector, elementCssSelector, formName, driver) {
|
|
606
|
+
super(parentCssSelector, elementCssSelector, driver);
|
|
377
607
|
this._formName = formName;
|
|
378
608
|
}
|
|
379
|
-
|
|
380
|
-
const dropdown = await this.getElement();
|
|
381
|
-
await click(dropdown, this.driver);
|
|
382
|
-
}
|
|
383
|
-
getCssSelectorToButton(name) {
|
|
609
|
+
getButtonNameBy(name) {
|
|
384
610
|
return byTestId(`ftb-${this._formName}-${name}`);
|
|
385
611
|
}
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
const
|
|
391
|
-
|
|
392
|
-
element: toolbarMenuItem,
|
|
393
|
-
errorMessage: this.buttonNotDisplayedError(name),
|
|
394
|
-
driver: this.driver
|
|
395
|
-
});
|
|
396
|
-
await click(toolbarMenuItem, this.driver);
|
|
612
|
+
};
|
|
613
|
+
var ToolbarMenu = class extends AbstractDropDownMenuButton {
|
|
614
|
+
constructor(parentCssSelector, formName, name, driver) {
|
|
615
|
+
const fullSelector = getFullCssSelector(formName, name);
|
|
616
|
+
const list = new ToolbarMenuList(parentCssSelector, ".toolbar-dropdown-context-menu", formName, driver);
|
|
617
|
+
super(parentCssSelector, fullSelector, list, driver);
|
|
397
618
|
}
|
|
398
619
|
async clickButton(name) {
|
|
399
|
-
await this.openDropdownMenu();
|
|
400
620
|
if (!isString(name) && !isArray(name))
|
|
401
621
|
throw new Error(`"name" must be a string or array of string`);
|
|
402
|
-
|
|
403
|
-
for (let n of lName) {
|
|
404
|
-
await this.goToButton(n, this.getCssSelectorToButton(n));
|
|
405
|
-
}
|
|
622
|
+
await super.clickButton(name);
|
|
406
623
|
}
|
|
407
624
|
async clickButtonByTitle(title) {
|
|
408
|
-
await this.openDropdownMenu();
|
|
409
625
|
if (!isString(title) && !isArray(title))
|
|
410
626
|
throw new Error(`"title" must be a string or array of string`);
|
|
411
|
-
|
|
412
|
-
for (let t of lTitle) {
|
|
413
|
-
await this.goToButton(t, By6.xpath(buttonByTextXpath(t)));
|
|
414
|
-
}
|
|
627
|
+
await super.clickButtonByTitle(title);
|
|
415
628
|
}
|
|
416
629
|
};
|
|
417
630
|
|
|
@@ -445,6 +658,14 @@ var ToolbarItem = class extends AbstractElementWithParent {
|
|
|
445
658
|
await this.init();
|
|
446
659
|
return await this._button.isDisabled();
|
|
447
660
|
}
|
|
661
|
+
async isDisplayed() {
|
|
662
|
+
try {
|
|
663
|
+
await this.init();
|
|
664
|
+
return this._button.isDisplayed();
|
|
665
|
+
} catch (error) {
|
|
666
|
+
return false;
|
|
667
|
+
}
|
|
668
|
+
}
|
|
448
669
|
get menu() {
|
|
449
670
|
return new ToolbarMenu(this.parentCssSelector, this._formName, this._itemName, this.driver);
|
|
450
671
|
}
|
|
@@ -492,7 +713,7 @@ var FilterOperation = class extends AbstractElementWithParent {
|
|
|
492
713
|
}
|
|
493
714
|
async initOperationWidget() {
|
|
494
715
|
const widgetButtonEl = await this.getElement();
|
|
495
|
-
await
|
|
716
|
+
await waitElementIsClickable_default({
|
|
496
717
|
element: widgetButtonEl,
|
|
497
718
|
errorMessage: "Widget operation is not clickable",
|
|
498
719
|
driver: this.driver
|
|
@@ -577,8 +798,15 @@ var FormFilterField = class extends AbstractEditor {
|
|
|
577
798
|
* @example
|
|
578
799
|
* await form.formFilter('NumberFld').setValue(123);
|
|
579
800
|
* await form.formFilter('TextFld').setValue('TestValue');
|
|
801
|
+
* await form.formFilter('TextFld').setValue('TestValue', '=', true);
|
|
580
802
|
*/
|
|
581
|
-
async setValue(value) {
|
|
803
|
+
async setValue(value, operation, isBlank) {
|
|
804
|
+
if (typeof operation === "string") {
|
|
805
|
+
await this.setOperation(operation);
|
|
806
|
+
}
|
|
807
|
+
if (typeof isBlank === "boolean") {
|
|
808
|
+
await this.setIsBlank(isBlank);
|
|
809
|
+
}
|
|
582
810
|
return super.setValue(value);
|
|
583
811
|
}
|
|
584
812
|
/**
|
|
@@ -670,8 +898,15 @@ var PanelFilterField = class extends AbstractEditor {
|
|
|
670
898
|
* @example
|
|
671
899
|
* await form.filterPanel.filterField('NumberFld').setValue(123);
|
|
672
900
|
* await form.filterPanel.filterField('TextFld').setValue('TestValue');
|
|
901
|
+
* await form.filterPanel.filterField('TextFld').setValue('TestValue', '=', true);
|
|
673
902
|
*/
|
|
674
|
-
async setValue(value) {
|
|
903
|
+
async setValue(value, operation, isBlank) {
|
|
904
|
+
if (typeof operation === "string") {
|
|
905
|
+
await this.setOperation(operation);
|
|
906
|
+
}
|
|
907
|
+
if (typeof isBlank === "boolean") {
|
|
908
|
+
await this.setIsBlank(isBlank);
|
|
909
|
+
}
|
|
675
910
|
return super.setValue(value);
|
|
676
911
|
}
|
|
677
912
|
/**
|
|
@@ -892,9 +1127,23 @@ var ColumnFilter = class extends AbstractElement {
|
|
|
892
1127
|
* @example
|
|
893
1128
|
* await form.columnFilter('NumberFld').setValue(123);
|
|
894
1129
|
* await form.columnFilter('TextFld').setValue('TestValue');
|
|
1130
|
+
* await form.columnFilter('TextFld').setValue('TestValue', '=', true);
|
|
895
1131
|
*/
|
|
896
|
-
async setValue(value) {
|
|
1132
|
+
async setValue(value, operation, isBlank) {
|
|
897
1133
|
const filter = await this.initFilter();
|
|
1134
|
+
const filterOperation = new FilterOperation({
|
|
1135
|
+
parentCssSelector: HEADER_FILTER_CONTAINER,
|
|
1136
|
+
filterTestID: createHeaderFilterTestId(this._formName, this._name)
|
|
1137
|
+
});
|
|
1138
|
+
const inputEl = await filter.getElement();
|
|
1139
|
+
if (typeof operation === "string") {
|
|
1140
|
+
await inputEl.click();
|
|
1141
|
+
await filterOperation.setOperation(operation);
|
|
1142
|
+
}
|
|
1143
|
+
if (typeof isBlank === "boolean") {
|
|
1144
|
+
await inputEl.click();
|
|
1145
|
+
await filterOperation.setIsBlank(isBlank);
|
|
1146
|
+
}
|
|
898
1147
|
await filter.setValue(value);
|
|
899
1148
|
return this.apply();
|
|
900
1149
|
}
|
|
@@ -918,32 +1167,52 @@ var ColumnFilter = class extends AbstractElement {
|
|
|
918
1167
|
await filter.remove(itemText);
|
|
919
1168
|
return this.apply();
|
|
920
1169
|
}
|
|
921
|
-
|
|
1170
|
+
/**
|
|
1171
|
+
* Инициализация операции фильтра
|
|
1172
|
+
*/
|
|
922
1173
|
async initOperation() {
|
|
923
|
-
await this.initFilter();
|
|
1174
|
+
const filter = await this.initFilter();
|
|
1175
|
+
const inputEl = await filter.getElement();
|
|
1176
|
+
await inputEl.click();
|
|
924
1177
|
return new FilterOperation({
|
|
925
1178
|
parentCssSelector: HEADER_FILTER_CONTAINER,
|
|
926
1179
|
filterTestID: createHeaderFilterTestId(this._formName, this._name)
|
|
927
1180
|
});
|
|
928
1181
|
}
|
|
929
|
-
|
|
1182
|
+
/**
|
|
1183
|
+
* Устанавливает операцию для фильтра
|
|
1184
|
+
* @example
|
|
1185
|
+
* await form.columnFilter('TagBox').setOperation("=");
|
|
1186
|
+
*/
|
|
930
1187
|
async setOperation(operationName) {
|
|
931
1188
|
const filterOperation = await this.initOperation();
|
|
932
1189
|
await filterOperation.setOperation(operationName);
|
|
933
1190
|
await this.apply();
|
|
934
1191
|
}
|
|
935
|
-
|
|
1192
|
+
/**
|
|
1193
|
+
* Возвращает операцию фильтра
|
|
1194
|
+
* @example
|
|
1195
|
+
* expect(await form.columnFilter('NumberFld').getOperation()).toBe("=");
|
|
1196
|
+
*/
|
|
936
1197
|
async getOperation() {
|
|
937
1198
|
const filterOperation = await this.initOperation();
|
|
938
1199
|
return await filterOperation.getOperation();
|
|
939
1200
|
}
|
|
940
|
-
|
|
1201
|
+
/**
|
|
1202
|
+
* Устанавливает операцию 'isblank' для фильтра
|
|
1203
|
+
* @example
|
|
1204
|
+
* await form.columnFilter('TagBox').setIsBlank(true);
|
|
1205
|
+
*/
|
|
941
1206
|
async setIsBlank(value) {
|
|
942
1207
|
const filterOperation = await this.initOperation();
|
|
943
1208
|
await filterOperation.setIsBlank(value);
|
|
944
1209
|
await this.apply();
|
|
945
1210
|
}
|
|
946
|
-
|
|
1211
|
+
/**
|
|
1212
|
+
* Возвращает true|false, если операция 'isblank' установлена для фильтра
|
|
1213
|
+
* @example
|
|
1214
|
+
* expect(await form.columnFilter('NumberFld').getIsBlank()).toBe(false);
|
|
1215
|
+
*/
|
|
947
1216
|
async getIsBlank() {
|
|
948
1217
|
const filterOperation = await this.initOperation();
|
|
949
1218
|
return await filterOperation.getIsBlank();
|
|
@@ -952,12 +1221,21 @@ var ColumnFilter = class extends AbstractElement {
|
|
|
952
1221
|
|
|
953
1222
|
// src/pageObjects/elements/Forms/ListForm.ts
|
|
954
1223
|
var DATAGRID_HEADER_CSS_SELECTOR = ".dx-datagrid-headers .dx-datagrid-content:not(.dx-datagrid-content-fixed)";
|
|
1224
|
+
var DATAGRID_CONTENT_CSS_SELECTOR = ".dx-datagrid-content:not(.dx-datagrid-content-fixed)";
|
|
1225
|
+
var FIXED_DATAGRID_CONTENT_CSS_SELECTOR = ".dx-fixed-columns .dx-datagrid-content.dx-datagrid-content-fixed";
|
|
1226
|
+
var CONTEXT_MENU_CSS_SELECTOR = ".dx-datagrid";
|
|
955
1227
|
var ListForm = class extends Form {
|
|
956
1228
|
headerCssSelector;
|
|
1229
|
+
fixedTableContentCssSelector;
|
|
1230
|
+
tableContentCssSelector;
|
|
1231
|
+
contextMenuCssSelector;
|
|
957
1232
|
constructor(driver) {
|
|
958
1233
|
super(driver);
|
|
959
|
-
this.popupContainerCssSelector = `.popup
|
|
1234
|
+
this.popupContainerCssSelector = `.popup.form-inline-${this.formName}`;
|
|
960
1235
|
this.headerCssSelector = DATAGRID_HEADER_CSS_SELECTOR;
|
|
1236
|
+
this.fixedTableContentCssSelector = FIXED_DATAGRID_CONTENT_CSS_SELECTOR;
|
|
1237
|
+
this.tableContentCssSelector = DATAGRID_CONTENT_CSS_SELECTOR;
|
|
1238
|
+
this.contextMenuCssSelector = CONTEXT_MENU_CSS_SELECTOR;
|
|
961
1239
|
}
|
|
962
1240
|
/**
|
|
963
1241
|
* Находит таблицу
|
|
@@ -967,7 +1245,17 @@ var ListForm = class extends Form {
|
|
|
967
1245
|
* expect(listForm.table());
|
|
968
1246
|
*/
|
|
969
1247
|
table() {
|
|
970
|
-
return new Table(
|
|
1248
|
+
return new Table(
|
|
1249
|
+
{
|
|
1250
|
+
parentCssSelector: this.containerCssSelector,
|
|
1251
|
+
headerCssSelector: this.headerCssSelector,
|
|
1252
|
+
fixedTableContentCssSelector: this.fixedTableContentCssSelector,
|
|
1253
|
+
formName: this.formName,
|
|
1254
|
+
driver: this.driver,
|
|
1255
|
+
contextMenuCssSelector: this.contextMenuCssSelector,
|
|
1256
|
+
tableContentCssSelector: this.tableContentCssSelector
|
|
1257
|
+
}
|
|
1258
|
+
);
|
|
971
1259
|
}
|
|
972
1260
|
/**
|
|
973
1261
|
* Находит таблицу
|