artes 1.1.21 → 1.1.24
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 +110 -25
- package/cucumber.config.js +19 -1
- package/executer.js +19 -14
- package/package.json +1 -1
- package/src/helper/controller/pomCollector.js +5 -1
- package/src/helper/executers/helper.js +6 -0
- package/src/helper/executers/projectCreator.js +3 -0
- package/src/helper/imports/commons.js +1 -1
- package/src/hooks/hooks.js +138 -89
package/README.md
CHANGED
|
@@ -42,30 +42,32 @@ 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`
|
|
52
|
-
| `--reportSuccess`
|
|
53
|
-
|
|
|
54
|
-
|
|
|
55
|
-
|
|
|
56
|
-
|
|
|
57
|
-
|
|
|
58
|
-
|
|
|
59
|
-
|
|
|
60
|
-
|
|
|
61
|
-
|
|
|
62
|
-
|
|
|
63
|
-
|
|
|
64
|
-
|
|
|
65
|
-
|
|
|
66
|
-
|
|
|
67
|
-
|
|
|
68
|
-
|
|
|
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
|
+
| `--reportSuccess` | Add screenshots and video records for also Success test cases | `artes --reportSuccess` |
|
|
53
|
+
| `--trace` | Enable tracing | `artes --trace ` |
|
|
54
|
+
| `-rwt, --reportWithTrace` | Add trace to the report | `artes -rwt` or `artes --reportWithTrace` |
|
|
55
|
+
| 📁 `--features` | Specify one or more feature files' relative paths to run (comma-separated) | `artes --features "tests/features/Alma,tests/features/Banan.feature"` |
|
|
56
|
+
| 📜 `--stepDef` | Specify one or more step definition files' relative paths to use (comma-separated) | `artes --stepDef "tests/steps/login.js,tests/steps/home.js"` |
|
|
57
|
+
| 🔖 `--tags` | Run tests with specified Cucumber tags | `artes --tags "@smoke or @wip"` |
|
|
58
|
+
| 🌐 `--env` | Set the environment for the test run | `artes --env "dev"` |
|
|
59
|
+
| 🕶️ `--headless` | Run browser in headless mode | `artes --headless` |
|
|
60
|
+
| ⚡ `--parallel` | Run tests in parallel mode | `artes --parallel 2` |
|
|
61
|
+
| 🔁 `--retry` | Retry failed tests | `artes --retry 3` |
|
|
62
|
+
| 🎭 `--dryRun` | Perform a dry run without executing tests | `artes --dryRun` |
|
|
63
|
+
| 📈 `--percentage` | Set minimum success percentage to pass test run (default is 0) | `artes --percentage 85` |
|
|
64
|
+
| 🌍 `--browser` | Specify browser to use (`chromium`, `firefox`, or `webkit`) | `artes --browser chromium` |
|
|
65
|
+
| 🔗 `--baseURL` | Set base URL for the tests | `artes --baseURL "https://example.com"` |
|
|
66
|
+
| 🖥️ `--maxScreen` | Maximize browser window on launch | `artes --maxScreen` |
|
|
67
|
+
| 📏 `--width` | Set browser width (default is 1280) | `artes --width 1920` |
|
|
68
|
+
| 📐 `--height` | Set browser height (default is 720) | `artes --height 1080` |
|
|
69
|
+
| ⏱️ `--timeout` | Set timeout for each test step in seconds (default is 30 seconds) | `artes --timeout 10` |
|
|
70
|
+
| 🐢 `--slowMo` | Slow down text execution for clear view (default: 0 seconds) | `artes --slowMo 1` |
|
|
69
71
|
|
|
70
72
|
\*\* To just run the tests: <br>
|
|
71
73
|
Globally: artes <br>
|
|
@@ -173,6 +175,86 @@ Feature: Searching on Google 🔍
|
|
|
173
175
|
|
|
174
176
|
---
|
|
175
177
|
|
|
178
|
+
## 🌍 Environment Variables Configuration
|
|
179
|
+
|
|
180
|
+
Artes now supports environment-specific configurations through environment variables. This feature allows you to manage different settings for development, staging, and production environments.
|
|
181
|
+
|
|
182
|
+
### Setting Up Environment Variables
|
|
183
|
+
|
|
184
|
+
1. **Configure Environment in artes.config.js:**
|
|
185
|
+
|
|
186
|
+
```javascript
|
|
187
|
+
module.exports = {
|
|
188
|
+
baseURL: {
|
|
189
|
+
dev: "https://dev.dlp.az",
|
|
190
|
+
pre: "https://pre.dlp.az",
|
|
191
|
+
prod: "https://api.dlp.az",
|
|
192
|
+
},
|
|
193
|
+
env: "dev", // Specify which environment to use
|
|
194
|
+
// ... other configurations
|
|
195
|
+
};
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
**Alternative single URL configuration:**
|
|
199
|
+
|
|
200
|
+
```javascript
|
|
201
|
+
module.exports = {
|
|
202
|
+
baseURL: "https://api.example.com", // Direct string URL
|
|
203
|
+
env: "dev",
|
|
204
|
+
// ... other configurations
|
|
205
|
+
};
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
2. **Create Environment Variable Files:**
|
|
209
|
+
Create JSON files under `src/tests/environment-variables/` folder with names matching your environment:
|
|
210
|
+
|
|
211
|
+
**dev.json:**
|
|
212
|
+
|
|
213
|
+
```json
|
|
214
|
+
{
|
|
215
|
+
"api_key": "dev-api-key-12345",
|
|
216
|
+
"auth_token": "dev-auth-token",
|
|
217
|
+
"database_url": "dev-db.example.com",
|
|
218
|
+
"timeout": 5000,
|
|
219
|
+
"headers": {
|
|
220
|
+
"Authorization": "Bearer dev-token",
|
|
221
|
+
"Content-Type": "application/json"
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
**pre.json:**
|
|
227
|
+
|
|
228
|
+
```json
|
|
229
|
+
{
|
|
230
|
+
"api_key": "pre-api-key-67890",
|
|
231
|
+
"auth_token": "pre-auth-token",
|
|
232
|
+
"database_url": "pre-db.example.com",
|
|
233
|
+
"timeout": 3000,
|
|
234
|
+
"headers": {
|
|
235
|
+
"Authorization": "Bearer pre-token",
|
|
236
|
+
"Content-Type": "application/json"
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### How It Works
|
|
242
|
+
|
|
243
|
+
1. **Environment Detection:** When Artes runs, it reads the `env` value from `artes.config.js`
|
|
244
|
+
2. **Base URL Resolution:** If `baseURL` is an object, it uses the environment key to find the corresponding URL. If `baseURL` is a string, it uses it directly
|
|
245
|
+
3. **Variable Loading:** Artes looks for a JSON file matching the environment name in `src/tests/environment-variables/`
|
|
246
|
+
4. **Runtime Access:** All variables from the environment file become available during test execution
|
|
247
|
+
|
|
248
|
+
### Important Notes
|
|
249
|
+
|
|
250
|
+
- ⚠️ **Base URLs must be defined in `artes.config.js`** - they cannot be set in the environment variable JSON files
|
|
251
|
+
- 📁 Environment variable files should be placed in `src/tests/environment-variables/`
|
|
252
|
+
- 🏷️ File names must exactly match the environment name (e.g., `dev.json` for `env: "dev"`)
|
|
253
|
+
- 🔄 Variables are loaded into variable storage and can be accessed during test runs
|
|
254
|
+
- 🌐 Use environment variables for headers, API keys, timeouts, and other environment-specific configurations
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
176
258
|
## 🛠️ Customization
|
|
177
259
|
|
|
178
260
|
## ✍️ Writing Custom Step Definitions
|
|
@@ -295,7 +377,10 @@ You can configure Artes by editing the `artes.config.js` file. Below are the def
|
|
|
295
377
|
| `pomPath` | `moduleConfig.pomPath` | Path to Page Object Models. |
|
|
296
378
|
| `import` | `[]` | Support code paths. |
|
|
297
379
|
| `testPercentage` | `0` | Define test coverage percentage |
|
|
298
|
-
| `
|
|
380
|
+
| `report` | `false` | Generate report |
|
|
381
|
+
| `reportSuccess` | `false` | Add screenshots and video records for also success test cases |
|
|
382
|
+
| `trace` | `false` | Enable trace |
|
|
383
|
+
| `reportWithTrace` | `false` | Add trace to the report |
|
|
299
384
|
| `format` | `["rerun:@rerun.txt", "allure-cucumberjs/reporter"]` | Formatter names/paths. |
|
|
300
385
|
| `formatOptions` | `{ "resultsDir": "allure-result" }` | Formatter options. |
|
|
301
386
|
| `parallel` | `1` | Number of parallel workers. |
|
package/cucumber.config.js
CHANGED
|
@@ -58,10 +58,23 @@ module.exports = {
|
|
|
58
58
|
: moduleConfig.pomPath,
|
|
59
59
|
import: artesConfig.import || [], // Support code paths
|
|
60
60
|
|
|
61
|
+
report:
|
|
62
|
+
process.env.REPORT_WITH_TRACE ??
|
|
63
|
+
artesConfig.reportWithTrace ??
|
|
64
|
+
process.env.REPORT ??
|
|
65
|
+
artesConfig.report ??
|
|
66
|
+
false, // Generate report
|
|
61
67
|
// Formatting and output
|
|
62
68
|
successReport: process.env.REPORT_SUCCESS
|
|
63
69
|
? true
|
|
64
70
|
: artesConfig.reportSuccess || false, // Include successful tests in report
|
|
71
|
+
|
|
72
|
+
trace: process.env.TRACE ? process.env.TRACE : artesConfig.trace || false, // Enable tracing
|
|
73
|
+
|
|
74
|
+
reportWithTrace: process.env.REPORT_WITH_TRACE
|
|
75
|
+
? process.env.REPORT_WITH_TRACE
|
|
76
|
+
: artesConfig.reportWithTrace || false, // Include trace in report
|
|
77
|
+
|
|
65
78
|
format: finalFormats, // Formatter names/paths
|
|
66
79
|
formatOptions: artesConfig.formatOptions || {
|
|
67
80
|
resultsDir: `allure-result`,
|
|
@@ -103,7 +116,12 @@ module.exports = {
|
|
|
103
116
|
// World parameters
|
|
104
117
|
worldParameters: artesConfig.worldParameters || {}, // Custom world parameters
|
|
105
118
|
},
|
|
106
|
-
env: process.env.ENV
|
|
119
|
+
env: process.env.ENV
|
|
120
|
+
? JSON.parse(process.env.ENV)
|
|
121
|
+
: artesConfig.env ||
|
|
122
|
+
(typeof artesConfig.baseURL === "object" && artesConfig.baseURL !== null
|
|
123
|
+
? Object.keys(artesConfig.baseURL)[0]
|
|
124
|
+
: ""),
|
|
107
125
|
baseURL: process.env.BASE_URL
|
|
108
126
|
? JSON.parse(process.env.BASE_URL)
|
|
109
127
|
: artesConfig?.baseURL
|
package/executer.js
CHANGED
|
@@ -7,6 +7,7 @@ const {
|
|
|
7
7
|
generateReport,
|
|
8
8
|
cleanUp,
|
|
9
9
|
} = require("./src/helper/executers/exporter");
|
|
10
|
+
const artesConfig = require("../../artes.config");
|
|
10
11
|
const fs = require("fs");
|
|
11
12
|
const path = require("path");
|
|
12
13
|
|
|
@@ -20,6 +21,7 @@ const flags = {
|
|
|
20
21
|
report: args.includes("-r") || args.includes("--report"),
|
|
21
22
|
reportSuccess: args.includes("--reportSuccess"),
|
|
22
23
|
trace: args.includes("-t") || args.includes("--trace"),
|
|
24
|
+
reportWithTrace: args.includes("-rwt") || args.includes("--reportWithTrace"),
|
|
23
25
|
features: args.includes("--features"),
|
|
24
26
|
stepDef: args.includes("--stepDef"),
|
|
25
27
|
tags: args.includes("--tags"),
|
|
@@ -56,7 +58,10 @@ const slowMo = args[args.indexOf("--slowMo") + 1];
|
|
|
56
58
|
flags.env && console.log("Running env:", env);
|
|
57
59
|
flags.env ? (process.env.ENV = JSON.stringify(env)) : "";
|
|
58
60
|
|
|
59
|
-
flags.
|
|
61
|
+
flags.reportWithTrace ||
|
|
62
|
+
artesConfig.reportWithTrace ||
|
|
63
|
+
flags.report ||
|
|
64
|
+
artesConfig.report
|
|
60
65
|
? (process.env.REPORT_FORMAT = JSON.stringify([
|
|
61
66
|
"allure-cucumberjs/reporter:./allure-results",
|
|
62
67
|
]))
|
|
@@ -73,8 +78,12 @@ flags.features ? (process.env.FEATURES = features) : "";
|
|
|
73
78
|
flags.stepDef && console.log("Running step definitions:", flags.stepDef);
|
|
74
79
|
flags.stepDef ? (process.env.STEP_DEFINITIONS = stepDef) : "";
|
|
75
80
|
|
|
81
|
+
flags.report ? (process.env.REPORT = true) : "";
|
|
82
|
+
|
|
76
83
|
flags.trace ? (process.env.TRACE = true) : "";
|
|
77
84
|
|
|
85
|
+
flags.reportWithTrace ? (process.env.REPORT_WITH_TRACE = true) : "";
|
|
86
|
+
|
|
78
87
|
flags.headless &&
|
|
79
88
|
console.log("Running mode:", flags.headless ? "headless" : "headed");
|
|
80
89
|
flags.headless ? (process.env.MODE = JSON.stringify(true)) : false;
|
|
@@ -112,25 +121,21 @@ function main() {
|
|
|
112
121
|
if (flags.create) return createProject(flags.createYes);
|
|
113
122
|
|
|
114
123
|
runTests();
|
|
115
|
-
if (
|
|
124
|
+
if (
|
|
125
|
+
flags.reportWithTrace ||
|
|
126
|
+
artesConfig.reportWithTrace ||
|
|
127
|
+
flags.report ||
|
|
128
|
+
artesConfig.report
|
|
129
|
+
)
|
|
130
|
+
generateReport();
|
|
116
131
|
|
|
117
132
|
if (
|
|
118
133
|
fs.existsSync(
|
|
119
|
-
path.join(
|
|
120
|
-
process.cwd(),
|
|
121
|
-
"node_modules",
|
|
122
|
-
"artes",
|
|
123
|
-
"EXIT_CODE.txt",
|
|
124
|
-
),
|
|
134
|
+
path.join(process.cwd(), "node_modules", "artes", "EXIT_CODE.txt"),
|
|
125
135
|
)
|
|
126
136
|
) {
|
|
127
137
|
const data = fs.readFileSync(
|
|
128
|
-
path.join(
|
|
129
|
-
process.cwd(),
|
|
130
|
-
"node_modules",
|
|
131
|
-
"artes",
|
|
132
|
-
"EXIT_CODE.txt",
|
|
133
|
-
),
|
|
138
|
+
path.join(process.cwd(), "node_modules", "artes", "EXIT_CODE.txt"),
|
|
134
139
|
"utf8",
|
|
135
140
|
);
|
|
136
141
|
process.env.EXIT_CODE = parseInt(data, 10);
|
package/package.json
CHANGED
|
@@ -9,7 +9,11 @@ function pomCollector() {
|
|
|
9
9
|
`${cucumberConfig.default.pomPath}/${file}`,
|
|
10
10
|
"utf-8",
|
|
11
11
|
(err, content) => {
|
|
12
|
-
|
|
12
|
+
try {
|
|
13
|
+
addElements(JSON.parse(content));
|
|
14
|
+
} catch (error) {
|
|
15
|
+
console.log(`Error parsing POM file ${file}:`, error.message);
|
|
16
|
+
}
|
|
13
17
|
},
|
|
14
18
|
);
|
|
15
19
|
});
|
|
@@ -27,6 +27,12 @@ function showHelp() {
|
|
|
27
27
|
|
|
28
28
|
✅ --reportSuccess Generate screenshot and video record with also successful tests
|
|
29
29
|
Usage: artes --reportSuccess
|
|
30
|
+
|
|
31
|
+
--trace Enable tracing for all tests
|
|
32
|
+
Usage: artes --trace
|
|
33
|
+
|
|
34
|
+
-rwt, --reportWithTrace Include trace in the report
|
|
35
|
+
Usage: artes --reportWithTrace
|
|
30
36
|
|
|
31
37
|
📁 --features Specify one or more feature files' relative paths to run (comma-separated)
|
|
32
38
|
Usage: artes --features "tests/features/Alma, tests/features/Banan.feature"
|
|
@@ -48,7 +48,10 @@ function createProject(createYes) {
|
|
|
48
48
|
// timeout : 0, // number - Test timeout in seconds
|
|
49
49
|
// slowMo: 0, // number - Slow down test execution (Default: 0 seconds)
|
|
50
50
|
// parallel: 0, // number - Number of parallel workers
|
|
51
|
+
//report: true / boolean - Generate report
|
|
51
52
|
// reportSuccess: false, // boolean - Add screenshots and video records to report also for success test cases
|
|
53
|
+
// trace: false, // boolean - Enable tracing
|
|
54
|
+
// reportWithTrace: false, // boolean - Include trace in report
|
|
52
55
|
// format: [], // string[] - Formatter names/paths
|
|
53
56
|
// formatOptions: {}, // object - Formatter options
|
|
54
57
|
// retry: 0, // number - Retry attempts for failing tests
|
|
@@ -35,7 +35,7 @@ const moduleConfig = {
|
|
|
35
35
|
stepsPath: path.join(projectPath, "/tests/steps/*.js"),
|
|
36
36
|
pomPath: path.join(projectPath, "/tests/POMs"),
|
|
37
37
|
cleanUpPaths:
|
|
38
|
-
"allure-result allure-results test-results @rerun.txt testsStatus EXIT_CODE.txt"
|
|
38
|
+
"allure-result allure-results test-results @rerun.txt testsStatus EXIT_CODE.txt",
|
|
39
39
|
};
|
|
40
40
|
|
|
41
41
|
module.exports = {
|
package/src/hooks/hooks.js
CHANGED
|
@@ -8,26 +8,70 @@ const {
|
|
|
8
8
|
BeforeStep,
|
|
9
9
|
AfterAll,
|
|
10
10
|
} = require("@cucumber/cucumber");
|
|
11
|
+
const { spawnSync } = require("child_process");
|
|
11
12
|
const { invokeBrowser } = require("../helper/contextManager/browserManager");
|
|
12
13
|
const { invokeRequest } = require("../helper/contextManager/requestManager");
|
|
13
14
|
const { pomCollector } = require("../helper/controller/pomCollector");
|
|
14
15
|
const cucumberConfig = require("../../cucumber.config");
|
|
15
16
|
const { context } = require("./context");
|
|
16
17
|
const fs = require("fs");
|
|
17
|
-
const { moduleConfig } = require("artes/src/helper/imports/commons");
|
|
18
18
|
const path = require("path");
|
|
19
|
+
const { moduleConfig } = require("artes/src/helper/imports/commons");
|
|
19
20
|
|
|
20
21
|
const statusDir = path.join(process.cwd(), "testsStatus");
|
|
22
|
+
const HTTP_METHODS = ["GET", "HEAD", "POST", "PUT", "PATCH", "DELETE"];
|
|
23
|
+
|
|
24
|
+
/* ------------------- Helpers ------------------- */
|
|
21
25
|
|
|
22
26
|
setDefaultTimeout(cucumberConfig.default.timeout);
|
|
23
27
|
|
|
24
|
-
|
|
28
|
+
async function attachResponse(attachFn) {
|
|
29
|
+
if (!context.response) return;
|
|
30
|
+
|
|
31
|
+
for (const [key, value] of Object.entries(context.response)) {
|
|
32
|
+
const text =
|
|
33
|
+
typeof value === "object"
|
|
34
|
+
? `${key}:\n${JSON.stringify(value, null, 2)}`
|
|
35
|
+
: `${key}:\n${value}`;
|
|
36
|
+
|
|
37
|
+
await attachFn(text, "text/plain");
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function saveTestStatus(result, pickle) {
|
|
42
|
+
fs.mkdirSync(statusDir, { recursive: true });
|
|
43
|
+
fs.writeFileSync(
|
|
44
|
+
path.join(statusDir, `${result.status}-${pickle.id}.txt`),
|
|
45
|
+
"",
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/* ------------------- Hooks ------------------- */
|
|
50
|
+
|
|
51
|
+
BeforeAll(() => {
|
|
25
52
|
pomCollector();
|
|
26
53
|
});
|
|
27
54
|
|
|
28
55
|
Before(async function () {
|
|
29
56
|
context.vars = {};
|
|
30
57
|
|
|
58
|
+
const envFilePath = path.join(
|
|
59
|
+
moduleConfig.projectPath,
|
|
60
|
+
"tests",
|
|
61
|
+
"environment_variables",
|
|
62
|
+
`${cucumberConfig.env}.env.json`,
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
if (fs.existsSync(envFilePath)) {
|
|
66
|
+
let env_vars = fs.readFileSync(envFilePath, "utf-8");
|
|
67
|
+
try {
|
|
68
|
+
env_vars = JSON.parse(env_vars);
|
|
69
|
+
context.vars = { ...context.vars, ...env_vars };
|
|
70
|
+
} catch (err) {
|
|
71
|
+
console.log("Error parsing environment variables JSON:", err);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
31
75
|
const { browser, context: browserContext } = await invokeBrowser();
|
|
32
76
|
const requestInstance = await invokeRequest();
|
|
33
77
|
|
|
@@ -38,130 +82,135 @@ Before(async function () {
|
|
|
38
82
|
|
|
39
83
|
await context.page.setDefaultTimeout(cucumberConfig.default.timeout);
|
|
40
84
|
|
|
41
|
-
|
|
42
|
-
(
|
|
85
|
+
if (
|
|
86
|
+
(cucumberConfig.default.reportWithTrace || cucumberConfig.default.trace) &&
|
|
87
|
+
!context.response
|
|
88
|
+
) {
|
|
89
|
+
await browserContext.tracing.start({
|
|
43
90
|
sources: true,
|
|
44
91
|
screenshots: true,
|
|
45
92
|
snapshots: true,
|
|
46
|
-
})
|
|
93
|
+
});
|
|
94
|
+
}
|
|
47
95
|
});
|
|
48
96
|
|
|
49
|
-
BeforeStep(
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
const methods = ["GET", "HEAD", "POST", "PUT", "PATCH", "DELETE"];
|
|
53
|
-
|
|
54
|
-
if (methods.some((method) => stepText.includes(method))) {
|
|
97
|
+
BeforeStep(({ pickleStep }) => {
|
|
98
|
+
if (HTTP_METHODS.some((method) => pickleStep.text.includes(method))) {
|
|
55
99
|
context.response = {};
|
|
56
100
|
}
|
|
57
101
|
});
|
|
58
102
|
|
|
59
103
|
AfterStep(async function ({ pickleStep }) {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
const methods = ["GET", "HEAD", "POST", "PUT", "PATCH", "DELETE"];
|
|
63
|
-
|
|
64
|
-
if (methods.some((method) => stepText.includes(method))) {
|
|
65
|
-
if (await context.response) {
|
|
66
|
-
for (const [key, value] of Object.entries(context.response)) {
|
|
67
|
-
let text = `${key}:\n`;
|
|
68
|
-
|
|
69
|
-
if (typeof value === "object") {
|
|
70
|
-
text += JSON.stringify(value, null, 2);
|
|
71
|
-
} else {
|
|
72
|
-
text += value;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
await this.attach(text, "text/plain");
|
|
76
|
-
}
|
|
77
|
-
}
|
|
104
|
+
if (HTTP_METHODS.some((method) => pickleStep.text.includes(method))) {
|
|
105
|
+
await attachResponse(this.attach);
|
|
78
106
|
}
|
|
79
107
|
});
|
|
80
108
|
|
|
81
109
|
After(async function ({ pickle, result }) {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
110
|
+
const shouldReport =
|
|
111
|
+
(cucumberConfig.default.successReport ||
|
|
112
|
+
result?.status !== Status.PASSED) &&
|
|
113
|
+
!context.response;
|
|
114
|
+
|
|
115
|
+
if (shouldReport) {
|
|
116
|
+
const screenshotPath = path.join(
|
|
117
|
+
"test-results",
|
|
118
|
+
"visualReport",
|
|
119
|
+
pickle.name,
|
|
120
|
+
`${pickle.name}.png`,
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
const img = await context.page.screenshot({
|
|
124
|
+
path: screenshotPath,
|
|
85
125
|
type: "png",
|
|
86
126
|
});
|
|
87
|
-
await this.attach(img,
|
|
127
|
+
await this.attach(img, {
|
|
128
|
+
mediaType: "image/png",
|
|
129
|
+
fileName: `${pickle.name.replaceAll(" ", "_")}.png`,
|
|
130
|
+
});
|
|
88
131
|
}
|
|
89
132
|
|
|
90
|
-
|
|
133
|
+
saveTestStatus(result, pickle);
|
|
91
134
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
"",
|
|
135
|
+
const tracePath = path.join(
|
|
136
|
+
moduleConfig.projectPath,
|
|
137
|
+
`./${pickle.name.replaceAll(" ", "_")}.zip`,
|
|
95
138
|
);
|
|
96
139
|
|
|
97
|
-
|
|
98
|
-
(
|
|
99
|
-
|
|
100
|
-
|
|
140
|
+
if (
|
|
141
|
+
(cucumberConfig.default.reportWithTrace || cucumberConfig.default.trace) &&
|
|
142
|
+
!context.response &&
|
|
143
|
+
shouldReport
|
|
144
|
+
) {
|
|
145
|
+
await context.browserContext.tracing.stop({
|
|
146
|
+
path: tracePath,
|
|
147
|
+
});
|
|
101
148
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
let text = `${key}:\n`;
|
|
149
|
+
if (cucumberConfig.default.reportWithTrace) {
|
|
150
|
+
const trace = fs.readFileSync(tracePath);
|
|
105
151
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
}
|
|
152
|
+
await this.attach(trace, {
|
|
153
|
+
mediaType: "application/zip",
|
|
154
|
+
fileName: `${pickle.name.replace(/\s+/g, "_")}_trace.zip`,
|
|
155
|
+
});
|
|
111
156
|
|
|
112
|
-
|
|
157
|
+
if (!cucumberConfig.default.trace) {
|
|
158
|
+
spawnSync("npx", ["rimraf", tracePath], {
|
|
159
|
+
cwd: moduleConfig.projectPath,
|
|
160
|
+
stdio: "inherit",
|
|
161
|
+
shell: true,
|
|
162
|
+
});
|
|
163
|
+
}
|
|
113
164
|
}
|
|
114
165
|
}
|
|
115
166
|
|
|
116
|
-
await
|
|
167
|
+
await attachResponse(this.attach);
|
|
117
168
|
|
|
169
|
+
await context.page?.close();
|
|
118
170
|
await context.browserContext?.close();
|
|
119
|
-
|
|
120
171
|
await context.browser?.close();
|
|
121
|
-
|
|
122
172
|
await context.request?.dispose();
|
|
123
173
|
|
|
124
|
-
if (
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
const videoPath = await context.page.video().path();
|
|
129
|
-
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
174
|
+
if (shouldReport && context.page.video) {
|
|
175
|
+
const video = context.page.video();
|
|
176
|
+
if (video) {
|
|
177
|
+
const videoPath = await video.path();
|
|
130
178
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
179
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
180
|
+
|
|
181
|
+
if (fs.existsSync(videoPath)) {
|
|
182
|
+
const webmBuffer = fs.readFileSync(videoPath);
|
|
183
|
+
await this.attach(webmBuffer, {
|
|
184
|
+
mediaType: "video/webm",
|
|
185
|
+
fileName: `${pickle.name.replaceAll(" ", "_")}.webm`,
|
|
186
|
+
});
|
|
187
|
+
}
|
|
134
188
|
}
|
|
135
189
|
}
|
|
136
190
|
});
|
|
137
191
|
|
|
138
|
-
AfterAll(
|
|
139
|
-
if (fs.existsSync(statusDir))
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
const
|
|
148
|
-
successPercentage
|
|
149
|
-
|
|
150
|
-
if (
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
)
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
console.log(
|
|
161
|
-
`Tests failed at required ${cucumberConfig.default.testPercentage}% success rate with ${successPercentage.toFixed(2)}%!`,
|
|
162
|
-
);
|
|
163
|
-
fs.writeFileSync(path.join(process.cwd(), `EXIT_CODE.txt`), "1");
|
|
164
|
-
}
|
|
192
|
+
AfterAll(() => {
|
|
193
|
+
if (!fs.existsSync(statusDir)) return;
|
|
194
|
+
|
|
195
|
+
const files = fs.readdirSync(statusDir);
|
|
196
|
+
const passedCount = files.filter((f) => f.split("-")[0] === "PASSED").length;
|
|
197
|
+
const totalTests = files.length;
|
|
198
|
+
const successPercentage = (passedCount / totalTests) * 100;
|
|
199
|
+
|
|
200
|
+
if (cucumberConfig.default.testPercentage !== undefined) {
|
|
201
|
+
const meetsThreshold =
|
|
202
|
+
successPercentage >= cucumberConfig.default.testPercentage;
|
|
203
|
+
|
|
204
|
+
if (meetsThreshold) {
|
|
205
|
+
console.log(
|
|
206
|
+
`✅ Tests passed required ${cucumberConfig.default.testPercentage}% success rate with ${successPercentage.toFixed(2)}%!`,
|
|
207
|
+
);
|
|
208
|
+
fs.writeFileSync(path.join(process.cwd(), "EXIT_CODE.txt"), "0");
|
|
209
|
+
} else {
|
|
210
|
+
console.log(
|
|
211
|
+
`❌ Tests failed required ${cucumberConfig.default.testPercentage}% success rate with ${successPercentage.toFixed(2)}%!`,
|
|
212
|
+
);
|
|
213
|
+
fs.writeFileSync(path.join(process.cwd(), "EXIT_CODE.txt"), "1");
|
|
165
214
|
}
|
|
166
215
|
}
|
|
167
216
|
});
|