@seleniumhq/side-runtime 4.0.0-alpha.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.
Files changed (85) hide show
  1. package/dist/callstack.d.ts +23 -0
  2. package/dist/callstack.d.ts.map +1 -0
  3. package/dist/callstack.js +40 -0
  4. package/dist/callstack.js.map +1 -0
  5. package/dist/errors/assertion.d.ts +4 -0
  6. package/dist/errors/assertion.d.ts.map +1 -0
  7. package/dist/errors/assertion.js +28 -0
  8. package/dist/errors/assertion.js.map +1 -0
  9. package/dist/errors/index.d.ts +3 -0
  10. package/dist/errors/index.d.ts.map +1 -0
  11. package/dist/errors/index.js +27 -0
  12. package/dist/errors/index.js.map +1 -0
  13. package/dist/errors/verification.d.ts +4 -0
  14. package/dist/errors/verification.d.ts.map +1 -0
  15. package/dist/errors/verification.js +28 -0
  16. package/dist/errors/verification.js.map +1 -0
  17. package/dist/index.d.ts +17 -0
  18. package/dist/index.d.ts.map +1 -0
  19. package/dist/index.js +54 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/playback-tree/command-leveler.d.ts +7 -0
  22. package/dist/playback-tree/command-leveler.d.ts.map +1 -0
  23. package/dist/playback-tree/command-leveler.js +73 -0
  24. package/dist/playback-tree/command-leveler.js.map +1 -0
  25. package/dist/playback-tree/command-node.d.ts +54 -0
  26. package/dist/playback-tree/command-node.d.ts.map +1 -0
  27. package/dist/playback-tree/command-node.js +185 -0
  28. package/dist/playback-tree/command-node.js.map +1 -0
  29. package/dist/playback-tree/commands.d.ts +42 -0
  30. package/dist/playback-tree/commands.d.ts.map +1 -0
  31. package/dist/playback-tree/commands.js +137 -0
  32. package/dist/playback-tree/commands.js.map +1 -0
  33. package/dist/playback-tree/control-flow-syntax-error.d.ts +5 -0
  34. package/dist/playback-tree/control-flow-syntax-error.d.ts.map +1 -0
  35. package/dist/playback-tree/control-flow-syntax-error.js +27 -0
  36. package/dist/playback-tree/control-flow-syntax-error.js.map +1 -0
  37. package/dist/playback-tree/index.d.ts +15 -0
  38. package/dist/playback-tree/index.d.ts.map +1 -0
  39. package/dist/playback-tree/index.js +161 -0
  40. package/dist/playback-tree/index.js.map +1 -0
  41. package/dist/playback-tree/state.d.ts +9 -0
  42. package/dist/playback-tree/state.d.ts.map +1 -0
  43. package/dist/playback-tree/state.js +38 -0
  44. package/dist/playback-tree/state.js.map +1 -0
  45. package/dist/playback-tree/syntax-validation.d.ts +4 -0
  46. package/dist/playback-tree/syntax-validation.d.ts.map +1 -0
  47. package/dist/playback-tree/syntax-validation.js +95 -0
  48. package/dist/playback-tree/syntax-validation.js.map +1 -0
  49. package/dist/playback.d.ts +167 -0
  50. package/dist/playback.d.ts.map +1 -0
  51. package/dist/playback.js +627 -0
  52. package/dist/playback.js.map +1 -0
  53. package/dist/plugins.d.ts +6 -0
  54. package/dist/plugins.d.ts.map +1 -0
  55. package/dist/plugins.js +24 -0
  56. package/dist/plugins.js.map +1 -0
  57. package/dist/preprocessors.d.ts +10 -0
  58. package/dist/preprocessors.d.ts.map +1 -0
  59. package/dist/preprocessors.js +179 -0
  60. package/dist/preprocessors.js.map +1 -0
  61. package/dist/recording-syncronizer-webdriver.d.ts +15 -0
  62. package/dist/recording-syncronizer-webdriver.d.ts.map +1 -0
  63. package/dist/recording-syncronizer-webdriver.js +33 -0
  64. package/dist/recording-syncronizer-webdriver.js.map +1 -0
  65. package/dist/recording-syncronizer.d.ts +22 -0
  66. package/dist/recording-syncronizer.d.ts.map +1 -0
  67. package/dist/recording-syncronizer.js +68 -0
  68. package/dist/recording-syncronizer.js.map +1 -0
  69. package/dist/types.d.ts +60 -0
  70. package/dist/types.d.ts.map +1 -0
  71. package/dist/types.js +6 -0
  72. package/dist/types.js.map +1 -0
  73. package/dist/utils.d.ts +2 -0
  74. package/dist/utils.d.ts.map +1 -0
  75. package/dist/utils.js +24 -0
  76. package/dist/utils.js.map +1 -0
  77. package/dist/variables.d.ts +10 -0
  78. package/dist/variables.d.ts.map +1 -0
  79. package/dist/variables.js +41 -0
  80. package/dist/variables.js.map +1 -0
  81. package/dist/webdriver.d.ts +173 -0
  82. package/dist/webdriver.d.ts.map +1 -0
  83. package/dist/webdriver.js +1007 -0
  84. package/dist/webdriver.js.map +1 -0
  85. package/package.json +37 -0
@@ -0,0 +1,1007 @@
1
+ "use strict";
2
+ // Licensed to the Software Freedom Conservancy (SFC) under one
3
+ // or more contributor license agreements. See the NOTICE file
4
+ // distributed with this work for additional information
5
+ // regarding copyright ownership. The SFC licenses this file
6
+ // to you under the Apache License, Version 2.0 (the
7
+ // "License"); you may not use this file except in compliance
8
+ // with the License. You may obtain a copy of the License at
9
+ //
10
+ // http://www.apache.org/licenses/LICENSE-2.0
11
+ //
12
+ // Unless required by applicable law or agreed to in writing,
13
+ // software distributed under the License is distributed on an
14
+ // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
+ // KIND, either express or implied. See the License for the
16
+ // specific language governing permissions and limitations
17
+ // under the License.
18
+ var __importDefault = (this && this.__importDefault) || function (mod) {
19
+ return (mod && mod.__esModule) ? mod : { "default": mod };
20
+ };
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ const selenium_webdriver_1 = __importDefault(require("selenium-webdriver"));
23
+ const utils_1 = require("./utils");
24
+ const preprocessors_1 = require("./preprocessors");
25
+ const errors_1 = require("./errors");
26
+ const { By, Condition, until, Key, WebElement, WebElementCondition, WebElementPromise, } = selenium_webdriver_1.default;
27
+ const { TimeoutError } = selenium_webdriver_1.default.error;
28
+ const POLL_TIMEOUT = 50;
29
+ const DEFAULT_CAPABILITIES = {
30
+ browserName: 'chrome',
31
+ };
32
+ const state = Symbol('state');
33
+ const defaultWindowAPI = {
34
+ setWindowSize: async (executor, width, height) => {
35
+ await executor.driver.manage().window().setSize(width, height);
36
+ },
37
+ };
38
+ class WebDriverExecutor {
39
+ constructor({ customCommands = {}, driver, capabilities, server, hooks = {}, implicitWait, windowAPI = defaultWindowAPI, }) {
40
+ if (driver) {
41
+ this.driver = driver;
42
+ }
43
+ else {
44
+ this.capabilities = capabilities || DEFAULT_CAPABILITIES;
45
+ this.server = server;
46
+ }
47
+ this.initialized = false;
48
+ this.implicitWait = implicitWait || 5 * 1000;
49
+ this.hooks = hooks;
50
+ this.waitForNewWindow = this.waitForNewWindow.bind(this);
51
+ this.customCommands = customCommands;
52
+ this.windowAPI = windowAPI;
53
+ }
54
+ async init({ baseUrl, logger, variables }) {
55
+ this.baseUrl = baseUrl;
56
+ this.logger = logger;
57
+ this.variables = variables;
58
+ this[state] = {};
59
+ if (!this.driver) {
60
+ const { browserName, ...capabilities } = this
61
+ .capabilities;
62
+ this.driver = await new selenium_webdriver_1.default.Builder()
63
+ .withCapabilities(capabilities)
64
+ .usingServer(this.server)
65
+ .forBrowser(browserName)
66
+ .build();
67
+ }
68
+ this.initialized = true;
69
+ }
70
+ async cancel() {
71
+ if (this.cancellable) {
72
+ await this.cancellable.cancel();
73
+ }
74
+ }
75
+ async cleanup() {
76
+ if (this.initialized) {
77
+ await this.driver.quit();
78
+ // @ts-expect-error
79
+ this.driver = undefined;
80
+ this.initialized = false;
81
+ }
82
+ }
83
+ isAlive() {
84
+ // webdriver will throw for us, but not necessarily for all commands
85
+ // TODO: check if there are commands that will succeed if we always return true
86
+ return true;
87
+ }
88
+ name(command) {
89
+ if (!command) {
90
+ return 'skip';
91
+ }
92
+ const upperCase = command.charAt(0).toUpperCase() + command.slice(1);
93
+ const func = 'do' + upperCase;
94
+ // @ts-expect-error
95
+ if (!this[func]) {
96
+ throw new Error(`Unknown command ${command}`);
97
+ }
98
+ return func;
99
+ }
100
+ async executeHook(hook, ...args) {
101
+ const fn = this.hooks[hook];
102
+ if (!fn)
103
+ return;
104
+ // @ts-expect-error
105
+ await fn.apply(this, args);
106
+ }
107
+ async beforeCommand(commandObject) {
108
+ if (commandObject.opensWindow) {
109
+ this[state].openedWindows = await this.driver.getAllWindowHandles();
110
+ }
111
+ await this.executeHook('onBeforeCommand', { command: commandObject });
112
+ }
113
+ async afterCommand(commandObject) {
114
+ this.cancellable = undefined;
115
+ if (commandObject.opensWindow) {
116
+ const handle = await this.wait(this.waitForNewWindow(), commandObject.windowTimeout);
117
+ this.variables.set(commandObject.windowHandleName, handle);
118
+ await this.executeHook('onWindowAppeared', {
119
+ command: commandObject,
120
+ windowHandleName: commandObject.windowHandleName,
121
+ windowHandle: handle,
122
+ });
123
+ }
124
+ await this.executeHook('onAfterCommand', { command: commandObject });
125
+ }
126
+ async waitForNewWindow() {
127
+ const currentHandles = await this.driver.getAllWindowHandles();
128
+ return currentHandles.find((handle) => !this[state].openedWindows.includes(handle));
129
+ }
130
+ registerCommand(commandName, fn) {
131
+ // @ts-expect-error
132
+ this['do' + commandName.charAt(0).toUpperCase() + commandName.slice(1)] = fn;
133
+ }
134
+ // Commands go after this line
135
+ async skip() {
136
+ return Promise.resolve();
137
+ }
138
+ // window commands
139
+ async doOpen(url) {
140
+ await this.driver.get((0, utils_1.absolutifyUrl)(url, this.baseUrl));
141
+ }
142
+ async doSetWindowSize(widthXheight) {
143
+ const [width, height] = widthXheight.split('x').map((v) => parseInt(v));
144
+ await this.windowAPI.setWindowSize(this, width, height);
145
+ }
146
+ async doSelectWindow(handleLocator) {
147
+ const prefix = 'handle=';
148
+ if (handleLocator.startsWith(prefix)) {
149
+ const handle = handleLocator.substr(prefix.length);
150
+ await this.driver.switchTo().window(handle);
151
+ await this.executeHook('onWindowSwitched', {
152
+ windowHandle: handle,
153
+ });
154
+ }
155
+ else {
156
+ throw new Error('Invalid window handle given (e.g. handle=${handleVariable})');
157
+ }
158
+ }
159
+ async doClose() {
160
+ await this.driver.close();
161
+ }
162
+ async doSelectFrame(locator) {
163
+ // It's possible that for the browser and webdriver to index frames differently.
164
+ // We can ask the browser for the URL of the underlying original index and use that in
165
+ // webdriver to ensure we get the proper match.
166
+ const targetLocator = this.driver.switchTo();
167
+ if (locator === 'relative=top') {
168
+ await targetLocator.defaultContent();
169
+ }
170
+ else if (locator === 'relative=parent') {
171
+ await targetLocator.parentFrame();
172
+ }
173
+ else if (locator.startsWith('index=')) {
174
+ const frameIndex = locator.substr('index='.length);
175
+ // Delay for a second. Check too fast, and browser will think this iframe location is 'about:blank'
176
+ await new Promise((f) => setTimeout(f, 1000));
177
+ const frameUrl = await this.driver.executeScript("return window.frames['" + frameIndex + "'].location.href");
178
+ const windowFrames = await this.driver.findElements(By.css('iframe'));
179
+ let matchIndex = 0;
180
+ for (let frame of windowFrames) {
181
+ let localFrameUrl = await frame.getAttribute('src');
182
+ if (localFrameUrl === frameUrl) {
183
+ break;
184
+ }
185
+ matchIndex++;
186
+ }
187
+ this.driver.switchTo().frame(matchIndex);
188
+ // await targetLocator.frame(+locator.substr('index='.length))
189
+ }
190
+ else {
191
+ const element = await this.waitForElement(locator);
192
+ await targetLocator.frame(element);
193
+ }
194
+ }
195
+ async doSubmit() {
196
+ throw new Error('"submit" is not a supported command in Selenium WebDriver. Please re-record the step.');
197
+ }
198
+ // mouse commands
199
+ async doAddSelection(locator, optionLocator, commandObject = {}) {
200
+ const element = await this.waitForElement(locator, commandObject.targetFallback);
201
+ const option = await element.findElement(parseOptionLocator(optionLocator));
202
+ const selections = (await this.driver.executeScript('return arguments[0].selectedOptions', element));
203
+ if (!(await findElement(selections, option))) {
204
+ await option.click();
205
+ }
206
+ }
207
+ async doRemoveSelection(locator, optionLocator, commandObject = {}) {
208
+ const element = await this.waitForElement(locator, commandObject.targetFallback);
209
+ if (!(await element.getAttribute('multiple'))) {
210
+ throw new Error('Given element is not a multiple select type element');
211
+ }
212
+ const option = await element.findElement(parseOptionLocator(optionLocator));
213
+ const selections = (await this.driver.executeScript('return arguments[0].selectedOptions', element));
214
+ if (await findElement(selections, option)) {
215
+ await option.click();
216
+ }
217
+ }
218
+ async doCheck(locator, _, commandObject = {}) {
219
+ const element = await this.waitForElement(locator, commandObject.targetFallback);
220
+ if (!(await element.isSelected())) {
221
+ await element.click();
222
+ }
223
+ }
224
+ async doUncheck(locator, _, commandObject = {}) {
225
+ const element = await this.waitForElement(locator, commandObject.targetFallback);
226
+ if (await element.isSelected()) {
227
+ await element.click();
228
+ }
229
+ }
230
+ async doClick(locator, _, commandObject = {}) {
231
+ // This technically uses double the implicitWait but o well darn
232
+ const element = await this.waitForElement(locator, commandObject.targets);
233
+ const timeout = Date.now() + this.implicitWait;
234
+ await this.wait(until.elementIsVisible(element), timeout - Date.now());
235
+ await element.click();
236
+ }
237
+ async doClickAt(locator, coordString, commandObject = {}) {
238
+ const coords = parseCoordString(coordString);
239
+ const element = await this.waitForElement(locator, commandObject.targetFallback);
240
+ await this.driver
241
+ .actions({ bridge: true })
242
+ .move({ origin: element, ...coords })
243
+ .click()
244
+ .perform();
245
+ }
246
+ async doDoubleClick(locator, _, commandObject = {}) {
247
+ const element = await this.waitForElement(locator, commandObject.targetFallback);
248
+ await this.driver.actions({ bridge: true }).doubleClick(element).perform();
249
+ }
250
+ async doDoubleClickAt(locator, coordString, commandObject = {}) {
251
+ const coords = parseCoordString(coordString);
252
+ const element = await this.waitForElement(locator, commandObject.targetFallback);
253
+ await this.driver
254
+ .actions({ bridge: true })
255
+ .move({ origin: element, ...coords })
256
+ .doubleClick()
257
+ .perform();
258
+ }
259
+ async doDragAndDropToObject(dragLocator, dropLocator, commandObject = {}) {
260
+ const drag = await this.waitForElement(dragLocator, commandObject.targetFallback);
261
+ const drop = await this.waitForElement(dropLocator, commandObject.valueFallback);
262
+ await this.driver
263
+ .actions({ bridge: true })
264
+ .dragAndDrop(drag, drop)
265
+ .perform();
266
+ }
267
+ async doMouseDown(locator, _, commandObject = {}) {
268
+ const element = await this.waitForElement(locator, commandObject.targetFallback);
269
+ await this.driver
270
+ .actions({ bridge: true })
271
+ .move({ origin: element })
272
+ .press()
273
+ .perform();
274
+ }
275
+ async doMouseDownAt(locator, coordString, commandObject = {}) {
276
+ const coords = parseCoordString(coordString);
277
+ const element = await this.waitForElement(locator, commandObject.targetFallback);
278
+ await this.driver
279
+ .actions({ bridge: true })
280
+ .move({ origin: element, ...coords })
281
+ .press()
282
+ .perform();
283
+ }
284
+ async doMouseMoveAt(locator, coordString, commandObject = {}) {
285
+ const coords = parseCoordString(coordString);
286
+ const element = await this.waitForElement(locator, commandObject.targetFallback);
287
+ await this.driver
288
+ .actions({ bridge: true })
289
+ .move({ origin: element, ...coords })
290
+ .perform();
291
+ }
292
+ async doMouseOut(locator, _, commandObject = {}) {
293
+ const element = await this.waitForElement(locator, commandObject.targetFallback);
294
+ const [rect, vp] = await this.driver.executeScript('return [arguments[0].getBoundingClientRect(), {height: window.innerHeight, width: window.innerWidth}];', element);
295
+ // try top
296
+ if (rect.top > 0) {
297
+ const y = -(rect.height / 2 + 1);
298
+ return await this.driver
299
+ .actions({ bridge: true })
300
+ .move({ origin: element, y })
301
+ .perform();
302
+ }
303
+ // try right
304
+ else if (vp.width > rect.right) {
305
+ const x = rect.right / 2 + 1;
306
+ return await this.driver
307
+ .actions({ bridge: true })
308
+ .move({ origin: element, x })
309
+ .perform();
310
+ }
311
+ // try bottom
312
+ else if (vp.height > rect.bottom) {
313
+ const y = rect.height / 2 + 1;
314
+ return await this.driver
315
+ .actions({ bridge: true })
316
+ .move({ origin: element, y })
317
+ .perform();
318
+ }
319
+ // try left
320
+ else if (rect.left > 0) {
321
+ const x = -rect.right / 2;
322
+ return await this.driver
323
+ .actions({ bridge: true })
324
+ .move({ origin: element, x })
325
+ .perform();
326
+ }
327
+ throw new Error('Unable to perform mouse out as the element takes up the entire viewport');
328
+ }
329
+ async doMouseOver(locator, _, commandObject = {}) {
330
+ const element = await this.waitForElement(locator, commandObject.targetFallback);
331
+ await this.driver
332
+ .actions({ bridge: true })
333
+ .move({ origin: element })
334
+ .perform();
335
+ }
336
+ async doMouseUp(locator, _, commandObject = {}) {
337
+ const element = await this.waitForElement(locator, commandObject.targetFallback);
338
+ await this.driver
339
+ .actions({ bridge: true })
340
+ .move({ origin: element })
341
+ .release()
342
+ .perform();
343
+ }
344
+ async doMouseUpAt(locator, coordString, commandObject = {}) {
345
+ const coords = parseCoordString(coordString);
346
+ const element = await this.waitForElement(locator, commandObject.targetFallback);
347
+ await this.driver
348
+ .actions({ bridge: true })
349
+ .move({ origin: element, ...coords })
350
+ .release()
351
+ .perform();
352
+ }
353
+ async doSelect(locator, optionLocator, commandObject = {}) {
354
+ const element = await this.waitForElement(locator, commandObject.targetFallback);
355
+ const option = await element.findElement(parseOptionLocator(optionLocator));
356
+ await option.click();
357
+ }
358
+ // keyboard commands
359
+ async doEditContent(locator, value, commandObject = {}) {
360
+ const element = await this.waitForElement(locator, commandObject.targetFallback);
361
+ await this.driver.executeScript("if(arguments[0].contentEditable === 'true') {arguments[0].innerText = arguments[1]} else {throw new Error('Element is not content editable')}", element, value);
362
+ }
363
+ async doType(locator, value, commandObject = {}) {
364
+ const element = await this.waitForElement(locator, commandObject.targetFallback);
365
+ await element.clear();
366
+ await element.sendKeys(value);
367
+ }
368
+ async doSendKeys(locator, value, commandObject = {}) {
369
+ const element = await this.waitForElement(locator, commandObject.targetFallback);
370
+ await element.sendKeys(...value);
371
+ }
372
+ // wait commands
373
+ async doWaitForElementEditable(locator, timeout) {
374
+ const element = await this.driver.findElement(parseLocator(locator));
375
+ await this.wait(this.isElementEditable(element), parseInt(timeout), 'Timed out waiting for element to be editable');
376
+ }
377
+ async doWaitForElementNotEditable(locator, timeout) {
378
+ const element = await this.driver.findElement(parseLocator(locator));
379
+ await this.wait(this.isElementEditable(element), parseInt(timeout), 'Timed out waiting for element to not be editable');
380
+ }
381
+ async doWaitForElementPresent(locator, timeout) {
382
+ await this.wait(until.elementLocated(parseLocator(locator)), parseInt(timeout));
383
+ }
384
+ async doWaitForElementNotPresent(locator, timeout) {
385
+ const parsedLocator = parseLocator(locator);
386
+ const elements = await this.driver.findElements(parsedLocator);
387
+ if (elements.length !== 0) {
388
+ await this.wait(until.stalenessOf(elements[0]), parseInt(timeout));
389
+ }
390
+ }
391
+ async doWaitForElementVisible(locator, timeout) {
392
+ await this.waitForElementVisible(locator, parseInt(timeout));
393
+ }
394
+ async doWaitForElementNotVisible(locator, timeout) {
395
+ const parsedLocator = parseLocator(locator);
396
+ const elements = await this.driver.findElements(parsedLocator);
397
+ if (elements.length > 0) {
398
+ await this.wait(until.elementIsNotVisible(elements[0]), parseInt(timeout));
399
+ }
400
+ }
401
+ // script commands
402
+ async doRunScript(script) {
403
+ await this.driver.executeScript(script.script, ...script.argv);
404
+ }
405
+ async doExecuteScript(script, optionalVariable) {
406
+ const result = await this.driver.executeScript(script.script, ...script.argv);
407
+ if (optionalVariable) {
408
+ this.variables.set(optionalVariable, result);
409
+ }
410
+ }
411
+ async doExecuteAsyncScript(script, optionalVariable) {
412
+ const result = await this.driver.executeAsyncScript(`var callback = arguments[arguments.length - 1];${script.script}.then(callback).catch(callback);`, ...script.argv);
413
+ if (optionalVariable) {
414
+ this.variables.set(optionalVariable, result);
415
+ }
416
+ }
417
+ // alert commands
418
+ async doAcceptAlert() {
419
+ await this.driver.switchTo().alert().accept();
420
+ }
421
+ async doAcceptConfirmation() {
422
+ await this.driver.switchTo().alert().accept();
423
+ }
424
+ async doAnswerPrompt(optAnswer) {
425
+ const alert = await this.driver.switchTo().alert();
426
+ if (optAnswer) {
427
+ await alert.sendKeys(optAnswer);
428
+ }
429
+ await alert.accept();
430
+ }
431
+ async doDismissConfirmation() {
432
+ await this.driver.switchTo().alert().dismiss();
433
+ }
434
+ async doDismissPrompt() {
435
+ await this.driver.switchTo().alert().dismiss();
436
+ }
437
+ // store commands
438
+ async doStore(string, variable) {
439
+ this.variables.set(variable, string);
440
+ return Promise.resolve();
441
+ }
442
+ async doStoreAttribute(attributeLocator, variable) {
443
+ const attributePos = attributeLocator.lastIndexOf('@');
444
+ const elementLocator = attributeLocator.slice(0, attributePos);
445
+ const attributeName = attributeLocator.slice(attributePos + 1);
446
+ const element = await this.waitForElement(elementLocator);
447
+ const value = await element.getAttribute(attributeName);
448
+ this.variables.set(variable, value);
449
+ }
450
+ async doStoreElementCount(locator, variable) {
451
+ const elements = await this.driver.findElements(parseLocator(locator));
452
+ this.variables.set(variable, elements.length);
453
+ }
454
+ async doStoreJson(json, variable) {
455
+ this.variables.set(variable, JSON.parse(json));
456
+ return Promise.resolve();
457
+ }
458
+ async doStoreText(locator, variable, commandObject = {}) {
459
+ const element = await this.waitForElement(locator, commandObject.targetFallback);
460
+ const text = await element.getText();
461
+ this.variables.set(variable, text);
462
+ }
463
+ async doStoreTitle(variable) {
464
+ const title = await this.driver.getTitle();
465
+ this.variables.set(variable, title);
466
+ }
467
+ async doStoreValue(locator, variable, commandObject = {}) {
468
+ const element = await this.waitForElement(locator, commandObject.targetFallback);
469
+ const value = await element.getAttribute('value');
470
+ this.variables.set(variable, value);
471
+ }
472
+ async doStoreWindowHandle(variable) {
473
+ const handle = await this.driver.getWindowHandle();
474
+ this.variables.set(variable, handle);
475
+ await this.executeHook('onStoreWindowHandle', {
476
+ windowHandle: handle,
477
+ windowHandleName: variable,
478
+ });
479
+ }
480
+ // assertions
481
+ async doAssert(variableName, value) {
482
+ const variable = `${this.variables.get(variableName)}`;
483
+ if (variable != value) {
484
+ throw new errors_1.AssertionError("Actual value '" + variable + "' did not match '" + value + "'");
485
+ }
486
+ }
487
+ async doAssertAlert(expectedText) {
488
+ const alert = await this.driver.switchTo().alert();
489
+ const actualText = await alert.getText();
490
+ if (actualText !== expectedText) {
491
+ throw new errors_1.AssertionError("Actual alert text '" +
492
+ actualText +
493
+ "' did not match '" +
494
+ expectedText +
495
+ "'");
496
+ }
497
+ }
498
+ async doAssertConfirmation(expectedText) {
499
+ const alert = await this.driver.switchTo().alert();
500
+ const actualText = await alert.getText();
501
+ if (actualText !== expectedText) {
502
+ throw new errors_1.AssertionError("Actual confirm text '" +
503
+ actualText +
504
+ "' did not match '" +
505
+ expectedText +
506
+ "'");
507
+ }
508
+ }
509
+ async doAssertEditable(locator, _, commandObject = {}) {
510
+ const element = await this.waitForElement(locator, commandObject.targetFallback);
511
+ if (!(await this.isElementEditable(element))) {
512
+ throw new errors_1.AssertionError('Element is not editable');
513
+ }
514
+ }
515
+ async doAssertNotEditable(locator, _, commandObject = {}) {
516
+ const element = await this.waitForElement(locator, commandObject.targetFallback);
517
+ if (await this.isElementEditable(element)) {
518
+ throw new errors_1.AssertionError('Element is editable');
519
+ }
520
+ }
521
+ async doAssertPrompt(expectedText) {
522
+ const alert = await this.driver.switchTo().alert();
523
+ const actualText = await alert.getText();
524
+ if (actualText !== expectedText) {
525
+ throw new errors_1.AssertionError("Actual prompt text '" +
526
+ actualText +
527
+ "' did not match '" +
528
+ expectedText +
529
+ "'");
530
+ }
531
+ }
532
+ async doAssertTitle(title) {
533
+ const actualTitle = await this.driver.getTitle();
534
+ if (title != actualTitle) {
535
+ throw new errors_1.AssertionError("Actual value '" + actualTitle + "' did not match '" + title + "'");
536
+ }
537
+ }
538
+ async doAssertElementPresent(locator, _, commandObject = {}) {
539
+ await this.waitForElement(locator, commandObject.targetFallback);
540
+ }
541
+ async doAssertElementNotPresent(locator) {
542
+ const elements = await this.driver.findElements(parseLocator(locator));
543
+ if (elements.length) {
544
+ throw new errors_1.AssertionError('Unexpected element was found in page');
545
+ }
546
+ }
547
+ async doAssertText(locator, value, commandObject = {}) {
548
+ const element = await this.waitForElement(locator, commandObject.targetFallback);
549
+ const text = await element.getText();
550
+ if (text !== value) {
551
+ throw new errors_1.AssertionError("Actual value '" + text + "' did not match '" + value + "'");
552
+ }
553
+ }
554
+ async doAssertNotText(locator, value, commandObject = {}) {
555
+ const element = await this.waitForElement(locator, commandObject.targetFallback);
556
+ const text = await element.getText();
557
+ if (text === value) {
558
+ throw new errors_1.AssertionError("Actual value '" + text + "' did match '" + value + "'");
559
+ }
560
+ }
561
+ async doAssertValue(locator, value, commandObject = {}) {
562
+ const element = await this.waitForElement(locator, commandObject.targetFallback);
563
+ const elementValue = await element.getAttribute('value');
564
+ if (elementValue !== value) {
565
+ throw new errors_1.AssertionError("Actual value '" + elementValue + "' did not match '" + value + "'");
566
+ }
567
+ }
568
+ // not generally implemented
569
+ async doAssertNotValue(locator, value, commandObject = {}) {
570
+ const element = await this.waitForElement(locator, commandObject.targetFallback);
571
+ const elementValue = await element.getAttribute('value');
572
+ if (elementValue === value) {
573
+ throw new errors_1.AssertionError("Actual value '" + elementValue + "' did match '" + value + "'");
574
+ }
575
+ }
576
+ async doAssertChecked(locator, _, commandObject = {}) {
577
+ const element = await this.waitForElement(locator, commandObject.targetFallback);
578
+ if (!(await element.isSelected())) {
579
+ throw new errors_1.AssertionError('Element is not checked, expected to be checked');
580
+ }
581
+ }
582
+ async doAssertNotChecked(locator, _, commandObject = {}) {
583
+ const element = await this.waitForElement(locator, commandObject.targetFallback);
584
+ if (await element.isSelected()) {
585
+ throw new errors_1.AssertionError('Element is checked, expected to be unchecked');
586
+ }
587
+ }
588
+ async doAssertSelectedValue(locator, value, commandObject = {}) {
589
+ const element = await this.waitForElement(locator, commandObject.targetFallback);
590
+ const elementValue = await element.getAttribute('value');
591
+ if (elementValue !== value) {
592
+ throw new errors_1.AssertionError("Actual value '" + elementValue + "' did not match '" + value + "'");
593
+ }
594
+ }
595
+ async doAssertNotSelectedValue(locator, value, commandObject = {}) {
596
+ const element = await this.waitForElement(locator, commandObject.targetFallback);
597
+ const elementValue = await element.getAttribute('value');
598
+ if (elementValue === value) {
599
+ throw new errors_1.AssertionError("Actual value '" + elementValue + "' did match '" + value + "'");
600
+ }
601
+ }
602
+ async doAssertSelectedLabel(locator, label, commandObject = {}) {
603
+ const element = await this.waitForElement(locator, commandObject.targetFallback);
604
+ const selectedValue = await element.getAttribute('value');
605
+ const selectedOption = await element.findElement(By.xpath(`option[@value="${selectedValue}"]`));
606
+ const selectedOptionLabel = await selectedOption.getText();
607
+ if (selectedOptionLabel !== label) {
608
+ throw new errors_1.AssertionError("Actual value '" +
609
+ selectedOptionLabel +
610
+ "' did not match '" +
611
+ label +
612
+ "'");
613
+ }
614
+ }
615
+ async doAssertNotSelectedLabel(locator, label, commandObject = {}) {
616
+ const element = await this.waitForElement(locator, commandObject?.targetFallback);
617
+ const selectedValue = await element.getAttribute('value');
618
+ const selectedOption = await element.findElement(By.xpath(`option[@value="${selectedValue}"]`));
619
+ const selectedOptionLabel = await selectedOption.getText();
620
+ if (selectedOptionLabel === label) {
621
+ throw new errors_1.AssertionError("Actual value '" + selectedOptionLabel + "' not match '" + label + "'");
622
+ }
623
+ }
624
+ // other commands
625
+ async doDebugger() {
626
+ throw new Error('`debugger` is not supported in this run mode');
627
+ }
628
+ async doEcho(string) {
629
+ if (this.logger) {
630
+ this.logger.log(`echo: ${string}`);
631
+ }
632
+ }
633
+ async doPause(time) {
634
+ await this.driver.sleep(time);
635
+ }
636
+ async doRun() {
637
+ throw new Error('`run` is not supported in this run mode');
638
+ }
639
+ async doSetSpeed() {
640
+ throw new Error('`set speed` is not supported in this run mode');
641
+ }
642
+ async evaluateConditional(script) {
643
+ const result = await this.driver.executeScript(`return (${script.script})`, ...script.argv);
644
+ return {
645
+ value: !!result,
646
+ };
647
+ }
648
+ async waitForElement(locator, fallback = []) {
649
+ const elementLocator = parseLocator(locator);
650
+ try {
651
+ return (await this.wait(until.elementLocated(elementLocator), this.implicitWait));
652
+ }
653
+ catch (err) {
654
+ if (fallback) {
655
+ for (let i = 0; i < fallback.length; i++) {
656
+ try {
657
+ let loc = parseLocator(fallback[i][0]);
658
+ return await this.driver.findElement(loc);
659
+ }
660
+ catch (e) {
661
+ // try the next one
662
+ }
663
+ }
664
+ }
665
+ throw err;
666
+ }
667
+ }
668
+ async isElementEditable(element) {
669
+ const { enabled, readonly } = await this.driver.executeScript('return { enabled: !arguments[0].disabled, readonly: arguments[0].readOnly };', element);
670
+ return enabled && !readonly;
671
+ }
672
+ async retryToAllowForIntermittency(locator, timeout) {
673
+ const startTime = Date.now();
674
+ const element = (await this.wait(until.elementLocated(parseLocator(locator)), timeout));
675
+ const elapsed = Date.now() - startTime;
676
+ await this.wait(until.elementIsVisible(element), timeout - elapsed);
677
+ return element;
678
+ }
679
+ async waitForElementVisible(locator, timeout) {
680
+ const startTime = Date.now();
681
+ const element = (await this.wait(until.elementLocated(parseLocator(locator)), timeout));
682
+ const elapsed = Date.now() - startTime;
683
+ await this.wait(until.elementIsVisible(element), timeout - elapsed);
684
+ return element;
685
+ }
686
+ async wait(condition, timeout = 0, message = '', pollTimeout = POLL_TIMEOUT) {
687
+ if (typeof timeout !== 'number' || timeout < 0) {
688
+ throw TypeError('timeout must be a number >= 0: ' + timeout);
689
+ }
690
+ if (typeof pollTimeout !== 'number' || pollTimeout < 0) {
691
+ throw TypeError('pollTimeout must be a number >= 0: ' + pollTimeout);
692
+ }
693
+ if (isConditionPromiseLike(condition)) {
694
+ return new Promise((resolve, reject) => {
695
+ if (!timeout) {
696
+ resolve(condition);
697
+ return;
698
+ }
699
+ let start = Date.now();
700
+ let timer = setTimeout(function () {
701
+ timer = null;
702
+ reject(new TimeoutError((message ? `${message}\n` : '') +
703
+ 'Timed out waiting for promise to resolve after ' +
704
+ (Date.now() - start) +
705
+ 'ms'));
706
+ }, timeout);
707
+ const clearTimer = () => timer && clearTimeout(timer);
708
+ condition.then(function (value) {
709
+ clearTimer();
710
+ resolve(value);
711
+ }, function (error) {
712
+ clearTimer();
713
+ reject(error);
714
+ });
715
+ });
716
+ }
717
+ // @ts-expect-error
718
+ let fn = condition;
719
+ if (condition instanceof Condition) {
720
+ message = message || condition.description();
721
+ fn = condition.fn;
722
+ }
723
+ if (typeof fn !== 'function') {
724
+ throw TypeError('Wait condition must be a promise-like object, function, or a ' +
725
+ 'Condition object');
726
+ }
727
+ const { driver } = this;
728
+ function evaluateCondition() {
729
+ return new Promise((resolve, reject) => {
730
+ try {
731
+ resolve(fn(driver));
732
+ }
733
+ catch (ex) {
734
+ reject(ex);
735
+ }
736
+ });
737
+ }
738
+ let result = new Promise((resolve, reject) => {
739
+ const startTime = Date.now();
740
+ let cancelled = false;
741
+ let resolveCancel;
742
+ const cancelPromise = new Promise((res) => {
743
+ resolveCancel = res;
744
+ });
745
+ this.cancellable = {
746
+ cancel: () => {
747
+ cancelled = true;
748
+ return cancelPromise;
749
+ },
750
+ };
751
+ const pollCondition = async () => {
752
+ evaluateCondition().then((value) => {
753
+ const elapsed = Date.now() - startTime;
754
+ if (cancelled) {
755
+ resolveCancel();
756
+ reject(new Error('Aborted by user'));
757
+ this.cancellable = undefined;
758
+ }
759
+ else if (value) {
760
+ resolve(value);
761
+ this.cancellable = undefined;
762
+ }
763
+ else if (timeout && elapsed >= timeout) {
764
+ reject(new TimeoutError((message ? `${message}\n` : '') +
765
+ `Wait timed out after ${elapsed}ms`));
766
+ this.cancellable = undefined;
767
+ }
768
+ else {
769
+ setTimeout(pollCondition, pollTimeout);
770
+ }
771
+ }, reject);
772
+ };
773
+ pollCondition();
774
+ });
775
+ if (condition instanceof WebElementCondition) {
776
+ result = new WebElementPromise(driver, result.then(function (value) {
777
+ if (!(value instanceof WebElement)) {
778
+ throw TypeError('WebElementCondition did not resolve to a WebElement: ' +
779
+ Object.prototype.toString.call(value));
780
+ }
781
+ return value;
782
+ }));
783
+ }
784
+ return result;
785
+ }
786
+ }
787
+ exports.default = WebDriverExecutor;
788
+ function isConditionPromiseLike(condition) {
789
+ return condition && typeof condition.then === 'function';
790
+ }
791
+ WebDriverExecutor.prototype.doOpen = (0, preprocessors_1.composePreprocessors)(preprocessors_1.interpolateString, WebDriverExecutor.prototype.doOpen);
792
+ WebDriverExecutor.prototype.doSetWindowSize = (0, preprocessors_1.composePreprocessors)(preprocessors_1.interpolateString, WebDriverExecutor.prototype.doSetWindowSize);
793
+ WebDriverExecutor.prototype.doSelectWindow = (0, preprocessors_1.composePreprocessors)(preprocessors_1.interpolateString, WebDriverExecutor.prototype.doSelectWindow);
794
+ WebDriverExecutor.prototype.doSelectFrame = (0, preprocessors_1.composePreprocessors)(preprocessors_1.interpolateString, WebDriverExecutor.prototype.doSelectFrame);
795
+ WebDriverExecutor.prototype.doAnswerPrompt = (0, preprocessors_1.composePreprocessors)(preprocessors_1.interpolateString, null, WebDriverExecutor.prototype.doAnswerPrompt);
796
+ WebDriverExecutor.prototype.doAddSelection = (0, preprocessors_1.composePreprocessors)(preprocessors_1.interpolateString, preprocessors_1.interpolateString, {
797
+ targetFallback: (0, preprocessors_1.preprocessArray)(preprocessors_1.interpolateString),
798
+ valueFallback: (0, preprocessors_1.preprocessArray)(preprocessors_1.interpolateString),
799
+ }, WebDriverExecutor.prototype.doAddSelection);
800
+ WebDriverExecutor.prototype.doRemoveSelection = (0, preprocessors_1.composePreprocessors)(preprocessors_1.interpolateString, preprocessors_1.interpolateString, {
801
+ targetFallback: (0, preprocessors_1.preprocessArray)(preprocessors_1.interpolateString),
802
+ valueFallback: (0, preprocessors_1.preprocessArray)(preprocessors_1.interpolateString),
803
+ }, WebDriverExecutor.prototype.doRemoveSelection);
804
+ WebDriverExecutor.prototype.doCheck = (0, preprocessors_1.composePreprocessors)(preprocessors_1.interpolateString, null, { targetFallback: (0, preprocessors_1.preprocessArray)(preprocessors_1.interpolateString) }, WebDriverExecutor.prototype.doCheck);
805
+ WebDriverExecutor.prototype.doUncheck = (0, preprocessors_1.composePreprocessors)(preprocessors_1.interpolateString, null, { targetFallback: (0, preprocessors_1.preprocessArray)(preprocessors_1.interpolateString) }, WebDriverExecutor.prototype.doUncheck);
806
+ WebDriverExecutor.prototype.doClick = (0, preprocessors_1.composePreprocessors)(preprocessors_1.interpolateString, preprocessors_1.interpolateString, { targetFallback: (0, preprocessors_1.preprocessArray)(preprocessors_1.interpolateString) }, WebDriverExecutor.prototype.doClick);
807
+ WebDriverExecutor.prototype.doClickAt = (0, preprocessors_1.composePreprocessors)(preprocessors_1.interpolateString, preprocessors_1.interpolateString, { targetFallback: (0, preprocessors_1.preprocessArray)(preprocessors_1.interpolateString) }, WebDriverExecutor.prototype.doClickAt);
808
+ WebDriverExecutor.prototype.doDoubleClick = (0, preprocessors_1.composePreprocessors)(preprocessors_1.interpolateString, null, { targetFallback: (0, preprocessors_1.preprocessArray)(preprocessors_1.interpolateString) }, WebDriverExecutor.prototype.doDoubleClick);
809
+ WebDriverExecutor.prototype.doDoubleClickAt = (0, preprocessors_1.composePreprocessors)(preprocessors_1.interpolateString, preprocessors_1.interpolateString, { targetFallback: (0, preprocessors_1.preprocessArray)(preprocessors_1.interpolateString) }, WebDriverExecutor.prototype.doDoubleClickAt);
810
+ WebDriverExecutor.prototype.doDragAndDropToObject = (0, preprocessors_1.composePreprocessors)(preprocessors_1.interpolateString, preprocessors_1.interpolateString, {
811
+ targetFallback: (0, preprocessors_1.preprocessArray)(preprocessors_1.interpolateString),
812
+ valueFallback: (0, preprocessors_1.preprocessArray)(preprocessors_1.interpolateString),
813
+ }, WebDriverExecutor.prototype.doDragAndDropToObject);
814
+ WebDriverExecutor.prototype.doMouseDown = (0, preprocessors_1.composePreprocessors)(preprocessors_1.interpolateString, null, {
815
+ targetFallback: (0, preprocessors_1.preprocessArray)(preprocessors_1.interpolateString),
816
+ }, WebDriverExecutor.prototype.doMouseDown);
817
+ WebDriverExecutor.prototype.doMouseDownAt = (0, preprocessors_1.composePreprocessors)(preprocessors_1.interpolateString, preprocessors_1.interpolateString, {
818
+ targetFallback: (0, preprocessors_1.preprocessArray)(preprocessors_1.interpolateString),
819
+ }, WebDriverExecutor.prototype.doMouseDownAt);
820
+ WebDriverExecutor.prototype.doMouseMoveAt = (0, preprocessors_1.composePreprocessors)(preprocessors_1.interpolateString, preprocessors_1.interpolateString, {
821
+ targetFallback: (0, preprocessors_1.preprocessArray)(preprocessors_1.interpolateString),
822
+ }, WebDriverExecutor.prototype.doMouseMoveAt);
823
+ WebDriverExecutor.prototype.doMouseOut = (0, preprocessors_1.composePreprocessors)(preprocessors_1.interpolateString, null, {
824
+ targetFallback: (0, preprocessors_1.preprocessArray)(preprocessors_1.interpolateString),
825
+ }, WebDriverExecutor.prototype.doMouseOut);
826
+ WebDriverExecutor.prototype.doMouseOver = (0, preprocessors_1.composePreprocessors)(preprocessors_1.interpolateString, null, {
827
+ targetFallback: (0, preprocessors_1.preprocessArray)(preprocessors_1.interpolateString),
828
+ }, WebDriverExecutor.prototype.doMouseOver);
829
+ WebDriverExecutor.prototype.doMouseUp = (0, preprocessors_1.composePreprocessors)(preprocessors_1.interpolateString, null, {
830
+ targetFallback: (0, preprocessors_1.preprocessArray)(preprocessors_1.interpolateString),
831
+ }, WebDriverExecutor.prototype.doMouseUp);
832
+ WebDriverExecutor.prototype.doMouseUpAt = (0, preprocessors_1.composePreprocessors)(preprocessors_1.interpolateString, preprocessors_1.interpolateString, {
833
+ targetFallback: (0, preprocessors_1.preprocessArray)(preprocessors_1.interpolateString),
834
+ }, WebDriverExecutor.prototype.doMouseUpAt);
835
+ WebDriverExecutor.prototype.doSelect = (0, preprocessors_1.composePreprocessors)(preprocessors_1.interpolateString, preprocessors_1.interpolateString, {
836
+ targetFallback: (0, preprocessors_1.preprocessArray)(preprocessors_1.interpolateString),
837
+ valueFallback: (0, preprocessors_1.preprocessArray)(preprocessors_1.interpolateString),
838
+ }, WebDriverExecutor.prototype.doSelect);
839
+ WebDriverExecutor.prototype.doEditContent = (0, preprocessors_1.composePreprocessors)(preprocessors_1.interpolateString, preprocessors_1.interpolateString, {
840
+ targetFallback: (0, preprocessors_1.preprocessArray)(preprocessors_1.interpolateString),
841
+ }, WebDriverExecutor.prototype.doEditContent);
842
+ WebDriverExecutor.prototype.doType = (0, preprocessors_1.composePreprocessors)(preprocessors_1.interpolateString, preprocessors_1.interpolateString, { targetFallback: (0, preprocessors_1.preprocessArray)(preprocessors_1.interpolateString) }, WebDriverExecutor.prototype.doType);
843
+ WebDriverExecutor.prototype.doSendKeys = (0, preprocessors_1.composePreprocessors)(preprocessors_1.interpolateString, preprocessKeys, { targetFallback: (0, preprocessors_1.preprocessArray)(preprocessors_1.interpolateString) }, WebDriverExecutor.prototype.doSendKeys);
844
+ WebDriverExecutor.prototype.doRunScript = (0, preprocessors_1.composePreprocessors)(preprocessors_1.interpolateScript, WebDriverExecutor.prototype.doRunScript);
845
+ WebDriverExecutor.prototype.doExecuteScript = (0, preprocessors_1.composePreprocessors)(preprocessors_1.interpolateScript, null, WebDriverExecutor.prototype.doExecuteScript);
846
+ WebDriverExecutor.prototype.doExecuteAsyncScript = (0, preprocessors_1.composePreprocessors)(preprocessors_1.interpolateScript, null, WebDriverExecutor.prototype.doExecuteAsyncScript);
847
+ WebDriverExecutor.prototype.doStore = (0, preprocessors_1.composePreprocessors)(preprocessors_1.interpolateString, null, WebDriverExecutor.prototype.doStore);
848
+ WebDriverExecutor.prototype.doStoreAttribute = (0, preprocessors_1.composePreprocessors)(preprocessors_1.interpolateString, null, { targetFallback: (0, preprocessors_1.preprocessArray)(preprocessors_1.interpolateString) }, WebDriverExecutor.prototype.doStoreAttribute);
849
+ WebDriverExecutor.prototype.doStoreElementCount = (0, preprocessors_1.composePreprocessors)(preprocessors_1.interpolateString, null, { targetFallback: (0, preprocessors_1.preprocessArray)(preprocessors_1.interpolateString) }, WebDriverExecutor.prototype.doStoreElementCount);
850
+ WebDriverExecutor.prototype.doStoreJson = (0, preprocessors_1.composePreprocessors)(preprocessors_1.interpolateString, null, WebDriverExecutor.prototype.doStoreJson);
851
+ WebDriverExecutor.prototype.doStoreText = (0, preprocessors_1.composePreprocessors)(preprocessors_1.interpolateString, null, { targetFallback: (0, preprocessors_1.preprocessArray)(preprocessors_1.interpolateString) }, WebDriverExecutor.prototype.doStoreText);
852
+ WebDriverExecutor.prototype.doStoreValue = (0, preprocessors_1.composePreprocessors)(preprocessors_1.interpolateString, null, { targetFallback: (0, preprocessors_1.preprocessArray)(preprocessors_1.interpolateString) }, WebDriverExecutor.prototype.doStoreValue);
853
+ WebDriverExecutor.prototype.doAssert = (0, preprocessors_1.composePreprocessors)(null, preprocessors_1.interpolateString, WebDriverExecutor.prototype.doAssert);
854
+ WebDriverExecutor.prototype.doAssertAlert = (0, preprocessors_1.composePreprocessors)(preprocessors_1.interpolateString, null, WebDriverExecutor.prototype.doAssertAlert);
855
+ WebDriverExecutor.prototype.doAssertConfirmation = (0, preprocessors_1.composePreprocessors)(preprocessors_1.interpolateString, null, WebDriverExecutor.prototype.doAssertConfirmation);
856
+ WebDriverExecutor.prototype.doAssertEditable = (0, preprocessors_1.composePreprocessors)(preprocessors_1.interpolateString, null, { targetFallback: (0, preprocessors_1.preprocessArray)(preprocessors_1.interpolateString) }, WebDriverExecutor.prototype.doAssertEditable);
857
+ WebDriverExecutor.prototype.doAssertNotEditable = (0, preprocessors_1.composePreprocessors)(preprocessors_1.interpolateString, null, { targetFallback: (0, preprocessors_1.preprocessArray)(preprocessors_1.interpolateString) }, WebDriverExecutor.prototype.doAssertNotEditable);
858
+ WebDriverExecutor.prototype.doAssertPrompt = (0, preprocessors_1.composePreprocessors)(preprocessors_1.interpolateString, null, WebDriverExecutor.prototype.doAssertPrompt);
859
+ WebDriverExecutor.prototype.doAssertText = (0, preprocessors_1.composePreprocessors)(preprocessors_1.interpolateString, preprocessors_1.interpolateString, WebDriverExecutor.prototype.doAssertText);
860
+ WebDriverExecutor.prototype.doEcho = (0, preprocessors_1.composePreprocessors)(preprocessors_1.interpolateString, WebDriverExecutor.prototype.doEcho);
861
+ function createVerifyCommands(Executor) {
862
+ // @ts-expect-error
863
+ Object.getOwnPropertyNames(Executor.prototype)
864
+ .filter((command) => /^doAssert/.test(command))
865
+ .forEach((assertion) => {
866
+ const verify = assertion.replace('doAssert', 'doVerify');
867
+ // @ts-expect-error
868
+ Executor.prototype[verify] = {
869
+ // creating the function inside an object since function declared in an
870
+ // object are named after the property, thus creating dyanmic named funcs
871
+ // also in order to be able to call(this) the function has to be normal
872
+ // declaration rather than arrow, as arrow will be bound to
873
+ // createVerifyCommands context which is undefined
874
+ [verify]: async function (...args) {
875
+ try {
876
+ // @ts-expect-error
877
+ return await Executor.prototype[assertion].call(this, ...args);
878
+ }
879
+ catch (err) {
880
+ if (err instanceof errors_1.AssertionError) {
881
+ throw new errors_1.VerificationError(err.message);
882
+ }
883
+ throw err;
884
+ }
885
+ },
886
+ }[verify];
887
+ });
888
+ }
889
+ // @ts-expect-error
890
+ createVerifyCommands(WebDriverExecutor);
891
+ function parseLocator(locator) {
892
+ if (/^\/\//.test(locator)) {
893
+ return By.xpath(locator);
894
+ }
895
+ const fragments = locator.split('=');
896
+ const type = fragments.shift();
897
+ const selector = fragments.join('=');
898
+ if (LOCATORS[type] && selector) {
899
+ return LOCATORS[type](selector);
900
+ }
901
+ else {
902
+ throw new Error(type ? `Unknown locator ${type}` : "Locator can't be empty");
903
+ }
904
+ }
905
+ function parseOptionLocator(locator) {
906
+ const fragments = locator.split('=');
907
+ const type = fragments.shift();
908
+ const selector = fragments.join('=');
909
+ if (OPTIONS_LOCATORS[type] && selector) {
910
+ return OPTIONS_LOCATORS[type](selector);
911
+ }
912
+ else if (!selector) {
913
+ // no selector strategy given, assuming label
914
+ return OPTIONS_LOCATORS['label'](type);
915
+ }
916
+ else {
917
+ throw new Error(type ? `Unknown selection locator ${type}` : "Locator can't be empty");
918
+ }
919
+ }
920
+ function parseCoordString(coord) {
921
+ const [x, y] = coord.split(',').map((n) => parseInt(n));
922
+ return {
923
+ x,
924
+ y,
925
+ };
926
+ }
927
+ function preprocessKeys(_str, variables) {
928
+ const str = (0, preprocessors_1.interpolateString)(_str, variables);
929
+ let keys = [];
930
+ let match = str.match(/\$\{\w+\}/g);
931
+ if (!match) {
932
+ keys.push(str);
933
+ }
934
+ else {
935
+ let i = 0;
936
+ while (i < str.length) {
937
+ let currentKey = match.shift(), currentKeyIndex = str.indexOf(currentKey, i);
938
+ if (currentKeyIndex > i) {
939
+ // push the string before the current key
940
+ keys.push(str.substr(i, currentKeyIndex - i));
941
+ i = currentKeyIndex;
942
+ }
943
+ if (currentKey) {
944
+ if (/^\$\{KEY_\w+\}/.test(currentKey)) {
945
+ // is a key
946
+ let keyName = currentKey.match(/\$\{KEY_(\w+)\}/)[1];
947
+ // @ts-expect-error
948
+ let key = Key[keyName];
949
+ if (key) {
950
+ keys.push(key);
951
+ }
952
+ else {
953
+ throw new Error(`Unrecognised key ${keyName}`);
954
+ }
955
+ }
956
+ else {
957
+ // not a key, and not a stored variable, push it as-is
958
+ keys.push(currentKey);
959
+ }
960
+ i += currentKey.length;
961
+ }
962
+ else if (i < str.length) {
963
+ // push the rest of the string
964
+ keys.push(str.substr(i, str.length));
965
+ i = str.length;
966
+ }
967
+ }
968
+ }
969
+ return keys;
970
+ }
971
+ const LOCATORS = {
972
+ id: By.id,
973
+ name: By.name,
974
+ link: By.linkText,
975
+ linkText: By.linkText,
976
+ partialLinkText: By.partialLinkText,
977
+ css: By.css,
978
+ xpath: By.xpath,
979
+ };
980
+ const nbsp = String.fromCharCode(160);
981
+ const OPTIONS_LOCATORS = {
982
+ id: (id) => By.css(`*[id="${id}"]`),
983
+ value: (value) => By.css(`*[value="${value}"]`),
984
+ label: (label) => {
985
+ const labels = label.match(/^[\w|-]+(?=:)/);
986
+ if (labels?.length) {
987
+ const [type, ...labelParts] = label.split(':');
988
+ const labelBody = labelParts.join(':');
989
+ switch (type) {
990
+ case 'mostly-equals':
991
+ return By.xpath(`//option[normalize-space(translate(., '${nbsp}', ' ')) = '${labelBody}']`);
992
+ }
993
+ }
994
+ return By.xpath(`//option[. = '${label}']`);
995
+ },
996
+ index: (index) => By.css(`*:nth-child(${index})`),
997
+ };
998
+ async function findElement(elements, element) {
999
+ const id = await element.getId();
1000
+ for (let i = 0; i < elements.length; i++) {
1001
+ if ((await elements[i].getId()) === id) {
1002
+ return true;
1003
+ }
1004
+ }
1005
+ return false;
1006
+ }
1007
+ //# sourceMappingURL=webdriver.js.map