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