d5-testing-library 1.1.0 → 1.3.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 +669 -402
- package/dist/d5-testing-library.d.ts +197 -48
- package/dist/d5-testing-library.legacy-esm.js +656 -394
- package/dist/d5-testing-library.mjs +656 -394
- package/package.json +1 -1
|
@@ -38,11 +38,58 @@ function config(cfg) {
|
|
|
38
38
|
return configInstance.config(cfg);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
// src/pageObjects/AbstractElement.ts
|
|
42
|
+
import { By } from "selenium-webdriver";
|
|
43
|
+
|
|
44
|
+
// src/utils/waitElementIsVisible.ts
|
|
45
|
+
import { until } from "selenium-webdriver";
|
|
46
|
+
|
|
47
|
+
// src/utils/wait.ts
|
|
48
|
+
async function wait(condition, driver, errorMessage, timeout) {
|
|
49
|
+
driver = driver ?? config().driver;
|
|
50
|
+
await driver.wait(condition, timeout ?? config().timeout, errorMessage);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// src/utils/waitElementIsVisible.ts
|
|
54
|
+
async function waitElementIsVisible({
|
|
55
|
+
element,
|
|
56
|
+
timeout,
|
|
57
|
+
errorMessage,
|
|
58
|
+
driver
|
|
59
|
+
}) {
|
|
60
|
+
driver = driver ?? config().driver;
|
|
61
|
+
const condition = until.elementIsVisible(element);
|
|
62
|
+
await wait(condition.fn, driver, errorMessage ?? condition.description(), timeout ?? config().timeout);
|
|
63
|
+
}
|
|
64
|
+
|
|
41
65
|
// src/pageObjects/AbstractElement.ts
|
|
42
66
|
var AbstractElement = class {
|
|
43
67
|
driver;
|
|
44
|
-
|
|
68
|
+
elementCssSelector;
|
|
69
|
+
constructor(driver, elementCssSelector) {
|
|
45
70
|
this.driver = driver || config().driver;
|
|
71
|
+
this.elementCssSelector = elementCssSelector;
|
|
72
|
+
}
|
|
73
|
+
getFullCssSelector() {
|
|
74
|
+
return this.elementCssSelector;
|
|
75
|
+
}
|
|
76
|
+
async getElement() {
|
|
77
|
+
return this.driver.findElement(By.css(this.getFullCssSelector()));
|
|
78
|
+
}
|
|
79
|
+
async getAttribute(attr) {
|
|
80
|
+
const element = await this.getElement();
|
|
81
|
+
await waitElementIsVisible({
|
|
82
|
+
element,
|
|
83
|
+
driver: this.driver,
|
|
84
|
+
errorMessage: `Element not found: ${this.getFullCssSelector()}`
|
|
85
|
+
});
|
|
86
|
+
return await element.getAttribute(attr);
|
|
87
|
+
}
|
|
88
|
+
async getClasses() {
|
|
89
|
+
return await this.getAttribute("class");
|
|
90
|
+
}
|
|
91
|
+
async getDataTestId() {
|
|
92
|
+
return await this.getAttribute("data-testid");
|
|
46
93
|
}
|
|
47
94
|
};
|
|
48
95
|
|
|
@@ -75,10 +122,56 @@ var AbstractPage = class extends AbstractElement {
|
|
|
75
122
|
}
|
|
76
123
|
};
|
|
77
124
|
|
|
125
|
+
// src/utils/actions.ts
|
|
126
|
+
var click = async (webElement, driver) => {
|
|
127
|
+
driver = driver ?? config().driver;
|
|
128
|
+
const actions = driver.actions({ async: true });
|
|
129
|
+
await actions.move({ origin: webElement }).click().perform();
|
|
130
|
+
};
|
|
131
|
+
|
|
78
132
|
// src/utils/locators.ts
|
|
79
|
-
import { By } from "selenium-webdriver";
|
|
133
|
+
import { By as By2 } from "selenium-webdriver";
|
|
134
|
+
var byTestIdCssSelector = (testId, element = "div") => {
|
|
135
|
+
return `${element}[data-testid="${testId}"]`;
|
|
136
|
+
};
|
|
80
137
|
var byTestId = (testId, element = "div") => {
|
|
81
|
-
return
|
|
138
|
+
return By2.css(byTestIdCssSelector(testId, element));
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
// src/pageObjects/pages/LoginPage.ts
|
|
142
|
+
var LOGIN_PATH = "/login";
|
|
143
|
+
var LoginPage = class extends AbstractPage {
|
|
144
|
+
usernameField = byTestId("loginField", "input");
|
|
145
|
+
passwordField = byTestId("passwordField", "input");
|
|
146
|
+
loginButton = byTestId("loginButton");
|
|
147
|
+
async locate() {
|
|
148
|
+
await super.locate();
|
|
149
|
+
const login = await this.driver.findElement(this.usernameField);
|
|
150
|
+
await waitElementIsVisible({
|
|
151
|
+
element: login,
|
|
152
|
+
driver: this.driver
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
get path() {
|
|
156
|
+
return LOGIN_PATH;
|
|
157
|
+
}
|
|
158
|
+
async enterUsername(username) {
|
|
159
|
+
await this.driver.findElement(this.usernameField).sendKeys(username);
|
|
160
|
+
}
|
|
161
|
+
async enterPassword(password) {
|
|
162
|
+
await this.driver.findElement(this.passwordField).sendKeys(password);
|
|
163
|
+
}
|
|
164
|
+
async clickLoginButton() {
|
|
165
|
+
await click(await this.driver.findElement(this.loginButton), this.driver);
|
|
166
|
+
}
|
|
167
|
+
async loginWith(username, password) {
|
|
168
|
+
await this.enterUsername(username);
|
|
169
|
+
await this.enterPassword(password);
|
|
170
|
+
await this.clickLoginButton();
|
|
171
|
+
}
|
|
172
|
+
async authorize() {
|
|
173
|
+
await this.loginWith(config().auth.login, config().auth.password);
|
|
174
|
+
}
|
|
82
175
|
};
|
|
83
176
|
|
|
84
177
|
// src/utils/createDriver.ts
|
|
@@ -100,78 +193,67 @@ var elementIsNotPresent = function elementIsNotPresent2(locator) {
|
|
|
100
193
|
});
|
|
101
194
|
};
|
|
102
195
|
|
|
103
|
-
// src/utils/
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
const
|
|
108
|
-
await
|
|
196
|
+
// src/utils/signIn.ts
|
|
197
|
+
async function signIn(driver) {
|
|
198
|
+
const webDriver = driver ?? await createDriver();
|
|
199
|
+
config().driver = webDriver;
|
|
200
|
+
const loginPage = new LoginPage(webDriver);
|
|
201
|
+
await loginPage.locate();
|
|
202
|
+
await loginPage.authorize();
|
|
203
|
+
return webDriver;
|
|
109
204
|
}
|
|
110
205
|
|
|
111
206
|
// src/pageObjects/AbstractElementWithParent.ts
|
|
112
207
|
var AbstractElementWithParent = class extends AbstractElement {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
await waitElementIsVisible({
|
|
127
|
-
element: el,
|
|
128
|
-
driver: this.driver
|
|
129
|
-
});
|
|
130
|
-
return el;
|
|
131
|
-
}
|
|
132
|
-
async getAttribute(attr) {
|
|
133
|
-
const el = await this.getElement();
|
|
134
|
-
return await el.getAttribute(attr);
|
|
135
|
-
}
|
|
136
|
-
async getClasses() {
|
|
137
|
-
return await this.getAttribute("class");
|
|
208
|
+
parentCssSelector;
|
|
209
|
+
constructor(parentCssSelector, elementCssSelector, driver) {
|
|
210
|
+
super(driver, elementCssSelector);
|
|
211
|
+
this.parentCssSelector = parentCssSelector;
|
|
212
|
+
}
|
|
213
|
+
getFullCssSelector() {
|
|
214
|
+
if (!this.elementCssSelector) {
|
|
215
|
+
return this.parentCssSelector;
|
|
216
|
+
}
|
|
217
|
+
if (!this.parentCssSelector) {
|
|
218
|
+
return this.elementCssSelector;
|
|
219
|
+
}
|
|
220
|
+
return `${this.parentCssSelector} ${this.elementCssSelector}`;
|
|
138
221
|
}
|
|
139
222
|
};
|
|
140
223
|
|
|
141
224
|
// src/pageObjects/elements/SubsystemsPanel/SubsystemsPanelHeader.ts
|
|
225
|
+
import { By as By4 } from "selenium-webdriver";
|
|
142
226
|
var SubsystemsPanelHeader = class extends AbstractElementWithParent {
|
|
143
|
-
titleBy = byTestId("subsystems-panel-title", "span");
|
|
144
227
|
async title() {
|
|
145
|
-
|
|
146
|
-
return panel.findElement(this.titleBy);
|
|
228
|
+
return this.driver.findElement(By4.css(this.getFullCssSelector()));
|
|
147
229
|
}
|
|
148
230
|
};
|
|
149
231
|
|
|
150
232
|
// src/pageObjects/elements/SubsystemsPanel/SubsystemsPanel.ts
|
|
151
|
-
import { By as By3 } from "selenium-webdriver";
|
|
152
233
|
var SubsystemsPanel = class extends AbstractElement {
|
|
153
|
-
panelBy = By3.id("aside");
|
|
154
234
|
header;
|
|
155
235
|
constructor(driver) {
|
|
156
236
|
super(driver);
|
|
157
|
-
this.header = new SubsystemsPanelHeader(
|
|
237
|
+
this.header = new SubsystemsPanelHeader("#aside", byTestIdCssSelector("subsystems-panel-title", "span"), this.driver);
|
|
158
238
|
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
return this.header.title().then((el) => el.getText());
|
|
239
|
+
async headerTitle() {
|
|
240
|
+
const title = await this.header.title();
|
|
241
|
+
await wait(async () => await title.getText() != "", this.driver);
|
|
242
|
+
return title.getText();
|
|
164
243
|
}
|
|
165
244
|
};
|
|
166
245
|
|
|
167
246
|
// src/pageObjects/elements/Forms/AbstractForm.ts
|
|
168
|
-
import { By as
|
|
247
|
+
import { By as By5 } from "selenium-webdriver";
|
|
169
248
|
var AbstractForm = class extends AbstractPage {
|
|
249
|
+
containerCssSelector = "";
|
|
170
250
|
containerBy;
|
|
171
|
-
|
|
251
|
+
popupContainerCssSelector;
|
|
172
252
|
constructor(driver) {
|
|
173
253
|
super(driver);
|
|
174
|
-
|
|
254
|
+
const testId = `form-content-wrapper-${this.formName}`;
|
|
255
|
+
this.containerBy = byTestId(testId);
|
|
256
|
+
this.containerCssSelector = byTestIdCssSelector(testId);
|
|
175
257
|
}
|
|
176
258
|
async isModal() {
|
|
177
259
|
const el = await this.getContainerElement();
|
|
@@ -194,10 +276,10 @@ var AbstractForm = class extends AbstractPage {
|
|
|
194
276
|
*/
|
|
195
277
|
async exists() {
|
|
196
278
|
try {
|
|
197
|
-
await this.driver.
|
|
279
|
+
let elements = await this.driver.findElements(this.containerBy);
|
|
280
|
+
return elements.length > 0;
|
|
281
|
+
} catch (error) {
|
|
198
282
|
return false;
|
|
199
|
-
} catch {
|
|
200
|
-
return true;
|
|
201
283
|
}
|
|
202
284
|
}
|
|
203
285
|
/**
|
|
@@ -209,29 +291,42 @@ var AbstractForm = class extends AbstractPage {
|
|
|
209
291
|
*/
|
|
210
292
|
async getTitleText() {
|
|
211
293
|
if (await this.isModal()) {
|
|
212
|
-
const
|
|
213
|
-
const titleEl2 = await popupEl.findElement(By4.className("popup-title"));
|
|
294
|
+
const titleEl2 = await this.driver.findElement(By5.css(`${this.popupContainerCssSelector} .popup-title`));
|
|
214
295
|
return titleEl2.getText();
|
|
215
296
|
}
|
|
216
|
-
let
|
|
217
|
-
let titleEl = await container.findElement(By4.className("form-toolbar-name-container"));
|
|
297
|
+
let titleEl = await this.driver.findElement(By5.className("main-toolbar-form-title"));
|
|
218
298
|
return titleEl.getText();
|
|
219
299
|
}
|
|
220
300
|
};
|
|
221
301
|
|
|
222
302
|
// src/pageObjects/elements/Forms/FormEdit.ts
|
|
223
|
-
import { By as
|
|
303
|
+
import { By as By12 } from "selenium-webdriver";
|
|
224
304
|
|
|
225
|
-
// src/
|
|
226
|
-
|
|
305
|
+
// src/utils/createDataTestId.ts
|
|
306
|
+
function createDataTestId(formName, itemType, itemName) {
|
|
307
|
+
return `${formName}-${itemType}-${itemName}`;
|
|
308
|
+
}
|
|
309
|
+
function createFieldTestId(formName, itemName) {
|
|
310
|
+
return createDataTestId(formName, "form_field" /* FORM_FIELD */, itemName);
|
|
311
|
+
}
|
|
312
|
+
function createGroupTestId(formName, itemName) {
|
|
313
|
+
return createDataTestId(formName, "group" /* GROUP */, itemName);
|
|
314
|
+
}
|
|
315
|
+
function createFilterTestId(formName, itemName, layout) {
|
|
316
|
+
return createDataTestId(formName, "filter" /* FILTER */, itemName) + `-${layout}`;
|
|
317
|
+
}
|
|
318
|
+
function createDocFilterTestId(formName, itemName) {
|
|
319
|
+
return createFilterTestId(formName, itemName, "dock-panel-filter" /* DOCK_PANEL */);
|
|
320
|
+
}
|
|
321
|
+
function createLayoutFilterTestId(formName, itemName) {
|
|
322
|
+
return createFilterTestId(formName, itemName, "layout-filter" /* LAYOUT */);
|
|
323
|
+
}
|
|
324
|
+
function createTableId(formName) {
|
|
325
|
+
return `${"table" /* TABLE */}-${formName}`;
|
|
326
|
+
}
|
|
227
327
|
|
|
228
|
-
// src/pageObjects/
|
|
229
|
-
|
|
230
|
-
constructor(getParentElement, elementBy, driver) {
|
|
231
|
-
super(getParentElement, driver);
|
|
232
|
-
this.elementBy = elementBy;
|
|
233
|
-
}
|
|
234
|
-
};
|
|
328
|
+
// src/pageObjects/elements/Editors/AbstractEditor.ts
|
|
329
|
+
import { By as By6, Key } from "selenium-webdriver";
|
|
235
330
|
|
|
236
331
|
// src/pageObjects/elements/Editors/ClearStrategy/InputClearStrategy.ts
|
|
237
332
|
var InputClearStrategy = class {
|
|
@@ -242,14 +337,16 @@ var InputClearStrategy = class {
|
|
|
242
337
|
};
|
|
243
338
|
|
|
244
339
|
// src/pageObjects/elements/Editors/AbstractEditor.ts
|
|
245
|
-
var AbstractDXEditorWithInput = class extends
|
|
340
|
+
var AbstractDXEditorWithInput = class extends AbstractElementWithParent {
|
|
246
341
|
clearStrategy = new InputClearStrategy();
|
|
247
342
|
setClearStrategy(strategy) {
|
|
248
343
|
this.clearStrategy = strategy;
|
|
249
344
|
}
|
|
345
|
+
getInputCssSelector() {
|
|
346
|
+
return `${this.getFullCssSelector()} .dx-texteditor-input`;
|
|
347
|
+
}
|
|
250
348
|
async getInputElement() {
|
|
251
|
-
|
|
252
|
-
return controlEl.findElement(By5.className("dx-texteditor-input"));
|
|
349
|
+
return this.driver.findElement(By6.css(this.getInputCssSelector()));
|
|
253
350
|
}
|
|
254
351
|
async getInputValue() {
|
|
255
352
|
const inputEl = await this.getInputElement();
|
|
@@ -267,8 +364,8 @@ var AbstractDXEditorWithInput = class extends AbstractFormElement {
|
|
|
267
364
|
|
|
268
365
|
// src/pageObjects/elements/Editors/TextEditor.ts
|
|
269
366
|
var TextEditor = class extends AbstractDXEditorWithInput {
|
|
270
|
-
constructor(
|
|
271
|
-
super(
|
|
367
|
+
constructor(parentCssSelector, elementCssSelector, driver) {
|
|
368
|
+
super(parentCssSelector, elementCssSelector, driver);
|
|
272
369
|
this.setClearStrategy(new InputClearStrategy());
|
|
273
370
|
}
|
|
274
371
|
getValue() {
|
|
@@ -281,8 +378,8 @@ var TextEditor = class extends AbstractDXEditorWithInput {
|
|
|
281
378
|
|
|
282
379
|
// src/pageObjects/elements/Editors/NumberEditor.ts
|
|
283
380
|
var NumberEditor = class extends AbstractDXEditorWithInput {
|
|
284
|
-
constructor(
|
|
285
|
-
super(
|
|
381
|
+
constructor(parentCssSelector, elementCssSelector, driver) {
|
|
382
|
+
super(parentCssSelector, elementCssSelector, driver);
|
|
286
383
|
this.setClearStrategy(new InputClearStrategy());
|
|
287
384
|
}
|
|
288
385
|
async getValue() {
|
|
@@ -294,11 +391,17 @@ var NumberEditor = class extends AbstractDXEditorWithInput {
|
|
|
294
391
|
}
|
|
295
392
|
};
|
|
296
393
|
|
|
394
|
+
// src/pageObjects/AbstractFormElement.ts
|
|
395
|
+
var AbstractFormElement = class extends AbstractElementWithParent {
|
|
396
|
+
constructor(parentCssSelector, elementCssSelector, driver) {
|
|
397
|
+
super(parentCssSelector, elementCssSelector, driver);
|
|
398
|
+
}
|
|
399
|
+
};
|
|
400
|
+
|
|
297
401
|
// src/pageObjects/elements/Editors/CheckBox.ts
|
|
298
|
-
var CheckBox = class extends
|
|
402
|
+
var CheckBox = class extends AbstractElementWithParent {
|
|
299
403
|
async getValue() {
|
|
300
|
-
const
|
|
301
|
-
const result = await inputEl.getAttribute("aria-checked");
|
|
404
|
+
const result = await this.getAttribute("aria-checked");
|
|
302
405
|
if (result === "true")
|
|
303
406
|
return 1;
|
|
304
407
|
if (result === "false")
|
|
@@ -315,7 +418,7 @@ var CheckBox = class extends AbstractFormElement {
|
|
|
315
418
|
};
|
|
316
419
|
|
|
317
420
|
// src/pageObjects/elements/Editors/SelectBoxEditor.ts
|
|
318
|
-
import { By as
|
|
421
|
+
import { By as By8, Key as Key2 } from "selenium-webdriver";
|
|
319
422
|
|
|
320
423
|
// src/utils/xpathHelper.ts
|
|
321
424
|
var XPathHelper = class {
|
|
@@ -328,28 +431,28 @@ var XPathHelper = class {
|
|
|
328
431
|
};
|
|
329
432
|
|
|
330
433
|
// src/pageObjects/elements/Editors/ClearStrategy/ClearButtonStrategy.ts
|
|
331
|
-
import { By as
|
|
434
|
+
import { By as By7 } from "selenium-webdriver";
|
|
332
435
|
var DX_TEXTEDITOR_EMPTY = "dx-texteditor-empty";
|
|
333
436
|
var DX_CLEAR_BUTTON_AREA = "dx-clear-button-area";
|
|
334
437
|
var ClearButtonStrategy = class {
|
|
335
438
|
editorContainerClass;
|
|
336
|
-
|
|
439
|
+
_driver;
|
|
440
|
+
constructor(editorContainerClass, driver) {
|
|
337
441
|
this.editorContainerClass = editorContainerClass;
|
|
442
|
+
this._driver = driver;
|
|
338
443
|
}
|
|
339
|
-
async isEmptyEditorField(
|
|
340
|
-
const
|
|
341
|
-
const editorContainer = await parentEl.findElement(By6.className(this.editorContainerClass));
|
|
444
|
+
async isEmptyEditorField() {
|
|
445
|
+
const editorContainer = await this._driver.findElement(By7.css(this.editorContainerClass));
|
|
342
446
|
const classAttribute = await editorContainer.getAttribute("class");
|
|
343
447
|
return classAttribute.includes(DX_TEXTEDITOR_EMPTY);
|
|
344
448
|
}
|
|
345
|
-
async clear(
|
|
346
|
-
if (await this.isEmptyEditorField(
|
|
449
|
+
async clear() {
|
|
450
|
+
if (await this.isEmptyEditorField()) {
|
|
347
451
|
throw new Error("This field is already empty");
|
|
348
452
|
}
|
|
349
|
-
const clearBtnSelector =
|
|
350
|
-
const
|
|
351
|
-
|
|
352
|
-
await click(clearBtn, editor.driver);
|
|
453
|
+
const clearBtnSelector = `${this.editorContainerClass} .${DX_CLEAR_BUTTON_AREA}`;
|
|
454
|
+
const clearBtn = await this._driver.findElement(By7.css(clearBtnSelector));
|
|
455
|
+
await click(clearBtn, this._driver);
|
|
353
456
|
}
|
|
354
457
|
};
|
|
355
458
|
|
|
@@ -360,25 +463,17 @@ var combinedValueXpath = (value) => `${XPathHelper.getRoleXpath(SELECT_BOX_ELEME
|
|
|
360
463
|
SELECT_BOX_OPTION_TEXT_CONTAINER_CLASS,
|
|
361
464
|
value
|
|
362
465
|
)}`;
|
|
363
|
-
var DX_SELECTBOX = "dx-selectbox";
|
|
364
466
|
var SelectBoxEditor = class extends AbstractDXEditorWithInput {
|
|
365
|
-
constructor(
|
|
366
|
-
super(
|
|
367
|
-
this.setClearStrategy(new ClearButtonStrategy(
|
|
467
|
+
constructor(parentCssSelector, elementCssSelector, driver) {
|
|
468
|
+
super(parentCssSelector, elementCssSelector, driver);
|
|
469
|
+
this.setClearStrategy(new ClearButtonStrategy(this.getFullCssSelector(), this.driver));
|
|
368
470
|
}
|
|
369
471
|
async setSelectInputValue(value) {
|
|
370
472
|
const inputEl = await this.getInputElement();
|
|
371
473
|
await click(inputEl, this.driver);
|
|
372
474
|
await inputEl.sendKeys(value, Key2.ENTER);
|
|
373
|
-
await
|
|
374
|
-
|
|
375
|
-
const optElement = await inputEl.findElement(By7.xpath(combinedValueXpath(value)));
|
|
376
|
-
await click(optElement, this.driver);
|
|
377
|
-
return true;
|
|
378
|
-
} catch (e) {
|
|
379
|
-
return false;
|
|
380
|
-
}
|
|
381
|
-
}, 2e3);
|
|
475
|
+
const optElement = await inputEl.findElement(By8.xpath(combinedValueXpath(value)));
|
|
476
|
+
await click(optElement, this.driver);
|
|
382
477
|
}
|
|
383
478
|
async getValue() {
|
|
384
479
|
const value = await super.getInputValue();
|
|
@@ -390,10 +485,9 @@ var SelectBoxEditor = class extends AbstractDXEditorWithInput {
|
|
|
390
485
|
};
|
|
391
486
|
|
|
392
487
|
// src/pageObjects/elements/Editors/SwitchEditor.ts
|
|
393
|
-
var SwitchEditor = class extends
|
|
488
|
+
var SwitchEditor = class extends AbstractElementWithParent {
|
|
394
489
|
async getValue() {
|
|
395
|
-
const
|
|
396
|
-
const result = await inputEl.getAttribute("aria-label");
|
|
490
|
+
const result = await this.getAttribute("aria-label");
|
|
397
491
|
if (result === "ON")
|
|
398
492
|
return 1;
|
|
399
493
|
if (result === "OFF")
|
|
@@ -406,27 +500,28 @@ var SwitchEditor = class extends AbstractFormElement {
|
|
|
406
500
|
}
|
|
407
501
|
const inputEl = await this.getElement();
|
|
408
502
|
const currentValue = await this.getValue();
|
|
409
|
-
if (currentValue
|
|
410
|
-
|
|
411
|
-
await this.driver.wait(async () => {
|
|
412
|
-
const updatedValue = await this.getValue();
|
|
413
|
-
return updatedValue !== currentValue;
|
|
414
|
-
});
|
|
503
|
+
if (currentValue === value) {
|
|
504
|
+
return;
|
|
415
505
|
}
|
|
506
|
+
await click(inputEl, this.driver);
|
|
507
|
+
await wait(async () => {
|
|
508
|
+
const updatedValue = await this.getValue();
|
|
509
|
+
return updatedValue !== currentValue;
|
|
510
|
+
}, this.driver);
|
|
416
511
|
}
|
|
417
512
|
};
|
|
418
513
|
|
|
419
514
|
// src/pageObjects/elements/Editors/TagBox.ts
|
|
420
|
-
import { By as
|
|
515
|
+
import { By as By9 } from "selenium-webdriver";
|
|
421
516
|
var TAGS_SELECTOR = ".dx-tag .tag-text";
|
|
422
517
|
var DX_TAG_CONTAINER = "dx-tag-container";
|
|
423
|
-
var DX_TAGBOX = "dx-tagbox";
|
|
424
518
|
var DX_TEXTEDITOR_EMPTY2 = "dx-texteditor-empty";
|
|
425
519
|
var BTN_OK_SELECTOR = ".dx-tagbox-popup-wrapper .dx-popup-bottom .dx-button.dx-popup-done";
|
|
520
|
+
var TAG_BOX_LIST_ITEM_SELECTOR = '.dx-tagbox-popup-wrapper .dx-list-item[aria-selected="true"]';
|
|
426
521
|
var TagBox = class extends AbstractDXEditorWithInput {
|
|
427
|
-
constructor(
|
|
428
|
-
super(
|
|
429
|
-
this.setClearStrategy(new ClearButtonStrategy(
|
|
522
|
+
constructor(parentCssSelector, elementCssSelector, driver) {
|
|
523
|
+
super(parentCssSelector, elementCssSelector, driver);
|
|
524
|
+
this.setClearStrategy(new ClearButtonStrategy(this.getFullCssSelector(), this.driver));
|
|
430
525
|
}
|
|
431
526
|
async setTagBoxInputValue(values) {
|
|
432
527
|
const lastElement = values[values.length - 1];
|
|
@@ -437,37 +532,28 @@ var TagBox = class extends AbstractDXEditorWithInput {
|
|
|
437
532
|
}
|
|
438
533
|
await this.confirmSelection();
|
|
439
534
|
}
|
|
535
|
+
async waitOptionSelection() {
|
|
536
|
+
const option = await this.driver.findElement(By9.css(TAG_BOX_LIST_ITEM_SELECTOR));
|
|
537
|
+
await wait(() => option.isDisplayed(), this.driver);
|
|
538
|
+
}
|
|
440
539
|
async selectOption(inputEl, value, lastElement) {
|
|
441
540
|
await inputEl.sendKeys(value);
|
|
442
|
-
await
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
await click(optElement, this.driver);
|
|
446
|
-
return true;
|
|
447
|
-
} catch (e) {
|
|
448
|
-
return false;
|
|
449
|
-
}
|
|
450
|
-
});
|
|
541
|
+
const optElement = await inputEl.findElement(By9.xpath(combinedValueXpath(value)));
|
|
542
|
+
await click(optElement, this.driver);
|
|
543
|
+
await this.waitOptionSelection();
|
|
451
544
|
if (value !== lastElement) {
|
|
452
545
|
await inputEl.clear();
|
|
453
546
|
}
|
|
454
547
|
}
|
|
455
548
|
async confirmSelection() {
|
|
456
|
-
const
|
|
457
|
-
const option = await inputEl.findElement(By8.xpath(XPathHelper.getRoleXpath(SELECT_BOX_ELEMENT_ROLE)));
|
|
458
|
-
const btnOk = await this.driver.findElement(By8.css(BTN_OK_SELECTOR));
|
|
459
|
-
await this.driver.wait(async () => {
|
|
460
|
-
return await option.getAttribute("aria-selected") === "true";
|
|
461
|
-
});
|
|
549
|
+
const btnOk = await this.driver.findElement(By9.css(BTN_OK_SELECTOR));
|
|
462
550
|
await click(btnOk, this.driver);
|
|
463
551
|
}
|
|
464
552
|
async getTagBoxInputValue() {
|
|
465
553
|
if (await this.isTagBoxEmpty()) {
|
|
466
554
|
return [];
|
|
467
555
|
}
|
|
468
|
-
const
|
|
469
|
-
const inputEl = await parentEl.findElement(By8.className(DX_TAG_CONTAINER));
|
|
470
|
-
const tags = await inputEl.findElements(By8.css(TAGS_SELECTOR));
|
|
556
|
+
const tags = await this.driver.findElements(By9.css(`${this.getFullCssSelector()} .${DX_TAG_CONTAINER} ${TAGS_SELECTOR}`));
|
|
471
557
|
const values = [];
|
|
472
558
|
for (const tag of tags) {
|
|
473
559
|
const text = await tag.getText();
|
|
@@ -476,9 +562,7 @@ var TagBox = class extends AbstractDXEditorWithInput {
|
|
|
476
562
|
return values;
|
|
477
563
|
}
|
|
478
564
|
async isTagBoxEmpty() {
|
|
479
|
-
const
|
|
480
|
-
const tagboxContainer = await parentEl.findElement(By8.className(DX_TAGBOX));
|
|
481
|
-
const classAttribute = await tagboxContainer.getAttribute("class");
|
|
565
|
+
const classAttribute = await this.getClasses();
|
|
482
566
|
return classAttribute.includes(DX_TEXTEDITOR_EMPTY2);
|
|
483
567
|
}
|
|
484
568
|
async getValue() {
|
|
@@ -497,28 +581,25 @@ var TagBox = class extends AbstractDXEditorWithInput {
|
|
|
497
581
|
if (!tagExists) {
|
|
498
582
|
throw new Error(`The tag with the text: ${itemText} was not found`);
|
|
499
583
|
}
|
|
500
|
-
const
|
|
501
|
-
const
|
|
502
|
-
const clearBtnTestId = byTestId(`clear-button-${itemText}`);
|
|
503
|
-
const clearBtn = await inputEl.findElement(clearBtnTestId);
|
|
584
|
+
const clearBtnTestId = byTestIdCssSelector(`clear-button-${itemText}`);
|
|
585
|
+
const clearBtn = await this.driver.findElement(By9.css(`${this.getFullCssSelector()} .${DX_TAG_CONTAINER} ${clearBtnTestId}`));
|
|
504
586
|
await click(clearBtn, this.driver);
|
|
505
587
|
}
|
|
506
588
|
};
|
|
507
589
|
|
|
508
590
|
// src/pageObjects/elements/Editors/ButtonGroup.ts
|
|
509
|
-
import { By as
|
|
591
|
+
import { By as By10 } from "selenium-webdriver";
|
|
510
592
|
var ITEM_CLASS = "dx-buttongroup-item";
|
|
511
593
|
var SELECTED_CLASS = "dx-state-selected";
|
|
512
|
-
var ButtonGroup = class extends
|
|
513
|
-
|
|
514
|
-
return
|
|
594
|
+
var ButtonGroup = class extends AbstractElementWithParent {
|
|
595
|
+
getItems() {
|
|
596
|
+
return this.driver.findElements(By10.css(`${this.getFullCssSelector()} .${ITEM_CLASS}`));
|
|
515
597
|
}
|
|
516
598
|
getDataValue(el) {
|
|
517
599
|
return el.getAttribute("data-value");
|
|
518
600
|
}
|
|
519
601
|
async getValue() {
|
|
520
|
-
const
|
|
521
|
-
const selectedEl = await inputEl.findElement(By9.className(`${ITEM_CLASS} ${SELECTED_CLASS}`));
|
|
602
|
+
const selectedEl = await this.driver.findElement(By10.css(`${this.getFullCssSelector()} .${ITEM_CLASS}.${SELECTED_CLASS}`));
|
|
522
603
|
return this.getDataValue(selectedEl);
|
|
523
604
|
}
|
|
524
605
|
async setValue(value) {
|
|
@@ -552,19 +633,14 @@ var BooleanSelector = class extends ButtonGroup {
|
|
|
552
633
|
};
|
|
553
634
|
|
|
554
635
|
// src/pageObjects/elements/Editors/DateEditor.ts
|
|
555
|
-
import { By as
|
|
636
|
+
import { By as By11, Key as Key3 } from "selenium-webdriver";
|
|
556
637
|
var DateEditor = class extends AbstractDXEditorWithInput {
|
|
557
|
-
constructor(
|
|
558
|
-
super(
|
|
638
|
+
constructor(parentCssSelector, elementCssSelector, driver) {
|
|
639
|
+
super(parentCssSelector, elementCssSelector, driver);
|
|
559
640
|
this.setClearStrategy(new InputClearStrategy());
|
|
560
641
|
}
|
|
561
|
-
async getControlElement() {
|
|
562
|
-
const controlEl = await this.getElement();
|
|
563
|
-
return controlEl.findElement(By10.className("dx-dropdowneditor-input-wrapper"));
|
|
564
|
-
}
|
|
565
642
|
async getDateElement() {
|
|
566
|
-
|
|
567
|
-
return controlEl.findElement(By10.css("input[type=hidden]"));
|
|
643
|
+
return this.driver.findElement(By11.css(this.getFullCssSelector() + " .dx-dropdowneditor-input-wrapper input[type=hidden]"));
|
|
568
644
|
}
|
|
569
645
|
async setDateValue(value) {
|
|
570
646
|
const dateEl = await this.getInputElement();
|
|
@@ -594,54 +670,39 @@ var DateEditor = class extends AbstractDXEditorWithInput {
|
|
|
594
670
|
};
|
|
595
671
|
|
|
596
672
|
// src/pageObjects/elements/Editors/editorFactory.ts
|
|
597
|
-
var editorFactory = async (
|
|
598
|
-
const elementInstance = new AbstractFormElement(
|
|
673
|
+
var editorFactory = async (parentCssSelector, elementCssSelector, driver) => {
|
|
674
|
+
const elementInstance = new AbstractFormElement(parentCssSelector, elementCssSelector, driver);
|
|
599
675
|
const classSting = await elementInstance.getClasses();
|
|
600
676
|
if (classSting.includes("text-control"))
|
|
601
|
-
return new TextEditor(
|
|
677
|
+
return new TextEditor(parentCssSelector, elementCssSelector, driver);
|
|
602
678
|
if (classSting.includes("number-control"))
|
|
603
|
-
return new NumberEditor(
|
|
679
|
+
return new NumberEditor(parentCssSelector, elementCssSelector, driver);
|
|
604
680
|
if (classSting.includes("check-box"))
|
|
605
|
-
return new CheckBox(
|
|
681
|
+
return new CheckBox(parentCssSelector, elementCssSelector, driver);
|
|
606
682
|
if (classSting.includes("multi-select-control"))
|
|
607
|
-
return new TagBox(
|
|
683
|
+
return new TagBox(parentCssSelector, elementCssSelector, driver);
|
|
608
684
|
if (classSting.includes("select-control"))
|
|
609
|
-
return new SelectBoxEditor(
|
|
685
|
+
return new SelectBoxEditor(parentCssSelector, elementCssSelector, driver);
|
|
610
686
|
if (classSting.includes("switch-control"))
|
|
611
|
-
return new SwitchEditor(
|
|
687
|
+
return new SwitchEditor(parentCssSelector, elementCssSelector, driver);
|
|
612
688
|
if (classSting.includes("date-control"))
|
|
613
|
-
return new DateEditor(
|
|
689
|
+
return new DateEditor(parentCssSelector, elementCssSelector, driver);
|
|
614
690
|
if (classSting.includes("buttons-group"))
|
|
615
|
-
return new BooleanSelector(
|
|
691
|
+
return new BooleanSelector(parentCssSelector, elementCssSelector, driver);
|
|
616
692
|
if (classSting.includes("button-group-field"))
|
|
617
|
-
return new ButtonGroup(
|
|
693
|
+
return new ButtonGroup(parentCssSelector, elementCssSelector, driver);
|
|
618
694
|
throw new Error("Unknown type of editor. Please write ticket to the support");
|
|
619
695
|
};
|
|
620
696
|
|
|
621
|
-
// src/
|
|
622
|
-
|
|
623
|
-
return `${formName}-${itemType}-${itemName}`;
|
|
624
|
-
}
|
|
625
|
-
function createFieldTestId(formName, itemName) {
|
|
626
|
-
return createDataTestId(formName, "form_field" /* FORM_FIELD */, itemName);
|
|
627
|
-
}
|
|
628
|
-
function createGroupTestId(formName, itemName) {
|
|
629
|
-
return createDataTestId(formName, "group" /* GROUP */, itemName);
|
|
630
|
-
}
|
|
631
|
-
function createTableId(formName) {
|
|
632
|
-
return `${"table" /* TABLE */}-${formName}`;
|
|
633
|
-
}
|
|
634
|
-
|
|
635
|
-
// src/pageObjects/elements/FormField.ts
|
|
636
|
-
var FormField = class extends AbstractElementWithParent {
|
|
697
|
+
// src/pageObjects/elements/AbstractEditor.ts
|
|
698
|
+
var AbstractEditor = class extends AbstractElementWithParent {
|
|
637
699
|
editor;
|
|
638
|
-
constructor(
|
|
639
|
-
super(
|
|
640
|
-
this.elementBy = byTestId(createFieldTestId(formName, name));
|
|
700
|
+
constructor(parentCssSelector, elementCssSelector, driver) {
|
|
701
|
+
super(parentCssSelector, elementCssSelector, driver);
|
|
641
702
|
}
|
|
642
703
|
async initEditor() {
|
|
643
704
|
if (!this.editor) {
|
|
644
|
-
this.editor = await editorFactory(this.
|
|
705
|
+
this.editor = await editorFactory(this.parentCssSelector, this.elementCssSelector, this.driver);
|
|
645
706
|
}
|
|
646
707
|
}
|
|
647
708
|
/**
|
|
@@ -690,37 +751,43 @@ var FormField = class extends AbstractElementWithParent {
|
|
|
690
751
|
}
|
|
691
752
|
};
|
|
692
753
|
|
|
693
|
-
// src/pageObjects/elements/
|
|
694
|
-
var
|
|
754
|
+
// src/pageObjects/elements/FormField.ts
|
|
755
|
+
var FormField = class extends AbstractEditor {
|
|
756
|
+
constructor(parentCssSelector, formName, name, driver) {
|
|
757
|
+
super(parentCssSelector, byTestIdCssSelector(createFieldTestId(formName, name)), driver);
|
|
758
|
+
}
|
|
695
759
|
};
|
|
696
760
|
|
|
697
|
-
// src/pageObjects/elements/Groups/
|
|
698
|
-
var
|
|
761
|
+
// src/pageObjects/elements/Groups/AbstractGroup.ts
|
|
762
|
+
var AbstractGroup = class extends AbstractElementWithParent {
|
|
699
763
|
async isDisplayed() {
|
|
700
764
|
const groupElement = await this.getElement();
|
|
701
765
|
return await groupElement.isDisplayed();
|
|
702
766
|
}
|
|
703
767
|
};
|
|
704
768
|
|
|
769
|
+
// src/pageObjects/elements/Groups/Panel.ts
|
|
770
|
+
var Panel = class extends AbstractGroup {
|
|
771
|
+
};
|
|
772
|
+
|
|
705
773
|
// src/pageObjects/elements/Groups/groupFactory.ts
|
|
706
|
-
var groupFactory = async (
|
|
707
|
-
const elementInstance = new AbstractFormElement(
|
|
774
|
+
var groupFactory = async (parentCssSelector, elementCssSelector, driver) => {
|
|
775
|
+
const elementInstance = new AbstractFormElement(parentCssSelector, elementCssSelector, driver);
|
|
708
776
|
const classSting = await elementInstance.getClasses();
|
|
709
777
|
if (classSting.includes("panel-group"))
|
|
710
|
-
return new Panel(
|
|
778
|
+
return new Panel(parentCssSelector, elementCssSelector, driver);
|
|
711
779
|
throw new Error("Unknown type of group. Please write ticket to the support");
|
|
712
780
|
};
|
|
713
781
|
|
|
714
782
|
// src/pageObjects/elements/FormGroup.ts
|
|
715
783
|
var FormGroup = class extends AbstractElementWithParent {
|
|
716
784
|
editor;
|
|
717
|
-
constructor(
|
|
718
|
-
super(
|
|
719
|
-
this.elementBy = byTestId(createGroupTestId(formName, name));
|
|
785
|
+
constructor(parentCssSelector, formName, name, driver) {
|
|
786
|
+
super(parentCssSelector, byTestIdCssSelector(createGroupTestId(formName, name)), driver);
|
|
720
787
|
}
|
|
721
788
|
async initEditor() {
|
|
722
789
|
if (!this.editor) {
|
|
723
|
-
this.editor = await groupFactory(this.
|
|
790
|
+
this.editor = await groupFactory(this.parentCssSelector, this.elementCssSelector, this.driver);
|
|
724
791
|
}
|
|
725
792
|
}
|
|
726
793
|
/**
|
|
@@ -729,17 +796,21 @@ var FormGroup = class extends AbstractElementWithParent {
|
|
|
729
796
|
* expect(await tableList.group('MainSuperPanel').isDisplayed();
|
|
730
797
|
*/
|
|
731
798
|
async isDisplayed() {
|
|
732
|
-
|
|
733
|
-
|
|
799
|
+
try {
|
|
800
|
+
await this.initEditor();
|
|
801
|
+
return this.editor.isDisplayed();
|
|
802
|
+
} catch {
|
|
803
|
+
return false;
|
|
804
|
+
}
|
|
734
805
|
}
|
|
735
806
|
};
|
|
736
807
|
|
|
737
808
|
// src/pageObjects/elements/Forms/FormEdit.ts
|
|
738
809
|
var FormEdit = class extends AbstractForm {
|
|
739
|
-
saveButtonBy =
|
|
810
|
+
saveButtonBy = By12.id("button-save");
|
|
740
811
|
constructor(driver) {
|
|
741
812
|
super(driver);
|
|
742
|
-
this.
|
|
813
|
+
this.popupContainerCssSelector = `.popup .form-edit-${this.formName}`;
|
|
743
814
|
}
|
|
744
815
|
/**
|
|
745
816
|
* Находит поле формы редактирования по имени
|
|
@@ -749,7 +820,7 @@ var FormEdit = class extends AbstractForm {
|
|
|
749
820
|
* expect(await formEdit.field('Name').getValue()).toBe('test value');
|
|
750
821
|
*/
|
|
751
822
|
field(name) {
|
|
752
|
-
return new FormField(this.
|
|
823
|
+
return new FormField(this.containerCssSelector, this.formName, name, this.driver);
|
|
753
824
|
}
|
|
754
825
|
/**
|
|
755
826
|
* Проверяет не отключена ли кнопка Сохранить
|
|
@@ -771,7 +842,7 @@ var FormEdit = class extends AbstractForm {
|
|
|
771
842
|
* expect(await formEdit.group('Name');
|
|
772
843
|
*/
|
|
773
844
|
group(name) {
|
|
774
|
-
return new FormGroup(this.
|
|
845
|
+
return new FormGroup(this.containerCssSelector, this.formName, name, this.driver);
|
|
775
846
|
}
|
|
776
847
|
/**
|
|
777
848
|
* Нажатие на кнопку Сохранить
|
|
@@ -782,50 +853,67 @@ var FormEdit = class extends AbstractForm {
|
|
|
782
853
|
*/
|
|
783
854
|
async saveButtonClick() {
|
|
784
855
|
const saveButton = await this.driver.findElement(this.saveButtonBy);
|
|
785
|
-
await
|
|
856
|
+
await wait(async () => !await this.isSaveButtonDisabled(), this.driver, "Button is disabled");
|
|
786
857
|
await click(saveButton, this.driver);
|
|
787
858
|
}
|
|
788
859
|
};
|
|
789
860
|
|
|
790
|
-
// src/pageObjects/elements/
|
|
861
|
+
// src/pageObjects/elements/Table/Table.ts
|
|
791
862
|
import { By as By17 } from "selenium-webdriver";
|
|
792
863
|
|
|
793
|
-
// src/pageObjects/elements/Table/
|
|
864
|
+
// src/pageObjects/elements/Table/elements/Row.ts
|
|
865
|
+
import { By as By15 } from "selenium-webdriver";
|
|
866
|
+
|
|
867
|
+
// src/pageObjects/elements/Table/elements/Cell.ts
|
|
794
868
|
import { By as By14 } from "selenium-webdriver";
|
|
795
869
|
|
|
796
870
|
// src/pageObjects/elements/Table/utils.ts
|
|
797
|
-
import { By as
|
|
798
|
-
|
|
799
|
-
return
|
|
800
|
-
}
|
|
871
|
+
import { By as By13 } from "selenium-webdriver";
|
|
872
|
+
function getCssRowByIndexSelector(index) {
|
|
873
|
+
return `tr[aria-rowindex="${transformInputIndex(index)}"]`;
|
|
874
|
+
}
|
|
801
875
|
var getColumnByIndexCssSelector = (columnIndex) => `td[aria-colindex="${transformInputIndex(columnIndex)}"]`;
|
|
802
|
-
var getColumnPathByIndex = (index) => {
|
|
803
|
-
return By12.css(getColumnByIndexCssSelector(index));
|
|
804
|
-
};
|
|
805
876
|
var getColumnByCaptionCssSelector = (caption) => `td[role="columnheader"][aria-label="Column ${caption}"]`;
|
|
806
|
-
var
|
|
807
|
-
|
|
808
|
-
}
|
|
877
|
+
var getColumnByNameCssSelector = (name) => `td[role="columnheader"][data-fieldname="${name}"]`;
|
|
878
|
+
function getCssCellByIndexSelector(index) {
|
|
879
|
+
return `td[role="gridcell"][aria-colindex="${transformInputIndex(index)}"]`;
|
|
880
|
+
}
|
|
809
881
|
var transformInputIndex = (index) => index + 1;
|
|
810
882
|
var transformOutputIndex = (index) => +index - 1;
|
|
811
883
|
|
|
812
|
-
// src/pageObjects/elements/Table/elements/Row.ts
|
|
813
|
-
import { By as By13 } from "selenium-webdriver";
|
|
814
|
-
|
|
815
884
|
// src/pageObjects/elements/Table/elements/Cell.ts
|
|
816
885
|
var Cell = class extends AbstractElementWithParent {
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
this.
|
|
886
|
+
_index;
|
|
887
|
+
getCellIndex;
|
|
888
|
+
constructor(parentCssSelector, getCellIndex, index, driver) {
|
|
889
|
+
super(parentCssSelector, getCssCellByIndexSelector(index), driver);
|
|
890
|
+
this.getCellIndex = getCellIndex;
|
|
891
|
+
this._index = index;
|
|
892
|
+
}
|
|
893
|
+
set index(index) {
|
|
894
|
+
this._index = index;
|
|
895
|
+
this.elementCssSelector = getCssCellByIndexSelector(index);
|
|
896
|
+
}
|
|
897
|
+
async getBooleanValue(cellEl) {
|
|
898
|
+
const booleanEl = await cellEl.findElement(By14.className("boolean-widget"));
|
|
899
|
+
return await booleanEl.getAttribute("aria-checked") === "true" ? 1 : 0;
|
|
900
|
+
}
|
|
901
|
+
async getElement() {
|
|
902
|
+
if (this._index == null) {
|
|
903
|
+
this.index = await this.getCellIndex();
|
|
904
|
+
}
|
|
905
|
+
return super.getElement();
|
|
822
906
|
}
|
|
823
907
|
async getValue() {
|
|
824
908
|
const cellEl = await this.getElement();
|
|
909
|
+
const cellElClass = await cellEl.getAttribute("class");
|
|
910
|
+
if (cellElClass.includes("boolean-column")) {
|
|
911
|
+
return this.getBooleanValue(cellEl);
|
|
912
|
+
}
|
|
825
913
|
return cellEl.getText();
|
|
826
914
|
}
|
|
827
915
|
getIndex() {
|
|
828
|
-
return this.
|
|
916
|
+
return this._index;
|
|
829
917
|
}
|
|
830
918
|
};
|
|
831
919
|
|
|
@@ -835,51 +923,46 @@ var DX_ROW_EDIT_CLASS = "dx-edit-row";
|
|
|
835
923
|
var DX_DATA_ROW_CLASS = "dx-data-row";
|
|
836
924
|
var Row = class extends AbstractElementWithParent {
|
|
837
925
|
index;
|
|
838
|
-
|
|
839
|
-
constructor(
|
|
840
|
-
super(
|
|
926
|
+
getColumnBy;
|
|
927
|
+
constructor(parentCssSelector, index, driver, getColumnBy) {
|
|
928
|
+
super(parentCssSelector, getCssRowByIndexSelector(index), driver);
|
|
841
929
|
this.index = index;
|
|
842
|
-
this.
|
|
843
|
-
this.getColumnByCaption = getColumnByCaption;
|
|
930
|
+
this.getColumnBy = getColumnBy;
|
|
844
931
|
}
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
return new Cell(rowEl, index, this.driver);
|
|
850
|
-
}
|
|
851
|
-
throw new Error(`Cannot find cell by index: ${index}`);
|
|
932
|
+
_getCell({ index, name, title }) {
|
|
933
|
+
return new Cell(this.getFullCssSelector(), () => {
|
|
934
|
+
return this.getColumnBy({ title, name }).getIndex();
|
|
935
|
+
}, index, this.driver);
|
|
852
936
|
}
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
937
|
+
getCellByIndex(index) {
|
|
938
|
+
return this._getCell({ index });
|
|
939
|
+
}
|
|
940
|
+
getCell(name) {
|
|
941
|
+
return this._getCell({ name });
|
|
942
|
+
}
|
|
943
|
+
getCellByTitle(title) {
|
|
944
|
+
return this._getCell({ title });
|
|
860
945
|
}
|
|
861
946
|
async select() {
|
|
862
947
|
const rowEl = await this.getElement();
|
|
863
948
|
await click(rowEl, this.driver);
|
|
864
|
-
await
|
|
865
|
-
const classes = await
|
|
949
|
+
await wait(async () => {
|
|
950
|
+
const classes = await this.getClasses();
|
|
866
951
|
return classes.includes(DX_SELECTION_CLASS);
|
|
867
|
-
},
|
|
952
|
+
}, this.driver, "Cannot select row");
|
|
868
953
|
}
|
|
869
954
|
async isSelected() {
|
|
870
|
-
const
|
|
871
|
-
const result = await rowEl.getAttribute("aria-selected");
|
|
955
|
+
const result = await this.getAttribute("aria-selected");
|
|
872
956
|
return result === "true";
|
|
873
957
|
}
|
|
874
958
|
getIndex() {
|
|
875
959
|
return this.index;
|
|
876
960
|
}
|
|
877
961
|
async getCells() {
|
|
878
|
-
const
|
|
879
|
-
const cells = await rowEl.findElements(By13.css(`td[role="gridcell"]`));
|
|
962
|
+
const cells = await this.driver.findElements(By15.css(`${this.getFullCssSelector()} td[role="gridcell"]`));
|
|
880
963
|
const result = [];
|
|
881
964
|
cells.forEach((_, index) => {
|
|
882
|
-
const newCell =
|
|
965
|
+
const newCell = this.getCellByIndex(index);
|
|
883
966
|
result.push(newCell);
|
|
884
967
|
});
|
|
885
968
|
return result;
|
|
@@ -887,15 +970,13 @@ var Row = class extends AbstractElementWithParent {
|
|
|
887
970
|
async clickInlineButton(buttonClass) {
|
|
888
971
|
const FIXED_TABLE_CSS_SELECTOR = ".dx-fixed-columns .dx-datagrid-content.dx-datagrid-content-fixed";
|
|
889
972
|
const buttonCssSelector = `.${DX_DATA_ROW_CLASS}[aria-rowindex="${transformInputIndex(this.index)}"] .${buttonClass}`;
|
|
890
|
-
const button =
|
|
891
|
-
By13.css(`${FIXED_TABLE_CSS_SELECTOR} ${buttonCssSelector}`)
|
|
892
|
-
);
|
|
973
|
+
const button = await this.driver.findElement(By15.css(`${this.parentCssSelector} ${FIXED_TABLE_CSS_SELECTOR} ${buttonCssSelector}`));
|
|
893
974
|
return click(button, this.driver);
|
|
894
975
|
}
|
|
895
976
|
async checkEditingMode(isEditing, msg) {
|
|
896
|
-
await
|
|
977
|
+
await wait(async () => {
|
|
897
978
|
return (await this.getClasses()).includes(DX_ROW_EDIT_CLASS) === isEditing;
|
|
898
|
-
},
|
|
979
|
+
}, this.driver, msg);
|
|
899
980
|
}
|
|
900
981
|
async edit() {
|
|
901
982
|
await this.clickInlineButton("edit");
|
|
@@ -912,86 +993,119 @@ var Row = class extends AbstractElementWithParent {
|
|
|
912
993
|
};
|
|
913
994
|
|
|
914
995
|
// src/pageObjects/elements/Table/elements/Column.ts
|
|
996
|
+
import { By as By16 } from "selenium-webdriver";
|
|
997
|
+
var getHeaderCssSelector = () => {
|
|
998
|
+
return ".dx-datagrid-headers .dx-datagrid-content:not(.dx-datagrid-content-fixed)";
|
|
999
|
+
};
|
|
915
1000
|
var Column = class extends AbstractElementWithParent {
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
1001
|
+
_index;
|
|
1002
|
+
_caption;
|
|
1003
|
+
_name;
|
|
1004
|
+
constructor({ parentCssSelector, name, caption, index, driver }) {
|
|
1005
|
+
super(parentCssSelector, "", driver);
|
|
1006
|
+
this._name = name;
|
|
919
1007
|
this.index = index;
|
|
920
|
-
this.
|
|
1008
|
+
this._caption = caption;
|
|
1009
|
+
}
|
|
1010
|
+
set index(index) {
|
|
1011
|
+
this._index = index;
|
|
1012
|
+
this.elementCssSelector = getColumnByIndexCssSelector(index);
|
|
1013
|
+
}
|
|
1014
|
+
get index() {
|
|
1015
|
+
return this._index;
|
|
1016
|
+
}
|
|
1017
|
+
async getElement() {
|
|
1018
|
+
await this.getIndex();
|
|
1019
|
+
return super.getElement();
|
|
1020
|
+
}
|
|
1021
|
+
async getColumnHeaderIndexBy(cssSelector) {
|
|
1022
|
+
const column = await this.driver.findElement(By16.css(`${this.parentCssSelector} ${getHeaderCssSelector()} ${cssSelector}`));
|
|
1023
|
+
return transformOutputIndex(await column.getAttribute("aria-colindex"));
|
|
1024
|
+
}
|
|
1025
|
+
async getIndexByCaption() {
|
|
1026
|
+
return this.getColumnHeaderIndexBy(getColumnByCaptionCssSelector(this._caption));
|
|
1027
|
+
}
|
|
1028
|
+
async getIndexByName() {
|
|
1029
|
+
return this.getColumnHeaderIndexBy(getColumnByNameCssSelector(this._name));
|
|
921
1030
|
}
|
|
922
1031
|
async caption() {
|
|
923
1032
|
const el = await this.getElement();
|
|
924
1033
|
return el.getText();
|
|
925
1034
|
}
|
|
926
|
-
getIndex() {
|
|
927
|
-
|
|
1035
|
+
async getIndex() {
|
|
1036
|
+
if (this.index != null) {
|
|
1037
|
+
return this.index;
|
|
1038
|
+
}
|
|
1039
|
+
if (this._caption != null) {
|
|
1040
|
+
this.index = await this.getIndexByCaption();
|
|
1041
|
+
return this.index;
|
|
1042
|
+
}
|
|
1043
|
+
if (this._name != null) {
|
|
1044
|
+
this.index = await this.getIndexByName();
|
|
1045
|
+
return this.index;
|
|
1046
|
+
}
|
|
1047
|
+
throw new Error("Cant get the index in the column");
|
|
928
1048
|
}
|
|
929
1049
|
};
|
|
930
1050
|
|
|
931
1051
|
// src/pageObjects/elements/Table/Table.ts
|
|
932
1052
|
var Table = class extends AbstractElementWithParent {
|
|
933
1053
|
formName;
|
|
934
|
-
constructor(
|
|
935
|
-
super(
|
|
936
|
-
this.elementBy = By14.id(createTableId(formName));
|
|
1054
|
+
constructor(parentCssSelector, formName, driver) {
|
|
1055
|
+
super(parentCssSelector, `#${createTableId(formName)}`, driver);
|
|
937
1056
|
this.formName = formName;
|
|
938
1057
|
}
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
async getDataGrid() {
|
|
943
|
-
const parentEl = await this.getElement();
|
|
944
|
-
return parentEl.findElement(By14.css(`div[role="grid"]`));
|
|
945
|
-
}
|
|
946
|
-
getTableElement = () => {
|
|
947
|
-
return this.getElement();
|
|
948
|
-
};
|
|
949
|
-
async getRowByIndex(index) {
|
|
950
|
-
const gridContainer = await this.getDataGrid();
|
|
951
|
-
const row = await gridContainer.findElement(getRowPathByIndex(index));
|
|
952
|
-
if (row) {
|
|
953
|
-
return new Row(this.getTableElement, index, this.driver, this.getColumnByCaption.bind(this));
|
|
954
|
-
}
|
|
955
|
-
throw new Error(`Cannot find row by index: ${index}`);
|
|
956
|
-
}
|
|
957
|
-
async getColumnByIndex(index) {
|
|
958
|
-
const column = await (await this.getElement()).findElement(By14.css(`${this.getHeaderCssSelector()} ${getColumnByIndexCssSelector(index)}`));
|
|
959
|
-
if (column) {
|
|
960
|
-
return new Column(this.getTableElement, index, this.driver);
|
|
1058
|
+
getColumnBy = (args) => {
|
|
1059
|
+
if (args.title) {
|
|
1060
|
+
return this.getColumnByTitle(args.title);
|
|
961
1061
|
}
|
|
962
|
-
|
|
1062
|
+
return this.getColumnByName(args.name);
|
|
1063
|
+
};
|
|
1064
|
+
getRowByIndex(index) {
|
|
1065
|
+
return new Row(this.getFullCssSelector(), index, this.driver, this.getColumnBy);
|
|
1066
|
+
}
|
|
1067
|
+
getColumnByIndex(index) {
|
|
1068
|
+
return new Column({
|
|
1069
|
+
parentCssSelector: this.getFullCssSelector(),
|
|
1070
|
+
driver: this.driver,
|
|
1071
|
+
index
|
|
1072
|
+
});
|
|
963
1073
|
}
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
}
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
}
|
|
977
|
-
|
|
978
|
-
|
|
1074
|
+
getColumnByTitle = (title) => {
|
|
1075
|
+
return new Column({
|
|
1076
|
+
parentCssSelector: this.getFullCssSelector(),
|
|
1077
|
+
caption: title,
|
|
1078
|
+
driver: this.driver
|
|
1079
|
+
});
|
|
1080
|
+
};
|
|
1081
|
+
getColumnByName = (name) => {
|
|
1082
|
+
return new Column({
|
|
1083
|
+
parentCssSelector: this.getFullCssSelector(),
|
|
1084
|
+
name,
|
|
1085
|
+
driver: this.driver
|
|
1086
|
+
});
|
|
1087
|
+
};
|
|
1088
|
+
selectRowByIndex(index) {
|
|
1089
|
+
return this.getRowByIndex(index).select();
|
|
979
1090
|
}
|
|
980
1091
|
async getRows() {
|
|
981
|
-
const
|
|
982
|
-
const rows = await gridContainer.findElements(By14.className("dx-row dx-data-row"));
|
|
1092
|
+
const rows = await this.driver.findElements(By17.css(`${this.getFullCssSelector()} .dx-row.dx-data-row`));
|
|
983
1093
|
const result = [];
|
|
984
1094
|
rows.forEach((_, index) => {
|
|
985
|
-
const newRow = new Row(this.
|
|
1095
|
+
const newRow = new Row(this.getFullCssSelector(), index, this.driver, this.getColumnBy);
|
|
986
1096
|
result.push(newRow);
|
|
987
1097
|
});
|
|
988
1098
|
return result;
|
|
989
1099
|
}
|
|
990
1100
|
async getColumns() {
|
|
991
|
-
const columns = await
|
|
1101
|
+
const columns = await this.driver.findElements(By17.css(`${this.getFullCssSelector()} ${getHeaderCssSelector()} td[role="columnheader"]`));
|
|
992
1102
|
const result = [];
|
|
993
1103
|
columns.forEach((_, index) => {
|
|
994
|
-
const newCol = new Column(
|
|
1104
|
+
const newCol = new Column({
|
|
1105
|
+
parentCssSelector: this.getFullCssSelector(),
|
|
1106
|
+
index,
|
|
1107
|
+
driver: this.driver
|
|
1108
|
+
});
|
|
995
1109
|
result.push(newCol);
|
|
996
1110
|
});
|
|
997
1111
|
return result;
|
|
@@ -1007,54 +1121,229 @@ var Table = class extends AbstractElementWithParent {
|
|
|
1007
1121
|
* expect(await form.field('Name').getValue()).toBe('test value');
|
|
1008
1122
|
*/
|
|
1009
1123
|
field(name) {
|
|
1010
|
-
return new FormField(this.
|
|
1124
|
+
return new FormField(this.getFullCssSelector(), this.formName, name, this.driver);
|
|
1011
1125
|
}
|
|
1012
1126
|
};
|
|
1013
1127
|
|
|
1014
|
-
// src/pageObjects/elements/TableToolbar/
|
|
1015
|
-
|
|
1128
|
+
// src/pageObjects/elements/TableToolbar/AbstractButton.ts
|
|
1129
|
+
var AbstractButton = class extends AbstractElementWithParent {
|
|
1130
|
+
constructor(parentCssSelector, elementCssSelector, driver) {
|
|
1131
|
+
super(parentCssSelector, elementCssSelector, driver);
|
|
1132
|
+
}
|
|
1133
|
+
async click() {
|
|
1134
|
+
const button = await this.getElement();
|
|
1135
|
+
await wait(async () => {
|
|
1136
|
+
return await button.isDisplayed() && !await this.isDisabled();
|
|
1137
|
+
}, this.driver, this.buttonNotDisplayedError());
|
|
1138
|
+
await click(button, this.driver);
|
|
1139
|
+
}
|
|
1140
|
+
async isDisabled() {
|
|
1141
|
+
const button = await this.getElement();
|
|
1142
|
+
return await button.getCssValue("pointer-events") === "none";
|
|
1143
|
+
}
|
|
1144
|
+
};
|
|
1016
1145
|
|
|
1017
|
-
// src/pageObjects/elements/TableToolbar/
|
|
1018
|
-
|
|
1146
|
+
// src/pageObjects/elements/TableToolbar/ToolbarGroupButton.ts
|
|
1147
|
+
var ToolbarGroupButton = class extends AbstractButton {
|
|
1148
|
+
name;
|
|
1149
|
+
constructor(parentCssSelector, name, driver) {
|
|
1150
|
+
super(parentCssSelector, ``, driver);
|
|
1151
|
+
this.name = name;
|
|
1152
|
+
}
|
|
1153
|
+
buttonNotDisplayedError() {
|
|
1154
|
+
return `Button ${this.name} cannot be clicked. It is not displayed or it is disabled`;
|
|
1155
|
+
}
|
|
1156
|
+
};
|
|
1157
|
+
|
|
1158
|
+
// src/pageObjects/elements/TableToolbar/ToolbarButton.ts
|
|
1019
1159
|
var TOOLBAR_BUTTON_CLASS = "toolbar-button";
|
|
1020
|
-
var
|
|
1160
|
+
var ToolbarButton = class extends AbstractButton {
|
|
1021
1161
|
name;
|
|
1022
|
-
constructor(
|
|
1023
|
-
super(
|
|
1162
|
+
constructor(parentCssSelector, name, driver) {
|
|
1163
|
+
super(parentCssSelector, `#${TOOLBAR_BUTTON_CLASS}-${name}`, driver);
|
|
1024
1164
|
this.name = name;
|
|
1025
|
-
|
|
1165
|
+
}
|
|
1166
|
+
buttonNotDisplayedError() {
|
|
1167
|
+
return `Button ${this.name} cannot be clicked. It is not displayed or it is disabled`;
|
|
1168
|
+
}
|
|
1169
|
+
};
|
|
1170
|
+
|
|
1171
|
+
// src/pageObjects/elements/TableToolbar/ToolbarItem.ts
|
|
1172
|
+
var GROUP_BUTTON_CLASS = "toolbar-group-button";
|
|
1173
|
+
var toolbarItemSelector = (form, name) => byTestIdCssSelector(`ftb-${form}-${name}`);
|
|
1174
|
+
var ToolbarItem = class extends AbstractElementWithParent {
|
|
1175
|
+
_button;
|
|
1176
|
+
// private _formName: string;
|
|
1177
|
+
_itemName;
|
|
1178
|
+
constructor(parentCssSelector, formName, itemName, driver) {
|
|
1179
|
+
super(parentCssSelector, toolbarItemSelector(formName, itemName), driver);
|
|
1180
|
+
this._itemName = itemName;
|
|
1181
|
+
}
|
|
1182
|
+
async init() {
|
|
1183
|
+
if (this._button)
|
|
1184
|
+
return this._button;
|
|
1185
|
+
const classNames = await this.getClasses();
|
|
1186
|
+
if (classNames.includes(GROUP_BUTTON_CLASS)) {
|
|
1187
|
+
this._button = new ToolbarGroupButton(this.getFullCssSelector(), this._itemName, this.driver);
|
|
1188
|
+
return;
|
|
1189
|
+
}
|
|
1190
|
+
this._button = new ToolbarButton(this.parentCssSelector, this._itemName, this.driver);
|
|
1026
1191
|
}
|
|
1027
1192
|
async click() {
|
|
1028
|
-
|
|
1029
|
-
await this.
|
|
1030
|
-
return await button.isDisplayed() && !await this.isDisabled();
|
|
1031
|
-
}, 1e3, `Button ${this.name} cannot be clicked. It is not displayed or it is disabled`);
|
|
1032
|
-
return click(button, this.driver);
|
|
1193
|
+
await this.init();
|
|
1194
|
+
await this._button.click();
|
|
1033
1195
|
}
|
|
1034
1196
|
async isDisabled() {
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
return result === "true";
|
|
1197
|
+
await this.init();
|
|
1198
|
+
return await this._button.isDisabled();
|
|
1038
1199
|
}
|
|
1039
1200
|
};
|
|
1040
1201
|
|
|
1041
|
-
// src/pageObjects/elements/TableToolbar/
|
|
1202
|
+
// src/pageObjects/elements/TableToolbar/FormToolbar.ts
|
|
1042
1203
|
var TABLE_TOOLBAR_CLASS = "d5-table-toolbar";
|
|
1043
|
-
var
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1204
|
+
var FormToolbar = class extends AbstractElementWithParent {
|
|
1205
|
+
formName;
|
|
1206
|
+
constructor(parentCssSelector, formName, driver) {
|
|
1207
|
+
super(parentCssSelector, `#${TABLE_TOOLBAR_CLASS}-${formName}`, driver);
|
|
1208
|
+
this.formName = formName;
|
|
1047
1209
|
}
|
|
1048
|
-
|
|
1049
|
-
return this.
|
|
1050
|
-
}
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1210
|
+
button(name) {
|
|
1211
|
+
return new ToolbarItem(this.getFullCssSelector(), this.formName, name, this.driver);
|
|
1212
|
+
}
|
|
1213
|
+
};
|
|
1214
|
+
|
|
1215
|
+
// src/pageObjects/elements/Filters/FormFilterField.ts
|
|
1216
|
+
var FormFilterField = class extends AbstractEditor {
|
|
1217
|
+
constructor(parentCssSelector, formName, name, driver) {
|
|
1218
|
+
super(parentCssSelector, byTestIdCssSelector(createLayoutFilterTestId(formName, name)), driver);
|
|
1219
|
+
}
|
|
1220
|
+
/**
|
|
1221
|
+
* Возвращает значение в поле
|
|
1222
|
+
* @example
|
|
1223
|
+
* expect(await form.formFilter('NumberFld').getValue()).toBe(10);
|
|
1224
|
+
* expect(await form.formFilter('TextFld').getValue()).toBe('TestValue');
|
|
1225
|
+
*/
|
|
1226
|
+
async getValue() {
|
|
1227
|
+
return super.getValue();
|
|
1228
|
+
}
|
|
1229
|
+
/**
|
|
1230
|
+
* Устанавливает значение в поле
|
|
1231
|
+
* @example
|
|
1232
|
+
* await form.formFilter('NumberFld').setValue(123);
|
|
1233
|
+
* await form.formFilter('TextFld').setValue('TestValue');
|
|
1234
|
+
*/
|
|
1235
|
+
async setValue(value) {
|
|
1236
|
+
return super.setValue(value);
|
|
1237
|
+
}
|
|
1238
|
+
/**
|
|
1239
|
+
* Очищает значение в поле
|
|
1240
|
+
* @example
|
|
1241
|
+
* await form.formFilter('NumberFld').clear();
|
|
1242
|
+
*/
|
|
1243
|
+
async clear() {
|
|
1244
|
+
return super.clear();
|
|
1245
|
+
}
|
|
1246
|
+
/**
|
|
1247
|
+
* Удаляет тег по переданному тексту
|
|
1248
|
+
* @example
|
|
1249
|
+
* await form.formFilter('TagBox').remove('test');
|
|
1250
|
+
*/
|
|
1251
|
+
async remove(itemText) {
|
|
1252
|
+
return super.remove(itemText);
|
|
1253
|
+
}
|
|
1254
|
+
};
|
|
1255
|
+
|
|
1256
|
+
// src/pageObjects/elements/Filters/FilterPanel.ts
|
|
1257
|
+
import { By as By18 } from "selenium-webdriver";
|
|
1258
|
+
|
|
1259
|
+
// src/pageObjects/elements/Filters/PanelFilterField.ts
|
|
1260
|
+
var PanelFilterField = class extends AbstractEditor {
|
|
1261
|
+
constructor(parentCssSelector, formName, name, driver) {
|
|
1262
|
+
super(parentCssSelector, byTestIdCssSelector(createDocFilterTestId(formName, name)), driver);
|
|
1263
|
+
}
|
|
1264
|
+
/**
|
|
1265
|
+
* Возвращает значение в поле
|
|
1266
|
+
* @example
|
|
1267
|
+
* expect(await form.filterPanel.filterField('NumberFld').getValue()).toBe(10);
|
|
1268
|
+
* expect(await form.filterPanel.filterField('TextFld').getValue()).toBe('TestValue');
|
|
1269
|
+
*/
|
|
1270
|
+
async getValue() {
|
|
1271
|
+
return super.getValue();
|
|
1272
|
+
}
|
|
1273
|
+
/**
|
|
1274
|
+
* Устанавливает значение в поле
|
|
1275
|
+
* @example
|
|
1276
|
+
* await form.filterPanel.filterField('NumberFld').setValue(123);
|
|
1277
|
+
* await form.filterPanel.filterField('TextFld').setValue('TestValue');
|
|
1278
|
+
*/
|
|
1279
|
+
async setValue(value) {
|
|
1280
|
+
return super.setValue(value);
|
|
1281
|
+
}
|
|
1282
|
+
/**
|
|
1283
|
+
* Очищает значение в поле
|
|
1284
|
+
* @example
|
|
1285
|
+
* await form.filterPanel.filterField('NumberFld').clear();
|
|
1286
|
+
*/
|
|
1287
|
+
async clear() {
|
|
1288
|
+
return super.clear();
|
|
1289
|
+
}
|
|
1290
|
+
/**
|
|
1291
|
+
* Удаляет тег по переданному тексту
|
|
1292
|
+
* @example
|
|
1293
|
+
* await form.filterPanel.filterField('TagBox').remove('test');
|
|
1294
|
+
*/
|
|
1295
|
+
async remove(itemText) {
|
|
1296
|
+
return super.remove(itemText);
|
|
1297
|
+
}
|
|
1298
|
+
};
|
|
1299
|
+
|
|
1300
|
+
// src/pageObjects/elements/Filters/FilterPanel.ts
|
|
1301
|
+
var drawerSelector = (formName) => `.secondary-drawer-side-panel.form-${formName}`;
|
|
1302
|
+
var FILTER_PANEL_SELECTOR = ".filter-panel";
|
|
1303
|
+
var CLOSE_SELECTOR = ".button-close";
|
|
1304
|
+
var FilterPanel = class extends AbstractElement {
|
|
1305
|
+
_formName;
|
|
1306
|
+
get filterPanelSelector() {
|
|
1307
|
+
return `${this.elementCssSelector} ${FILTER_PANEL_SELECTOR}`;
|
|
1308
|
+
}
|
|
1309
|
+
async filterPanelButtons() {
|
|
1310
|
+
const selector = `${this.elementCssSelector} ${FILTER_PANEL_SELECTOR} .filter-panel__buttons-panel .dx-button-text`;
|
|
1311
|
+
const el = await this.getElement();
|
|
1312
|
+
return el.findElements(By18.css(selector));
|
|
1313
|
+
}
|
|
1314
|
+
constructor(formName, driver) {
|
|
1315
|
+
super(driver, drawerSelector(formName));
|
|
1316
|
+
this._formName = formName;
|
|
1317
|
+
}
|
|
1318
|
+
/**
|
|
1319
|
+
* Возвращает фильтр на панели фильтрации
|
|
1320
|
+
* @returns {PanelFilterField}
|
|
1321
|
+
* @example
|
|
1322
|
+
* await form.filterPanel.filterField('NumberFld');
|
|
1323
|
+
*/
|
|
1324
|
+
filterField(name) {
|
|
1325
|
+
return new PanelFilterField(this.filterPanelSelector, this._formName, name, this.driver);
|
|
1326
|
+
}
|
|
1327
|
+
async apply() {
|
|
1328
|
+
const btn = await this.findButtonByTitle("\u0417\u0430\u0441\u0442\u043E\u0441\u0443\u0432\u0430\u0442\u0438");
|
|
1329
|
+
await click(btn, this.driver);
|
|
1330
|
+
}
|
|
1331
|
+
async findButtonByTitle(title) {
|
|
1332
|
+
const buttons = await this.filterPanelButtons();
|
|
1333
|
+
for (const btn of buttons) {
|
|
1334
|
+
if (await btn.getText() === title) {
|
|
1335
|
+
return btn;
|
|
1336
|
+
}
|
|
1056
1337
|
}
|
|
1057
|
-
|
|
1338
|
+
}
|
|
1339
|
+
async clearAll() {
|
|
1340
|
+
const btn = await this.findButtonByTitle("\u041E\u0447\u0438\u0441\u0442\u0438\u0442\u0438");
|
|
1341
|
+
await click(btn, this.driver);
|
|
1342
|
+
await this.driver.sleep(300);
|
|
1343
|
+
}
|
|
1344
|
+
async close() {
|
|
1345
|
+
const btn = await this.driver.findElement(By18.css(`${this.elementCssSelector} ${CLOSE_SELECTOR}`));
|
|
1346
|
+
await click(btn, this.driver);
|
|
1058
1347
|
}
|
|
1059
1348
|
};
|
|
1060
1349
|
|
|
@@ -1062,7 +1351,7 @@ var TableToolbar = class extends AbstractElementWithParent {
|
|
|
1062
1351
|
var ListForm = class extends AbstractForm {
|
|
1063
1352
|
constructor(driver) {
|
|
1064
1353
|
super(driver);
|
|
1065
|
-
this.
|
|
1354
|
+
this.popupContainerCssSelector = `.popup .form-inline-${this.formName}`;
|
|
1066
1355
|
}
|
|
1067
1356
|
/**
|
|
1068
1357
|
* Находит таблицу
|
|
@@ -1072,7 +1361,7 @@ var ListForm = class extends AbstractForm {
|
|
|
1072
1361
|
* expect(listForm.table());
|
|
1073
1362
|
*/
|
|
1074
1363
|
table() {
|
|
1075
|
-
return new Table(this.
|
|
1364
|
+
return new Table(this.containerCssSelector, this.formName, this.driver);
|
|
1076
1365
|
}
|
|
1077
1366
|
/**
|
|
1078
1367
|
* Находит группу на лист форме по имени
|
|
@@ -1082,7 +1371,7 @@ var ListForm = class extends AbstractForm {
|
|
|
1082
1371
|
* expect(await formEdit.group('Name');
|
|
1083
1372
|
*/
|
|
1084
1373
|
group(name) {
|
|
1085
|
-
return new FormGroup(this.
|
|
1374
|
+
return new FormGroup(this.containerCssSelector, this.formName, name, this.driver);
|
|
1086
1375
|
}
|
|
1087
1376
|
/**
|
|
1088
1377
|
* Находит таблицу
|
|
@@ -1092,78 +1381,51 @@ var ListForm = class extends AbstractForm {
|
|
|
1092
1381
|
* expect(listForm.toolbarButton());
|
|
1093
1382
|
*/
|
|
1094
1383
|
toolbarButton(name) {
|
|
1095
|
-
const toolbar = new
|
|
1384
|
+
const toolbar = new FormToolbar(this.containerCssSelector, this.formName, this.driver);
|
|
1096
1385
|
return toolbar.button(name);
|
|
1097
1386
|
}
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
return webDriver;
|
|
1108
|
-
}
|
|
1109
|
-
|
|
1110
|
-
// src/utils/actions.ts
|
|
1111
|
-
var click = async (webElement, driver) => {
|
|
1112
|
-
driver = driver ?? config().driver;
|
|
1113
|
-
const actions = driver.actions({ async: true });
|
|
1114
|
-
await actions.move({ origin: webElement }).click().perform();
|
|
1115
|
-
};
|
|
1116
|
-
|
|
1117
|
-
// src/pageObjects/pages/LoginPage.ts
|
|
1118
|
-
var LOGIN_PATH = "/login";
|
|
1119
|
-
var LoginPage = class extends AbstractPage {
|
|
1120
|
-
usernameField = byTestId("loginField", "input");
|
|
1121
|
-
passwordField = byTestId("passwordField", "input");
|
|
1122
|
-
loginButton = byTestId("loginButton");
|
|
1123
|
-
async locate() {
|
|
1124
|
-
await super.locate();
|
|
1125
|
-
const login = await this.driver.findElement(this.usernameField);
|
|
1126
|
-
await waitElementIsVisible({
|
|
1127
|
-
element: login,
|
|
1128
|
-
driver: this.driver
|
|
1129
|
-
});
|
|
1130
|
-
}
|
|
1131
|
-
get path() {
|
|
1132
|
-
return LOGIN_PATH;
|
|
1133
|
-
}
|
|
1134
|
-
async enterUsername(username) {
|
|
1135
|
-
await this.driver.findElement(this.usernameField).sendKeys(username);
|
|
1136
|
-
}
|
|
1137
|
-
async enterPassword(password) {
|
|
1138
|
-
await this.driver.findElement(this.passwordField).sendKeys(password);
|
|
1139
|
-
}
|
|
1140
|
-
async clickLoginButton() {
|
|
1141
|
-
await click(await this.driver.findElement(this.loginButton), this.driver);
|
|
1142
|
-
}
|
|
1143
|
-
async loginWith(username, password) {
|
|
1144
|
-
await this.enterUsername(username);
|
|
1145
|
-
await this.enterPassword(password);
|
|
1146
|
-
await this.clickLoginButton();
|
|
1387
|
+
/**
|
|
1388
|
+
* Фильтр который расположен на форме
|
|
1389
|
+
* @example
|
|
1390
|
+
* const listForm = new MyForm();
|
|
1391
|
+
* //...
|
|
1392
|
+
* expect(listForm.formFilter());
|
|
1393
|
+
*/
|
|
1394
|
+
formFilter(name) {
|
|
1395
|
+
return new FormFilterField(this.containerCssSelector, this.formName, name, this.driver);
|
|
1147
1396
|
}
|
|
1148
|
-
|
|
1149
|
-
|
|
1397
|
+
/**
|
|
1398
|
+
* Модель панели фильтрации
|
|
1399
|
+
* @returns {FilterPanel}
|
|
1400
|
+
* @example
|
|
1401
|
+
* const listForm = new MyForm();
|
|
1402
|
+
* //...
|
|
1403
|
+
* expect(listForm.filterPanel());
|
|
1404
|
+
*/
|
|
1405
|
+
get filterPanel() {
|
|
1406
|
+
return new FilterPanel(this.formName, this.driver);
|
|
1150
1407
|
}
|
|
1151
1408
|
};
|
|
1152
1409
|
export {
|
|
1153
1410
|
AbstractPage,
|
|
1411
|
+
FilterPanel,
|
|
1154
1412
|
FormEdit,
|
|
1155
1413
|
FormField,
|
|
1414
|
+
FormFilterField,
|
|
1156
1415
|
ListForm,
|
|
1157
1416
|
LoginPage,
|
|
1158
1417
|
NumberEditor,
|
|
1418
|
+
PanelFilterField,
|
|
1159
1419
|
SubsystemsPanel,
|
|
1160
1420
|
TextEditor,
|
|
1161
1421
|
byTestId,
|
|
1422
|
+
byTestIdCssSelector,
|
|
1162
1423
|
click,
|
|
1163
1424
|
config,
|
|
1164
1425
|
createDriver,
|
|
1165
1426
|
editorFactory,
|
|
1166
1427
|
elementIsNotPresent,
|
|
1167
1428
|
signIn,
|
|
1429
|
+
wait,
|
|
1168
1430
|
waitElementIsVisible
|
|
1169
1431
|
};
|