codeceptjs 3.6.0-beta.1.ai-healers → 3.6.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 (130) hide show
  1. package/README.md +2 -2
  2. package/bin/codecept.js +2 -1
  3. package/docs/webapi/dontSeeTraffic.mustache +13 -0
  4. package/docs/webapi/flushNetworkTraffics.mustache +5 -0
  5. package/docs/webapi/grabRecordedNetworkTraffics.mustache +10 -0
  6. package/docs/webapi/seeTraffic.mustache +36 -0
  7. package/docs/webapi/startRecordingTraffic.mustache +8 -0
  8. package/docs/webapi/startRecordingWebSocketMessages.mustache +8 -0
  9. package/docs/webapi/stopRecordingTraffic.mustache +5 -0
  10. package/docs/webapi/stopRecordingWebSocketMessages.mustache +7 -0
  11. package/docs/webapi/waitForCookie.mustache +9 -0
  12. package/lib/actor.js +6 -3
  13. package/lib/command/dryRun.js +44 -13
  14. package/lib/helper/Appium.js +36 -12
  15. package/lib/helper/Expect.js +11 -8
  16. package/lib/helper/JSONResponse.js +8 -8
  17. package/lib/helper/MockServer.js +221 -0
  18. package/lib/helper/Playwright.js +107 -371
  19. package/lib/helper/Puppeteer.js +404 -71
  20. package/lib/helper/REST.js +4 -1
  21. package/lib/helper/WebDriver.js +189 -13
  22. package/lib/helper/errors/ElementAssertion.js +38 -0
  23. package/lib/helper/extras/PlaywrightReactVueLocator.js +6 -1
  24. package/lib/helper/network/actions.js +123 -0
  25. package/lib/helper/network/utils.js +187 -0
  26. package/lib/locator.js +36 -5
  27. package/lib/pause.js +4 -9
  28. package/lib/plugin/coverage.js +112 -99
  29. package/lib/step.js +3 -1
  30. package/package.json +49 -38
  31. package/typings/index.d.ts +19 -2
  32. package/typings/promiseBasedTypes.d.ts +505 -41
  33. package/typings/types.d.ts +531 -43
  34. package/docs/advanced.md +0 -351
  35. package/docs/ai.md +0 -365
  36. package/docs/api.md +0 -323
  37. package/docs/basics.md +0 -979
  38. package/docs/bdd.md +0 -539
  39. package/docs/best.md +0 -237
  40. package/docs/books.md +0 -37
  41. package/docs/bootstrap.md +0 -135
  42. package/docs/build/AI.js +0 -124
  43. package/docs/build/ApiDataFactory.js +0 -410
  44. package/docs/build/Appium.js +0 -2027
  45. package/docs/build/Expect.js +0 -422
  46. package/docs/build/FileSystem.js +0 -228
  47. package/docs/build/GraphQL.js +0 -229
  48. package/docs/build/GraphQLDataFactory.js +0 -309
  49. package/docs/build/JSONResponse.js +0 -338
  50. package/docs/build/Mochawesome.js +0 -71
  51. package/docs/build/Nightmare.js +0 -2152
  52. package/docs/build/OpenAI.js +0 -126
  53. package/docs/build/Playwright.js +0 -5110
  54. package/docs/build/Protractor.js +0 -2706
  55. package/docs/build/Puppeteer.js +0 -3905
  56. package/docs/build/REST.js +0 -344
  57. package/docs/build/TestCafe.js +0 -2125
  58. package/docs/build/WebDriver.js +0 -4240
  59. package/docs/changelog.md +0 -2572
  60. package/docs/commands.md +0 -266
  61. package/docs/community-helpers.md +0 -58
  62. package/docs/configuration.md +0 -157
  63. package/docs/continuous-integration.md +0 -22
  64. package/docs/custom-helpers.md +0 -306
  65. package/docs/data.md +0 -379
  66. package/docs/detox.md +0 -235
  67. package/docs/docker.md +0 -136
  68. package/docs/email.md +0 -183
  69. package/docs/examples.md +0 -149
  70. package/docs/heal.md +0 -186
  71. package/docs/helpers/ApiDataFactory.md +0 -266
  72. package/docs/helpers/Appium.md +0 -1374
  73. package/docs/helpers/Detox.md +0 -586
  74. package/docs/helpers/Expect.md +0 -275
  75. package/docs/helpers/FileSystem.md +0 -152
  76. package/docs/helpers/GraphQL.md +0 -151
  77. package/docs/helpers/GraphQLDataFactory.md +0 -226
  78. package/docs/helpers/JSONResponse.md +0 -254
  79. package/docs/helpers/Mochawesome.md +0 -8
  80. package/docs/helpers/MockRequest.md +0 -377
  81. package/docs/helpers/Nightmare.md +0 -1305
  82. package/docs/helpers/OpenAI.md +0 -70
  83. package/docs/helpers/Playwright.md +0 -2759
  84. package/docs/helpers/Polly.md +0 -44
  85. package/docs/helpers/Protractor.md +0 -1769
  86. package/docs/helpers/Puppeteer-firefox.md +0 -86
  87. package/docs/helpers/Puppeteer.md +0 -2317
  88. package/docs/helpers/REST.md +0 -218
  89. package/docs/helpers/TestCafe.md +0 -1321
  90. package/docs/helpers/WebDriver.md +0 -2547
  91. package/docs/hooks.md +0 -340
  92. package/docs/index.md +0 -111
  93. package/docs/installation.md +0 -75
  94. package/docs/internal-api.md +0 -266
  95. package/docs/locators.md +0 -339
  96. package/docs/mobile-react-native-locators.md +0 -67
  97. package/docs/mobile.md +0 -338
  98. package/docs/pageobjects.md +0 -291
  99. package/docs/parallel.md +0 -400
  100. package/docs/playwright.md +0 -632
  101. package/docs/plugins.md +0 -1247
  102. package/docs/puppeteer.md +0 -316
  103. package/docs/quickstart.md +0 -162
  104. package/docs/react.md +0 -70
  105. package/docs/reports.md +0 -392
  106. package/docs/secrets.md +0 -36
  107. package/docs/shadow.md +0 -68
  108. package/docs/shared/keys.mustache +0 -31
  109. package/docs/shared/react.mustache +0 -1
  110. package/docs/testcafe.md +0 -174
  111. package/docs/translation.md +0 -247
  112. package/docs/tutorial.md +0 -271
  113. package/docs/typescript.md +0 -180
  114. package/docs/ui.md +0 -59
  115. package/docs/videos.md +0 -28
  116. package/docs/visual.md +0 -202
  117. package/docs/vue.md +0 -143
  118. package/docs/webdriver.md +0 -701
  119. package/docs/wiki/Books-&-Posts.md +0 -27
  120. package/docs/wiki/Community-Helpers-&-Plugins.md +0 -53
  121. package/docs/wiki/Converting-Playwright-to-Istanbul-Coverage.md +0 -61
  122. package/docs/wiki/Examples.md +0 -145
  123. package/docs/wiki/Google-Summer-of-Code-(GSoC)-2020.md +0 -68
  124. package/docs/wiki/Home.md +0 -16
  125. package/docs/wiki/Migration-to-Appium-v2---CodeceptJS.md +0 -83
  126. package/docs/wiki/Release-Process.md +0 -24
  127. package/docs/wiki/Roadmap.md +0 -23
  128. package/docs/wiki/Tests.md +0 -1393
  129. package/docs/wiki/Upgrading-to-CodeceptJS-3.md +0 -153
  130. package/docs/wiki/Videos.md +0 -19
package/lib/locator.js CHANGED
@@ -1,9 +1,9 @@
1
- const cssToXPath = require('csstoxpath');
1
+ let cssToXPath;
2
2
  const { sprintf } = require('sprintf-js');
3
3
 
4
4
  const { xpathLocator } = require('./utils');
5
5
 
6
- const locatorTypes = ['css', 'by', 'xpath', 'id', 'name', 'fuzzy', 'frame', 'shadow'];
6
+ const locatorTypes = ['css', 'by', 'xpath', 'id', 'name', 'fuzzy', 'frame', 'shadow', 'pw'];
7
7
  /** @class */
8
8
  class Locator {
9
9
  /**
@@ -51,6 +51,9 @@ class Locator {
51
51
  if (isShadow(locator)) {
52
52
  this.type = 'shadow';
53
53
  }
54
+ if (isPlaywrightLocator(locator)) {
55
+ this.type = 'pw';
56
+ }
54
57
 
55
58
  Locator.filters.forEach(f => f(locator, this));
56
59
  }
@@ -71,6 +74,8 @@ class Locator {
71
74
  return this.value;
72
75
  case 'shadow':
73
76
  return { shadow: this.value };
77
+ case 'pw':
78
+ return { pw: this.value };
74
79
  }
75
80
  return this.value;
76
81
  }
@@ -115,6 +120,13 @@ class Locator {
115
120
  return this.type === 'css';
116
121
  }
117
122
 
123
+ /**
124
+ * @returns {boolean}
125
+ */
126
+ isPlaywrightLocator() {
127
+ return this.type === 'pw';
128
+ }
129
+
118
130
  /**
119
131
  * @returns {boolean}
120
132
  */
@@ -162,8 +174,17 @@ class Locator {
162
174
  * @returns {string}
163
175
  */
164
176
  toXPath(pseudoSelector = '') {
177
+ const locator = `${this.value}${pseudoSelector}`;
178
+ const limitation = [':nth-of-type', ':first-of-type', ':last-of-type', ':nth-last-child', ':nth-last-of-type', ':checked', ':disabled', ':enabled', ':required', ':lang', ':nth-child'];
179
+
180
+ if (limitation.some(item => locator.includes(item))) {
181
+ cssToXPath = require('css-to-xpath');
182
+ } else {
183
+ cssToXPath = require('csstoxpath');
184
+ }
185
+
165
186
  if (this.isXPath()) return this.value;
166
- if (this.isCSS()) return cssToXPath(`${this.value}${pseudoSelector}`);
187
+ if (this.isCSS()) return cssToXPath(locator);
167
188
 
168
189
  throw new Error('Can\'t be converted to XPath');
169
190
  }
@@ -250,7 +271,7 @@ class Locator {
250
271
  */
251
272
  withText(text) {
252
273
  text = xpathLocator.literal(text);
253
- const xpath = this.toXPath(`:text-contains-case(${text})`);
274
+ const xpath = sprintf('%s[%s]', this.toXPath(), `contains(., ${text})`);
254
275
  return new Locator({ xpath });
255
276
  }
256
277
 
@@ -261,7 +282,7 @@ class Locator {
261
282
  */
262
283
  withTextEquals(text) {
263
284
  text = xpathLocator.literal(text);
264
- const xpath = this.toXPath(`:text-case(${text})`);
285
+ const xpath = sprintf('%s[%s]', this.toXPath(), `.= ${text}`);
265
286
  return new Locator({ xpath });
266
287
  }
267
288
 
@@ -513,6 +534,16 @@ function removePrefix(xpath) {
513
534
  .replace(/^(\.|\/)+/, '');
514
535
  }
515
536
 
537
+ /**
538
+ * @private
539
+ * check if the locator is a Playwright locator
540
+ * @param {string} locator
541
+ * @returns {boolean}
542
+ */
543
+ function isPlaywrightLocator(locator) {
544
+ return locator.includes('_react') || locator.includes('_vue') || locator.includes('data-testid');
545
+ }
546
+
516
547
  /**
517
548
  * @private
518
549
  * @param {CodeceptJS.LocatorOrString} locator
package/lib/pause.js CHANGED
@@ -6,7 +6,7 @@ const debug = require('debug')('codeceptjs:pause');
6
6
  const container = require('./container');
7
7
  const history = require('./history');
8
8
  const store = require('./store');
9
- const AiAssistant = require('./ai');
9
+ const aiAssistant = require('./ai');
10
10
  const recorder = require('./recorder');
11
11
  const event = require('./event');
12
12
  const output = require('./output');
@@ -18,7 +18,6 @@ let nextStep;
18
18
  let finish;
19
19
  let next;
20
20
  let registeredVariables = {};
21
- let aiAssistant;
22
21
  /**
23
22
  * Pauses test execution and starts interactive shell
24
23
  * @param {Object<string, *>} [passedObject]
@@ -44,8 +43,6 @@ function pauseSession(passedObject = {}) {
44
43
  let vars = Object.keys(registeredVariables).join(', ');
45
44
  if (vars) vars = `(vars: ${vars})`;
46
45
 
47
- aiAssistant = AiAssistant.getInstance();
48
-
49
46
  output.print(colors.yellow(' Interactive shell started'));
50
47
  output.print(colors.yellow(' Use JavaScript syntax to try steps in action'));
51
48
  output.print(colors.yellow(` - Press ${colors.bold('ENTER')} to run the next step`));
@@ -54,11 +51,9 @@ function pauseSession(passedObject = {}) {
54
51
  output.print(colors.yellow(` - Prefix ${colors.bold('=>')} to run js commands ${colors.bold(vars)}`));
55
52
 
56
53
  if (aiAssistant.isEnabled) {
57
- output.print(colors.blue(` ${colors.bold('OpenAI is enabled! (experimental)')} Write what you want and make OpenAI run it`));
58
- output.print(colors.blue(' Please note, only HTML fragments with interactive elements are sent to OpenAI'));
54
+ output.print(colors.blue(` ${colors.bold('AI is enabled! (experimental)')} Write what you want and make AI run it`));
55
+ output.print(colors.blue(' Please note, only HTML fragments with interactive elements are sent to AI provider'));
59
56
  output.print(colors.blue(' Ideas: ask it to fill forms for you or to click'));
60
- } else {
61
- output.print(colors.blue(` Enable OpenAI assistant by setting ${colors.bold('OPENAI_API_KEY')} env variable`));
62
57
  }
63
58
  }
64
59
  rl = readline.createInterface(process.stdin, process.stdout, completer);
@@ -125,7 +120,7 @@ async function parseInput(cmd) {
125
120
  } finally {
126
121
  output.level(currentOutputLevel);
127
122
  }
128
- // aiAssistant.mockResponse("```js\nI.click('Sign in');\n```");
123
+
129
124
  const spinner = ora("Processing OpenAI request...").start();
130
125
  cmd = await aiAssistant.writeSteps(cmd);
131
126
  spinner.stop();
@@ -1,44 +1,67 @@
1
1
  const debugModule = require('debug');
2
- const fs = require('fs');
3
- const path = require('path');
4
-
2
+ const { CoverageReport } = require('monocart-coverage-reports');
5
3
  const Container = require('../container');
6
4
  const recorder = require('../recorder');
7
5
  const event = require('../event');
8
6
  const output = require('../output');
9
- const { clearString } = require('../utils');
7
+ const { deepMerge } = require('../utils');
10
8
 
11
9
  const defaultConfig = {
12
- coverageDir: 'output/coverage',
13
- uniqueFileName: true,
10
+ name: 'CodeceptJS Coverage Report',
11
+ outputDir: 'output/coverage',
14
12
  };
15
13
 
16
14
  const supportedHelpers = ['Puppeteer', 'Playwright'];
17
15
 
18
- function buildFileName(test, uniqueFileName) {
19
- let fileName = clearString(test.title);
20
-
21
- // This prevent data driven to be included in the failed screenshot file name
22
- if (fileName.indexOf('{') !== -1) {
23
- fileName = fileName.substr(0, fileName.indexOf('{') - 3).trim();
24
- }
25
-
26
- if (test.ctx && test.ctx.test && test.ctx.test.type === 'hook') {
27
- fileName = clearString(`${test.title}_${test.ctx.test.title}`);
28
- }
29
-
30
- if (uniqueFileName) {
31
- const uuid = test.uuid
32
- || test.ctx.test.uuid
33
- || Math.floor(new Date().getTime() / 1000);
34
-
35
- fileName = `${fileName.substring(0, 10)}_${uuid}.coverage.json`;
36
- } else {
37
- fileName = `${fileName}.coverage.json`;
38
- }
39
-
40
- return fileName;
41
- }
16
+ const v8CoverageHelpers = {
17
+ Playwright: {
18
+ startCoverage: async (page) => {
19
+ await Promise.all([
20
+ page.coverage.startJSCoverage({
21
+ resetOnNavigation: false,
22
+ }),
23
+ page.coverage.startCSSCoverage({
24
+ resetOnNavigation: false,
25
+ }),
26
+ ]);
27
+ },
28
+ takeCoverage: async (page, coverageReport) => {
29
+ const [jsCoverage, cssCoverage] = await Promise.all([
30
+ page.coverage.stopJSCoverage(),
31
+ page.coverage.stopCSSCoverage(),
32
+ ]);
33
+ const coverageList = [...jsCoverage, ...cssCoverage];
34
+ await coverageReport.add(coverageList);
35
+ },
36
+ },
37
+ Puppeteer: {
38
+ startCoverage: async (page) => {
39
+ await Promise.all([
40
+ page.coverage.startJSCoverage({
41
+ resetOnNavigation: false,
42
+ includeRawScriptCoverage: true,
43
+ }),
44
+ page.coverage.startCSSCoverage({
45
+ resetOnNavigation: false,
46
+ }),
47
+ ]);
48
+ },
49
+ takeCoverage: async (page, coverageReport) => {
50
+ const [jsCoverage, cssCoverage] = await Promise.all([
51
+ page.coverage.stopJSCoverage(),
52
+ page.coverage.stopCSSCoverage(),
53
+ ]);
54
+ // to raw V8 script coverage
55
+ const coverageList = [...jsCoverage.map((it) => {
56
+ return {
57
+ source: it.text,
58
+ ...it.rawScriptCoverage,
59
+ };
60
+ }), ...cssCoverage];
61
+ await coverageReport.add(coverageList);
62
+ },
63
+ },
64
+ };
42
65
 
43
66
  /**
44
67
  * Dumps code coverage from Playwright/Puppeteer after every test.
@@ -49,94 +72,84 @@ function buildFileName(test, uniqueFileName) {
49
72
  * ```js
50
73
  * plugins: {
51
74
  * coverage: {
52
- * enabled: true
75
+ * enabled: true,
76
+ * debug: true,
77
+ * name: 'CodeceptJS Coverage Report',
78
+ * outputDir: 'output/coverage'
53
79
  * }
54
80
  * }
55
81
  * ```
56
82
  *
57
- * Possible config options:
83
+ * Possible config options, More could be found at [monocart-coverage-reports](https://github.com/cenfun/monocart-coverage-reports?tab=readme-ov-file#default-options)
84
+ *
85
+ * * `debug`: debug info. By default, false.
86
+ * * `name`: coverage report name.
87
+ * * `outputDir`: path to coverage report.
88
+ * * `sourceFilter`: filter the source files.
89
+ * * `sourcePath`: option to resolve a custom path.
58
90
  *
59
- * * `coverageDir`: directory to dump coverage files
60
- * * `uniqueFileName`: generate a unique filename by adding uuid
61
91
  */
62
92
  module.exports = function (config) {
93
+ config = deepMerge(defaultConfig, config);
94
+
95
+ if (config.debug) config.logging = 'debug';
96
+
63
97
  const helpers = Container.helpers();
64
98
  let coverageRunning = false;
65
- let helper;
66
99
 
67
- let debug;
68
- for (const helperName of supportedHelpers) {
69
- if (Object.keys(helpers).indexOf(helperName) > -1) {
70
- helper = helpers[helperName];
71
- debug = debugModule(`codeceptjs:plugin:${helperName.toLowerCase()}Coverage`);
72
- }
100
+ const v8Names = Object.keys(v8CoverageHelpers);
101
+ const helperName = Object.keys(helpers).find((it) => v8Names.includes(it));
102
+ if (!helperName) {
103
+ console.error(`Coverage is only supported in ${supportedHelpers.join(' or ')}`);
104
+ // no helpers for screenshot
105
+ return;
73
106
  }
74
107
 
75
- if (!helper) {
76
- console.error('Coverage is only supported in Puppeteer, Playwright');
77
- return; // no helpers for screenshot
78
- }
108
+ config.name = `${config.name} - in ${helperName}`;
109
+ const debug = debugModule(`codeceptjs:plugin:${helperName.toLowerCase()}Coverage`);
110
+
111
+ const helper = helpers[helperName];
112
+ const v8Helper = v8CoverageHelpers[helperName];
79
113
 
80
- const options = Object.assign(defaultConfig, helper.options, config);
114
+ const coverageOptions = {
115
+ ...config,
116
+ };
117
+ const coverageReport = new CoverageReport(coverageOptions);
118
+ coverageReport.cleanCache();
81
119
 
82
- event.dispatcher.on(event.all.before, async () => {
83
- output.debug('*** Collecting coverage for tests ****');
120
+ event.dispatcher.on(event.all.after, async () => {
121
+ output.print(`writing ${coverageOptions.outputDir}`);
122
+ await coverageReport.generate();
84
123
  });
85
124
 
86
- // Hack! we're going to try to "start" coverage before each step because this is
125
+ // we're going to try to "start" coverage before each step because this is
87
126
  // when the browser is already up and is ready to start coverage.
88
- event.dispatcher.on(event.step.before, async () => {
89
- recorder.add(
90
- 'starting coverage',
91
- async () => {
92
- try {
93
- if (!coverageRunning && helper.page && helper.page.coverage) {
94
- debug('--> starting coverage <--');
95
- coverageRunning = true;
96
- await helper.page.coverage.startJSCoverage();
97
- }
98
- } catch (err) {
99
- console.error(err);
100
- }
101
- },
102
- true,
103
- );
127
+ event.dispatcher.on(event.step.before, () => {
128
+ recorder.add('start coverage', async () => {
129
+ if (coverageRunning) {
130
+ return;
131
+ }
132
+ if (!helper.page || !helper.page.coverage) {
133
+ return;
134
+ }
135
+ coverageRunning = true;
136
+ debug('--> starting coverage <--');
137
+ await v8Helper.startCoverage(helper.page);
138
+ }, true);
104
139
  });
105
140
 
106
141
  // Save coverage data after every test run
107
- event.dispatcher.on(event.test.after, async (test) => {
108
- recorder.add(
109
- 'saving coverage',
110
- async () => {
111
- try {
112
- if (coverageRunning && helper.page && helper.page.coverage) {
113
- debug('--> stopping coverage <--');
114
- coverageRunning = false;
115
- const coverage = await helper.page.coverage.stopJSCoverage();
116
-
117
- const coverageDir = path.resolve(
118
- process.cwd(),
119
- options.coverageDir,
120
- );
121
-
122
- // Checking if coverageDir already exists, if not, create new one
123
-
124
- if (!fs.existsSync(coverageDir)) {
125
- fs.mkdirSync(coverageDir, { recursive: true });
126
- }
127
-
128
- const coveragePath = path.resolve(
129
- coverageDir,
130
- buildFileName(test, options.uniqueFileName),
131
- );
132
- output.print(`writing ${coveragePath}`);
133
- fs.writeFileSync(coveragePath, JSON.stringify(coverage));
134
- }
135
- } catch (err) {
136
- console.error(err);
137
- }
138
- },
139
- true,
140
- );
142
+ event.dispatcher.on(event.test.after, (test) => {
143
+ recorder.add('take coverage', async () => {
144
+ if (!coverageRunning) {
145
+ return;
146
+ }
147
+ if (!helper.page || !helper.page.coverage) {
148
+ return;
149
+ }
150
+ coverageRunning = false;
151
+ debug('--> stopping coverage <--');
152
+ await v8Helper.takeCoverage(helper.page, coverageReport);
153
+ }, true);
141
154
  });
142
155
  };
package/lib/step.js CHANGED
@@ -119,7 +119,9 @@ class Step {
119
119
  }
120
120
  let result;
121
121
  try {
122
- result = this.helper[this.helperMethod].apply(this.helper, this.args);
122
+ if (this.helperMethod !== 'say') {
123
+ result = this.helper[this.helperMethod].apply(this.helper, this.args);
124
+ }
123
125
  this.setStatus('success');
124
126
  } catch (err) {
125
127
  this.setStatus('failed');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeceptjs",
3
- "version": "3.6.0-beta.1.ai-healers",
3
+ "version": "3.6.1",
4
4
  "description": "Supercharged End 2 End Testing Framework for NodeJS",
5
5
  "keywords": [
6
6
  "acceptance",
@@ -23,13 +23,13 @@
23
23
  },
24
24
  "files": [
25
25
  "bin",
26
- "docs",
27
26
  "lib",
28
27
  "translations",
29
- "typings/**/*.d.ts"
28
+ "typings/**/*.d.ts",
29
+ "docs/webapi/**"
30
30
  ],
31
31
  "main": "lib/index.js",
32
- "typings": "typings/index.d.ts",
32
+ "types": "typings/index.d.ts",
33
33
  "bin": {
34
34
  "codeceptjs": "./bin/codecept.js"
35
35
  },
@@ -56,54 +56,59 @@
56
56
  "test:unit:webbapi:webDriver:devtools": "mocha test/helper/WebDriver_devtools_test.js --exit",
57
57
  "test:unit:webbapi:testCafe": "mocha test/helper/TestCafe_test.js",
58
58
  "test:unit:expect": "mocha test/helper/Expect_test.js",
59
+ "test:unit:mockServer": "mocha test/helper/MockServer_test.js",
59
60
  "test:plugin": "mocha test/plugin/plugin_test.js",
60
61
  "def": "./runok.js def",
61
62
  "dev:graphql": "node test/data/graphql/index.js",
62
63
  "publish:site": "./runok.js publish:site",
63
64
  "update-contributor-faces": "./runok.js contributor:faces",
64
- "dtslint": "dtslint typings --localTs './node_modules/typescript/lib'",
65
+ "types-fix": "node typings/fixDefFiles.js",
66
+ "dtslint": "npm run types-fix && tsd",
65
67
  "prepare": "husky install",
66
68
  "prepare-release": "./runok.js versioning && ./runok.js get:commit-log"
67
69
  },
68
70
  "dependencies": {
69
- "@codeceptjs/configure": "0.10.0",
70
- "@codeceptjs/helper": "2.0.1",
71
+ "@codeceptjs/configure": "1.0.1",
72
+ "@codeceptjs/helper": "2.0.4",
71
73
  "@cucumber/cucumber-expressions": "17",
72
74
  "@cucumber/gherkin": "26",
73
- "@cucumber/messages": "24.0.1",
75
+ "@cucumber/messages": "24.1.0",
74
76
  "@xmldom/xmldom": "0.8.10",
75
- "acorn": "8.11.2",
77
+ "acorn": "8.11.3",
76
78
  "arrify": "2.0.1",
77
- "axios": "1.6.3",
78
- "chai": "4.3.8",
79
+ "axios": "1.6.7",
80
+ "chai": "5.1.0",
79
81
  "chai-deep-match": "1.2.1",
80
- "chai-exclude": "^2.1.0",
81
- "chai-json-schema": "^1.5.1",
82
- "chai-json-schema-ajv": "^5.2.4",
83
- "chai-match-pattern": "^1.3.0",
84
- "chai-string": "^1.5.0",
82
+ "chai-exclude": "2.1.0",
83
+ "chai-json-schema": "1.5.1",
84
+ "chai-json-schema-ajv": "5.2.4",
85
+ "chai-match-pattern": "1.3.0",
86
+ "chai-string": "1.5.0",
85
87
  "chalk": "4.1.2",
86
88
  "commander": "11.1.0",
87
89
  "cross-spawn": "7.0.3",
90
+ "css-to-xpath": "0.1.0",
88
91
  "csstoxpath": "1.6.0",
89
- "devtools": "8.27.2",
90
- "envinfo": "7.11.0",
92
+ "devtools": "8.33.1",
93
+ "envinfo": "7.11.1",
91
94
  "escape-string-regexp": "4.0.0",
92
95
  "figures": "3.2.0",
93
96
  "fn-args": "4.0.0",
94
97
  "fs-extra": "11.2.0",
95
98
  "glob": "6.0.1",
96
- "html-minifier-terser": "^7.2.0",
99
+ "html-minifier-terser": "7.2.0",
97
100
  "inquirer": "6.5.2",
98
- "joi": "17.11.0",
99
- "js-beautify": "1.14.11",
101
+ "joi": "17.12.2",
102
+ "js-beautify": "1.15.1",
100
103
  "lodash.clonedeep": "4.5.0",
101
104
  "lodash.merge": "4.6.2",
102
105
  "mkdirp": "1.0.4",
103
- "mocha": "10.2.0",
106
+ "mocha": "10.3.0",
107
+ "monocart-coverage-reports": "2.7.4",
104
108
  "ms": "2.1.3",
105
109
  "ora-classic": "5.4.2",
106
- "parse-function": "5.6.4",
110
+ "pactum": "3.6.6",
111
+ "parse-function": "5.6.10",
107
112
  "parse5": "7.1.2",
108
113
  "promise-retry": "1.1.1",
109
114
  "resq": "1.11.0",
@@ -111,55 +116,55 @@
111
116
  "uuid": "9.0"
112
117
  },
113
118
  "optionalDependencies": {
114
- "@codeceptjs/detox-helper": "1.0.2"
119
+ "@codeceptjs/detox-helper": "1.0.5"
115
120
  },
116
121
  "devDependencies": {
117
122
  "@codeceptjs/mock-request": "0.3.1",
118
123
  "@faker-js/faker": "7.6.0",
119
124
  "@pollyjs/adapter-puppeteer": "6.0.6",
120
125
  "@pollyjs/core": "5.1.0",
121
- "@types/chai": "^4.3.7",
126
+ "@types/chai": "4.3.12",
122
127
  "@types/inquirer": "9.0.3",
123
- "@types/node": "20.10.7",
124
- "@wdio/sauce-service": "8.27.0",
128
+ "@types/node": "20.11.30",
129
+ "@wdio/sauce-service": "8.35.1",
125
130
  "@wdio/selenium-standalone-service": "8.3.2",
126
- "@wdio/utils": "8.27.2",
131
+ "@wdio/utils": "8.33.1",
127
132
  "@xmldom/xmldom": "0.8.10",
128
133
  "apollo-server-express": "2.25.3",
129
134
  "chai-as-promised": "7.1.1",
130
135
  "chai-subset": "1.6.0",
131
136
  "contributor-faces": "1.1.0",
132
137
  "documentation": "12.3.0",
133
- "dtslint": "4.2.1",
134
- "electron": "28.0.0",
138
+ "electron": "28.2.1",
135
139
  "eslint": "8.56.0",
136
140
  "eslint-config-airbnb-base": "15.0.0",
137
141
  "eslint-plugin-import": "2.29.1",
138
142
  "eslint-plugin-mocha": "6.3.0",
139
143
  "expect": "29.7.0",
140
- "express": "4.18.2",
144
+ "express": "4.19.2",
141
145
  "graphql": "14.6.0",
142
146
  "husky": "8.0.3",
143
147
  "inquirer-test": "2.0.1",
144
148
  "jsdoc": "3.6.11",
145
149
  "jsdoc-typeof-plugin": "1.0.0",
146
150
  "json-server": "0.10.1",
147
- "playwright": "1.40.1",
148
- "puppeteer": "21.1.1",
151
+ "playwright": "1.43.0",
152
+ "puppeteer": "22.6.3",
149
153
  "qrcode-terminal": "0.12.0",
150
154
  "rosie": "2.1.1",
151
155
  "runok": "0.9.3",
152
156
  "sinon": "17.0.1",
153
157
  "sinon-chai": "3.7.0",
154
- "testcafe": "3.3.0",
158
+ "testcafe": "3.5.0",
155
159
  "ts-morph": "21.0.1",
156
160
  "ts-node": "10.9.2",
161
+ "tsd": "^0.31.0",
157
162
  "tsd-jsdoc": "2.5.0",
158
- "typedoc": "0.25.7",
163
+ "typedoc": "0.25.12",
159
164
  "typedoc-plugin-markdown": "3.17.1",
160
165
  "typescript": "5.3.3",
161
166
  "wdio-docker-service": "1.5.0",
162
- "webdriverio": "8.27.2",
167
+ "webdriverio": "8.35.1",
163
168
  "xml2js": "0.6.2",
164
169
  "xpath": "0.0.34"
165
170
  },
@@ -167,5 +172,11 @@
167
172
  "node": ">=16.0",
168
173
  "npm": ">=5.6.0"
169
174
  },
170
- "es6": true
171
- }
175
+ "es6": true,
176
+ "tsd": {
177
+ "directory": "typings",
178
+ "compilerOptions": {
179
+ "strict": false
180
+ }
181
+ }
182
+ }
@@ -8,6 +8,7 @@
8
8
 
9
9
  declare namespace CodeceptJS {
10
10
  type WithTranslation<T> = T &
11
+ // @ts-ignore
11
12
  import("./utils").Translate<T, Translation.Actions>;
12
13
 
13
14
  type Cookie = {
@@ -382,6 +383,22 @@ declare namespace CodeceptJS {
382
383
  [key: string]: any;
383
384
  };
384
385
 
386
+ type MockRequest = {
387
+ method: 'GET'|'PUT'|'POST'|'PATCH'|'DELETE'|string;
388
+ path: string;
389
+ queryParams?: object;
390
+ }
391
+
392
+ type MockResponse = {
393
+ status: number;
394
+ body?: object;
395
+ }
396
+
397
+ type MockInteraction = {
398
+ request: MockRequest;
399
+ response: MockResponse;
400
+ }
401
+
385
402
  interface PageScrollPosition {
386
403
  x: number;
387
404
  y: number;
@@ -425,8 +442,8 @@ declare namespace CodeceptJS {
425
442
  | { react: string }
426
443
  | { vue: string }
427
444
  | { shadow: string[] }
428
- | { custom: string };
429
-
445
+ | { custom: string }
446
+ | { pw: string };
430
447
  interface CustomLocators {}
431
448
  interface OtherLocators { props?: object }
432
449
  type LocatorOrString =