codeceptjs 3.6.4-beta.2 → 3.6.5-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 (92) hide show
  1. package/bin/codecept.js +84 -63
  2. package/lib/ai.js +47 -1
  3. package/lib/assert/empty.js +19 -19
  4. package/lib/assert/equal.js +32 -30
  5. package/lib/assert/error.js +14 -14
  6. package/lib/assert/include.js +42 -42
  7. package/lib/assert/throws.js +13 -11
  8. package/lib/assert/truth.js +17 -18
  9. package/lib/command/configMigrate.js +57 -52
  10. package/lib/command/definitions.js +88 -88
  11. package/lib/command/dryRun.js +65 -63
  12. package/lib/command/generate.js +191 -181
  13. package/lib/command/info.js +39 -37
  14. package/lib/command/init.js +289 -286
  15. package/lib/command/interactive.js +32 -32
  16. package/lib/command/list.js +26 -26
  17. package/lib/command/run-multiple.js +113 -93
  18. package/lib/command/run-rerun.js +22 -22
  19. package/lib/command/run-workers.js +63 -63
  20. package/lib/command/run.js +24 -26
  21. package/lib/command/utils.js +64 -63
  22. package/lib/data/context.js +60 -60
  23. package/lib/data/dataScenarioConfig.js +47 -47
  24. package/lib/data/dataTableArgument.js +29 -29
  25. package/lib/data/table.js +26 -20
  26. package/lib/helper/AI.js +114 -35
  27. package/lib/helper/ApiDataFactory.js +72 -69
  28. package/lib/helper/Appium.js +409 -379
  29. package/lib/helper/ExpectHelper.js +214 -248
  30. package/lib/helper/FileSystem.js +77 -78
  31. package/lib/helper/GraphQL.js +44 -43
  32. package/lib/helper/GraphQLDataFactory.js +49 -50
  33. package/lib/helper/JSONResponse.js +64 -62
  34. package/lib/helper/Mochawesome.js +28 -28
  35. package/lib/helper/MockServer.js +12 -12
  36. package/lib/helper/Nightmare.js +664 -572
  37. package/lib/helper/Playwright.js +1320 -1211
  38. package/lib/helper/Protractor.js +663 -629
  39. package/lib/helper/Puppeteer.js +1232 -1124
  40. package/lib/helper/REST.js +115 -69
  41. package/lib/helper/TestCafe.js +490 -491
  42. package/lib/helper/WebDriver.js +1294 -1156
  43. package/lib/history.js +16 -3
  44. package/lib/interfaces/bdd.js +38 -51
  45. package/lib/interfaces/featureConfig.js +19 -19
  46. package/lib/interfaces/gherkin.js +122 -111
  47. package/lib/interfaces/scenarioConfig.js +29 -29
  48. package/lib/listener/artifacts.js +9 -9
  49. package/lib/listener/config.js +24 -23
  50. package/lib/listener/exit.js +12 -12
  51. package/lib/listener/helpers.js +42 -42
  52. package/lib/listener/mocha.js +11 -11
  53. package/lib/listener/retry.js +32 -30
  54. package/lib/listener/steps.js +50 -51
  55. package/lib/listener/timeout.js +53 -53
  56. package/lib/pause.js +17 -3
  57. package/lib/plugin/allure.js +14 -14
  58. package/lib/plugin/autoDelay.js +29 -36
  59. package/lib/plugin/autoLogin.js +70 -66
  60. package/lib/plugin/commentStep.js +18 -18
  61. package/lib/plugin/coverage.js +92 -77
  62. package/lib/plugin/customLocator.js +20 -19
  63. package/lib/plugin/debugErrors.js +24 -24
  64. package/lib/plugin/eachElement.js +37 -37
  65. package/lib/plugin/fakerTransform.js +6 -6
  66. package/lib/plugin/heal.js +66 -63
  67. package/lib/plugin/pauseOnFail.js +10 -10
  68. package/lib/plugin/retryFailedStep.js +31 -38
  69. package/lib/plugin/retryTo.js +28 -28
  70. package/lib/plugin/screenshotOnFail.js +107 -86
  71. package/lib/plugin/selenoid.js +131 -117
  72. package/lib/plugin/standardActingHelpers.js +2 -8
  73. package/lib/plugin/stepByStepReport.js +102 -92
  74. package/lib/plugin/stepTimeout.js +23 -22
  75. package/lib/plugin/subtitles.js +34 -34
  76. package/lib/plugin/tryTo.js +39 -29
  77. package/lib/plugin/wdio.js +77 -72
  78. package/lib/template/heal.js +11 -14
  79. package/package.json +5 -3
  80. package/translations/de-DE.js +1 -1
  81. package/translations/fr-FR.js +1 -1
  82. package/translations/index.js +9 -9
  83. package/translations/it-IT.js +1 -1
  84. package/translations/ja-JP.js +1 -1
  85. package/translations/pl-PL.js +1 -1
  86. package/translations/pt-BR.js +1 -1
  87. package/translations/ru-RU.js +1 -1
  88. package/translations/zh-CN.js +1 -1
  89. package/translations/zh-TW.js +1 -1
  90. package/typings/index.d.ts +42 -19
  91. package/typings/promiseBasedTypes.d.ts +280 -1
  92. package/typings/types.d.ts +76 -1
@@ -1,8 +1,9 @@
1
- const axios = require('axios').default;
2
- const Helper = require('@codeceptjs/helper');
3
- const Secret = require('../secret');
1
+ const axios = require('axios').default
2
+ const Helper = require('@codeceptjs/helper')
3
+ const { Agent } = require('https')
4
+ const Secret = require('../secret')
4
5
 
5
- const { beautify } = require('../utils');
6
+ const { beautify } = require('../utils')
6
7
 
7
8
  /**
8
9
  * ## Configuration
@@ -14,11 +15,12 @@ const { beautify } = require('../utils');
14
15
  * @prop {boolean} [printCurl=false] - print cURL request on console logs. False by default.
15
16
  * @prop {number} [timeout=1000] - timeout for requests in milliseconds. 10000ms by default.
16
17
  * @prop {object} [defaultHeaders] - a list of default headers.
18
+ * @prop {object} [httpAgent] - create an agent with SSL certificate
17
19
  * @prop {function} [onRequest] - an async function which can update request object.
18
20
  * @prop {function} [onResponse] - an async function which can update response object.
19
21
  * @prop {number} [maxUploadFileSize] - set the max content file size in MB when performing api calls.
20
22
  */
21
- const config = {};
23
+ const config = {}
22
24
 
23
25
  /**
24
26
  * REST helper allows to send additional requests to the REST API during acceptance tests.
@@ -42,6 +44,25 @@ const config = {};
42
44
  *}
43
45
  * ```
44
46
  *
47
+ * With httpAgent
48
+ *
49
+ * ```js
50
+ * {
51
+ * helpers: {
52
+ * REST: {
53
+ * endpoint: 'http://site.com/api',
54
+ * prettyPrintJson: true,
55
+ * httpAgent: {
56
+ * key: fs.readFileSync(__dirname + '/path/to/keyfile.key'),
57
+ * cert: fs.readFileSync(__dirname + '/path/to/certfile.cert'),
58
+ * rejectUnauthorized: false,
59
+ * keepAlive: true
60
+ * }
61
+ * }
62
+ * }
63
+ * }
64
+ * ```
65
+ *
45
66
  * ## Access From Helpers
46
67
  *
47
68
  * Send REST requests by accessing `_executeRequest` method:
@@ -57,7 +78,7 @@ const config = {};
57
78
  */
58
79
  class REST extends Helper {
59
80
  constructor(config) {
60
- super(config);
81
+ super(config)
61
82
  this.options = {
62
83
  timeout: 10000,
63
84
  defaultHeaders: {},
@@ -65,39 +86,51 @@ class REST extends Helper {
65
86
  prettyPrintJson: false,
66
87
  onRequest: null,
67
88
  onResponse: null,
68
- };
89
+ }
69
90
 
70
91
  if (this.options.maxContentLength) {
71
- const maxContentLength = this.options.maxUploadFileSize * 1024 * 1024;
72
- this.options.maxContentLength = maxContentLength;
73
- this.options.maxBodyLength = maxContentLength;
92
+ const maxContentLength = this.options.maxUploadFileSize * 1024 * 1024
93
+ this.options.maxContentLength = maxContentLength
94
+ this.options.maxBodyLength = maxContentLength
74
95
  }
75
96
 
76
97
  // override defaults with config
77
- this._setConfig(config);
98
+ this._setConfig(config)
78
99
 
79
- this.headers = { ...this.options.defaultHeaders };
80
- this.axios = axios.create();
100
+ this.headers = { ...this.options.defaultHeaders }
101
+
102
+ // Create an agent with SSL certificate
103
+ if (this.options.httpAgent) {
104
+ if (!this.options.httpAgent.key || !this.options.httpAgent.cert)
105
+ throw Error('Please recheck your httpAgent config!')
106
+ this.httpsAgent = new Agent(this.options.httpAgent)
107
+ }
108
+
109
+ this.axios = this.httpsAgent ? axios.create({ httpsAgent: this.httpsAgent }) : axios.create()
81
110
  // @ts-ignore
82
- this.axios.defaults.headers = this.options.defaultHeaders;
111
+ this.axios.defaults.headers = this.options.defaultHeaders
83
112
  }
84
113
 
85
114
  static _config() {
86
115
  return [
87
- { name: 'endpoint', message: 'Endpoint of API you are going to test', default: 'http://localhost:3000/api' },
88
- ];
116
+ {
117
+ name: 'endpoint',
118
+ message: 'Endpoint of API you are going to test',
119
+ default: 'http://localhost:3000/api',
120
+ },
121
+ ]
89
122
  }
90
123
 
91
124
  static _checkRequirements() {
92
125
  try {
93
- require('axios');
126
+ require('axios')
94
127
  } catch (e) {
95
- return ['axios'];
128
+ return ['axios']
96
129
  }
97
130
  }
98
131
 
99
132
  _before() {
100
- this.headers = { ...this.options.defaultHeaders };
133
+ this.headers = { ...this.options.defaultHeaders }
101
134
  }
102
135
 
103
136
  /**
@@ -106,7 +139,7 @@ class REST extends Helper {
106
139
  * @param {object} headers headers list
107
140
  */
108
141
  haveRequestHeaders(headers) {
109
- this.headers = { ...this.headers, ...headers };
142
+ this.headers = { ...this.headers, ...headers }
110
143
  }
111
144
 
112
145
  /**
@@ -120,7 +153,7 @@ class REST extends Helper {
120
153
  * @param {string | CodeceptJS.Secret} accessToken Bearer access token
121
154
  */
122
155
  amBearerAuthenticated(accessToken) {
123
- this.haveRequestHeaders({ Authorization: `Bearer ${accessToken}` });
156
+ this.haveRequestHeaders({ Authorization: `Bearer ${accessToken}` })
124
157
  }
125
158
 
126
159
  /**
@@ -132,55 +165,65 @@ class REST extends Helper {
132
165
  */
133
166
  async _executeRequest(request) {
134
167
  // Add custom headers. They can be set by amBearerAuthenticated() or haveRequestHeaders()
135
- request.headers = { ...this.headers, ...request.headers };
168
+ request.headers = { ...this.headers, ...request.headers }
136
169
 
137
- const _debugRequest = { ...request };
138
- this.axios.defaults.timeout = request.timeout || this.options.timeout;
170
+ const _debugRequest = { ...request }
171
+ this.axios.defaults.timeout = request.timeout || this.options.timeout
139
172
 
140
173
  if (this.headers && this.headers.auth) {
141
- request.auth = this.headers.auth;
174
+ request.auth = this.headers.auth
142
175
  }
143
176
 
144
177
  if (typeof request.data === 'object') {
145
- const returnedValue = {};
178
+ const returnedValue = {}
146
179
  for (const [key, value] of Object.entries(request.data)) {
147
- returnedValue[key] = value;
148
- if (value instanceof Secret) returnedValue[key] = value.getMasked();
180
+ returnedValue[key] = value
181
+ if (value instanceof Secret) returnedValue[key] = value.getMasked()
149
182
  }
150
- _debugRequest.data = returnedValue;
183
+ _debugRequest.data = returnedValue
151
184
  }
152
185
 
153
186
  if (request.data instanceof Secret) {
154
- _debugRequest.data = '*****';
155
- request.data = (typeof request.data === 'object' && !(request.data instanceof Secret)) ? { ...request.data.toString() } : request.data.toString();
187
+ _debugRequest.data = '*****'
188
+ request.data =
189
+ typeof request.data === 'object' && !(request.data instanceof Secret)
190
+ ? { ...request.data.toString() }
191
+ : request.data.toString()
156
192
  }
157
193
 
158
- if ((typeof request.data) === 'string') {
194
+ if (typeof request.data === 'string') {
159
195
  if (!request.headers || !request.headers['Content-Type']) {
160
- request.headers = { ...request.headers, ...{ 'Content-Type': 'application/x-www-form-urlencoded' } };
196
+ request.headers = { ...request.headers, ...{ 'Content-Type': 'application/x-www-form-urlencoded' } }
161
197
  }
162
198
  }
163
199
 
164
200
  if (this.config.onRequest) {
165
- await this.config.onRequest(request);
201
+ await this.config.onRequest(request)
166
202
  }
167
203
 
168
- this.options.prettyPrintJson ? this.debugSection('Request', beautify(JSON.stringify(_debugRequest))) : this.debugSection('Request', JSON.stringify(_debugRequest));
169
- if (this.options.printCurl) this.debugSection('CURL Request', curlize(request));
204
+ this.options.prettyPrintJson
205
+ ? this.debugSection('Request', beautify(JSON.stringify(_debugRequest)))
206
+ : this.debugSection('Request', JSON.stringify(_debugRequest))
170
207
 
171
- let response;
208
+ if (this.options.printCurl) {
209
+ this.debugSection('CURL Request', curlize(request));
210
+ }
211
+
212
+ let response
172
213
  try {
173
- response = await this.axios(request);
214
+ response = await this.axios(request)
174
215
  } catch (err) {
175
- if (!err.response) throw err;
176
- this.debugSection('Response', `Response error. Status code: ${err.response.status}`);
177
- response = err.response;
216
+ if (!err.response) throw err
217
+ this.debugSection('Response', `Response error. Status code: ${err.response.status}`)
218
+ response = err.response
178
219
  }
179
220
  if (this.config.onResponse) {
180
- await this.config.onResponse(response);
221
+ await this.config.onResponse(response)
181
222
  }
182
- this.options.prettyPrintJson ? this.debugSection('Response', beautify(JSON.stringify(response.data))) : this.debugSection('Response', JSON.stringify(response.data));
183
- return response;
223
+ this.options.prettyPrintJson
224
+ ? this.debugSection('Response', beautify(JSON.stringify(response.data)))
225
+ : this.debugSection('Response', JSON.stringify(response.data))
226
+ return response
184
227
  }
185
228
 
186
229
  /**
@@ -189,7 +232,7 @@ class REST extends Helper {
189
232
  * @param {*} url
190
233
  */
191
234
  _url(url) {
192
- return /^\w+\:\/\//.test(url) ? url : this.options.endpoint + url;
235
+ return /^\w+\:\/\//.test(url) ? url : this.options.endpoint + url
193
236
  }
194
237
 
195
238
  /**
@@ -202,7 +245,7 @@ class REST extends Helper {
202
245
  * @param {number} newTimeout - timeout in milliseconds
203
246
  */
204
247
  setRequestTimeout(newTimeout) {
205
- this.options.timeout = newTimeout;
248
+ this.options.timeout = newTimeout
206
249
  }
207
250
 
208
251
  /**
@@ -221,8 +264,8 @@ class REST extends Helper {
221
264
  const request = {
222
265
  baseURL: this._url(url),
223
266
  headers,
224
- };
225
- return this._executeRequest(request);
267
+ }
268
+ return this._executeRequest(request)
226
269
  }
227
270
 
228
271
  /**
@@ -248,14 +291,14 @@ class REST extends Helper {
248
291
  method: 'POST',
249
292
  data: payload,
250
293
  headers,
251
- };
294
+ }
252
295
 
253
296
  if (this.options.maxContentLength) {
254
- request.maxContentLength = this.options.maxContentLength;
255
- request.maxBodyLength = this.options.maxContentLength;
297
+ request.maxContentLength = this.options.maxContentLength
298
+ request.maxBodyLength = this.options.maxContentLength
256
299
  }
257
300
 
258
- return this._executeRequest(request);
301
+ return this._executeRequest(request)
259
302
  }
260
303
 
261
304
  /**
@@ -281,14 +324,14 @@ class REST extends Helper {
281
324
  method: 'PATCH',
282
325
  data: payload,
283
326
  headers,
284
- };
327
+ }
285
328
 
286
329
  if (this.options.maxContentLength) {
287
- request.maxContentLength = this.options.maxContentLength;
288
- request.maxBodyLength = this.options.maxBodyLength;
330
+ request.maxContentLength = this.options.maxContentLength
331
+ request.maxBodyLength = this.options.maxBodyLength
289
332
  }
290
333
 
291
- return this._executeRequest(request);
334
+ return this._executeRequest(request)
292
335
  }
293
336
 
294
337
  /**
@@ -314,14 +357,14 @@ class REST extends Helper {
314
357
  method: 'PUT',
315
358
  data: payload,
316
359
  headers,
317
- };
360
+ }
318
361
 
319
362
  if (this.options.maxContentLength) {
320
- request.maxContentLength = this.options.maxContentLength;
321
- request.maxBodyLength = this.options.maxBodyLength;
363
+ request.maxContentLength = this.options.maxContentLength
364
+ request.maxBodyLength = this.options.maxBodyLength
322
365
  }
323
366
 
324
- return this._executeRequest(request);
367
+ return this._executeRequest(request)
325
368
  }
326
369
 
327
370
  /**
@@ -341,28 +384,31 @@ class REST extends Helper {
341
384
  baseURL: this._url(url),
342
385
  method: 'DELETE',
343
386
  headers,
344
- };
387
+ }
345
388
 
346
- return this._executeRequest(request);
389
+ return this._executeRequest(request)
347
390
  }
348
391
  }
349
- module.exports = REST;
392
+
393
+ module.exports = REST
350
394
 
351
395
  function curlize(request) {
352
- let curl = `curl --location --request ${request.method ? request.method.toUpperCase() : 'GET'} ${request.baseURL} `.replace("'", '');
396
+ if (request.data?.constructor.name.toLowerCase() === 'formdata') return 'cURL is not printed as the request body is not a JSON'
397
+ let curl = `curl --location --request ${request.method ? request.method.toUpperCase() : 'GET'} ${request.baseURL} `.replace("'", '')
353
398
 
354
399
  if (request.headers) {
355
400
  Object.entries(request.headers).forEach(([key, value]) => {
356
- curl += `-H "${key}: ${value}" `;
357
- });
401
+ curl += `-H "${key}: ${value}" `
402
+ })
358
403
  }
359
404
 
360
405
  if (!curl.toLowerCase().includes('content-type: application/json')) {
361
- curl += '-H "Content-Type: application/json" ';
406
+ curl += '-H "Content-Type: application/json" '
362
407
  }
363
408
 
364
409
  if (request.data) {
365
- curl += `-d '${JSON.stringify(request.data)}'`;
410
+ curl += `-d '${JSON.stringify(request.data)}'`
366
411
  }
367
- return curl;
412
+ return curl
368
413
  }
414
+