d5-testing-library 1.8.0-alpha.13 → 1.8.0-alpha.16

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.
@@ -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
- waitElementIsClickable,
18
+ waitElementIsClickable_default,
18
19
  waitElementIsVisible
19
- } from "./chunk-D7226XWY.mjs";
20
+ } from "./chunk-27K3WKCG.mjs";
20
21
 
21
22
  // src/pageObjects/elements/Table/Table.ts
22
- import { By as By5 } from "selenium-webdriver";
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(parentCssSelector, headerCssSelector, tableContentCssSelector, fixedTableContentCssSelector, formName, driver) {
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(By5.css(rowsFullCssSelector));
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
- By5.css(`${this.getFullCssSelector()} ${this.headerCssSelector} td[role="columnheader"] .header-template-text`)
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,88 +573,57 @@ var ToolbarButton = class extends AbstractButton {
384
573
  }
385
574
  };
386
575
 
387
- // src/pageObjects/elements/TableToolbar/ToolbarMenu.ts
388
- import { By as By6 } from "selenium-webdriver";
389
-
390
- // src/utils/typesUtil.ts
391
- var types = {
392
- "[object Array]": "array",
393
- "[object Date]": "date",
394
- "[object Object]": "object",
395
- "[object String]": "string",
396
- "[object Null]": "null"
397
- };
398
- var type = function(object) {
399
- const typeOfObject = Object.prototype.toString.call(object);
400
- return typeof object === "object" ? types[typeOfObject] || "object" : typeof object;
401
- };
402
- var isArray = function(value) {
403
- return type(value) === "array";
404
- };
405
- var isString = function(object) {
406
- return typeof object === "string";
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 buttonByTextXpath = (text) => `//div[contains(@class, '${CONTEXT_MENU_CLASS}')]//span[contains(@class, 'dx-menu-item-text') and text()='${text}']`;
415
- var ToolbarMenu = class extends AbstractElementWithParent {
602
+ var ToolbarMenuList = class extends DXContextMenuList {
416
603
  _formName;
417
- constructor(parentCssSelector, formName, name, driver) {
418
- super(parentCssSelector, getFullCssSelector(formName, name), driver);
604
+ constructor(parentCssSelector, elementCssSelector, formName, driver) {
605
+ super(parentCssSelector, elementCssSelector, driver);
419
606
  this._formName = formName;
420
607
  }
421
- async openDropdownMenu() {
422
- await wait(
423
- async () => {
424
- const dropdown = await this.getElement();
425
- await click(dropdown, this.driver);
426
- try {
427
- const contextMenu = this.driver.findElement(By6.css(`.dx-overlay-wrapper .${CONTEXT_MENU_CLASS}`));
428
- return await contextMenu.isDisplayed() && await contextMenu.isEnabled();
429
- } catch (_) {
430
- return false;
431
- }
432
- },
433
- this.driver,
434
- `Cannot find dropdown element`
435
- );
436
- }
437
- getCssSelectorToButton(name) {
608
+ getButtonNameBy(name) {
438
609
  return byTestId(`ftb-${this._formName}-${name}`);
439
610
  }
440
- buttonNotDisplayedError(name) {
441
- return `Toolbar menu button ${name} cannot be clicked. It is not displayed or it is disabled`;
442
- }
443
- async goToButton(name, by) {
444
- const toolbarMenuItem = await fixElementStaleError(by, this.driver);
445
- await waitElementIsClickable({
446
- element: toolbarMenuItem,
447
- errorMessage: this.buttonNotDisplayedError(name),
448
- driver: this.driver
449
- });
450
- 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);
451
617
  }
452
618
  async clickButton(name) {
453
- await this.openDropdownMenu();
454
619
  if (!isString(name) && !isArray(name))
455
620
  throw new Error(`"name" must be a string or array of string`);
456
- let lName = isString(name) ? [name] : name;
457
- for (let n of lName) {
458
- await this.goToButton(n, this.getCssSelectorToButton(n));
459
- }
621
+ await super.clickButton(name);
460
622
  }
461
623
  async clickButtonByTitle(title) {
462
- await this.openDropdownMenu();
463
624
  if (!isString(title) && !isArray(title))
464
625
  throw new Error(`"title" must be a string or array of string`);
465
- let lTitle = isString(title) ? [title] : title;
466
- for (let t of lTitle) {
467
- await this.goToButton(t, By6.xpath(buttonByTextXpath(t)));
468
- }
626
+ await super.clickButtonByTitle(title);
469
627
  }
470
628
  };
471
629
 
@@ -554,7 +712,7 @@ var FilterOperation = class extends AbstractElementWithParent {
554
712
  }
555
713
  async initOperationWidget() {
556
714
  const widgetButtonEl = await this.getElement();
557
- await waitElementIsClickable({
715
+ await waitElementIsClickable_default({
558
716
  element: widgetButtonEl,
559
717
  errorMessage: "Widget operation is not clickable",
560
718
  driver: this.driver
@@ -1063,16 +1221,19 @@ var ColumnFilter = class extends AbstractElement {
1063
1221
  var DATAGRID_HEADER_CSS_SELECTOR = ".dx-datagrid-headers .dx-datagrid-content:not(.dx-datagrid-content-fixed)";
1064
1222
  var DATAGRID_CONTENT_CSS_SELECTOR = ".dx-datagrid-content:not(.dx-datagrid-content-fixed)";
1065
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";
1066
1225
  var ListForm = class extends Form {
1067
1226
  headerCssSelector;
1068
1227
  fixedTableContentCssSelector;
1069
1228
  tableContentCssSelector;
1229
+ contextMenuCssSelector;
1070
1230
  constructor(driver) {
1071
1231
  super(driver);
1072
1232
  this.popupContainerCssSelector = `.popup.form-inline-${this.formName}`;
1073
1233
  this.headerCssSelector = DATAGRID_HEADER_CSS_SELECTOR;
1074
1234
  this.fixedTableContentCssSelector = FIXED_DATAGRID_CONTENT_CSS_SELECTOR;
1075
1235
  this.tableContentCssSelector = DATAGRID_CONTENT_CSS_SELECTOR;
1236
+ this.contextMenuCssSelector = CONTEXT_MENU_CSS_SELECTOR;
1076
1237
  }
1077
1238
  /**
1078
1239
  * Находит таблицу
@@ -1083,12 +1244,15 @@ var ListForm = class extends Form {
1083
1244
  */
1084
1245
  table() {
1085
1246
  return new Table(
1086
- this.containerCssSelector,
1087
- this.headerCssSelector,
1088
- this.tableContentCssSelector,
1089
- this.fixedTableContentCssSelector,
1090
- this.formName,
1091
- this.driver
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
+ }
1092
1256
  );
1093
1257
  }
1094
1258
  /**
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  ListForm
3
- } from "./chunk-YSGDK2Y2.mjs";
3
+ } from "./chunk-GUBPWJAU.mjs";
4
4
 
5
5
  // src/pageObjects/elements/Forms/TreeView.ts
6
6
  var TREELIST_HEADER_CSS_SELECTOR = ".dx-treelist-headers .dx-treelist-content:not(.dx-datagrid-content-fixed)";
@@ -9,9 +9,10 @@ var FIXED_TREELIST_CONTENT_CSS_SELECTOR = ".dx-fixed-columns .dx-treelist-conten
9
9
  var TreeView = class extends ListForm {
10
10
  constructor(driver) {
11
11
  super(driver);
12
- this.popupContainerCssSelector = `.popup.wrapper-tree-view-${this.formName}`;
12
+ this.popupContainerCssSelector = `.popup.tree-view-${this.formName}`;
13
13
  this.headerCssSelector = TREELIST_HEADER_CSS_SELECTOR;
14
14
  this.fixedTableContentCssSelector = FIXED_TREELIST_CONTENT_CSS_SELECTOR;
15
+ this.contextMenuCssSelector = ".dx-treelist-container";
15
16
  this.tableContentCssSelector = TREELIST_CONTENT_CSS_SELECTOR;
16
17
  }
17
18
  };
@@ -3,7 +3,7 @@ import {
3
3
  FormField,
4
4
  click,
5
5
  wait
6
- } from "./chunk-D7226XWY.mjs";
6
+ } from "./chunk-27K3WKCG.mjs";
7
7
 
8
8
  // src/pageObjects/elements/Forms/FormEdit.ts
9
9
  import { By } from "selenium-webdriver";