artes 1.7.11 → 1.7.14

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/index.js CHANGED
@@ -13,6 +13,7 @@ const {
13
13
  random,
14
14
  time,
15
15
  resolveVariable,
16
+ pathToCamelCase
16
17
  } = require("./src/helper/imports/commons");
17
18
 
18
19
  const {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "artes",
3
- "version": "1.7.11",
3
+ "version": "1.7.14",
4
4
  "description": "The simplest way to automate UI and API tests using Cucumber-style steps.",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -27,6 +27,9 @@ async function getEnvInfo() {
27
27
  }
28
28
 
29
29
  const environment = {
30
+ // ── ARTES Version ───────────────────────
31
+ ARTES_Version: require(moduleConfig.modulePackageJsonPath).version,
32
+
30
33
  // ── System ──────────────────────────────
31
34
  OS_Name: os.type(),
32
35
  OS_Version: os.release(),
@@ -48,6 +48,10 @@ function curlExtractor(url, method, headers, body, requestDataType) {
48
48
  }
49
49
  }
50
50
  break;
51
+ case "xml":
52
+ curlCommand += ` \\\n -H 'Content-Type: application/xml'`;
53
+ curlCommand += ` \\\n --data-raw '${data}'`;
54
+ break;
51
55
 
52
56
  case "urlencoded":
53
57
  case "application/x-www-form-urlencoded":
@@ -106,28 +110,37 @@ function processForm(requestBody) {
106
110
  }
107
111
  }
108
112
 
109
- if (
110
- typeof value === "string" &&
111
- (value.endsWith(".pdf") ||
112
- value.endsWith(".jpg") ||
113
- value.endsWith(".png") ||
114
- value.endsWith(".txt") ||
115
- value.endsWith(".doc") ||
116
- value.endsWith(".docx") ||
117
- value.includes("/"))
118
- ) {
119
- try {
120
- const filePath = path.join(moduleConfig.projectPath, value);
121
- if (fs.existsSync(filePath)) {
122
- formData[key] = {
123
- name: path.basename(filePath),
124
- mimeType: getMimeType(filePath),
125
- buffer: fs.readFileSync(filePath),
126
- };
127
- continue;
113
+ if (typeof value === "string") {
114
+
115
+ const normalizedValue = path.normalize(value);
116
+
117
+ const looksLikeFilePath =
118
+ normalizedValue.endsWith(".pdf") ||
119
+ normalizedValue.endsWith(".jpg") ||
120
+ normalizedValue.endsWith(".jpeg") ||
121
+ normalizedValue.endsWith(".png") ||
122
+ normalizedValue.endsWith(".txt") ||
123
+ normalizedValue.endsWith(".doc") ||
124
+ normalizedValue.endsWith(".docx") ||
125
+ normalizedValue.includes(path.sep);
126
+
127
+ if (looksLikeFilePath) {
128
+ try {
129
+ const filePath = path.isAbsolute(normalizedValue)
130
+ ? normalizedValue
131
+ : path.join(moduleConfig.projectPath, normalizedValue);
132
+
133
+ if (fs.existsSync(filePath)) {
134
+ formData[key] = {
135
+ name: path.basename(filePath),
136
+ mimeType: getMimeType(filePath),
137
+ buffer: fs.readFileSync(filePath),
138
+ };
139
+ continue;
140
+ }
141
+ } catch (error) {
142
+ console.log(error);
128
143
  }
129
- } catch (error) {
130
- console.log(error);
131
144
  }
132
145
  }
133
146
 
@@ -145,6 +158,12 @@ async function requestMaker(headers, data, requestDataType) {
145
158
  case "multipart":
146
159
  Object.assign(request, { multipart: data });
147
160
  break;
161
+ case "xml":
162
+ Object.assign(request, {
163
+ headers: { ...headers, "Content-Type": "application/xml" },
164
+ data: data,
165
+ });
166
+ break;
148
167
  case "urlencoded":
149
168
  case "application/x-www-form-urlencoded":
150
169
  const urlEncodedData = new URLSearchParams(data).toString();
@@ -264,6 +283,14 @@ const api = {
264
283
  );
265
284
  bodyForCurl = formRequest;
266
285
  break;
286
+ case "xml":
287
+ req = await requestMaker(
288
+ payloadJSON?.headers || {},
289
+ payloadJSON?.body || {},
290
+ requestDataType,
291
+ );
292
+ bodyForCurl = payloadJSON?.body || {};
293
+ break;
267
294
  case "urlencoded":
268
295
  case "application/x-www-form-urlencoded":
269
296
  req = await requestMaker(
@@ -334,6 +361,14 @@ const api = {
334
361
  );
335
362
  bodyForCurl = formRequest;
336
363
  break;
364
+ case "xml":
365
+ req = await requestMaker(
366
+ payloadJSON?.headers || {},
367
+ payloadJSON?.body || {},
368
+ requestDataType,
369
+ );
370
+ bodyForCurl = payloadJSON?.body || {};
371
+ break;
337
372
  case "urlencoded":
338
373
  case "application/x-www-form-urlencoded":
339
374
  req = await requestMaker(
@@ -404,6 +439,14 @@ const api = {
404
439
  );
405
440
  bodyForCurl = formRequest;
406
441
  break;
442
+ case "xml":
443
+ req = await requestMaker(
444
+ payloadJSON?.headers || {},
445
+ payloadJSON?.body || {},
446
+ requestDataType,
447
+ );
448
+ bodyForCurl = payloadJSON?.body || {};
449
+ break;
407
450
  case "urlencoded":
408
451
  case "application/x-www-form-urlencoded":
409
452
  req = await requestMaker(
@@ -452,7 +495,7 @@ const api = {
452
495
 
453
496
  context.response = response;
454
497
  },
455
- delete: async (url, payload, options) => {
498
+ delete: async (url, payload, requestDataType, options) => {
456
499
  const URL = await selector(url);
457
500
 
458
501
  options = options ?? {};
@@ -460,10 +503,53 @@ const api = {
460
503
  const resolvedPayload = (await payload) && resolveVariable(payload);
461
504
  const payloadJSON = (await resolvedPayload) && JSON.parse(resolvedPayload);
462
505
 
463
- const req = await requestMaker(
464
- payloadJSON?.headers || {},
465
- payloadJSON?.body || {},
466
- );
506
+ let req;
507
+ let bodyForCurl = payloadJSON?.body || {};
508
+
509
+ switch (requestDataType) {
510
+ case "multipart":
511
+ const formRequest = processForm(payloadJSON?.body || {});
512
+ req = await requestMaker(
513
+ payloadJSON?.headers || {},
514
+ formRequest || {},
515
+ requestDataType,
516
+ );
517
+ bodyForCurl = formRequest;
518
+ break;
519
+ case "urlencoded":
520
+ case "application/x-www-form-urlencoded":
521
+ req = await requestMaker(
522
+ {
523
+ ...payloadJSON?.headers,
524
+ "Content-Type": "application/x-www-form-urlencoded",
525
+ },
526
+ payloadJSON?.body || {},
527
+ requestDataType,
528
+ );
529
+ break;
530
+ case "form":
531
+ req = await requestMaker(
532
+ payloadJSON?.headers || {},
533
+ payloadJSON?.body || {},
534
+ requestDataType,
535
+ );
536
+ break;
537
+ case "xml":
538
+ req = await requestMaker(
539
+ {
540
+ ...payloadJSON?.headers,
541
+ "Content-Type": "application/xml",
542
+ },
543
+ payloadJSON?.body || {},
544
+ requestDataType,
545
+ );
546
+ break;
547
+ default:
548
+ req = await requestMaker(
549
+ payloadJSON?.headers || {},
550
+ payloadJSON?.body || {},
551
+ );
552
+ }
467
553
 
468
554
  const requestStarts = performance.now();
469
555
 
@@ -474,9 +560,9 @@ const api = {
474
560
  const curlCommand = curlExtractor(
475
561
  res.url(),
476
562
  "DELETE",
477
- payloadJSON?.headers || {},
478
- payloadJSON?.body || {},
479
- null,
563
+ req.headers,
564
+ bodyForCurl,
565
+ requestDataType,
480
566
  );
481
567
 
482
568
  const response = responseMaker(payloadJSON, res, duration, curlCommand);
@@ -88,6 +88,21 @@ When(
88
88
  },
89
89
  );
90
90
 
91
+ When(
92
+ "User sends xml POST request to {string} with payload:",
93
+ async (url, payload) => {
94
+ await api.post(url, payload, "xml");
95
+ },
96
+ );
97
+
98
+ When(
99
+ "User sends xml POST request to {string} with payload and saves {string} variables",
100
+ async (url, vars, payload) => {
101
+ await api.post(url, payload, "xml");
102
+ await extractVarsFromResponse(context.response["Response Body"], vars);
103
+ },
104
+ );
105
+
91
106
  When(
92
107
  "User sends PUT request to {string} with payload:",
93
108
  async function (url, payload) {
@@ -133,6 +148,21 @@ When(
133
148
  },
134
149
  );
135
150
 
151
+ When(
152
+ "User sends xml PUT request to {string} with payload:",
153
+ async (url, payload) => {
154
+ await api.put(url, payload, "xml");
155
+ },
156
+ );
157
+
158
+ When(
159
+ "User sends xml PUT request to {string} with payload and saves {string} variables",
160
+ async (url, vars, payload) => {
161
+ await api.put(url, payload, "xml");
162
+ await extractVarsFromResponse(context.response["Response Body"], vars);
163
+ },
164
+ );
165
+
136
166
  When(
137
167
  "User sends PATCH request to {string} with payload:",
138
168
  async function (url, payload) {
@@ -178,6 +208,21 @@ When(
178
208
  },
179
209
  );
180
210
 
211
+ When(
212
+ "User sends xml PATCH request to {string} with payload:",
213
+ async (url, payload) => {
214
+ await api.patch(url, payload, "xml");
215
+ },
216
+ );
217
+
218
+ When(
219
+ "User sends xml PATCH request to {string} with payload and saves {string} variables",
220
+ async (url, vars, payload) => {
221
+ await api.patch(url, payload, "xml");
222
+ await extractVarsFromResponse(context.response["Response Body"], vars);
223
+ },
224
+ );
225
+
181
226
  When("User sends DELETE request to {string}", async function (url) {
182
227
  await api.delete(url);
183
228
  });
@@ -205,6 +250,21 @@ When(
205
250
  },
206
251
  );
207
252
 
253
+ When(
254
+ "User sends xml DELETE request to {string} with payload:",
255
+ async (url, payload) => {
256
+ await api.delete(url, payload, "xml");
257
+ },
258
+ );
259
+
260
+ When(
261
+ "User sends xml DELETE request to {string} with payload and saves {string} variables",
262
+ async (url, vars, payload) => {
263
+ await api.delete(url, payload, "xml");
264
+ await extractVarsFromResponse(context.response["Response Body"], vars);
265
+ },
266
+ );
267
+
208
268
  When(
209
269
  "User saves {string} variable from response as {string}",
210
270
  async function (vars, customVarName) {
@@ -223,6 +283,33 @@ When(
223
283
  },
224
284
  );
225
285
 
286
+ When(
287
+ 'User sets {int} year from current year as {string}',
288
+ async function (year, yearName) {
289
+ const targetYear = time().add(year, 'year').year();
290
+ context.vars[yearName] = targetYear.toString();
291
+ }
292
+ );
293
+
294
+ When(
295
+ 'User sets {int} month from current month as {string}',
296
+ async function (month, monthName) {
297
+ const targetMonth = time().add(month, 'month').month() + 1;
298
+
299
+ context.vars[monthName] = targetMonth.toString().padStart(2, '0');
300
+ }
301
+ );
302
+
303
+ When(
304
+ "User saves request time in ISO format as {string}",
305
+ async (request_time) => {
306
+ context.vars[request_time] = new Date(
307
+ context.response["Response Headers"].date,
308
+ ).toISOString();
309
+ allure.attachment("Request Time", context.vars[request_time], "text/plain");
310
+ },
311
+ );
312
+
226
313
  When("User wants to see saved variables", async function () {
227
314
  console.log("\nVariables:", api.vars(null), "\n");
228
315
  });
@@ -302,9 +389,14 @@ When(
302
389
  async (file, variable) => {
303
390
  file = await resolveVariable(file);
304
391
 
305
- const filePath = await path.join(moduleConfig.projectPath, file);
306
- const fileData = await fs.readFileSync(filePath);
307
- const base64Data = await fileData.toString("base64");
308
- context.vars[variable] = await base64Data;
392
+ const normalizedFile = path.normalize(file);
393
+
394
+ const filePath = path.isAbsolute(normalizedFile)
395
+ ? normalizedFile
396
+ : path.join(moduleConfig.projectPath, normalizedFile);
397
+
398
+ const fileData = fs.readFileSync(filePath);
399
+ const base64Data = fileData.toString("base64");
400
+ context.vars[variable] = base64Data;
309
401
  },
310
- );
402
+ );
@@ -1264,6 +1264,15 @@ Then(
1264
1264
  },
1265
1265
  );
1266
1266
 
1267
+ Then(
1268
+ "User expects that {string} array has {int} items",
1269
+ async (field, count) => {
1270
+ extractVarsFromResponse(context.response["Response Body"], field);
1271
+ const key = pathToCamelCase(field);
1272
+ expect(context.vars[key].length).toEqual(count);
1273
+ },
1274
+ );
1275
+
1267
1276
  Then(
1268
1277
  "User expects that {string} should match {string}",
1269
1278
  async (value1, value2) => {
@@ -1303,3 +1312,41 @@ Then(
1303
1312
  expect(actualStatusCode).toBe(expectedStatusCode);
1304
1313
  },
1305
1314
  );
1315
+
1316
+
1317
+ Then("User expects that response should have {string} field", async (field) => {
1318
+ extractVarsFromResponse(context.response["Response Body"], field);
1319
+ const key = pathToCamelCase(field);
1320
+ const varToString = JSON.stringify(context.vars[field]);
1321
+ expect(varToString).toBeDefined();
1322
+ });
1323
+
1324
+ Then(
1325
+ "User expects that response should not have {string} field",
1326
+ async (field) => {
1327
+ extractVarsFromResponse(context.response["Response Body"], field);
1328
+ const key = pathToCamelCase(field);
1329
+ const varToString = JSON.stringify(context.vars[field]);
1330
+ expect(varToString).not.toBeDefined();
1331
+ },
1332
+ );
1333
+
1334
+ Then(
1335
+ "User expects that {string} array has items more than {int}",
1336
+ (field, count) => {
1337
+ extractVarsFromResponse(context.response["Response Body"], field);
1338
+ const key = pathToCamelCase(field);
1339
+ const resolvedCount = resolveVariable(count)
1340
+ expect(context.vars[key].length).toBeLessThan(resolvedCount);
1341
+ },
1342
+ );
1343
+
1344
+ Then(
1345
+ "User expects that {string} array has items less than {int}",
1346
+ (field, count) => {
1347
+ extractVarsFromResponse(context.response["Response Body"], field);
1348
+ const key = pathToCamelCase(field);
1349
+ const resolvedCount = resolveVariable(count)
1350
+ expect(context.vars[key].length).toBeLessThan(resolvedCount);
1351
+ },
1352
+ );
@@ -60,7 +60,7 @@ When(
60
60
  When("User clicks at {int}, {int} coordinates", async function (x, y) {
61
61
  x = await resolveVariable(x);
62
62
  y = await resolveVariable(y);
63
- await context.page.click({ position: { x: x, y: y } });
63
+ await context.page.mouse.click(x, y);
64
64
  });
65
65
 
66
66
  // User clicks at specific coordinates with click count and delay
@@ -69,11 +69,7 @@ When(
69
69
  async function (x, y, clickCount, delay) {
70
70
  x = await resolveVariable(x);
71
71
  y = await resolveVariable(y);
72
- await context.page.click({
73
- position: { x: x, y: y },
74
- clickCount: clickCount,
75
- delay: delay,
76
- });
72
+ await context.page.mouse.click(x, y, { clickCount: clickCount, delay: delay });
77
73
  },
78
74
  );
79
75
 
@@ -83,7 +79,7 @@ When(
83
79
  async function (x, y) {
84
80
  x = await resolveVariable(x);
85
81
  y = await resolveVariable(y);
86
- context.page.click({ position: { x: x, y: y }, force: true });
82
+ await context.page.mouse.click(x, y, { force: true });
87
83
  },
88
84
  );
89
85
 
@@ -0,0 +1,5 @@
1
+ const { Given } = require("../helper/imports/commons");
2
+
3
+ Given('{string}', (s) => {
4
+ // This step is for adding description between the steps to the report
5
+ })