d5-testing-library 1.0.5 → 1.2.0
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/cjs/d5-testing-library.cjs +578 -231
- package/dist/d5-testing-library.d.ts +140 -33
- package/dist/d5-testing-library.legacy-esm.js +572 -228
- package/dist/d5-testing-library.mjs +572 -228
- package/package.json +1 -1
|
@@ -39,12 +39,15 @@ __export(src_exports, {
|
|
|
39
39
|
SubsystemsPanel: () => SubsystemsPanel,
|
|
40
40
|
TextEditor: () => TextEditor,
|
|
41
41
|
byTestId: () => byTestId,
|
|
42
|
+
byTestIdCssSelector: () => byTestIdCssSelector,
|
|
42
43
|
click: () => click,
|
|
43
44
|
config: () => config,
|
|
44
45
|
createDriver: () => createDriver,
|
|
45
46
|
editorFactory: () => editorFactory,
|
|
46
47
|
elementIsNotPresent: () => elementIsNotPresent,
|
|
47
|
-
signIn: () => signIn
|
|
48
|
+
signIn: () => signIn,
|
|
49
|
+
wait: () => wait,
|
|
50
|
+
waitElementIsVisible: () => waitElementIsVisible
|
|
48
51
|
});
|
|
49
52
|
module.exports = __toCommonJS(src_exports);
|
|
50
53
|
|
|
@@ -127,8 +130,11 @@ var AbstractPage = class extends AbstractElement {
|
|
|
127
130
|
|
|
128
131
|
// src/utils/locators.ts
|
|
129
132
|
var import_selenium_webdriver = require("selenium-webdriver");
|
|
133
|
+
var byTestIdCssSelector = (testId, element = "div") => {
|
|
134
|
+
return `${element}[data-testid="${testId}"]`;
|
|
135
|
+
};
|
|
130
136
|
var byTestId = (testId, element = "div") => {
|
|
131
|
-
return import_selenium_webdriver.By.css(
|
|
137
|
+
return import_selenium_webdriver.By.css(byTestIdCssSelector(testId, element));
|
|
132
138
|
};
|
|
133
139
|
|
|
134
140
|
// src/utils/createDriver.ts
|
|
@@ -153,54 +159,91 @@ var elementIsNotPresent = function elementIsNotPresent2(locator) {
|
|
|
153
159
|
// src/utils/waitElementIsVisible.ts
|
|
154
160
|
var import_selenium_webdriver4 = require("selenium-webdriver");
|
|
155
161
|
|
|
162
|
+
// src/utils/wait.ts
|
|
163
|
+
async function wait(condition, driver, errorMessage, timeout) {
|
|
164
|
+
driver = driver ?? config().driver;
|
|
165
|
+
await driver.wait(condition, timeout ?? config().timeout, errorMessage);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// src/utils/waitElementIsVisible.ts
|
|
169
|
+
async function waitElementIsVisible({
|
|
170
|
+
element,
|
|
171
|
+
timeout,
|
|
172
|
+
errorMessage,
|
|
173
|
+
driver
|
|
174
|
+
}) {
|
|
175
|
+
driver = driver ?? config().driver;
|
|
176
|
+
const condition = import_selenium_webdriver4.until.elementIsVisible(element);
|
|
177
|
+
await wait(condition.fn, driver, errorMessage ?? condition.description(), timeout ?? config().timeout);
|
|
178
|
+
}
|
|
179
|
+
|
|
156
180
|
// src/pageObjects/AbstractElementWithParent.ts
|
|
181
|
+
var import_selenium_webdriver5 = require("selenium-webdriver");
|
|
157
182
|
var AbstractElementWithParent = class extends AbstractElement {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
constructor(
|
|
183
|
+
elementCssSelector;
|
|
184
|
+
parentCssSelector;
|
|
185
|
+
constructor(parentCssSelector, elementCssSelector, driver) {
|
|
161
186
|
super(driver);
|
|
162
|
-
this.
|
|
187
|
+
this.parentCssSelector = parentCssSelector;
|
|
188
|
+
this.elementCssSelector = elementCssSelector;
|
|
189
|
+
}
|
|
190
|
+
getFullCssSelector() {
|
|
191
|
+
if (!this.elementCssSelector) {
|
|
192
|
+
return this.parentCssSelector;
|
|
193
|
+
}
|
|
194
|
+
if (!this.parentCssSelector) {
|
|
195
|
+
return this.elementCssSelector;
|
|
196
|
+
}
|
|
197
|
+
return `${this.parentCssSelector} ${this.elementCssSelector}`;
|
|
163
198
|
}
|
|
164
199
|
async getElement() {
|
|
165
|
-
|
|
166
|
-
|
|
200
|
+
return this.driver.findElement(import_selenium_webdriver5.By.css(this.getFullCssSelector()));
|
|
201
|
+
}
|
|
202
|
+
async getAttribute(attr) {
|
|
203
|
+
const element = await this.getElement();
|
|
204
|
+
await waitElementIsVisible({
|
|
205
|
+
element,
|
|
206
|
+
driver: this.driver,
|
|
207
|
+
errorMessage: `Element not found: ${this.getFullCssSelector()}`
|
|
208
|
+
});
|
|
209
|
+
return await element.getAttribute(attr);
|
|
210
|
+
}
|
|
211
|
+
async getClasses() {
|
|
212
|
+
return await this.getAttribute("class");
|
|
167
213
|
}
|
|
168
214
|
};
|
|
169
215
|
|
|
170
216
|
// src/pageObjects/elements/SubsystemsPanel/SubsystemsPanelHeader.ts
|
|
217
|
+
var import_selenium_webdriver6 = require("selenium-webdriver");
|
|
171
218
|
var SubsystemsPanelHeader = class extends AbstractElementWithParent {
|
|
172
|
-
titleBy = byTestId("subsystems-panel-title", "span");
|
|
173
219
|
async title() {
|
|
174
|
-
|
|
175
|
-
return panel.findElement(this.titleBy);
|
|
220
|
+
return this.driver.findElement(import_selenium_webdriver6.By.css(this.getFullCssSelector()));
|
|
176
221
|
}
|
|
177
222
|
};
|
|
178
223
|
|
|
179
224
|
// src/pageObjects/elements/SubsystemsPanel/SubsystemsPanel.ts
|
|
180
|
-
var import_selenium_webdriver5 = require("selenium-webdriver");
|
|
181
225
|
var SubsystemsPanel = class extends AbstractElement {
|
|
182
|
-
panelBy = import_selenium_webdriver5.By.id("aside");
|
|
183
226
|
header;
|
|
184
227
|
constructor(driver) {
|
|
185
228
|
super(driver);
|
|
186
|
-
this.header = new SubsystemsPanelHeader(
|
|
229
|
+
this.header = new SubsystemsPanelHeader("#aside", byTestIdCssSelector("subsystems-panel-title", "span"), this.driver);
|
|
187
230
|
}
|
|
188
|
-
panelElement = () => {
|
|
189
|
-
return this.driver.findElement(this.panelBy);
|
|
190
|
-
};
|
|
191
231
|
headerTitle() {
|
|
192
232
|
return this.header.title().then((el) => el.getText());
|
|
193
233
|
}
|
|
194
234
|
};
|
|
195
235
|
|
|
196
236
|
// src/pageObjects/elements/Forms/AbstractForm.ts
|
|
197
|
-
var
|
|
237
|
+
var import_selenium_webdriver7 = require("selenium-webdriver");
|
|
198
238
|
var AbstractForm = class extends AbstractPage {
|
|
239
|
+
containerCssSelector = "";
|
|
199
240
|
containerBy;
|
|
200
|
-
|
|
241
|
+
popupContainerCssSelector;
|
|
201
242
|
constructor(driver) {
|
|
202
243
|
super(driver);
|
|
203
|
-
|
|
244
|
+
const testId = `form-content-wrapper-${this.formName}`;
|
|
245
|
+
this.containerBy = byTestId(testId);
|
|
246
|
+
this.containerCssSelector = byTestIdCssSelector(testId);
|
|
204
247
|
}
|
|
205
248
|
async isModal() {
|
|
206
249
|
const el = await this.getContainerElement();
|
|
@@ -223,7 +266,7 @@ var AbstractForm = class extends AbstractPage {
|
|
|
223
266
|
*/
|
|
224
267
|
async exists() {
|
|
225
268
|
try {
|
|
226
|
-
await
|
|
269
|
+
await wait(elementIsNotPresent(this.containerBy), this.driver);
|
|
227
270
|
return false;
|
|
228
271
|
} catch {
|
|
229
272
|
return true;
|
|
@@ -238,35 +281,39 @@ var AbstractForm = class extends AbstractPage {
|
|
|
238
281
|
*/
|
|
239
282
|
async getTitleText() {
|
|
240
283
|
if (await this.isModal()) {
|
|
241
|
-
const
|
|
242
|
-
const titleEl2 = await popupEl.findElement(import_selenium_webdriver6.By.className("popup-title"));
|
|
284
|
+
const titleEl2 = await this.driver.findElement(import_selenium_webdriver7.By.css(`${this.popupContainerCssSelector} .popup-title`));
|
|
243
285
|
return titleEl2.getText();
|
|
244
286
|
}
|
|
245
|
-
let
|
|
246
|
-
let titleEl = await container.findElement(import_selenium_webdriver6.By.className("form-toolbar-name-container"));
|
|
287
|
+
let titleEl = await this.driver.findElement(import_selenium_webdriver7.By.css(`${this.containerCssSelector} .form-toolbar-name-container`));
|
|
247
288
|
return titleEl.getText();
|
|
248
289
|
}
|
|
249
290
|
};
|
|
250
291
|
|
|
251
292
|
// src/pageObjects/elements/Forms/FormEdit.ts
|
|
252
|
-
var
|
|
293
|
+
var import_selenium_webdriver14 = require("selenium-webdriver");
|
|
253
294
|
|
|
254
295
|
// src/pageObjects/elements/Editors/AbstractEditor.ts
|
|
255
|
-
var
|
|
296
|
+
var import_selenium_webdriver8 = require("selenium-webdriver");
|
|
256
297
|
|
|
257
|
-
// src/pageObjects/
|
|
258
|
-
var
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
298
|
+
// src/pageObjects/elements/Editors/ClearStrategy/InputClearStrategy.ts
|
|
299
|
+
var InputClearStrategy = class {
|
|
300
|
+
async clear(editor) {
|
|
301
|
+
const inputEl = await editor.getInputElement();
|
|
302
|
+
await inputEl.clear();
|
|
262
303
|
}
|
|
263
304
|
};
|
|
264
305
|
|
|
265
306
|
// src/pageObjects/elements/Editors/AbstractEditor.ts
|
|
266
|
-
var AbstractDXEditorWithInput = class extends
|
|
307
|
+
var AbstractDXEditorWithInput = class extends AbstractElementWithParent {
|
|
308
|
+
clearStrategy = new InputClearStrategy();
|
|
309
|
+
setClearStrategy(strategy) {
|
|
310
|
+
this.clearStrategy = strategy;
|
|
311
|
+
}
|
|
312
|
+
getInputCssSelector() {
|
|
313
|
+
return `${this.getFullCssSelector()} .dx-texteditor-input`;
|
|
314
|
+
}
|
|
267
315
|
async getInputElement() {
|
|
268
|
-
|
|
269
|
-
return controlEl.findElement(import_selenium_webdriver7.By.className("dx-texteditor-input"));
|
|
316
|
+
return this.driver.findElement(import_selenium_webdriver8.By.css(this.getInputCssSelector()));
|
|
270
317
|
}
|
|
271
318
|
async getInputValue() {
|
|
272
319
|
const inputEl = await this.getInputElement();
|
|
@@ -275,12 +322,19 @@ var AbstractDXEditorWithInput = class extends AbstractFormElement {
|
|
|
275
322
|
async setInputValue(value) {
|
|
276
323
|
const inputEl = await this.getInputElement();
|
|
277
324
|
await click(inputEl, this.driver);
|
|
278
|
-
await inputEl.sendKeys(value,
|
|
325
|
+
await inputEl.sendKeys(value, import_selenium_webdriver8.Key.ENTER);
|
|
326
|
+
}
|
|
327
|
+
async clear() {
|
|
328
|
+
await this.clearStrategy.clear(this);
|
|
279
329
|
}
|
|
280
330
|
};
|
|
281
331
|
|
|
282
332
|
// src/pageObjects/elements/Editors/TextEditor.ts
|
|
283
333
|
var TextEditor = class extends AbstractDXEditorWithInput {
|
|
334
|
+
constructor(parentCssSelector, elementCssSelector, driver) {
|
|
335
|
+
super(parentCssSelector, elementCssSelector, driver);
|
|
336
|
+
this.setClearStrategy(new InputClearStrategy());
|
|
337
|
+
}
|
|
284
338
|
getValue() {
|
|
285
339
|
return this.getInputValue();
|
|
286
340
|
}
|
|
@@ -291,6 +345,10 @@ var TextEditor = class extends AbstractDXEditorWithInput {
|
|
|
291
345
|
|
|
292
346
|
// src/pageObjects/elements/Editors/NumberEditor.ts
|
|
293
347
|
var NumberEditor = class extends AbstractDXEditorWithInput {
|
|
348
|
+
constructor(parentCssSelector, elementCssSelector, driver) {
|
|
349
|
+
super(parentCssSelector, elementCssSelector, driver);
|
|
350
|
+
this.setClearStrategy(new InputClearStrategy());
|
|
351
|
+
}
|
|
294
352
|
async getValue() {
|
|
295
353
|
const value = await super.getInputValue();
|
|
296
354
|
return value == "" ? null : Number.parseFloat(value);
|
|
@@ -300,16 +358,22 @@ var NumberEditor = class extends AbstractDXEditorWithInput {
|
|
|
300
358
|
}
|
|
301
359
|
};
|
|
302
360
|
|
|
361
|
+
// src/pageObjects/AbstractFormElement.ts
|
|
362
|
+
var AbstractFormElement = class extends AbstractElementWithParent {
|
|
363
|
+
constructor(parentCssSelector, elementCssSelector, driver) {
|
|
364
|
+
super(parentCssSelector, elementCssSelector, driver);
|
|
365
|
+
}
|
|
366
|
+
};
|
|
367
|
+
|
|
303
368
|
// src/pageObjects/elements/Editors/CheckBox.ts
|
|
304
|
-
var CheckBox = class extends
|
|
369
|
+
var CheckBox = class extends AbstractElementWithParent {
|
|
305
370
|
async getValue() {
|
|
306
|
-
const
|
|
307
|
-
const result = await inputEl.getAttribute("aria-checked");
|
|
371
|
+
const result = await this.getAttribute("aria-checked");
|
|
308
372
|
if (result === "true")
|
|
309
|
-
return
|
|
373
|
+
return 1;
|
|
310
374
|
if (result === "false")
|
|
311
|
-
return
|
|
312
|
-
return
|
|
375
|
+
return 0;
|
|
376
|
+
return null;
|
|
313
377
|
}
|
|
314
378
|
async setValue(value) {
|
|
315
379
|
const inputEl = await this.getElement();
|
|
@@ -321,7 +385,7 @@ var CheckBox = class extends AbstractFormElement {
|
|
|
321
385
|
};
|
|
322
386
|
|
|
323
387
|
// src/pageObjects/elements/Editors/SelectBoxEditor.ts
|
|
324
|
-
var
|
|
388
|
+
var import_selenium_webdriver10 = require("selenium-webdriver");
|
|
325
389
|
|
|
326
390
|
// src/utils/xpathHelper.ts
|
|
327
391
|
var XPathHelper = class {
|
|
@@ -333,24 +397,50 @@ var XPathHelper = class {
|
|
|
333
397
|
}
|
|
334
398
|
};
|
|
335
399
|
|
|
400
|
+
// src/pageObjects/elements/Editors/ClearStrategy/ClearButtonStrategy.ts
|
|
401
|
+
var import_selenium_webdriver9 = require("selenium-webdriver");
|
|
402
|
+
var DX_TEXTEDITOR_EMPTY = "dx-texteditor-empty";
|
|
403
|
+
var DX_CLEAR_BUTTON_AREA = "dx-clear-button-area";
|
|
404
|
+
var ClearButtonStrategy = class {
|
|
405
|
+
editorContainerClass;
|
|
406
|
+
_driver;
|
|
407
|
+
constructor(editorContainerClass, driver) {
|
|
408
|
+
this.editorContainerClass = editorContainerClass;
|
|
409
|
+
this._driver = driver;
|
|
410
|
+
}
|
|
411
|
+
async isEmptyEditorField() {
|
|
412
|
+
const editorContainer = await this._driver.findElement(import_selenium_webdriver9.By.css(this.editorContainerClass));
|
|
413
|
+
const classAttribute = await editorContainer.getAttribute("class");
|
|
414
|
+
return classAttribute.includes(DX_TEXTEDITOR_EMPTY);
|
|
415
|
+
}
|
|
416
|
+
async clear() {
|
|
417
|
+
if (await this.isEmptyEditorField()) {
|
|
418
|
+
throw new Error("This field is already empty");
|
|
419
|
+
}
|
|
420
|
+
const clearBtnSelector = `${this.editorContainerClass} .${DX_CLEAR_BUTTON_AREA}`;
|
|
421
|
+
const clearBtn = await this._driver.findElement(import_selenium_webdriver9.By.css(clearBtnSelector));
|
|
422
|
+
await click(clearBtn, this._driver);
|
|
423
|
+
}
|
|
424
|
+
};
|
|
425
|
+
|
|
336
426
|
// src/pageObjects/elements/Editors/SelectBoxEditor.ts
|
|
337
427
|
var SELECT_BOX_OPTION_TEXT_CONTAINER_CLASS = "d5-multi-select-item";
|
|
338
428
|
var SELECT_BOX_ELEMENT_ROLE = "option";
|
|
429
|
+
var combinedValueXpath = (value) => `${XPathHelper.getRoleXpath(SELECT_BOX_ELEMENT_ROLE)}${XPathHelper.getClassAndValueXpath(
|
|
430
|
+
SELECT_BOX_OPTION_TEXT_CONTAINER_CLASS,
|
|
431
|
+
value
|
|
432
|
+
)}`;
|
|
339
433
|
var SelectBoxEditor = class extends AbstractDXEditorWithInput {
|
|
434
|
+
constructor(parentCssSelector, elementCssSelector, driver) {
|
|
435
|
+
super(parentCssSelector, elementCssSelector, driver);
|
|
436
|
+
this.setClearStrategy(new ClearButtonStrategy(this.getFullCssSelector(), this.driver));
|
|
437
|
+
}
|
|
340
438
|
async setSelectInputValue(value) {
|
|
341
439
|
const inputEl = await this.getInputElement();
|
|
342
440
|
await click(inputEl, this.driver);
|
|
343
|
-
await inputEl.sendKeys(value,
|
|
344
|
-
const
|
|
345
|
-
await this.driver
|
|
346
|
-
try {
|
|
347
|
-
const optElement = await inputEl.findElement(import_selenium_webdriver8.By.xpath(combinedValueXpath));
|
|
348
|
-
await click(optElement, this.driver);
|
|
349
|
-
return true;
|
|
350
|
-
} catch (e) {
|
|
351
|
-
return false;
|
|
352
|
-
}
|
|
353
|
-
}, 2e3);
|
|
441
|
+
await inputEl.sendKeys(value, import_selenium_webdriver10.Key.ENTER);
|
|
442
|
+
const optElement = await inputEl.findElement(import_selenium_webdriver10.By.xpath(combinedValueXpath(value)));
|
|
443
|
+
await click(optElement, this.driver);
|
|
354
444
|
}
|
|
355
445
|
async getValue() {
|
|
356
446
|
const value = await super.getInputValue();
|
|
@@ -362,15 +452,14 @@ var SelectBoxEditor = class extends AbstractDXEditorWithInput {
|
|
|
362
452
|
};
|
|
363
453
|
|
|
364
454
|
// src/pageObjects/elements/Editors/SwitchEditor.ts
|
|
365
|
-
var SwitchEditor = class extends
|
|
455
|
+
var SwitchEditor = class extends AbstractElementWithParent {
|
|
366
456
|
async getValue() {
|
|
367
|
-
const
|
|
368
|
-
const result = await inputEl.getAttribute("aria-label");
|
|
457
|
+
const result = await this.getAttribute("aria-label");
|
|
369
458
|
if (result === "ON")
|
|
370
459
|
return 1;
|
|
371
460
|
if (result === "OFF")
|
|
372
461
|
return 0;
|
|
373
|
-
return
|
|
462
|
+
return null;
|
|
374
463
|
}
|
|
375
464
|
async setValue(value) {
|
|
376
465
|
if (value !== 0 && value !== 1) {
|
|
@@ -378,31 +467,196 @@ var SwitchEditor = class extends AbstractFormElement {
|
|
|
378
467
|
}
|
|
379
468
|
const inputEl = await this.getElement();
|
|
380
469
|
const currentValue = await this.getValue();
|
|
381
|
-
if (currentValue
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
470
|
+
if (currentValue === value) {
|
|
471
|
+
return;
|
|
472
|
+
}
|
|
473
|
+
await click(inputEl, this.driver);
|
|
474
|
+
await wait(async () => {
|
|
475
|
+
const updatedValue = await this.getValue();
|
|
476
|
+
return updatedValue !== currentValue;
|
|
477
|
+
}, this.driver);
|
|
478
|
+
}
|
|
479
|
+
};
|
|
480
|
+
|
|
481
|
+
// src/pageObjects/elements/Editors/TagBox.ts
|
|
482
|
+
var import_selenium_webdriver11 = require("selenium-webdriver");
|
|
483
|
+
var TAGS_SELECTOR = ".dx-tag .tag-text";
|
|
484
|
+
var DX_TAG_CONTAINER = "dx-tag-container";
|
|
485
|
+
var DX_TEXTEDITOR_EMPTY2 = "dx-texteditor-empty";
|
|
486
|
+
var BTN_OK_SELECTOR = ".dx-tagbox-popup-wrapper .dx-popup-bottom .dx-button.dx-popup-done";
|
|
487
|
+
var TagBox = class extends AbstractDXEditorWithInput {
|
|
488
|
+
constructor(parentCssSelector, elementCssSelector, driver) {
|
|
489
|
+
super(parentCssSelector, elementCssSelector, driver);
|
|
490
|
+
this.setClearStrategy(new ClearButtonStrategy(this.getFullCssSelector(), this.driver));
|
|
491
|
+
}
|
|
492
|
+
async setTagBoxInputValue(values) {
|
|
493
|
+
const lastElement = values[values.length - 1];
|
|
494
|
+
const inputEl = await this.getInputElement();
|
|
495
|
+
await inputEl.click();
|
|
496
|
+
for (const value of values) {
|
|
497
|
+
await this.selectOption(inputEl, value, lastElement);
|
|
498
|
+
}
|
|
499
|
+
await this.confirmSelection();
|
|
500
|
+
}
|
|
501
|
+
async selectOption(inputEl, value, lastElement) {
|
|
502
|
+
await inputEl.sendKeys(value);
|
|
503
|
+
const optElement = await inputEl.findElement(import_selenium_webdriver11.By.xpath(combinedValueXpath(value)));
|
|
504
|
+
await click(optElement, this.driver);
|
|
505
|
+
if (value !== lastElement) {
|
|
506
|
+
await inputEl.clear();
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
async confirmSelection() {
|
|
510
|
+
const inputEl = await this.getInputElement();
|
|
511
|
+
const option = await inputEl.findElement(import_selenium_webdriver11.By.xpath(XPathHelper.getRoleXpath(SELECT_BOX_ELEMENT_ROLE)));
|
|
512
|
+
const btnOk = await this.driver.findElement(import_selenium_webdriver11.By.css(BTN_OK_SELECTOR));
|
|
513
|
+
await wait(async () => {
|
|
514
|
+
return await option.getAttribute("aria-selected") === "true";
|
|
515
|
+
}, this.driver);
|
|
516
|
+
await click(btnOk, this.driver);
|
|
517
|
+
}
|
|
518
|
+
async getTagBoxInputValue() {
|
|
519
|
+
if (await this.isTagBoxEmpty()) {
|
|
520
|
+
return [];
|
|
521
|
+
}
|
|
522
|
+
const tags = await this.driver.findElements(import_selenium_webdriver11.By.css(`${this.getFullCssSelector()} .${DX_TAG_CONTAINER} ${TAGS_SELECTOR}`));
|
|
523
|
+
const values = [];
|
|
524
|
+
for (const tag of tags) {
|
|
525
|
+
const text = await tag.getText();
|
|
526
|
+
values.push(text);
|
|
527
|
+
}
|
|
528
|
+
return values;
|
|
529
|
+
}
|
|
530
|
+
async isTagBoxEmpty() {
|
|
531
|
+
const classAttribute = await this.getClasses();
|
|
532
|
+
return classAttribute.includes(DX_TEXTEDITOR_EMPTY2);
|
|
533
|
+
}
|
|
534
|
+
async getValue() {
|
|
535
|
+
const value = await this.getTagBoxInputValue();
|
|
536
|
+
return value.length ? value : null;
|
|
537
|
+
}
|
|
538
|
+
async setValue(values) {
|
|
539
|
+
if (!Array.isArray(values)) {
|
|
540
|
+
throw new Error("The provided value is not an array");
|
|
541
|
+
}
|
|
542
|
+
await this.setTagBoxInputValue(values);
|
|
543
|
+
}
|
|
544
|
+
async remove(itemText) {
|
|
545
|
+
const tagValues = await this.getValue();
|
|
546
|
+
const tagExists = tagValues.includes(itemText);
|
|
547
|
+
if (!tagExists) {
|
|
548
|
+
throw new Error(`The tag with the text: ${itemText} was not found`);
|
|
549
|
+
}
|
|
550
|
+
const clearBtnTestId = byTestIdCssSelector(`clear-button-${itemText}`);
|
|
551
|
+
const clearBtn = await this.driver.findElement(import_selenium_webdriver11.By.css(`${this.getFullCssSelector()} .${DX_TAG_CONTAINER} ${clearBtnTestId}`));
|
|
552
|
+
await click(clearBtn, this.driver);
|
|
553
|
+
}
|
|
554
|
+
};
|
|
555
|
+
|
|
556
|
+
// src/pageObjects/elements/Editors/ButtonGroup.ts
|
|
557
|
+
var import_selenium_webdriver12 = require("selenium-webdriver");
|
|
558
|
+
var ITEM_CLASS = "dx-buttongroup-item";
|
|
559
|
+
var SELECTED_CLASS = "dx-state-selected";
|
|
560
|
+
var ButtonGroup = class extends AbstractElementWithParent {
|
|
561
|
+
getItems() {
|
|
562
|
+
return this.driver.findElements(import_selenium_webdriver12.By.css(`${this.getFullCssSelector()} .${ITEM_CLASS}`));
|
|
563
|
+
}
|
|
564
|
+
getDataValue(el) {
|
|
565
|
+
return el.getAttribute("data-value");
|
|
566
|
+
}
|
|
567
|
+
async getValue() {
|
|
568
|
+
const selectedEl = await this.driver.findElement(import_selenium_webdriver12.By.css(`${this.getFullCssSelector()} .${ITEM_CLASS}.${SELECTED_CLASS}`));
|
|
569
|
+
return this.getDataValue(selectedEl);
|
|
570
|
+
}
|
|
571
|
+
async setValue(value) {
|
|
572
|
+
const items = await this.getItems();
|
|
573
|
+
let buttonEl = void 0;
|
|
574
|
+
for (const item of items) {
|
|
575
|
+
const text = await this.getDataValue(item);
|
|
576
|
+
if (text == value) {
|
|
577
|
+
buttonEl = item;
|
|
578
|
+
break;
|
|
579
|
+
}
|
|
387
580
|
}
|
|
581
|
+
if (!buttonEl)
|
|
582
|
+
throw new Error(`Cannot find item in button group with text: ${value}`);
|
|
583
|
+
await click(buttonEl, this.driver);
|
|
584
|
+
}
|
|
585
|
+
};
|
|
586
|
+
|
|
587
|
+
// src/pageObjects/elements/Editors/BooleanSelector.ts
|
|
588
|
+
var BooleanSelector = class extends ButtonGroup {
|
|
589
|
+
// @ts-ignore
|
|
590
|
+
async getValue() {
|
|
591
|
+
const value = await super.getValue();
|
|
592
|
+
return value === "null" ? null : value === "1" ? 1 : 0;
|
|
593
|
+
}
|
|
594
|
+
// @ts-ignore
|
|
595
|
+
async setValue(value) {
|
|
596
|
+
const val = value == null ? "null" : value ? "1" : "0";
|
|
597
|
+
await super.setValue(val);
|
|
598
|
+
}
|
|
599
|
+
};
|
|
600
|
+
|
|
601
|
+
// src/pageObjects/elements/Editors/DateEditor.ts
|
|
602
|
+
var import_selenium_webdriver13 = require("selenium-webdriver");
|
|
603
|
+
var DateEditor = class extends AbstractDXEditorWithInput {
|
|
604
|
+
constructor(parentCssSelector, elementCssSelector, driver) {
|
|
605
|
+
super(parentCssSelector, elementCssSelector, driver);
|
|
606
|
+
this.setClearStrategy(new InputClearStrategy());
|
|
607
|
+
}
|
|
608
|
+
async getDateElement() {
|
|
609
|
+
return this.driver.findElement(import_selenium_webdriver13.By.css(this.getFullCssSelector() + " .dx-dropdowneditor-input-wrapper input[type=hidden]"));
|
|
610
|
+
}
|
|
611
|
+
async setDateValue(value) {
|
|
612
|
+
const dateEl = await this.getInputElement();
|
|
613
|
+
const stringDate = value.toJSON().split("T")[0];
|
|
614
|
+
const dateArr = stringDate.split("-");
|
|
615
|
+
const [year, month, day] = dateArr;
|
|
616
|
+
const keys = day + month + year;
|
|
617
|
+
await click(dateEl, this.driver);
|
|
618
|
+
const actions = this.driver.actions({ async: true });
|
|
619
|
+
await actions.move({ origin: dateEl }).sendKeys(import_selenium_webdriver13.Key.HOME).perform();
|
|
620
|
+
await actions.move({ origin: dateEl }).sendKeys(keys, import_selenium_webdriver13.Key.ENTER).perform();
|
|
621
|
+
}
|
|
622
|
+
async getDateValue() {
|
|
623
|
+
const inputEl = await this.getDateElement();
|
|
624
|
+
return inputEl.getAttribute("value");
|
|
625
|
+
}
|
|
626
|
+
async getValue() {
|
|
627
|
+
const value = await this.getDateValue();
|
|
628
|
+
return value == "" ? null : new Date(value);
|
|
629
|
+
}
|
|
630
|
+
setValue(value) {
|
|
631
|
+
if (typeof value === "object") {
|
|
632
|
+
return this.setDateValue(value);
|
|
633
|
+
}
|
|
634
|
+
throw new Error(`Value is incorrect. It should be Object`);
|
|
388
635
|
}
|
|
389
636
|
};
|
|
390
637
|
|
|
391
638
|
// src/pageObjects/elements/Editors/editorFactory.ts
|
|
392
|
-
var editorFactory = async (
|
|
393
|
-
const elementInstance = new AbstractFormElement(
|
|
394
|
-
const
|
|
395
|
-
const classSting = await element.getAttribute("class");
|
|
639
|
+
var editorFactory = async (parentCssSelector, elementCssSelector, driver) => {
|
|
640
|
+
const elementInstance = new AbstractFormElement(parentCssSelector, elementCssSelector, driver);
|
|
641
|
+
const classSting = await elementInstance.getClasses();
|
|
396
642
|
if (classSting.includes("text-control"))
|
|
397
|
-
return new TextEditor(
|
|
643
|
+
return new TextEditor(parentCssSelector, elementCssSelector, driver);
|
|
398
644
|
if (classSting.includes("number-control"))
|
|
399
|
-
return new NumberEditor(
|
|
645
|
+
return new NumberEditor(parentCssSelector, elementCssSelector, driver);
|
|
400
646
|
if (classSting.includes("check-box"))
|
|
401
|
-
return new CheckBox(
|
|
647
|
+
return new CheckBox(parentCssSelector, elementCssSelector, driver);
|
|
648
|
+
if (classSting.includes("multi-select-control"))
|
|
649
|
+
return new TagBox(parentCssSelector, elementCssSelector, driver);
|
|
402
650
|
if (classSting.includes("select-control"))
|
|
403
|
-
return new SelectBoxEditor(
|
|
651
|
+
return new SelectBoxEditor(parentCssSelector, elementCssSelector, driver);
|
|
404
652
|
if (classSting.includes("switch-control"))
|
|
405
|
-
return new SwitchEditor(
|
|
653
|
+
return new SwitchEditor(parentCssSelector, elementCssSelector, driver);
|
|
654
|
+
if (classSting.includes("date-control"))
|
|
655
|
+
return new DateEditor(parentCssSelector, elementCssSelector, driver);
|
|
656
|
+
if (classSting.includes("buttons-group"))
|
|
657
|
+
return new BooleanSelector(parentCssSelector, elementCssSelector, driver);
|
|
658
|
+
if (classSting.includes("button-group-field"))
|
|
659
|
+
return new ButtonGroup(parentCssSelector, elementCssSelector, driver);
|
|
406
660
|
throw new Error("Unknown type of editor. Please write ticket to the support");
|
|
407
661
|
};
|
|
408
662
|
|
|
@@ -413,6 +667,9 @@ function createDataTestId(formName, itemType, itemName) {
|
|
|
413
667
|
function createFieldTestId(formName, itemName) {
|
|
414
668
|
return createDataTestId(formName, "form_field" /* FORM_FIELD */, itemName);
|
|
415
669
|
}
|
|
670
|
+
function createGroupTestId(formName, itemName) {
|
|
671
|
+
return createDataTestId(formName, "group" /* GROUP */, itemName);
|
|
672
|
+
}
|
|
416
673
|
function createTableId(formName) {
|
|
417
674
|
return `${"table" /* TABLE */}-${formName}`;
|
|
418
675
|
}
|
|
@@ -420,13 +677,12 @@ function createTableId(formName) {
|
|
|
420
677
|
// src/pageObjects/elements/FormField.ts
|
|
421
678
|
var FormField = class extends AbstractElementWithParent {
|
|
422
679
|
editor;
|
|
423
|
-
constructor(
|
|
424
|
-
super(
|
|
425
|
-
this.elementBy = byTestId(createFieldTestId(formName, name));
|
|
680
|
+
constructor(parentCssSelector, formName, name, driver) {
|
|
681
|
+
super(parentCssSelector, byTestIdCssSelector(createFieldTestId(formName, name)), driver);
|
|
426
682
|
}
|
|
427
683
|
async initEditor() {
|
|
428
684
|
if (!this.editor) {
|
|
429
|
-
this.editor = await editorFactory(this.
|
|
685
|
+
this.editor = await editorFactory(this.parentCssSelector, this.elementCssSelector, this.driver);
|
|
430
686
|
}
|
|
431
687
|
}
|
|
432
688
|
/**
|
|
@@ -449,14 +705,85 @@ var FormField = class extends AbstractElementWithParent {
|
|
|
449
705
|
await this.initEditor();
|
|
450
706
|
return this.editor.setValue(value);
|
|
451
707
|
}
|
|
708
|
+
/**
|
|
709
|
+
* Очищает значение в поле
|
|
710
|
+
* @example
|
|
711
|
+
* await formEdit.field('NumberFld').clear();
|
|
712
|
+
*/
|
|
713
|
+
async clear() {
|
|
714
|
+
await this.initEditor();
|
|
715
|
+
if (!this.editor.clear) {
|
|
716
|
+
throw new Error("The clear method is not available for this field type.");
|
|
717
|
+
}
|
|
718
|
+
return this.editor.clear();
|
|
719
|
+
}
|
|
720
|
+
/**
|
|
721
|
+
* Удаляет тег по переданному тексту
|
|
722
|
+
* @example
|
|
723
|
+
* await formEdit.field('TagBox').remove('test');
|
|
724
|
+
*/
|
|
725
|
+
async remove(itemText) {
|
|
726
|
+
await this.initEditor();
|
|
727
|
+
if (!this.editor.remove) {
|
|
728
|
+
throw new Error("This method is only available for the TagBox field.");
|
|
729
|
+
}
|
|
730
|
+
return this.editor.remove(itemText);
|
|
731
|
+
}
|
|
732
|
+
};
|
|
733
|
+
|
|
734
|
+
// src/pageObjects/elements/Groups/AbstractGroup.ts
|
|
735
|
+
var AbstractGroup = class extends AbstractElementWithParent {
|
|
736
|
+
async isDisplayed() {
|
|
737
|
+
const groupElement = await this.getElement();
|
|
738
|
+
return await groupElement.isDisplayed();
|
|
739
|
+
}
|
|
740
|
+
};
|
|
741
|
+
|
|
742
|
+
// src/pageObjects/elements/Groups/Panel.ts
|
|
743
|
+
var Panel = class extends AbstractGroup {
|
|
744
|
+
};
|
|
745
|
+
|
|
746
|
+
// src/pageObjects/elements/Groups/groupFactory.ts
|
|
747
|
+
var groupFactory = async (parentCssSelector, elementCssSelector, driver) => {
|
|
748
|
+
const elementInstance = new AbstractFormElement(parentCssSelector, elementCssSelector, driver);
|
|
749
|
+
const classSting = await elementInstance.getClasses();
|
|
750
|
+
if (classSting.includes("panel-group"))
|
|
751
|
+
return new Panel(parentCssSelector, elementCssSelector, driver);
|
|
752
|
+
throw new Error("Unknown type of group. Please write ticket to the support");
|
|
753
|
+
};
|
|
754
|
+
|
|
755
|
+
// src/pageObjects/elements/FormGroup.ts
|
|
756
|
+
var FormGroup = class extends AbstractElementWithParent {
|
|
757
|
+
editor;
|
|
758
|
+
constructor(parentCssSelector, formName, name, driver) {
|
|
759
|
+
super(parentCssSelector, byTestIdCssSelector(createGroupTestId(formName, name)), driver);
|
|
760
|
+
}
|
|
761
|
+
async initEditor() {
|
|
762
|
+
if (!this.editor) {
|
|
763
|
+
this.editor = await groupFactory(this.parentCssSelector, this.elementCssSelector, this.driver);
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
/**
|
|
767
|
+
* Возвращает булевое значение доступна ли группа
|
|
768
|
+
* @example
|
|
769
|
+
* expect(await tableList.group('MainSuperPanel').isDisplayed();
|
|
770
|
+
*/
|
|
771
|
+
async isDisplayed() {
|
|
772
|
+
try {
|
|
773
|
+
await this.initEditor();
|
|
774
|
+
return this.editor.isDisplayed();
|
|
775
|
+
} catch {
|
|
776
|
+
return false;
|
|
777
|
+
}
|
|
778
|
+
}
|
|
452
779
|
};
|
|
453
780
|
|
|
454
781
|
// src/pageObjects/elements/Forms/FormEdit.ts
|
|
455
782
|
var FormEdit = class extends AbstractForm {
|
|
456
|
-
saveButtonBy =
|
|
783
|
+
saveButtonBy = import_selenium_webdriver14.By.id("button-save");
|
|
457
784
|
constructor(driver) {
|
|
458
785
|
super(driver);
|
|
459
|
-
this.
|
|
786
|
+
this.popupContainerCssSelector = `.popup .form-edit-${this.formName}`;
|
|
460
787
|
}
|
|
461
788
|
/**
|
|
462
789
|
* Находит поле формы редактирования по имени
|
|
@@ -466,7 +793,29 @@ var FormEdit = class extends AbstractForm {
|
|
|
466
793
|
* expect(await formEdit.field('Name').getValue()).toBe('test value');
|
|
467
794
|
*/
|
|
468
795
|
field(name) {
|
|
469
|
-
return new FormField(this.
|
|
796
|
+
return new FormField(this.containerCssSelector, this.formName, name, this.driver);
|
|
797
|
+
}
|
|
798
|
+
/**
|
|
799
|
+
* Проверяет не отключена ли кнопка Сохранить
|
|
800
|
+
* @example
|
|
801
|
+
* const formEdit = new MyForm();
|
|
802
|
+
* //...
|
|
803
|
+
* await formEdit.isSaveButtonDisabled();
|
|
804
|
+
*/
|
|
805
|
+
async isSaveButtonDisabled() {
|
|
806
|
+
const saveButton = await this.driver.findElement(this.saveButtonBy);
|
|
807
|
+
const result = await saveButton.getAttribute("aria-disabled");
|
|
808
|
+
return result === "true";
|
|
809
|
+
}
|
|
810
|
+
/**
|
|
811
|
+
* Находит группу формы редактирования по имени
|
|
812
|
+
* @example
|
|
813
|
+
* const formEdit = new MyForm();
|
|
814
|
+
* //...
|
|
815
|
+
* expect(await formEdit.group('Name');
|
|
816
|
+
*/
|
|
817
|
+
group(name) {
|
|
818
|
+
return new FormGroup(this.containerCssSelector, this.formName, name, this.driver);
|
|
470
819
|
}
|
|
471
820
|
/**
|
|
472
821
|
* Нажатие на кнопку Сохранить
|
|
@@ -476,145 +825,167 @@ var FormEdit = class extends AbstractForm {
|
|
|
476
825
|
* await formEdit.saveButtonClick();
|
|
477
826
|
*/
|
|
478
827
|
async saveButtonClick() {
|
|
479
|
-
|
|
828
|
+
const saveButton = await this.driver.findElement(this.saveButtonBy);
|
|
829
|
+
await wait(async () => !await this.isSaveButtonDisabled(), this.driver, "Button is disabled");
|
|
830
|
+
await click(saveButton, this.driver);
|
|
480
831
|
}
|
|
481
832
|
};
|
|
482
833
|
|
|
483
|
-
// src/pageObjects/elements/Forms/ListForm.ts
|
|
484
|
-
var import_selenium_webdriver15 = require("selenium-webdriver");
|
|
485
|
-
|
|
486
834
|
// src/pageObjects/elements/Table/Table.ts
|
|
487
|
-
var
|
|
835
|
+
var import_selenium_webdriver18 = require("selenium-webdriver");
|
|
836
|
+
|
|
837
|
+
// src/pageObjects/elements/Table/elements/Row.ts
|
|
838
|
+
var import_selenium_webdriver16 = require("selenium-webdriver");
|
|
488
839
|
|
|
489
840
|
// src/pageObjects/elements/Table/utils.ts
|
|
490
|
-
var
|
|
491
|
-
|
|
492
|
-
return
|
|
493
|
-
}
|
|
494
|
-
var
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
};
|
|
500
|
-
var getCellPathByIndex = (index) => {
|
|
501
|
-
return import_selenium_webdriver10.By.css(`td[role="gridcell"][aria-colindex="${transformInputIndex(index)}"]`);
|
|
502
|
-
};
|
|
841
|
+
var import_selenium_webdriver15 = require("selenium-webdriver");
|
|
842
|
+
function getCssRowByIndexSelector(index) {
|
|
843
|
+
return `tr[aria-rowindex="${transformInputIndex(index)}"]`;
|
|
844
|
+
}
|
|
845
|
+
var getColumnByIndexCssSelector = (columnIndex) => `td[aria-colindex="${transformInputIndex(columnIndex)}"]`;
|
|
846
|
+
var getColumnByCaptionCssSelector = (caption) => `td[role="columnheader"][aria-label="Column ${caption}"]`;
|
|
847
|
+
function getCssCellByIndexSelector(index) {
|
|
848
|
+
return `td[role="gridcell"][aria-colindex="${transformInputIndex(index)}"]`;
|
|
849
|
+
}
|
|
503
850
|
var transformInputIndex = (index) => index + 1;
|
|
504
851
|
var transformOutputIndex = (index) => +index - 1;
|
|
505
852
|
|
|
506
|
-
// src/pageObjects/elements/Table/elements/Row.ts
|
|
507
|
-
var import_selenium_webdriver11 = require("selenium-webdriver");
|
|
508
|
-
|
|
509
853
|
// src/pageObjects/elements/Table/elements/Cell.ts
|
|
510
854
|
var Cell = class extends AbstractElementWithParent {
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
this.
|
|
855
|
+
_index;
|
|
856
|
+
getCellIndex;
|
|
857
|
+
constructor(parentCssSelector, getCellIndex, index, driver) {
|
|
858
|
+
super(parentCssSelector, getCssCellByIndexSelector(index), driver);
|
|
859
|
+
this.getCellIndex = getCellIndex;
|
|
860
|
+
this._index = index;
|
|
861
|
+
}
|
|
862
|
+
set index(index) {
|
|
863
|
+
this._index = index;
|
|
864
|
+
this.elementCssSelector = getCssCellByIndexSelector(index);
|
|
865
|
+
}
|
|
866
|
+
async getElement() {
|
|
867
|
+
if (this._index == null) {
|
|
868
|
+
this.index = await this.getCellIndex();
|
|
869
|
+
}
|
|
870
|
+
return super.getElement();
|
|
516
871
|
}
|
|
517
872
|
async getValue() {
|
|
518
873
|
const cellEl = await this.getElement();
|
|
519
874
|
return cellEl.getText();
|
|
520
875
|
}
|
|
521
876
|
getIndex() {
|
|
522
|
-
return this.
|
|
877
|
+
return this._index;
|
|
523
878
|
}
|
|
524
879
|
};
|
|
525
880
|
|
|
526
881
|
// src/pageObjects/elements/Table/elements/Row.ts
|
|
527
882
|
var DX_SELECTION_CLASS = "dx-selection";
|
|
528
883
|
var DX_ROW_EDIT_CLASS = "dx-edit-row";
|
|
884
|
+
var DX_DATA_ROW_CLASS = "dx-data-row";
|
|
529
885
|
var Row = class extends AbstractElementWithParent {
|
|
530
886
|
index;
|
|
531
887
|
getColumnByCaption;
|
|
532
|
-
constructor(
|
|
533
|
-
super(
|
|
888
|
+
constructor(parentCssSelector, index, driver, getColumnByCaption) {
|
|
889
|
+
super(parentCssSelector, getCssRowByIndexSelector(index), driver);
|
|
534
890
|
this.index = index;
|
|
535
|
-
this.elementBy = getRowPathByIndex(index);
|
|
536
891
|
this.getColumnByCaption = getColumnByCaption;
|
|
537
892
|
}
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
return new Cell(rowEl, index, this.driver);
|
|
543
|
-
}
|
|
544
|
-
throw new Error(`Cannot find cell by index: ${index}`);
|
|
893
|
+
_getCell(index, caption) {
|
|
894
|
+
return new Cell(this.getFullCssSelector(), () => {
|
|
895
|
+
return this.getColumnByCaption(caption).getIndex();
|
|
896
|
+
}, index, this.driver);
|
|
545
897
|
}
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
}
|
|
552
|
-
throw new Error("Unknown caption of cell");
|
|
898
|
+
getCellByIndex(index) {
|
|
899
|
+
return this._getCell(index);
|
|
900
|
+
}
|
|
901
|
+
getCell(caption) {
|
|
902
|
+
return this._getCell(void 0, caption);
|
|
553
903
|
}
|
|
554
904
|
async select() {
|
|
555
905
|
const rowEl = await this.getElement();
|
|
556
906
|
await click(rowEl, this.driver);
|
|
557
|
-
await
|
|
558
|
-
const classes = await
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
return true;
|
|
562
|
-
}, 500);
|
|
907
|
+
await wait(async () => {
|
|
908
|
+
const classes = await this.getClasses();
|
|
909
|
+
return classes.includes(DX_SELECTION_CLASS);
|
|
910
|
+
}, this.driver, "Cannot select row");
|
|
563
911
|
}
|
|
564
912
|
async isSelected() {
|
|
565
|
-
const
|
|
566
|
-
const result = await rowEl.getAttribute("aria-selected");
|
|
913
|
+
const result = await this.getAttribute("aria-selected");
|
|
567
914
|
return result === "true";
|
|
568
915
|
}
|
|
569
916
|
getIndex() {
|
|
570
917
|
return this.index;
|
|
571
918
|
}
|
|
572
919
|
async getCells() {
|
|
573
|
-
const
|
|
574
|
-
const cells = await rowEl.findElements(import_selenium_webdriver11.By.css(`td[role="gridcell"]`));
|
|
920
|
+
const cells = await this.driver.findElements(import_selenium_webdriver16.By.css(`${this.getFullCssSelector()} td[role="gridcell"]`));
|
|
575
921
|
const result = [];
|
|
576
922
|
cells.forEach((_, index) => {
|
|
577
|
-
const newCell =
|
|
923
|
+
const newCell = this.getCellByIndex(index);
|
|
578
924
|
result.push(newCell);
|
|
579
925
|
});
|
|
580
926
|
return result;
|
|
581
927
|
}
|
|
582
|
-
async clickInlineButton(
|
|
583
|
-
const
|
|
584
|
-
|
|
585
|
-
);
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
928
|
+
async clickInlineButton(buttonClass) {
|
|
929
|
+
const FIXED_TABLE_CSS_SELECTOR = ".dx-fixed-columns .dx-datagrid-content.dx-datagrid-content-fixed";
|
|
930
|
+
const buttonCssSelector = `.${DX_DATA_ROW_CLASS}[aria-rowindex="${transformInputIndex(this.index)}"] .${buttonClass}`;
|
|
931
|
+
const button = await this.driver.findElement(import_selenium_webdriver16.By.css(`${this.parentCssSelector} ${FIXED_TABLE_CSS_SELECTOR} ${buttonCssSelector}`));
|
|
932
|
+
return click(button, this.driver);
|
|
933
|
+
}
|
|
934
|
+
async checkEditingMode(isEditing, msg) {
|
|
935
|
+
await wait(async () => {
|
|
936
|
+
return (await this.getClasses()).includes(DX_ROW_EDIT_CLASS) === isEditing;
|
|
937
|
+
}, this.driver, msg);
|
|
592
938
|
}
|
|
593
939
|
async edit() {
|
|
594
|
-
await this.
|
|
595
|
-
|
|
940
|
+
await this.clickInlineButton("edit");
|
|
941
|
+
await this.checkEditingMode(true, "Row did not switch to edit mode");
|
|
596
942
|
}
|
|
597
943
|
async save() {
|
|
598
|
-
|
|
944
|
+
await this.clickInlineButton("save");
|
|
945
|
+
await this.checkEditingMode(false, "Row did not saved");
|
|
599
946
|
}
|
|
600
947
|
async cancel() {
|
|
601
|
-
|
|
948
|
+
await this.clickInlineButton("cancel");
|
|
949
|
+
await this.checkEditingMode(false, "Row did not switch to normal mode");
|
|
602
950
|
}
|
|
603
951
|
};
|
|
604
952
|
|
|
605
953
|
// src/pageObjects/elements/Table/elements/Column.ts
|
|
954
|
+
var import_selenium_webdriver17 = require("selenium-webdriver");
|
|
955
|
+
var getHeaderCssSelector = () => {
|
|
956
|
+
return ".dx-datagrid-headers .dx-datagrid-content:not(.dx-datagrid-content-fixed)";
|
|
957
|
+
};
|
|
606
958
|
var Column = class extends AbstractElementWithParent {
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
959
|
+
_index;
|
|
960
|
+
_caption;
|
|
961
|
+
constructor(parentCssSelector, caption, index, driver) {
|
|
962
|
+
super(parentCssSelector, "", driver);
|
|
610
963
|
this.index = index;
|
|
611
|
-
this.
|
|
964
|
+
this._caption = caption;
|
|
965
|
+
}
|
|
966
|
+
set index(index) {
|
|
967
|
+
this._index = index;
|
|
968
|
+
this.elementCssSelector = getColumnByIndexCssSelector(index);
|
|
969
|
+
}
|
|
970
|
+
get index() {
|
|
971
|
+
return this._index;
|
|
972
|
+
}
|
|
973
|
+
async getElement() {
|
|
974
|
+
await this.getIndex();
|
|
975
|
+
return super.getElement();
|
|
976
|
+
}
|
|
977
|
+
async getIndexByCaption() {
|
|
978
|
+
const column = await this.driver.findElement(import_selenium_webdriver17.By.css(`${this.parentCssSelector} ${getHeaderCssSelector()} ${getColumnByCaptionCssSelector(this._caption)}`));
|
|
979
|
+
return transformOutputIndex(await column.getAttribute("aria-colindex"));
|
|
612
980
|
}
|
|
613
981
|
async caption() {
|
|
614
982
|
const el = await this.getElement();
|
|
615
983
|
return el.getText();
|
|
616
984
|
}
|
|
617
|
-
getIndex() {
|
|
985
|
+
async getIndex() {
|
|
986
|
+
if (this.index == null) {
|
|
987
|
+
this.index = await this.getIndexByCaption();
|
|
988
|
+
}
|
|
618
989
|
return this.index;
|
|
619
990
|
}
|
|
620
991
|
};
|
|
@@ -622,71 +993,36 @@ var Column = class extends AbstractElementWithParent {
|
|
|
622
993
|
// src/pageObjects/elements/Table/Table.ts
|
|
623
994
|
var Table = class extends AbstractElementWithParent {
|
|
624
995
|
formName;
|
|
625
|
-
constructor(
|
|
626
|
-
super(
|
|
627
|
-
this.elementBy = import_selenium_webdriver12.By.id(createTableId(formName));
|
|
996
|
+
constructor(parentCssSelector, formName, driver) {
|
|
997
|
+
super(parentCssSelector, `#${createTableId(formName)}`, driver);
|
|
628
998
|
this.formName = formName;
|
|
629
999
|
}
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
return parentEl.findElement(import_selenium_webdriver12.By.className("dx-header-row"));
|
|
1000
|
+
getRowByIndex(index) {
|
|
1001
|
+
return new Row(this.getFullCssSelector(), index, this.driver, this.getColumnByCaption.bind(this));
|
|
633
1002
|
}
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
return parentEl.findElement(import_selenium_webdriver12.By.css(`div[role="grid"]`));
|
|
1003
|
+
getColumnByIndex(index) {
|
|
1004
|
+
return new Column(this.getFullCssSelector(), void 0, index, this.driver);
|
|
637
1005
|
}
|
|
638
|
-
|
|
639
|
-
return this.
|
|
1006
|
+
getColumnByCaption = (caption) => {
|
|
1007
|
+
return new Column(this.getFullCssSelector(), caption, void 0, this.driver);
|
|
640
1008
|
};
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
const row = await gridContainer.findElement(getRowPathByIndex(index));
|
|
644
|
-
if (row) {
|
|
645
|
-
return new Row(this.getTableElement, index, this.driver, this.getColumnByCaption.bind(this));
|
|
646
|
-
}
|
|
647
|
-
throw new Error(`Cannot find row by index: ${index}`);
|
|
648
|
-
}
|
|
649
|
-
async getColumnByIndex(index) {
|
|
650
|
-
const headerContainer = await this.getHeaderElement();
|
|
651
|
-
const column = await headerContainer.findElement(getColumnPathByIndex(index));
|
|
652
|
-
if (column) {
|
|
653
|
-
return new Column(this.getTableElement, index, this.driver);
|
|
654
|
-
}
|
|
655
|
-
throw new Error(`Cannot find column by index: ${index}`);
|
|
656
|
-
}
|
|
657
|
-
async getColumnByCaption(caption) {
|
|
658
|
-
const headerContainer = await this.getHeaderElement();
|
|
659
|
-
const column = await headerContainer.findElement(getColumnPathByCaption(caption));
|
|
660
|
-
if (column) {
|
|
661
|
-
const index = await column.getAttribute("aria-colindex");
|
|
662
|
-
return new Column(this.getTableElement, transformOutputIndex(index), this.driver);
|
|
663
|
-
}
|
|
664
|
-
throw new Error(`Cannot find column by caption: ${caption}`);
|
|
665
|
-
}
|
|
666
|
-
async selectRowByIndex(index) {
|
|
667
|
-
const row = await this.getRowByIndex(index);
|
|
668
|
-
if (row) {
|
|
669
|
-
await row.select();
|
|
670
|
-
} else {
|
|
671
|
-
throw new Error(`Cannot find row by index: ${index}`);
|
|
672
|
-
}
|
|
1009
|
+
selectRowByIndex(index) {
|
|
1010
|
+
return this.getRowByIndex(index).select();
|
|
673
1011
|
}
|
|
674
1012
|
async getRows() {
|
|
675
|
-
const
|
|
676
|
-
const rows = await gridContainer.findElements(import_selenium_webdriver12.By.className("dx-row dx-data-row"));
|
|
1013
|
+
const rows = await this.driver.findElements(import_selenium_webdriver18.By.css(`${this.getFullCssSelector()} .dx-row.dx-data-row`));
|
|
677
1014
|
const result = [];
|
|
678
1015
|
rows.forEach((_, index) => {
|
|
679
|
-
const newRow = new Row(this.
|
|
1016
|
+
const newRow = new Row(this.getFullCssSelector(), index, this.driver, this.getColumnByCaption);
|
|
680
1017
|
result.push(newRow);
|
|
681
1018
|
});
|
|
682
1019
|
return result;
|
|
683
1020
|
}
|
|
684
1021
|
async getColumns() {
|
|
685
|
-
const
|
|
686
|
-
const columns = await headerContainer.findElements(import_selenium_webdriver12.By.css(`td[role="columnheader"]`));
|
|
1022
|
+
const columns = await this.driver.findElements(import_selenium_webdriver18.By.css(`${this.getFullCssSelector()} ${getHeaderCssSelector()} td[role="columnheader"]`));
|
|
687
1023
|
const result = [];
|
|
688
1024
|
columns.forEach((_, index) => {
|
|
689
|
-
const newCol = new Column(this.
|
|
1025
|
+
const newCol = new Column(this.getFullCssSelector(), void 0, index, this.driver);
|
|
690
1026
|
result.push(newCol);
|
|
691
1027
|
});
|
|
692
1028
|
return result;
|
|
@@ -702,49 +1038,39 @@ var Table = class extends AbstractElementWithParent {
|
|
|
702
1038
|
* expect(await form.field('Name').getValue()).toBe('test value');
|
|
703
1039
|
*/
|
|
704
1040
|
field(name) {
|
|
705
|
-
return new FormField(this.
|
|
1041
|
+
return new FormField(this.getFullCssSelector(), this.formName, name, this.driver);
|
|
706
1042
|
}
|
|
707
1043
|
};
|
|
708
1044
|
|
|
709
|
-
// src/pageObjects/elements/TableToolbar/TableToolbar.ts
|
|
710
|
-
var import_selenium_webdriver14 = require("selenium-webdriver");
|
|
711
|
-
|
|
712
1045
|
// src/pageObjects/elements/TableToolbar/TableToolbarButton.ts
|
|
713
|
-
var import_selenium_webdriver13 = require("selenium-webdriver");
|
|
714
1046
|
var TOOLBAR_BUTTON_CLASS = "toolbar-button";
|
|
715
1047
|
var TableToolbarButton = class extends AbstractElementWithParent {
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
1048
|
+
name;
|
|
1049
|
+
constructor(parentCssSelector, name, driver) {
|
|
1050
|
+
super(parentCssSelector, `#${TOOLBAR_BUTTON_CLASS}-${name}`, driver);
|
|
1051
|
+
this.name = name;
|
|
719
1052
|
}
|
|
720
1053
|
async click() {
|
|
721
1054
|
const button = await this.getElement();
|
|
722
|
-
|
|
1055
|
+
await wait(async () => {
|
|
1056
|
+
return await button.isDisplayed() && !await this.isDisabled();
|
|
1057
|
+
}, this.driver, `Button ${this.name} cannot be clicked. It is not displayed or it is disabled`);
|
|
1058
|
+
await click(button, this.driver);
|
|
723
1059
|
}
|
|
724
1060
|
async isDisabled() {
|
|
725
1061
|
const button = await this.getElement();
|
|
726
|
-
|
|
727
|
-
return result === "true";
|
|
1062
|
+
return await button.getCssValue("pointer-events") === "none";
|
|
728
1063
|
}
|
|
729
1064
|
};
|
|
730
1065
|
|
|
731
1066
|
// src/pageObjects/elements/TableToolbar/TableToolbar.ts
|
|
732
1067
|
var TABLE_TOOLBAR_CLASS = "d5-table-toolbar";
|
|
733
1068
|
var TableToolbar = class extends AbstractElementWithParent {
|
|
734
|
-
constructor(
|
|
735
|
-
super(
|
|
736
|
-
this.elementBy = import_selenium_webdriver14.By.id(`${TABLE_TOOLBAR_CLASS}-${formName}`);
|
|
1069
|
+
constructor(parentCssSelector, formName, driver) {
|
|
1070
|
+
super(parentCssSelector, `#${TABLE_TOOLBAR_CLASS}-${formName}`, driver);
|
|
737
1071
|
}
|
|
738
|
-
|
|
739
|
-
return this.
|
|
740
|
-
};
|
|
741
|
-
async button(name) {
|
|
742
|
-
const toolbar = await this.getTableToolbarElement();
|
|
743
|
-
const button = await toolbar.findElement(import_selenium_webdriver14.By.id(`${TOOLBAR_BUTTON_CLASS}-${name}`));
|
|
744
|
-
if (button) {
|
|
745
|
-
return new TableToolbarButton(this.getTableToolbarElement, name, this.driver);
|
|
746
|
-
}
|
|
747
|
-
throw new Error(`Cannot find button by name: ${name}`);
|
|
1072
|
+
button(name) {
|
|
1073
|
+
return new TableToolbarButton(this.getFullCssSelector(), name, this.driver);
|
|
748
1074
|
}
|
|
749
1075
|
};
|
|
750
1076
|
|
|
@@ -752,7 +1078,7 @@ var TableToolbar = class extends AbstractElementWithParent {
|
|
|
752
1078
|
var ListForm = class extends AbstractForm {
|
|
753
1079
|
constructor(driver) {
|
|
754
1080
|
super(driver);
|
|
755
|
-
this.
|
|
1081
|
+
this.popupContainerCssSelector = `.popup .form-inline-${this.formName}`;
|
|
756
1082
|
}
|
|
757
1083
|
/**
|
|
758
1084
|
* Находит таблицу
|
|
@@ -762,7 +1088,17 @@ var ListForm = class extends AbstractForm {
|
|
|
762
1088
|
* expect(listForm.table());
|
|
763
1089
|
*/
|
|
764
1090
|
table() {
|
|
765
|
-
return new Table(this.
|
|
1091
|
+
return new Table(this.containerCssSelector, this.formName, this.driver);
|
|
1092
|
+
}
|
|
1093
|
+
/**
|
|
1094
|
+
* Находит группу на лист форме по имени
|
|
1095
|
+
* @example
|
|
1096
|
+
* const formEdit = new MyForm();
|
|
1097
|
+
* //...
|
|
1098
|
+
* expect(await formEdit.group('Name');
|
|
1099
|
+
*/
|
|
1100
|
+
group(name) {
|
|
1101
|
+
return new FormGroup(this.containerCssSelector, this.formName, name, this.driver);
|
|
766
1102
|
}
|
|
767
1103
|
/**
|
|
768
1104
|
* Находит таблицу
|
|
@@ -772,7 +1108,7 @@ var ListForm = class extends AbstractForm {
|
|
|
772
1108
|
* expect(listForm.toolbarButton());
|
|
773
1109
|
*/
|
|
774
1110
|
toolbarButton(name) {
|
|
775
|
-
const toolbar = new TableToolbar(this.
|
|
1111
|
+
const toolbar = new TableToolbar(this.containerCssSelector, this.formName, this.driver);
|
|
776
1112
|
return toolbar.button(name);
|
|
777
1113
|
}
|
|
778
1114
|
};
|
|
@@ -800,6 +1136,14 @@ var LoginPage = class extends AbstractPage {
|
|
|
800
1136
|
usernameField = byTestId("loginField", "input");
|
|
801
1137
|
passwordField = byTestId("passwordField", "input");
|
|
802
1138
|
loginButton = byTestId("loginButton");
|
|
1139
|
+
async locate() {
|
|
1140
|
+
await super.locate();
|
|
1141
|
+
const login = await this.driver.findElement(this.usernameField);
|
|
1142
|
+
await waitElementIsVisible({
|
|
1143
|
+
element: login,
|
|
1144
|
+
driver: this.driver
|
|
1145
|
+
});
|
|
1146
|
+
}
|
|
803
1147
|
get path() {
|
|
804
1148
|
return LOGIN_PATH;
|
|
805
1149
|
}
|
|
@@ -832,10 +1176,13 @@ var LoginPage = class extends AbstractPage {
|
|
|
832
1176
|
SubsystemsPanel,
|
|
833
1177
|
TextEditor,
|
|
834
1178
|
byTestId,
|
|
1179
|
+
byTestIdCssSelector,
|
|
835
1180
|
click,
|
|
836
1181
|
config,
|
|
837
1182
|
createDriver,
|
|
838
1183
|
editorFactory,
|
|
839
1184
|
elementIsNotPresent,
|
|
840
|
-
signIn
|
|
1185
|
+
signIn,
|
|
1186
|
+
wait,
|
|
1187
|
+
waitElementIsVisible
|
|
841
1188
|
});
|