codeceptjs 3.3.8-beta.1 → 3.4.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 (63) hide show
  1. package/CHANGELOG.md +47 -0
  2. package/README.md +31 -32
  3. package/docs/advanced.md +48 -24
  4. package/docs/basics.md +115 -40
  5. package/docs/best.md +2 -2
  6. package/docs/build/ApiDataFactory.js +6 -6
  7. package/docs/build/Appium.js +2 -19
  8. package/docs/build/FileSystem.js +2 -2
  9. package/docs/build/GraphQLDataFactory.js +2 -2
  10. package/docs/build/Playwright.js +3 -2
  11. package/docs/build/TestCafe.js +4 -4
  12. package/docs/build/WebDriver.js +29 -164
  13. package/docs/helpers/ApiDataFactory.md +6 -6
  14. package/docs/helpers/FileSystem.md +2 -2
  15. package/docs/helpers/GraphQLDataFactory.md +2 -2
  16. package/docs/helpers/Playwright.md +2 -1
  17. package/docs/index.md +1 -1
  18. package/docs/plugins.md +73 -48
  19. package/docs/reports.md +0 -56
  20. package/docs/typescript.md +2 -8
  21. package/lib/actor.js +2 -1
  22. package/lib/cli.js +3 -3
  23. package/lib/codecept.js +2 -1
  24. package/lib/command/generate.js +3 -1
  25. package/lib/command/gherkin/snippets.js +8 -4
  26. package/lib/command/init.js +0 -8
  27. package/lib/command/run-workers.js +3 -6
  28. package/lib/command/utils.js +0 -10
  29. package/lib/command/workers/runTests.js +2 -2
  30. package/lib/config.js +5 -1
  31. package/lib/helper/ApiDataFactory.js +7 -7
  32. package/lib/helper/Appium.js +2 -19
  33. package/lib/helper/FileSystem.js +3 -3
  34. package/lib/helper/GraphQL.js +1 -1
  35. package/lib/helper/GraphQLDataFactory.js +3 -3
  36. package/lib/helper/JSONResponse.js +1 -1
  37. package/lib/helper/Mochawesome.js +1 -1
  38. package/lib/helper/Nightmare.js +1 -1
  39. package/lib/helper/Playwright.js +4 -3
  40. package/lib/helper/Protractor.js +1 -1
  41. package/lib/helper/Puppeteer.js +1 -1
  42. package/lib/helper/REST.js +1 -1
  43. package/lib/helper/TestCafe.js +5 -5
  44. package/lib/helper/WebDriver.js +30 -165
  45. package/lib/helper.js +0 -2
  46. package/lib/interfaces/bdd.js +1 -1
  47. package/lib/interfaces/featureConfig.js +1 -0
  48. package/lib/interfaces/gherkin.js +38 -25
  49. package/lib/listener/exit.js +2 -2
  50. package/lib/listener/retry.js +67 -0
  51. package/lib/listener/steps.js +1 -1
  52. package/lib/listener/timeout.js +47 -10
  53. package/lib/mochaFactory.js +3 -3
  54. package/lib/plugin/allure.js +14 -323
  55. package/lib/plugin/fakerTransform.js +2 -2
  56. package/lib/recorder.js +1 -1
  57. package/lib/scenario.js +25 -18
  58. package/lib/utils.js +6 -0
  59. package/lib/workers.js +4 -7
  60. package/package.json +13 -17
  61. package/typings/index.d.ts +66 -1
  62. package/typings/promiseBasedTypes.d.ts +12 -12
  63. package/typings/types.d.ts +95 -262
@@ -1,5 +1,4 @@
1
1
  let webdriverio;
2
- let wdioV4;
3
2
 
4
3
  const fs = require('fs');
5
4
  const axios = require('axios').default;
@@ -131,6 +130,7 @@ class Appium extends Webdriver {
131
130
  * @augments WebDriver
132
131
  */
133
132
 
133
+ // @ts-ignore
134
134
  constructor(config) {
135
135
  super(config);
136
136
 
@@ -138,7 +138,6 @@ class Appium extends Webdriver {
138
138
  this.axios = axios.create();
139
139
 
140
140
  webdriverio = require('webdriverio');
141
- (!webdriverio.VERSION || webdriverio.VERSION.indexOf('4') !== 0) ? wdioV4 = false : wdioV4 = true;
142
141
  }
143
142
 
144
143
  _validateConfig(config) {
@@ -516,10 +515,6 @@ class Appium extends Webdriver {
516
515
  async removeApp(appId, bundleId) {
517
516
  onlyForApps.call(this, supportedPlatform.android);
518
517
 
519
- if (wdioV4) {
520
- return this.browser.removeApp(bundleId);
521
- }
522
-
523
518
  return this.axios({
524
519
  method: 'post',
525
520
  url: `${this._buildAppiumEndpoint()}/session/${this.browser.sessionId}/appium/device/remove_app`,
@@ -610,19 +605,13 @@ class Appium extends Webdriver {
610
605
  */
611
606
  async seeOrientationIs(orientation) {
612
607
  onlyForApps.call(this);
613
- let currentOrientation;
614
-
615
- if (wdioV4) {
616
- const res = await this.browser.orientation();
617
- currentOrientation = res;
618
- }
619
608
 
620
609
  const res = await this.axios({
621
610
  method: 'get',
622
611
  url: `${this._buildAppiumEndpoint()}/session/${this.browser.sessionId}/orientation`,
623
612
  });
624
613
 
625
- currentOrientation = res.data.value;
614
+ const currentOrientation = res.data.value;
626
615
  return truth('orientation', `to be ${orientation}`).assert(currentOrientation === orientation);
627
616
  }
628
617
 
@@ -640,9 +629,6 @@ class Appium extends Webdriver {
640
629
  */
641
630
  async setOrientation(orientation) {
642
631
  onlyForApps.call(this);
643
- if (wdioV4) {
644
- return this.browser.setOrientation(orientation);
645
- }
646
632
 
647
633
  return this.axios({
648
634
  method: 'post',
@@ -916,9 +902,6 @@ class Appium extends Webdriver {
916
902
  */
917
903
  async sendDeviceKeyEvent(keyValue) {
918
904
  onlyForApps.call(this, supportedPlatform.android);
919
- if (wdioV4) {
920
- return this.browser.sendKeyEvent(keyValue);
921
- }
922
905
  return this.browser.pressKeyCode(keyValue);
923
906
  }
924
907
 
@@ -2,7 +2,7 @@ const assert = require('assert');
2
2
  const path = require('path');
3
3
  const fs = require('fs');
4
4
 
5
- const Helper = require('../helper');
5
+ const Helper = require('@codeceptjs/helper');
6
6
  const { fileExists } = require('../utils');
7
7
  const { fileIncludes } = require('../assert/include');
8
8
  const { fileEquals } = require('../assert/equal');
@@ -71,10 +71,10 @@ class FileSystem extends Helper {
71
71
  }
72
72
 
73
73
  /**
74
- * Waits for file to be present in current directory.
74
+ * Waits for the file to be present in the current directory.
75
75
  *
76
76
  * ```js
77
- * I.handleDownloads();
77
+ * I.handleDownloads('downloads/largeFilesName.txt');
78
78
  * I.click('Download large File');
79
79
  * I.amInPath('output/downloads');
80
80
  * I.waitForFile('largeFilesName.txt', 10); // wait 10 seconds for file
@@ -1,5 +1,5 @@
1
1
  const axios = require('axios').default;
2
- const Helper = require('../helper');
2
+ const Helper = require('@codeceptjs/helper');
3
3
 
4
4
  /**
5
5
  * GraphQL helper allows to send additional requests to a GraphQl endpoint during acceptance tests.
@@ -1,6 +1,6 @@
1
1
  const path = require('path');
2
2
 
3
- const Helper = require('../helper');
3
+ const Helper = require('@codeceptjs/helper');
4
4
  const GraphQL = require('./GraphQL');
5
5
 
6
6
  /**
@@ -46,8 +46,8 @@ const GraphQL = require('./GraphQL');
46
46
  * ```js
47
47
  * // tests/factories/users.js
48
48
  *
49
- * const Factory = require('rosie').Factory;
50
- * const faker = require('@faker-js/faker');
49
+ * const { Factory } = require('rosie').Factory;
50
+ * const { faker } = require('@faker-js/faker');
51
51
  *
52
52
  * // Used with a constructor function passed to Factory, so that the final build
53
53
  * // object matches the necessary pattern to be sent as the variables object.
@@ -2,7 +2,7 @@ const assert = require('assert');
2
2
  const chai = require('chai');
3
3
  const joi = require('joi');
4
4
  const chaiDeepMatch = require('chai-deep-match');
5
- const Helper = require('../helper');
5
+ const Helper = require('@codeceptjs/helper');
6
6
 
7
7
  chai.use(chaiDeepMatch);
8
8
 
@@ -2,7 +2,7 @@ let addMochawesomeContext;
2
2
  let currentTest;
3
3
  let currentSuite;
4
4
 
5
- const Helper = require('../helper');
5
+ const Helper = require('@codeceptjs/helper');
6
6
  const { clearString } = require('../utils');
7
7
 
8
8
  class Mochawesome extends Helper {
@@ -2,7 +2,7 @@ const path = require('path');
2
2
 
3
3
  const urlResolve = require('url').resolve;
4
4
 
5
- const Helper = require('../helper');
5
+ const Helper = require('@codeceptjs/helper');
6
6
  const { includes: stringIncludes } = require('../assert/include');
7
7
  const { urlEquals } = require('../assert/equal');
8
8
  const { equals } = require('../assert/equal');
@@ -1,7 +1,7 @@
1
1
  const path = require('path');
2
2
  const fs = require('fs');
3
3
 
4
- const Helper = require('../helper');
4
+ const Helper = require('@codeceptjs/helper');
5
5
  const Locator = require('../locator');
6
6
  const recorder = require('../recorder');
7
7
  const stringIncludes = require('../assert/include').includes;
@@ -66,6 +66,7 @@ const pathSeparator = path.sep;
66
66
  * @prop {boolean} [video=false] - enables video recording for failed tests; videos are saved into `output/videos` folder
67
67
  * @prop {boolean} [keepVideoForPassedTests=false] - save videos for passed tests; videos are saved into `output/videos` folder
68
68
  * @prop {boolean} [trace=false] - record [tracing information](https://playwright.dev/docs/trace-viewer) with screenshots and snapshots.
69
+ * @prop {boolean} [keepTraceForPassedTests=false] - save trace for passed tests.
69
70
  * @prop {boolean} [fullPageScreenshots=false] - make full page screenshots on failure.
70
71
  * @prop {boolean} [uniqueScreenshotNames=false] - option to prevent screenshot override if you have scenarios with the same name in different suites.
71
72
  * @prop {boolean} [keepBrowserState=false] - keep browser state between tests when `restart` is set to 'session'.
@@ -1259,7 +1260,7 @@ class Playwright extends Helper {
1259
1260
  *
1260
1261
  * ```
1261
1262
  *
1262
- * @param {string} [fileName] set filename for downloaded file
1263
+ * @param {string} fileName set filename for downloaded file
1263
1264
  * @return {Promise<void>}
1264
1265
  */
1265
1266
  async handleDownloads(fileName) {
@@ -2981,7 +2982,7 @@ async function refreshContextSession() {
2981
2982
 
2982
2983
  async function saveVideoForPage(page, name) {
2983
2984
  if (!page.video()) return null;
2984
- const fileName = `${global.output_dir}${pathSeparator}videos${pathSeparator}${Date.now()}_${clearString(name).slice(0, 245)}.webm`;
2985
+ const fileName = `${`${global.output_dir}${pathSeparator}videos${pathSeparator}${Date.now()}_${clearString(name)}`.slice(0, 245)}.webm`;
2985
2986
  page.video().saveAs(fileName).then(() => {
2986
2987
  if (!page) return;
2987
2988
  page.video().delete().catch(e => {});
@@ -6,7 +6,7 @@ let ProtractorExpectedConditions;
6
6
 
7
7
  const path = require('path');
8
8
 
9
- const Helper = require('../helper');
9
+ const Helper = require('@codeceptjs/helper');
10
10
  const stringIncludes = require('../assert/include').includes;
11
11
  const { urlEquals, equals } = require('../assert/equal');
12
12
  const { empty } = require('../assert/empty');
@@ -3,7 +3,7 @@ const fs = require('fs');
3
3
  const fsExtra = require('fs-extra');
4
4
  const path = require('path');
5
5
 
6
- const Helper = require('../helper');
6
+ const Helper = require('@codeceptjs/helper');
7
7
  const Locator = require('../locator');
8
8
  const recorder = require('../recorder');
9
9
  const stringIncludes = require('../assert/include').includes;
@@ -1,7 +1,7 @@
1
1
  const axios = require('axios').default;
2
+ const Helper = require('@codeceptjs/helper');
2
3
  const Secret = require('../secret');
3
4
 
4
- const Helper = require('../helper');
5
5
  const { beautify } = require('../utils');
6
6
 
7
7
  /**
@@ -6,6 +6,7 @@ const qrcode = require('qrcode-terminal');
6
6
  const createTestCafe = require('testcafe');
7
7
  const { Selector, ClientFunction } = require('testcafe');
8
8
 
9
+ const Helper = require('@codeceptjs/helper');
9
10
  const ElementNotFound = require('./errors/ElementNotFound');
10
11
  const testControllerHolder = require('./testcafe/testControllerHolder');
11
12
  const {
@@ -22,7 +23,6 @@ const {
22
23
  xpathLocator,
23
24
  } = require('../utils');
24
25
  const Locator = require('../locator');
25
- const Helper = require('../helper');
26
26
 
27
27
  /**
28
28
  * Client Functions
@@ -545,8 +545,8 @@ class TestCafe extends Helper {
545
545
 
546
546
  // TODO As far as I understand the testcafe docs this should do a multi-select
547
547
  // but it does not work
548
- const clickOpts = { ctrl: option.length > 1 };
549
- await this.t.click(el, clickOpts).catch(mapError);
548
+ // const clickOpts = { ctrl: option.length > 1 };
549
+ await this.t.click(el).catch(mapError);
550
550
 
551
551
  for (const key of option) {
552
552
  const opt = key;
@@ -555,7 +555,7 @@ class TestCafe extends Helper {
555
555
  try {
556
556
  optEl = el.child('option').withText(opt);
557
557
  if (await optEl.count) {
558
- await this.t.click(optEl, clickOpts).catch(mapError);
558
+ await this.t.click(optEl).catch(mapError);
559
559
  continue;
560
560
  }
561
561
  // eslint-disable-next-line no-empty
@@ -566,7 +566,7 @@ class TestCafe extends Helper {
566
566
  const sel = `[value="${opt}"]`;
567
567
  optEl = el.find(sel);
568
568
  if (await optEl.count) {
569
- await this.t.click(optEl, clickOpts).catch(mapError);
569
+ await this.t.click(optEl).catch(mapError);
570
570
  }
571
571
  // eslint-disable-next-line no-empty
572
572
  } catch (err) {
@@ -4,12 +4,12 @@ const assert = require('assert');
4
4
  const path = require('path');
5
5
  const fs = require('fs');
6
6
 
7
- const Helper = require('../helper');
7
+ const Helper = require('@codeceptjs/helper');
8
8
  const stringIncludes = require('../assert/include').includes;
9
9
  const { urlEquals, equals } = require('../assert/equal');
10
10
  const { debug } = require('../output');
11
- const empty = require('../assert/empty').empty;
12
- const truth = require('../assert/truth').truth;
11
+ const { empty } = require('../assert/empty');
12
+ const { truth } = require('../assert/truth');
13
13
  const {
14
14
  xpathLocator,
15
15
  fileExists,
@@ -31,8 +31,6 @@ const Locator = require('../locator');
31
31
  const SHADOW = 'shadow';
32
32
  const webRoot = 'body';
33
33
 
34
- let version;
35
-
36
34
  /**
37
35
  * ## Configuration
38
36
  *
@@ -266,7 +264,7 @@ const config = {};
266
264
  * ```js
267
265
  * plugins: {
268
266
  * wdio: {
269
- * enabled: true,
267
+ * enabled: true,
270
268
  * services: ['sauce'],
271
269
  * user: ... ,// saucelabs username
272
270
  * key: ... // saucelabs api key
@@ -294,7 +292,7 @@ const config = {};
294
292
  * ```js
295
293
  * plugins: {
296
294
  * wdio: {
297
- * enabled: true,
295
+ * enabled: true,
298
296
  * services: ['browserstack'],
299
297
  * user: ... ,// browserstack username
300
298
  * key: ... // browserstack api key
@@ -386,16 +384,6 @@ class WebDriver extends Helper {
386
384
  super(config);
387
385
  webdriverio = require('webdriverio');
388
386
 
389
- try {
390
- version = JSON.parse(fs.readFileSync(path.join(require.resolve('webdriverio'), '/../../', 'package.json')).toString()).version;
391
- } catch (err) {
392
- this.debug('Can\'t detect webdriverio version, assuming webdriverio v6 is used');
393
- }
394
-
395
- if (isWebDriver5()) {
396
- console.log('DEPRECATION NOTICE:');
397
- console.log('You are using webdriverio v5. It is recommended to update to webdriverio@6.\nSupport of webdriverio v5 is deprecated and will be removed in CodeceptJS 3.0\n');
398
- }
399
387
  // set defaults
400
388
  this.root = webRoot;
401
389
  this.isWeb = true;
@@ -661,23 +649,23 @@ class WebDriver extends Helper {
661
649
  }
662
650
 
663
651
  /**
664
- * Use [webdriverio](https://webdriver.io/docs/api.html) API inside a test.
665
- *
666
- * First argument is a description of an action.
667
- * Second argument is async function that gets this helper as parameter.
668
- *
669
- * { [`browser`](https://webdriver.io/docs/api.html)) } object from WebDriver API is available.
670
- *
671
- * ```js
672
- * I.useWebDriverTo('open multiple windows', async ({ browser }) {
673
- * // create new window
674
- * await browser.newWindow('https://webdriver.io');
675
- * });
676
- * ```
677
- *
678
- * @param {string} description used to show in logs.
679
- * @param {function} fn async functuion that executed with WebDriver helper as argument
680
- */
652
+ * Use [webdriverio](https://webdriver.io/docs/api.html) API inside a test.
653
+ *
654
+ * First argument is a description of an action.
655
+ * Second argument is async function that gets this helper as parameter.
656
+ *
657
+ * { [`browser`](https://webdriver.io/docs/api.html)) } object from WebDriver API is available.
658
+ *
659
+ * ```js
660
+ * I.useWebDriverTo('open multiple windows', async ({ browser }) {
661
+ * // create new window
662
+ * await browser.newWindow('https://webdriver.io');
663
+ * });
664
+ * ```
665
+ *
666
+ * @param {string} description used to show in logs.
667
+ * @param {function} fn async functuion that executed with WebDriver helper as argument
668
+ */
681
669
  useWebDriverTo(description, fn) {
682
670
  return this._useTo(...arguments);
683
671
  }
@@ -1654,7 +1642,6 @@ class WebDriver extends Helper {
1654
1642
  const res = await this._locate(withStrictLocator(locator), true);
1655
1643
  assertElementExists(res, locator);
1656
1644
  const elem = usingFirstElement(res);
1657
- if (isWebDriver5()) return elem.moveTo(xOffset, yOffset);
1658
1645
  return elem.moveTo({ xOffset, yOffset });
1659
1646
  }
1660
1647
 
@@ -2043,19 +2030,7 @@ class WebDriver extends Helper {
2043
2030
  */
2044
2031
  async waitForEnabled(locator, sec = null) {
2045
2032
  const aSec = sec || this.options.waitForTimeoutInSeconds;
2046
- if (isWebDriver5()) {
2047
- return this.browser.waitUntil(async () => {
2048
- const res = await this.$$(withStrictLocator(locator));
2049
- if (!res || res.length === 0) {
2050
- return false;
2051
- }
2052
- const selected = await forEachAsync(res, async el => this.browser.isElementEnabled(getElementId(el)));
2053
- if (Array.isArray(selected)) {
2054
- return selected.filter(val => val === true).length > 0;
2055
- }
2056
- return selected;
2057
- }, aSec * 1000, `element (${new Locator(locator)}) still not enabled after ${aSec} sec`);
2058
- }
2033
+
2059
2034
  return this.browser.waitUntil(async () => {
2060
2035
  const res = await this._res(locator);
2061
2036
  if (!res || res.length === 0) {
@@ -2077,12 +2052,7 @@ class WebDriver extends Helper {
2077
2052
  */
2078
2053
  async waitForElement(locator, sec = null) {
2079
2054
  const aSec = sec || this.options.waitForTimeoutInSeconds;
2080
- if (isWebDriver5()) {
2081
- return this.browser.waitUntil(async () => {
2082
- const res = await this.$$(withStrictLocator(locator));
2083
- return res && res.length;
2084
- }, aSec * 1000, `element (${(new Locator(locator))}) still not present on page after ${aSec} sec`);
2085
- }
2055
+
2086
2056
  return this.browser.waitUntil(async () => {
2087
2057
  const res = await this._res(locator);
2088
2058
  return res && res.length;
@@ -2111,20 +2081,7 @@ class WebDriver extends Helper {
2111
2081
  const client = this.browser;
2112
2082
  const aSec = sec || this.options.waitForTimeoutInSeconds;
2113
2083
  let currUrl = '';
2114
- if (isWebDriver5()) {
2115
- return client
2116
- .waitUntil(function () {
2117
- return this.getUrl().then((res) => {
2118
- currUrl = decodeUrl(res);
2119
- return currUrl.indexOf(urlPart) > -1;
2120
- });
2121
- }, aSec * 1000).catch((e) => {
2122
- if (e.message.indexOf('timeout')) {
2123
- throw new Error(`expected url to include ${urlPart}, but found ${currUrl}`);
2124
- }
2125
- throw e;
2126
- });
2127
- }
2084
+
2128
2085
  return client
2129
2086
  .waitUntil(function () {
2130
2087
  return this.getUrl().then((res) => {
@@ -2169,20 +2126,6 @@ class WebDriver extends Helper {
2169
2126
  async waitForText(text, sec = null, context = null) {
2170
2127
  const aSec = sec || this.options.waitForTimeoutInSeconds;
2171
2128
  const _context = context || this.root;
2172
- if (isWebDriver5()) {
2173
- return this.browser.waitUntil(
2174
- async () => {
2175
- const res = await this.$$(withStrictLocator.call(this, _context));
2176
- if (!res || res.length === 0) return false;
2177
- const selected = await forEachAsync(res, async el => this.browser.getElementText(getElementId(el)));
2178
- if (Array.isArray(selected)) {
2179
- return selected.filter(part => part.indexOf(text) >= 0).length > 0;
2180
- }
2181
- return selected.indexOf(text) >= 0;
2182
- }, aSec * 1000,
2183
- `element (${_context}) is not in DOM or there is no element(${_context}) with text "${text}" after ${aSec} sec`,
2184
- );
2185
- }
2186
2129
 
2187
2130
  return this.browser.waitUntil(
2188
2131
  async () => {
@@ -2206,20 +2149,7 @@ class WebDriver extends Helper {
2206
2149
  async waitForValue(field, value, sec = null) {
2207
2150
  const client = this.browser;
2208
2151
  const aSec = sec || this.options.waitForTimeoutInSeconds;
2209
- if (isWebDriver5()) {
2210
- return client.waitUntil(
2211
- async () => {
2212
- const res = await findFields.call(this, field);
2213
- if (!res || res.length === 0) return false;
2214
- const selected = await forEachAsync(res, async el => el.getValue());
2215
- if (Array.isArray(selected)) {
2216
- return selected.filter(part => part.indexOf(value) >= 0).length > 0;
2217
- }
2218
- return selected.indexOf(value) >= 0;
2219
- }, aSec * 1000,
2220
- `element (${field}) is not in DOM or there is no element(${field}) with value "${value}" after ${aSec} sec`,
2221
- );
2222
- }
2152
+
2223
2153
  return client.waitUntil(
2224
2154
  async () => {
2225
2155
  const res = await findFields.call(this, field);
@@ -2242,17 +2172,7 @@ class WebDriver extends Helper {
2242
2172
  */
2243
2173
  async waitForVisible(locator, sec = null) {
2244
2174
  const aSec = sec || this.options.waitForTimeoutInSeconds;
2245
- if (isWebDriver5()) {
2246
- return this.browser.waitUntil(async () => {
2247
- const res = await this.$$(withStrictLocator(locator));
2248
- if (!res || res.length === 0) return false;
2249
- const selected = await forEachAsync(res, async el => el.isDisplayed());
2250
- if (Array.isArray(selected)) {
2251
- return selected.filter(val => val === true).length > 0;
2252
- }
2253
- return selected;
2254
- }, aSec * 1000, `element (${new Locator(locator)}) still not visible after ${aSec} sec`);
2255
- }
2175
+
2256
2176
  return this.browser.waitUntil(async () => {
2257
2177
  const res = await this._res(locator);
2258
2178
  if (!res || res.length === 0) return false;
@@ -2269,17 +2189,7 @@ class WebDriver extends Helper {
2269
2189
  */
2270
2190
  async waitNumberOfVisibleElements(locator, num, sec = null) {
2271
2191
  const aSec = sec || this.options.waitForTimeoutInSeconds;
2272
- if (isWebDriver5()) {
2273
- return this.browser.waitUntil(async () => {
2274
- const res = await this.$$(withStrictLocator(locator));
2275
- if (!res || res.length === 0) return false;
2276
- let selected = await forEachAsync(res, async el => el.isDisplayed());
2277
2192
 
2278
- if (!Array.isArray(selected)) selected = [selected];
2279
- selected = selected.filter(val => val === true);
2280
- return selected.length === num;
2281
- }, aSec * 1000, `The number of elements (${new Locator(locator)}) is not ${num} after ${aSec} sec`);
2282
- }
2283
2193
  return this.browser.waitUntil(async () => {
2284
2194
  const res = await this._res(locator);
2285
2195
  if (!res || res.length === 0) return false;
@@ -2296,14 +2206,7 @@ class WebDriver extends Helper {
2296
2206
  */
2297
2207
  async waitForInvisible(locator, sec = null) {
2298
2208
  const aSec = sec || this.options.waitForTimeoutInSeconds;
2299
- if (isWebDriver5()) {
2300
- return this.browser.waitUntil(async () => {
2301
- const res = await this.$$(withStrictLocator(locator));
2302
- if (!res || res.length === 0) return true;
2303
- const selected = await forEachAsync(res, async el => el.isDisplayed());
2304
- return !selected.length;
2305
- }, aSec * 1000, `element (${new Locator(locator)}) still visible after ${aSec} sec`);
2306
- }
2209
+
2307
2210
  return this.browser.waitUntil(async () => {
2308
2211
  const res = await this._res(locator);
2309
2212
  if (!res || res.length === 0) return true;
@@ -2324,15 +2227,7 @@ class WebDriver extends Helper {
2324
2227
  */
2325
2228
  async waitForDetached(locator, sec = null) {
2326
2229
  const aSec = sec || this.options.waitForTimeoutInSeconds;
2327
- if (isWebDriver5()) {
2328
- return this.browser.waitUntil(async () => {
2329
- const res = await this._res(locator);
2330
- if (!res || res.length === 0) {
2331
- return true;
2332
- }
2333
- return false;
2334
- }, aSec * 1000, `element (${new Locator(locator)}) still on page after ${aSec} sec`);
2335
- }
2230
+
2336
2231
  return this.browser.waitUntil(async () => {
2337
2232
  const res = await this._res(locator);
2338
2233
  if (!res || res.length === 0) {
@@ -2356,9 +2251,7 @@ class WebDriver extends Helper {
2356
2251
  }
2357
2252
 
2358
2253
  const aSec = sec || this.options.waitForTimeoutInSeconds;
2359
- if (isWebDriver5()) {
2360
- return this.browser.waitUntil(async () => this.browser.execute(fn, ...args), aSec * 1000, '');
2361
- }
2254
+
2362
2255
  return this.browser.waitUntil(async () => this.browser.execute(fn, ...args), { timeout: aSec * 1000, timeoutMsg: '' });
2363
2256
  }
2364
2257
 
@@ -2388,18 +2281,6 @@ class WebDriver extends Helper {
2388
2281
  let target;
2389
2282
  const current = await this.browser.getWindowHandle();
2390
2283
 
2391
- if (isWebDriver5()) {
2392
- await this.browser.waitUntil(async () => {
2393
- await this.browser.getWindowHandles().then((handles) => {
2394
- if (handles.indexOf(current) + num + 1 <= handles.length) {
2395
- target = handles[handles.indexOf(current) + num];
2396
- }
2397
- });
2398
- return target;
2399
- }, aSec * 1000, `There is no ability to switch to next tab with offset ${num}`);
2400
- return this.browser.switchToWindow(target);
2401
- }
2402
-
2403
2284
  await this.browser.waitUntil(async () => {
2404
2285
  await this.browser.getWindowHandles().then((handles) => {
2405
2286
  if (handles.indexOf(current) + num + 1 <= handles.length) {
@@ -2419,18 +2300,6 @@ class WebDriver extends Helper {
2419
2300
  const current = await this.browser.getWindowHandle();
2420
2301
  let target;
2421
2302
 
2422
- if (isWebDriver5()) {
2423
- await this.browser.waitUntil(async () => {
2424
- await this.browser.getWindowHandles().then((handles) => {
2425
- if (handles.indexOf(current) - num > -1) {
2426
- target = handles[handles.indexOf(current) - num];
2427
- }
2428
- });
2429
- return target;
2430
- }, aSec * 1000, `There is no ability to switch to previous tab with offset ${num}`);
2431
- return this.browser.switchToWindow(target);
2432
- }
2433
-
2434
2303
  await this.browser.waitUntil(async () => {
2435
2304
  await this.browser.getWindowHandles().then((handles) => {
2436
2305
  if (handles.indexOf(current) - num > -1) {
@@ -3018,8 +2887,4 @@ function prepareLocateFn(context) {
3018
2887
  };
3019
2888
  }
3020
2889
 
3021
- function isWebDriver5() {
3022
- return version && version.indexOf('5') === 0;
3023
- }
3024
-
3025
2890
  module.exports = WebDriver;
package/lib/helper.js CHANGED
@@ -1,4 +1,2 @@
1
1
  // helper class was moved out from this repository to allow extending from base class
2
- // without loading full CodeceptJS package
3
- if (!global.codeceptjs) global.codeceptjs = require('./index');
4
2
  module.exports = require('@codeceptjs/helper');
@@ -1,4 +1,4 @@
1
- const { CucumberExpression, ParameterTypeRegistry, ParameterType } = require('cucumber-expressions');
1
+ const { CucumberExpression, ParameterTypeRegistry, ParameterType } = require('@cucumber/cucumber-expressions');
2
2
  const Config = require('../config');
3
3
 
4
4
  let steps = {};
@@ -19,6 +19,7 @@ class FeatureConfig {
19
19
  * Set timeout for this suite
20
20
  * @param {number} timeout
21
21
  * @returns {this}
22
+ * @deprecated
22
23
  */
23
24
  timeout(timeout) {
24
25
  console.log(`Feature('${this.suite.title}').timeout(${timeout}) is deprecated!`);