d5-testing-library 2.0.0-alpha.0 → 2.0.0-alpha.2
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-I63LWQEH.mjs +6 -0
- package/dist/ListForm-NEBCZD4X.mjs +6 -0
- package/dist/TreeView-T3PIDSZQ.mjs +6 -0
- package/dist/chunk-75NROWLM.mjs +6193 -0
- package/dist/cjs/d5-testing-library.cjs +1175 -1473
- package/dist/cjs/d5-testing-library.d.ts +126 -160
- package/dist/d5-testing-library.d.mts +126 -160
- package/dist/d5-testing-library.legacy-esm.js +14 -3174
- package/dist/d5-testing-library.mjs +14 -3174
- package/package.json +3 -16
- package/dist/FormEdit-VFV53QIZ.mjs +0 -7
- package/dist/ListForm-KIHLT7EU.mjs +0 -7
- package/dist/TreeView-TFBZB2UK.mjs +0 -8
- package/dist/chunk-EFNMD3S7.mjs +0 -22
- package/dist/chunk-GVYXH7L3.mjs +0 -75
- package/dist/chunk-RPSLW2WB.mjs +0 -1722
- package/dist/chunk-TSE33S3X.mjs +0 -1555
package/dist/chunk-RPSLW2WB.mjs
DELETED
|
@@ -1,1722 +0,0 @@
|
|
|
1
|
-
var __create = Object.create;
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
-
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
8
|
-
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
9
|
-
}) : x)(function(x) {
|
|
10
|
-
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
11
|
-
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
12
|
-
});
|
|
13
|
-
var __commonJS = (cb, mod) => function __require2() {
|
|
14
|
-
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
15
|
-
};
|
|
16
|
-
var __copyProps = (to, from, except, desc) => {
|
|
17
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
18
|
-
for (let key of __getOwnPropNames(from))
|
|
19
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
20
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
21
|
-
}
|
|
22
|
-
return to;
|
|
23
|
-
};
|
|
24
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
25
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
26
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
27
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
28
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
29
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
30
|
-
mod
|
|
31
|
-
));
|
|
32
|
-
|
|
33
|
-
// src/config.ts
|
|
34
|
-
var Config = class _Config {
|
|
35
|
-
static instance;
|
|
36
|
-
appConfig;
|
|
37
|
-
static getInstance() {
|
|
38
|
-
if (!_Config.instance) {
|
|
39
|
-
_Config.instance = new _Config();
|
|
40
|
-
}
|
|
41
|
-
return _Config.instance;
|
|
42
|
-
}
|
|
43
|
-
config = (cfg) => {
|
|
44
|
-
if (!cfg) return this.appConfig;
|
|
45
|
-
this.appConfig = cfg;
|
|
46
|
-
};
|
|
47
|
-
};
|
|
48
|
-
var configInstance = Config.getInstance();
|
|
49
|
-
function config(cfg) {
|
|
50
|
-
return configInstance.config(cfg);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// src/pageObjects/AbstractElement.ts
|
|
54
|
-
import { By } from "selenium-webdriver";
|
|
55
|
-
|
|
56
|
-
// src/utils/fixElementStaleError.ts
|
|
57
|
-
function fixElementStaleError(by, driver) {
|
|
58
|
-
const maxCount = 3;
|
|
59
|
-
let err;
|
|
60
|
-
const call = async (times) => {
|
|
61
|
-
if (times > maxCount) throw err;
|
|
62
|
-
try {
|
|
63
|
-
let el = await driver.findElement(by);
|
|
64
|
-
await el.getAttribute("class");
|
|
65
|
-
return el;
|
|
66
|
-
} catch (e) {
|
|
67
|
-
err = e;
|
|
68
|
-
if (e instanceof Error && e.message.toLowerCase().includes("stale element")) {
|
|
69
|
-
return call(times + 1);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
if (err) throw err;
|
|
73
|
-
};
|
|
74
|
-
return call(0);
|
|
75
|
-
}
|
|
76
|
-
async function staleElementAction(action) {
|
|
77
|
-
const maxCount = 3;
|
|
78
|
-
let err;
|
|
79
|
-
const call = async (times) => {
|
|
80
|
-
if (times > maxCount) throw err;
|
|
81
|
-
try {
|
|
82
|
-
await action();
|
|
83
|
-
} catch (e) {
|
|
84
|
-
err = e;
|
|
85
|
-
if (e instanceof Error && e.message.toLowerCase().includes("stale element")) {
|
|
86
|
-
await call(times + 1);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
if (err) throw err;
|
|
90
|
-
};
|
|
91
|
-
await call(0);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// src/pageObjects/AbstractElement.ts
|
|
95
|
-
var AbstractElement = class {
|
|
96
|
-
driver;
|
|
97
|
-
elementCssSelector;
|
|
98
|
-
constructor(driver, elementCssSelector) {
|
|
99
|
-
this.driver = driver;
|
|
100
|
-
this.elementCssSelector = elementCssSelector;
|
|
101
|
-
}
|
|
102
|
-
getFullCssSelector() {
|
|
103
|
-
return this.elementCssSelector;
|
|
104
|
-
}
|
|
105
|
-
joinRelativeCssSelectors(selectors) {
|
|
106
|
-
return selectors.join(" ");
|
|
107
|
-
}
|
|
108
|
-
getElement() {
|
|
109
|
-
return fixElementStaleError(By.css(this.getFullCssSelector()), this.driver);
|
|
110
|
-
}
|
|
111
|
-
async getAttribute(attr) {
|
|
112
|
-
const element = await this.getElement();
|
|
113
|
-
return await element.getAttribute(attr);
|
|
114
|
-
}
|
|
115
|
-
async getClasses() {
|
|
116
|
-
return await this.getAttribute("class");
|
|
117
|
-
}
|
|
118
|
-
async getDataTestId() {
|
|
119
|
-
return await this.getAttribute("data-testid");
|
|
120
|
-
}
|
|
121
|
-
async getDataDateMode() {
|
|
122
|
-
return await this.getAttribute("data-datemode");
|
|
123
|
-
}
|
|
124
|
-
};
|
|
125
|
-
|
|
126
|
-
// src/pageObjects/pages/AbstractPage.ts
|
|
127
|
-
var AbstractPage = class extends AbstractElement {
|
|
128
|
-
url;
|
|
129
|
-
host;
|
|
130
|
-
constructor(driver) {
|
|
131
|
-
super(driver);
|
|
132
|
-
this.host = config().auth.host;
|
|
133
|
-
this.url = this.host + this.prependHash(this.path);
|
|
134
|
-
}
|
|
135
|
-
prependHash(urlPath) {
|
|
136
|
-
if (!urlPath.startsWith("/#")) {
|
|
137
|
-
return `/#${urlPath}`;
|
|
138
|
-
}
|
|
139
|
-
return urlPath;
|
|
140
|
-
}
|
|
141
|
-
async goToUrl(url) {
|
|
142
|
-
await this.driver.get(url);
|
|
143
|
-
}
|
|
144
|
-
get path() {
|
|
145
|
-
return "/#";
|
|
146
|
-
}
|
|
147
|
-
async locate() {
|
|
148
|
-
await this.goToUrl(this.url);
|
|
149
|
-
}
|
|
150
|
-
async reloadPage() {
|
|
151
|
-
await this.driver.navigate().refresh();
|
|
152
|
-
}
|
|
153
|
-
};
|
|
154
|
-
|
|
155
|
-
// src/utils/wait.ts
|
|
156
|
-
async function wait(condition, driver, errorMessage, timeout) {
|
|
157
|
-
await driver.wait(condition, timeout ?? config().timeout, errorMessage);
|
|
158
|
-
}
|
|
159
|
-
function safeWait(condition, driver, errorMessage, timeout) {
|
|
160
|
-
return wait(async () => {
|
|
161
|
-
try {
|
|
162
|
-
return await condition(driver);
|
|
163
|
-
} catch {
|
|
164
|
-
return false;
|
|
165
|
-
}
|
|
166
|
-
}, driver, errorMessage, timeout);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
// src/utils/waitElementIsVisible.ts
|
|
170
|
-
async function waitElementIsVisible({
|
|
171
|
-
timeout,
|
|
172
|
-
errorMessage,
|
|
173
|
-
driver,
|
|
174
|
-
...rest
|
|
175
|
-
}) {
|
|
176
|
-
await safeWait(async () => {
|
|
177
|
-
const searchedElement = "by" in rest ? await fixElementStaleError(rest.by, driver) : rest.element;
|
|
178
|
-
return await searchedElement.isDisplayed();
|
|
179
|
-
}, driver, errorMessage ?? "Element is not visible", timeout ?? config().timeout);
|
|
180
|
-
}
|
|
181
|
-
var waitElementIsVisible_default = waitElementIsVisible;
|
|
182
|
-
|
|
183
|
-
// src/utils/actions.ts
|
|
184
|
-
var click = async (webElement, driver) => {
|
|
185
|
-
if (!await webElement.isDisplayed()) {
|
|
186
|
-
await driver.executeScript("arguments[0].scrollIntoView(true);", webElement);
|
|
187
|
-
}
|
|
188
|
-
const actions = driver.actions({ async: true });
|
|
189
|
-
await actions.move({ origin: webElement }).click().perform();
|
|
190
|
-
};
|
|
191
|
-
var contextMenu = async (webElement, driver) => {
|
|
192
|
-
if (!await webElement.isDisplayed()) {
|
|
193
|
-
await driver.executeScript("arguments[0].scrollIntoView(true);", webElement);
|
|
194
|
-
}
|
|
195
|
-
const actions = driver.actions({ async: true });
|
|
196
|
-
await actions.move({ origin: webElement }).contextClick().perform();
|
|
197
|
-
};
|
|
198
|
-
|
|
199
|
-
// src/utils/locators.ts
|
|
200
|
-
import { By as By2 } from "selenium-webdriver";
|
|
201
|
-
var byTestIdCssSelector = (testId, element = "div") => {
|
|
202
|
-
return `${element}[data-testid="${testId}"]`;
|
|
203
|
-
};
|
|
204
|
-
var byTestId = (testId, element = "div") => {
|
|
205
|
-
return By2.css(byTestIdCssSelector(testId, element));
|
|
206
|
-
};
|
|
207
|
-
var readonlyLocator = "readonly";
|
|
208
|
-
var disabledLocator = "disabled";
|
|
209
|
-
|
|
210
|
-
// src/utils/waitElementIsClickable.ts
|
|
211
|
-
async function waitElementIsClickable({
|
|
212
|
-
timeout,
|
|
213
|
-
errorMessage,
|
|
214
|
-
driver,
|
|
215
|
-
...rest
|
|
216
|
-
}) {
|
|
217
|
-
await safeWait(async () => {
|
|
218
|
-
const searchedElement = "by" in rest ? await fixElementStaleError(rest.by, driver) : rest.element;
|
|
219
|
-
const isDisabled = await searchedElement.getCssValue("pointer-events") === "none";
|
|
220
|
-
return await searchedElement.isDisplayed() && !isDisabled;
|
|
221
|
-
}, driver, errorMessage, timeout ?? config().timeout);
|
|
222
|
-
}
|
|
223
|
-
var waitElementIsClickable_default = waitElementIsClickable;
|
|
224
|
-
|
|
225
|
-
// src/pageObjects/elements/Editors/AbstractEditor.ts
|
|
226
|
-
import { By as By3, Key } from "selenium-webdriver";
|
|
227
|
-
|
|
228
|
-
// src/pageObjects/elements/Editors/ClearStrategy/InputClearStrategy.ts
|
|
229
|
-
var InputClearStrategy = class {
|
|
230
|
-
async clear(editor) {
|
|
231
|
-
const inputEl = await editor.getInputElement();
|
|
232
|
-
await inputEl.clear();
|
|
233
|
-
}
|
|
234
|
-
};
|
|
235
|
-
|
|
236
|
-
// src/pageObjects/AbstractElementWithParent.ts
|
|
237
|
-
var AbstractElementWithParent = class extends AbstractElement {
|
|
238
|
-
parentCssSelector;
|
|
239
|
-
constructor(parentCssSelector, elementCssSelector, driver) {
|
|
240
|
-
super(driver, elementCssSelector);
|
|
241
|
-
this.parentCssSelector = parentCssSelector;
|
|
242
|
-
}
|
|
243
|
-
getFullCssSelector() {
|
|
244
|
-
if (!this.elementCssSelector) {
|
|
245
|
-
return this.parentCssSelector;
|
|
246
|
-
}
|
|
247
|
-
if (!this.parentCssSelector) {
|
|
248
|
-
return this.elementCssSelector;
|
|
249
|
-
}
|
|
250
|
-
return `${this.parentCssSelector} ${this.elementCssSelector}`;
|
|
251
|
-
}
|
|
252
|
-
async isReadonly() {
|
|
253
|
-
const classSting = await this.getClasses();
|
|
254
|
-
return classSting.includes(readonlyLocator);
|
|
255
|
-
}
|
|
256
|
-
async isDisabled() {
|
|
257
|
-
const classSting = await this.getClasses();
|
|
258
|
-
return classSting.includes(disabledLocator);
|
|
259
|
-
}
|
|
260
|
-
};
|
|
261
|
-
|
|
262
|
-
// src/pageObjects/elements/Editors/AbstractEditor.ts
|
|
263
|
-
var AbstractDXEditorWithInput = class extends AbstractElementWithParent {
|
|
264
|
-
clearStrategy = new InputClearStrategy();
|
|
265
|
-
setClearStrategy(strategy) {
|
|
266
|
-
this.clearStrategy = strategy;
|
|
267
|
-
}
|
|
268
|
-
getInputCssSelector() {
|
|
269
|
-
return `${this.getFullCssSelector()} .dx-texteditor-input`;
|
|
270
|
-
}
|
|
271
|
-
async getInputElement() {
|
|
272
|
-
return this.driver.findElement(By3.css(this.getInputCssSelector()));
|
|
273
|
-
}
|
|
274
|
-
async getInputValue() {
|
|
275
|
-
const inputEl = await this.getInputElement();
|
|
276
|
-
return inputEl.getAttribute("value");
|
|
277
|
-
}
|
|
278
|
-
async setInputValue(value) {
|
|
279
|
-
const inputEl = await this.getInputElement();
|
|
280
|
-
await click(inputEl, this.driver);
|
|
281
|
-
await inputEl.sendKeys(value, Key.ENTER);
|
|
282
|
-
}
|
|
283
|
-
async clear() {
|
|
284
|
-
await this.clearStrategy.clear(this);
|
|
285
|
-
}
|
|
286
|
-
};
|
|
287
|
-
|
|
288
|
-
// src/pageObjects/elements/Editors/TextEditor.ts
|
|
289
|
-
var TextEditor = class extends AbstractDXEditorWithInput {
|
|
290
|
-
constructor(parentCssSelector, elementCssSelector, driver) {
|
|
291
|
-
super(parentCssSelector, elementCssSelector, driver);
|
|
292
|
-
this.setClearStrategy(new InputClearStrategy());
|
|
293
|
-
}
|
|
294
|
-
async getValue() {
|
|
295
|
-
const value = await super.getInputValue();
|
|
296
|
-
return value == "" ? null : value;
|
|
297
|
-
}
|
|
298
|
-
setValue(value) {
|
|
299
|
-
return this.setInputValue(value);
|
|
300
|
-
}
|
|
301
|
-
};
|
|
302
|
-
|
|
303
|
-
// src/pageObjects/elements/Editors/NumberEditor.ts
|
|
304
|
-
var NumberEditor = class extends AbstractDXEditorWithInput {
|
|
305
|
-
constructor(parentCssSelector, elementCssSelector, driver) {
|
|
306
|
-
super(parentCssSelector, elementCssSelector, driver);
|
|
307
|
-
this.setClearStrategy(new InputClearStrategy());
|
|
308
|
-
}
|
|
309
|
-
async getValue() {
|
|
310
|
-
const value = await super.getInputValue();
|
|
311
|
-
return value == "" ? null : Number.parseFloat(value);
|
|
312
|
-
}
|
|
313
|
-
setValue(value) {
|
|
314
|
-
return this.setInputValue(value);
|
|
315
|
-
}
|
|
316
|
-
};
|
|
317
|
-
|
|
318
|
-
// src/pageObjects/elements/Editors/types.ts
|
|
319
|
-
var ControlClass = /* @__PURE__ */ ((ControlClass2) => {
|
|
320
|
-
ControlClass2["Text"] = "text-control";
|
|
321
|
-
ControlClass2["TextArea"] = "text-area-control";
|
|
322
|
-
ControlClass2["Number"] = "number-control";
|
|
323
|
-
ControlClass2["CheckBox"] = "check-box";
|
|
324
|
-
ControlClass2["Multiselect"] = "multi-select-control";
|
|
325
|
-
ControlClass2["Select"] = "select-control";
|
|
326
|
-
ControlClass2["Switch"] = "switch-control";
|
|
327
|
-
ControlClass2["Date"] = "date-control";
|
|
328
|
-
ControlClass2["SingleDateRange"] = "single-date-range-control";
|
|
329
|
-
ControlClass2["BooleanSelector"] = "buttons-group";
|
|
330
|
-
ControlClass2["ButtonGroup"] = "button-group-field";
|
|
331
|
-
ControlClass2["HeaderFilterDictionary"] = "header-filter-dictionary";
|
|
332
|
-
return ControlClass2;
|
|
333
|
-
})(ControlClass || {});
|
|
334
|
-
|
|
335
|
-
// src/pageObjects/AbstractFormElement.ts
|
|
336
|
-
var AbstractFormElement = class extends AbstractElementWithParent {
|
|
337
|
-
constructor(parentCssSelector, elementCssSelector, driver) {
|
|
338
|
-
super(parentCssSelector, elementCssSelector, driver);
|
|
339
|
-
}
|
|
340
|
-
};
|
|
341
|
-
|
|
342
|
-
// src/pageObjects/elements/Editors/CheckBox.ts
|
|
343
|
-
var CheckBox = class extends AbstractElementWithParent {
|
|
344
|
-
async getValue() {
|
|
345
|
-
const result = await this.getAttribute("aria-checked");
|
|
346
|
-
if (result === "true") return 1;
|
|
347
|
-
if (result === "false") return 0;
|
|
348
|
-
return null;
|
|
349
|
-
}
|
|
350
|
-
async setValue(value) {
|
|
351
|
-
const inputEl = await this.getElement();
|
|
352
|
-
const currentValue = await this.getValue();
|
|
353
|
-
if (currentValue !== value) {
|
|
354
|
-
await click(inputEl, this.driver);
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
};
|
|
358
|
-
|
|
359
|
-
// src/pageObjects/elements/Editors/SelectBoxEditor.ts
|
|
360
|
-
import { By as By5, Key as Key2 } from "selenium-webdriver";
|
|
361
|
-
|
|
362
|
-
// src/utils/xpathHelper.ts
|
|
363
|
-
var XPathHelper = class {
|
|
364
|
-
static getClassAndValueXpath(cssClass, value) {
|
|
365
|
-
return `div[contains(@class, '${cssClass}') and contains(.,'${value}')]`;
|
|
366
|
-
}
|
|
367
|
-
};
|
|
368
|
-
|
|
369
|
-
// src/pageObjects/elements/Editors/ClearStrategy/ClearButtonStrategy.ts
|
|
370
|
-
import { By as By4 } from "selenium-webdriver";
|
|
371
|
-
var DX_TEXTEDITOR_EMPTY = "dx-texteditor-empty";
|
|
372
|
-
var DX_CLEAR_BUTTON_AREA = "dx-clear-button-area";
|
|
373
|
-
var ClearButtonStrategy = class {
|
|
374
|
-
editorContainerClass;
|
|
375
|
-
_driver;
|
|
376
|
-
constructor(editorContainerClass, driver) {
|
|
377
|
-
this.editorContainerClass = editorContainerClass;
|
|
378
|
-
this._driver = driver;
|
|
379
|
-
}
|
|
380
|
-
async isEmptyEditorField() {
|
|
381
|
-
const editorContainer = await this._driver.findElement(By4.css(this.editorContainerClass));
|
|
382
|
-
const classAttribute = await editorContainer.getAttribute("class");
|
|
383
|
-
return classAttribute.includes(DX_TEXTEDITOR_EMPTY);
|
|
384
|
-
}
|
|
385
|
-
async clear() {
|
|
386
|
-
if (await this.isEmptyEditorField()) {
|
|
387
|
-
throw new Error("This field is already empty");
|
|
388
|
-
}
|
|
389
|
-
const clearBtnSelector = `${this.editorContainerClass} .${DX_CLEAR_BUTTON_AREA}`;
|
|
390
|
-
const clearBtn = await this._driver.findElement(By4.css(clearBtnSelector));
|
|
391
|
-
await click(clearBtn, this._driver);
|
|
392
|
-
}
|
|
393
|
-
};
|
|
394
|
-
|
|
395
|
-
// src/utils/withCustomTimeouts.ts
|
|
396
|
-
async function withCustomTimeouts({ driver, timeout, callback }) {
|
|
397
|
-
const { implicit: defaultTimeout } = await driver.manage().getTimeouts();
|
|
398
|
-
try {
|
|
399
|
-
await driver.manage().setTimeouts({ implicit: timeout ?? defaultTimeout });
|
|
400
|
-
return await callback();
|
|
401
|
-
} finally {
|
|
402
|
-
await driver.manage().setTimeouts({ implicit: defaultTimeout });
|
|
403
|
-
}
|
|
404
|
-
}
|
|
405
|
-
var withCustomTimeouts_default = withCustomTimeouts;
|
|
406
|
-
|
|
407
|
-
// src/pageObjects/elements/Editors/SelectBoxEditor.ts
|
|
408
|
-
var SELECT_BOX_OPTION_TEXT_CONTAINER_CLASS = "d5-multi-select-item";
|
|
409
|
-
var combinedValueXpath = (value) => `//body/div[@id="root"]/div[contains(@class, "dx-overlay-wrapper")]//${XPathHelper.getClassAndValueXpath(SELECT_BOX_OPTION_TEXT_CONTAINER_CLASS, value)}`;
|
|
410
|
-
var dropDownOptionClick = async (optionValue, driver, delay = true) => {
|
|
411
|
-
let err = null;
|
|
412
|
-
try {
|
|
413
|
-
await withCustomTimeouts_default({
|
|
414
|
-
driver,
|
|
415
|
-
timeout: delay ? void 0 : 200,
|
|
416
|
-
callback: async () => {
|
|
417
|
-
let optElement = await driver.findElement(By5.xpath(combinedValueXpath(optionValue)));
|
|
418
|
-
await click(optElement, driver);
|
|
419
|
-
}
|
|
420
|
-
});
|
|
421
|
-
} catch (e) {
|
|
422
|
-
err = new Error(`Item not found: "${optionValue}"`);
|
|
423
|
-
}
|
|
424
|
-
if (err)
|
|
425
|
-
throw err;
|
|
426
|
-
};
|
|
427
|
-
var SelectBoxEditor = class extends AbstractDXEditorWithInput {
|
|
428
|
-
constructor(parentCssSelector, elementCssSelector, driver) {
|
|
429
|
-
super(parentCssSelector, elementCssSelector, driver);
|
|
430
|
-
this.setClearStrategy(new ClearButtonStrategy(this.getFullCssSelector(), this.driver));
|
|
431
|
-
}
|
|
432
|
-
async setSelectInputValue(value) {
|
|
433
|
-
const inputEl = await this.getInputElement();
|
|
434
|
-
await click(inputEl, this.driver);
|
|
435
|
-
try {
|
|
436
|
-
await dropDownOptionClick(value, this.driver, false);
|
|
437
|
-
} catch {
|
|
438
|
-
await inputEl.sendKeys(value, Key2.ENTER);
|
|
439
|
-
await dropDownOptionClick(value, this.driver);
|
|
440
|
-
}
|
|
441
|
-
}
|
|
442
|
-
async getValue() {
|
|
443
|
-
const value = await super.getInputValue();
|
|
444
|
-
return value == "" ? null : value;
|
|
445
|
-
}
|
|
446
|
-
setValue(value) {
|
|
447
|
-
return this.setSelectInputValue(value);
|
|
448
|
-
}
|
|
449
|
-
};
|
|
450
|
-
|
|
451
|
-
// src/pageObjects/elements/Editors/SwitchEditor.ts
|
|
452
|
-
var SwitchEditor = class extends AbstractElementWithParent {
|
|
453
|
-
async getValue() {
|
|
454
|
-
const result = await this.getAttribute("aria-label");
|
|
455
|
-
if (result === "ON") return 1;
|
|
456
|
-
if (result === "OFF") return 0;
|
|
457
|
-
return null;
|
|
458
|
-
}
|
|
459
|
-
async setValue(value) {
|
|
460
|
-
if (value !== 0 && value !== 1) {
|
|
461
|
-
value = value ? 1 : 0;
|
|
462
|
-
}
|
|
463
|
-
const inputEl = await this.getElement();
|
|
464
|
-
const currentValue = await this.getValue();
|
|
465
|
-
if (currentValue === value) {
|
|
466
|
-
return;
|
|
467
|
-
}
|
|
468
|
-
await click(inputEl, this.driver);
|
|
469
|
-
await safeWait(async () => {
|
|
470
|
-
const updatedValue = await this.getValue();
|
|
471
|
-
return updatedValue !== currentValue;
|
|
472
|
-
}, this.driver);
|
|
473
|
-
}
|
|
474
|
-
};
|
|
475
|
-
|
|
476
|
-
// src/pageObjects/elements/Editors/TagBox.ts
|
|
477
|
-
import { By as By6 } from "selenium-webdriver";
|
|
478
|
-
var TAGS_SELECTOR = ".dx-tag .tag-text";
|
|
479
|
-
var DX_TAG_CONTAINER = "dx-tag-container";
|
|
480
|
-
var DX_TEXTEDITOR_EMPTY2 = "dx-texteditor-empty";
|
|
481
|
-
var BTN_OK_SELECTOR = ".dx-tagbox-popup-wrapper .dx-popup-bottom .dx-button.dx-popup-done";
|
|
482
|
-
var getSelectedOptionXpath = (value) => `//body/div[@id="root"]/div[contains(@class, "dx-overlay-wrapper")]//div[contains(@class, 'dx-list-item') and @aria-selected="true"]//div[contains(., "${value}")]`;
|
|
483
|
-
var TagBox = class extends AbstractDXEditorWithInput {
|
|
484
|
-
constructor(parentCssSelector, elementCssSelector, driver) {
|
|
485
|
-
super(parentCssSelector, elementCssSelector, driver);
|
|
486
|
-
this.setClearStrategy(new ClearButtonStrategy(this.getFullCssSelector(), this.driver));
|
|
487
|
-
}
|
|
488
|
-
async setTagBoxInputValue(values) {
|
|
489
|
-
const lastElement = values[values.length - 1];
|
|
490
|
-
const inputEl = await this.getInputElement();
|
|
491
|
-
await inputEl.click();
|
|
492
|
-
for (const value of values) {
|
|
493
|
-
await this.selectOption(inputEl, value, lastElement);
|
|
494
|
-
}
|
|
495
|
-
await this.confirmSelection();
|
|
496
|
-
}
|
|
497
|
-
async waitOptionSelection(value) {
|
|
498
|
-
await safeWait(
|
|
499
|
-
async () => {
|
|
500
|
-
const elements = await this.driver.findElements(By6.xpath(getSelectedOptionXpath(value)));
|
|
501
|
-
if (elements.length === 0) return false;
|
|
502
|
-
return await elements[0].isDisplayed();
|
|
503
|
-
},
|
|
504
|
-
this.driver
|
|
505
|
-
);
|
|
506
|
-
}
|
|
507
|
-
async selectOption(inputEl, value, lastElement) {
|
|
508
|
-
try {
|
|
509
|
-
await dropDownOptionClick(value, this.driver, false);
|
|
510
|
-
} catch {
|
|
511
|
-
await inputEl.sendKeys(value);
|
|
512
|
-
await dropDownOptionClick(value, this.driver);
|
|
513
|
-
}
|
|
514
|
-
await this.waitOptionSelection(value);
|
|
515
|
-
if (value !== lastElement) {
|
|
516
|
-
await inputEl.clear();
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
async confirmSelection() {
|
|
520
|
-
const btnOk = await fixElementStaleError(By6.css(BTN_OK_SELECTOR), this.driver);
|
|
521
|
-
await click(btnOk, this.driver);
|
|
522
|
-
}
|
|
523
|
-
async getTagBoxInputValue() {
|
|
524
|
-
if (await this.isTagBoxEmpty()) {
|
|
525
|
-
return [];
|
|
526
|
-
}
|
|
527
|
-
const tags = await this.driver.findElements(
|
|
528
|
-
By6.css(`${this.getFullCssSelector()} .${DX_TAG_CONTAINER} ${TAGS_SELECTOR}`)
|
|
529
|
-
);
|
|
530
|
-
const values = [];
|
|
531
|
-
for (const tag of tags) {
|
|
532
|
-
values.push(await tag.getAttribute("textContent"));
|
|
533
|
-
}
|
|
534
|
-
return values;
|
|
535
|
-
}
|
|
536
|
-
async isTagBoxEmpty() {
|
|
537
|
-
const classAttribute = await this.getClasses();
|
|
538
|
-
return classAttribute.includes(DX_TEXTEDITOR_EMPTY2);
|
|
539
|
-
}
|
|
540
|
-
async getValue() {
|
|
541
|
-
const value = await this.getTagBoxInputValue();
|
|
542
|
-
return value.length ? value : null;
|
|
543
|
-
}
|
|
544
|
-
async setValue(values) {
|
|
545
|
-
if (!Array.isArray(values)) {
|
|
546
|
-
throw new Error("The provided value is not an array");
|
|
547
|
-
}
|
|
548
|
-
await this.setTagBoxInputValue(values);
|
|
549
|
-
}
|
|
550
|
-
async remove(itemText) {
|
|
551
|
-
const tagValues = await this.getValue();
|
|
552
|
-
const tagExists = tagValues.includes(itemText);
|
|
553
|
-
if (!tagExists) {
|
|
554
|
-
throw new Error(`The tag with the text: ${itemText} was not found`);
|
|
555
|
-
}
|
|
556
|
-
const clearBtnTestId = byTestIdCssSelector(`clear-button-${itemText}`);
|
|
557
|
-
const clearBtn = await this.driver.findElement(
|
|
558
|
-
By6.css(`${this.getFullCssSelector()} .${DX_TAG_CONTAINER} ${clearBtnTestId}`)
|
|
559
|
-
);
|
|
560
|
-
await click(clearBtn, this.driver);
|
|
561
|
-
}
|
|
562
|
-
};
|
|
563
|
-
|
|
564
|
-
// src/pageObjects/elements/Editors/ButtonGroup.ts
|
|
565
|
-
import { By as By7 } from "selenium-webdriver";
|
|
566
|
-
var ITEM_CLASS = "dx-buttongroup-item";
|
|
567
|
-
var SELECTED_CLASS = "dx-state-selected";
|
|
568
|
-
var ButtonGroup = class extends AbstractElementWithParent {
|
|
569
|
-
getItems() {
|
|
570
|
-
return this.driver.findElements(By7.css(`${this.getFullCssSelector()} .${ITEM_CLASS}`));
|
|
571
|
-
}
|
|
572
|
-
getDataValue(el) {
|
|
573
|
-
return el.getAttribute("data-value");
|
|
574
|
-
}
|
|
575
|
-
async getValue() {
|
|
576
|
-
const selectedEl = await this.driver.findElement(By7.css(`${this.getFullCssSelector()} .${ITEM_CLASS}.${SELECTED_CLASS}`));
|
|
577
|
-
return this.getDataValue(selectedEl);
|
|
578
|
-
}
|
|
579
|
-
async setValue(value) {
|
|
580
|
-
const items = await this.getItems();
|
|
581
|
-
let buttonEl = void 0;
|
|
582
|
-
for (const item of items) {
|
|
583
|
-
const text = await this.getDataValue(item);
|
|
584
|
-
if (text == value) {
|
|
585
|
-
buttonEl = item;
|
|
586
|
-
break;
|
|
587
|
-
}
|
|
588
|
-
}
|
|
589
|
-
if (!buttonEl) throw new Error(`Cannot find item in button group with text: ${value}`);
|
|
590
|
-
await click(buttonEl, this.driver);
|
|
591
|
-
}
|
|
592
|
-
};
|
|
593
|
-
|
|
594
|
-
// src/pageObjects/elements/Editors/BooleanSelector.ts
|
|
595
|
-
var BooleanSelector = class extends ButtonGroup {
|
|
596
|
-
// @ts-ignore
|
|
597
|
-
async getValue() {
|
|
598
|
-
const value = await super.getValue();
|
|
599
|
-
return value === "null" ? null : value === "1" ? 1 : 0;
|
|
600
|
-
}
|
|
601
|
-
// @ts-ignore
|
|
602
|
-
async setValue(value) {
|
|
603
|
-
const val = value == null ? "null" : value ? "1" : "0";
|
|
604
|
-
await super.setValue(val);
|
|
605
|
-
}
|
|
606
|
-
};
|
|
607
|
-
|
|
608
|
-
// src/pageObjects/elements/Editors/Date/SingleDateEditor.ts
|
|
609
|
-
import { By as By10 } from "selenium-webdriver";
|
|
610
|
-
|
|
611
|
-
// src/pageObjects/elements/Editors/Date/BaseDateEditor.ts
|
|
612
|
-
import { By as By9, Key as Key3 } from "selenium-webdriver";
|
|
613
|
-
|
|
614
|
-
// src/pageObjects/elements/Editors/Date/utils.ts
|
|
615
|
-
var formatDMYDate = (date, isTimeAllowed = false) => {
|
|
616
|
-
const [year, month, day] = date.toISOString().split("T")[0].split("-");
|
|
617
|
-
if (!isTimeAllowed) {
|
|
618
|
-
return `${day}${month}${year}`;
|
|
619
|
-
}
|
|
620
|
-
const hours = String(date.getHours()).padStart(2, "0");
|
|
621
|
-
const minutes = String(date.getMinutes()).padStart(2, "0");
|
|
622
|
-
return `${day}${month}${year}${hours}${minutes}`;
|
|
623
|
-
};
|
|
624
|
-
var formatToDateTime = (dateString) => {
|
|
625
|
-
const [datePart, timePart] = dateString.split("T");
|
|
626
|
-
const [year, month, day] = datePart.split("-").map(Number);
|
|
627
|
-
const [hours, minutes] = timePart.split(":").map(Number);
|
|
628
|
-
return new Date(year, month - 1, day, hours, minutes, 0, 0);
|
|
629
|
-
};
|
|
630
|
-
var getYearMonthDay = (date) => {
|
|
631
|
-
const [year, month, day] = date.toISOString().split("T")[0].split("-");
|
|
632
|
-
return { year: +year, month: +month, day: +day };
|
|
633
|
-
};
|
|
634
|
-
|
|
635
|
-
// src/pageObjects/elements/Editors/Date/DateSelectMode.ts
|
|
636
|
-
var DateSelectMode = class {
|
|
637
|
-
static isWeek(t) {
|
|
638
|
-
return t === "week" /* Week */;
|
|
639
|
-
}
|
|
640
|
-
static isMonth(t) {
|
|
641
|
-
return t === "month" /* Month */;
|
|
642
|
-
}
|
|
643
|
-
static isWeekOrMonth(t) {
|
|
644
|
-
return this.isWeek(t) || this.isMonth(t);
|
|
645
|
-
}
|
|
646
|
-
};
|
|
647
|
-
|
|
648
|
-
// src/pageObjects/elements/Editors/Date/Calendar.ts
|
|
649
|
-
import { By as By8 } from "selenium-webdriver";
|
|
650
|
-
var BTN_CALENDAR_POPOVER_OPEN_SELECTOR = "calendar-popover-open-button";
|
|
651
|
-
var BTN_CALENDAR_POPOVER_DATE_FROM_INPUT_SELECTOR = "DateRange__inputs-item--dateFrom";
|
|
652
|
-
var BTN_CALENDAR_POPOVER_DATE_TO_INPUT_SELECTOR = "DateRange__inputs-item--dateTo";
|
|
653
|
-
var BTN_SAVE_SELECTOR = "DateRange__button-save";
|
|
654
|
-
var CALENDAR_CAPTION_SELECTOR = "dx-calendar-caption-button";
|
|
655
|
-
var CALENDAR_CELL_SELECTOR = "dx-calendar-cell";
|
|
656
|
-
var CALENDAR_PREVIOUS_SELECTOR = "dx-calendar-navigator-previous-month";
|
|
657
|
-
var CALENDAR_NEXT_SELECTOR = "dx-calendar-navigator-next-month";
|
|
658
|
-
var TEXT_EDITOR_SELECTOR = "dx-texteditor-input";
|
|
659
|
-
var movesToCalendarEndForWeek = 3;
|
|
660
|
-
var movesToCalendarEndForMonth = 1;
|
|
661
|
-
var Calendar = class extends AbstractElementWithParent {
|
|
662
|
-
_parentCssSelector;
|
|
663
|
-
constructor({ parentCssSelector, dateFieldDataTestID, driver }) {
|
|
664
|
-
super("", byTestIdCssSelector(`${dateFieldDataTestID}-calendar-popover`), driver);
|
|
665
|
-
this._parentCssSelector = parentCssSelector;
|
|
666
|
-
}
|
|
667
|
-
async init() {
|
|
668
|
-
const dateField = await this.driver.findElement(By8.css(this._parentCssSelector));
|
|
669
|
-
const button = await dateField.findElement(By8.css(`.${BTN_CALENDAR_POPOVER_OPEN_SELECTOR}`));
|
|
670
|
-
await click(button, this.driver);
|
|
671
|
-
}
|
|
672
|
-
/**
|
|
673
|
-
* Переходимо на найвищий рівень календаря
|
|
674
|
-
*/
|
|
675
|
-
async moveToCalendarEnd(count) {
|
|
676
|
-
while (count >= 0) {
|
|
677
|
-
const calendarElement = await this.getElement();
|
|
678
|
-
const button = await calendarElement.findElement(By8.css(`.${CALENDAR_CAPTION_SELECTOR}`));
|
|
679
|
-
await click(button, this.driver);
|
|
680
|
-
count--;
|
|
681
|
-
}
|
|
682
|
-
}
|
|
683
|
-
/**
|
|
684
|
-
* Пошук та клік по правильному періоду (2010-2019, 2020-2029, і т.д.)
|
|
685
|
-
*/
|
|
686
|
-
async choosePeriodForYear(targetYear) {
|
|
687
|
-
let found = false;
|
|
688
|
-
while (!found) {
|
|
689
|
-
const calendarElement = await this.getElement();
|
|
690
|
-
const periodCells = await calendarElement.findElements(By8.css(`.${CALENDAR_CELL_SELECTOR} span`));
|
|
691
|
-
for (const cell of periodCells) {
|
|
692
|
-
const text = await cell.getText();
|
|
693
|
-
if (text) {
|
|
694
|
-
const [start, end] = text.split("-").map(Number);
|
|
695
|
-
if (targetYear >= start && targetYear <= end) {
|
|
696
|
-
await click(cell, this.driver);
|
|
697
|
-
found = true;
|
|
698
|
-
break;
|
|
699
|
-
}
|
|
700
|
-
}
|
|
701
|
-
}
|
|
702
|
-
if (!found) {
|
|
703
|
-
const firstPeriod = await periodCells[0].getText();
|
|
704
|
-
const [start] = firstPeriod.split("-").map(Number);
|
|
705
|
-
if (targetYear < start) {
|
|
706
|
-
const prevBtn = await calendarElement.findElement(By8.css(`.${CALENDAR_PREVIOUS_SELECTOR}`));
|
|
707
|
-
await click(prevBtn, this.driver);
|
|
708
|
-
} else {
|
|
709
|
-
const nextBtn = await calendarElement.findElement(By8.css(`.${CALENDAR_NEXT_SELECTOR}`));
|
|
710
|
-
await click(nextBtn, this.driver);
|
|
711
|
-
}
|
|
712
|
-
}
|
|
713
|
-
}
|
|
714
|
-
}
|
|
715
|
-
/**
|
|
716
|
-
* Пошук та клік по конкретному року з навігацією
|
|
717
|
-
*/
|
|
718
|
-
async chooseYear(targetYear) {
|
|
719
|
-
let found = false;
|
|
720
|
-
while (!found) {
|
|
721
|
-
const calendarElement = await this.getElement();
|
|
722
|
-
const yearCells = await calendarElement.findElements(By8.css(`.${CALENDAR_CELL_SELECTOR} span`));
|
|
723
|
-
for (const cell of yearCells) {
|
|
724
|
-
const text = await cell.getText();
|
|
725
|
-
const cellYear = Number(text);
|
|
726
|
-
if (!isNaN(cellYear) && cellYear === targetYear) {
|
|
727
|
-
await click(cell, this.driver);
|
|
728
|
-
found = true;
|
|
729
|
-
break;
|
|
730
|
-
}
|
|
731
|
-
}
|
|
732
|
-
if (!found) {
|
|
733
|
-
const firstYearText = await yearCells[0].getText();
|
|
734
|
-
const lastYearText = await yearCells[yearCells.length - 1].getText();
|
|
735
|
-
const firstYear = Number(firstYearText);
|
|
736
|
-
const lastYear = Number(lastYearText);
|
|
737
|
-
if (targetYear < firstYear) {
|
|
738
|
-
const prevBtn = await calendarElement.findElement(By8.css(`.${CALENDAR_PREVIOUS_SELECTOR}`));
|
|
739
|
-
await click(prevBtn, this.driver);
|
|
740
|
-
} else if (targetYear > lastYear) {
|
|
741
|
-
const nextBtn = await calendarElement.findElement(By8.css(`.${CALENDAR_NEXT_SELECTOR}`));
|
|
742
|
-
await click(nextBtn, this.driver);
|
|
743
|
-
} else {
|
|
744
|
-
throw new Error(`Year ${targetYear} is not in the visible range but navigation failed`);
|
|
745
|
-
}
|
|
746
|
-
}
|
|
747
|
-
}
|
|
748
|
-
}
|
|
749
|
-
/**
|
|
750
|
-
* Пошук та клік по конкретному місяцю
|
|
751
|
-
*/
|
|
752
|
-
async chooseMonth(year, month) {
|
|
753
|
-
const calendarElement = await this.getElement();
|
|
754
|
-
const monthCells = await calendarElement.findElements(By8.css(`.${CALENDAR_CELL_SELECTOR}`));
|
|
755
|
-
for (const cell of monthCells) {
|
|
756
|
-
const dataValue = await cell.getAttribute("data-value");
|
|
757
|
-
if (dataValue) {
|
|
758
|
-
const [cellYear, cellMonth] = dataValue.split("/").map(Number);
|
|
759
|
-
if (cellYear === year && cellMonth === month) {
|
|
760
|
-
await click(cell, this.driver);
|
|
761
|
-
return;
|
|
762
|
-
}
|
|
763
|
-
}
|
|
764
|
-
}
|
|
765
|
-
throw new Error(`Month ${month} for year ${year} not found`);
|
|
766
|
-
}
|
|
767
|
-
/**
|
|
768
|
-
* Пошук та клік по конкретному дню (ігноруємо дні з іншого місяця)
|
|
769
|
-
*/
|
|
770
|
-
async chooseDay(year, month, day) {
|
|
771
|
-
const calendarElement = await this.getElement();
|
|
772
|
-
const dayCells = await calendarElement.findElements(By8.css(`.${CALENDAR_CELL_SELECTOR}`));
|
|
773
|
-
for (const cell of dayCells) {
|
|
774
|
-
const dataValue = await cell.getAttribute("data-value");
|
|
775
|
-
if (dataValue) {
|
|
776
|
-
const [cellYear, cellMonth, cellDay] = dataValue.split("/").map(Number);
|
|
777
|
-
if (cellYear === year && cellMonth === month && cellDay === day) {
|
|
778
|
-
await click(cell, this.driver);
|
|
779
|
-
return;
|
|
780
|
-
}
|
|
781
|
-
}
|
|
782
|
-
}
|
|
783
|
-
throw new Error(`Day ${day}.${month}.${year} not found`);
|
|
784
|
-
}
|
|
785
|
-
/**
|
|
786
|
-
* Встановлення дати для тижня
|
|
787
|
-
*/
|
|
788
|
-
async setValueForWeek(date) {
|
|
789
|
-
const { year, month, day } = getYearMonthDay(date);
|
|
790
|
-
await this.moveToCalendarEnd(movesToCalendarEndForWeek);
|
|
791
|
-
await this.choosePeriodForYear(year);
|
|
792
|
-
await this.chooseYear(year);
|
|
793
|
-
await this.chooseMonth(year, month);
|
|
794
|
-
await this.chooseDay(year, month, day);
|
|
795
|
-
await this.save();
|
|
796
|
-
}
|
|
797
|
-
/**
|
|
798
|
-
* Встановлення дати для місяця
|
|
799
|
-
*/
|
|
800
|
-
async setValueForMonth(date) {
|
|
801
|
-
const { year, month } = getYearMonthDay(date);
|
|
802
|
-
await this.moveToCalendarEnd(movesToCalendarEndForMonth);
|
|
803
|
-
await this.chooseYear(year);
|
|
804
|
-
await this.chooseMonth(year, month);
|
|
805
|
-
await this.save();
|
|
806
|
-
}
|
|
807
|
-
async getDateFromInput() {
|
|
808
|
-
const calendarPopoverElement = await this.getElement();
|
|
809
|
-
return calendarPopoverElement.findElement(
|
|
810
|
-
By8.css(`.${BTN_CALENDAR_POPOVER_DATE_FROM_INPUT_SELECTOR} .${TEXT_EDITOR_SELECTOR}`)
|
|
811
|
-
);
|
|
812
|
-
}
|
|
813
|
-
async getDateToInput() {
|
|
814
|
-
const calendarPopoverElement = await this.getElement();
|
|
815
|
-
return calendarPopoverElement.findElement(
|
|
816
|
-
By8.css(`.${BTN_CALENDAR_POPOVER_DATE_TO_INPUT_SELECTOR} .${TEXT_EDITOR_SELECTOR}`)
|
|
817
|
-
);
|
|
818
|
-
}
|
|
819
|
-
async save() {
|
|
820
|
-
const btnOk = await this.driver.findElement(By8.css(`.${BTN_SAVE_SELECTOR}`));
|
|
821
|
-
await click(btnOk, this.driver);
|
|
822
|
-
}
|
|
823
|
-
};
|
|
824
|
-
|
|
825
|
-
// src/pageObjects/elements/Editors/Date/BaseDateEditor.ts
|
|
826
|
-
var DATETIME_ALLOWED_SELECTOR = "dx-datebox-datetime";
|
|
827
|
-
var BaseDateEditor = class extends AbstractDXEditorWithInput {
|
|
828
|
-
constructor(parentCssSelector, elementCssSelector, driver) {
|
|
829
|
-
super(parentCssSelector, elementCssSelector, driver);
|
|
830
|
-
this.setClearStrategy(new InputClearStrategy());
|
|
831
|
-
}
|
|
832
|
-
async getIsAllowedTime() {
|
|
833
|
-
const dateField = await this.driver.findElement(By9.css(`${this.getFullCssSelector()}`));
|
|
834
|
-
const classString = await dateField.getAttribute("class");
|
|
835
|
-
return classString.includes(DATETIME_ALLOWED_SELECTOR);
|
|
836
|
-
}
|
|
837
|
-
async initCalendar() {
|
|
838
|
-
const dateFieldDataTestID = await this.getDataTestId();
|
|
839
|
-
const calendar = new Calendar({
|
|
840
|
-
parentCssSelector: this.getFullCssSelector(),
|
|
841
|
-
dateFieldDataTestID,
|
|
842
|
-
driver: this.driver
|
|
843
|
-
});
|
|
844
|
-
await calendar.init();
|
|
845
|
-
return calendar;
|
|
846
|
-
}
|
|
847
|
-
async setValueForWeek(value) {
|
|
848
|
-
const calendar = await this.initCalendar();
|
|
849
|
-
await calendar.setValueForWeek(value);
|
|
850
|
-
}
|
|
851
|
-
async setValueForMonth(value) {
|
|
852
|
-
const calendar = await this.initCalendar();
|
|
853
|
-
await calendar.setValueForMonth(value);
|
|
854
|
-
}
|
|
855
|
-
async setArrayValue(value) {
|
|
856
|
-
const calendar = await this.initCalendar();
|
|
857
|
-
const dateFromInput = await calendar.getDateFromInput();
|
|
858
|
-
const dateToInput = await calendar.getDateToInput();
|
|
859
|
-
await this.setSingleValue(value[0], dateFromInput);
|
|
860
|
-
await this.setSingleValue(value[1], dateToInput);
|
|
861
|
-
await calendar.save();
|
|
862
|
-
}
|
|
863
|
-
async setSingleValue(value, inputEl) {
|
|
864
|
-
const dateMode = await this.getDataDateMode();
|
|
865
|
-
if (DateSelectMode.isWeek(dateMode)) {
|
|
866
|
-
await this.setValueForWeek(value);
|
|
867
|
-
return;
|
|
868
|
-
}
|
|
869
|
-
if (DateSelectMode.isMonth(dateMode)) {
|
|
870
|
-
await this.setValueForMonth(value);
|
|
871
|
-
return;
|
|
872
|
-
}
|
|
873
|
-
const actions = this.driver.actions({ async: true });
|
|
874
|
-
const isTimeAllowed = await this.getIsAllowedTime();
|
|
875
|
-
const formattedDate = formatDMYDate(value, isTimeAllowed);
|
|
876
|
-
await click(inputEl, this.driver);
|
|
877
|
-
await actions.move({ origin: inputEl }).sendKeys(Key3.HOME).perform();
|
|
878
|
-
await actions.move({ origin: inputEl }).sendKeys(formattedDate, Key3.ENTER).perform();
|
|
879
|
-
}
|
|
880
|
-
async setDateValue(value) {
|
|
881
|
-
if (Array.isArray(value)) {
|
|
882
|
-
await this.setArrayValue(value);
|
|
883
|
-
} else {
|
|
884
|
-
await this.setSingleValue(value, await this.getInputElement());
|
|
885
|
-
}
|
|
886
|
-
}
|
|
887
|
-
};
|
|
888
|
-
|
|
889
|
-
// src/pageObjects/elements/Editors/Date/SingleDateEditor.ts
|
|
890
|
-
var SingleDateEditor = class extends BaseDateEditor {
|
|
891
|
-
constructor(parentCssSelector, elementCssSelector, driver) {
|
|
892
|
-
super(parentCssSelector, elementCssSelector, driver);
|
|
893
|
-
this.setClearStrategy(new InputClearStrategy());
|
|
894
|
-
}
|
|
895
|
-
async getDateElement() {
|
|
896
|
-
return this.driver.findElement(By10.css(this.getFullCssSelector() + " .dx-dropdowneditor-input-wrapper input[type=hidden]"));
|
|
897
|
-
}
|
|
898
|
-
async getDateValue() {
|
|
899
|
-
const inputEl = await this.getDateElement();
|
|
900
|
-
return inputEl.getAttribute("value");
|
|
901
|
-
}
|
|
902
|
-
async getValue() {
|
|
903
|
-
const value = await this.getDateValue();
|
|
904
|
-
const isTimeAllowed = await this.getIsAllowedTime();
|
|
905
|
-
if (isTimeAllowed) {
|
|
906
|
-
return value == "" ? null : formatToDateTime(value);
|
|
907
|
-
}
|
|
908
|
-
return value == "" ? null : new Date(value);
|
|
909
|
-
}
|
|
910
|
-
setValue(value) {
|
|
911
|
-
if (typeof value === "object") {
|
|
912
|
-
return this.setDateValue(value);
|
|
913
|
-
}
|
|
914
|
-
throw new Error(`Value is incorrect. It should be Object`);
|
|
915
|
-
}
|
|
916
|
-
};
|
|
917
|
-
|
|
918
|
-
// src/pageObjects/elements/Editors/Date/DateRangeEditor.ts
|
|
919
|
-
import { By as By11 } from "selenium-webdriver";
|
|
920
|
-
var DateRangeEditor = class extends BaseDateEditor {
|
|
921
|
-
constructor(parentCssSelector, elementCssSelector, driver) {
|
|
922
|
-
super(parentCssSelector, elementCssSelector, driver);
|
|
923
|
-
this.setClearStrategy(new InputClearStrategy());
|
|
924
|
-
}
|
|
925
|
-
async getDateElement() {
|
|
926
|
-
return this.driver.findElement(By11.css(this.getFullCssSelector() + " .dx-texteditor-input"));
|
|
927
|
-
}
|
|
928
|
-
async getDateValue() {
|
|
929
|
-
const inputEl = await this.getDateElement();
|
|
930
|
-
const dateFromStr = await inputEl.getAttribute("datefrom");
|
|
931
|
-
const dateToStr = await inputEl.getAttribute("dateto");
|
|
932
|
-
const dateFrom = new Date(dateFromStr);
|
|
933
|
-
const dateTo = new Date(dateToStr);
|
|
934
|
-
return [dateFrom, dateTo];
|
|
935
|
-
}
|
|
936
|
-
async getValue() {
|
|
937
|
-
const values = await this.getDateValue();
|
|
938
|
-
return !values.length ? null : values;
|
|
939
|
-
}
|
|
940
|
-
setValue(value) {
|
|
941
|
-
if (typeof value === "object") {
|
|
942
|
-
return this.setDateValue(value);
|
|
943
|
-
}
|
|
944
|
-
throw new Error(`Value is incorrect. It should be Object`);
|
|
945
|
-
}
|
|
946
|
-
};
|
|
947
|
-
|
|
948
|
-
// src/pageObjects/elements/Editors/Date/DateEditor.ts
|
|
949
|
-
var DateEditor = class extends AbstractDXEditorWithInput {
|
|
950
|
-
editorInstance = null;
|
|
951
|
-
async init() {
|
|
952
|
-
if (this.editorInstance) {
|
|
953
|
-
return this.editorInstance;
|
|
954
|
-
}
|
|
955
|
-
await this.setEditorInstance();
|
|
956
|
-
}
|
|
957
|
-
async setEditorInstance() {
|
|
958
|
-
const { parentCssSelector, elementCssSelector, driver } = this;
|
|
959
|
-
const elementInstance = new AbstractFormElement(parentCssSelector, elementCssSelector, driver);
|
|
960
|
-
const classString = await elementInstance.getClasses();
|
|
961
|
-
switch (true) {
|
|
962
|
-
case classString.includes("date-control" /* Date */):
|
|
963
|
-
this.editorInstance = new SingleDateEditor(parentCssSelector, elementCssSelector, driver);
|
|
964
|
-
break;
|
|
965
|
-
case classString.includes("single-date-range-control" /* SingleDateRange */):
|
|
966
|
-
this.editorInstance = new DateRangeEditor(parentCssSelector, elementCssSelector, driver);
|
|
967
|
-
break;
|
|
968
|
-
default:
|
|
969
|
-
this.editorInstance = new SingleDateEditor(parentCssSelector, elementCssSelector, driver);
|
|
970
|
-
}
|
|
971
|
-
}
|
|
972
|
-
async setValue(value) {
|
|
973
|
-
await this.init();
|
|
974
|
-
await this.editorInstance.setValue(value);
|
|
975
|
-
await this.setEditorInstance();
|
|
976
|
-
}
|
|
977
|
-
async getValue() {
|
|
978
|
-
await this.init();
|
|
979
|
-
return this.editorInstance.getValue();
|
|
980
|
-
}
|
|
981
|
-
};
|
|
982
|
-
|
|
983
|
-
// src/pageObjects/elements/Editors/HeaderFilterDictionary.ts
|
|
984
|
-
import { By as By12, Key as Key4 } from "selenium-webdriver";
|
|
985
|
-
var TAGS_SELECTOR2 = ".dx-tag .tag-text";
|
|
986
|
-
var DX_TAG_CONTAINER2 = "dx-tag-container";
|
|
987
|
-
var DX_TEXTEDITOR_EMPTY3 = "dx-texteditor-empty";
|
|
988
|
-
var CUSTOM_OPTION_LIST_SELECTOR = "custom-list";
|
|
989
|
-
var SELECT_BOX_OPTION_TEXT_CONTAINER_CLASS2 = "d5-multi-select-item";
|
|
990
|
-
var TAG_BOX_LIST_ITEM_SELECTOR = '.dx-overlay-wrapper .dx-list-item[aria-selected="true"]';
|
|
991
|
-
var combinedOptionHeaderFilterDictValueXpath = (value) => `//div[contains(@class, '${SELECT_BOX_OPTION_TEXT_CONTAINER_CLASS2}') and contains(text(), '${value}')]`;
|
|
992
|
-
var dropDownHeaderFilterDictionaryOptionClick = async (optionValue, driver, dataTEST = "", delay = true) => {
|
|
993
|
-
let err = null;
|
|
994
|
-
try {
|
|
995
|
-
const calendarPopoverSelector = byTestIdCssSelector(`${dataTEST}`);
|
|
996
|
-
await withCustomTimeouts_default({
|
|
997
|
-
driver,
|
|
998
|
-
timeout: delay ? void 0 : 600,
|
|
999
|
-
callback: async () => {
|
|
1000
|
-
const calendarPopoverElement = await driver.findElement(By12.css(calendarPopoverSelector));
|
|
1001
|
-
const customOptionList = calendarPopoverElement.findElement(By12.css(`.${CUSTOM_OPTION_LIST_SELECTOR}`));
|
|
1002
|
-
const optElement = await customOptionList.findElement(By12.xpath(combinedOptionHeaderFilterDictValueXpath(optionValue)));
|
|
1003
|
-
await click(optElement, driver);
|
|
1004
|
-
}
|
|
1005
|
-
});
|
|
1006
|
-
} catch (e) {
|
|
1007
|
-
err = new Error(`Item not found: "${optionValue}"`);
|
|
1008
|
-
}
|
|
1009
|
-
if (err)
|
|
1010
|
-
throw err;
|
|
1011
|
-
};
|
|
1012
|
-
var HeaderFilterDictionary = class extends AbstractDXEditorWithInput {
|
|
1013
|
-
constructor(parentCssSelector, elementCssSelector, driver) {
|
|
1014
|
-
super(parentCssSelector, elementCssSelector, driver);
|
|
1015
|
-
this.setClearStrategy(new ClearButtonStrategy(this.getFullCssSelector(), this.driver));
|
|
1016
|
-
}
|
|
1017
|
-
async setTagBoxInputValue(values) {
|
|
1018
|
-
const lastElement = values[values.length - 1];
|
|
1019
|
-
const inputEl = await this.getInputElement();
|
|
1020
|
-
await inputEl.click();
|
|
1021
|
-
for (const value of values) {
|
|
1022
|
-
await this.selectOption(inputEl, value, lastElement);
|
|
1023
|
-
}
|
|
1024
|
-
}
|
|
1025
|
-
async waitOptionSelection() {
|
|
1026
|
-
await fixElementStaleError(By12.css(TAG_BOX_LIST_ITEM_SELECTOR), this.driver);
|
|
1027
|
-
}
|
|
1028
|
-
async selectOption(inputEl, value, lastElement) {
|
|
1029
|
-
try {
|
|
1030
|
-
await inputEl.sendKeys(value);
|
|
1031
|
-
const dataTEST = await this.getDataTestId();
|
|
1032
|
-
await dropDownHeaderFilterDictionaryOptionClick(value, this.driver, dataTEST);
|
|
1033
|
-
const textLength = await inputEl.getAttribute("value").then((value2) => value2.length);
|
|
1034
|
-
for (let i = 0; i < textLength; i++) {
|
|
1035
|
-
await inputEl.sendKeys(Key4.BACK_SPACE);
|
|
1036
|
-
}
|
|
1037
|
-
} catch (error) {
|
|
1038
|
-
throw error;
|
|
1039
|
-
}
|
|
1040
|
-
await this.waitOptionSelection();
|
|
1041
|
-
if (value !== lastElement) {
|
|
1042
|
-
await inputEl.clear();
|
|
1043
|
-
}
|
|
1044
|
-
}
|
|
1045
|
-
async getHeaderFilterDictionaryInputValue() {
|
|
1046
|
-
if (await this.isHeaderFilterDictionaryEmpty()) {
|
|
1047
|
-
return [];
|
|
1048
|
-
}
|
|
1049
|
-
const tags = await this.driver.findElements(
|
|
1050
|
-
By12.css(`${this.getFullCssSelector()} .${DX_TAG_CONTAINER2} ${TAGS_SELECTOR2}`)
|
|
1051
|
-
);
|
|
1052
|
-
const values = [];
|
|
1053
|
-
for (const tag of tags) {
|
|
1054
|
-
values.push(await tag.getAttribute("textContent"));
|
|
1055
|
-
}
|
|
1056
|
-
return values;
|
|
1057
|
-
}
|
|
1058
|
-
async isHeaderFilterDictionaryEmpty() {
|
|
1059
|
-
const classAttribute = await this.getClasses();
|
|
1060
|
-
return classAttribute.includes(DX_TEXTEDITOR_EMPTY3);
|
|
1061
|
-
}
|
|
1062
|
-
async getValue() {
|
|
1063
|
-
const value = await this.getHeaderFilterDictionaryInputValue();
|
|
1064
|
-
return value.length ? value : null;
|
|
1065
|
-
}
|
|
1066
|
-
async setValue(values) {
|
|
1067
|
-
if (!Array.isArray(values)) {
|
|
1068
|
-
values = [values];
|
|
1069
|
-
}
|
|
1070
|
-
await this.setTagBoxInputValue(values);
|
|
1071
|
-
}
|
|
1072
|
-
};
|
|
1073
|
-
|
|
1074
|
-
// src/pageObjects/elements/Editors/editorFactory.ts
|
|
1075
|
-
var editorFactory = async (parentCssSelector, elementCssSelector, driver) => {
|
|
1076
|
-
const elementInstance = new AbstractFormElement(parentCssSelector, elementCssSelector, driver);
|
|
1077
|
-
const classSting = await elementInstance.getClasses();
|
|
1078
|
-
if ((classSting.includes("text-control" /* Text */) || classSting.includes("text-area-control" /* TextArea */)) && !classSting.includes("single-date-range-control" /* SingleDateRange */))
|
|
1079
|
-
return new TextEditor(parentCssSelector, elementCssSelector, driver);
|
|
1080
|
-
if (classSting.includes("number-control" /* Number */)) return new NumberEditor(parentCssSelector, elementCssSelector, driver);
|
|
1081
|
-
if (classSting.includes("check-box" /* CheckBox */)) return new CheckBox(parentCssSelector, elementCssSelector, driver);
|
|
1082
|
-
if (classSting.includes("multi-select-control" /* Multiselect */)) return new TagBox(parentCssSelector, elementCssSelector, driver);
|
|
1083
|
-
if (classSting.includes("select-control" /* Select */))
|
|
1084
|
-
return new SelectBoxEditor(parentCssSelector, elementCssSelector, driver);
|
|
1085
|
-
if (classSting.includes("switch-control" /* Switch */)) return new SwitchEditor(parentCssSelector, elementCssSelector, driver);
|
|
1086
|
-
if (classSting.includes("date-control" /* Date */) || classSting.includes("single-date-range-control" /* SingleDateRange */)) {
|
|
1087
|
-
return new DateEditor(parentCssSelector, elementCssSelector, driver);
|
|
1088
|
-
}
|
|
1089
|
-
if (classSting.includes("buttons-group" /* BooleanSelector */))
|
|
1090
|
-
return new BooleanSelector(parentCssSelector, elementCssSelector, driver);
|
|
1091
|
-
if (classSting.includes("button-group-field" /* ButtonGroup */))
|
|
1092
|
-
return new ButtonGroup(parentCssSelector, elementCssSelector, driver);
|
|
1093
|
-
if (classSting.includes("header-filter-dictionary" /* HeaderFilterDictionary */))
|
|
1094
|
-
return new HeaderFilterDictionary(parentCssSelector, elementCssSelector, driver);
|
|
1095
|
-
throw new Error("Unknown type of editor. Please write ticket to the support");
|
|
1096
|
-
};
|
|
1097
|
-
|
|
1098
|
-
// src/utils/createDataTestId.ts
|
|
1099
|
-
function createDataTestId(formName, itemType, itemName) {
|
|
1100
|
-
return `${formName}-${itemType}-${itemName}`;
|
|
1101
|
-
}
|
|
1102
|
-
function createFieldTestId(formName, itemName) {
|
|
1103
|
-
return createDataTestId(formName, "form_field" /* FORM_FIELD */, itemName);
|
|
1104
|
-
}
|
|
1105
|
-
function createGroupTestId(formName, itemName) {
|
|
1106
|
-
return createDataTestId(formName, "group" /* GROUP */, itemName);
|
|
1107
|
-
}
|
|
1108
|
-
function createFilterTestId(formName, itemName, layout) {
|
|
1109
|
-
return createDataTestId(formName, "filter" /* FILTER */, itemName) + `-${layout}`;
|
|
1110
|
-
}
|
|
1111
|
-
function createDocFilterTestId(formName, itemName) {
|
|
1112
|
-
return createFilterTestId(formName, itemName, "dock-panel-filter" /* DOCK_PANEL */);
|
|
1113
|
-
}
|
|
1114
|
-
function createHeaderFilterTestId(formName, itemName) {
|
|
1115
|
-
return createFilterTestId(formName, itemName, "header-filter" /* HEADER_FILTER */);
|
|
1116
|
-
}
|
|
1117
|
-
function createLayoutFilterTestId(formName, itemName) {
|
|
1118
|
-
return createFilterTestId(formName, itemName, "layout-filter" /* LAYOUT */);
|
|
1119
|
-
}
|
|
1120
|
-
function createTableId(formName) {
|
|
1121
|
-
return `${"table" /* TABLE */}-${formName}`;
|
|
1122
|
-
}
|
|
1123
|
-
function createFormButtonTestId(formName, itemName) {
|
|
1124
|
-
return createDataTestId(formName, "button" /* BUTTON */, itemName);
|
|
1125
|
-
}
|
|
1126
|
-
function createSubSystemTestId(itemName) {
|
|
1127
|
-
return `${"subsystem-item" /* SUBSYSTEM_ITEM */}-${itemName}`;
|
|
1128
|
-
}
|
|
1129
|
-
function createEditorButtonTestId(itemName) {
|
|
1130
|
-
return `${"editor-button" /* EDITOR_BUTTON */}-${itemName}`;
|
|
1131
|
-
}
|
|
1132
|
-
|
|
1133
|
-
// src/pageObjects/elements/EditorButton.ts
|
|
1134
|
-
var EditorButton = class extends AbstractElementWithParent {
|
|
1135
|
-
name;
|
|
1136
|
-
constructor(parentCssSelector, name, driver) {
|
|
1137
|
-
super(parentCssSelector, byTestIdCssSelector(createEditorButtonTestId(name)), driver);
|
|
1138
|
-
this.name = name;
|
|
1139
|
-
}
|
|
1140
|
-
buttonNotDisplayedError() {
|
|
1141
|
-
return `Editor Button ${this.name} cannot be clicked. It is not displayed or it is disabled`;
|
|
1142
|
-
}
|
|
1143
|
-
async click() {
|
|
1144
|
-
const button = await this.getElement();
|
|
1145
|
-
await waitElementIsClickable_default({
|
|
1146
|
-
element: button,
|
|
1147
|
-
errorMessage: this.buttonNotDisplayedError(),
|
|
1148
|
-
driver: this.driver
|
|
1149
|
-
});
|
|
1150
|
-
await click(button, this.driver);
|
|
1151
|
-
}
|
|
1152
|
-
async isDisplayed() {
|
|
1153
|
-
try {
|
|
1154
|
-
const button = await this.getElement();
|
|
1155
|
-
return await button.isDisplayed();
|
|
1156
|
-
} catch (error) {
|
|
1157
|
-
return false;
|
|
1158
|
-
}
|
|
1159
|
-
}
|
|
1160
|
-
};
|
|
1161
|
-
|
|
1162
|
-
// src/pageObjects/elements/AbstractEditor.ts
|
|
1163
|
-
var AbstractEditor = class extends AbstractElementWithParent {
|
|
1164
|
-
editor;
|
|
1165
|
-
constructor(parentCssSelector, elementCssSelector, driver) {
|
|
1166
|
-
super(parentCssSelector, elementCssSelector, driver);
|
|
1167
|
-
}
|
|
1168
|
-
async initEditor() {
|
|
1169
|
-
if (!this.editor) {
|
|
1170
|
-
this.editor = await editorFactory(this.parentCssSelector, this.elementCssSelector, this.driver);
|
|
1171
|
-
}
|
|
1172
|
-
}
|
|
1173
|
-
/**
|
|
1174
|
-
* Возвращает значение в поле
|
|
1175
|
-
* @example
|
|
1176
|
-
* expect(await formEdit.field('NumberFld').getValue()).toBe(10);
|
|
1177
|
-
* expect(await formEdit.field('TextFld').getValue()).toBe('TestValue');
|
|
1178
|
-
*/
|
|
1179
|
-
async getValue() {
|
|
1180
|
-
await this.initEditor();
|
|
1181
|
-
return this.editor.getValue();
|
|
1182
|
-
}
|
|
1183
|
-
/**
|
|
1184
|
-
* Устанавливает значение в поле
|
|
1185
|
-
* @example
|
|
1186
|
-
* await formEdit.field('NumberFld').setValue(123);
|
|
1187
|
-
* await formEdit.field('TextFld').setValue('TestValue');
|
|
1188
|
-
*/
|
|
1189
|
-
async setValue(value) {
|
|
1190
|
-
await this.initEditor();
|
|
1191
|
-
return this.editor.setValue(value);
|
|
1192
|
-
}
|
|
1193
|
-
/**
|
|
1194
|
-
* Очищает значение в поле
|
|
1195
|
-
* @example
|
|
1196
|
-
* await formEdit.field('NumberFld').clear();
|
|
1197
|
-
*/
|
|
1198
|
-
async clear() {
|
|
1199
|
-
await this.initEditor();
|
|
1200
|
-
if (!this.editor.clear) {
|
|
1201
|
-
throw new Error("The clear method is not available for this field type.");
|
|
1202
|
-
}
|
|
1203
|
-
return this.editor.clear();
|
|
1204
|
-
}
|
|
1205
|
-
/**
|
|
1206
|
-
* Удаляет тег по переданному тексту
|
|
1207
|
-
* @example
|
|
1208
|
-
* await formEdit.field('TagBox').remove('test');
|
|
1209
|
-
*/
|
|
1210
|
-
async remove(itemText) {
|
|
1211
|
-
await this.initEditor();
|
|
1212
|
-
if (!this.editor.remove) {
|
|
1213
|
-
throw new Error("This method is only available for the TagBox field.");
|
|
1214
|
-
}
|
|
1215
|
-
return this.editor.remove(itemText);
|
|
1216
|
-
}
|
|
1217
|
-
/**
|
|
1218
|
-
* Возвращает значение true|false в зависимости readOnly поле или нет
|
|
1219
|
-
* @example
|
|
1220
|
-
* expect(await formEdit.field('NumberFld').isReadonly()).toBe(true);
|
|
1221
|
-
* expect(await formEdit.field('TextFld').isReadonly()).toBe(false);
|
|
1222
|
-
*/
|
|
1223
|
-
async isReadonly() {
|
|
1224
|
-
await this.initEditor();
|
|
1225
|
-
return this.editor.isReadonly();
|
|
1226
|
-
}
|
|
1227
|
-
/**
|
|
1228
|
-
* Возвращает значение true|false в зависимости isDisabled поле или нет
|
|
1229
|
-
* @example
|
|
1230
|
-
* expect(await formEdit.field('NumberFld').isDisabled()).toBe(true);
|
|
1231
|
-
* expect(await formEdit.field('TextFld').isDisabled()).toBe(false);
|
|
1232
|
-
*/
|
|
1233
|
-
async isDisabled() {
|
|
1234
|
-
await this.initEditor();
|
|
1235
|
-
return this.editor.isDisabled();
|
|
1236
|
-
}
|
|
1237
|
-
/**
|
|
1238
|
-
* Возвращает значение true|false в зависимости isDisplayed поле или нет
|
|
1239
|
-
* @example
|
|
1240
|
-
* expect(await formEdit.field('NumberFld').isDisplayed()).toBe(true);
|
|
1241
|
-
* expect(await formEdit.field('TextFld').isDisplayed()).toBe(false);
|
|
1242
|
-
*/
|
|
1243
|
-
async isDisplayed() {
|
|
1244
|
-
try {
|
|
1245
|
-
await this.initEditor();
|
|
1246
|
-
const element = await this.getElement();
|
|
1247
|
-
return await element.isDisplayed();
|
|
1248
|
-
} catch {
|
|
1249
|
-
return false;
|
|
1250
|
-
}
|
|
1251
|
-
}
|
|
1252
|
-
/**
|
|
1253
|
-
* Находит кнопку на поле по имени
|
|
1254
|
-
* @example
|
|
1255
|
-
* const form= new MyForm();
|
|
1256
|
-
* //...
|
|
1257
|
-
* await form.field('Name').button('editorButton).click()
|
|
1258
|
-
*/
|
|
1259
|
-
button(name) {
|
|
1260
|
-
return new EditorButton(this.getFullCssSelector(), name, this.driver);
|
|
1261
|
-
}
|
|
1262
|
-
};
|
|
1263
|
-
|
|
1264
|
-
// src/pageObjects/elements/FormField.ts
|
|
1265
|
-
var FormField = class extends AbstractEditor {
|
|
1266
|
-
constructor(parentCssSelector, formName, name, driver) {
|
|
1267
|
-
super(parentCssSelector, byTestIdCssSelector(createFieldTestId(formName, name)), driver);
|
|
1268
|
-
}
|
|
1269
|
-
};
|
|
1270
|
-
|
|
1271
|
-
// src/pageObjects/elements/Forms/Form.ts
|
|
1272
|
-
import { By as By16 } from "selenium-webdriver";
|
|
1273
|
-
|
|
1274
|
-
// src/pageObjects/elements/AbstractButton.ts
|
|
1275
|
-
var D5_BUTTON_IS_PRESSED = "d5-is-pressed";
|
|
1276
|
-
var AbstractButton = class extends AbstractElementWithParent {
|
|
1277
|
-
constructor(parentCssSelector, elementCssSelector, driver) {
|
|
1278
|
-
super(parentCssSelector, elementCssSelector, driver);
|
|
1279
|
-
}
|
|
1280
|
-
async click() {
|
|
1281
|
-
const button = await this.getElement();
|
|
1282
|
-
await waitElementIsClickable_default({
|
|
1283
|
-
element: button,
|
|
1284
|
-
errorMessage: this.buttonNotDisplayedError(),
|
|
1285
|
-
driver: this.driver
|
|
1286
|
-
});
|
|
1287
|
-
await click(button, this.driver);
|
|
1288
|
-
}
|
|
1289
|
-
async isDisabled() {
|
|
1290
|
-
const button = await this.getElement();
|
|
1291
|
-
return await button.getCssValue("pointer-events") === "none";
|
|
1292
|
-
}
|
|
1293
|
-
async isDisplayed() {
|
|
1294
|
-
try {
|
|
1295
|
-
const button = await this.getElement();
|
|
1296
|
-
return await button.isDisplayed();
|
|
1297
|
-
} catch {
|
|
1298
|
-
return false;
|
|
1299
|
-
}
|
|
1300
|
-
}
|
|
1301
|
-
async isPressed() {
|
|
1302
|
-
try {
|
|
1303
|
-
const button = await this.getElement();
|
|
1304
|
-
const classAttribute = await button.getAttribute("class");
|
|
1305
|
-
return classAttribute.includes(D5_BUTTON_IS_PRESSED);
|
|
1306
|
-
} catch {
|
|
1307
|
-
return false;
|
|
1308
|
-
}
|
|
1309
|
-
}
|
|
1310
|
-
};
|
|
1311
|
-
|
|
1312
|
-
// src/pageObjects/elements/DXComponents/DXButton.ts
|
|
1313
|
-
import { By as By13 } from "selenium-webdriver";
|
|
1314
|
-
var DXButton = class extends AbstractButton {
|
|
1315
|
-
async getText() {
|
|
1316
|
-
const classes = await this.getClasses();
|
|
1317
|
-
if (!classes.includes("dx-button-has-text")) {
|
|
1318
|
-
return null;
|
|
1319
|
-
}
|
|
1320
|
-
const el = await this.getElement();
|
|
1321
|
-
const textEl = el.findElement(By13.className("dx-button-text"));
|
|
1322
|
-
return await textEl.getText();
|
|
1323
|
-
}
|
|
1324
|
-
};
|
|
1325
|
-
|
|
1326
|
-
// src/pageObjects/elements/FormButton.ts
|
|
1327
|
-
var FormButton = class extends DXButton {
|
|
1328
|
-
name;
|
|
1329
|
-
constructor(parentCssSelector, formName, name, driver) {
|
|
1330
|
-
super(parentCssSelector, byTestIdCssSelector(createFormButtonTestId(formName, name)), driver);
|
|
1331
|
-
this.name = name;
|
|
1332
|
-
}
|
|
1333
|
-
buttonNotDisplayedError() {
|
|
1334
|
-
return `Form Button ${this.name} cannot be clicked. It is not displayed or it is disabled`;
|
|
1335
|
-
}
|
|
1336
|
-
async getTitle() {
|
|
1337
|
-
return await this.getText();
|
|
1338
|
-
}
|
|
1339
|
-
};
|
|
1340
|
-
|
|
1341
|
-
// src/pageObjects/elements/Groups/AbstractGroup.ts
|
|
1342
|
-
var AbstractGroup = class extends AbstractElementWithParent {
|
|
1343
|
-
async isDisplayed() {
|
|
1344
|
-
const groupElement = await this.getElement();
|
|
1345
|
-
return await groupElement.isDisplayed();
|
|
1346
|
-
}
|
|
1347
|
-
};
|
|
1348
|
-
|
|
1349
|
-
// src/pageObjects/elements/Groups/Panel.ts
|
|
1350
|
-
var Panel = class extends AbstractGroup {
|
|
1351
|
-
};
|
|
1352
|
-
|
|
1353
|
-
// src/pageObjects/elements/Groups/TabPanel.ts
|
|
1354
|
-
import { By as By14 } from "selenium-webdriver";
|
|
1355
|
-
var TabPanelItem = class extends AbstractGroup {
|
|
1356
|
-
constructor(parentCssSelector, elementCssSelector, driver) {
|
|
1357
|
-
super(parentCssSelector, elementCssSelector, driver);
|
|
1358
|
-
}
|
|
1359
|
-
async click() {
|
|
1360
|
-
await click(await this.getElement(), this.driver);
|
|
1361
|
-
}
|
|
1362
|
-
async isActive() {
|
|
1363
|
-
const tabPanelItemElement = await this.getElement();
|
|
1364
|
-
const grandparentTab = await tabPanelItemElement.findElement(By14.xpath('ancestor::div[@role="tab"][1]'));
|
|
1365
|
-
return await grandparentTab.getAttribute("aria-selected") === "true";
|
|
1366
|
-
}
|
|
1367
|
-
async getTitle() {
|
|
1368
|
-
return "";
|
|
1369
|
-
}
|
|
1370
|
-
};
|
|
1371
|
-
var TabPanel = class extends AbstractGroup {
|
|
1372
|
-
item(name) {
|
|
1373
|
-
return new TabPanelItem(this.getFullCssSelector(), `.tab-panel-item[data-groupname="${name}"]`, this.driver);
|
|
1374
|
-
}
|
|
1375
|
-
async getTitle() {
|
|
1376
|
-
return "";
|
|
1377
|
-
}
|
|
1378
|
-
};
|
|
1379
|
-
|
|
1380
|
-
// src/pageObjects/elements/Groups/Accordion/AccordionItem.ts
|
|
1381
|
-
import { By as By15 } from "selenium-webdriver";
|
|
1382
|
-
var ACCORDION_TITLE_CONTAINER = "accordion-title-container";
|
|
1383
|
-
var AccordionItem = class extends AbstractGroup {
|
|
1384
|
-
constructor(parentCssSelector, elementCssSelector, driver) {
|
|
1385
|
-
super(parentCssSelector, elementCssSelector, driver);
|
|
1386
|
-
}
|
|
1387
|
-
async getDataOpenedAccordItemAttr() {
|
|
1388
|
-
const accordionElement = await this.getElement();
|
|
1389
|
-
return await accordionElement.getAttribute("data-opened");
|
|
1390
|
-
}
|
|
1391
|
-
async clickAccordionItemTitle() {
|
|
1392
|
-
const accordionElement = await this.getElement();
|
|
1393
|
-
const accordTitleElement = await accordionElement.findElement(By15.className(ACCORDION_TITLE_CONTAINER));
|
|
1394
|
-
await accordTitleElement.click();
|
|
1395
|
-
}
|
|
1396
|
-
async click() {
|
|
1397
|
-
await click(await this.getElement(), this.driver);
|
|
1398
|
-
}
|
|
1399
|
-
async isExpanded() {
|
|
1400
|
-
const dataOpened = await this.getDataOpenedAccordItemAttr();
|
|
1401
|
-
return dataOpened === "true";
|
|
1402
|
-
}
|
|
1403
|
-
async isCollapsed() {
|
|
1404
|
-
const dataOpened = await this.getDataOpenedAccordItemAttr();
|
|
1405
|
-
return dataOpened === "false" || !dataOpened;
|
|
1406
|
-
}
|
|
1407
|
-
async expand() {
|
|
1408
|
-
if (!await this.isExpanded()) {
|
|
1409
|
-
await this.clickAccordionItemTitle();
|
|
1410
|
-
}
|
|
1411
|
-
}
|
|
1412
|
-
async collapse() {
|
|
1413
|
-
if (await this.isExpanded()) {
|
|
1414
|
-
await this.clickAccordionItemTitle();
|
|
1415
|
-
}
|
|
1416
|
-
}
|
|
1417
|
-
};
|
|
1418
|
-
|
|
1419
|
-
// src/pageObjects/elements/Groups/Accordion/Accordion.ts
|
|
1420
|
-
var Accordion = class extends AbstractGroup {
|
|
1421
|
-
constructor(parentCssSelector, elementCssSelector, driver) {
|
|
1422
|
-
super(parentCssSelector, elementCssSelector, driver);
|
|
1423
|
-
}
|
|
1424
|
-
item(name) {
|
|
1425
|
-
return new AccordionItem(this.getFullCssSelector(), `.d5-accordion-item[data-groupname="${name}"]`, this.driver);
|
|
1426
|
-
}
|
|
1427
|
-
};
|
|
1428
|
-
|
|
1429
|
-
// src/pageObjects/elements/Groups/groupFactory.ts
|
|
1430
|
-
var groupFactory = async (parentCssSelector, elementCssSelector, driver) => {
|
|
1431
|
-
const elementInstance = new AbstractFormElement(parentCssSelector, elementCssSelector, driver);
|
|
1432
|
-
const classSting = await elementInstance.getClasses();
|
|
1433
|
-
if (classSting.includes("tab-panel-group")) return new TabPanel(parentCssSelector, elementCssSelector, driver);
|
|
1434
|
-
if (classSting.includes("tab-panel-item")) return new TabPanelItem(parentCssSelector, elementCssSelector, driver);
|
|
1435
|
-
if (classSting.includes("panel-group")) return new Panel(parentCssSelector, elementCssSelector, driver);
|
|
1436
|
-
if (classSting.includes("accordion-group")) return new Accordion(parentCssSelector, elementCssSelector, driver);
|
|
1437
|
-
if (classSting.includes("d5-accordion-item")) return new AccordionItem(parentCssSelector, elementCssSelector, driver);
|
|
1438
|
-
throw new Error("Unknown type of group. Please write ticket to the support");
|
|
1439
|
-
};
|
|
1440
|
-
|
|
1441
|
-
// src/pageObjects/elements/FormGroup.ts
|
|
1442
|
-
var FormGroup = class extends AbstractElementWithParent {
|
|
1443
|
-
groupInstance;
|
|
1444
|
-
constructor(parentCssSelector, formName, name, driver) {
|
|
1445
|
-
super(parentCssSelector, byTestIdCssSelector(createGroupTestId(formName, name)), driver);
|
|
1446
|
-
}
|
|
1447
|
-
async initInstance() {
|
|
1448
|
-
if (!this.groupInstance) {
|
|
1449
|
-
this.groupInstance = await groupFactory(this.parentCssSelector, this.elementCssSelector, this.driver);
|
|
1450
|
-
}
|
|
1451
|
-
}
|
|
1452
|
-
/**
|
|
1453
|
-
* Возвращает булевое значение доступна ли группа
|
|
1454
|
-
* @example
|
|
1455
|
-
* expect(await tableList.group('MainSuperPanel').isDisplayed();
|
|
1456
|
-
*/
|
|
1457
|
-
async isDisplayed() {
|
|
1458
|
-
try {
|
|
1459
|
-
await this.initInstance();
|
|
1460
|
-
return this.groupInstance.isDisplayed();
|
|
1461
|
-
} catch {
|
|
1462
|
-
return false;
|
|
1463
|
-
}
|
|
1464
|
-
}
|
|
1465
|
-
/**
|
|
1466
|
-
* Клик по элементам группы.
|
|
1467
|
-
* Метод работает если у группы есть дочерние элементы, например элементы аккордеона или вкладки таб панели.
|
|
1468
|
-
* @example
|
|
1469
|
-
* expect(await tableList.group('TabPanel').itemClick('Tab');
|
|
1470
|
-
* expect(await tableList.group('Accordion').itemClick('AccordionItem');
|
|
1471
|
-
*/
|
|
1472
|
-
async itemClick(name) {
|
|
1473
|
-
await this.initInstance();
|
|
1474
|
-
const item = this.groupInstance.item?.(name);
|
|
1475
|
-
await item?.click();
|
|
1476
|
-
}
|
|
1477
|
-
/**
|
|
1478
|
-
* Метод работает если группа - это элемент аккордеона или вкладка таб панели
|
|
1479
|
-
* @example
|
|
1480
|
-
* expect(await tableList.group('Tab').click();
|
|
1481
|
-
* expect(await tableList.group('AccordionItem').click();
|
|
1482
|
-
*/
|
|
1483
|
-
async click() {
|
|
1484
|
-
await this.initInstance();
|
|
1485
|
-
await this.groupInstance.click?.();
|
|
1486
|
-
}
|
|
1487
|
-
async collapse() {
|
|
1488
|
-
await this.initInstance();
|
|
1489
|
-
if (this.groupInstance instanceof AccordionItem) {
|
|
1490
|
-
await this.groupInstance.collapse();
|
|
1491
|
-
}
|
|
1492
|
-
}
|
|
1493
|
-
async expand() {
|
|
1494
|
-
await this.initInstance();
|
|
1495
|
-
if (this.groupInstance instanceof AccordionItem) {
|
|
1496
|
-
await this.groupInstance.expand();
|
|
1497
|
-
}
|
|
1498
|
-
}
|
|
1499
|
-
async isExpanded() {
|
|
1500
|
-
await this.initInstance();
|
|
1501
|
-
if (this.groupInstance instanceof AccordionItem) {
|
|
1502
|
-
return await this.groupInstance.isExpanded();
|
|
1503
|
-
}
|
|
1504
|
-
return false;
|
|
1505
|
-
}
|
|
1506
|
-
async isCollapsed() {
|
|
1507
|
-
await this.initInstance();
|
|
1508
|
-
if (this.groupInstance instanceof AccordionItem) {
|
|
1509
|
-
return await this.groupInstance.isCollapsed();
|
|
1510
|
-
}
|
|
1511
|
-
return false;
|
|
1512
|
-
}
|
|
1513
|
-
async isActive() {
|
|
1514
|
-
await this.initInstance();
|
|
1515
|
-
if (this.groupInstance instanceof TabPanelItem) {
|
|
1516
|
-
return await this.groupInstance.isActive();
|
|
1517
|
-
}
|
|
1518
|
-
return false;
|
|
1519
|
-
}
|
|
1520
|
-
};
|
|
1521
|
-
|
|
1522
|
-
// src/pageObjects/elements/Forms/AbstractForm.ts
|
|
1523
|
-
var AbstractForm = class extends AbstractPage {
|
|
1524
|
-
containerCssSelector = "";
|
|
1525
|
-
_formName = "";
|
|
1526
|
-
containerBy;
|
|
1527
|
-
getContainerElement = () => {
|
|
1528
|
-
return this.driver.findElement(this.containerBy);
|
|
1529
|
-
};
|
|
1530
|
-
set formName(name) {
|
|
1531
|
-
this._formName = name;
|
|
1532
|
-
}
|
|
1533
|
-
get formName() {
|
|
1534
|
-
return this._formName;
|
|
1535
|
-
}
|
|
1536
|
-
/**
|
|
1537
|
-
* Возвращает true если форма есть в DOM
|
|
1538
|
-
* @example
|
|
1539
|
-
* class MyForm extends FormEdit {}
|
|
1540
|
-
* //...
|
|
1541
|
-
* const formEdit = new MyForm();
|
|
1542
|
-
* expect(await formEdit.exists()).toBe(true);
|
|
1543
|
-
*/
|
|
1544
|
-
async exists() {
|
|
1545
|
-
try {
|
|
1546
|
-
let elements = await this.driver.findElements(this.containerBy);
|
|
1547
|
-
if (elements.length === 0) {
|
|
1548
|
-
return false;
|
|
1549
|
-
}
|
|
1550
|
-
await waitElementIsVisible_default({
|
|
1551
|
-
element: elements[0],
|
|
1552
|
-
errorMessage: "Element exists in DOM but is not visible",
|
|
1553
|
-
driver: this.driver
|
|
1554
|
-
});
|
|
1555
|
-
return true;
|
|
1556
|
-
} catch (error) {
|
|
1557
|
-
return false;
|
|
1558
|
-
}
|
|
1559
|
-
}
|
|
1560
|
-
button(name) {
|
|
1561
|
-
return new FormButton(this.containerCssSelector, this.formName, name, this.driver);
|
|
1562
|
-
}
|
|
1563
|
-
/**
|
|
1564
|
-
* Находит группу на форме по имени
|
|
1565
|
-
* @example
|
|
1566
|
-
* const formEdit = new MyForm();
|
|
1567
|
-
* //...
|
|
1568
|
-
* expect(await formEdit.group('Name');
|
|
1569
|
-
*/
|
|
1570
|
-
group(name) {
|
|
1571
|
-
return new FormGroup(this.containerCssSelector, this.formName, name, this.driver);
|
|
1572
|
-
}
|
|
1573
|
-
};
|
|
1574
|
-
|
|
1575
|
-
// src/pageObjects/elements/Forms/createSubFormInstance.ts
|
|
1576
|
-
var SECONDARY_DRAWER_LAYOUT_CONTENT = ".secondary-drawer-layout-content";
|
|
1577
|
-
var subFormTestId = (name) => `subform-${name}`;
|
|
1578
|
-
function subformCssSelector(parentCssSelector, testId, isDockPanel = false) {
|
|
1579
|
-
if (isDockPanel) {
|
|
1580
|
-
return `${SECONDARY_DRAWER_LAYOUT_CONTENT} ${byTestIdCssSelector(testId)}`;
|
|
1581
|
-
} else {
|
|
1582
|
-
return `${parentCssSelector} ${byTestIdCssSelector(testId)}`;
|
|
1583
|
-
}
|
|
1584
|
-
}
|
|
1585
|
-
async function classDependencyInjector(formType) {
|
|
1586
|
-
let SubFormFactoryClass;
|
|
1587
|
-
switch (formType) {
|
|
1588
|
-
case "1" /* LIST */:
|
|
1589
|
-
SubFormFactoryClass = (await import("./ListForm-KIHLT7EU.mjs")).default;
|
|
1590
|
-
break;
|
|
1591
|
-
case "3" /* TREE */:
|
|
1592
|
-
SubFormFactoryClass = (await import("./TreeView-TFBZB2UK.mjs")).default;
|
|
1593
|
-
break;
|
|
1594
|
-
case "2" /* EDIT */:
|
|
1595
|
-
case "99" /* FREE_FORM */:
|
|
1596
|
-
case "4" /* REPORT */:
|
|
1597
|
-
SubFormFactoryClass = (await import("./FormEdit-VFV53QIZ.mjs")).default;
|
|
1598
|
-
break;
|
|
1599
|
-
default:
|
|
1600
|
-
throw new Error(`Unsupported form type ${formType}`);
|
|
1601
|
-
}
|
|
1602
|
-
return SubFormFactoryClass;
|
|
1603
|
-
}
|
|
1604
|
-
|
|
1605
|
-
// src/pageObjects/elements/Forms/Form.ts
|
|
1606
|
-
var formTestId = (formName) => `form-content-wrapper-${formName}`;
|
|
1607
|
-
var Form = class extends AbstractForm {
|
|
1608
|
-
popupContainerCssSelector;
|
|
1609
|
-
constructor(driver) {
|
|
1610
|
-
super(driver);
|
|
1611
|
-
this.setSubFormMode();
|
|
1612
|
-
}
|
|
1613
|
-
async isModal() {
|
|
1614
|
-
const el = await this.getContainerElement();
|
|
1615
|
-
const value = await el.getAttribute("data-ismodal");
|
|
1616
|
-
return value === "true";
|
|
1617
|
-
}
|
|
1618
|
-
async isFullScreen() {
|
|
1619
|
-
const el = await this.getContainerElement();
|
|
1620
|
-
const value = await el.getAttribute("data-isfullscreen");
|
|
1621
|
-
return value === "true";
|
|
1622
|
-
}
|
|
1623
|
-
/**
|
|
1624
|
-
* Получение заголовка на формы
|
|
1625
|
-
* @example
|
|
1626
|
-
* const listForm = new MyForm();
|
|
1627
|
-
* //...
|
|
1628
|
-
* expect(await listForm.getTitleText()).toBe('MyFormTitle');
|
|
1629
|
-
*/
|
|
1630
|
-
async getTitleText() {
|
|
1631
|
-
const getFullScreenTitle = async () => {
|
|
1632
|
-
let titleEl = await this.driver.findElement(By16.className("main-toolbar-form-title"));
|
|
1633
|
-
return titleEl.getText();
|
|
1634
|
-
};
|
|
1635
|
-
if (await this.isFullScreen()) {
|
|
1636
|
-
return getFullScreenTitle();
|
|
1637
|
-
}
|
|
1638
|
-
if (await this.isModal()) {
|
|
1639
|
-
const titleEl = await this.driver.findElement(By16.css(`${this.popupContainerCssSelector} .popup-title`));
|
|
1640
|
-
await waitElementIsVisible_default({
|
|
1641
|
-
element: titleEl,
|
|
1642
|
-
driver: this.driver,
|
|
1643
|
-
errorMessage: `Form title element is not visible`
|
|
1644
|
-
});
|
|
1645
|
-
return titleEl.getText();
|
|
1646
|
-
}
|
|
1647
|
-
return getFullScreenTitle();
|
|
1648
|
-
}
|
|
1649
|
-
setSubFormMode() {
|
|
1650
|
-
const testId = formTestId(this.formName);
|
|
1651
|
-
this.containerBy = byTestId(testId);
|
|
1652
|
-
this.containerCssSelector = byTestIdCssSelector(testId);
|
|
1653
|
-
}
|
|
1654
|
-
/**
|
|
1655
|
-
* Возвращает сабформу
|
|
1656
|
-
* @returns {Promise<ListForm | TreeView | FormEdit>}
|
|
1657
|
-
* @example
|
|
1658
|
-
* const form = new MyForm();
|
|
1659
|
-
* //...
|
|
1660
|
-
* expect(await form.subForm(name));
|
|
1661
|
-
*/
|
|
1662
|
-
async subForm(name, options = {}) {
|
|
1663
|
-
const { isDockPanel = false } = options;
|
|
1664
|
-
const cssSelector = subformCssSelector(this.containerCssSelector, subFormTestId(name), isDockPanel);
|
|
1665
|
-
const byCssSelector = By16.css(cssSelector);
|
|
1666
|
-
const subFormEl = await this.driver.findElement(byCssSelector);
|
|
1667
|
-
await waitElementIsVisible_default({
|
|
1668
|
-
element: subFormEl,
|
|
1669
|
-
driver: this.driver,
|
|
1670
|
-
errorMessage: `Subform "${name}" is not visible`
|
|
1671
|
-
});
|
|
1672
|
-
const formType = await subFormEl.getAttribute("data-formtype");
|
|
1673
|
-
const formName = await subFormEl.getAttribute("data-formname");
|
|
1674
|
-
let SubFormFactoryClass = await classDependencyInjector(formType);
|
|
1675
|
-
const SubForm = class extends SubFormFactoryClass {
|
|
1676
|
-
setSubFormMode() {
|
|
1677
|
-
this.containerCssSelector = cssSelector;
|
|
1678
|
-
this.containerBy = byCssSelector;
|
|
1679
|
-
}
|
|
1680
|
-
get formName() {
|
|
1681
|
-
return formName;
|
|
1682
|
-
}
|
|
1683
|
-
};
|
|
1684
|
-
return new SubForm(this.driver);
|
|
1685
|
-
}
|
|
1686
|
-
};
|
|
1687
|
-
|
|
1688
|
-
export {
|
|
1689
|
-
__require,
|
|
1690
|
-
__commonJS,
|
|
1691
|
-
__toESM,
|
|
1692
|
-
config,
|
|
1693
|
-
fixElementStaleError,
|
|
1694
|
-
staleElementAction,
|
|
1695
|
-
AbstractElement,
|
|
1696
|
-
AbstractPage,
|
|
1697
|
-
safeWait,
|
|
1698
|
-
waitElementIsVisible_default,
|
|
1699
|
-
click,
|
|
1700
|
-
contextMenu,
|
|
1701
|
-
byTestIdCssSelector,
|
|
1702
|
-
byTestId,
|
|
1703
|
-
readonlyLocator,
|
|
1704
|
-
disabledLocator,
|
|
1705
|
-
waitElementIsClickable_default,
|
|
1706
|
-
AbstractElementWithParent,
|
|
1707
|
-
TextEditor,
|
|
1708
|
-
NumberEditor,
|
|
1709
|
-
ControlClass,
|
|
1710
|
-
DX_CLEAR_BUTTON_AREA,
|
|
1711
|
-
withCustomTimeouts_default,
|
|
1712
|
-
editorFactory,
|
|
1713
|
-
createDocFilterTestId,
|
|
1714
|
-
createHeaderFilterTestId,
|
|
1715
|
-
createLayoutFilterTestId,
|
|
1716
|
-
createTableId,
|
|
1717
|
-
createSubSystemTestId,
|
|
1718
|
-
AbstractButton,
|
|
1719
|
-
AbstractEditor,
|
|
1720
|
-
FormField,
|
|
1721
|
-
Form
|
|
1722
|
-
};
|