codeceptjs 3.0.7 → 3.1.3

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 (57) hide show
  1. package/CHANGELOG.md +96 -2
  2. package/README.md +9 -1
  3. package/bin/codecept.js +27 -17
  4. package/docs/bdd.md +55 -1
  5. package/docs/build/Appium.js +76 -4
  6. package/docs/build/Playwright.js +186 -69
  7. package/docs/build/Protractor.js +2 -0
  8. package/docs/build/Puppeteer.js +56 -18
  9. package/docs/build/REST.js +12 -0
  10. package/docs/build/WebDriver.js +1 -3
  11. package/docs/changelog.md +96 -2
  12. package/docs/commands.md +21 -7
  13. package/docs/configuration.md +15 -2
  14. package/docs/helpers/Appium.md +96 -94
  15. package/docs/helpers/Playwright.md +259 -202
  16. package/docs/helpers/Puppeteer.md +17 -1
  17. package/docs/helpers/REST.md +23 -9
  18. package/docs/helpers/WebDriver.md +2 -2
  19. package/docs/mobile.md +2 -1
  20. package/docs/playwright.md +156 -6
  21. package/docs/plugins.md +61 -69
  22. package/docs/react.md +1 -1
  23. package/docs/reports.md +21 -3
  24. package/lib/actor.js +2 -3
  25. package/lib/codecept.js +13 -2
  26. package/lib/command/definitions.js +8 -1
  27. package/lib/command/run-multiple/collection.js +4 -0
  28. package/lib/config.js +1 -1
  29. package/lib/container.js +3 -3
  30. package/lib/data/dataTableArgument.js +35 -0
  31. package/lib/helper/Appium.js +49 -4
  32. package/lib/helper/Playwright.js +186 -69
  33. package/lib/helper/Protractor.js +2 -0
  34. package/lib/helper/Puppeteer.js +56 -18
  35. package/lib/helper/REST.js +12 -0
  36. package/lib/helper/WebDriver.js +1 -3
  37. package/lib/helper/errors/ConnectionRefused.js +1 -1
  38. package/lib/helper/extras/Popup.js +1 -1
  39. package/lib/helper/extras/React.js +44 -32
  40. package/lib/index.js +2 -0
  41. package/lib/interfaces/gherkin.js +8 -1
  42. package/lib/listener/exit.js +2 -4
  43. package/lib/listener/helpers.js +4 -4
  44. package/lib/locator.js +7 -0
  45. package/lib/mochaFactory.js +13 -9
  46. package/lib/output.js +2 -2
  47. package/lib/plugin/allure.js +7 -18
  48. package/lib/plugin/commentStep.js +1 -1
  49. package/lib/plugin/{puppeteerCoverage.js → coverage.js} +10 -22
  50. package/lib/plugin/customLocator.js +2 -2
  51. package/lib/plugin/subtitles.js +88 -0
  52. package/lib/plugin/tryTo.js +1 -1
  53. package/lib/recorder.js +5 -3
  54. package/lib/step.js +4 -2
  55. package/package.json +4 -3
  56. package/typings/index.d.ts +2 -0
  57. package/typings/types.d.ts +158 -18
@@ -1,4 +1,4 @@
1
- const debug = require('debug')('codeceptjs:plugin:puppeteerCoverage');
1
+ const debugModule = require('debug');
2
2
  const fs = require('fs');
3
3
  const path = require('path');
4
4
 
@@ -13,7 +13,7 @@ const defaultConfig = {
13
13
  uniqueFileName: true,
14
14
  };
15
15
 
16
- const supportedHelpers = ['Puppeteer'];
16
+ const supportedHelpers = ['Puppeteer', 'Playwright'];
17
17
 
18
18
  function buildFileName(test, uniqueFileName) {
19
19
  let fileName = clearString(test.title);
@@ -41,15 +41,14 @@ function buildFileName(test, uniqueFileName) {
41
41
  }
42
42
 
43
43
  /**
44
- * Dumps puppeteers code coverage after every test.
44
+ * Dumps code coverage from Playwright/Puppeteer after every test.
45
45
  *
46
46
  * #### Configuration
47
47
  *
48
- * Configuration can either be taken from a corresponding helper (deprecated) or a from plugin config (recommended).
49
48
  *
50
49
  * ```js
51
50
  * plugins: {
52
- * puppeteerCoverage: {
51
+ * coverage: {
53
52
  * enabled: true
54
53
  * }
55
54
  * }
@@ -59,33 +58,22 @@ function buildFileName(test, uniqueFileName) {
59
58
  *
60
59
  * * `coverageDir`: directory to dump coverage files
61
60
  * * `uniqueFileName`: generate a unique filename by adding uuid
62
- *
63
- * First of all, your mileage may vary!
64
- *
65
- * To work, you need the client javascript code to be NOT uglified. They need to be built in "development" mode.
66
- * And the end of your tests, you'll get a directory full of coverage per test run. Now what?
67
- * You'll need to convert the coverage code to something istanbul can read. Good news is someone wrote the code
68
- * for you (see puppeteer-to-istanbul link below). Then using istanbul you need to combine the converted
69
- * coverage and create a report. Good luck!
70
- *
71
- * Links:
72
- * * https://github.com/GoogleChrome/puppeteer/blob/v1.12.2/docs/api.md#class-coverage
73
- * * https://github.com/istanbuljs/puppeteer-to-istanbul
74
- * * https://github.com/gotwarlost/istanbul
75
61
  */
76
62
  module.exports = function (config) {
77
63
  const helpers = Container.helpers();
78
64
  let coverageRunning = false;
79
65
  let helper;
80
66
 
67
+ let debug;
81
68
  for (const helperName of supportedHelpers) {
82
69
  if (Object.keys(helpers).indexOf(helperName) > -1) {
83
70
  helper = helpers[helperName];
71
+ debug = debugModule(`codeceptjs:plugin:${helperName.toLowerCase()}Coverage`);
84
72
  }
85
73
  }
86
74
 
87
75
  if (!helper) {
88
- console.error('Coverage is only supported in Puppeteer');
76
+ console.error('Coverage is only supported in Puppeteer, Playwright');
89
77
  return; // no helpers for screenshot
90
78
  }
91
79
 
@@ -102,7 +90,7 @@ module.exports = function (config) {
102
90
  'starting coverage',
103
91
  async () => {
104
92
  try {
105
- if (!coverageRunning) {
93
+ if (!coverageRunning && helper.page && helper.page.coverage) {
106
94
  debug('--> starting coverage <--');
107
95
  coverageRunning = true;
108
96
  await helper.page.coverage.startJSCoverage();
@@ -115,13 +103,13 @@ module.exports = function (config) {
115
103
  );
116
104
  });
117
105
 
118
- // Save puppeteer coverage data after every test run
106
+ // Save coverage data after every test run
119
107
  event.dispatcher.on(event.test.after, async (test) => {
120
108
  recorder.add(
121
109
  'saving coverage',
122
110
  async () => {
123
111
  try {
124
- if (coverageRunning) {
112
+ if (coverageRunning && helper.page && helper.page.coverage) {
125
113
  debug('--> stopping coverage <--');
126
114
  coverageRunning = false;
127
115
  const coverage = await helper.page.coverage.stopJSCoverage();
@@ -38,7 +38,7 @@ const defaultConfig = {
38
38
  * // in codecept.conf.js
39
39
  * plugins: {
40
40
  * customLocator: {
41
- * enabled: true
41
+ * enabled: true,
42
42
  * attribute: 'data-test'
43
43
  * }
44
44
  * }
@@ -57,7 +57,7 @@ const defaultConfig = {
57
57
  * // in codecept.conf.js
58
58
  * plugins: {
59
59
  * customLocator: {
60
- * enabled: true
60
+ * enabled: true,
61
61
  * prefix: '=',
62
62
  * attribute: 'data-qa'
63
63
  * }
@@ -0,0 +1,88 @@
1
+ const { v4: uuidv4 } = require('uuid');
2
+ const fsPromise = require('fs').promises;
3
+ const path = require('path');
4
+ const event = require('../event');
5
+
6
+ // This will convert a given timestamp in milliseconds to
7
+ // an SRT recognized timestamp, ie HH:mm:ss,SSS
8
+ function formatTimestamp(timestampInMs) {
9
+ const date = new Date(0, 0, 0, 0, 0, 0, timestampInMs);
10
+ const hours = date.getHours();
11
+ const minutes = date.getMinutes();
12
+ const seconds = date.getSeconds();
13
+ const ms = timestampInMs - (hours * 3600000 + minutes * 60000 + seconds * 1000);
14
+ return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')},${ms.toString().padStart(3, '0')}`;
15
+ }
16
+
17
+ let steps = {};
18
+ let testStartedAt;
19
+ /**
20
+ * Automatically captures steps as subtitle, and saves it as an artifact when a video is found for a failed test
21
+ *
22
+ * #### Configuration
23
+ * ```js
24
+ * plugins: {
25
+ * subtitles: {
26
+ * enabled: true
27
+ * }
28
+ * }
29
+ * ```
30
+ */
31
+ module.exports = function () {
32
+ event.dispatcher.on(event.test.before, (_) => {
33
+ testStartedAt = Date.now();
34
+ steps = {};
35
+ });
36
+
37
+ event.dispatcher.on(event.step.started, (step) => {
38
+ const stepStartedAt = Date.now();
39
+ step.id = uuidv4();
40
+
41
+ let title = `${step.actor}.${step.name}(${step.args ? step.args.join(',') : ''})`;
42
+ if (title.length > 100) {
43
+ title = `${title.substring(0, 100)}...`;
44
+ }
45
+
46
+ steps[step.id] = {
47
+ start: formatTimestamp(stepStartedAt - testStartedAt),
48
+ startedAt: stepStartedAt,
49
+ title,
50
+ };
51
+ });
52
+
53
+ event.dispatcher.on(event.step.finished, (step) => {
54
+ if (step && step.id && steps[step.id]) {
55
+ steps[step.id].end = formatTimestamp(Date.now() - testStartedAt);
56
+ }
57
+ });
58
+
59
+ event.dispatcher.on(event.test.after, async (test) => {
60
+ if (test && test.artifacts && test.artifacts.video) {
61
+ const stepsSortedByStartTime = Object.values(steps);
62
+ stepsSortedByStartTime.sort((stepA, stepB) => {
63
+ return stepA.startedAt - stepB.startedAt;
64
+ });
65
+
66
+ let subtitle = '';
67
+
68
+ // For an SRT file, every subtitle has to be in the format as mentioned below:
69
+ //
70
+ // 1
71
+ // HH:mm:ss,SSS --> HH:mm:ss,SSS
72
+ // [title]
73
+ stepsSortedByStartTime.forEach((step, index) => {
74
+ if (step.end) {
75
+ subtitle = `${subtitle}${index + 1}
76
+ ${step.start} --> ${step.end}
77
+ ${step.title}
78
+
79
+ `;
80
+ }
81
+ });
82
+
83
+ const { dir: artifactsDirectory, name: fileName } = path.parse(test.artifacts.video);
84
+ await fsPromise.writeFile(`${artifactsDirectory}/${fileName}.srt`, subtitle);
85
+ test.artifacts.subtitle = `${artifactsDirectory}/${fileName}.srt`;
86
+ }
87
+ });
88
+ };
@@ -89,7 +89,7 @@ function tryTo(callback) {
89
89
  recorder.session.catch((err) => {
90
90
  result = false;
91
91
  const msg = err.inspect ? err.inspect() : err.toString();
92
- debug(`Unsuccesful try > ${msg}`);
92
+ debug(`Unsuccessful try > ${msg}`);
93
93
  recorder.session.restore('tryTo');
94
94
  return result;
95
95
  });
package/lib/recorder.js CHANGED
@@ -3,6 +3,8 @@ const promiseRetry = require('promise-retry');
3
3
 
4
4
  const { log } = require('./output');
5
5
 
6
+ const MAX_TASKS = 100;
7
+
6
8
  let promise;
7
9
  let running = false;
8
10
  let errFn;
@@ -172,7 +174,7 @@ module.exports = {
172
174
  return;
173
175
  }
174
176
  tasks.push(taskName);
175
- debug(`${currentQueue()}Queued | ${taskName}`);
177
+ if (process.env.DEBUG) debug(`${currentQueue()}Queued | ${taskName}`);
176
178
 
177
179
  return promise = Promise.resolve(promise).then((res) => {
178
180
  const retryOpts = this.retries.slice(-1).pop();
@@ -296,7 +298,7 @@ module.exports = {
296
298
  * @inner
297
299
  */
298
300
  stop() {
299
- debug(this.toString());
301
+ if (process.env.DEBUG) debug(this.toString());
300
302
  log(`${currentQueue()}Stopping recording promises`);
301
303
  running = false;
302
304
  },
@@ -318,7 +320,7 @@ module.exports = {
318
320
  * @inner
319
321
  */
320
322
  scheduled() {
321
- return tasks.join('\n');
323
+ return tasks.slice(-MAX_TASKS).join('\n');
322
324
  },
323
325
 
324
326
  /**
package/lib/step.js CHANGED
@@ -212,16 +212,18 @@ class MetaStep extends Step {
212
212
  step.metaStep = this;
213
213
  };
214
214
  event.dispatcher.prependListener(event.step.before, registerStep);
215
+ let rethrownError = null;
215
216
  try {
216
217
  this.startTime = Date.now();
217
218
  result = fn.apply(this.context, this.args);
218
219
  } catch (error) {
219
- this.status = 'failed';
220
+ this.setStatus('failed');
221
+ rethrownError = error;
220
222
  } finally {
221
223
  this.endTime = Date.now();
222
-
223
224
  event.dispatcher.removeListener(event.step.before, registerStep);
224
225
  }
226
+ if (rethrownError) { throw rethrownError; }
225
227
  return result;
226
228
  }
227
229
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeceptjs",
3
- "version": "3.0.7",
3
+ "version": "3.1.3",
4
4
  "description": "Supercharged End 2 End Testing Framework for NodeJS",
5
5
  "keywords": [
6
6
  "acceptance",
@@ -84,7 +84,8 @@
84
84
  "promise-retry": "^1.1.1",
85
85
  "requireg": "^0.2.2",
86
86
  "resq": "^1.10.0",
87
- "sprintf-js": "^1.1.1"
87
+ "sprintf-js": "^1.1.1",
88
+ "uuid": "^8.3.2"
88
89
  },
89
90
  "devDependencies": {
90
91
  "@codeceptjs/detox-helper": "^1.0.2",
@@ -122,7 +123,7 @@
122
123
  "nodemon": "^1.19.4",
123
124
  "playwright": "^1.9.1",
124
125
  "protractor": "^5.4.4",
125
- "puppeteer": "^8.0.0",
126
+ "puppeteer": "^10.0.0",
126
127
  "qrcode-terminal": "^0.12.0",
127
128
  "rosie": "^1.6.0",
128
129
  "runok": "^0.9.2",
@@ -111,6 +111,7 @@ declare const pause: typeof CodeceptJS.pause;
111
111
  declare const within: typeof CodeceptJS.within;
112
112
  declare const session: typeof CodeceptJS.session;
113
113
  declare const DataTable: typeof CodeceptJS.DataTable;
114
+ declare const DataTableArgument: typeof CodeceptJS.DataTableArgument;
114
115
  declare const codeceptjs: typeof CodeceptJS.index;
115
116
  declare const locate: typeof CodeceptJS.Locator.build;
116
117
  declare function inject(): CodeceptJS.SupportObject;
@@ -160,6 +161,7 @@ declare namespace NodeJS {
160
161
  within: typeof within;
161
162
  session: typeof session;
162
163
  DataTable: typeof DataTable;
164
+ DataTableArgument: typeof DataTableArgument;
163
165
  locate: typeof locate;
164
166
  inject: typeof inject;
165
167
  secret: typeof secret;
@@ -321,11 +321,11 @@ declare namespace CodeceptJS {
321
321
  * ```js
322
322
  * I.removeApp('appName', 'com.example.android.apis');
323
323
  * ```
324
- * @param bundleId - String ID of bundle
325
324
  *
326
325
  * Appium: support only Android
326
+ * @param [bundleId] - ID of bundle
327
327
  */
328
- removeApp(appId: string, bundleId: string): void;
328
+ removeApp(appId: string, bundleId?: string): void;
329
329
  /**
330
330
  * Check current activity on an Android device.
331
331
  *
@@ -522,11 +522,12 @@ declare namespace CodeceptJS {
522
522
  * // or by pressing key
523
523
  * I.hideDeviceKeyboard('pressKey', 'Done');
524
524
  * ```
525
- * @param strategy - desired strategy to close keyboard (‘tapOutside’ or ‘pressKey’)
526
525
  *
527
526
  * Appium: support Android and iOS
527
+ * @param [strategy] - Desired strategy to close keyboard (‘tapOutside’ or ‘pressKey’)
528
+ * @param [key] - Optional key
528
529
  */
529
- hideDeviceKeyboard(strategy: 'tapOutside' | 'pressKey'): void;
530
+ hideDeviceKeyboard(strategy?: 'tapOutside' | 'pressKey', key?: string): void;
530
531
  /**
531
532
  * Send a key event to the device.
532
533
  * List of keys: https://developer.android.com/reference/android/view/KeyEvent.html
@@ -682,8 +683,9 @@ declare namespace CodeceptJS {
682
683
  * ```
683
684
  *
684
685
  * Appium: support Android and iOS
686
+ * @param actions - Array of touch actions
685
687
  */
686
- touchPerform(): void;
688
+ touchPerform(actions: any[]): void;
687
689
  /**
688
690
  * Pulls a file from the device.
689
691
  *
@@ -886,6 +888,45 @@ declare namespace CodeceptJS {
886
888
  * @returns attribute value
887
889
  */
888
890
  grabTextFrom(locator: CodeceptJS.LocatorOrString): Promise<string>;
891
+ /**
892
+ * Grab number of visible elements by locator.
893
+ * Resumes test execution, so **should be used inside async function with `await`** operator.
894
+ *
895
+ * ```js
896
+ * let numOfElements = await I.grabNumberOfVisibleElements('p');
897
+ * ```
898
+ * @param locator - located by CSS|XPath|strict locator.
899
+ * @returns number of visible elements
900
+ */
901
+ grabNumberOfVisibleElements(locator: CodeceptJS.LocatorOrString): Promise<number>;
902
+ /**
903
+ * Can be used for apps only with several values ("contentDescription", "text", "className", "resourceId")
904
+ *
905
+ * Retrieves an attribute from an element located by CSS or XPath and returns it to test.
906
+ * Resumes test execution, so **should be used inside async with `await`** operator.
907
+ * If more than one element is found - attribute of first element is returned.
908
+ *
909
+ * ```js
910
+ * let hint = await I.grabAttributeFrom('#tooltip', 'title');
911
+ * ```
912
+ * @param locator - element located by CSS|XPath|strict locator.
913
+ * @param attr - attribute name.
914
+ * @returns attribute value
915
+ */
916
+ grabAttributeFrom(locator: CodeceptJS.LocatorOrString, attr: string): Promise<string>;
917
+ /**
918
+ * Can be used for apps only with several values ("contentDescription", "text", "className", "resourceId")
919
+ * Retrieves an array of attributes from elements located by CSS or XPath and returns it to test.
920
+ * Resumes test execution, so **should be used inside async with `await`** operator.
921
+ *
922
+ * ```js
923
+ * let hints = await I.grabAttributeFromAll('.tooltip', 'title');
924
+ * ```
925
+ * @param locator - element located by CSS|XPath|strict locator.
926
+ * @param attr - attribute name.
927
+ * @returns attribute value
928
+ */
929
+ grabAttributeFromAll(locator: CodeceptJS.LocatorOrString, attr: string): Promise<string[]>;
889
930
  /**
890
931
  * Retrieves an array of value from a form located by CSS or XPath and returns it to test.
891
932
  * Resumes test execution, so **should be used inside async function with `await`** operator.
@@ -909,6 +950,16 @@ declare namespace CodeceptJS {
909
950
  * @returns attribute value
910
951
  */
911
952
  grabValueFrom(locator: CodeceptJS.LocatorOrString): Promise<string>;
953
+ /**
954
+ * Saves a screenshot to ouput folder (set in codecept.json or codecept.conf.js).
955
+ * Filename is relative to output folder.
956
+ *
957
+ * ```js
958
+ * I.saveScreenshot('debug.png');
959
+ * ```
960
+ * @param fileName - file name to save.
961
+ */
962
+ saveScreenshot(fileName: string): void;
912
963
  /**
913
964
  * Scroll element into viewport.
914
965
  *
@@ -2368,6 +2419,8 @@ declare namespace CodeceptJS {
2368
2419
  * * `restart`: (optional, default: true) - restart browser between tests.
2369
2420
  * * `disableScreenshots`: (optional, default: false) - don't save screenshot on failure.
2370
2421
  * * `emulate`: (optional, default: {}) launch browser in device emulation mode.
2422
+ * * `video`: (optional, default: false) enables video recording for failed tests; videos are saved into `output/videos` folder
2423
+ * * `trace`: (optional, default: false) record [tracing information](https://playwright.dev/docs/trace-viewer) with screenshots and snapshots.
2371
2424
  * * `fullPageScreenshots` (optional, default: false) - make full page screenshots on failure.
2372
2425
  * * `uniqueScreenshotNames`: (optional, default: false) - option to prevent screenshot override if you have scenarios with the same name in different suites.
2373
2426
  * * `keepBrowserState`: (optional, default: false) - keep browser state between tests when `restart` is set to false.
@@ -2384,6 +2437,22 @@ declare namespace CodeceptJS {
2384
2437
  * * `chromium`: (optional) pass additional chromium options
2385
2438
  * * `electron`: (optional) pass additional electron options
2386
2439
  *
2440
+ * #### Video Recording Customization
2441
+ *
2442
+ * By default, video is saved to `output/video` dir. You can customize this path by passing `dir` option to `recordVideo` option.
2443
+ *
2444
+ * * `video`: enables video recording for failed tests; videos are saved into `output/videos` folder
2445
+ * * `keepVideoForPassedTests`: - save videos for passed tests
2446
+ * * `recordVideo`: [additional options for videos customization](https://playwright.dev/docs/next/api/class-browser#browser-new-context)
2447
+ *
2448
+ * #### Trace Recording Customization
2449
+ *
2450
+ * Trace recording provides a complete information on test execution and includes DOM snapshots, screenshots, and network requests logged during run.
2451
+ * Traces will be saved to `output/trace`
2452
+ *
2453
+ * * `trace`: enables trace recording for failed tests; trace are saved into `output/trace` folder
2454
+ * * `keepTraceForPassedTests`: - save trace for passed tests
2455
+ *
2387
2456
  * #### Example #1: Wait for 0 network connections.
2388
2457
  *
2389
2458
  * ```js
@@ -2435,7 +2504,7 @@ declare namespace CodeceptJS {
2435
2504
  * Playwright: {
2436
2505
  * url: "http://localhost",
2437
2506
  * chromium: {
2438
- * browserWSEndpoint: { wsEndpoint: 'ws://localhost:9222/devtools/browser/c5aa6160-b5bc-4d53-bb49-6ecb36cd2e0a' }
2507
+ * browserWSEndpoint: 'ws://localhost:9222/devtools/browser/c5aa6160-b5bc-4d53-bb49-6ecb36cd2e0a'
2439
2508
  * }
2440
2509
  * }
2441
2510
  * }
@@ -3902,6 +3971,29 @@ declare namespace CodeceptJS {
3902
3971
  * @returns Element bounding rectangle
3903
3972
  */
3904
3973
  grabElementBoundingRect(locator: LocatorOrString, elementSize?: string): Promise<DOMRect> | Promise<number>;
3974
+ /**
3975
+ * Mocks network request using [`browserContext.route`](https://playwright.dev/docs/api/class-browsercontext#browser-context-route) of Playwright
3976
+ *
3977
+ * ```js
3978
+ * I.mockRoute(/(\.png$)|(\.jpg$)/, route => route.abort());
3979
+ * ```
3980
+ * This method allows intercepting and mocking requests & responses. [Learn more about it](https://playwright.dev/docs/network#handle-requests)
3981
+ * @param [url] - URL, regex or pattern for to match URL
3982
+ * @param [handler] - a function to process request
3983
+ */
3984
+ mockRoute(url?: string, handler?: (...params: any[]) => any): void;
3985
+ /**
3986
+ * Stops network mocking created by `mockRoute`.
3987
+ *
3988
+ * ```js
3989
+ * I.stopMockingRoute(/(\.png$)|(\.jpg$)/);
3990
+ * I.stopMockingRoute(/(\.png$)|(\.jpg$)/, previouslySetHandler);
3991
+ * ```
3992
+ * If no handler is passed, all mock requests for the rote are disabled.
3993
+ * @param [url] - URL, regex or pattern for to match URL
3994
+ * @param [handler] - a function to process request
3995
+ */
3996
+ stopMockingRoute(url?: string, handler?: (...params: any[]) => any): void;
3905
3997
  }
3906
3998
  /**
3907
3999
  * This helper works the same as MockRequest helper. It has been included for backwards compatibility
@@ -5294,6 +5386,7 @@ declare namespace CodeceptJS {
5294
5386
  * }
5295
5387
  * }
5296
5388
  * ```
5389
+ * > Note: When connecting to remote browser `show` and specific `chrome` options (e.g. `headless` or `devtools`) are ignored.
5297
5390
  *
5298
5391
  * #### Example #5: Target URL with provided basic authentication
5299
5392
  *
@@ -5308,10 +5401,25 @@ declare namespace CodeceptJS {
5308
5401
  * }
5309
5402
  * }
5310
5403
  * ```
5404
+ * #### Troubleshooting
5311
5405
  *
5406
+ * Error Message: `No usable sandbox!`
5407
+ *
5408
+ * When running Puppeteer on CI try to disable sandbox if you see that message
5409
+ *
5410
+ * ```
5411
+ * helpers: {
5412
+ * Puppeteer: {
5413
+ * url: 'http://localhost',
5414
+ * show: false,
5415
+ * chrome: {
5416
+ * args: ['--no-sandbox', '--disable-setuid-sandbox']
5417
+ * }
5418
+ * },
5419
+ * }
5420
+ * ```
5312
5421
  *
5313
5422
  *
5314
- * Note: When connecting to remote browser `show` and specific `chrome` options (e.g. `headless` or `devtools`) are ignored.
5315
5423
  *
5316
5424
  * ## Access From Helpers
5317
5425
  *
@@ -6850,8 +6958,9 @@ declare namespace CodeceptJS {
6850
6958
  class REST {
6851
6959
  /**
6852
6960
  * Executes axios request
6961
+ * @returns response
6853
6962
  */
6854
- _executeRequest(request: any): void;
6963
+ _executeRequest(request: any): Promise<any>;
6855
6964
  /**
6856
6965
  * Generates url based on format sent (takes endpoint + url if latter lacks 'http')
6857
6966
  */
@@ -6871,8 +6980,9 @@ declare namespace CodeceptJS {
6871
6980
  * I.sendGetRequest('/api/users.json');
6872
6981
  * ```
6873
6982
  * @param [headers = {}] - the headers object to be sent. By default it is sent as an empty object
6983
+ * @returns response
6874
6984
  */
6875
- sendGetRequest(url: any, headers?: any): void;
6985
+ sendGetRequest(url: any, headers?: any): Promise<any>;
6876
6986
  /**
6877
6987
  * Sends POST request to API.
6878
6988
  *
@@ -6885,8 +6995,9 @@ declare namespace CodeceptJS {
6885
6995
  * ```
6886
6996
  * @param [payload = {}] - the payload to be sent. By default it is sent as an empty object
6887
6997
  * @param [headers = {}] - the headers object to be sent. By default it is sent as an empty object
6998
+ * @returns response
6888
6999
  */
6889
- sendPostRequest(url: any, payload?: any, headers?: any): void;
7000
+ sendPostRequest(url: any, payload?: any, headers?: any): Promise<any>;
6890
7001
  /**
6891
7002
  * Sends PATCH request to API.
6892
7003
  *
@@ -6899,8 +7010,9 @@ declare namespace CodeceptJS {
6899
7010
  * ```
6900
7011
  * @param [payload = {}] - the payload to be sent. By default it is sent as an empty object
6901
7012
  * @param [headers = {}] - the headers object to be sent. By default it is sent as an empty object
7013
+ * @returns response
6902
7014
  */
6903
- sendPatchRequest(url: string, payload?: any, headers?: any): void;
7015
+ sendPatchRequest(url: string, payload?: any, headers?: any): Promise<any>;
6904
7016
  /**
6905
7017
  * Sends PUT request to API.
6906
7018
  *
@@ -6913,8 +7025,9 @@ declare namespace CodeceptJS {
6913
7025
  * ```
6914
7026
  * @param [payload = {}] - the payload to be sent. By default it is sent as an empty object
6915
7027
  * @param [headers = {}] - the headers object to be sent. By default it is sent as an empty object
7028
+ * @returns response
6916
7029
  */
6917
- sendPutRequest(url: string, payload?: any, headers?: any): void;
7030
+ sendPutRequest(url: string, payload?: any, headers?: any): Promise<any>;
6918
7031
  /**
6919
7032
  * Sends DELETE request to API.
6920
7033
  *
@@ -6922,8 +7035,9 @@ declare namespace CodeceptJS {
6922
7035
  * I.sendDeleteRequest('/api/users/1');
6923
7036
  * ```
6924
7037
  * @param [headers = {}] - the headers object to be sent. By default it is sent as an empty object
7038
+ * @returns response
6925
7039
  */
6926
- sendDeleteRequest(url: any, headers?: any): void;
7040
+ sendDeleteRequest(url: any, headers?: any): Promise<any>;
6927
7041
  }
6928
7042
  /**
6929
7043
  * SeleniumWebdriver helper is based on the official [Selenium Webdriver JS](https://www.npmjs.com/package/selenium-webdriver)
@@ -8656,8 +8770,6 @@ declare namespace CodeceptJS {
8656
8770
  * @param locator - element located by CSS|XPath|strict locator.
8657
8771
  * @param attr - attribute name.
8658
8772
  * @returns attribute value
8659
- *
8660
- * Appium: can be used for apps only with several values ("contentDescription", "text", "className", "resourceId")
8661
8773
  */
8662
8774
  grabAttributeFromAll(locator: CodeceptJS.LocatorOrString, attr: string): Promise<string[]>;
8663
8775
  /**
@@ -8671,8 +8783,6 @@ declare namespace CodeceptJS {
8671
8783
  * @param locator - element located by CSS|XPath|strict locator.
8672
8784
  * @param attr - attribute name.
8673
8785
  * @returns attribute value
8674
- *
8675
- * Appium: can be used for apps only with several values ("contentDescription", "text", "className", "resourceId")
8676
8786
  */
8677
8787
  grabAttributeFrom(locator: CodeceptJS.LocatorOrString, attr: string): Promise<string>;
8678
8788
  /**
@@ -9695,7 +9805,7 @@ declare namespace CodeceptJS {
9695
9805
  * add print comment method`
9696
9806
  */
9697
9807
  say(msg: string, color?: string): Promise<any> | undefined;
9698
- retry(opts: any): this;
9808
+ retry(opts?: any): this;
9699
9809
  }
9700
9810
  /**
9701
9811
  * Create CodeceptJS runner.
@@ -9839,6 +9949,34 @@ declare namespace CodeceptJS {
9839
9949
  xadd(array: any[]): void;
9840
9950
  filter(func: (...params: any[]) => any): void;
9841
9951
  }
9952
+ /**
9953
+ * DataTableArgument class to store the Cucumber data table from
9954
+ * a step as an object with methods that can be used to access the data.
9955
+ */
9956
+ class DataTableArgument {
9957
+ constructor(gherkinDataTable: any);
9958
+ /**
9959
+ * Returns the table as a 2-D array
9960
+ */
9961
+ raw(): string[][];
9962
+ /**
9963
+ * Returns the table as a 2-D array, without the first row
9964
+ */
9965
+ rows(): string[][];
9966
+ /**
9967
+ * Returns an array of objects where each row is converted to an object (column header is the key)
9968
+ */
9969
+ hashes(): any[];
9970
+ /**
9971
+ * Returns an object where each row corresponds to an entry
9972
+ * (first column is the key, second column is the value)
9973
+ */
9974
+ rowsHash(): Record<string, string>;
9975
+ /**
9976
+ * Transposed the data
9977
+ */
9978
+ transpose(): void;
9979
+ }
9842
9980
  namespace event {
9843
9981
  const dispatcher: NodeJS.EventEmitter;
9844
9982
  const test: {
@@ -9935,6 +10073,7 @@ declare namespace CodeceptJS {
9935
10073
  var pause: typeof CodeceptJS.pause;
9936
10074
  var within: typeof CodeceptJS.within;
9937
10075
  var dataTable: typeof CodeceptJS.DataTable;
10076
+ var dataTableArgument: typeof CodeceptJS.DataTableArgument;
9938
10077
  var store: typeof CodeceptJS.store;
9939
10078
  var locator: typeof CodeceptJS.Locator;
9940
10079
  }
@@ -10020,6 +10159,7 @@ declare namespace CodeceptJS {
10020
10159
  isCustom(): boolean;
10021
10160
  isStrict(): boolean;
10022
10161
  isAccessibilityId(): boolean;
10162
+ isBasic(): boolean;
10023
10163
  toXPath(): string;
10024
10164
  or(locator: CodeceptJS.LocatorOrString): Locator;
10025
10165
  find(locator: CodeceptJS.LocatorOrString): Locator;