codeceptjs 4.0.0-beta.1 → 4.0.0-beta.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.
- package/bin/codecept.js +84 -81
- package/lib/actor.js +13 -13
- package/lib/ai.js +10 -13
- package/lib/assert/empty.js +20 -21
- package/lib/assert/equal.js +37 -39
- package/lib/assert/error.js +14 -14
- package/lib/assert/include.js +46 -47
- package/lib/assert/throws.js +13 -11
- package/lib/assert/truth.js +19 -22
- package/lib/assert.js +4 -2
- package/lib/cli.js +57 -49
- package/lib/codecept.js +142 -155
- package/lib/colorUtils.js +3 -3
- package/lib/command/configMigrate.js +58 -52
- package/lib/command/definitions.js +88 -89
- package/lib/command/dryRun.js +71 -68
- package/lib/command/generate.js +197 -188
- package/lib/command/gherkin/init.js +27 -16
- package/lib/command/gherkin/snippets.js +20 -20
- package/lib/command/gherkin/steps.js +8 -8
- package/lib/command/info.js +40 -38
- package/lib/command/init.js +290 -288
- package/lib/command/interactive.js +32 -32
- package/lib/command/list.js +26 -26
- package/lib/command/run-multiple/chunk.js +5 -5
- package/lib/command/run-multiple/collection.js +3 -3
- package/lib/command/run-multiple/run.js +6 -2
- package/lib/command/run-multiple.js +113 -93
- package/lib/command/run-rerun.js +20 -25
- package/lib/command/run-workers.js +64 -66
- package/lib/command/run.js +26 -29
- package/lib/command/utils.js +80 -65
- package/lib/command/workers/runTests.js +10 -10
- package/lib/config.js +10 -9
- package/lib/container.js +40 -48
- package/lib/data/context.js +60 -59
- package/lib/data/dataScenarioConfig.js +47 -47
- package/lib/data/dataTableArgument.js +29 -29
- package/lib/data/table.js +26 -20
- package/lib/event.js +163 -167
- package/lib/heal.js +13 -17
- package/lib/helper/AI.js +130 -41
- package/lib/helper/ApiDataFactory.js +73 -69
- package/lib/helper/Appium.js +413 -382
- package/lib/helper/ExpectHelper.js +40 -48
- package/lib/helper/FileSystem.js +80 -79
- package/lib/helper/GraphQL.js +44 -43
- package/lib/helper/GraphQLDataFactory.js +50 -50
- package/lib/helper/JSONResponse.js +65 -62
- package/lib/helper/Mochawesome.js +28 -28
- package/lib/helper/MockServer.js +12 -14
- package/lib/helper/Nightmare.js +662 -566
- package/lib/helper/Playwright.js +1361 -1216
- package/lib/helper/Protractor.js +663 -627
- package/lib/helper/Puppeteer.js +1231 -1128
- package/lib/helper/REST.js +159 -68
- package/lib/helper/SoftExpectHelper.js +2 -2
- package/lib/helper/TestCafe.js +490 -484
- package/lib/helper/WebDriver.js +1297 -1156
- package/lib/helper/clientscripts/PollyWebDriverExt.js +1 -1
- package/lib/helper/errors/ConnectionRefused.js +1 -1
- package/lib/helper/errors/ElementAssertion.js +2 -2
- package/lib/helper/errors/ElementNotFound.js +2 -2
- package/lib/helper/errors/RemoteBrowserConnectionRefused.js +1 -1
- package/lib/helper/extras/Console.js +1 -1
- package/lib/helper/extras/PlaywrightPropEngine.js +2 -2
- package/lib/helper/extras/PlaywrightReactVueLocator.js +1 -1
- package/lib/helper/extras/PlaywrightRestartOpts.js +21 -18
- package/lib/helper/extras/Popup.js +1 -1
- package/lib/helper/extras/React.js +3 -3
- package/lib/helper/network/actions.js +14 -7
- package/lib/helper/network/utils.js +3 -2
- package/lib/helper/scripts/blurElement.js +1 -1
- package/lib/helper/scripts/focusElement.js +1 -1
- package/lib/helper/scripts/highlightElement.js +1 -1
- package/lib/helper/scripts/isElementClickable.js +1 -1
- package/lib/helper/testcafe/testControllerHolder.js +1 -1
- package/lib/helper/testcafe/testcafe-utils.js +6 -7
- package/lib/helper.js +1 -3
- package/lib/history.js +6 -5
- package/lib/hooks.js +6 -6
- package/lib/html.js +7 -7
- package/lib/index.js +25 -41
- package/lib/interfaces/bdd.js +47 -64
- package/lib/interfaces/featureConfig.js +19 -19
- package/lib/interfaces/gherkin.js +124 -118
- package/lib/interfaces/scenarioConfig.js +29 -29
- package/lib/listener/artifacts.js +9 -9
- package/lib/listener/config.js +24 -24
- 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 -53
- package/lib/listener/timeout.js +54 -54
- package/lib/locator.js +6 -10
- package/lib/mochaFactory.js +18 -15
- package/lib/output.js +6 -10
- package/lib/parser.js +15 -12
- package/lib/pause.js +40 -33
- package/lib/plugin/allure.js +15 -15
- package/lib/plugin/autoDelay.js +29 -37
- package/lib/plugin/autoLogin.js +70 -65
- package/lib/plugin/commentStep.js +18 -18
- package/lib/plugin/coverage.js +115 -67
- package/lib/plugin/customLocator.js +21 -20
- package/lib/plugin/debugErrors.js +24 -24
- package/lib/plugin/eachElement.js +38 -38
- package/lib/plugin/fakerTransform.js +6 -6
- package/lib/plugin/heal.js +67 -108
- package/lib/plugin/pauseOnFail.js +11 -11
- package/lib/plugin/retryFailedStep.js +32 -39
- package/lib/plugin/retryTo.js +46 -40
- package/lib/plugin/screenshotOnFail.js +109 -87
- package/lib/plugin/selenoid.js +131 -118
- package/lib/plugin/standardActingHelpers.js +2 -8
- package/lib/plugin/stepByStepReport.js +110 -91
- package/lib/plugin/stepTimeout.js +24 -23
- package/lib/plugin/subtitles.js +34 -35
- package/lib/plugin/tryTo.js +40 -30
- package/lib/plugin/wdio.js +78 -75
- package/lib/recorder.js +14 -17
- package/lib/rerun.js +11 -10
- package/lib/scenario.js +25 -23
- package/lib/secret.js +4 -2
- package/lib/session.js +10 -10
- package/lib/step.js +12 -9
- package/lib/store.js +2 -3
- package/lib/transform.js +1 -1
- package/lib/translation.js +7 -8
- package/lib/ui.js +12 -14
- package/lib/utils.js +70 -72
- package/lib/within.js +10 -10
- package/lib/workerStorage.js +27 -25
- package/lib/workers.js +29 -32
- package/package.json +56 -57
- package/translations/de-DE.js +1 -1
- package/translations/fr-FR.js +1 -1
- package/translations/index.js +9 -13
- 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/index.d.ts +415 -65
- package/typings/promiseBasedTypes.d.ts +32 -0
- package/typings/types.d.ts +32 -0
- package/lib/dirname.js +0 -5
- package/lib/helper/Expect.js +0 -425
package/lib/helper/GraphQL.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
const axios = require('axios').default
|
|
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.
|
|
@@ -38,31 +38,35 @@ import Helper from '@codeceptjs/helper';
|
|
|
38
38
|
*/
|
|
39
39
|
class GraphQL extends Helper {
|
|
40
40
|
constructor(config) {
|
|
41
|
-
super(config)
|
|
42
|
-
this.axios = axios.create()
|
|
43
|
-
this.headers = {}
|
|
41
|
+
super(config)
|
|
42
|
+
this.axios = axios.create()
|
|
43
|
+
this.headers = {}
|
|
44
44
|
this.options = {
|
|
45
45
|
timeout: 10000,
|
|
46
46
|
defaultHeaders: {},
|
|
47
47
|
endpoint: '',
|
|
48
|
-
}
|
|
49
|
-
this.options = Object.assign(this.options, config)
|
|
50
|
-
this.headers = { ...this.options.defaultHeaders }
|
|
51
|
-
this.axios.defaults.headers = this.options.defaultHeaders
|
|
48
|
+
}
|
|
49
|
+
this.options = Object.assign(this.options, config)
|
|
50
|
+
this.headers = { ...this.options.defaultHeaders }
|
|
51
|
+
this.axios.defaults.headers = this.options.defaultHeaders
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
static _checkRequirements() {
|
|
55
55
|
try {
|
|
56
|
-
require('axios')
|
|
56
|
+
require('axios')
|
|
57
57
|
} catch (e) {
|
|
58
|
-
return ['axios']
|
|
58
|
+
return ['axios']
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
static _config() {
|
|
63
63
|
return [
|
|
64
|
-
{
|
|
65
|
-
|
|
64
|
+
{
|
|
65
|
+
name: 'endpoint',
|
|
66
|
+
message: 'Endpoint of API you are going to test',
|
|
67
|
+
default: 'http://localhost:3000/graphql',
|
|
68
|
+
},
|
|
69
|
+
]
|
|
66
70
|
}
|
|
67
71
|
|
|
68
72
|
/**
|
|
@@ -71,42 +75,39 @@ class GraphQL extends Helper {
|
|
|
71
75
|
* @param {object} request
|
|
72
76
|
*/
|
|
73
77
|
async _executeQuery(request) {
|
|
74
|
-
this.axios.defaults.timeout = request.timeout || this.options.timeout
|
|
78
|
+
this.axios.defaults.timeout = request.timeout || this.options.timeout
|
|
75
79
|
|
|
76
80
|
if (this.headers && this.headers.auth) {
|
|
77
|
-
request.auth = this.headers.auth
|
|
81
|
+
request.auth = this.headers.auth
|
|
78
82
|
}
|
|
79
83
|
|
|
80
84
|
request.headers = Object.assign(request.headers, {
|
|
81
85
|
'Content-Type': 'application/json',
|
|
82
|
-
})
|
|
86
|
+
})
|
|
83
87
|
|
|
84
|
-
request.headers = { ...this.headers, ...request.headers }
|
|
88
|
+
request.headers = { ...this.headers, ...request.headers }
|
|
85
89
|
|
|
86
90
|
if (this.config.onRequest) {
|
|
87
|
-
await this.config.onRequest(request)
|
|
91
|
+
await this.config.onRequest(request)
|
|
88
92
|
}
|
|
89
93
|
|
|
90
|
-
this.debugSection('Request', JSON.stringify(request))
|
|
94
|
+
this.debugSection('Request', JSON.stringify(request))
|
|
91
95
|
|
|
92
|
-
let response
|
|
96
|
+
let response
|
|
93
97
|
try {
|
|
94
|
-
response = await this.axios(request)
|
|
98
|
+
response = await this.axios(request)
|
|
95
99
|
} catch (err) {
|
|
96
|
-
if (!err.response) throw err
|
|
97
|
-
this.debugSection(
|
|
98
|
-
|
|
99
|
-
`Response error. Status code: ${err.response.status}`,
|
|
100
|
-
);
|
|
101
|
-
response = err.response;
|
|
100
|
+
if (!err.response) throw err
|
|
101
|
+
this.debugSection('Response', `Response error. Status code: ${err.response.status}`)
|
|
102
|
+
response = err.response
|
|
102
103
|
}
|
|
103
104
|
|
|
104
105
|
if (this.config.onResponse) {
|
|
105
|
-
await this.config.onResponse(response)
|
|
106
|
+
await this.config.onResponse(response)
|
|
106
107
|
}
|
|
107
108
|
|
|
108
|
-
this.debugSection('Response', JSON.stringify(response.data))
|
|
109
|
-
return response
|
|
109
|
+
this.debugSection('Response', JSON.stringify(response.data))
|
|
110
|
+
return response
|
|
110
111
|
}
|
|
111
112
|
|
|
112
113
|
/**
|
|
@@ -122,7 +123,7 @@ class GraphQL extends Helper {
|
|
|
122
123
|
method: 'POST',
|
|
123
124
|
data: operation,
|
|
124
125
|
headers,
|
|
125
|
-
}
|
|
126
|
+
}
|
|
126
127
|
}
|
|
127
128
|
|
|
128
129
|
/**
|
|
@@ -148,15 +149,15 @@ class GraphQL extends Helper {
|
|
|
148
149
|
*/
|
|
149
150
|
async sendQuery(query, variables, options = {}, headers = {}) {
|
|
150
151
|
if (typeof query !== 'string') {
|
|
151
|
-
throw new Error(`query expected to be a String, instead received ${typeof query}`)
|
|
152
|
+
throw new Error(`query expected to be a String, instead received ${typeof query}`)
|
|
152
153
|
}
|
|
153
154
|
const operation = {
|
|
154
155
|
query,
|
|
155
156
|
variables,
|
|
156
157
|
...options,
|
|
157
|
-
}
|
|
158
|
-
const request = this._prepareGraphQLRequest(operation, headers)
|
|
159
|
-
return this._executeQuery(request)
|
|
158
|
+
}
|
|
159
|
+
const request = this._prepareGraphQLRequest(operation, headers)
|
|
160
|
+
return this._executeQuery(request)
|
|
160
161
|
}
|
|
161
162
|
|
|
162
163
|
/**
|
|
@@ -188,19 +189,19 @@ class GraphQL extends Helper {
|
|
|
188
189
|
*/
|
|
189
190
|
async sendMutation(mutation, variables, options = {}, headers = {}) {
|
|
190
191
|
if (typeof mutation !== 'string') {
|
|
191
|
-
throw new Error(`mutation expected to be a String, instead received ${typeof mutation}`)
|
|
192
|
+
throw new Error(`mutation expected to be a String, instead received ${typeof mutation}`)
|
|
192
193
|
}
|
|
193
194
|
const operation = {
|
|
194
195
|
query: mutation,
|
|
195
196
|
variables,
|
|
196
197
|
...options,
|
|
197
|
-
}
|
|
198
|
-
const request = this._prepareGraphQLRequest(operation, headers)
|
|
199
|
-
return this._executeQuery(request)
|
|
198
|
+
}
|
|
199
|
+
const request = this._prepareGraphQLRequest(operation, headers)
|
|
200
|
+
return this._executeQuery(request)
|
|
200
201
|
}
|
|
201
202
|
|
|
202
203
|
_setRequestTimeout(newTimeout) {
|
|
203
|
-
this.options.timeout = newTimeout
|
|
204
|
+
this.options.timeout = newTimeout
|
|
204
205
|
}
|
|
205
206
|
|
|
206
207
|
/**
|
|
@@ -209,7 +210,7 @@ class GraphQL extends Helper {
|
|
|
209
210
|
* @param {object} headers headers list
|
|
210
211
|
*/
|
|
211
212
|
haveRequestHeaders(headers) {
|
|
212
|
-
this.headers = { ...this.headers, ...headers }
|
|
213
|
+
this.headers = { ...this.headers, ...headers }
|
|
213
214
|
}
|
|
214
215
|
|
|
215
216
|
/**
|
|
@@ -223,7 +224,7 @@ class GraphQL extends Helper {
|
|
|
223
224
|
* @param {string | CodeceptJS.Secret} accessToken Bearer access token
|
|
224
225
|
*/
|
|
225
226
|
amBearerAuthenticated(accessToken) {
|
|
226
|
-
this.haveRequestHeaders({ Authorization: `Bearer ${accessToken}` })
|
|
227
|
+
this.haveRequestHeaders({ Authorization: `Bearer ${accessToken}` })
|
|
227
228
|
}
|
|
228
229
|
}
|
|
229
|
-
|
|
230
|
+
module.exports = GraphQL
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
const path = require('path')
|
|
2
|
+
|
|
3
|
+
const Helper = require('@codeceptjs/helper')
|
|
4
|
+
const GraphQL = require('./GraphQL')
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Helper for managing remote data using GraphQL queries.
|
|
@@ -150,52 +151,52 @@ import GraphQL from './GraphQL';
|
|
|
150
151
|
*/
|
|
151
152
|
class GraphQLDataFactory extends Helper {
|
|
152
153
|
constructor(config) {
|
|
153
|
-
super(config)
|
|
154
|
+
super(config)
|
|
154
155
|
|
|
155
156
|
const defaultConfig = {
|
|
156
157
|
cleanup: true,
|
|
157
158
|
GraphQL: {},
|
|
158
159
|
factories: {},
|
|
159
|
-
}
|
|
160
|
-
this.config = Object.assign(defaultConfig, this.config)
|
|
160
|
+
}
|
|
161
|
+
this.config = Object.assign(defaultConfig, this.config)
|
|
161
162
|
|
|
162
163
|
if (this.config.headers) {
|
|
163
|
-
this.config.GraphQL.defaultHeaders = this.config.headers
|
|
164
|
+
this.config.GraphQL.defaultHeaders = this.config.headers
|
|
164
165
|
}
|
|
165
166
|
if (this.config.onRequest) {
|
|
166
|
-
this.config.GraphQL.onRequest = this.config.onRequest
|
|
167
|
+
this.config.GraphQL.onRequest = this.config.onRequest
|
|
167
168
|
}
|
|
168
|
-
this.graphqlHelper = new GraphQL(Object.assign(this.config.GraphQL, { endpoint: this.config.endpoint }))
|
|
169
|
-
this.factories = this.config.factories
|
|
169
|
+
this.graphqlHelper = new GraphQL(Object.assign(this.config.GraphQL, { endpoint: this.config.endpoint }))
|
|
170
|
+
this.factories = this.config.factories
|
|
170
171
|
|
|
171
|
-
this.created = {}
|
|
172
|
-
Object.keys(this.factories).forEach(f => (this.created[f] = []))
|
|
172
|
+
this.created = {}
|
|
173
|
+
Object.keys(this.factories).forEach((f) => (this.created[f] = []))
|
|
173
174
|
}
|
|
174
175
|
|
|
175
176
|
static _checkRequirements() {
|
|
176
177
|
try {
|
|
177
|
-
require('axios')
|
|
178
|
-
require('rosie')
|
|
178
|
+
require('axios')
|
|
179
|
+
require('rosie')
|
|
179
180
|
} catch (e) {
|
|
180
|
-
return ['axios', 'rosie']
|
|
181
|
+
return ['axios', 'rosie']
|
|
181
182
|
}
|
|
182
183
|
}
|
|
183
184
|
|
|
184
185
|
_after() {
|
|
185
186
|
if (!this.config.cleanup) {
|
|
186
|
-
return Promise.resolve()
|
|
187
|
+
return Promise.resolve()
|
|
187
188
|
}
|
|
188
|
-
const promises = []
|
|
189
|
+
const promises = []
|
|
189
190
|
// clean up all created items
|
|
190
191
|
for (const mutationName in this.created) {
|
|
191
|
-
const createdItems = this.created[mutationName]
|
|
192
|
-
if (!createdItems.length) continue
|
|
193
|
-
this.debug(`Deleting ${createdItems.length} ${mutationName}(s)`)
|
|
192
|
+
const createdItems = this.created[mutationName]
|
|
193
|
+
if (!createdItems.length) continue
|
|
194
|
+
this.debug(`Deleting ${createdItems.length} ${mutationName}(s)`)
|
|
194
195
|
for (const itemData of createdItems) {
|
|
195
|
-
promises.push(this._requestDelete(mutationName, itemData))
|
|
196
|
+
promises.push(this._requestDelete(mutationName, itemData))
|
|
196
197
|
}
|
|
197
198
|
}
|
|
198
|
-
return Promise.all(promises)
|
|
199
|
+
return Promise.all(promises)
|
|
199
200
|
}
|
|
200
201
|
|
|
201
202
|
/**
|
|
@@ -213,9 +214,9 @@ class GraphQLDataFactory extends Helper {
|
|
|
213
214
|
* @param {*} params predefined parameters
|
|
214
215
|
*/
|
|
215
216
|
mutateData(operation, params) {
|
|
216
|
-
const variables = this._createItem(operation, params)
|
|
217
|
-
this.debug(`Creating ${operation} ${JSON.stringify(variables)}`)
|
|
218
|
-
return this._requestCreate(operation, variables)
|
|
217
|
+
const variables = this._createItem(operation, params)
|
|
218
|
+
this.debug(`Creating ${operation} ${JSON.stringify(variables)}`)
|
|
219
|
+
return this._requestCreate(operation, variables)
|
|
219
220
|
}
|
|
220
221
|
|
|
221
222
|
/**
|
|
@@ -234,26 +235,26 @@ class GraphQLDataFactory extends Helper {
|
|
|
234
235
|
* @param {*} params
|
|
235
236
|
*/
|
|
236
237
|
mutateMultiple(operation, times, params) {
|
|
237
|
-
const promises = []
|
|
238
|
+
const promises = []
|
|
238
239
|
for (let i = 0; i < times; i++) {
|
|
239
|
-
promises.push(this.mutateData(operation, params))
|
|
240
|
+
promises.push(this.mutateData(operation, params))
|
|
240
241
|
}
|
|
241
|
-
return Promise.all(promises)
|
|
242
|
+
return Promise.all(promises)
|
|
242
243
|
}
|
|
243
244
|
|
|
244
245
|
_createItem(operation, data) {
|
|
245
246
|
if (!this.factories[operation]) {
|
|
246
|
-
throw new Error(`Mutation ${operation} is not defined in config.factories`)
|
|
247
|
+
throw new Error(`Mutation ${operation} is not defined in config.factories`)
|
|
247
248
|
}
|
|
248
|
-
let modulePath = this.factories[operation].factory
|
|
249
|
+
let modulePath = this.factories[operation].factory
|
|
249
250
|
try {
|
|
250
251
|
try {
|
|
251
|
-
require.resolve(modulePath)
|
|
252
|
+
require.resolve(modulePath)
|
|
252
253
|
} catch (e) {
|
|
253
|
-
modulePath = path.join(global.codecept_dir, modulePath)
|
|
254
|
+
modulePath = path.join(global.codecept_dir, modulePath)
|
|
254
255
|
}
|
|
255
|
-
const builder = require(modulePath)
|
|
256
|
-
return builder.build(data)
|
|
256
|
+
const builder = require(modulePath)
|
|
257
|
+
return builder.build(data)
|
|
257
258
|
} catch (err) {
|
|
258
259
|
throw new Error(`Couldn't load factory file from ${modulePath}, check that
|
|
259
260
|
|
|
@@ -264,7 +265,7 @@ class GraphQLDataFactory extends Helper {
|
|
|
264
265
|
points to valid factory file.
|
|
265
266
|
Factory file should export an object with build method.
|
|
266
267
|
|
|
267
|
-
Current file error: ${err.message}`)
|
|
268
|
+
Current file error: ${err.message}`)
|
|
268
269
|
}
|
|
269
270
|
}
|
|
270
271
|
|
|
@@ -276,13 +277,13 @@ class GraphQLDataFactory extends Helper {
|
|
|
276
277
|
* @param {*} variables to be sent along with the query
|
|
277
278
|
*/
|
|
278
279
|
_requestCreate(operation, variables) {
|
|
279
|
-
const { query } = this.factories[operation]
|
|
280
|
+
const { query } = this.factories[operation]
|
|
280
281
|
return this.graphqlHelper.sendMutation(query, variables).then((response) => {
|
|
281
|
-
const data = response.data.data[operation]
|
|
282
|
-
this.created[operation].push(data)
|
|
283
|
-
this.debugSection('Created', `record: ${data}`)
|
|
284
|
-
return data
|
|
285
|
-
})
|
|
282
|
+
const data = response.data.data[operation]
|
|
283
|
+
this.created[operation].push(data)
|
|
284
|
+
this.debugSection('Created', `record: ${data}`)
|
|
285
|
+
return data
|
|
286
|
+
})
|
|
286
287
|
}
|
|
287
288
|
|
|
288
289
|
/**
|
|
@@ -293,16 +294,15 @@ class GraphQLDataFactory extends Helper {
|
|
|
293
294
|
* @param {*} data of the record to be deleted.
|
|
294
295
|
*/
|
|
295
296
|
_requestDelete(operation, data) {
|
|
296
|
-
const deleteOperation = this.factories[operation].revert(data)
|
|
297
|
-
const { query, variables } = deleteOperation
|
|
297
|
+
const deleteOperation = this.factories[operation].revert(data)
|
|
298
|
+
const { query, variables } = deleteOperation
|
|
298
299
|
|
|
299
|
-
return this.graphqlHelper.sendMutation(query, variables)
|
|
300
|
-
.
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
});
|
|
300
|
+
return this.graphqlHelper.sendMutation(query, variables).then((response) => {
|
|
301
|
+
const idx = this.created[operation].indexOf(data)
|
|
302
|
+
this.debugSection('Deleted', `record: ${response.data.data}`)
|
|
303
|
+
this.created[operation].splice(idx, 1)
|
|
304
|
+
})
|
|
305
305
|
}
|
|
306
306
|
}
|
|
307
307
|
|
|
308
|
-
|
|
308
|
+
module.exports = GraphQLDataFactory
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
import Helper from '../helper.js';
|
|
1
|
+
const Helper = require('@codeceptjs/helper')
|
|
3
2
|
|
|
4
|
-
let expect
|
|
3
|
+
let expect
|
|
5
4
|
|
|
6
|
-
import('chai').then(chai => {
|
|
7
|
-
expect = chai.expect
|
|
8
|
-
chai.use(require('chai-deep-match'))
|
|
9
|
-
})
|
|
5
|
+
import('chai').then((chai) => {
|
|
6
|
+
expect = chai.expect
|
|
7
|
+
chai.use(require('chai-deep-match'))
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
const joi = require('joi')
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* This helper allows performing assertions on JSON responses paired with following helpers:
|
|
@@ -66,33 +67,35 @@ import('chai').then(chai => {
|
|
|
66
67
|
*/
|
|
67
68
|
class JSONResponse extends Helper {
|
|
68
69
|
constructor(config = {}) {
|
|
69
|
-
super(config)
|
|
70
|
+
super(config)
|
|
70
71
|
this.options = {
|
|
71
72
|
requestHelper: 'REST',
|
|
72
|
-
}
|
|
73
|
-
this.options = { ...this.options, ...config }
|
|
73
|
+
}
|
|
74
|
+
this.options = { ...this.options, ...config }
|
|
74
75
|
}
|
|
75
76
|
|
|
76
77
|
_beforeSuite() {
|
|
77
|
-
this.response = null
|
|
78
|
+
this.response = null
|
|
78
79
|
if (!this.helpers[this.options.requestHelper]) {
|
|
79
|
-
throw new Error(
|
|
80
|
+
throw new Error(
|
|
81
|
+
`Error setting JSONResponse, helper ${this.options.requestHelper} is not enabled in config, helpers: ${Object.keys(this.helpers)}`,
|
|
82
|
+
)
|
|
80
83
|
}
|
|
81
84
|
// connect to REST helper
|
|
82
85
|
this.helpers[this.options.requestHelper].config.onResponse = (response) => {
|
|
83
|
-
this.response = response
|
|
84
|
-
}
|
|
86
|
+
this.response = response
|
|
87
|
+
}
|
|
85
88
|
}
|
|
86
89
|
|
|
87
90
|
_before() {
|
|
88
|
-
this.response = null
|
|
91
|
+
this.response = null
|
|
89
92
|
}
|
|
90
93
|
|
|
91
94
|
static _checkRequirements() {
|
|
92
95
|
try {
|
|
93
|
-
require('joi')
|
|
96
|
+
require('joi')
|
|
94
97
|
} catch (e) {
|
|
95
|
-
return ['joi']
|
|
98
|
+
return ['joi']
|
|
96
99
|
}
|
|
97
100
|
}
|
|
98
101
|
|
|
@@ -106,8 +109,8 @@ class JSONResponse extends Helper {
|
|
|
106
109
|
* @param {number} code
|
|
107
110
|
*/
|
|
108
111
|
seeResponseCodeIs(code) {
|
|
109
|
-
this._checkResponseReady()
|
|
110
|
-
expect(this.response.status).to.eql(code, 'Response code is not the same as expected')
|
|
112
|
+
this._checkResponseReady()
|
|
113
|
+
expect(this.response.status).to.eql(code, 'Response code is not the same as expected')
|
|
111
114
|
}
|
|
112
115
|
|
|
113
116
|
/**
|
|
@@ -120,35 +123,35 @@ class JSONResponse extends Helper {
|
|
|
120
123
|
* @param {number} code
|
|
121
124
|
*/
|
|
122
125
|
dontSeeResponseCodeIs(code) {
|
|
123
|
-
this._checkResponseReady()
|
|
124
|
-
expect(this.response.status).not.to.eql(code)
|
|
126
|
+
this._checkResponseReady()
|
|
127
|
+
expect(this.response.status).not.to.eql(code)
|
|
125
128
|
}
|
|
126
129
|
|
|
127
130
|
/**
|
|
128
131
|
* Checks that the response code is 4xx
|
|
129
132
|
*/
|
|
130
133
|
seeResponseCodeIsClientError() {
|
|
131
|
-
this._checkResponseReady()
|
|
132
|
-
expect(this.response.status).to.be.gte(400)
|
|
133
|
-
expect(this.response.status).to.be.lt(500)
|
|
134
|
+
this._checkResponseReady()
|
|
135
|
+
expect(this.response.status).to.be.gte(400)
|
|
136
|
+
expect(this.response.status).to.be.lt(500)
|
|
134
137
|
}
|
|
135
138
|
|
|
136
139
|
/**
|
|
137
140
|
* Checks that the response code is 3xx
|
|
138
141
|
*/
|
|
139
142
|
seeResponseCodeIsRedirection() {
|
|
140
|
-
this._checkResponseReady()
|
|
141
|
-
expect(this.response.status).to.be.gte(300)
|
|
142
|
-
expect(this.response.status).to.be.lt(400)
|
|
143
|
+
this._checkResponseReady()
|
|
144
|
+
expect(this.response.status).to.be.gte(300)
|
|
145
|
+
expect(this.response.status).to.be.lt(400)
|
|
143
146
|
}
|
|
144
147
|
|
|
145
148
|
/**
|
|
146
149
|
* Checks that the response code is 5xx
|
|
147
150
|
*/
|
|
148
151
|
seeResponseCodeIsServerError() {
|
|
149
|
-
this._checkResponseReady()
|
|
150
|
-
expect(this.response.status).to.be.gte(500)
|
|
151
|
-
expect(this.response.status).to.be.lt(600)
|
|
152
|
+
this._checkResponseReady()
|
|
153
|
+
expect(this.response.status).to.be.gte(500)
|
|
154
|
+
expect(this.response.status).to.be.lt(600)
|
|
152
155
|
}
|
|
153
156
|
|
|
154
157
|
/**
|
|
@@ -160,9 +163,9 @@ class JSONResponse extends Helper {
|
|
|
160
163
|
* ```
|
|
161
164
|
*/
|
|
162
165
|
seeResponseCodeIsSuccessful() {
|
|
163
|
-
this._checkResponseReady()
|
|
164
|
-
expect(this.response.status).to.be.gte(200)
|
|
165
|
-
expect(this.response.status).to.be.lt(300)
|
|
166
|
+
this._checkResponseReady()
|
|
167
|
+
expect(this.response.status).to.be.gte(200)
|
|
168
|
+
expect(this.response.status).to.be.lt(300)
|
|
166
169
|
}
|
|
167
170
|
|
|
168
171
|
/**
|
|
@@ -183,19 +186,19 @@ class JSONResponse extends Helper {
|
|
|
183
186
|
* @param {object} json
|
|
184
187
|
*/
|
|
185
188
|
seeResponseContainsJson(json = {}) {
|
|
186
|
-
this._checkResponseReady()
|
|
189
|
+
this._checkResponseReady()
|
|
187
190
|
if (Array.isArray(this.response.data)) {
|
|
188
|
-
let fails = 0
|
|
191
|
+
let fails = 0
|
|
189
192
|
for (const el of this.response.data) {
|
|
190
193
|
try {
|
|
191
|
-
expect(el).to.deep.match(json)
|
|
194
|
+
expect(el).to.deep.match(json)
|
|
192
195
|
} catch (err) {
|
|
193
|
-
fails
|
|
196
|
+
fails++
|
|
194
197
|
}
|
|
195
198
|
}
|
|
196
|
-
expect(fails < this.response.data.length, `No elements in array matched ${JSON.stringify(json)}`).to.be.true
|
|
199
|
+
expect(fails < this.response.data.length, `No elements in array matched ${JSON.stringify(json)}`).to.be.true
|
|
197
200
|
} else {
|
|
198
|
-
expect(this.response.data).to.deep.match(json)
|
|
201
|
+
expect(this.response.data).to.deep.match(json)
|
|
199
202
|
}
|
|
200
203
|
}
|
|
201
204
|
|
|
@@ -217,11 +220,11 @@ class JSONResponse extends Helper {
|
|
|
217
220
|
* @param {object} json
|
|
218
221
|
*/
|
|
219
222
|
dontSeeResponseContainsJson(json = {}) {
|
|
220
|
-
this._checkResponseReady()
|
|
223
|
+
this._checkResponseReady()
|
|
221
224
|
if (Array.isArray(this.response.data)) {
|
|
222
|
-
this.response.data.forEach(data => expect(data).not.to.deep.match(json))
|
|
225
|
+
this.response.data.forEach((data) => expect(data).not.to.deep.match(json))
|
|
223
226
|
} else {
|
|
224
|
-
expect(this.response.data).not.to.deep.match(json)
|
|
227
|
+
expect(this.response.data).not.to.deep.match(json)
|
|
225
228
|
}
|
|
226
229
|
}
|
|
227
230
|
|
|
@@ -245,11 +248,11 @@ class JSONResponse extends Helper {
|
|
|
245
248
|
* @param {array} keys
|
|
246
249
|
*/
|
|
247
250
|
seeResponseContainsKeys(keys = []) {
|
|
248
|
-
this._checkResponseReady()
|
|
251
|
+
this._checkResponseReady()
|
|
249
252
|
if (Array.isArray(this.response.data)) {
|
|
250
|
-
this.response.data.forEach(data => expect(data).to.include.keys(keys))
|
|
253
|
+
this.response.data.forEach((data) => expect(data).to.include.keys(keys))
|
|
251
254
|
} else {
|
|
252
|
-
expect(this.response.data).to.include.keys(keys)
|
|
255
|
+
expect(this.response.data).to.include.keys(keys)
|
|
253
256
|
}
|
|
254
257
|
}
|
|
255
258
|
|
|
@@ -267,10 +270,10 @@ class JSONResponse extends Helper {
|
|
|
267
270
|
* @param {function} fn
|
|
268
271
|
*/
|
|
269
272
|
seeResponseValidByCallback(fn) {
|
|
270
|
-
this._checkResponseReady()
|
|
271
|
-
fn({ ...this.response, expect })
|
|
272
|
-
const body = fn.toString()
|
|
273
|
-
fn.toString = () => `${body.split('\n')[1]}
|
|
273
|
+
this._checkResponseReady()
|
|
274
|
+
fn({ ...this.response, expect })
|
|
275
|
+
const body = fn.toString()
|
|
276
|
+
fn.toString = () => `${body.split('\n')[1]}...`
|
|
274
277
|
}
|
|
275
278
|
|
|
276
279
|
/**
|
|
@@ -284,8 +287,8 @@ class JSONResponse extends Helper {
|
|
|
284
287
|
* @param {object} resp
|
|
285
288
|
*/
|
|
286
289
|
seeResponseEquals(resp) {
|
|
287
|
-
this._checkResponseReady()
|
|
288
|
-
expect(this.response.data).to.deep.equal(resp)
|
|
290
|
+
this._checkResponseReady()
|
|
291
|
+
expect(this.response.data).to.deep.equal(resp)
|
|
289
292
|
}
|
|
290
293
|
|
|
291
294
|
/**
|
|
@@ -316,22 +319,22 @@ class JSONResponse extends Helper {
|
|
|
316
319
|
* @param {any} fnOrSchema
|
|
317
320
|
*/
|
|
318
321
|
seeResponseMatchesJsonSchema(fnOrSchema) {
|
|
319
|
-
this._checkResponseReady()
|
|
320
|
-
let schema = fnOrSchema
|
|
322
|
+
this._checkResponseReady()
|
|
323
|
+
let schema = fnOrSchema
|
|
321
324
|
if (typeof fnOrSchema === 'function') {
|
|
322
|
-
schema = fnOrSchema(joi)
|
|
323
|
-
const body = fnOrSchema.toString()
|
|
324
|
-
fnOrSchema.toString = () => `${body.split('\n')[1]}
|
|
325
|
+
schema = fnOrSchema(joi)
|
|
326
|
+
const body = fnOrSchema.toString()
|
|
327
|
+
fnOrSchema.toString = () => `${body.split('\n')[1]}...`
|
|
325
328
|
}
|
|
326
|
-
if (!schema) throw new Error('Empty Joi schema provided, see https://joi.dev/ for details')
|
|
327
|
-
if (!joi.isSchema(schema)) throw new Error('Invalid Joi schema provided, see https://joi.dev/ for details')
|
|
328
|
-
schema.toString = () => schema.describe()
|
|
329
|
-
joi.assert(this.response.data, schema)
|
|
329
|
+
if (!schema) throw new Error('Empty Joi schema provided, see https://joi.dev/ for details')
|
|
330
|
+
if (!joi.isSchema(schema)) throw new Error('Invalid Joi schema provided, see https://joi.dev/ for details')
|
|
331
|
+
schema.toString = () => schema.describe()
|
|
332
|
+
joi.assert(this.response.data, schema)
|
|
330
333
|
}
|
|
331
334
|
|
|
332
335
|
_checkResponseReady() {
|
|
333
|
-
if (!this.response) throw new Error('Response is not available')
|
|
336
|
+
if (!this.response) throw new Error('Response is not available')
|
|
334
337
|
}
|
|
335
338
|
}
|
|
336
339
|
|
|
337
|
-
|
|
340
|
+
module.exports = JSONResponse
|