@cuppet/core 1.0.17 → 1.1.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.
|
@@ -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.
|
|
3
|
+
"version": "1.1.1",
|
|
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,6 +3,9 @@ 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} */
|
|
@@ -40,11 +43,15 @@ module.exports = {
|
|
|
40
43
|
'Content-Type': 'application/json',
|
|
41
44
|
Accept: 'application/json',
|
|
42
45
|
};
|
|
46
|
+
if (this.formData) {
|
|
47
|
+
defaultHeaders = {};
|
|
48
|
+
Object.assign(defaultHeaders, this.formData.getHeaders());
|
|
49
|
+
}
|
|
43
50
|
if (config.has('api.x-api-key')) {
|
|
44
51
|
defaultHeaders['X-Api-Key'] = config.get('api.x-api-key');
|
|
45
52
|
}
|
|
46
53
|
if (config.has('api.Authorization')) {
|
|
47
|
-
defaultHeaders['
|
|
54
|
+
defaultHeaders['Authorization'] = config.get('api.Authorization');
|
|
48
55
|
}
|
|
49
56
|
if (headers && defaultHeaders) {
|
|
50
57
|
defaultHeaders = {
|
|
@@ -104,9 +111,10 @@ module.exports = {
|
|
|
104
111
|
...(Object.keys(auth).length && { auth }),
|
|
105
112
|
// The data is conditionally added to the request, because it's not used with GET requests and creates conflict.
|
|
106
113
|
// 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 }),
|
|
114
|
+
...((data instanceof FormData || Object.keys(data).length) && { data }),
|
|
108
115
|
headers: requestHeaders,
|
|
109
116
|
});
|
|
117
|
+
|
|
110
118
|
return this.response;
|
|
111
119
|
} catch (error) {
|
|
112
120
|
console.log('Request has failed, use response code step definition to validate the response!');
|
|
@@ -156,7 +164,7 @@ module.exports = {
|
|
|
156
164
|
validateResponseCode: async function (code) {
|
|
157
165
|
if (this.response.status !== Number(code)) {
|
|
158
166
|
throw new Error(
|
|
159
|
-
`
|
|
167
|
+
`Unexpected response code, code: ${this.response.status}. Response: ${JSON.stringify(this.response.data)}`
|
|
160
168
|
);
|
|
161
169
|
}
|
|
162
170
|
},
|
|
@@ -262,32 +270,48 @@ module.exports = {
|
|
|
262
270
|
},
|
|
263
271
|
|
|
264
272
|
/**
|
|
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)
|
|
273
|
+
* Validate response header
|
|
274
|
+
* @param {string} header - header name
|
|
275
|
+
* @param {string} value - header value
|
|
271
276
|
* @returns {Promise<void>}
|
|
272
277
|
*/
|
|
273
|
-
validateResponseHeader: async function (
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
const
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
278
|
+
validateResponseHeader: async function (header, value) {
|
|
279
|
+
// Resolve header and value from variables or user input.
|
|
280
|
+
// The header is checked directly for faster execution as it is less likely to contain variables.
|
|
281
|
+
const resolveHeader = await storage.checkForVariable(header);
|
|
282
|
+
const resolveValue = await storage.checkForSavedVariable(value);
|
|
283
|
+
const actualValue = this.response.headers[resolveHeader.toLowerCase()];
|
|
284
|
+
assert.isDefined(actualValue, `The response header "${resolveHeader}" is not found!`);
|
|
285
|
+
assert.strictEqual(
|
|
286
|
+
actualValue,
|
|
287
|
+
resolveValue,
|
|
288
|
+
`The response header "${resolveHeader}" does not have the expected value`
|
|
289
|
+
);
|
|
290
|
+
},
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Build multipart/form-data request body
|
|
294
|
+
* If you want to send a file, you need to pass the file name (not the path) as a string.
|
|
295
|
+
* Please use the files from the files folder.
|
|
296
|
+
* @param {object} data - the data to be sent in the request body
|
|
297
|
+
* @returns {Promise<Object>} - returns the request body object
|
|
298
|
+
*/
|
|
299
|
+
buildMultipartFormData: async function (data) {
|
|
300
|
+
const filePath = config.get('filePath');
|
|
301
|
+
const formData = new FormData();
|
|
302
|
+
for (const [key, value] of Object.entries(data)) {
|
|
303
|
+
if (key === 'file') {
|
|
304
|
+
const mimeType = mime.contentType(value) || 'application/octet-stream';
|
|
305
|
+
formData.append('file', fs.createReadStream(filePath + value), {
|
|
306
|
+
filename: value,
|
|
307
|
+
contentType: mimeType,
|
|
308
|
+
});
|
|
309
|
+
formData.append('type', mimeType);
|
|
310
|
+
} else {
|
|
311
|
+
formData.append(key, await storage.checkForSavedVariable(value));
|
|
312
|
+
}
|
|
291
313
|
}
|
|
314
|
+
this.request = formData;
|
|
315
|
+
return this.request;
|
|
292
316
|
},
|
|
293
317
|
};
|