artes 1.0.51 โ 1.0.53
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/README.md +10 -7
- package/cucumber.config.js +3 -1
- package/executer.js +4 -2
- package/package.json +1 -1
- package/src/helper/executers/helper.js +6 -0
- package/src/helper/executers/testRunner.js +15 -2
- package/src/helper/stepFunctions/APIActions.js +163 -58
- package/src/stepDefinitions/API.steps.js +45 -5
package/README.md
CHANGED
|
@@ -42,13 +42,16 @@ npx artes [options]
|
|
|
42
42
|
|
|
43
43
|
### Options
|
|
44
44
|
|
|
45
|
-
| Option
|
|
46
|
-
|
|
|
47
|
-
| ๐ `-h, --help`
|
|
48
|
-
| ๐ท๏ธ `-v, --version`
|
|
49
|
-
| ๐๏ธ `-c, --create`
|
|
50
|
-
| โ
`-y, --yes`
|
|
51
|
-
| ๐ `-r, --report`
|
|
45
|
+
| Option | Description | Usage Example |
|
|
46
|
+
| -------------------| ------------------------------------------------------------- | -------------------------------------------------- |
|
|
47
|
+
| ๐ `-h, --help` | Show the usage options | `artes -h` or `artes --help` |
|
|
48
|
+
| ๐ท๏ธ `-v, --version` | Show the current version of Artes | `artes -v` or `artes --version` |
|
|
49
|
+
| ๐๏ธ `-c, --create` | Create an example project with Artes | `artes -c` or `artes --create` |
|
|
50
|
+
| โ
`-y, --yes` | Skip the confirmation prompt when creating an example project | `artes -c -y` or `artes --create --yes` |
|
|
51
|
+
| ๐ `-r, --report` | Run tests and generate Allure report | `artes -r` or `artes --report` |
|
|
52
|
+
| ๐ `--features` | Specify one or more feature files to run (comma-separated) | `artes --features 'Alma, Banan'` |
|
|
53
|
+
| ๐ `--tags` | Run tests with specified Cucumber tags | `artes --tags "@smoke or @wip"` |
|
|
54
|
+
|
|
52
55
|
|
|
53
56
|
\*\* To just run the tests: <br>
|
|
54
57
|
Globally: artes <br>
|
package/cucumber.config.js
CHANGED
|
@@ -50,7 +50,9 @@ module.exports = {
|
|
|
50
50
|
backtrace: artesConfig.backtrace || false, // Show full backtrace for errors
|
|
51
51
|
|
|
52
52
|
// Filtering and organization
|
|
53
|
-
tags:
|
|
53
|
+
tags: process.env.RUN_TAGS
|
|
54
|
+
? JSON.parse(process.env.RUN_TAGS)
|
|
55
|
+
: artesConfig.tags || artesConfig.tags || "", // Tag expression to filter scenarios
|
|
54
56
|
name: artesConfig.name || [], // Run scenarios matching regex
|
|
55
57
|
order: artesConfig.order || "defined", // Run order (defined/random)
|
|
56
58
|
language: artesConfig.language || "en", // Default feature file language
|
package/executer.js
CHANGED
|
@@ -18,6 +18,8 @@ const flags = {
|
|
|
18
18
|
createYes: args.includes("-y") || args.includes("--yes"),
|
|
19
19
|
report: args.includes("-r") || args.includes("--report"),
|
|
20
20
|
trace: args.includes("-t") || args.includes("--trace"),
|
|
21
|
+
features: args.includes("--features"),
|
|
22
|
+
tags: args.includes("--tags"),
|
|
21
23
|
};
|
|
22
24
|
|
|
23
25
|
function main() {
|
|
@@ -43,11 +45,11 @@ function main() {
|
|
|
43
45
|
// }
|
|
44
46
|
|
|
45
47
|
if (flags.report) {
|
|
46
|
-
runTests(flags.report);
|
|
48
|
+
runTests(flags.report, flags.tags, flags.features);
|
|
47
49
|
generateReport();
|
|
48
50
|
cleanUp();
|
|
49
51
|
} else {
|
|
50
|
-
runTests(flags.report);
|
|
52
|
+
runTests(flags.report, flags.tags, flags.features);
|
|
51
53
|
cleanUp();
|
|
52
54
|
}
|
|
53
55
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "artes",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.53",
|
|
4
4
|
"description": "The package provide step definitions and user writes feature files, and the package handles automation, with optional POM files and custom step definitions.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -24,6 +24,12 @@ function showHelp() {
|
|
|
24
24
|
|
|
25
25
|
๐ -r, --report Run tests and generate Allure report
|
|
26
26
|
Usage: artes -r or artes --report
|
|
27
|
+
|
|
28
|
+
๐ --features Specify one or more feature files to run (comma-separated)
|
|
29
|
+
Usage: artes --features "Alma, Banan"
|
|
30
|
+
|
|
31
|
+
๐ --tags Run tests with specified Cucumber tags
|
|
32
|
+
Usage: artes --tags "@smoke and not @wip"
|
|
27
33
|
`);
|
|
28
34
|
}
|
|
29
35
|
|
|
@@ -1,9 +1,22 @@
|
|
|
1
1
|
const { spawnSync } = require("child_process");
|
|
2
2
|
const { moduleConfig } = require("../imports/commons");
|
|
3
|
+
const path = require("path");
|
|
3
4
|
|
|
4
|
-
function runTests(
|
|
5
|
+
function runTests(flagReport, flagTags, flagFeatures) {
|
|
6
|
+
const args = process.argv.slice(2);
|
|
5
7
|
|
|
6
|
-
|
|
8
|
+
const featureFiles = args[args.indexOf("--features") + 1];
|
|
9
|
+
const features = flagFeatures && featureFiles.split(',').map(f=>path.join(moduleConfig.featuresPath, `${f.trim()}.feature`));
|
|
10
|
+
|
|
11
|
+
const tags = args[args.indexOf("--tags") + 1]
|
|
12
|
+
|
|
13
|
+
flagReport ? process.env.REPORT_FORMAT = JSON.stringify(["rerun:@rerun.txt", "allure-cucumberjs/reporter"]) : "";
|
|
14
|
+
|
|
15
|
+
flagTags && console.log("Running tags:", tags);
|
|
16
|
+
flagTags ? process.env.RUN_TAGS = JSON.stringify(tags) : "";
|
|
17
|
+
|
|
18
|
+
flagFeatures && console.log("Running features:", features);
|
|
19
|
+
flagFeatures ? process.env.FEATURES = JSON.stringify(features) : "";
|
|
7
20
|
|
|
8
21
|
try {
|
|
9
22
|
console.log("๐งช Running tests...");
|
|
@@ -1,5 +1,62 @@
|
|
|
1
1
|
const { context, selector, resolveVariable } = require("../imports/commons");
|
|
2
2
|
|
|
3
|
+
|
|
4
|
+
function getMimeType(filePath) {
|
|
5
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
6
|
+
const mimeTypes = {
|
|
7
|
+
'.jpg': 'image/jpeg',
|
|
8
|
+
'.jpeg': 'image/jpeg',
|
|
9
|
+
'.png': 'image/png',
|
|
10
|
+
'.gif': 'image/gif',
|
|
11
|
+
'.pdf': 'application/pdf',
|
|
12
|
+
'.txt': 'text/plain',
|
|
13
|
+
'.json': 'application/json',
|
|
14
|
+
'.xml': 'application/xml',
|
|
15
|
+
'.zip': 'application/zip',
|
|
16
|
+
'.doc': 'application/msword',
|
|
17
|
+
'.docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|
18
|
+
'.csv': 'text/csv'
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
return mimeTypes[ext] || 'application/octet-stream';
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function processForm(key, value) {
|
|
25
|
+
let formData = {};
|
|
26
|
+
|
|
27
|
+
if(typeof value === 'object') {
|
|
28
|
+
if(value.contentType) {
|
|
29
|
+
const content = typeof value.data === 'object' ? JSON.stringify(value.data) : String(value.data);
|
|
30
|
+
console.log("Content:", content)
|
|
31
|
+
formData[key] = {
|
|
32
|
+
name: value.filename || key,
|
|
33
|
+
mimeType: value.contentType,
|
|
34
|
+
buffer: Buffer.from(content, 'utf8')
|
|
35
|
+
};
|
|
36
|
+
} else {
|
|
37
|
+
formData[key] = JSON.stringify(value);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (typeof value === 'string' && (value.endsWith('.pdf') || value.endsWith('.jpg') || value.endsWith('.png') || value.endsWith('.txt') || value.endsWith('.doc') || value.endsWith('.docx') || value.includes('/'))) {
|
|
42
|
+
// If it looks like a file path, treat it as a file
|
|
43
|
+
try {
|
|
44
|
+
if (fs.existsSync(value)) {
|
|
45
|
+
formData[key] = {
|
|
46
|
+
name: path.basename(value),
|
|
47
|
+
mimeType: getMimeType(value),
|
|
48
|
+
buffer: fs.readFileSync(value)
|
|
49
|
+
};
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
} catch (error) {
|
|
53
|
+
// If file doesn't exist, treat as regular string
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return formData;
|
|
58
|
+
}
|
|
59
|
+
|
|
3
60
|
const api = {
|
|
4
61
|
get: async (url, payload) => {
|
|
5
62
|
const URL = await selector(url);
|
|
@@ -39,17 +96,33 @@ const api = {
|
|
|
39
96
|
|
|
40
97
|
context.response = response;
|
|
41
98
|
},
|
|
42
|
-
post: async (url, payload) => {
|
|
99
|
+
post: async (url, payload, bodyType) => {
|
|
43
100
|
const URL = await selector(url);
|
|
44
101
|
const resolvedURL = await resolveVariable(URL);
|
|
45
102
|
|
|
46
103
|
const resolvedPayload = await resolveVariable(payload);
|
|
47
104
|
const payloadJSON = (await resolvedPayload) && JSON.parse(resolvedPayload);
|
|
48
105
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
106
|
+
let requestBody = {}
|
|
107
|
+
|
|
108
|
+
switch (bodyType) {
|
|
109
|
+
case "multipart":
|
|
110
|
+
for (const [key, value] of Object.entries(payloadJSON.body)) {
|
|
111
|
+
var formData = processForm(key, value);
|
|
112
|
+
}
|
|
113
|
+
requestBody = {
|
|
114
|
+
headers: payloadJSON.headers,
|
|
115
|
+
multipart: formData
|
|
116
|
+
}
|
|
117
|
+
break;
|
|
118
|
+
default:
|
|
119
|
+
requestBody = {
|
|
120
|
+
headers: payloadJSON ? payloadJSON.headers : {},
|
|
121
|
+
data: payloadJSON ? payloadJSON.body : {},
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const res = await context.request.post(resolvedURL, requestBody);
|
|
53
126
|
|
|
54
127
|
const header = await res.headers();
|
|
55
128
|
const body = await res.json();
|
|
@@ -64,59 +137,91 @@ const api = {
|
|
|
64
137
|
};
|
|
65
138
|
|
|
66
139
|
context.response = response;
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
140
|
+
},
|
|
141
|
+
put: async (url, payload, bodyType) => {
|
|
142
|
+
const URL = await selector(url);
|
|
143
|
+
const resolvedURL = await resolveVariable(URL);
|
|
144
|
+
|
|
145
|
+
const resolvedPayload = await resolveVariable(payload);
|
|
146
|
+
const payloadJSON = (await resolvedPayload) && JSON.parse(resolvedPayload);
|
|
147
|
+
|
|
148
|
+
let requestBody = {}
|
|
149
|
+
|
|
150
|
+
switch (bodyType) {
|
|
151
|
+
case "multipart":
|
|
152
|
+
for (const [key, value] of Object.entries(payloadJSON.body)) {
|
|
153
|
+
var formData = processForm(key, value);
|
|
154
|
+
}
|
|
155
|
+
requestBody = {
|
|
156
|
+
headers: payloadJSON.headers,
|
|
157
|
+
multipart: formData
|
|
158
|
+
}
|
|
159
|
+
break;
|
|
160
|
+
default:
|
|
161
|
+
requestBody = {
|
|
162
|
+
headers: payloadJSON ? payloadJSON.headers : {},
|
|
163
|
+
data: payloadJSON ? payloadJSON.body : {},
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const res = await context.request.put(resolvedURL, requestBody);
|
|
168
|
+
|
|
169
|
+
const header = await res.headers();
|
|
170
|
+
const body = await res.json();
|
|
171
|
+
|
|
172
|
+
const response = {
|
|
173
|
+
url: res.url(),
|
|
174
|
+
requestHeaders: payloadJSON.headers,
|
|
175
|
+
requestBody: payloadJSON.body,
|
|
176
|
+
response: res,
|
|
177
|
+
responseHeaders: header,
|
|
178
|
+
responseBody: body,
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
context.response = response;
|
|
182
|
+
},
|
|
183
|
+
patch: async (url, payload, bodyType) => {
|
|
184
|
+
const URL = await selector(url);
|
|
185
|
+
const resolvedURL = await resolveVariable(URL);
|
|
186
|
+
|
|
187
|
+
const resolvedPayload = await resolveVariable(payload);
|
|
188
|
+
const payloadJSON = (await resolvedPayload) && JSON.parse(resolvedPayload);
|
|
189
|
+
|
|
190
|
+
let requestBody = {}
|
|
191
|
+
|
|
192
|
+
switch (bodyType) {
|
|
193
|
+
case "multipart":
|
|
194
|
+
for (const [key, value] of Object.entries(payloadJSON.body)) {
|
|
195
|
+
var formData = processForm(key, value);
|
|
196
|
+
}
|
|
197
|
+
requestBody = {
|
|
198
|
+
headers: payloadJSON.headers,
|
|
199
|
+
multipart: formData
|
|
200
|
+
}
|
|
201
|
+
break;
|
|
202
|
+
default:
|
|
203
|
+
requestBody = {
|
|
204
|
+
headers: payloadJSON ? payloadJSON.headers : {},
|
|
205
|
+
data: payloadJSON ? payloadJSON.body : {},
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
const res = await context.request.patch(resolvedURL, requestBody);
|
|
210
|
+
|
|
211
|
+
const header = await res.headers();
|
|
212
|
+
const body = await res.json();
|
|
213
|
+
|
|
214
|
+
const response = {
|
|
215
|
+
url: res.url(),
|
|
216
|
+
requestHeaders: payloadJSON.headers,
|
|
217
|
+
requestBody: payloadJSON.body,
|
|
218
|
+
response: res,
|
|
219
|
+
responseHeaders: header,
|
|
220
|
+
responseBody: body,
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
context.response = response;
|
|
224
|
+
},
|
|
120
225
|
delete: async (url, payload) => {
|
|
121
226
|
const URL = await selector(url);
|
|
122
227
|
const resolvedURL = await resolveVariable(URL);
|
|
@@ -15,7 +15,7 @@ When("User sends GET request to {string}", async function (url) {
|
|
|
15
15
|
|
|
16
16
|
When(
|
|
17
17
|
"User sends GET request to {string} with payload:",
|
|
18
|
-
async function (url,
|
|
18
|
+
async function (url, payload) {
|
|
19
19
|
await api.get(url, payload);
|
|
20
20
|
},
|
|
21
21
|
);
|
|
@@ -23,7 +23,7 @@ When(
|
|
|
23
23
|
When(
|
|
24
24
|
"User sends GET request to {string} and saves {string} variables",
|
|
25
25
|
async function (url, vars) {
|
|
26
|
-
await api.get(url
|
|
26
|
+
await api.get(url);
|
|
27
27
|
extractVarsFromResponse(vars);
|
|
28
28
|
},
|
|
29
29
|
);
|
|
@@ -49,12 +49,22 @@ When(
|
|
|
49
49
|
|
|
50
50
|
When(
|
|
51
51
|
"User sends POST request to {string} with payload and saves {string} variables",
|
|
52
|
-
async function (url, payload) {
|
|
52
|
+
async function (url, vars, payload) {
|
|
53
53
|
await api.post(url, payload);
|
|
54
54
|
extractVarsFromResponse(vars);
|
|
55
55
|
},
|
|
56
56
|
);
|
|
57
57
|
|
|
58
|
+
When('User sends multipart POST request to {string} with payload:', async (url, payload) => {
|
|
59
|
+
await api.post(url, payload, "multipart");
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
When('User sends multipart POST request to {string} with payload and {string} variables', async (url, vars, payload) => {
|
|
63
|
+
await api.post(url, payload, "multipart");
|
|
64
|
+
extractVarsFromResponse(vars);
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
|
|
58
68
|
When(
|
|
59
69
|
"User sends PUT request to {string} with payload:",
|
|
60
70
|
async function (url, payload) {
|
|
@@ -64,12 +74,27 @@ When(
|
|
|
64
74
|
|
|
65
75
|
When(
|
|
66
76
|
"User sends PUT request to {string} with payload and saves {string} variables",
|
|
67
|
-
async function (url, payload) {
|
|
77
|
+
async function (url, vars, payload) {
|
|
68
78
|
await api.put(url, payload);
|
|
69
79
|
extractVarsFromResponse(vars);
|
|
70
80
|
},
|
|
71
81
|
);
|
|
72
82
|
|
|
83
|
+
When(
|
|
84
|
+
"User sends multipart PUT request to {string} with payload:",
|
|
85
|
+
async function (url, payload) {
|
|
86
|
+
await api.put(url, payload, "multipart");
|
|
87
|
+
},
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
When(
|
|
91
|
+
"User sends multipart PUT request to {string} with payload and saves {string} variables",
|
|
92
|
+
async function (url, vars, payload) {
|
|
93
|
+
await api.put(url, payload, "multipart");
|
|
94
|
+
extractVarsFromResponse(vars);
|
|
95
|
+
},
|
|
96
|
+
);
|
|
97
|
+
|
|
73
98
|
When(
|
|
74
99
|
"User sends PATCH request to {string} with payload:",
|
|
75
100
|
async function (url, payload) {
|
|
@@ -79,12 +104,27 @@ When(
|
|
|
79
104
|
|
|
80
105
|
When(
|
|
81
106
|
"User sends PATCH request to {string} with payload and saves {string} variables",
|
|
82
|
-
async function (url, payload) {
|
|
107
|
+
async function (url, vars, payload) {
|
|
83
108
|
await api.patch(url, payload);
|
|
84
109
|
extractVarsFromResponse(vars);
|
|
85
110
|
},
|
|
86
111
|
);
|
|
87
112
|
|
|
113
|
+
When(
|
|
114
|
+
"User sends multipart PATCH request to {string} with payload:",
|
|
115
|
+
async function (url, payload) {
|
|
116
|
+
await api.patch(url, payload, "multipart");
|
|
117
|
+
},
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
When(
|
|
121
|
+
"User sends multipart PATCH request to {string} with payload and saves {string} variables",
|
|
122
|
+
async function (url, vars, payload) {
|
|
123
|
+
await api.patch(url, payload, "multipart");
|
|
124
|
+
extractVarsFromResponse(vars);
|
|
125
|
+
},
|
|
126
|
+
);
|
|
127
|
+
|
|
88
128
|
When("User sends DELETE request to {string}", async function (url) {
|
|
89
129
|
await api.delete(url);
|
|
90
130
|
});
|