@cuppet/core 1.0.17 → 1.1.0
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.
|
@@ -7,7 +7,7 @@ Given('that I send a {string} request to {string}', async function (method, path
|
|
|
7
7
|
await apiSteps.sendRequest(method, path);
|
|
8
8
|
});
|
|
9
9
|
When(
|
|
10
|
-
'I send a {string} request to {string} with http header {string} and value {string}',
|
|
10
|
+
'that I send a {string} request to {string} with http header {string} and value {string}',
|
|
11
11
|
async function (method, path, headerName, headerValue) {
|
|
12
12
|
const name = await dataStorage.checkForSavedVariable(headerName);
|
|
13
13
|
const value = await dataStorage.checkForSavedVariable(headerValue);
|
|
@@ -35,6 +35,10 @@ Given('that I have request body', async function (docString) {
|
|
|
35
35
|
const body = JSON.stringify(docString);
|
|
36
36
|
await apiSteps.prepareRequestBody(body);
|
|
37
37
|
});
|
|
38
|
+
Given('that I have a multipart request body', async function (docString) {
|
|
39
|
+
const body = JSON.parse(docString);
|
|
40
|
+
await apiSteps.buildMultipartFormData(body);
|
|
41
|
+
});
|
|
38
42
|
Given(
|
|
39
43
|
'I put {string} to {string} property of {string} element in the body',
|
|
40
44
|
async function (value, property, parentObj) {
|
|
@@ -50,3 +54,6 @@ Given('I validate that the page is a valid XML', async function () {
|
|
|
50
54
|
const currentPath = main.extractPath(this.page, true);
|
|
51
55
|
await apiSteps.validateXMLEndpoint(currentPath);
|
|
52
56
|
});
|
|
57
|
+
Then('the response header {string} should be {string}', async function (header, value) {
|
|
58
|
+
await apiSteps.validateResponseHeader(header, value);
|
|
59
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cuppet/core",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Core testing framework components for Cuppet - BDD framework based on Cucumber and Puppeteer",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"files": [
|
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
"chai": "^4.3.7",
|
|
37
37
|
"lighthouse": "^12.1.0",
|
|
38
38
|
"mime": "^3.0.0",
|
|
39
|
+
"mime-types": "^3.0.1",
|
|
39
40
|
"moment": "^2.30.1",
|
|
40
41
|
"pa11y": "^8.0.0",
|
|
41
42
|
"pa11y-reporter-html": "^2.0.0",
|
|
@@ -61,8 +62,10 @@
|
|
|
61
62
|
"scripts": {
|
|
62
63
|
"test": "cucumber-js features/tests",
|
|
63
64
|
"postinstall": "node postinstall.js",
|
|
64
|
-
"lint": "eslint .",
|
|
65
|
-
"format": "prettier --
|
|
65
|
+
"lint:check": "eslint .",
|
|
66
|
+
"format:check": "prettier --check .",
|
|
67
|
+
"format": "eslint . --fix && prettier --write .",
|
|
68
|
+
"verify": "yarn lint:check && yarn format:check"
|
|
66
69
|
},
|
|
67
70
|
"repository": {
|
|
68
71
|
"type": "git",
|
package/src/apiFunctions.js
CHANGED
|
@@ -3,12 +3,17 @@ const config = require('config');
|
|
|
3
3
|
const storage = require('./dataStorage');
|
|
4
4
|
const xml2js = require('xml2js');
|
|
5
5
|
const assert = require('chai').assert;
|
|
6
|
+
const fs = require('fs');
|
|
7
|
+
const mime = require('mime-types');
|
|
8
|
+
const FormData = require('form-data');
|
|
6
9
|
|
|
7
10
|
module.exports = {
|
|
8
11
|
/** @type {object} */
|
|
9
12
|
response: null,
|
|
10
13
|
/** @type {object} */
|
|
11
14
|
request: null,
|
|
15
|
+
/** @type {object} */
|
|
16
|
+
formData: null,
|
|
12
17
|
|
|
13
18
|
/**
|
|
14
19
|
* Prepare path for API test usage
|
|
@@ -40,11 +45,15 @@ module.exports = {
|
|
|
40
45
|
'Content-Type': 'application/json',
|
|
41
46
|
Accept: 'application/json',
|
|
42
47
|
};
|
|
48
|
+
if (this.formData) {
|
|
49
|
+
defaultHeaders = {};
|
|
50
|
+
Object.assign(defaultHeaders, this.formData.getHeaders());
|
|
51
|
+
}
|
|
43
52
|
if (config.has('api.x-api-key')) {
|
|
44
53
|
defaultHeaders['X-Api-Key'] = config.get('api.x-api-key');
|
|
45
54
|
}
|
|
46
55
|
if (config.has('api.Authorization')) {
|
|
47
|
-
defaultHeaders['
|
|
56
|
+
defaultHeaders['Authorization'] = config.get('api.Authorization');
|
|
48
57
|
}
|
|
49
58
|
if (headers && defaultHeaders) {
|
|
50
59
|
defaultHeaders = {
|
|
@@ -97,6 +106,9 @@ module.exports = {
|
|
|
97
106
|
if (this.request) {
|
|
98
107
|
data = this.request;
|
|
99
108
|
}
|
|
109
|
+
if (this.formData) {
|
|
110
|
+
data = this.formData;
|
|
111
|
+
}
|
|
100
112
|
try {
|
|
101
113
|
this.response = await axios.request({
|
|
102
114
|
url: apiUrl,
|
|
@@ -104,9 +116,10 @@ module.exports = {
|
|
|
104
116
|
...(Object.keys(auth).length && { auth }),
|
|
105
117
|
// The data is conditionally added to the request, because it's not used with GET requests and creates conflict.
|
|
106
118
|
// The following checks if data object is not empty, returns data object if not empty or skip if empty.
|
|
107
|
-
...(Object.keys(data).length && { data }),
|
|
119
|
+
...((data instanceof FormData || Object.keys(data).length) && { data }),
|
|
108
120
|
headers: requestHeaders,
|
|
109
121
|
});
|
|
122
|
+
|
|
110
123
|
return this.response;
|
|
111
124
|
} catch (error) {
|
|
112
125
|
console.log('Request has failed, use response code step definition to validate the response!');
|
|
@@ -156,7 +169,7 @@ module.exports = {
|
|
|
156
169
|
validateResponseCode: async function (code) {
|
|
157
170
|
if (this.response.status !== Number(code)) {
|
|
158
171
|
throw new Error(
|
|
159
|
-
`
|
|
172
|
+
`Unexpected response code, code: ${this.response.status}. Response: ${JSON.stringify(this.response.data)}`
|
|
160
173
|
);
|
|
161
174
|
}
|
|
162
175
|
},
|
|
@@ -262,32 +275,48 @@ module.exports = {
|
|
|
262
275
|
},
|
|
263
276
|
|
|
264
277
|
/**
|
|
265
|
-
*
|
|
266
|
-
* @param {string}
|
|
267
|
-
* @param {string}
|
|
268
|
-
* @param {object} reqHeaders - request headers
|
|
269
|
-
* @param {string} resHeaders - response headers
|
|
270
|
-
* @param {boolean} flag - direction of presence (true/false)
|
|
278
|
+
* Validate response header
|
|
279
|
+
* @param {string} header - header name
|
|
280
|
+
* @param {string} value - header value
|
|
271
281
|
* @returns {Promise<void>}
|
|
272
282
|
*/
|
|
273
|
-
validateResponseHeader: async function (
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
const
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
283
|
+
validateResponseHeader: async function (header, value) {
|
|
284
|
+
// Resolve header and value from variables or user input.
|
|
285
|
+
// The header is checked directly for faster execution as it is less likely to contain variables.
|
|
286
|
+
const resolveHeader = await storage.checkForVariable(header);
|
|
287
|
+
const resolveValue = await storage.checkForSavedVariable(value);
|
|
288
|
+
const actualValue = this.response.headers[resolveHeader.toLowerCase()];
|
|
289
|
+
assert.isDefined(actualValue, `The response header "${resolveHeader}" is not found!`);
|
|
290
|
+
assert.strictEqual(
|
|
291
|
+
actualValue,
|
|
292
|
+
resolveValue,
|
|
293
|
+
`The response header "${resolveHeader}" does not have the expected value`
|
|
294
|
+
);
|
|
295
|
+
},
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Build multipart/form-data request body
|
|
299
|
+
* If you want to send a file, you need to pass the file name (not the path) as a string.
|
|
300
|
+
* Please use the files from the files folder.
|
|
301
|
+
* @param {object} data - the data to be sent in the request body
|
|
302
|
+
* @returns {Promise<Object>} - returns the request body object
|
|
303
|
+
*/
|
|
304
|
+
buildMultipartFormData: async function (data) {
|
|
305
|
+
const filePath = config.get('filePath');
|
|
306
|
+
const formData = new FormData();
|
|
307
|
+
for (const [key, value] of Object.entries(data)) {
|
|
308
|
+
if (key === 'file') {
|
|
309
|
+
const mimeType = mime.contentType(value) || 'application/octet-stream';
|
|
310
|
+
formData.append('file', fs.createReadStream(filePath + value), {
|
|
311
|
+
filename: value,
|
|
312
|
+
contentType: mimeType,
|
|
313
|
+
});
|
|
314
|
+
formData.append('type', mimeType);
|
|
315
|
+
} else {
|
|
316
|
+
formData.append(key, await storage.checkForSavedVariable(value));
|
|
317
|
+
}
|
|
291
318
|
}
|
|
319
|
+
this.formData = formData;
|
|
320
|
+
return this.formData;
|
|
292
321
|
},
|
|
293
322
|
};
|