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