artes 1.0.78 → 1.0.79

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 CHANGED
@@ -56,7 +56,7 @@ npx artes [options]
56
56
  | ⚡ `--parallel` | Run tests in parallel mode | `artes --parallel 2` |
57
57
  | 🔁 `--retry` | Retry failed tests | `artes --retry 3` |
58
58
  | 🎭 `--dryrun` | Perform a dry run without executing tests | `artes --dryrun` |
59
-
59
+ | 📈 `--percentage` | Set minimum success percentage to pass test run | `artes --percentage 85` |
60
60
 
61
61
  \*\* To just run the tests: <br>
62
62
  Globally: artes <br>
@@ -17,6 +17,7 @@ try {
17
17
  module.exports = {
18
18
  default: {
19
19
  // File paths and patterns
20
+ testPercentage: process.env.PERCENTAGE ? process.env.PERCENTAGE : artesConfig.testPercentage || 0, // number - Percentage of tests to run (0-100)
20
21
  timeout: artesConfig.timeout || 30, // Default timeout in milliseconds
21
22
  paths: process.env.FEATURES
22
23
  ? [path.join(moduleConfig.projectPath, process.env.FEATURES)]
@@ -47,8 +48,12 @@ module.exports = {
47
48
  }, // Formatter options
48
49
 
49
50
  // Execution options
50
- parallel: process.env.PARALLEL ? JSON.parse(process.env.PARALLEL) : artesConfig.parallel || 1, // Number of parallel workers
51
- dryRun: process.env.DRYRUN ? JSON.parse(process.env.DRYRUN) : artesConfig.dryRun || false, // Prepare test run without execution
51
+ parallel: process.env.PARALLEL
52
+ ? JSON.parse(process.env.PARALLEL)
53
+ : artesConfig.parallel || 1, // Number of parallel workers
54
+ dryRun: process.env.DRYRUN
55
+ ? JSON.parse(process.env.DRYRUN)
56
+ : artesConfig.dryRun || false, // Prepare test run without execution
52
57
  failFast: artesConfig.failFast || false, // Stop on first test failure
53
58
  forceExit: artesConfig.forceExit || false, // Force process.exit() after tests
54
59
  strict: artesConfig.strict || true, // Fail on pending steps
@@ -67,7 +72,9 @@ module.exports = {
67
72
  requireModule: artesConfig.requireModule || [], // Transpilation module names
68
73
 
69
74
  // Retry logic
70
- retry: process.env.RETRY ? JSON.parse(process.env.RETRY) : artesConfig.retry || 0, // Retry attempts for failing tests
75
+ retry: process.env.RETRY
76
+ ? JSON.parse(process.env.RETRY)
77
+ : artesConfig.retry || 0, // Retry attempts for failing tests
71
78
  retryTagFilter: artesConfig.retryTagFilter || "", // Tag expression for retries
72
79
 
73
80
  // Publishing
@@ -3,7 +3,14 @@
3
3
  If you don't want to deal with Playwright methods directly, you can simply use the following predefined actions methods by import them:
4
4
 
5
5
  ```javascript
6
- const { mouse, keyboard, frame, elementInteractions, page, api } = require("artes");
6
+ const {
7
+ mouse,
8
+ keyboard,
9
+ frame,
10
+ elementInteractions,
11
+ page,
12
+ api,
13
+ } = require("artes");
7
14
  ```
8
15
 
9
16
  - **Mouse Actions:**
@@ -2114,16 +2121,21 @@ The `api` object provides methods for making HTTP requests with automatic URL re
2114
2121
  Makes a GET request to the specified URL.
2115
2122
 
2116
2123
  **Parameters:**
2124
+
2117
2125
  - `url` (string): The target URL (supports variable resolution)
2118
2126
  - `payload` (string, optional): JSON string containing headers and other request options
2119
2127
 
2120
2128
  **Returns:** Promise that resolves when the request completes
2121
2129
 
2122
2130
  **Example:**
2131
+
2123
2132
  ```javascript
2124
- await api.get("https://api.example.com/users", JSON.stringify({
2125
- headers: { "Authorization": "Bearer {{token}}" }
2126
- }));
2133
+ await api.get(
2134
+ "https://api.example.com/users",
2135
+ JSON.stringify({
2136
+ headers: { Authorization: "Bearer {{token}}" },
2137
+ }),
2138
+ );
2127
2139
  ```
2128
2140
 
2129
2141
  ### `api.head(url)`
@@ -2131,11 +2143,13 @@ await api.get("https://api.example.com/users", JSON.stringify({
2131
2143
  Makes a HEAD request to the specified URL.
2132
2144
 
2133
2145
  **Parameters:**
2146
+
2134
2147
  - `url` (string): The target URL (supports variable resolution)
2135
2148
 
2136
2149
  **Returns:** Promise that resolves when the request completes
2137
2150
 
2138
2151
  **Example:**
2152
+
2139
2153
  ```javascript
2140
2154
  await api.head("https://api.example.com/status");
2141
2155
  ```
@@ -2145,6 +2159,7 @@ await api.head("https://api.example.com/status");
2145
2159
  Makes a POST request to the specified URL.
2146
2160
 
2147
2161
  **Parameters:**
2162
+
2148
2163
  - `url` (string): The target URL (supports variable resolution)
2149
2164
  - `payload` (string): JSON string containing headers, body, and other request options
2150
2165
  - `requestDataType` (string, optional): Request data type ("multipart" for form data, default for JSON)
@@ -2152,18 +2167,26 @@ Makes a POST request to the specified URL.
2152
2167
  **Returns:** Promise that resolves when the request completes
2153
2168
 
2154
2169
  **Example:**
2170
+
2155
2171
  ```javascript
2156
2172
  // Regular POST request
2157
- await api.post("https://api.example.com/users", JSON.stringify({
2158
- headers: { "Content-Type": "application/json" },
2159
- body: { name: "John", email: "john@example.com" }
2160
- }));
2173
+ await api.post(
2174
+ "https://api.example.com/users",
2175
+ JSON.stringify({
2176
+ headers: { "Content-Type": "application/json" },
2177
+ body: { name: "John", email: "john@example.com" },
2178
+ }),
2179
+ );
2161
2180
 
2162
2181
  // Multipart form data
2163
- await api.post("https://api.example.com/upload", JSON.stringify({
2164
- headers: {},
2165
- body: { file: "/path/to/file.pdf", description: "Document upload" }
2166
- }), "multipart");
2182
+ await api.post(
2183
+ "https://api.example.com/upload",
2184
+ JSON.stringify({
2185
+ headers: {},
2186
+ body: { file: "/path/to/file.pdf", description: "Document upload" },
2187
+ }),
2188
+ "multipart",
2189
+ );
2167
2190
  ```
2168
2191
 
2169
2192
  ### `api.put(url, payload, requestDataType)`
@@ -2171,6 +2194,7 @@ await api.post("https://api.example.com/upload", JSON.stringify({
2171
2194
  Makes a PUT request to the specified URL.
2172
2195
 
2173
2196
  **Parameters:**
2197
+
2174
2198
  - `url` (string): The target URL (supports variable resolution)
2175
2199
  - `payload` (string): JSON string containing headers, body, and other request options
2176
2200
  - `requestDataType` (string, optional): Request data type ("multipart" for form data, default for JSON)
@@ -2178,11 +2202,15 @@ Makes a PUT request to the specified URL.
2178
2202
  **Returns:** Promise that resolves when the request completes
2179
2203
 
2180
2204
  **Example:**
2205
+
2181
2206
  ```javascript
2182
- await api.put("https://api.example.com/users/{{userId}}", JSON.stringify({
2183
- headers: { "Content-Type": "application/json" },
2184
- body: { name: "Updated Name" }
2185
- }));
2207
+ await api.put(
2208
+ "https://api.example.com/users/{{userId}}",
2209
+ JSON.stringify({
2210
+ headers: { "Content-Type": "application/json" },
2211
+ body: { name: "Updated Name" },
2212
+ }),
2213
+ );
2186
2214
  ```
2187
2215
 
2188
2216
  ### `api.patch(url, payload, requestDataType)`
@@ -2190,6 +2218,7 @@ await api.put("https://api.example.com/users/{{userId}}", JSON.stringify({
2190
2218
  Makes a PATCH request to the specified URL.
2191
2219
 
2192
2220
  **Parameters:**
2221
+
2193
2222
  - `url` (string): The target URL (supports variable resolution)
2194
2223
  - `payload` (string): JSON string containing headers, body, and other request options
2195
2224
  - `requestDataType` (string, optional): Request data type ("multipart" for form data, default for JSON)
@@ -2197,11 +2226,15 @@ Makes a PATCH request to the specified URL.
2197
2226
  **Returns:** Promise that resolves when the request completes
2198
2227
 
2199
2228
  **Example:**
2229
+
2200
2230
  ```javascript
2201
- await api.patch("https://api.example.com/users/{{userId}}", JSON.stringify({
2202
- headers: { "Content-Type": "application/json" },
2203
- body: { email: "newemail@example.com" }
2204
- }));
2231
+ await api.patch(
2232
+ "https://api.example.com/users/{{userId}}",
2233
+ JSON.stringify({
2234
+ headers: { "Content-Type": "application/json" },
2235
+ body: { email: "newemail@example.com" },
2236
+ }),
2237
+ );
2205
2238
  ```
2206
2239
 
2207
2240
  ### `api.delete(url, payload)`
@@ -2209,16 +2242,21 @@ await api.patch("https://api.example.com/users/{{userId}}", JSON.stringify({
2209
2242
  Makes a DELETE request to the specified URL.
2210
2243
 
2211
2244
  **Parameters:**
2245
+
2212
2246
  - `url` (string): The target URL (supports variable resolution)
2213
2247
  - `payload` (string, optional): JSON string containing headers and other request options
2214
2248
 
2215
2249
  **Returns:** Promise that resolves when the request completes
2216
2250
 
2217
2251
  **Example:**
2252
+
2218
2253
  ```javascript
2219
- await api.delete("https://api.example.com/users/{{userId}}", JSON.stringify({
2220
- headers: { "Authorization": "Bearer {{token}}" }
2221
- }));
2254
+ await api.delete(
2255
+ "https://api.example.com/users/{{userId}}",
2256
+ JSON.stringify({
2257
+ headers: { Authorization: "Bearer {{token}}" },
2258
+ }),
2259
+ );
2222
2260
  ```
2223
2261
 
2224
2262
  ### `api.vars()`
@@ -2228,12 +2266,12 @@ Returns the current context variables object.
2228
2266
  **Returns:** Object containing all stored variables
2229
2267
 
2230
2268
  **Example:**
2269
+
2231
2270
  ```javascript
2232
2271
  const currentVars = api.vars();
2233
2272
  console.log(currentVars); // { token: "abc123", userId: "user456" }
2234
2273
  ```
2235
2274
 
2236
-
2237
2275
  ## Static Methods
2238
2276
 
2239
2277
  ### `extractVarsFromResponse(object, vars, customVarName)`
@@ -2241,15 +2279,18 @@ console.log(currentVars); // { token: "abc123", userId: "user456" }
2241
2279
  Extracts variables from the response body using dot notation paths.
2242
2280
 
2243
2281
  **Parameters:**
2282
+
2244
2283
  - `vars` (string): Comma-separated list of dot notation paths (e.g., "user.id,user.name")
2245
2284
  - `customVarName` (string, optional): Custom variable name to use instead of auto-generated names
2246
2285
 
2247
2286
  **Behavior:**
2287
+
2248
2288
  - Extracts values from `context.response.responseBody` using specified paths
2249
2289
  - Saves extracted values as variables using `saveVar()`
2250
2290
  - If `customVarName` is provided, uses it; otherwise generates camelCase names
2251
2291
 
2252
2292
  **Example:**
2293
+
2253
2294
  ```javascript
2254
2295
  // Response body: { user: { id: 123, profile: { name: "John" } } }
2255
2296
  extractVarsFromResponse(object, "user.id,user.profile.name");
@@ -2264,11 +2305,13 @@ extractVarsFromResponse(object, "user.id", "currentUserId");
2264
2305
  Saves a variable to the context with either a custom name or auto-generated camelCase name.
2265
2306
 
2266
2307
  **Parameters:**
2308
+
2267
2309
  - `value` (any): The value to store
2268
2310
  - `customName` (string, optional): Custom variable name
2269
2311
  - `path` (string): Dot notation path used for auto-generating variable name
2270
2312
 
2271
2313
  **Behavior:**
2314
+
2272
2315
  - If `customName` is provided, uses it as the variable name
2273
2316
  - Otherwise, converts dot notation path to camelCase (e.g., "user.profile.name" → "userProfileName")
2274
2317
 
@@ -2277,17 +2320,19 @@ Saves a variable to the context with either a custom name or auto-generated came
2277
2320
  Resolves variable placeholders in template strings using the format `{{variableName}}`.
2278
2321
 
2279
2322
  **Parameters:**
2323
+
2280
2324
  - `template` (string): Template string containing variable placeholders
2281
2325
 
2282
2326
  **Returns:** String with variables resolved, or original value if not a string
2283
2327
 
2284
2328
  **Example:**
2329
+
2285
2330
  ```javascript
2286
2331
  // Assuming context.vars = { userId: "123", token: "abc" }
2287
- resolveVariable("https://api.example.com/users/{{userId}}")
2332
+ resolveVariable("https://api.example.com/users/{{userId}}");
2288
2333
  // Returns: "https://api.example.com/users/123"
2289
2334
 
2290
- resolveVariable("Bearer {{token}}")
2335
+ resolveVariable("Bearer {{token}}");
2291
2336
  // Returns: "Bearer abc"
2292
2337
  ```
2293
2338
 
@@ -2301,9 +2346,12 @@ context.vars.baseUrl = "https://api.example.com";
2301
2346
  context.vars.token = "your-auth-token";
2302
2347
 
2303
2348
  // Make a GET request
2304
- await api.get("{{baseUrl}}/users", JSON.stringify({
2305
- headers: { "Authorization": "Bearer {{token}}" }
2306
- }));
2349
+ await api.get(
2350
+ "{{baseUrl}}/users",
2351
+ JSON.stringify({
2352
+ headers: { Authorization: "Bearer {{token}}" },
2353
+ }),
2354
+ );
2307
2355
 
2308
2356
  // Extract user ID from response
2309
2357
  extractVarsFromResponse("data.0.id", "firstUserId");
@@ -2315,29 +2363,39 @@ await api.get("{{baseUrl}}/users/{{firstUserId}}/profile");
2315
2363
  ### File Upload Example
2316
2364
 
2317
2365
  ```javascript
2318
- await api.post("{{baseUrl}}/upload", JSON.stringify({
2319
- headers: { "Authorization": "Bearer {{token}}" },
2320
- body: {
2321
- file: "/path/to/document.pdf",
2322
- description: "Important document",
2323
- metadata: { type: "legal", priority: "high" }
2324
- }
2325
- }), "multipart");
2366
+ await api.post(
2367
+ "{{baseUrl}}/upload",
2368
+ JSON.stringify({
2369
+ headers: { Authorization: "Bearer {{token}}" },
2370
+ body: {
2371
+ file: "/path/to/document.pdf",
2372
+ description: "Important document",
2373
+ metadata: { type: "legal", priority: "high" },
2374
+ },
2375
+ }),
2376
+ "multipart",
2377
+ );
2326
2378
  ```
2327
2379
 
2328
2380
  ### Variable Extraction and Chaining
2329
2381
 
2330
2382
  ```javascript
2331
2383
  // Login request
2332
- await api.post("{{baseUrl}}/auth/login", JSON.stringify({
2333
- body: { username: "user@example.com", password: "password" }
2334
- }));
2384
+ await api.post(
2385
+ "{{baseUrl}}/auth/login",
2386
+ JSON.stringify({
2387
+ body: { username: "user@example.com", password: "password" },
2388
+ }),
2389
+ );
2335
2390
 
2336
2391
  // Extract token from login response
2337
2392
  extractVarsFromResponse("access_token", "authToken");
2338
2393
 
2339
2394
  // Use token in protected endpoint
2340
- await api.get("{{baseUrl}}/protected-data", JSON.stringify({
2341
- headers: { "Authorization": "Bearer {{authToken}}" }
2342
- }));
2343
- ```
2395
+ await api.get(
2396
+ "{{baseUrl}}/protected-data",
2397
+ JSON.stringify({
2398
+ headers: { Authorization: "Bearer {{authToken}}" },
2399
+ }),
2400
+ );
2401
+ ```
package/executer.js CHANGED
@@ -24,7 +24,8 @@ const flags = {
24
24
  headless: args.includes("--headless"),
25
25
  parallel: args.includes("--parallel"),
26
26
  retry: args.includes("--retry"),
27
- dryrun: args.includes("--dryrun")
27
+ dryrun: args.includes("--dryrun"),
28
+ percentage: args.includes("--percentage")
28
29
  };
29
30
 
30
31
  function main() {
package/index.js CHANGED
@@ -11,7 +11,7 @@ const {
11
11
  page,
12
12
  request,
13
13
  random,
14
- resolveVariable
14
+ resolveVariable,
15
15
  } = require("./src/helper/imports/commons");
16
16
  const {
17
17
  keyboard,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "artes",
3
- "version": "1.0.78",
3
+ "version": "1.0.79",
4
4
  "description": "The simplest way to automate UI and API tests using Cucumber-style steps.",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -58,13 +58,13 @@ const invokeBrowser = async () => {
58
58
  }
59
59
 
60
60
  const context = await browser.newContext(browserContextOptions);
61
-
61
+
62
62
  return {
63
63
  browser: browser,
64
- context: context
64
+ context: context,
65
65
  };
66
66
  };
67
67
 
68
68
  module.exports = {
69
69
  invokeBrowser,
70
- };
70
+ };
@@ -1,5 +1,5 @@
1
1
  function showHelp() {
2
- console.log(`
2
+ console.log(`
3
3
  🚀 Artes - Playwright Test Runner
4
4
 
5
5
  Description:
@@ -45,8 +45,11 @@ function showHelp() {
45
45
 
46
46
  🎭 --dryrun Perform a dry run without executing tests
47
47
  Usage: artes --dryrun
48
+
49
+ 📈 --percentage Set minimum success percentage to pass test run
50
+ Usage: artes --percentage 85
48
51
  `);
49
- }
52
+ }
50
53
 
51
54
  module.exports = {
52
55
  showHelp,
@@ -11,14 +11,16 @@ function runTests(args, flags) {
11
11
  const tags = args[args.indexOf("--tags") + 1];
12
12
  const parallel = args[args.indexOf("--parallel") + 1];
13
13
  const retry = args[args.indexOf("--retry") + 1];
14
+ const percentage = args[args.indexOf("percentage") + 1];
14
15
 
15
16
  flags.env && console.log("Running env:", env);
16
17
  flags.env ? (process.env.ENV = JSON.stringify(env)) : "";
17
18
 
18
19
  flags.report
19
20
  ? (process.env.REPORT_FORMAT = JSON.stringify([
20
- "rerun:@rerun.txt","progress-bar",
21
- "allure-cucumberjs/reporter:./allure-results"
21
+ "rerun:@rerun.txt",
22
+ "progress-bar",
23
+ "allure-cucumberjs/reporter:./allure-results",
22
24
  ]))
23
25
  : "";
24
26
 
@@ -35,6 +37,7 @@ function runTests(args, flags) {
35
37
  flags.parallel ? (process.env.PARALLEL = JSON.stringify(parallel)) : "";
36
38
  flags.retry ? (process.env.RETRY = JSON.stringify(retry)) : "";
37
39
  flags.dryrun ? (process.env.DRYRUN = JSON.stringify(true)) : "";
40
+ flags.percentage ? (process.env.PERCENTAGE = percentage) : "";
38
41
 
39
42
  try {
40
43
  console.log("🧪 Running tests...");
@@ -86,7 +86,6 @@ class Elements {
86
86
  }
87
87
 
88
88
  static extractVarsFromResponse(responseBody, vars, customVarName) {
89
-
90
89
  function getValueByPath(obj, path) {
91
90
  const keys = path.split(".");
92
91
  let current = obj;
@@ -1,6 +1,11 @@
1
1
  const path = require("path");
2
2
  const fs = require("fs");
3
- const { context, selector, resolveVariable, moduleConfig } = require("../imports/commons");
3
+ const {
4
+ context,
5
+ selector,
6
+ resolveVariable,
7
+ moduleConfig,
8
+ } = require("../imports/commons");
4
9
 
5
10
  function getMimeType(filePath) {
6
11
  const ext = path.extname(filePath).toLowerCase();
@@ -90,11 +95,12 @@ async function requestMaker(headers, data, requestDataType) {
90
95
  async function responseMaker(request, response, duration) {
91
96
  const responseObject = {};
92
97
 
93
- response && Object.assign(responseObject, {
94
- "Response Params": `URL: ${response.url()}
98
+ response &&
99
+ Object.assign(responseObject, {
100
+ "Response Params": `URL: ${response.url()}
95
101
  Response Status: ${await response.status()}
96
- Response Time: ${Math.round(duration)} ms`
97
- });
102
+ Response Time: ${Math.round(duration)} ms`,
103
+ });
98
104
 
99
105
  request?.headers &&
100
106
  Object.assign(responseObject, { "Request Headers": await request.headers });
@@ -117,7 +123,9 @@ async function responseMaker(request, response, duration) {
117
123
  }
118
124
  }
119
125
 
120
- Object.assign(responseObject, { "Response Time": `${Math.round(duration)} ms`});
126
+ Object.assign(responseObject, {
127
+ "Response Time": `${Math.round(duration)} ms`,
128
+ });
121
129
 
122
130
  return responseObject;
123
131
  }
@@ -168,7 +176,7 @@ const api = {
168
176
  switch (requestDataType) {
169
177
  case "multipart":
170
178
  let formData = {};
171
-
179
+
172
180
  for (const [key, value] of Object.entries(payloadJSON?.body)) {
173
181
  processForm(formData, key, value);
174
182
  }
@@ -208,7 +216,7 @@ const api = {
208
216
  switch (requestDataType) {
209
217
  case "multipart":
210
218
  let formData = {};
211
-
219
+
212
220
  for (const [key, value] of Object.entries(payloadJSON?.body)) {
213
221
  processForm(formData, key, value);
214
222
  }
@@ -249,7 +257,7 @@ const api = {
249
257
  switch (requestDataType) {
250
258
  case "multipart":
251
259
  let formData = {};
252
-
260
+
253
261
  for (const [key, value] of Object.entries(payloadJSON?.body)) {
254
262
  processForm(formData, key, value);
255
263
  }
@@ -18,4 +18,4 @@ const browser = {
18
18
 
19
19
  module.exports = {
20
20
  browser,
21
- };
21
+ };
@@ -3,8 +3,10 @@ const {
3
3
  Before,
4
4
  After,
5
5
  Status,
6
- setDefaultTimeout, AfterStep,
7
- BeforeStep
6
+ setDefaultTimeout,
7
+ AfterStep,
8
+ BeforeStep,
9
+ AfterAll,
8
10
  } = require("@cucumber/cucumber");
9
11
  const { invokeBrowser } = require("../helper/contextManager/browserManager");
10
12
  const { invokeRequest } = require("../helper/contextManager/requestManager");
@@ -44,33 +46,34 @@ Before(async function () {
44
46
  BeforeStep(async function ({ pickleStep }) {
45
47
  const stepText = pickleStep.text;
46
48
 
47
- const methods = ['GET', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE'];
49
+ const methods = ["GET", "HEAD", "POST", "PUT", "PATCH", "DELETE"];
48
50
 
49
- if( methods.some(method => stepText.includes(method))){
50
- context.response = {}
51
+ if (methods.some((method) => stepText.includes(method))) {
52
+ context.response = {};
51
53
  }
52
- })
54
+ });
53
55
 
54
- AfterStep(async function ({pickleStep}) {
56
+ AfterStep(async function ({ pickleStep }) {
55
57
  const stepText = pickleStep.text;
56
58
 
57
- const methods = ['GET', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE'];
59
+ const methods = ["GET", "HEAD", "POST", "PUT", "PATCH", "DELETE"];
58
60
 
59
- if( methods.some(method => stepText.includes(method))){
60
- if (await context.response) {
61
- for (const [key, value] of Object.entries(context.response)) {
62
- let text = `${key}:\n`;
63
-
64
- if (typeof value === 'object') {
65
- text += JSON.stringify(value, null, 2);
66
- } else {
67
- text += value;
61
+ if (methods.some((method) => stepText.includes(method))) {
62
+ if (await context.response) {
63
+ for (const [key, value] of Object.entries(context.response)) {
64
+ let text = `${key}:\n`;
65
+
66
+ if (typeof value === "object") {
67
+ text += JSON.stringify(value, null, 2);
68
+ } else {
69
+ text += value;
70
+ }
71
+
72
+ await this.attach(text, "text/plain");
68
73
  }
69
-
70
- await this.attach(text, "text/plain");
71
74
  }
72
- }}
73
- })
75
+ }
76
+ });
74
77
 
75
78
  After(async function ({ pickle, result }) {
76
79
  if (result?.status != Status.PASSED) {
@@ -88,33 +91,51 @@ After(async function ({ pickle, result }) {
88
91
  if (context.response) {
89
92
  for (const [key, value] of Object.entries(context.response)) {
90
93
  let text = `${key}:\n`;
91
-
92
- if (typeof value === 'object') {
94
+
95
+ if (typeof value === "object") {
93
96
  text += JSON.stringify(value, null, 2);
94
97
  } else {
95
98
  text += value;
96
99
  }
97
-
100
+
98
101
  await this.attach(text, "text/plain");
99
102
  }
100
103
  }
101
104
 
102
105
  await context.page?.close();
103
-
106
+
104
107
  await context.browserContext?.close();
105
-
108
+
106
109
  await context.browser?.close();
107
-
110
+
108
111
  await context.request?.dispose();
109
112
 
110
113
  if (result?.status != Status.PASSED && context.page.video()) {
111
114
  const videoPath = await context.page.video().path();
112
- await new Promise(resolve => setTimeout(resolve, 1000));
113
-
115
+ await new Promise((resolve) => setTimeout(resolve, 1000));
116
+
114
117
  if (fs.existsSync(videoPath)) {
115
118
  const webmBuffer = await fs.readFileSync(videoPath);
116
119
  await this.attach(webmBuffer, "video/webm");
117
120
  }
118
121
  }
122
+ });
119
123
 
120
- });
124
+ AfterAll(async function () {
125
+ const successPercentage = 100 - (testsFailed / totalTests) * 100;
126
+ const successRate =
127
+ successPercentage.toFixed(2) >= cucumberConfig.testPercentage;
128
+ if (!isNaN(successPercentage)) {
129
+ if (successRate) {
130
+ console.log(
131
+ `Tests passed with ${successPercentage.toFixed(2)}% results!`,
132
+ );
133
+ process.exit(0);
134
+ } else {
135
+ console.log(
136
+ `Tests failed with ${successPercentage.toFixed(2)}% results!`,
137
+ );
138
+ process.exit(1);
139
+ }
140
+ }
141
+ });
@@ -160,7 +160,11 @@ When(
160
160
  When(
161
161
  "User saves {string} variable from response as {string}",
162
162
  async function (vars, customVarName) {
163
- await extractVarsFromResponse(context.response["Response Body"], vars, customVarName);
163
+ await extractVarsFromResponse(
164
+ context.response["Response Body"],
165
+ vars,
166
+ customVarName,
167
+ );
164
168
  },
165
169
  );
166
170
 
@@ -18,14 +18,14 @@ Given(
18
18
  "User sends GET request to {string} and save {string} variable from {string} array as a {string} randomly",
19
19
  async (endPoint, varName, fromArray, variableKey) => {
20
20
  await api.get(endPoint);
21
- let responseBody
22
- if(fromArray=="[]"){
23
- responseBody = await context.response["Response Body"]
24
- }else{
25
- responseBody = await context.response["Response Body"][fromArray]
21
+ let responseBody;
22
+ if (fromArray == "[]") {
23
+ responseBody = await context.response["Response Body"];
24
+ } else {
25
+ responseBody = await context.response["Response Body"][fromArray];
26
26
  }
27
27
  const randomContent =
28
- responseBody[random.number.int({ min: 0, max: responseBody.length - 1 })];
28
+ responseBody[random.number.int({ min: 0, max: responseBody.length - 1 })];
29
29
  context.vars[variableKey] = randomContent[varName];
30
30
  },
31
- );
31
+ );