codeceptjs 3.6.6 → 4.0.0-beta.1

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 (151) hide show
  1. package/bin/codecept.js +81 -84
  2. package/lib/actor.js +13 -13
  3. package/lib/ai.js +13 -10
  4. package/lib/assert/empty.js +21 -20
  5. package/lib/assert/equal.js +39 -37
  6. package/lib/assert/error.js +14 -14
  7. package/lib/assert/include.js +47 -46
  8. package/lib/assert/throws.js +11 -13
  9. package/lib/assert/truth.js +22 -19
  10. package/lib/assert.js +2 -4
  11. package/lib/cli.js +49 -57
  12. package/lib/codecept.js +155 -142
  13. package/lib/colorUtils.js +3 -3
  14. package/lib/command/configMigrate.js +52 -58
  15. package/lib/command/definitions.js +89 -88
  16. package/lib/command/dryRun.js +68 -71
  17. package/lib/command/generate.js +188 -197
  18. package/lib/command/gherkin/init.js +16 -27
  19. package/lib/command/gherkin/snippets.js +20 -20
  20. package/lib/command/gherkin/steps.js +8 -8
  21. package/lib/command/info.js +38 -40
  22. package/lib/command/init.js +288 -290
  23. package/lib/command/interactive.js +32 -32
  24. package/lib/command/list.js +26 -26
  25. package/lib/command/run-multiple/chunk.js +5 -5
  26. package/lib/command/run-multiple/collection.js +3 -3
  27. package/lib/command/run-multiple/run.js +2 -6
  28. package/lib/command/run-multiple.js +93 -113
  29. package/lib/command/run-rerun.js +25 -20
  30. package/lib/command/run-workers.js +66 -64
  31. package/lib/command/run.js +29 -26
  32. package/lib/command/utils.js +65 -80
  33. package/lib/command/workers/runTests.js +10 -10
  34. package/lib/config.js +9 -10
  35. package/lib/container.js +48 -40
  36. package/lib/data/context.js +59 -60
  37. package/lib/data/dataScenarioConfig.js +47 -47
  38. package/lib/data/dataTableArgument.js +29 -29
  39. package/lib/data/table.js +20 -26
  40. package/lib/dirname.js +5 -0
  41. package/lib/event.js +167 -163
  42. package/lib/heal.js +17 -13
  43. package/lib/helper/AI.js +41 -130
  44. package/lib/helper/ApiDataFactory.js +69 -73
  45. package/lib/helper/Appium.js +381 -412
  46. package/lib/helper/Expect.js +425 -0
  47. package/lib/helper/ExpectHelper.js +48 -40
  48. package/lib/helper/FileSystem.js +79 -80
  49. package/lib/helper/GraphQL.js +43 -44
  50. package/lib/helper/GraphQLDataFactory.js +50 -50
  51. package/lib/helper/JSONResponse.js +62 -65
  52. package/lib/helper/Mochawesome.js +28 -28
  53. package/lib/helper/MockServer.js +14 -12
  54. package/lib/helper/Nightmare.js +566 -662
  55. package/lib/helper/Playwright.js +1216 -1361
  56. package/lib/helper/Protractor.js +627 -663
  57. package/lib/helper/Puppeteer.js +1128 -1231
  58. package/lib/helper/REST.js +68 -159
  59. package/lib/helper/SoftExpectHelper.js +2 -2
  60. package/lib/helper/TestCafe.js +484 -490
  61. package/lib/helper/WebDriver.js +1156 -1297
  62. package/lib/helper/clientscripts/PollyWebDriverExt.js +1 -1
  63. package/lib/helper/errors/ConnectionRefused.js +1 -1
  64. package/lib/helper/errors/ElementAssertion.js +2 -2
  65. package/lib/helper/errors/ElementNotFound.js +2 -2
  66. package/lib/helper/errors/RemoteBrowserConnectionRefused.js +1 -1
  67. package/lib/helper/extras/Console.js +1 -1
  68. package/lib/helper/extras/PlaywrightPropEngine.js +2 -2
  69. package/lib/helper/extras/PlaywrightReactVueLocator.js +1 -1
  70. package/lib/helper/extras/PlaywrightRestartOpts.js +18 -21
  71. package/lib/helper/extras/Popup.js +1 -1
  72. package/lib/helper/extras/React.js +3 -3
  73. package/lib/helper/network/actions.js +7 -14
  74. package/lib/helper/network/utils.js +2 -3
  75. package/lib/helper/scripts/blurElement.js +1 -1
  76. package/lib/helper/scripts/focusElement.js +1 -1
  77. package/lib/helper/scripts/highlightElement.js +1 -1
  78. package/lib/helper/scripts/isElementClickable.js +1 -1
  79. package/lib/helper/testcafe/testControllerHolder.js +1 -1
  80. package/lib/helper/testcafe/testcafe-utils.js +7 -6
  81. package/lib/helper.js +3 -1
  82. package/lib/history.js +5 -6
  83. package/lib/hooks.js +6 -6
  84. package/lib/html.js +7 -7
  85. package/lib/index.js +41 -25
  86. package/lib/interfaces/bdd.js +64 -47
  87. package/lib/interfaces/featureConfig.js +19 -19
  88. package/lib/interfaces/gherkin.js +118 -124
  89. package/lib/interfaces/scenarioConfig.js +29 -29
  90. package/lib/listener/artifacts.js +9 -9
  91. package/lib/listener/config.js +24 -24
  92. package/lib/listener/exit.js +12 -12
  93. package/lib/listener/helpers.js +42 -42
  94. package/lib/listener/mocha.js +11 -11
  95. package/lib/listener/retry.js +30 -32
  96. package/lib/listener/steps.js +53 -50
  97. package/lib/listener/timeout.js +54 -54
  98. package/lib/locator.js +10 -6
  99. package/lib/mochaFactory.js +15 -18
  100. package/lib/output.js +10 -6
  101. package/lib/parser.js +12 -15
  102. package/lib/pause.js +33 -40
  103. package/lib/plugin/allure.js +15 -15
  104. package/lib/plugin/autoDelay.js +37 -29
  105. package/lib/plugin/autoLogin.js +65 -70
  106. package/lib/plugin/commentStep.js +18 -18
  107. package/lib/plugin/coverage.js +67 -115
  108. package/lib/plugin/customLocator.js +20 -21
  109. package/lib/plugin/debugErrors.js +24 -24
  110. package/lib/plugin/eachElement.js +38 -38
  111. package/lib/plugin/fakerTransform.js +6 -6
  112. package/lib/plugin/heal.js +108 -67
  113. package/lib/plugin/pauseOnFail.js +11 -11
  114. package/lib/plugin/retryFailedStep.js +39 -32
  115. package/lib/plugin/retryTo.js +40 -46
  116. package/lib/plugin/screenshotOnFail.js +87 -109
  117. package/lib/plugin/selenoid.js +118 -131
  118. package/lib/plugin/standardActingHelpers.js +8 -2
  119. package/lib/plugin/stepByStepReport.js +91 -110
  120. package/lib/plugin/stepTimeout.js +23 -24
  121. package/lib/plugin/subtitles.js +35 -34
  122. package/lib/plugin/tryTo.js +30 -40
  123. package/lib/plugin/wdio.js +75 -78
  124. package/lib/recorder.js +17 -14
  125. package/lib/rerun.js +10 -11
  126. package/lib/scenario.js +23 -25
  127. package/lib/secret.js +2 -4
  128. package/lib/session.js +10 -10
  129. package/lib/step.js +9 -12
  130. package/lib/store.js +3 -2
  131. package/lib/transform.js +1 -1
  132. package/lib/translation.js +8 -7
  133. package/lib/ui.js +14 -12
  134. package/lib/utils.js +72 -70
  135. package/lib/within.js +10 -10
  136. package/lib/workerStorage.js +25 -27
  137. package/lib/workers.js +32 -29
  138. package/package.json +53 -51
  139. package/translations/de-DE.js +1 -1
  140. package/translations/fr-FR.js +1 -1
  141. package/translations/index.js +13 -9
  142. package/translations/it-IT.js +1 -1
  143. package/translations/ja-JP.js +1 -1
  144. package/translations/pl-PL.js +1 -1
  145. package/translations/pt-BR.js +1 -1
  146. package/translations/ru-RU.js +1 -1
  147. package/translations/zh-CN.js +1 -1
  148. package/translations/zh-TW.js +1 -1
  149. package/typings/index.d.ts +65 -415
  150. package/typings/promiseBasedTypes.d.ts +32 -0
  151. package/typings/types.d.ts +32 -0
@@ -1,26 +1,25 @@
1
- let webdriverio
2
-
3
- const fs = require('fs')
4
- const axios = require('axios').default
5
- const { v4: uuidv4 } = require('uuid')
6
-
7
- const Webdriver = require('./WebDriver')
8
- const AssertionFailedError = require('../assert/error')
9
- const { truth } = require('../assert/truth')
10
- const recorder = require('../recorder')
11
- const Locator = require('../locator')
12
- const ConnectionRefused = require('./errors/ConnectionRefused')
13
-
14
- const mobileRoot = '//*'
15
- const webRoot = 'body'
1
+ import fs from 'fs';
2
+ import { default as axios } from 'axios';
3
+ import { v4 as uuidv4 } from 'uuid';
4
+ import Webdriver from './WebDriver';
5
+ import AssertionFailedError from '../assert/error.js';
6
+ import { truth } from '../assert/truth';
7
+ import recorder from '../recorder.js';
8
+ import Locator from '../locator.js';
9
+ import ConnectionRefused from './errors/ConnectionRefused.js';
10
+
11
+ let webdriverio;
12
+
13
+ const mobileRoot = '//*';
14
+ const webRoot = 'body';
16
15
  const supportedPlatform = {
17
16
  android: 'Android',
18
17
  iOS: 'iOS',
19
- }
18
+ };
20
19
 
21
20
  const vendorPrefix = {
22
21
  appium: 'appium',
23
- }
22
+ };
24
23
 
25
24
  /**
26
25
  * Appium helper extends [Webdriver](http://codecept.io/helpers/WebDriver/) helper.
@@ -175,21 +174,19 @@ class Appium extends Webdriver {
175
174
 
176
175
  // @ts-ignore
177
176
  constructor(config) {
178
- super(config)
177
+ super(config);
179
178
 
180
- this.isRunning = false
179
+ this.isRunning = false;
181
180
  if (config.appiumV2 === true) {
182
- this.appiumV2 = true
181
+ this.appiumV2 = true;
183
182
  }
184
- this.axios = axios.create()
183
+ this.axios = axios.create();
185
184
 
186
- webdriverio = require('webdriverio')
185
+ webdriverio = require('webdriverio');
187
186
  if (!config.appiumV2) {
188
- console.log(
189
- 'The Appium core team does not maintain Appium 1.x anymore since the 1st of January 2022. Please migrating to Appium 2.x by adding appiumV2: true to your config.',
190
- )
191
- console.log('More info: https://bit.ly/appium-v2-migration')
192
- console.log('This Appium 1.x support will be removed in next major release.')
187
+ console.log('The Appium core team does not maintain Appium 1.x anymore since the 1st of January 2022. Please migrating to Appium 2.x by adding appiumV2: true to your config.');
188
+ console.log('More info: https://bit.ly/appium-v2-migration');
189
+ console.log('This Appium 1.x support will be removed in next major release.');
193
190
  }
194
191
  }
195
192
 
@@ -206,7 +203,7 @@ class Appium extends Webdriver {
206
203
  }
207
204
  }
208
205
  }
209
- `)
206
+ `);
210
207
  }
211
208
 
212
209
  // set defaults
@@ -227,174 +224,166 @@ class Appium extends Webdriver {
227
224
  timeouts: {
228
225
  script: 0, // ms
229
226
  },
230
- }
227
+ };
231
228
 
232
229
  // override defaults with config
233
- config = Object.assign(defaults, config)
230
+ config = Object.assign(defaults, config);
234
231
 
235
- config.baseUrl = config.url || config.baseUrl
232
+ config.baseUrl = config.url || config.baseUrl;
236
233
  if (config.desiredCapabilities && Object.keys(config.desiredCapabilities).length) {
237
- config.capabilities =
238
- this.appiumV2 === true ? this._convertAppiumV2Caps(config.desiredCapabilities) : config.desiredCapabilities
234
+ config.capabilities = this.appiumV2 === true ? this._convertAppiumV2Caps(config.desiredCapabilities) : config.desiredCapabilities;
239
235
  }
240
236
 
241
237
  if (this.appiumV2) {
242
- config.capabilities[`${vendorPrefix.appium}:deviceName`] =
243
- config[`${vendorPrefix.appium}:device`] || config.capabilities[`${vendorPrefix.appium}:deviceName`]
244
- config.capabilities[`${vendorPrefix.appium}:browserName`] =
245
- config[`${vendorPrefix.appium}:browser`] || config.capabilities[`${vendorPrefix.appium}:browserName`]
246
- config.capabilities[`${vendorPrefix.appium}:app`] =
247
- config[`${vendorPrefix.appium}:app`] || config.capabilities[`${vendorPrefix.appium}:app`]
248
- config.capabilities[`${vendorPrefix.appium}:tunnelIdentifier`] =
249
- config[`${vendorPrefix.appium}:tunnelIdentifier`] ||
250
- config.capabilities[`${vendorPrefix.appium}:tunnelIdentifier`] // Adding the code to connect to sauce labs via sauce tunnel
238
+ config.capabilities[`${vendorPrefix.appium}:deviceName`] = config[`${vendorPrefix.appium}:device`] || config.capabilities[`${vendorPrefix.appium}:deviceName`];
239
+ config.capabilities[`${vendorPrefix.appium}:browserName`] = config[`${vendorPrefix.appium}:browser`] || config.capabilities[`${vendorPrefix.appium}:browserName`];
240
+ config.capabilities[`${vendorPrefix.appium}:app`] = config[`${vendorPrefix.appium}:app`] || config.capabilities[`${vendorPrefix.appium}:app`];
241
+ config.capabilities[`${vendorPrefix.appium}:tunnelIdentifier`] = config[`${vendorPrefix.appium}:tunnelIdentifier`] || config.capabilities[`${vendorPrefix.appium}:tunnelIdentifier`]; // Adding the code to connect to sauce labs via sauce tunnel
251
242
  } else {
252
- config.capabilities.deviceName = config.device || config.capabilities.deviceName
253
- config.capabilities.browserName = config.browser || config.capabilities.browserName
254
- config.capabilities.app = config.app || config.capabilities.app
255
- config.capabilities.tunnelIdentifier = config.tunnelIdentifier || config.capabilities.tunnelIdentifier // Adding the code to connect to sauce labs via sauce tunnel
243
+ config.capabilities.deviceName = config.device || config.capabilities.deviceName;
244
+ config.capabilities.browserName = config.browser || config.capabilities.browserName;
245
+ config.capabilities.app = config.app || config.capabilities.app;
246
+ config.capabilities.tunnelIdentifier = config.tunnelIdentifier || config.capabilities.tunnelIdentifier; // Adding the code to connect to sauce labs via sauce tunnel
256
247
  }
257
248
 
258
- config.capabilities.platformName = config.platform || config.capabilities.platformName
259
- config.waitForTimeoutInSeconds = config.waitForTimeout / 1000 // convert to seconds
249
+ config.capabilities.platformName = config.platform || config.capabilities.platformName;
250
+ config.waitForTimeoutInSeconds = config.waitForTimeout / 1000; // convert to seconds
260
251
 
261
252
  // [CodeceptJS compatible] transform host to hostname
262
- config.hostname = config.host || config.hostname
253
+ config.hostname = config.host || config.hostname;
263
254
 
264
255
  if (!config.app && config.capabilities.browserName) {
265
- this.isWeb = true
266
- this.root = webRoot
256
+ this.isWeb = true;
257
+ this.root = webRoot;
267
258
  } else {
268
- this.isWeb = false
269
- this.root = mobileRoot
259
+ this.isWeb = false;
260
+ this.root = mobileRoot;
270
261
  }
271
262
 
272
- this.platform = null
263
+ this.platform = null;
273
264
  if (config.capabilities[`${vendorPrefix.appium}:platformName`]) {
274
- this.platform = config.capabilities[`${vendorPrefix.appium}:platformName`].toLowerCase()
265
+ this.platform = config.capabilities[`${vendorPrefix.appium}:platformName`].toLowerCase();
275
266
  }
276
267
 
277
268
  if (config.capabilities.platformName) {
278
- this.platform = config.capabilities.platformName.toLowerCase()
269
+ this.platform = config.capabilities.platformName.toLowerCase();
279
270
  }
280
271
 
281
- return config
272
+ return config;
282
273
  }
283
274
 
284
275
  _convertAppiumV2Caps(capabilities) {
285
- const _convertedCaps = {}
276
+ const _convertedCaps = {};
286
277
  for (const [key, value] of Object.entries(capabilities)) {
287
278
  if (!key.startsWith(vendorPrefix.appium)) {
288
279
  if (key !== 'platformName' && key !== 'bstack:options') {
289
- _convertedCaps[`${vendorPrefix.appium}:${key}`] = value
280
+ _convertedCaps[`${vendorPrefix.appium}:${key}`] = value;
290
281
  } else {
291
- _convertedCaps[`${key}`] = value
282
+ _convertedCaps[`${key}`] = value;
292
283
  }
293
284
  } else {
294
- _convertedCaps[`${key}`] = value
285
+ _convertedCaps[`${key}`] = value;
295
286
  }
296
287
  }
297
- return _convertedCaps
288
+ return _convertedCaps;
298
289
  }
299
290
 
300
291
  static _config() {
301
- return [
302
- {
303
- name: 'app',
304
- message: 'Application package. Path to file or url',
305
- default: 'http://localhost',
306
- },
307
- {
308
- name: 'platform',
309
- message: 'Mobile Platform',
310
- type: 'list',
311
- choices: ['iOS', supportedPlatform.android],
312
- default: supportedPlatform.android,
313
- },
314
- {
315
- name: 'device',
316
- message: 'Device to run tests on',
317
- default: 'emulator',
318
- },
319
- ]
292
+ return [{
293
+ name: 'app',
294
+ message: 'Application package. Path to file or url',
295
+ default: 'http://localhost',
296
+ }, {
297
+ name: 'platform',
298
+ message: 'Mobile Platform',
299
+ type: 'list',
300
+ choices: ['iOS', supportedPlatform.android],
301
+ default: supportedPlatform.android,
302
+ }, {
303
+ name: 'device',
304
+ message: 'Device to run tests on',
305
+ default: 'emulator',
306
+ }];
320
307
  }
321
308
 
322
309
  async _startBrowser() {
323
310
  if (this.appiumV2 === true) {
324
- this.options.capabilities = this._convertAppiumV2Caps(this.options.capabilities)
325
- this.options.desiredCapabilities = this._convertAppiumV2Caps(this.options.desiredCapabilities)
311
+ this.options.capabilities = this._convertAppiumV2Caps(this.options.capabilities);
312
+ this.options.desiredCapabilities = this._convertAppiumV2Caps(this.options.desiredCapabilities);
326
313
  }
327
314
 
328
315
  try {
329
316
  if (this.options.multiremote) {
330
- this.browser = await webdriverio.multiremote(this.options.multiremote)
317
+ this.browser = await webdriverio.multiremote(this.options.multiremote);
331
318
  } else {
332
- this.browser = await webdriverio.remote(this.options)
319
+ this.browser = await webdriverio.remote(this.options);
333
320
  }
334
321
  } catch (err) {
335
322
  if (err.toString().indexOf('ECONNREFUSED')) {
336
- throw new ConnectionRefused(err)
323
+ throw new ConnectionRefused(err);
337
324
  }
338
- throw err
325
+ throw err;
339
326
  }
340
- this.$$ = this.browser.$$.bind(this.browser)
327
+ this.$$ = this.browser.$$.bind(this.browser);
341
328
 
342
- this.isRunning = true
329
+ this.isRunning = true;
343
330
  if (this.options.timeouts && this.isWeb) {
344
- await this.defineTimeout(this.options.timeouts)
331
+ await this.defineTimeout(this.options.timeouts);
345
332
  }
346
333
  if (this.options.windowSize === 'maximize' && !this.platform) {
347
- const res = await this.browser.execute('return [screen.width, screen.height]')
334
+ const res = await this.browser.execute('return [screen.width, screen.height]');
348
335
  return this.browser.windowHandleSize({
349
336
  width: res.value[0],
350
337
  height: res.value[1],
351
- })
338
+ });
352
339
  }
353
340
  if (this.options.windowSize && this.options.windowSize.indexOf('x') > 0 && !this.platform) {
354
- const dimensions = this.options.windowSize.split('x')
341
+ const dimensions = this.options.windowSize.split('x');
355
342
  await this.browser.windowHandleSize({
356
343
  width: dimensions[0],
357
344
  height: dimensions[1],
358
- })
345
+ });
359
346
  }
360
347
  }
361
348
 
362
349
  async _after() {
363
- if (!this.isRunning) return
350
+ if (!this.isRunning) return;
364
351
  if (this.options.restart) {
365
- this.isRunning = false
366
- return this.browser.deleteSession()
352
+ this.isRunning = false;
353
+ return this.browser.deleteSession();
367
354
  }
368
355
  if (this.isWeb && !this.platform) {
369
- return super._after()
356
+ return super._after();
370
357
  }
371
358
  }
372
359
 
373
360
  async _withinBegin(context) {
374
361
  if (this.isWeb) {
375
- return super._withinBegin(context)
362
+ return super._withinBegin(context);
376
363
  }
377
364
  if (context === 'webview') {
378
- return this.switchToWeb()
365
+ return this.switchToWeb();
379
366
  }
380
367
  if (typeof context === 'object') {
381
- if (context.web) return this.switchToWeb(context.web)
382
- if (context.webview) return this.switchToWeb(context.webview)
368
+ if (context.web) return this.switchToWeb(context.web);
369
+ if (context.webview) return this.switchToWeb(context.webview);
383
370
  }
384
- return this.switchToContext(context)
371
+ return this.switchToContext(context);
385
372
  }
386
373
 
387
374
  _withinEnd() {
388
375
  if (this.isWeb) {
389
- return super._withinEnd()
376
+ return super._withinEnd();
390
377
  }
391
- return this.switchToNative()
378
+ return this.switchToNative();
392
379
  }
393
380
 
394
381
  _buildAppiumEndpoint() {
395
- const { protocol, port, hostname, path } = this.browser.options
382
+ const {
383
+ protocol, port, hostname, path,
384
+ } = this.browser.options;
396
385
  // Build path to Appium REST API endpoint
397
- return `${protocol}://${hostname}:${port}${path}`
386
+ return `${protocol}://${hostname}:${port}${path}`;
398
387
  }
399
388
 
400
389
  /**
@@ -432,11 +421,11 @@ class Appium extends Webdriver {
432
421
  * @param {*} fn
433
422
  */
434
423
  async runOnIOS(caps, fn) {
435
- if (this.platform !== 'ios') return
436
- recorder.session.start('iOS-only actions')
437
- await this._runWithCaps(caps, fn)
438
- await recorder.add('restore from iOS session', () => recorder.session.restore())
439
- return recorder.promise()
424
+ if (this.platform !== 'ios') return;
425
+ recorder.session.start('iOS-only actions');
426
+ await this._runWithCaps(caps, fn);
427
+ await recorder.add('restore from iOS session', () => recorder.session.restore());
428
+ return recorder.promise();
440
429
  }
441
430
 
442
431
  /**
@@ -474,11 +463,11 @@ class Appium extends Webdriver {
474
463
  * @param {*} fn
475
464
  */
476
465
  async runOnAndroid(caps, fn) {
477
- if (this.platform !== 'android') return
478
- recorder.session.start('Android-only actions')
479
- await this._runWithCaps(caps, fn)
480
- await recorder.add('restore from Android session', () => recorder.session.restore())
481
- return recorder.promise()
466
+ if (this.platform !== 'android') return;
467
+ recorder.session.start('Android-only actions');
468
+ await this._runWithCaps(caps, fn);
469
+ await recorder.add('restore from Android session', () => recorder.session.restore());
470
+ return recorder.promise();
482
471
  }
483
472
 
484
473
  /**
@@ -495,11 +484,11 @@ class Appium extends Webdriver {
495
484
  */
496
485
  /* eslint-disable */
497
486
  async runInWeb(fn) {
498
- if (!this.isWeb) return
499
- recorder.session.start('Web-only actions')
487
+ if (!this.isWeb) return;
488
+ recorder.session.start('Web-only actions');
500
489
 
501
- recorder.add('restore from Web session', () => recorder.session.restore(), true)
502
- return recorder.promise()
490
+ recorder.add('restore from Web session', () => recorder.session.restore(), true);
491
+ return recorder.promise();
503
492
  }
504
493
  /* eslint-enable */
505
494
 
@@ -508,21 +497,21 @@ class Appium extends Webdriver {
508
497
  for (const key in caps) {
509
498
  // skip if capabilities do not match
510
499
  if (this.config.desiredCapabilities[key] !== caps[key]) {
511
- return
500
+ return;
512
501
  }
513
502
  }
514
503
  }
515
504
  if (typeof caps === 'function') {
516
505
  if (!fn) {
517
- fn = caps
506
+ fn = caps;
518
507
  } else {
519
508
  // skip if capabilities are checked inside a function
520
- const enabled = caps(this.config.desiredCapabilities)
521
- if (!enabled) return
509
+ const enabled = caps(this.config.desiredCapabilities);
510
+ if (!enabled) return;
522
511
  }
523
512
  }
524
513
 
525
- fn()
514
+ fn();
526
515
  }
527
516
 
528
517
  /**
@@ -538,9 +527,9 @@ class Appium extends Webdriver {
538
527
  * Appium: support only Android
539
528
  */
540
529
  async checkIfAppIsInstalled(bundleId) {
541
- onlyForApps.call(this, supportedPlatform.android)
530
+ onlyForApps.call(this, supportedPlatform.android);
542
531
 
543
- return this.browser.isAppInstalled(bundleId)
532
+ return this.browser.isAppInstalled(bundleId);
544
533
  }
545
534
 
546
535
  /**
@@ -556,9 +545,9 @@ class Appium extends Webdriver {
556
545
  * Appium: support only Android
557
546
  */
558
547
  async seeAppIsInstalled(bundleId) {
559
- onlyForApps.call(this, supportedPlatform.android)
560
- const res = await this.browser.isAppInstalled(bundleId)
561
- return truth(`app ${bundleId}`, 'to be installed').assert(res)
548
+ onlyForApps.call(this, supportedPlatform.android);
549
+ const res = await this.browser.isAppInstalled(bundleId);
550
+ return truth(`app ${bundleId}`, 'to be installed').assert(res);
562
551
  }
563
552
 
564
553
  /**
@@ -574,9 +563,9 @@ class Appium extends Webdriver {
574
563
  * Appium: support only Android
575
564
  */
576
565
  async seeAppIsNotInstalled(bundleId) {
577
- onlyForApps.call(this, supportedPlatform.android)
578
- const res = await this.browser.isAppInstalled(bundleId)
579
- return truth(`app ${bundleId}`, 'not to be installed').negate(res)
566
+ onlyForApps.call(this, supportedPlatform.android);
567
+ const res = await this.browser.isAppInstalled(bundleId);
568
+ return truth(`app ${bundleId}`, 'not to be installed').negate(res);
580
569
  }
581
570
 
582
571
  /**
@@ -591,8 +580,8 @@ class Appium extends Webdriver {
591
580
  * Appium: support only Android
592
581
  */
593
582
  async installApp(path) {
594
- onlyForApps.call(this, supportedPlatform.android)
595
- return this.browser.installApp(path)
583
+ onlyForApps.call(this, supportedPlatform.android);
584
+ return this.browser.installApp(path);
596
585
  }
597
586
 
598
587
  /**
@@ -608,13 +597,13 @@ class Appium extends Webdriver {
608
597
  * @param {string} [bundleId] ID of bundle
609
598
  */
610
599
  async removeApp(appId, bundleId) {
611
- onlyForApps.call(this, supportedPlatform.android)
600
+ onlyForApps.call(this, supportedPlatform.android);
612
601
 
613
602
  return this.axios({
614
603
  method: 'post',
615
604
  url: `${this._buildAppiumEndpoint()}/session/${this.browser.sessionId}/appium/device/remove_app`,
616
605
  data: { appId, bundleId },
617
- })
606
+ });
618
607
  }
619
608
 
620
609
  /**
@@ -626,11 +615,11 @@ class Appium extends Webdriver {
626
615
  *
627
616
  */
628
617
  async resetApp() {
629
- onlyForApps.call(this)
618
+ onlyForApps.call(this);
630
619
  return this.axios({
631
620
  method: 'post',
632
621
  url: `${this._buildAppiumEndpoint()}/session/${this.browser.sessionId}/appium/app/reset`,
633
- })
622
+ });
634
623
  }
635
624
 
636
625
  /**
@@ -645,9 +634,9 @@ class Appium extends Webdriver {
645
634
  * Appium: support only Android
646
635
  */
647
636
  async seeCurrentActivityIs(currentActivity) {
648
- onlyForApps.call(this, supportedPlatform.android)
649
- const res = await this.browser.getCurrentActivity()
650
- return truth('current activity', `to be ${currentActivity}`).assert(res === currentActivity)
637
+ onlyForApps.call(this, supportedPlatform.android);
638
+ const res = await this.browser.getCurrentActivity();
639
+ return truth('current activity', `to be ${currentActivity}`).assert(res === currentActivity);
651
640
  }
652
641
 
653
642
  /**
@@ -662,9 +651,9 @@ class Appium extends Webdriver {
662
651
  * Appium: support only Android
663
652
  */
664
653
  async seeDeviceIsLocked() {
665
- onlyForApps.call(this, supportedPlatform.android)
666
- const res = await this.browser.isLocked()
667
- return truth('device', 'to be locked').assert(res)
654
+ onlyForApps.call(this, supportedPlatform.android);
655
+ const res = await this.browser.isLocked();
656
+ return truth('device', 'to be locked').assert(res);
668
657
  }
669
658
 
670
659
  /**
@@ -679,9 +668,9 @@ class Appium extends Webdriver {
679
668
  * Appium: support only Android
680
669
  */
681
670
  async seeDeviceIsUnlocked() {
682
- onlyForApps.call(this, supportedPlatform.android)
683
- const res = await this.browser.isLocked()
684
- return truth('device', 'to be locked').negate(res)
671
+ onlyForApps.call(this, supportedPlatform.android);
672
+ const res = await this.browser.isLocked();
673
+ return truth('device', 'to be locked').negate(res);
685
674
  }
686
675
 
687
676
  /**
@@ -699,15 +688,15 @@ class Appium extends Webdriver {
699
688
  * Appium: support Android and iOS
700
689
  */
701
690
  async seeOrientationIs(orientation) {
702
- onlyForApps.call(this)
691
+ onlyForApps.call(this);
703
692
 
704
693
  const res = await this.axios({
705
694
  method: 'get',
706
695
  url: `${this._buildAppiumEndpoint()}/session/${this.browser.sessionId}/orientation`,
707
- })
696
+ });
708
697
 
709
- const currentOrientation = res.data.value
710
- return truth('orientation', `to be ${orientation}`).assert(currentOrientation === orientation)
698
+ const currentOrientation = res.data.value;
699
+ return truth('orientation', `to be ${orientation}`).assert(currentOrientation === orientation);
711
700
  }
712
701
 
713
702
  /**
@@ -723,13 +712,13 @@ class Appium extends Webdriver {
723
712
  * Appium: support Android and iOS
724
713
  */
725
714
  async setOrientation(orientation) {
726
- onlyForApps.call(this)
715
+ onlyForApps.call(this);
727
716
 
728
717
  return this.axios({
729
718
  method: 'post',
730
719
  url: `${this._buildAppiumEndpoint()}/session/${this.browser.sessionId}/orientation`,
731
720
  data: { orientation },
732
- })
721
+ });
733
722
  }
734
723
 
735
724
  /**
@@ -744,8 +733,8 @@ class Appium extends Webdriver {
744
733
  * Appium: support Android and iOS
745
734
  */
746
735
  async grabAllContexts() {
747
- onlyForApps.call(this)
748
- return this.browser.getContexts()
736
+ onlyForApps.call(this);
737
+ return this.browser.getContexts();
749
738
  }
750
739
 
751
740
  /**
@@ -760,8 +749,8 @@ class Appium extends Webdriver {
760
749
  * Appium: support Android and iOS
761
750
  */
762
751
  async grabContext() {
763
- onlyForApps.call(this)
764
- return this.browser.getContext()
752
+ onlyForApps.call(this);
753
+ return this.browser.getContext();
765
754
  }
766
755
 
767
756
  /**
@@ -776,8 +765,8 @@ class Appium extends Webdriver {
776
765
  * Appium: support only Android
777
766
  */
778
767
  async grabCurrentActivity() {
779
- onlyForApps.call(this, supportedPlatform.android)
780
- return this.browser.getCurrentActivity()
768
+ onlyForApps.call(this, supportedPlatform.android);
769
+ return this.browser.getCurrentActivity();
781
770
  }
782
771
 
783
772
  /**
@@ -794,14 +783,14 @@ class Appium extends Webdriver {
794
783
  * Appium: support only Android
795
784
  */
796
785
  async grabNetworkConnection() {
797
- onlyForApps.call(this, supportedPlatform.android)
798
- const res = await this.browser.getNetworkConnection()
786
+ onlyForApps.call(this, supportedPlatform.android);
787
+ const res = await this.browser.getNetworkConnection();
799
788
  return {
800
789
  value: res,
801
790
  inAirplaneMode: res.inAirplaneMode,
802
791
  hasWifi: res.hasWifi,
803
792
  hasData: res.hasData,
804
- }
793
+ };
805
794
  }
806
795
 
807
796
  /**
@@ -816,10 +805,10 @@ class Appium extends Webdriver {
816
805
  * Appium: support Android and iOS
817
806
  */
818
807
  async grabOrientation() {
819
- onlyForApps.call(this)
820
- const res = await this.browser.orientation()
821
- this.debugSection('Orientation', res)
822
- return res
808
+ onlyForApps.call(this);
809
+ const res = await this.browser.orientation();
810
+ this.debugSection('Orientation', res);
811
+ return res;
823
812
  }
824
813
 
825
814
  /**
@@ -834,10 +823,10 @@ class Appium extends Webdriver {
834
823
  * Appium: support Android and iOS
835
824
  */
836
825
  async grabSettings() {
837
- onlyForApps.call(this)
838
- const res = await this.browser.getSettings()
839
- this.debugSection('Settings', JSON.stringify(res))
840
- return res
826
+ onlyForApps.call(this);
827
+ const res = await this.browser.getSettings();
828
+ this.debugSection('Settings', JSON.stringify(res));
829
+ return res;
841
830
  }
842
831
 
843
832
  /**
@@ -846,7 +835,7 @@ class Appium extends Webdriver {
846
835
  * @param {*} context the context to switch to
847
836
  */
848
837
  async switchToContext(context) {
849
- return this.browser.switchContext(context)
838
+ return this.browser.switchContext(context);
850
839
  }
851
840
 
852
841
  /**
@@ -866,17 +855,17 @@ class Appium extends Webdriver {
866
855
  * @param {string} [context]
867
856
  */
868
857
  async switchToWeb(context) {
869
- this.isWeb = true
870
- this.defaultContext = 'body'
858
+ this.isWeb = true;
859
+ this.defaultContext = 'body';
871
860
 
872
- if (context) return this.switchToContext(context)
873
- const contexts = await this.grabAllContexts()
874
- this.debugSection('Contexts', contexts.toString())
861
+ if (context) return this.switchToContext(context);
862
+ const contexts = await this.grabAllContexts();
863
+ this.debugSection('Contexts', contexts.toString());
875
864
  for (const idx in contexts) {
876
- if (contexts[idx].match(/^WEBVIEW/)) return this.switchToContext(contexts[idx])
865
+ if (contexts[idx].match(/^WEBVIEW/)) return this.switchToContext(contexts[idx]);
877
866
  }
878
867
 
879
- throw new Error('No WEBVIEW could be guessed, please specify one in params')
868
+ throw new Error('No WEBVIEW could be guessed, please specify one in params');
880
869
  }
881
870
 
882
871
  /**
@@ -893,11 +882,11 @@ class Appium extends Webdriver {
893
882
  * @return {Promise<void>}
894
883
  */
895
884
  async switchToNative(context = null) {
896
- this.isWeb = false
897
- this.defaultContext = '//*'
885
+ this.isWeb = false;
886
+ this.defaultContext = '//*';
898
887
 
899
- if (context) return this.switchToContext(context)
900
- return this.switchToContext('NATIVE_APP')
888
+ if (context) return this.switchToContext(context);
889
+ return this.switchToContext('NATIVE_APP');
901
890
  }
902
891
 
903
892
  /**
@@ -914,8 +903,8 @@ class Appium extends Webdriver {
914
903
  * @return {Promise<void>}
915
904
  */
916
905
  async startActivity(appPackage, appActivity) {
917
- onlyForApps.call(this, supportedPlatform.android)
918
- return this.browser.startActivity(appPackage, appActivity)
906
+ onlyForApps.call(this, supportedPlatform.android);
907
+ return this.browser.startActivity(appPackage, appActivity);
919
908
  }
920
909
 
921
910
  /**
@@ -940,8 +929,8 @@ class Appium extends Webdriver {
940
929
  * @return {Promise<number>}
941
930
  */
942
931
  async setNetworkConnection(value) {
943
- onlyForApps.call(this, supportedPlatform.android)
944
- return this.browser.setNetworkConnection(value)
932
+ onlyForApps.call(this, supportedPlatform.android);
933
+ return this.browser.setNetworkConnection(value);
945
934
  }
946
935
 
947
936
  /**
@@ -956,8 +945,8 @@ class Appium extends Webdriver {
956
945
  * Appium: support Android and iOS
957
946
  */
958
947
  async setSettings(settings) {
959
- onlyForApps.call(this)
960
- return this.browser.settings(settings)
948
+ onlyForApps.call(this);
949
+ return this.browser.settings(settings);
961
950
  }
962
951
 
963
952
  /**
@@ -978,9 +967,9 @@ class Appium extends Webdriver {
978
967
  * @param {string} [key] Optional key
979
968
  */
980
969
  async hideDeviceKeyboard(strategy, key) {
981
- onlyForApps.call(this)
982
- strategy = strategy || 'tapOutside'
983
- return this.browser.hideKeyboard(strategy, key)
970
+ onlyForApps.call(this);
971
+ strategy = strategy || 'tapOutside';
972
+ return this.browser.hideKeyboard(strategy, key);
984
973
  }
985
974
 
986
975
  /**
@@ -997,8 +986,8 @@ class Appium extends Webdriver {
997
986
  * Appium: support only Android
998
987
  */
999
988
  async sendDeviceKeyEvent(keyValue) {
1000
- onlyForApps.call(this, supportedPlatform.android)
1001
- return this.browser.pressKeyCode(keyValue)
989
+ onlyForApps.call(this, supportedPlatform.android);
990
+ return this.browser.pressKeyCode(keyValue);
1002
991
  }
1003
992
 
1004
993
  /**
@@ -1013,8 +1002,8 @@ class Appium extends Webdriver {
1013
1002
  * Appium: support only Android
1014
1003
  */
1015
1004
  async openNotifications() {
1016
- onlyForApps.call(this, supportedPlatform.android)
1017
- return this.browser.openNotifications()
1005
+ onlyForApps.call(this, supportedPlatform.android);
1006
+ return this.browser.openNotifications();
1018
1007
  }
1019
1008
 
1020
1009
  /**
@@ -1033,13 +1022,13 @@ class Appium extends Webdriver {
1033
1022
  * Appium: support Android and iOS
1034
1023
  */
1035
1024
  async makeTouchAction(locator, action) {
1036
- onlyForApps.call(this)
1037
- const element = await this.browser.$(parseLocator.call(this, locator))
1025
+ onlyForApps.call(this);
1026
+ const element = await this.browser.$(parseLocator.call(this, locator));
1038
1027
 
1039
1028
  return this.browser.touchAction({
1040
1029
  action,
1041
1030
  element,
1042
- })
1031
+ });
1043
1032
  }
1044
1033
 
1045
1034
  /**
@@ -1056,7 +1045,7 @@ class Appium extends Webdriver {
1056
1045
  * @param {*} locator
1057
1046
  */
1058
1047
  async tap(locator) {
1059
- return this.makeTouchAction(locator, 'tap')
1048
+ return this.makeTouchAction(locator, 'tap');
1060
1049
  }
1061
1050
 
1062
1051
  /**
@@ -1079,13 +1068,10 @@ class Appium extends Webdriver {
1079
1068
  */
1080
1069
  /* eslint-disable */
1081
1070
  async swipe(locator, xoffset, yoffset, speed = 1000) {
1082
- onlyForApps.call(this)
1083
- const res = await this.browser.$(parseLocator.call(this, locator))
1071
+ onlyForApps.call(this);
1072
+ const res = await this.browser.$(parseLocator.call(this, locator));
1084
1073
  // if (!res.length) throw new ElementNotFound(locator, 'was not found in UI');
1085
- return this.performSwipe(await res.getLocation(), {
1086
- x: (await res.getLocation()).x + xoffset,
1087
- y: (await res.getLocation()).y + yoffset,
1088
- })
1074
+ return this.performSwipe(await res.getLocation(), { x: (await res.getLocation()).x + xoffset, y: (await res.getLocation()).y + yoffset });
1089
1075
  }
1090
1076
  /* eslint-enable */
1091
1077
 
@@ -1102,44 +1088,42 @@ class Appium extends Webdriver {
1102
1088
  * Appium: support Android and iOS
1103
1089
  */
1104
1090
  async performSwipe(from, to) {
1105
- await this.browser.performActions([
1106
- {
1107
- id: uuidv4(),
1108
- type: 'pointer',
1109
- parameters: {
1110
- pointerType: 'touch',
1111
- },
1112
- actions: [
1113
- {
1114
- duration: 0,
1115
- x: from.x,
1116
- y: from.y,
1117
- type: 'pointerMove',
1118
- origin: 'viewport',
1119
- },
1120
- {
1121
- button: 1,
1122
- type: 'pointerDown',
1123
- },
1124
- {
1125
- duration: 200,
1126
- type: 'pause',
1127
- },
1128
- {
1129
- duration: 600,
1130
- x: to.x,
1131
- y: to.y,
1132
- type: 'pointerMove',
1133
- origin: 'viewport',
1134
- },
1135
- {
1136
- button: 1,
1137
- type: 'pointerUp',
1138
- },
1139
- ],
1091
+ await this.browser.performActions([{
1092
+ id: uuidv4(),
1093
+ type: 'pointer',
1094
+ parameters: {
1095
+ pointerType: 'touch',
1140
1096
  },
1141
- ])
1142
- await this.browser.pause(1000)
1097
+ actions: [
1098
+ {
1099
+ duration: 0,
1100
+ x: from.x,
1101
+ y: from.y,
1102
+ type: 'pointerMove',
1103
+ origin: 'viewport',
1104
+ },
1105
+ {
1106
+ button: 1,
1107
+ type: 'pointerDown',
1108
+ },
1109
+ {
1110
+ duration: 200,
1111
+ type: 'pause',
1112
+ },
1113
+ {
1114
+ duration: 600,
1115
+ x: to.x,
1116
+ y: to.y,
1117
+ type: 'pointerMove',
1118
+ origin: 'viewport',
1119
+ },
1120
+ {
1121
+ button: 1,
1122
+ type: 'pointerUp',
1123
+ },
1124
+ ],
1125
+ }]);
1126
+ await this.browser.pause(1000);
1143
1127
  }
1144
1128
 
1145
1129
  /**
@@ -1160,14 +1144,14 @@ class Appium extends Webdriver {
1160
1144
  * Appium: support Android and iOS
1161
1145
  */
1162
1146
  async swipeDown(locator, yoffset = 1000, speed) {
1163
- onlyForApps.call(this)
1147
+ onlyForApps.call(this);
1164
1148
 
1165
1149
  if (!speed) {
1166
- speed = yoffset
1167
- yoffset = 100
1150
+ speed = yoffset;
1151
+ yoffset = 100;
1168
1152
  }
1169
1153
 
1170
- return this.swipe(parseLocator.call(this, locator), 0, yoffset, speed)
1154
+ return this.swipe(parseLocator.call(this, locator), 0, yoffset, speed);
1171
1155
  }
1172
1156
 
1173
1157
  /**
@@ -1189,13 +1173,13 @@ class Appium extends Webdriver {
1189
1173
  * Appium: support Android and iOS
1190
1174
  */
1191
1175
  async swipeLeft(locator, xoffset = 1000, speed) {
1192
- onlyForApps.call(this)
1176
+ onlyForApps.call(this);
1193
1177
  if (!speed) {
1194
- speed = xoffset
1195
- xoffset = 100
1178
+ speed = xoffset;
1179
+ xoffset = 100;
1196
1180
  }
1197
1181
 
1198
- return this.swipe(parseLocator.call(this, locator), -xoffset, 0, speed)
1182
+ return this.swipe(parseLocator.call(this, locator), -xoffset, 0, speed);
1199
1183
  }
1200
1184
 
1201
1185
  /**
@@ -1216,13 +1200,13 @@ class Appium extends Webdriver {
1216
1200
  * Appium: support Android and iOS
1217
1201
  */
1218
1202
  async swipeRight(locator, xoffset = 1000, speed) {
1219
- onlyForApps.call(this)
1203
+ onlyForApps.call(this);
1220
1204
  if (!speed) {
1221
- speed = xoffset
1222
- xoffset = 100
1205
+ speed = xoffset;
1206
+ xoffset = 100;
1223
1207
  }
1224
1208
 
1225
- return this.swipe(parseLocator.call(this, locator), xoffset, 0, speed)
1209
+ return this.swipe(parseLocator.call(this, locator), xoffset, 0, speed);
1226
1210
  }
1227
1211
 
1228
1212
  /**
@@ -1243,14 +1227,14 @@ class Appium extends Webdriver {
1243
1227
  * Appium: support Android and iOS
1244
1228
  */
1245
1229
  async swipeUp(locator, yoffset = 1000, speed) {
1246
- onlyForApps.call(this)
1230
+ onlyForApps.call(this);
1247
1231
 
1248
1232
  if (!speed) {
1249
- speed = yoffset
1250
- yoffset = 100
1233
+ speed = yoffset;
1234
+ yoffset = 100;
1251
1235
  }
1252
1236
 
1253
- return this.swipe(parseLocator.call(this, locator), 0, -yoffset, speed)
1237
+ return this.swipe(parseLocator.call(this, locator), 0, -yoffset, speed);
1254
1238
  }
1255
1239
 
1256
1240
  /**
@@ -1277,66 +1261,55 @@ class Appium extends Webdriver {
1277
1261
  * Appium: support Android and iOS
1278
1262
  */
1279
1263
  async swipeTo(searchableLocator, scrollLocator, direction, timeout, offset, speed) {
1280
- onlyForApps.call(this)
1281
- direction = direction || 'down'
1264
+ onlyForApps.call(this);
1265
+ direction = direction || 'down';
1282
1266
  switch (direction) {
1283
1267
  case 'down':
1284
- direction = 'swipeDown'
1285
- break
1268
+ direction = 'swipeDown';
1269
+ break;
1286
1270
  case 'up':
1287
- direction = 'swipeUp'
1288
- break
1271
+ direction = 'swipeUp';
1272
+ break;
1289
1273
  case 'left':
1290
- direction = 'swipeLeft'
1291
- break
1274
+ direction = 'swipeLeft';
1275
+ break;
1292
1276
  case 'right':
1293
- direction = 'swipeRight'
1294
- break
1277
+ direction = 'swipeRight';
1278
+ break;
1295
1279
  }
1296
- timeout = timeout || this.options.waitForTimeoutInSeconds
1297
-
1298
- const errorMsg = `element ("${searchableLocator}") still not visible after ${timeout}seconds`
1299
- const browser = this.browser
1300
- let err = false
1301
- let currentSource
1302
- return browser
1303
- .waitUntil(
1304
- () => {
1305
- if (err) {
1306
- return new Error(`Scroll to the end and element ${searchableLocator} was not found`)
1280
+ timeout = timeout || this.options.waitForTimeoutInSeconds;
1281
+
1282
+ const errorMsg = `element ("${searchableLocator}") still not visible after ${timeout}seconds`;
1283
+ const browser = this.browser;
1284
+ let err = false;
1285
+ let currentSource;
1286
+ return browser.waitUntil(() => {
1287
+ if (err) {
1288
+ return new Error(`Scroll to the end and element ${searchableLocator} was not found`);
1289
+ }
1290
+ return browser.$$(parseLocator.call(this, searchableLocator))
1291
+ .then(els => els.length && els[0].isDisplayed())
1292
+ .then((res) => {
1293
+ if (res) {
1294
+ return true;
1307
1295
  }
1308
- return browser
1309
- .$$(parseLocator.call(this, searchableLocator))
1310
- .then((els) => els.length && els[0].isDisplayed())
1311
- .then((res) => {
1312
- if (res) {
1313
- return true
1314
- }
1315
- return this[direction](scrollLocator, offset, speed)
1316
- .getSource()
1317
- .then((source) => {
1318
- if (source === currentSource) {
1319
- err = true
1320
- } else {
1321
- currentSource = source
1322
- return false
1323
- }
1324
- })
1325
- })
1326
- },
1327
- timeout * 1000,
1328
- errorMsg,
1329
- )
1296
+ return this[direction](scrollLocator, offset, speed).getSource().then((source) => {
1297
+ if (source === currentSource) {
1298
+ err = true;
1299
+ } else {
1300
+ currentSource = source;
1301
+ return false;
1302
+ }
1303
+ });
1304
+ });
1305
+ }, timeout * 1000, errorMsg)
1330
1306
  .catch((e) => {
1331
1307
  if (e.message.indexOf('timeout') && e.type !== 'NoSuchElement') {
1332
- throw new AssertionFailedError(
1333
- { customMessage: `Scroll to the end and element ${searchableLocator} was not found` },
1334
- '',
1335
- )
1308
+ throw new AssertionFailedError({ customMessage: `Scroll to the end and element ${searchableLocator} was not found` }, '');
1336
1309
  } else {
1337
- throw e
1310
+ throw e;
1338
1311
  }
1339
- })
1312
+ });
1340
1313
  }
1341
1314
 
1342
1315
  /**
@@ -1368,8 +1341,8 @@ class Appium extends Webdriver {
1368
1341
  * @param {Array} actions Array of touch actions
1369
1342
  */
1370
1343
  async touchPerform(actions) {
1371
- onlyForApps.call(this)
1372
- return this.browser.touchPerform(actions)
1344
+ onlyForApps.call(this);
1345
+ return this.browser.touchPerform(actions);
1373
1346
  }
1374
1347
 
1375
1348
  /**
@@ -1388,15 +1361,13 @@ class Appium extends Webdriver {
1388
1361
  * Appium: support Android and iOS
1389
1362
  */
1390
1363
  async pullFile(path, dest) {
1391
- onlyForApps.call(this)
1392
- return this.browser.pullFile(path).then((res) =>
1393
- fs.writeFile(dest, Buffer.from(res, 'base64'), (err) => {
1394
- if (err) {
1395
- return false
1396
- }
1397
- return true
1398
- }),
1399
- )
1364
+ onlyForApps.call(this);
1365
+ return this.browser.pullFile(path).then(res => fs.writeFile(dest, Buffer.from(res, 'base64'), (err) => {
1366
+ if (err) {
1367
+ return false;
1368
+ }
1369
+ return true;
1370
+ }));
1400
1371
  }
1401
1372
 
1402
1373
  /**
@@ -1411,8 +1382,8 @@ class Appium extends Webdriver {
1411
1382
  * Appium: support only iOS
1412
1383
  */
1413
1384
  async shakeDevice() {
1414
- onlyForApps.call(this, 'iOS')
1415
- return this.browser.shake()
1385
+ onlyForApps.call(this, 'iOS');
1386
+ return this.browser.shake();
1416
1387
  }
1417
1388
 
1418
1389
  /**
@@ -1429,8 +1400,8 @@ class Appium extends Webdriver {
1429
1400
  * Appium: support only iOS
1430
1401
  */
1431
1402
  async rotate(x, y, duration, radius, rotation, touchCount) {
1432
- onlyForApps.call(this, 'iOS')
1433
- return this.browser.rotate(x, y, duration, radius, rotation, touchCount)
1403
+ onlyForApps.call(this, 'iOS');
1404
+ return this.browser.rotate(x, y, duration, radius, rotation, touchCount);
1434
1405
  }
1435
1406
 
1436
1407
  /**
@@ -1443,8 +1414,8 @@ class Appium extends Webdriver {
1443
1414
  * Appium: support only iOS
1444
1415
  */
1445
1416
  async setImmediateValue(id, value) {
1446
- onlyForApps.call(this, 'iOS')
1447
- return this.browser.setImmediateValue(id, value)
1417
+ onlyForApps.call(this, 'iOS');
1418
+ return this.browser.setImmediateValue(id, value);
1448
1419
  }
1449
1420
 
1450
1421
  /**
@@ -1462,9 +1433,9 @@ class Appium extends Webdriver {
1462
1433
  * TODO: not tested
1463
1434
  */
1464
1435
  async simulateTouchId(match) {
1465
- onlyForApps.call(this, 'iOS')
1466
- match = match || true
1467
- return this.browser.touchId(match)
1436
+ onlyForApps.call(this, 'iOS');
1437
+ match = match || true;
1438
+ return this.browser.touchId(match);
1468
1439
  }
1469
1440
 
1470
1441
  /**
@@ -1479,8 +1450,8 @@ class Appium extends Webdriver {
1479
1450
  * Appium: support both Android and iOS
1480
1451
  */
1481
1452
  async closeApp() {
1482
- onlyForApps.call(this)
1483
- return this.browser.closeApp()
1453
+ onlyForApps.call(this);
1454
+ return this.browser.closeApp();
1484
1455
  }
1485
1456
 
1486
1457
  /**
@@ -1488,8 +1459,8 @@ class Appium extends Webdriver {
1488
1459
  *
1489
1460
  */
1490
1461
  async appendField(field, value) {
1491
- if (this.isWeb) return super.appendField(field, value)
1492
- return super.appendField(parseLocator.call(this, field), value)
1462
+ if (this.isWeb) return super.appendField(field, value);
1463
+ return super.appendField(parseLocator.call(this, field), value);
1493
1464
  }
1494
1465
 
1495
1466
  /**
@@ -1497,8 +1468,8 @@ class Appium extends Webdriver {
1497
1468
  *
1498
1469
  */
1499
1470
  async checkOption(field) {
1500
- if (this.isWeb) return super.checkOption(field)
1501
- return super.checkOption(parseLocator.call(this, field))
1471
+ if (this.isWeb) return super.checkOption(field);
1472
+ return super.checkOption(parseLocator.call(this, field));
1502
1473
  }
1503
1474
 
1504
1475
  /**
@@ -1506,8 +1477,8 @@ class Appium extends Webdriver {
1506
1477
  *
1507
1478
  */
1508
1479
  async click(locator, context) {
1509
- if (this.isWeb) return super.click(locator, context)
1510
- return super.click(parseLocator.call(this, locator), parseLocator.call(this, context))
1480
+ if (this.isWeb) return super.click(locator, context);
1481
+ return super.click(parseLocator.call(this, locator), parseLocator.call(this, context));
1511
1482
  }
1512
1483
 
1513
1484
  /**
@@ -1515,16 +1486,16 @@ class Appium extends Webdriver {
1515
1486
  *
1516
1487
  */
1517
1488
  async dontSeeCheckboxIsChecked(field) {
1518
- if (this.isWeb) return super.dontSeeCheckboxIsChecked(field)
1519
- return super.dontSeeCheckboxIsChecked(parseLocator.call(this, field))
1489
+ if (this.isWeb) return super.dontSeeCheckboxIsChecked(field);
1490
+ return super.dontSeeCheckboxIsChecked(parseLocator.call(this, field));
1520
1491
  }
1521
1492
 
1522
1493
  /**
1523
1494
  * {{> dontSeeElement }}
1524
1495
  */
1525
1496
  async dontSeeElement(locator) {
1526
- if (this.isWeb) return super.dontSeeElement(locator)
1527
- return super.dontSeeElement(parseLocator.call(this, locator))
1497
+ if (this.isWeb) return super.dontSeeElement(locator);
1498
+ return super.dontSeeElement(parseLocator.call(this, locator));
1528
1499
  }
1529
1500
 
1530
1501
  /**
@@ -1532,17 +1503,17 @@ class Appium extends Webdriver {
1532
1503
  *
1533
1504
  */
1534
1505
  async dontSeeInField(field, value) {
1535
- const _value = typeof value === 'boolean' ? value : value.toString()
1536
- if (this.isWeb) return super.dontSeeInField(field, _value)
1537
- return super.dontSeeInField(parseLocator.call(this, field), _value)
1506
+ const _value = (typeof value === 'boolean') ? value : value.toString();
1507
+ if (this.isWeb) return super.dontSeeInField(field, _value);
1508
+ return super.dontSeeInField(parseLocator.call(this, field), _value);
1538
1509
  }
1539
1510
 
1540
1511
  /**
1541
1512
  * {{> dontSee }}
1542
1513
  */
1543
1514
  async dontSee(text, context = null) {
1544
- if (this.isWeb) return super.dontSee(text, context)
1545
- return super.dontSee(text, parseLocator.call(this, context))
1515
+ if (this.isWeb) return super.dontSee(text, context);
1516
+ return super.dontSee(text, parseLocator.call(this, context));
1546
1517
  }
1547
1518
 
1548
1519
  /**
@@ -1550,9 +1521,9 @@ class Appium extends Webdriver {
1550
1521
  *
1551
1522
  */
1552
1523
  async fillField(field, value) {
1553
- value = value.toString()
1554
- if (this.isWeb) return super.fillField(field, value)
1555
- return super.fillField(parseLocator.call(this, field), value)
1524
+ value = value.toString();
1525
+ if (this.isWeb) return super.fillField(field, value);
1526
+ return super.fillField(parseLocator.call(this, field), value);
1556
1527
  }
1557
1528
 
1558
1529
  /**
@@ -1560,8 +1531,8 @@ class Appium extends Webdriver {
1560
1531
  *
1561
1532
  */
1562
1533
  async grabTextFromAll(locator) {
1563
- if (this.isWeb) return super.grabTextFromAll(locator)
1564
- return super.grabTextFromAll(parseLocator.call(this, locator))
1534
+ if (this.isWeb) return super.grabTextFromAll(locator);
1535
+ return super.grabTextFromAll(parseLocator.call(this, locator));
1565
1536
  }
1566
1537
 
1567
1538
  /**
@@ -1569,16 +1540,16 @@ class Appium extends Webdriver {
1569
1540
  *
1570
1541
  */
1571
1542
  async grabTextFrom(locator) {
1572
- if (this.isWeb) return super.grabTextFrom(locator)
1573
- return super.grabTextFrom(parseLocator.call(this, locator))
1543
+ if (this.isWeb) return super.grabTextFrom(locator);
1544
+ return super.grabTextFrom(parseLocator.call(this, locator));
1574
1545
  }
1575
1546
 
1576
1547
  /**
1577
1548
  * {{> grabNumberOfVisibleElements }}
1578
1549
  */
1579
1550
  async grabNumberOfVisibleElements(locator) {
1580
- if (this.isWeb) return super.grabNumberOfVisibleElements(locator)
1581
- return super.grabNumberOfVisibleElements(parseLocator.call(this, locator))
1551
+ if (this.isWeb) return super.grabNumberOfVisibleElements(locator);
1552
+ return super.grabNumberOfVisibleElements(parseLocator.call(this, locator));
1582
1553
  }
1583
1554
 
1584
1555
  /**
@@ -1587,8 +1558,8 @@ class Appium extends Webdriver {
1587
1558
  * {{> grabAttributeFrom }}
1588
1559
  */
1589
1560
  async grabAttributeFrom(locator, attr) {
1590
- if (this.isWeb) return super.grabAttributeFrom(locator, attr)
1591
- return super.grabAttributeFrom(parseLocator.call(this, locator), attr)
1561
+ if (this.isWeb) return super.grabAttributeFrom(locator, attr);
1562
+ return super.grabAttributeFrom(parseLocator.call(this, locator), attr);
1592
1563
  }
1593
1564
 
1594
1565
  /**
@@ -1596,8 +1567,8 @@ class Appium extends Webdriver {
1596
1567
  * {{> grabAttributeFromAll }}
1597
1568
  */
1598
1569
  async grabAttributeFromAll(locator, attr) {
1599
- if (this.isWeb) return super.grabAttributeFromAll(locator, attr)
1600
- return super.grabAttributeFromAll(parseLocator.call(this, locator), attr)
1570
+ if (this.isWeb) return super.grabAttributeFromAll(locator, attr);
1571
+ return super.grabAttributeFromAll(parseLocator.call(this, locator), attr);
1601
1572
  }
1602
1573
 
1603
1574
  /**
@@ -1605,8 +1576,8 @@ class Appium extends Webdriver {
1605
1576
  *
1606
1577
  */
1607
1578
  async grabValueFromAll(locator) {
1608
- if (this.isWeb) return super.grabValueFromAll(locator)
1609
- return super.grabValueFromAll(parseLocator.call(this, locator))
1579
+ if (this.isWeb) return super.grabValueFromAll(locator);
1580
+ return super.grabValueFromAll(parseLocator.call(this, locator));
1610
1581
  }
1611
1582
 
1612
1583
  /**
@@ -1614,8 +1585,8 @@ class Appium extends Webdriver {
1614
1585
  *
1615
1586
  */
1616
1587
  async grabValueFrom(locator) {
1617
- if (this.isWeb) return super.grabValueFrom(locator)
1618
- return super.grabValueFrom(parseLocator.call(this, locator))
1588
+ if (this.isWeb) return super.grabValueFrom(locator);
1589
+ return super.grabValueFrom(parseLocator.call(this, locator));
1619
1590
  }
1620
1591
 
1621
1592
  /**
@@ -1630,7 +1601,7 @@ class Appium extends Webdriver {
1630
1601
  * @return {Promise<void>}
1631
1602
  */
1632
1603
  async saveScreenshot(fileName) {
1633
- return super.saveScreenshot(fileName, false)
1604
+ return super.saveScreenshot(fileName, false);
1634
1605
  }
1635
1606
 
1636
1607
  /**
@@ -1639,7 +1610,7 @@ class Appium extends Webdriver {
1639
1610
  * Supported only for web testing
1640
1611
  */
1641
1612
  async scrollIntoView(locator, scrollIntoViewOptions) {
1642
- if (this.isWeb) return super.scrollIntoView(locator, scrollIntoViewOptions)
1613
+ if (this.isWeb) return super.scrollIntoView(locator, scrollIntoViewOptions);
1643
1614
  }
1644
1615
 
1645
1616
  /**
@@ -1647,8 +1618,8 @@ class Appium extends Webdriver {
1647
1618
  *
1648
1619
  */
1649
1620
  async seeCheckboxIsChecked(field) {
1650
- if (this.isWeb) return super.seeCheckboxIsChecked(field)
1651
- return super.seeCheckboxIsChecked(parseLocator.call(this, field))
1621
+ if (this.isWeb) return super.seeCheckboxIsChecked(field);
1622
+ return super.seeCheckboxIsChecked(parseLocator.call(this, field));
1652
1623
  }
1653
1624
 
1654
1625
  /**
@@ -1656,8 +1627,8 @@ class Appium extends Webdriver {
1656
1627
  *
1657
1628
  */
1658
1629
  async seeElement(locator) {
1659
- if (this.isWeb) return super.seeElement(locator)
1660
- return super.seeElement(parseLocator.call(this, locator))
1630
+ if (this.isWeb) return super.seeElement(locator);
1631
+ return super.seeElement(parseLocator.call(this, locator));
1661
1632
  }
1662
1633
 
1663
1634
  /**
@@ -1665,9 +1636,9 @@ class Appium extends Webdriver {
1665
1636
  *
1666
1637
  */
1667
1638
  async seeInField(field, value) {
1668
- const _value = typeof value === 'boolean' ? value : value.toString()
1669
- if (this.isWeb) return super.seeInField(field, _value)
1670
- return super.seeInField(parseLocator.call(this, field), _value)
1639
+ const _value = (typeof value === 'boolean') ? value : value.toString();
1640
+ if (this.isWeb) return super.seeInField(field, _value);
1641
+ return super.seeInField(parseLocator.call(this, field), _value);
1671
1642
  }
1672
1643
 
1673
1644
  /**
@@ -1675,8 +1646,8 @@ class Appium extends Webdriver {
1675
1646
  *
1676
1647
  */
1677
1648
  async see(text, context) {
1678
- if (this.isWeb) return super.see(text, context)
1679
- return super.see(text, parseLocator.call(this, context))
1649
+ if (this.isWeb) return super.see(text, context);
1650
+ return super.see(text, parseLocator.call(this, context));
1680
1651
  }
1681
1652
 
1682
1653
  /**
@@ -1685,8 +1656,8 @@ class Appium extends Webdriver {
1685
1656
  * Supported only for web testing
1686
1657
  */
1687
1658
  async selectOption(select, option) {
1688
- if (this.isWeb) return super.selectOption(select, option)
1689
- throw new Error("Should be used only in Web context. In native context use 'click' method instead")
1659
+ if (this.isWeb) return super.selectOption(select, option);
1660
+ throw new Error('Should be used only in Web context. In native context use \'click\' method instead');
1690
1661
  }
1691
1662
 
1692
1663
  /**
@@ -1694,8 +1665,8 @@ class Appium extends Webdriver {
1694
1665
  *
1695
1666
  */
1696
1667
  async waitForElement(locator, sec = null) {
1697
- if (this.isWeb) return super.waitForElement(locator, sec)
1698
- return super.waitForElement(parseLocator.call(this, locator), sec)
1668
+ if (this.isWeb) return super.waitForElement(locator, sec);
1669
+ return super.waitForElement(parseLocator.call(this, locator), sec);
1699
1670
  }
1700
1671
 
1701
1672
  /**
@@ -1703,8 +1674,8 @@ class Appium extends Webdriver {
1703
1674
  *
1704
1675
  */
1705
1676
  async waitForVisible(locator, sec = null) {
1706
- if (this.isWeb) return super.waitForVisible(locator, sec)
1707
- return super.waitForVisible(parseLocator.call(this, locator), sec)
1677
+ if (this.isWeb) return super.waitForVisible(locator, sec);
1678
+ return super.waitForVisible(parseLocator.call(this, locator), sec);
1708
1679
  }
1709
1680
 
1710
1681
  /**
@@ -1712,8 +1683,8 @@ class Appium extends Webdriver {
1712
1683
  *
1713
1684
  */
1714
1685
  async waitForInvisible(locator, sec = null) {
1715
- if (this.isWeb) return super.waitForInvisible(locator, sec)
1716
- return super.waitForInvisible(parseLocator.call(this, locator), sec)
1686
+ if (this.isWeb) return super.waitForInvisible(locator, sec);
1687
+ return super.waitForInvisible(parseLocator.call(this, locator), sec);
1717
1688
  }
1718
1689
 
1719
1690
  /**
@@ -1721,76 +1692,74 @@ class Appium extends Webdriver {
1721
1692
  *
1722
1693
  */
1723
1694
  async waitForText(text, sec = null, context = null) {
1724
- if (this.isWeb) return super.waitForText(text, sec, context)
1725
- return super.waitForText(text, sec, parseLocator.call(this, context))
1695
+ if (this.isWeb) return super.waitForText(text, sec, context);
1696
+ return super.waitForText(text, sec, parseLocator.call(this, context));
1726
1697
  }
1727
1698
  }
1728
1699
 
1729
1700
  function parseLocator(locator) {
1730
- if (!locator) return null
1701
+ if (!locator) return null;
1731
1702
 
1732
1703
  if (typeof locator === 'object') {
1733
1704
  if (locator.web && this.isWeb) {
1734
- return parseLocator.call(this, locator.web)
1705
+ return parseLocator.call(this, locator.web);
1735
1706
  }
1736
1707
 
1737
1708
  if (locator.android && this.platform === 'android') {
1738
1709
  if (typeof locator.android === 'string') {
1739
- return parseLocator.call(this, locator.android)
1710
+ return parseLocator.call(this, locator.android);
1740
1711
  }
1741
1712
  // The locator is an Android DataMatcher or ViewMatcher locator so return as is
1742
- return locator.android
1713
+ return locator.android;
1743
1714
  }
1744
1715
 
1745
1716
  if (locator.ios && this.platform === 'ios') {
1746
- return parseLocator.call(this, locator.ios)
1717
+ return parseLocator.call(this, locator.ios);
1747
1718
  }
1748
1719
  }
1749
1720
 
1750
1721
  if (typeof locator === 'string') {
1751
- if (locator[0] === '~') return locator
1752
- if (locator.substr(0, 2) === '//') return locator
1722
+ if (locator[0] === '~') return locator;
1723
+ if (locator.substr(0, 2) === '//') return locator;
1753
1724
  if (locator[0] === '#' && !this.isWeb) {
1754
1725
  // hook before webdriverio supports native # locators
1755
- return parseLocator.call(this, { id: locator.slice(1) })
1726
+ return parseLocator.call(this, { id: locator.slice(1) });
1756
1727
  }
1757
1728
 
1758
1729
  if (this.platform === 'android' && !this.isWeb) {
1759
- const isNativeLocator = /^\-?android=?/.exec(locator)
1760
- return isNativeLocator ? locator : `android=new UiSelector().text("${locator}")`
1730
+ const isNativeLocator = /^\-?android=?/.exec(locator);
1731
+ return isNativeLocator
1732
+ ? locator
1733
+ : `android=new UiSelector().text("${locator}")`;
1761
1734
  }
1762
1735
  }
1763
1736
 
1764
- locator = new Locator(locator, 'xpath')
1765
- if (locator.type === 'css' && !this.isWeb)
1766
- throw new Error(
1767
- 'Unable to use css locators in apps. Locator strategies for this request: xpath, id, class name or accessibility id',
1768
- )
1769
- if (locator.type === 'name' && !this.isWeb)
1770
- throw new Error("Can't locate element by name in Native context. Use either ID, class name or accessibility id")
1771
- if (locator.type === 'id' && !this.isWeb && this.platform === 'android') return `//*[@resource-id='${locator.value}']`
1772
- return locator.simplify()
1737
+ locator = new Locator(locator, 'xpath');
1738
+ if (locator.type === 'css' && !this.isWeb) throw new Error('Unable to use css locators in apps. Locator strategies for this request: xpath, id, class name or accessibility id');
1739
+ if (locator.type === 'name' && !this.isWeb) throw new Error("Can't locate element by name in Native context. Use either ID, class name or accessibility id");
1740
+ if (locator.type === 'id' && !this.isWeb && this.platform === 'android') return `//*[@resource-id='${locator.value}']`;
1741
+ return locator.simplify();
1773
1742
  }
1774
1743
 
1775
1744
  // in the end of a file
1776
1745
  function onlyForApps(expectedPlatform) {
1777
- const stack = new Error().stack || ''
1778
- const re = /Appium.(\w+)/g
1779
- const caller = stack.split('\n')[2].trim()
1780
- const m = re.exec(caller)
1746
+ const stack = new Error().stack || '';
1747
+ const re = /Appium.(\w+)/g;
1748
+ const caller = stack.split('\n')[2].trim();
1749
+ const m = re.exec(caller);
1781
1750
 
1782
1751
  if (!m) {
1783
- throw new Error(`Invalid caller ${caller}`)
1752
+ throw new Error(`Invalid caller ${caller}`);
1784
1753
  }
1785
1754
 
1786
- const callerName = m[1] || m[2]
1755
+ const callerName = m[1] || m[2];
1787
1756
  if (!expectedPlatform) {
1788
1757
  if (!this.platform) {
1789
- throw new Error(`${callerName} method can be used only with apps`)
1758
+ throw new Error(`${callerName} method can be used only with apps`);
1790
1759
  }
1791
1760
  } else if (this.platform !== expectedPlatform.toLowerCase()) {
1792
- throw new Error(`${callerName} method can be used only with ${expectedPlatform} apps`)
1761
+ throw new Error(`${callerName} method can be used only with ${expectedPlatform} apps`);
1793
1762
  }
1794
1763
  }
1795
1764
 
1796
- module.exports = Appium
1765
+ export default Appium;