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/FileSystem.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
const assert = require('assert')
|
|
2
|
-
const path = require('path')
|
|
3
|
-
const fs = require('fs')
|
|
1
|
+
const assert = require('assert')
|
|
2
|
+
const path = require('path')
|
|
3
|
+
const fs = require('fs')
|
|
4
4
|
|
|
5
|
-
const Helper = require('@codeceptjs/helper')
|
|
6
|
-
const { fileExists } = require('../utils')
|
|
7
|
-
const { fileIncludes } = require('../assert/include')
|
|
8
|
-
const { fileEquals } = require('../assert/equal')
|
|
5
|
+
const Helper = require('@codeceptjs/helper')
|
|
6
|
+
const { fileExists } = require('../utils')
|
|
7
|
+
const { fileIncludes } = require('../assert/include')
|
|
8
|
+
const { fileEquals } = require('../assert/equal')
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Helper for testing filesystem.
|
|
@@ -32,13 +32,13 @@ const { fileEquals } = require('../assert/equal');
|
|
|
32
32
|
*/
|
|
33
33
|
class FileSystem extends Helper {
|
|
34
34
|
constructor() {
|
|
35
|
-
super()
|
|
36
|
-
this.dir = global.codecept_dir
|
|
37
|
-
this.file = ''
|
|
35
|
+
super()
|
|
36
|
+
this.dir = global.codecept_dir
|
|
37
|
+
this.file = ''
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
_before() {
|
|
41
|
-
this.debugSection('Dir', this.dir)
|
|
41
|
+
this.debugSection('Dir', this.dir)
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
/**
|
|
@@ -47,8 +47,8 @@ class FileSystem extends Helper {
|
|
|
47
47
|
* @param {string} openPath
|
|
48
48
|
*/
|
|
49
49
|
amInPath(openPath) {
|
|
50
|
-
this.dir = path.join(global.codecept_dir, openPath)
|
|
51
|
-
this.debugSection('Dir', this.dir)
|
|
50
|
+
this.dir = path.join(global.codecept_dir, openPath)
|
|
51
|
+
this.debugSection('Dir', this.dir)
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
/**
|
|
@@ -57,7 +57,7 @@ class FileSystem extends Helper {
|
|
|
57
57
|
* @param {string} text
|
|
58
58
|
*/
|
|
59
59
|
writeToFile(name, text) {
|
|
60
|
-
fs.writeFileSync(path.join(this.dir, name), text)
|
|
60
|
+
fs.writeFileSync(path.join(this.dir, name), text)
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
/**
|
|
@@ -65,9 +65,9 @@ class FileSystem extends Helper {
|
|
|
65
65
|
* @param {string} name
|
|
66
66
|
*/
|
|
67
67
|
seeFile(name) {
|
|
68
|
-
this.file = path.join(this.dir, name)
|
|
69
|
-
this.debugSection('File', this.file)
|
|
70
|
-
assert.ok(fileExists(this.file), `File ${name} not found in ${this.dir}`)
|
|
68
|
+
this.file = path.join(this.dir, name)
|
|
69
|
+
this.debugSection('File', this.file)
|
|
70
|
+
assert.ok(fileExists(this.file), `File ${name} not found in ${this.dir}`)
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
/**
|
|
@@ -83,31 +83,31 @@ class FileSystem extends Helper {
|
|
|
83
83
|
* @param {number} [sec=1] seconds to wait
|
|
84
84
|
*/
|
|
85
85
|
async waitForFile(name, sec = 1) {
|
|
86
|
-
if (sec === 0) assert.fail('Use `seeFile` instead of waiting 0 seconds!')
|
|
87
|
-
const waitTimeout = sec * 1000
|
|
88
|
-
this.file = path.join(this.dir, name)
|
|
89
|
-
this.debugSection('File', this.file)
|
|
86
|
+
if (sec === 0) assert.fail('Use `seeFile` instead of waiting 0 seconds!')
|
|
87
|
+
const waitTimeout = sec * 1000
|
|
88
|
+
this.file = path.join(this.dir, name)
|
|
89
|
+
this.debugSection('File', this.file)
|
|
90
90
|
return isFileExists(this.file, waitTimeout).catch(() => {
|
|
91
|
-
throw new Error(`file (${name}) still not present in directory ${this.dir} after ${waitTimeout / 1000} sec`)
|
|
92
|
-
})
|
|
91
|
+
throw new Error(`file (${name}) still not present in directory ${this.dir} after ${waitTimeout / 1000} sec`)
|
|
92
|
+
})
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
/**
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
96
|
+
* Checks that file with a name including given text exists in the current directory.
|
|
97
|
+
*
|
|
98
|
+
*```js
|
|
99
|
+
* I.handleDownloads();
|
|
100
|
+
* I.click('Download as PDF');
|
|
101
|
+
* I.amInPath('output/downloads');
|
|
102
|
+
* I.seeFileNameMatching('.pdf');
|
|
103
|
+
* ```
|
|
104
|
+
* @param {string} text
|
|
105
|
+
*/
|
|
106
106
|
seeFileNameMatching(text) {
|
|
107
107
|
assert.ok(
|
|
108
|
-
this.grabFileNames().some(file => file.includes(text)),
|
|
108
|
+
this.grabFileNames().some((file) => file.includes(text)),
|
|
109
109
|
`File name which contains ${text} not found in ${this.dir}`,
|
|
110
|
-
)
|
|
110
|
+
)
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
/**
|
|
@@ -116,8 +116,8 @@ class FileSystem extends Helper {
|
|
|
116
116
|
* @param {string} [encoding='utf8']
|
|
117
117
|
*/
|
|
118
118
|
seeInThisFile(text, encoding = 'utf8') {
|
|
119
|
-
const content = getFileContents(this.file, encoding)
|
|
120
|
-
fileIncludes(this.file).assert(text, content)
|
|
119
|
+
const content = getFileContents(this.file, encoding)
|
|
120
|
+
fileIncludes(this.file).assert(text, content)
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
/**
|
|
@@ -126,8 +126,8 @@ class FileSystem extends Helper {
|
|
|
126
126
|
* @param {string} [encoding='utf8']
|
|
127
127
|
*/
|
|
128
128
|
dontSeeInThisFile(text, encoding = 'utf8') {
|
|
129
|
-
const content = getFileContents(this.file, encoding)
|
|
130
|
-
fileIncludes(this.file).negate(text, content)
|
|
129
|
+
const content = getFileContents(this.file, encoding)
|
|
130
|
+
fileIncludes(this.file).negate(text, content)
|
|
131
131
|
}
|
|
132
132
|
|
|
133
133
|
/**
|
|
@@ -136,8 +136,8 @@ class FileSystem extends Helper {
|
|
|
136
136
|
* @param {string} [encoding='utf8']
|
|
137
137
|
*/
|
|
138
138
|
seeFileContentsEqual(text, encoding = 'utf8') {
|
|
139
|
-
const content = getFileContents(this.file, encoding)
|
|
140
|
-
fileEquals(this.file).assert(text, content)
|
|
139
|
+
const content = getFileContents(this.file, encoding)
|
|
140
|
+
fileEquals(this.file).assert(text, content)
|
|
141
141
|
}
|
|
142
142
|
|
|
143
143
|
/**
|
|
@@ -147,11 +147,11 @@ class FileSystem extends Helper {
|
|
|
147
147
|
* @param {string} [encodingReference='utf8']
|
|
148
148
|
*/
|
|
149
149
|
seeFileContentsEqualReferenceFile(pathToReferenceFile, encoding = 'utf8', encodingReference = '') {
|
|
150
|
-
const content = getFileContents(this.file, encoding)
|
|
151
|
-
assert.ok(fileExists(pathToReferenceFile), `Reference file ${pathToReferenceFile} not found.`)
|
|
152
|
-
encodingReference = encodingReference || encoding
|
|
153
|
-
const expectedContent = getFileContents(pathToReferenceFile, encodingReference)
|
|
154
|
-
fileEquals(this.file).assert(expectedContent, content)
|
|
150
|
+
const content = getFileContents(this.file, encoding)
|
|
151
|
+
assert.ok(fileExists(pathToReferenceFile), `Reference file ${pathToReferenceFile} not found.`)
|
|
152
|
+
encodingReference = encodingReference || encoding
|
|
153
|
+
const expectedContent = getFileContents(pathToReferenceFile, encodingReference)
|
|
154
|
+
fileEquals(this.file).assert(expectedContent, content)
|
|
155
155
|
}
|
|
156
156
|
|
|
157
157
|
/**
|
|
@@ -160,27 +160,26 @@ class FileSystem extends Helper {
|
|
|
160
160
|
* @param {string} [encoding='utf8']
|
|
161
161
|
*/
|
|
162
162
|
dontSeeFileContentsEqual(text, encoding = 'utf8') {
|
|
163
|
-
const content = getFileContents(this.file, encoding)
|
|
164
|
-
fileEquals(this.file).negate(text, content)
|
|
163
|
+
const content = getFileContents(this.file, encoding)
|
|
164
|
+
fileEquals(this.file).negate(text, content)
|
|
165
165
|
}
|
|
166
166
|
|
|
167
167
|
/**
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
168
|
+
* Returns file names in current directory.
|
|
169
|
+
*
|
|
170
|
+
* ```js
|
|
171
|
+
* I.handleDownloads();
|
|
172
|
+
* I.click('Download Files');
|
|
173
|
+
* I.amInPath('output/downloads');
|
|
174
|
+
* const downloadedFileNames = I.grabFileNames();
|
|
175
|
+
* ```
|
|
176
|
+
*/
|
|
177
177
|
grabFileNames() {
|
|
178
|
-
return fs.readdirSync(this.dir)
|
|
179
|
-
.filter(item => !fs.lstatSync(path.join(this.dir, item)).isDirectory());
|
|
178
|
+
return fs.readdirSync(this.dir).filter((item) => !fs.lstatSync(path.join(this.dir, item)).isDirectory())
|
|
180
179
|
}
|
|
181
180
|
}
|
|
182
181
|
|
|
183
|
-
module.exports = FileSystem
|
|
182
|
+
module.exports = FileSystem
|
|
184
183
|
|
|
185
184
|
/**
|
|
186
185
|
* @param {string} file
|
|
@@ -189,9 +188,9 @@ module.exports = FileSystem;
|
|
|
189
188
|
* @returns {string}
|
|
190
189
|
*/
|
|
191
190
|
function getFileContents(file, encoding = 'utf8') {
|
|
192
|
-
if (!file) assert.fail('No files were opened, please use seeFile action')
|
|
193
|
-
if (encoding === '') assert.fail('Encoding is an empty string, please set a valid encoding')
|
|
194
|
-
return fs.readFileSync(file, encoding)
|
|
191
|
+
if (!file) assert.fail('No files were opened, please use seeFile action')
|
|
192
|
+
if (encoding === '') assert.fail('Encoding is an empty string, please set a valid encoding')
|
|
193
|
+
return fs.readFileSync(file, encoding)
|
|
195
194
|
}
|
|
196
195
|
|
|
197
196
|
/**
|
|
@@ -201,28 +200,28 @@ function getFileContents(file, encoding = 'utf8') {
|
|
|
201
200
|
* @returns {Promise<any>}
|
|
202
201
|
*/
|
|
203
202
|
function isFileExists(file, timeout) {
|
|
204
|
-
return new Promise((
|
|
203
|
+
return new Promise((resolve, reject) => {
|
|
205
204
|
const timer = setTimeout(() => {
|
|
206
|
-
watcher.close()
|
|
207
|
-
reject(new Error('File did not exists and was not created during the timeout.'))
|
|
208
|
-
}, timeout)
|
|
205
|
+
watcher.close()
|
|
206
|
+
reject(new Error('File did not exists and was not created during the timeout.'))
|
|
207
|
+
}, timeout)
|
|
209
208
|
|
|
210
|
-
const dir = path.dirname(file)
|
|
211
|
-
const basename = path.basename(file)
|
|
209
|
+
const dir = path.dirname(file)
|
|
210
|
+
const basename = path.basename(file)
|
|
212
211
|
const watcher = fs.watch(dir, (eventType, filename) => {
|
|
213
212
|
if (eventType === 'rename' && filename === basename) {
|
|
214
|
-
clearTimeout(timer)
|
|
215
|
-
watcher.close()
|
|
216
|
-
resolve()
|
|
213
|
+
clearTimeout(timer)
|
|
214
|
+
watcher.close()
|
|
215
|
+
resolve()
|
|
217
216
|
}
|
|
218
|
-
})
|
|
217
|
+
})
|
|
219
218
|
|
|
220
219
|
fs.access(file, fs.constants.R_OK, (err) => {
|
|
221
220
|
if (!err) {
|
|
222
|
-
clearTimeout(timer)
|
|
223
|
-
watcher.close()
|
|
224
|
-
resolve()
|
|
221
|
+
clearTimeout(timer)
|
|
222
|
+
watcher.close()
|
|
223
|
+
resolve()
|
|
225
224
|
}
|
|
226
|
-
})
|
|
227
|
-
})
|
|
225
|
+
})
|
|
226
|
+
})
|
|
228
227
|
}
|
package/lib/helper/GraphQL.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
const axios = require('axios').default
|
|
2
|
-
const Helper = require('@codeceptjs/helper')
|
|
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 @@ 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
|
-
|
|
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
|
-
module.exports = GraphQL
|
|
230
|
+
module.exports = GraphQL
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
const path = require('path')
|
|
1
|
+
const path = require('path')
|
|
2
2
|
|
|
3
|
-
const Helper = require('@codeceptjs/helper')
|
|
4
|
-
const GraphQL = require('./GraphQL')
|
|
3
|
+
const Helper = require('@codeceptjs/helper')
|
|
4
|
+
const GraphQL = require('./GraphQL')
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Helper for managing remote data using GraphQL queries.
|
|
@@ -151,52 +151,52 @@ const GraphQL = require('./GraphQL');
|
|
|
151
151
|
*/
|
|
152
152
|
class GraphQLDataFactory extends Helper {
|
|
153
153
|
constructor(config) {
|
|
154
|
-
super(config)
|
|
154
|
+
super(config)
|
|
155
155
|
|
|
156
156
|
const defaultConfig = {
|
|
157
157
|
cleanup: true,
|
|
158
158
|
GraphQL: {},
|
|
159
159
|
factories: {},
|
|
160
|
-
}
|
|
161
|
-
this.config = Object.assign(defaultConfig, this.config)
|
|
160
|
+
}
|
|
161
|
+
this.config = Object.assign(defaultConfig, this.config)
|
|
162
162
|
|
|
163
163
|
if (this.config.headers) {
|
|
164
|
-
this.config.GraphQL.defaultHeaders = this.config.headers
|
|
164
|
+
this.config.GraphQL.defaultHeaders = this.config.headers
|
|
165
165
|
}
|
|
166
166
|
if (this.config.onRequest) {
|
|
167
|
-
this.config.GraphQL.onRequest = this.config.onRequest
|
|
167
|
+
this.config.GraphQL.onRequest = this.config.onRequest
|
|
168
168
|
}
|
|
169
|
-
this.graphqlHelper = new GraphQL(Object.assign(this.config.GraphQL, { endpoint: this.config.endpoint }))
|
|
170
|
-
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
|
|
171
171
|
|
|
172
|
-
this.created = {}
|
|
173
|
-
Object.keys(this.factories).forEach(f => (this.created[f] = []))
|
|
172
|
+
this.created = {}
|
|
173
|
+
Object.keys(this.factories).forEach((f) => (this.created[f] = []))
|
|
174
174
|
}
|
|
175
175
|
|
|
176
176
|
static _checkRequirements() {
|
|
177
177
|
try {
|
|
178
|
-
require('axios')
|
|
179
|
-
require('rosie')
|
|
178
|
+
require('axios')
|
|
179
|
+
require('rosie')
|
|
180
180
|
} catch (e) {
|
|
181
|
-
return ['axios', 'rosie']
|
|
181
|
+
return ['axios', 'rosie']
|
|
182
182
|
}
|
|
183
183
|
}
|
|
184
184
|
|
|
185
185
|
_after() {
|
|
186
186
|
if (!this.config.cleanup) {
|
|
187
|
-
return Promise.resolve()
|
|
187
|
+
return Promise.resolve()
|
|
188
188
|
}
|
|
189
|
-
const promises = []
|
|
189
|
+
const promises = []
|
|
190
190
|
// clean up all created items
|
|
191
191
|
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)`)
|
|
192
|
+
const createdItems = this.created[mutationName]
|
|
193
|
+
if (!createdItems.length) continue
|
|
194
|
+
this.debug(`Deleting ${createdItems.length} ${mutationName}(s)`)
|
|
195
195
|
for (const itemData of createdItems) {
|
|
196
|
-
promises.push(this._requestDelete(mutationName, itemData))
|
|
196
|
+
promises.push(this._requestDelete(mutationName, itemData))
|
|
197
197
|
}
|
|
198
198
|
}
|
|
199
|
-
return Promise.all(promises)
|
|
199
|
+
return Promise.all(promises)
|
|
200
200
|
}
|
|
201
201
|
|
|
202
202
|
/**
|
|
@@ -214,9 +214,9 @@ class GraphQLDataFactory extends Helper {
|
|
|
214
214
|
* @param {*} params predefined parameters
|
|
215
215
|
*/
|
|
216
216
|
mutateData(operation, params) {
|
|
217
|
-
const variables = this._createItem(operation, params)
|
|
218
|
-
this.debug(`Creating ${operation} ${JSON.stringify(variables)}`)
|
|
219
|
-
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)
|
|
220
220
|
}
|
|
221
221
|
|
|
222
222
|
/**
|
|
@@ -235,26 +235,26 @@ class GraphQLDataFactory extends Helper {
|
|
|
235
235
|
* @param {*} params
|
|
236
236
|
*/
|
|
237
237
|
mutateMultiple(operation, times, params) {
|
|
238
|
-
const promises = []
|
|
238
|
+
const promises = []
|
|
239
239
|
for (let i = 0; i < times; i++) {
|
|
240
|
-
promises.push(this.mutateData(operation, params))
|
|
240
|
+
promises.push(this.mutateData(operation, params))
|
|
241
241
|
}
|
|
242
|
-
return Promise.all(promises)
|
|
242
|
+
return Promise.all(promises)
|
|
243
243
|
}
|
|
244
244
|
|
|
245
245
|
_createItem(operation, data) {
|
|
246
246
|
if (!this.factories[operation]) {
|
|
247
|
-
throw new Error(`Mutation ${operation} is not defined in config.factories`)
|
|
247
|
+
throw new Error(`Mutation ${operation} is not defined in config.factories`)
|
|
248
248
|
}
|
|
249
|
-
let modulePath = this.factories[operation].factory
|
|
249
|
+
let modulePath = this.factories[operation].factory
|
|
250
250
|
try {
|
|
251
251
|
try {
|
|
252
|
-
require.resolve(modulePath)
|
|
252
|
+
require.resolve(modulePath)
|
|
253
253
|
} catch (e) {
|
|
254
|
-
modulePath = path.join(global.codecept_dir, modulePath)
|
|
254
|
+
modulePath = path.join(global.codecept_dir, modulePath)
|
|
255
255
|
}
|
|
256
|
-
const builder = require(modulePath)
|
|
257
|
-
return builder.build(data)
|
|
256
|
+
const builder = require(modulePath)
|
|
257
|
+
return builder.build(data)
|
|
258
258
|
} catch (err) {
|
|
259
259
|
throw new Error(`Couldn't load factory file from ${modulePath}, check that
|
|
260
260
|
|
|
@@ -265,7 +265,7 @@ class GraphQLDataFactory extends Helper {
|
|
|
265
265
|
points to valid factory file.
|
|
266
266
|
Factory file should export an object with build method.
|
|
267
267
|
|
|
268
|
-
Current file error: ${err.message}`)
|
|
268
|
+
Current file error: ${err.message}`)
|
|
269
269
|
}
|
|
270
270
|
}
|
|
271
271
|
|
|
@@ -277,13 +277,13 @@ class GraphQLDataFactory extends Helper {
|
|
|
277
277
|
* @param {*} variables to be sent along with the query
|
|
278
278
|
*/
|
|
279
279
|
_requestCreate(operation, variables) {
|
|
280
|
-
const { query } = this.factories[operation]
|
|
280
|
+
const { query } = this.factories[operation]
|
|
281
281
|
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
|
-
})
|
|
282
|
+
const data = response.data.data[operation]
|
|
283
|
+
this.created[operation].push(data)
|
|
284
|
+
this.debugSection('Created', `record: ${data}`)
|
|
285
|
+
return data
|
|
286
|
+
})
|
|
287
287
|
}
|
|
288
288
|
|
|
289
289
|
/**
|
|
@@ -294,16 +294,15 @@ class GraphQLDataFactory extends Helper {
|
|
|
294
294
|
* @param {*} data of the record to be deleted.
|
|
295
295
|
*/
|
|
296
296
|
_requestDelete(operation, data) {
|
|
297
|
-
const deleteOperation = this.factories[operation].revert(data)
|
|
298
|
-
const { query, variables } = deleteOperation
|
|
297
|
+
const deleteOperation = this.factories[operation].revert(data)
|
|
298
|
+
const { query, variables } = deleteOperation
|
|
299
299
|
|
|
300
|
-
return this.graphqlHelper.sendMutation(query, variables)
|
|
301
|
-
.
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
});
|
|
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
|
+
})
|
|
306
305
|
}
|
|
307
306
|
}
|
|
308
307
|
|
|
309
|
-
module.exports = GraphQLDataFactory
|
|
308
|
+
module.exports = GraphQLDataFactory
|