d5-testing-library 2.0.0-alpha.1 → 2.0.0-alpha.10
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/README.md +1 -1
- package/dist/{FormEdit-I63LWQEH.mjs → FormEdit-QX5S7TDU.mjs} +1 -1
- package/dist/{ListForm-NEBCZD4X.mjs → ListForm-4DCCOHKJ.mjs} +1 -1
- package/dist/{TreeView-T3PIDSZQ.mjs → TreeView-RDCA3LGU.mjs} +1 -1
- package/dist/{chunk-75NROWLM.mjs → chunk-GSTA5R4B.mjs} +233 -43
- package/dist/cjs/d5-testing-library.cjs +248 -42
- package/dist/cjs/d5-testing-library.d.ts +33 -10
- package/dist/d5-testing-library.d.mts +33 -10
- package/dist/d5-testing-library.legacy-esm.js +1 -1
- package/dist/d5-testing-library.mjs +1 -1
- package/package.json +2 -16
package/README.md
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
//.
|
|
@@ -2859,11 +2859,14 @@ var AbstractElement = class {
|
|
|
2859
2859
|
joinRelativeCssSelectors(selectors) {
|
|
2860
2860
|
return selectors.join(" ");
|
|
2861
2861
|
}
|
|
2862
|
-
|
|
2862
|
+
syncLocator() {
|
|
2863
2863
|
return this.page.locator(`css=${this.getFullCssSelector()}`);
|
|
2864
2864
|
}
|
|
2865
|
+
getLocator() {
|
|
2866
|
+
return this.syncLocator();
|
|
2867
|
+
}
|
|
2865
2868
|
async getAttribute(attr) {
|
|
2866
|
-
const locator = this.
|
|
2869
|
+
const locator = this.syncLocator();
|
|
2867
2870
|
if (await locator.isVisible()) {
|
|
2868
2871
|
return locator.getAttribute(attr);
|
|
2869
2872
|
}
|
|
@@ -2941,6 +2944,15 @@ function createSubSystemTestId(itemName) {
|
|
|
2941
2944
|
function createEditorButtonTestId(itemName) {
|
|
2942
2945
|
return `${"editor-button" /* EDITOR_BUTTON */}-${itemName}`;
|
|
2943
2946
|
}
|
|
2947
|
+
function createLabelFieldTestId(formName, itemName) {
|
|
2948
|
+
return `${"label" /* LABEL */}-${createFieldTestId(formName, itemName)}`;
|
|
2949
|
+
}
|
|
2950
|
+
function createLabelDocFilterTestId(formName, itemName) {
|
|
2951
|
+
return `${"label" /* LABEL */}-${createDocFilterTestId(formName, itemName)}`;
|
|
2952
|
+
}
|
|
2953
|
+
function createLabelLayoutFilterTestId(formName, itemName) {
|
|
2954
|
+
return `${"label" /* LABEL */}-${createLayoutFilterTestId(formName, itemName)}`;
|
|
2955
|
+
}
|
|
2944
2956
|
|
|
2945
2957
|
// src/pageObjects/AbstractElementWithParent.ts
|
|
2946
2958
|
var AbstractElementWithParent = class extends AbstractElement {
|
|
@@ -3263,7 +3275,7 @@ var AbstractForm = class extends AbstractPage {
|
|
|
3263
3275
|
async exists() {
|
|
3264
3276
|
try {
|
|
3265
3277
|
const container = this.page.locator(this.containerCssSelector);
|
|
3266
|
-
await waitElementIsVisible_default({ locator: container });
|
|
3278
|
+
await waitElementIsVisible_default({ locator: container, timeout: 3e3 });
|
|
3267
3279
|
return true;
|
|
3268
3280
|
} catch (error) {
|
|
3269
3281
|
return false;
|
|
@@ -3308,15 +3320,15 @@ async function classDependencyInjector(formType) {
|
|
|
3308
3320
|
let SubFormFactoryClass;
|
|
3309
3321
|
switch (formType) {
|
|
3310
3322
|
case "1" /* LIST */:
|
|
3311
|
-
SubFormFactoryClass = (await import("./ListForm-
|
|
3323
|
+
SubFormFactoryClass = (await import("./ListForm-4DCCOHKJ.mjs")).default;
|
|
3312
3324
|
break;
|
|
3313
3325
|
case "3" /* TREE */:
|
|
3314
|
-
SubFormFactoryClass = (await import("./TreeView-
|
|
3326
|
+
SubFormFactoryClass = (await import("./TreeView-RDCA3LGU.mjs")).default;
|
|
3315
3327
|
break;
|
|
3316
3328
|
case "2" /* EDIT */:
|
|
3317
3329
|
case "99" /* FREE_FORM */:
|
|
3318
3330
|
case "4" /* REPORT */:
|
|
3319
|
-
SubFormFactoryClass = (await import("./FormEdit-
|
|
3331
|
+
SubFormFactoryClass = (await import("./FormEdit-QX5S7TDU.mjs")).default;
|
|
3320
3332
|
break;
|
|
3321
3333
|
default:
|
|
3322
3334
|
throw new Error(`Unsupported form type ${formType}`);
|
|
@@ -3478,14 +3490,14 @@ var Cell = class extends AbstractElementWithParent {
|
|
|
3478
3490
|
}
|
|
3479
3491
|
return getDate(value);
|
|
3480
3492
|
}
|
|
3481
|
-
async
|
|
3493
|
+
async getLocator() {
|
|
3482
3494
|
if (this._index == null) {
|
|
3483
3495
|
this.index = await this.getCellIndex();
|
|
3484
3496
|
}
|
|
3485
|
-
return this.
|
|
3497
|
+
return this.syncLocator();
|
|
3486
3498
|
}
|
|
3487
3499
|
async getValue() {
|
|
3488
|
-
const cellEl = await this.
|
|
3500
|
+
const cellEl = await this.getLocator();
|
|
3489
3501
|
const cellElClass = await cellEl.getAttribute("class") ?? "";
|
|
3490
3502
|
if (cellElClass.includes("boolean-column" /* Boolean */)) return this.getBooleanValue(cellEl);
|
|
3491
3503
|
if (cellElClass.includes("tags-column" /* Tags */)) return this.getTagsValue(cellEl);
|
|
@@ -3632,9 +3644,9 @@ var Column = class extends AbstractElementWithParent {
|
|
|
3632
3644
|
constructor({ parentCssSelector, headerCssSelector, name, caption, index, page }) {
|
|
3633
3645
|
super(parentCssSelector, "", page);
|
|
3634
3646
|
this._name = name;
|
|
3647
|
+
this.headerCssSelector = headerCssSelector;
|
|
3635
3648
|
this.index = index;
|
|
3636
3649
|
this._caption = caption;
|
|
3637
|
-
this.headerCssSelector = headerCssSelector;
|
|
3638
3650
|
}
|
|
3639
3651
|
set index(index) {
|
|
3640
3652
|
this._index = index;
|
|
@@ -3643,9 +3655,9 @@ var Column = class extends AbstractElementWithParent {
|
|
|
3643
3655
|
get index() {
|
|
3644
3656
|
return this._index;
|
|
3645
3657
|
}
|
|
3646
|
-
async
|
|
3658
|
+
async getLocator() {
|
|
3647
3659
|
await this.getIndex();
|
|
3648
|
-
return this.
|
|
3660
|
+
return this.syncLocator();
|
|
3649
3661
|
}
|
|
3650
3662
|
async getColumnHeaderIndexBy(cssSelector) {
|
|
3651
3663
|
const column = this.page.locator(`${this.parentCssSelector} ${this.headerCssSelector} ${cssSelector}`);
|
|
@@ -3658,7 +3670,7 @@ var Column = class extends AbstractElementWithParent {
|
|
|
3658
3670
|
return this.getColumnHeaderIndexBy(getColumnByNameCssSelector(this._name));
|
|
3659
3671
|
}
|
|
3660
3672
|
async caption() {
|
|
3661
|
-
const el = await this.
|
|
3673
|
+
const el = await this.getLocator();
|
|
3662
3674
|
const text = await el.innerText();
|
|
3663
3675
|
return text?.trim() ?? null;
|
|
3664
3676
|
}
|
|
@@ -3723,7 +3735,7 @@ var AbstractDXEditorWithInput = class extends AbstractElementWithParent {
|
|
|
3723
3735
|
async setInputValue(value) {
|
|
3724
3736
|
const input = this.getInputLocator();
|
|
3725
3737
|
await input.click();
|
|
3726
|
-
await input.
|
|
3738
|
+
await input.pressSequentially(value + "");
|
|
3727
3739
|
await input.press("Enter");
|
|
3728
3740
|
}
|
|
3729
3741
|
async clear() {
|
|
@@ -3775,6 +3787,7 @@ var ControlClass = /* @__PURE__ */ ((ControlClass2) => {
|
|
|
3775
3787
|
ControlClass2["BooleanSelector"] = "buttons-group";
|
|
3776
3788
|
ControlClass2["ButtonGroup"] = "button-group-field";
|
|
3777
3789
|
ControlClass2["HeaderFilterDictionary"] = "header-filter-dictionary";
|
|
3790
|
+
ControlClass2["FileUploader"] = "file-uploader";
|
|
3778
3791
|
return ControlClass2;
|
|
3779
3792
|
})(ControlClass || {});
|
|
3780
3793
|
|
|
@@ -3798,7 +3811,7 @@ var CheckBox = class extends AbstractElementWithParent {
|
|
|
3798
3811
|
// src/utils/xpathHelper.ts
|
|
3799
3812
|
var XPathHelper = class {
|
|
3800
3813
|
static getClassAndValueXpath(cssClass, value) {
|
|
3801
|
-
return `div[contains(@class, '${cssClass}') and
|
|
3814
|
+
return `div[contains(@class, '${cssClass}') and .='${value}']`;
|
|
3802
3815
|
}
|
|
3803
3816
|
};
|
|
3804
3817
|
|
|
@@ -4157,7 +4170,12 @@ var FormFilterField = class extends AbstractEditor {
|
|
|
4157
4170
|
formName;
|
|
4158
4171
|
name;
|
|
4159
4172
|
constructor(parentCssSelector, formName, name, page) {
|
|
4160
|
-
super(
|
|
4173
|
+
super({
|
|
4174
|
+
parentCssSelector,
|
|
4175
|
+
elementCssSelector: byTestIdCssSelector(createLayoutFilterTestId(formName, name)),
|
|
4176
|
+
titleCssSelector: byTestIdCssSelector(createLabelLayoutFilterTestId(formName, name)),
|
|
4177
|
+
page
|
|
4178
|
+
});
|
|
4161
4179
|
this.formName = formName;
|
|
4162
4180
|
this.name = name;
|
|
4163
4181
|
}
|
|
@@ -4261,7 +4279,12 @@ var PanelFilterField = class extends AbstractEditor {
|
|
|
4261
4279
|
formName;
|
|
4262
4280
|
name;
|
|
4263
4281
|
constructor(parentCssSelector, formName, name, page) {
|
|
4264
|
-
super(
|
|
4282
|
+
super({
|
|
4283
|
+
parentCssSelector,
|
|
4284
|
+
elementCssSelector: byTestIdCssSelector(createDocFilterTestId(formName, name)),
|
|
4285
|
+
titleCssSelector: byTestIdCssSelector(createLabelDocFilterTestId(formName, name)),
|
|
4286
|
+
page
|
|
4287
|
+
});
|
|
4265
4288
|
this.formName = formName;
|
|
4266
4289
|
this.name = name;
|
|
4267
4290
|
}
|
|
@@ -4548,7 +4571,7 @@ var SelectBoxEditor = class extends AbstractDXEditorWithInput {
|
|
|
4548
4571
|
const inputEl = this.getInputLocator();
|
|
4549
4572
|
await inputEl.click();
|
|
4550
4573
|
try {
|
|
4551
|
-
await inputEl.
|
|
4574
|
+
await inputEl.pressSequentially(value + "");
|
|
4552
4575
|
await inputEl.press("Enter");
|
|
4553
4576
|
await dropDownOptionClick(value, this.page, false);
|
|
4554
4577
|
} catch {
|
|
@@ -4632,12 +4655,12 @@ var TagBox = class extends AbstractDXEditorWithInput {
|
|
|
4632
4655
|
try {
|
|
4633
4656
|
await dropDownOptionClick(value, this.page, false);
|
|
4634
4657
|
} catch {
|
|
4635
|
-
await input.
|
|
4658
|
+
await input.pressSequentially(value + "");
|
|
4636
4659
|
await dropDownOptionClick(value, this.page, true);
|
|
4637
4660
|
}
|
|
4638
4661
|
await this.waitOptionSelection(value);
|
|
4639
4662
|
if (value !== lastElement) {
|
|
4640
|
-
await input.
|
|
4663
|
+
await input.pressSequentially("");
|
|
4641
4664
|
}
|
|
4642
4665
|
}
|
|
4643
4666
|
async confirmSelection() {
|
|
@@ -5001,11 +5024,7 @@ var SingleDateEditor = class extends BaseDateEditor {
|
|
|
5001
5024
|
}
|
|
5002
5025
|
async setValue(value) {
|
|
5003
5026
|
if (value instanceof Date) {
|
|
5004
|
-
await
|
|
5005
|
-
await this.setDateValue(value);
|
|
5006
|
-
const updatedValue = await this.getValue();
|
|
5007
|
-
return updatedValue.toDateString() === value.toDateString();
|
|
5008
|
-
}, this.page);
|
|
5027
|
+
await this.setDateValue(value);
|
|
5009
5028
|
} else {
|
|
5010
5029
|
throw new Error(`Value is incorrect. It should be a Date object`);
|
|
5011
5030
|
}
|
|
@@ -5085,12 +5104,11 @@ var DX_TEXTEDITOR_EMPTY3 = "dx-texteditor-empty";
|
|
|
5085
5104
|
var CUSTOM_OPTION_LIST_SELECTOR = "custom-list";
|
|
5086
5105
|
var SELECT_BOX_OPTION_TEXT_CONTAINER_CLASS2 = "d5-multi-select-item";
|
|
5087
5106
|
var TAG_BOX_LIST_ITEM_SELECTOR = '.dx-overlay-wrapper .dx-list-item[aria-selected="true"]';
|
|
5088
|
-
var combinedOptionHeaderFilterDictValueXpath = (value) => `//div[contains(@class, '${SELECT_BOX_OPTION_TEXT_CONTAINER_CLASS2}') and contains(text(), '${value}')]`;
|
|
5089
5107
|
var dropDownHeaderFilterDictionaryOptionClick = async (optionValue, page, dataTEST = "", delay = true) => {
|
|
5090
5108
|
const calendarPopoverSelector = byTestIdCssSelector(`${dataTEST}`);
|
|
5091
5109
|
const calendarPopover = page.locator(calendarPopoverSelector);
|
|
5092
5110
|
const customOptionList = calendarPopover.locator(`.${CUSTOM_OPTION_LIST_SELECTOR}`);
|
|
5093
|
-
const optElement = customOptionList.locator(
|
|
5111
|
+
const optElement = customOptionList.locator(`.${SELECT_BOX_OPTION_TEXT_CONTAINER_CLASS2}`, { hasText: optionValue });
|
|
5094
5112
|
try {
|
|
5095
5113
|
await optElement.waitFor({ state: "visible", timeout: delay ? void 0 : 600 });
|
|
5096
5114
|
await optElement.click();
|
|
@@ -5114,28 +5132,28 @@ var HeaderFilterDictionary = class extends AbstractDXEditorWithInput {
|
|
|
5114
5132
|
await this.selectOption(inputEl, value, lastElement);
|
|
5115
5133
|
}
|
|
5116
5134
|
}
|
|
5117
|
-
async waitOptionSelection() {
|
|
5118
|
-
|
|
5119
|
-
await selectedItem.waitFor({ state: "visible" });
|
|
5135
|
+
async waitOptionSelection(value) {
|
|
5136
|
+
await this.page.locator(`${TAG_BOX_LIST_ITEM_SELECTOR}`).filter({ hasText: value }).first().waitFor({ state: "visible" });
|
|
5120
5137
|
}
|
|
5121
5138
|
async selectOption(inputEl, value, lastElement) {
|
|
5122
5139
|
try {
|
|
5123
|
-
await inputEl.
|
|
5140
|
+
await inputEl.pressSequentially(value + "");
|
|
5124
5141
|
const dataTEST = await this.getDataTestId();
|
|
5125
5142
|
await dropDownHeaderFilterDictionaryOptionClick(value, this.page, dataTEST);
|
|
5126
5143
|
if (value !== lastElement) {
|
|
5127
|
-
await inputEl.
|
|
5144
|
+
await inputEl.pressSequentially("");
|
|
5128
5145
|
}
|
|
5129
5146
|
} catch (error) {
|
|
5130
5147
|
throw error;
|
|
5131
5148
|
}
|
|
5132
|
-
await this.waitOptionSelection();
|
|
5149
|
+
await this.waitOptionSelection(value);
|
|
5133
5150
|
}
|
|
5134
5151
|
async getHeaderFilterDictionaryInputValue() {
|
|
5135
5152
|
if (await this.isHeaderFilterDictionaryEmpty()) {
|
|
5136
5153
|
return [];
|
|
5137
5154
|
}
|
|
5138
5155
|
const tags = this.page.locator(`${this.getFullCssSelector()} .${DX_TAG_CONTAINER2} ${TAGS_SELECTOR2}`);
|
|
5156
|
+
await tags.first().waitFor({ state: "visible" });
|
|
5139
5157
|
const count = await tags.count();
|
|
5140
5158
|
const values = [];
|
|
5141
5159
|
for (let i = 0; i < count; i++) {
|
|
@@ -5159,6 +5177,118 @@ var HeaderFilterDictionary = class extends AbstractDXEditorWithInput {
|
|
|
5159
5177
|
}
|
|
5160
5178
|
};
|
|
5161
5179
|
|
|
5180
|
+
// src/pageObjects/elements/Editors/FileUploader.ts
|
|
5181
|
+
var FILE_NAME_SELECTOR = ".file-text";
|
|
5182
|
+
var FILE_SIZE_ATTRIBUTE = "data-filesize";
|
|
5183
|
+
var FILE_DATE_ATTRIBUTE = "data-moddate";
|
|
5184
|
+
var FILE_TYPE_ATTRIBUTE = "data-filetype";
|
|
5185
|
+
var SELECT_FILE_BUTTON_SELECTOR = ".select-file-button";
|
|
5186
|
+
var DOWNLOAD_FILE_BUTTON_SELECTOR = ".download-file-button";
|
|
5187
|
+
var METADATA_SELECTOR = ".file-text-file-info-wrapper";
|
|
5188
|
+
var CLEAR_BUTTON_SELECTOR = ".clear-button";
|
|
5189
|
+
var FileUploader = class extends AbstractElementWithParent {
|
|
5190
|
+
constructor(parentCssSelector, elementCssSelector, page) {
|
|
5191
|
+
super(parentCssSelector, elementCssSelector, page);
|
|
5192
|
+
}
|
|
5193
|
+
/**
|
|
5194
|
+
* Returns the metadata container element for the uploaded file.
|
|
5195
|
+
* Returns null when metadata is not rendered or not visible.
|
|
5196
|
+
*/
|
|
5197
|
+
async getMedataElement() {
|
|
5198
|
+
const root = this.getFullCssSelector();
|
|
5199
|
+
const locator = this.page.locator(`${root} ${METADATA_SELECTOR}`);
|
|
5200
|
+
if (!await locator.isVisible()) return null;
|
|
5201
|
+
return locator;
|
|
5202
|
+
}
|
|
5203
|
+
/**
|
|
5204
|
+
* Returns the name of the uploaded file, or null if not present.
|
|
5205
|
+
*/
|
|
5206
|
+
async getFileName() {
|
|
5207
|
+
const root = this.getFullCssSelector();
|
|
5208
|
+
const locator = this.page.locator(`${root} ${FILE_NAME_SELECTOR}`);
|
|
5209
|
+
if (!await locator.isVisible()) return null;
|
|
5210
|
+
const text = await locator.innerText();
|
|
5211
|
+
return text?.trim() || null;
|
|
5212
|
+
}
|
|
5213
|
+
/**
|
|
5214
|
+
* Returns the size of the uploaded file, or null if not present.
|
|
5215
|
+
*/
|
|
5216
|
+
async getFileSize() {
|
|
5217
|
+
const element = await this.getMedataElement();
|
|
5218
|
+
if (!element) return null;
|
|
5219
|
+
const result = (await element.getAttribute(FILE_SIZE_ATTRIBUTE))?.trim();
|
|
5220
|
+
return isNaN(+result) ? null : +result;
|
|
5221
|
+
}
|
|
5222
|
+
/**
|
|
5223
|
+
* Returns the upload/modification date of the file, or null if not present.
|
|
5224
|
+
*/
|
|
5225
|
+
async getFileDate() {
|
|
5226
|
+
const element = await this.getMedataElement();
|
|
5227
|
+
if (!element) return null;
|
|
5228
|
+
const fileModDate = (await element.getAttribute(FILE_DATE_ATTRIBUTE))?.trim();
|
|
5229
|
+
return fileModDate ? new Date(fileModDate) : null;
|
|
5230
|
+
}
|
|
5231
|
+
/**
|
|
5232
|
+
* Returns the MIME/content type of the uploaded file from metadata.
|
|
5233
|
+
* Returns null when the type attribute is absent or empty.
|
|
5234
|
+
*/
|
|
5235
|
+
async getFileType() {
|
|
5236
|
+
const element = await this.getMedataElement();
|
|
5237
|
+
if (!element) return null;
|
|
5238
|
+
const fileType = (await element.getAttribute(FILE_TYPE_ATTRIBUTE))?.trim();
|
|
5239
|
+
return fileType || null;
|
|
5240
|
+
}
|
|
5241
|
+
/**
|
|
5242
|
+
* Returns current file information: name, size and upload/modification date.
|
|
5243
|
+
* Returns null if no file is uploaded.
|
|
5244
|
+
*/
|
|
5245
|
+
async getValue() {
|
|
5246
|
+
const name = await this.getFileName();
|
|
5247
|
+
const size = await this.getFileSize();
|
|
5248
|
+
const date = await this.getFileDate();
|
|
5249
|
+
const type2 = await this.getFileType();
|
|
5250
|
+
if (!name && !size && !date && !type2) return null;
|
|
5251
|
+
return { FileName: name, FileSize: size, FileType: type2, ModDate: date };
|
|
5252
|
+
}
|
|
5253
|
+
/**
|
|
5254
|
+
* Uploads a file by clicking the select-file-button and providing the file path.
|
|
5255
|
+
* @param filePath - Absolute or relative path to the file on disk.
|
|
5256
|
+
*/
|
|
5257
|
+
async setValue(filePath) {
|
|
5258
|
+
const root = this.getFullCssSelector();
|
|
5259
|
+
const fileChooserPromise = this.page.waitForEvent("filechooser");
|
|
5260
|
+
await this.page.locator(`${root} ${SELECT_FILE_BUTTON_SELECTOR}`).click();
|
|
5261
|
+
const fileChooser = await fileChooserPromise;
|
|
5262
|
+
await fileChooser.setFiles(filePath);
|
|
5263
|
+
}
|
|
5264
|
+
/**
|
|
5265
|
+
* Downloads the currently uploaded file by clicking the download-file-button.
|
|
5266
|
+
* Returns the suggested file name of the downloaded file.
|
|
5267
|
+
*/
|
|
5268
|
+
async download() {
|
|
5269
|
+
const root = this.getFullCssSelector();
|
|
5270
|
+
const buttonLocator = this.page.locator(
|
|
5271
|
+
`${root} ${DOWNLOAD_FILE_BUTTON_SELECTOR}`
|
|
5272
|
+
);
|
|
5273
|
+
if (await buttonLocator.isHidden()) return "";
|
|
5274
|
+
const downloadPromise = this.page.waitForEvent("download");
|
|
5275
|
+
await buttonLocator.click();
|
|
5276
|
+
const download = await downloadPromise;
|
|
5277
|
+
return download.suggestedFilename();
|
|
5278
|
+
}
|
|
5279
|
+
/**
|
|
5280
|
+
* Removes the currently uploaded file by clicking the delete-file-button.
|
|
5281
|
+
* Does nothing if no file is uploaded.
|
|
5282
|
+
*/
|
|
5283
|
+
async clear() {
|
|
5284
|
+
if (await this.getValue() === null) return;
|
|
5285
|
+
const root = this.getFullCssSelector();
|
|
5286
|
+
const deleteButton = this.page.locator(`${root} ${CLEAR_BUTTON_SELECTOR}`);
|
|
5287
|
+
if (await deleteButton.isHidden()) return;
|
|
5288
|
+
await deleteButton.click();
|
|
5289
|
+
}
|
|
5290
|
+
};
|
|
5291
|
+
|
|
5162
5292
|
// src/pageObjects/elements/Editors/editorFactory.ts
|
|
5163
5293
|
var editorFactory = async (parentCssSelector, elementCssSelector, page) => {
|
|
5164
5294
|
const elementInstance = new AbstractFormElement(parentCssSelector, elementCssSelector, page);
|
|
@@ -5180,6 +5310,8 @@ var editorFactory = async (parentCssSelector, elementCssSelector, page) => {
|
|
|
5180
5310
|
return new ButtonGroup(parentCssSelector, elementCssSelector, page);
|
|
5181
5311
|
if (classString.includes("header-filter-dictionary" /* HeaderFilterDictionary */))
|
|
5182
5312
|
return new HeaderFilterDictionary(parentCssSelector, elementCssSelector, page);
|
|
5313
|
+
if (classString.includes("file-uploader" /* FileUploader */))
|
|
5314
|
+
return new FileUploader(parentCssSelector, elementCssSelector, page);
|
|
5183
5315
|
throw new Error("Unknown type of editor. Please write ticket to the support");
|
|
5184
5316
|
};
|
|
5185
5317
|
|
|
@@ -5207,11 +5339,25 @@ var EditorButton = class extends AbstractElementWithParent {
|
|
|
5207
5339
|
}
|
|
5208
5340
|
};
|
|
5209
5341
|
|
|
5342
|
+
// src/pageObjects/elements/EditorTitle.ts
|
|
5343
|
+
var CAPTION_TEXT_CLASS = " .caption-text";
|
|
5344
|
+
var EditorTitle = class extends AbstractElementWithParent {
|
|
5345
|
+
constructor({ parentCssSelector, elementCssSelector, page }) {
|
|
5346
|
+
super(parentCssSelector, elementCssSelector, page);
|
|
5347
|
+
}
|
|
5348
|
+
async getTitle() {
|
|
5349
|
+
const captionElement = this.getLocator().locator(CAPTION_TEXT_CLASS);
|
|
5350
|
+
return captionElement.innerText();
|
|
5351
|
+
}
|
|
5352
|
+
};
|
|
5353
|
+
|
|
5210
5354
|
// src/pageObjects/elements/AbstractEditor.ts
|
|
5211
5355
|
var AbstractEditor = class extends AbstractElementWithParent {
|
|
5212
5356
|
editor;
|
|
5213
|
-
|
|
5357
|
+
_titleCssSelector;
|
|
5358
|
+
constructor({ parentCssSelector, elementCssSelector, titleCssSelector, page }) {
|
|
5214
5359
|
super(parentCssSelector, elementCssSelector, page);
|
|
5360
|
+
this._titleCssSelector = titleCssSelector;
|
|
5215
5361
|
}
|
|
5216
5362
|
async initEditor() {
|
|
5217
5363
|
if (!this.editor) {
|
|
@@ -5307,12 +5453,43 @@ var AbstractEditor = class extends AbstractElementWithParent {
|
|
|
5307
5453
|
button(name) {
|
|
5308
5454
|
return new EditorButton(this.getFullCssSelector(), name, this.page);
|
|
5309
5455
|
}
|
|
5456
|
+
/**
|
|
5457
|
+
* Повертає загловок едітора
|
|
5458
|
+
* @example
|
|
5459
|
+
* expect(await formEdit.field('NumberFld').title()).toBe('Title1');
|
|
5460
|
+
* expect(await formEdit.field('TextFld').title()).toBe('Title2`);
|
|
5461
|
+
*/
|
|
5462
|
+
async title() {
|
|
5463
|
+
return new EditorTitle({
|
|
5464
|
+
elementCssSelector: this._titleCssSelector,
|
|
5465
|
+
parentCssSelector: this.parentCssSelector,
|
|
5466
|
+
page: this.page
|
|
5467
|
+
}).getTitle();
|
|
5468
|
+
}
|
|
5469
|
+
/**
|
|
5470
|
+
* Вивантажує файл і повертає назву файла. Доступний тільки для поля FileUploader.
|
|
5471
|
+
* @example
|
|
5472
|
+
* const fileName = await formEdit.field('FileField').downloadFile();
|
|
5473
|
+
* expect(filename()).toBe('file.pdf');
|
|
5474
|
+
*/
|
|
5475
|
+
async download() {
|
|
5476
|
+
await this.initEditor();
|
|
5477
|
+
if (!this.editor.download) {
|
|
5478
|
+
throw new Error("download is only available for the FileUploader field type.");
|
|
5479
|
+
}
|
|
5480
|
+
return this.editor.download();
|
|
5481
|
+
}
|
|
5310
5482
|
};
|
|
5311
5483
|
|
|
5312
5484
|
// src/pageObjects/elements/FormField.ts
|
|
5313
5485
|
var FormField = class extends AbstractEditor {
|
|
5314
5486
|
constructor(parentCssSelector, formName, name, page) {
|
|
5315
|
-
super(
|
|
5487
|
+
super({
|
|
5488
|
+
parentCssSelector,
|
|
5489
|
+
elementCssSelector: byTestIdCssSelector(createFieldTestId(formName, name)),
|
|
5490
|
+
titleCssSelector: byTestIdCssSelector(createLabelFieldTestId(formName, name)),
|
|
5491
|
+
page
|
|
5492
|
+
});
|
|
5316
5493
|
}
|
|
5317
5494
|
};
|
|
5318
5495
|
|
|
@@ -5449,6 +5626,7 @@ var Table = class extends AbstractElementWithParent {
|
|
|
5449
5626
|
this.getRowByIndex(index);
|
|
5450
5627
|
return new Column({
|
|
5451
5628
|
parentCssSelector: this.getFullCssSelector(),
|
|
5629
|
+
headerCssSelector: this.headerCssSelector,
|
|
5452
5630
|
page: this.page,
|
|
5453
5631
|
index
|
|
5454
5632
|
});
|
|
@@ -5561,7 +5739,7 @@ var Table = class extends AbstractElementWithParent {
|
|
|
5561
5739
|
[row] = await this.getSelectedRows();
|
|
5562
5740
|
}
|
|
5563
5741
|
if (!row) throw new Error("No row available row for context menu");
|
|
5564
|
-
const cellElement = await row.getCell(fieldName).
|
|
5742
|
+
const cellElement = await row.getCell(fieldName).getLocator();
|
|
5565
5743
|
await cellElement.click({ button: "right" });
|
|
5566
5744
|
});
|
|
5567
5745
|
}
|
|
@@ -5620,10 +5798,14 @@ var Table = class extends AbstractElementWithParent {
|
|
|
5620
5798
|
* console.log('Таблиця містить 5 рядків');
|
|
5621
5799
|
*/
|
|
5622
5800
|
async waitRowsCount(count) {
|
|
5623
|
-
await wait(
|
|
5624
|
-
|
|
5625
|
-
|
|
5626
|
-
|
|
5801
|
+
await wait(
|
|
5802
|
+
async () => {
|
|
5803
|
+
const rowsCount = await this.getRowElements().count();
|
|
5804
|
+
return rowsCount === count;
|
|
5805
|
+
},
|
|
5806
|
+
this.page,
|
|
5807
|
+
`Rows count not equal: ${count}`
|
|
5808
|
+
);
|
|
5627
5809
|
}
|
|
5628
5810
|
};
|
|
5629
5811
|
|
|
@@ -5845,7 +6027,10 @@ var ToolbarItem = class extends AbstractElementWithParent {
|
|
|
5845
6027
|
async click() {
|
|
5846
6028
|
try {
|
|
5847
6029
|
await this.init();
|
|
5848
|
-
await
|
|
6030
|
+
await wait(async () => {
|
|
6031
|
+
const element = this._button.getLocator();
|
|
6032
|
+
return await element.isEnabled() && await element.isVisible();
|
|
6033
|
+
}, this.page);
|
|
5849
6034
|
await this._button.click();
|
|
5850
6035
|
} catch (error) {
|
|
5851
6036
|
throw new Error(`Cannot click on toolbar item: ${this._itemName}`);
|
|
@@ -5905,7 +6090,12 @@ var FormToolbar = class extends AbstractElementWithParent {
|
|
|
5905
6090
|
// src/pageObjects/elements/Filters/HeaderFilterField.ts
|
|
5906
6091
|
var HeaderFilterField = class extends AbstractEditor {
|
|
5907
6092
|
constructor(parentCssSelector, formName, name, page) {
|
|
5908
|
-
super(
|
|
6093
|
+
super({
|
|
6094
|
+
parentCssSelector,
|
|
6095
|
+
elementCssSelector: byTestIdCssSelector(createHeaderFilterTestId(formName, name)),
|
|
6096
|
+
titleCssSelector: "",
|
|
6097
|
+
page
|
|
6098
|
+
});
|
|
5909
6099
|
}
|
|
5910
6100
|
async getValue() {
|
|
5911
6101
|
return super.getValue();
|
|
@@ -5957,7 +6147,7 @@ var ColumnFilter = class {
|
|
|
5957
6147
|
await this.getCancelButton().click();
|
|
5958
6148
|
}
|
|
5959
6149
|
async initFilter() {
|
|
5960
|
-
const columnEl = await this._column.
|
|
6150
|
+
const columnEl = await this._column.getLocator();
|
|
5961
6151
|
await columnEl.hover();
|
|
5962
6152
|
const headerFilterIcon = columnEl.locator(HEADER_FILTER_ICON);
|
|
5963
6153
|
await headerFilterIcon.waitFor({ state: "visible" });
|