artes 1.7.3 → 1.7.5

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
@@ -139,61 +139,77 @@ npx artes [options]
139
139
  npx artes [options]
140
140
  ```
141
141
 
142
- ### Options
143
-
144
- | Option | Description | Usage Example |
145
- | ------------------------- | ---------------------------------------------------------------------------------- | --------------------------------------------------------------------- |
146
- | 🆘 `-h, --help` | Show the usage options | `artes -h` or `artes --help` |
147
- | 🏷️ `-v, --version` | Show the current version of Artes | `artes -v` or `artes --version` |
148
- | 🏗️ `-c, --create` | Create an example project with Artes | `artes -c` or `artes --create` |
149
- | `-y, --yes` | Skip the confirmation prompt when creating an example project | `artes -c -y` or `artes --create --yes` |
150
- | 🚫 --noDeps | Skip installing dependencies when creating example project | `artes -c --noDeps` |
151
- | 📊 `-r, --report` | Run tests and generate Allure report | `artes -r` or `artes --report` |
152
- | `--reportSuccess` | Add screenshots and video records for also Success test cases | `artes --reportSuccess` |
153
- | `--trace` | Enable tracing | `artes --trace` |
154
- | `-rwt, --reportWithTrace` | Add trace to the report | `artes -rwt` or `artes --reportWithTrace` |
155
- | `--singleFileReport` | Generate single file allure report | `artes -r --singleFileReport` |
156
- | `--zip` | Zip the report folder after generation | `artes -r --zip` |
157
- | `--uploadReport` | Upload the generated report to Artes Reporting System | `artes -r --zip --uploadReport --reporterURL "https://example.com"` |
158
- | `--reporterURL` | URL of the Artes Reporting System to upload the report | `artes -r --zip --uploadReport --reporterURL "https://example.com"` |
159
- | `--projectName` | Name of the project in the Artes Reporting System (default: `"Artes Report"`) | `artes -r --zip --uploadReport --reporterURL "https://example.com" --projectName "My Project"` |
160
- | `--projectType` | Type of the project for reporting purposes (default: `"Artes"`) | `artes -r --zip --uploadReport --reporterURL "https://example.com" --projectType "API"` |
161
- | `--reportPath` | Path to the report zip file to upload (default: `./report.zip`) | `artes -r --zip --uploadReport --reporterURL "https://example.com" --reportPath "./my_report.zip"` |
162
- | 🖼️ `--logo` | Set a custom logo in the report sidebar. Accepts an absolute path, a relative path, or a direct image URL | `artes -r --logo /abs/path/logo.png`<br>`artes --logo logo.png`<br>`artes --logo 'https://example.com/logo.png'` |
163
- | 🏢 `--brandName` | Set the brand name displayed next to the logo in the report sidebar | `artes --brandName 'My Company'` |
164
- | 📄 `--reportName` | Report name displayed on the summary widget and in the Artes Reporting System | `artes --reportName 'Alma UI'`
165
- | 📁 `--features` | Specify one or more feature files' relative paths to run (comma-separated) | `artes --features "tests/features/Alma,tests/features/Banan.feature"` |
166
- | 📜 `--stepDef` | Specify one or more step definition files' relative paths to use (comma-separated) | `artes --stepDef "tests/steps/login.js,tests/steps/home.js"` |
167
- | 🔖 `--tags` | Run tests with specified Cucumber tags | `artes --tags "@smoke or @wip"` |
168
- | 🌐 `--env` | Set the environment for the test run | `artes --env "dev"` |
169
- | `--saveVar` | Set the variables from CLI | `artes --saveVar '{"armud":20,"banana":200}'` |
170
- | 🕶️ `--headless` | Run browser in headless mode | `artes --headless` |
171
- | ⚡ `--parallel` | Run tests in parallel mode | `artes --parallel 2` |
172
- | 🔁 `--retry` | Retry failed tests | `artes --retry 3` |
173
- | 🔁 `--rerun` | Rerun only the failed tests from previous run | `artes --rerun @rerun.txt` |
174
- | 🎭 `--dryRun` | Perform a dry run without executing tests | `artes --dryRun` |
175
- | 📈 `--percentage` | Set minimum success percentage to pass test run (default is 0) | `artes --percentage 85` |
176
- | 🌍 `--browser` | Specify browser to use (`chromium`, `firefox`, or `webkit`) | `artes --browser chromium` |
177
- | `--offline` | Run browser in offline mode | `artes --offline` |
178
- | 📱 `--device` | Emulate specific device (e.g., "iPhone 13") | `artes --device "iPhone 13"` |
179
- | 🔗 `--baseURL` | Set base URL for the tests | `artes --baseURL "https://example.com"` |
180
- | 🖥️ `--maxScreen` | Maximize browser window on launch | `artes --maxScreen` |
181
- | 📏 `--width` | Set browser width (default is 1280) | `artes --width 1920` |
182
- | 📐 `--height` | Set browser height (default is 720) | `artes --height 1080` |
183
- | ⏱️ `--timeout` | Set timeout for each test step in seconds (default is 30 seconds) | `artes --timeout 10` |
184
- | 🐢 `--slowMo` | Slow down text execution for clear view (default: 0 seconds) | `artes --slowMo 1` |
185
-
186
- ### AI Options
142
+
143
+ ### General ( artes -h or artes --help )
144
+
145
+ | Option | Description | Usage Example |
146
+ | --- | --- | --- |
147
+ | `-h, --help` | Show this help message | `artes -h` or `artes --help` |
148
+ | `-v, --version` | Show current version of artes | `artes -v` or `artes --version` |
149
+ | `-c, --create` | Create example artes project | `artes -c` or `artes --create` |
150
+ | `-y, --yes` | Skip confirmation prompt when creating a project | `artes -c -y` or `artes -c --yes` |
151
+ | `--noDeps` | Create project without installing dependencies | `artes -c --noDeps` |
152
+
153
+ ### Reporting & Branding ( artes report --help )
154
+
155
+ | Option | Description | Usage Example |
156
+ | --- | --- | --- |
157
+ | `-r, --report` | Run tests and generate Allure report | `artes -r` or `artes --report` |
158
+ | `--reportSuccess` | Generate screenshot and video with successful tests too | `artes --reportSuccess` |
159
+ | `--trace` | Enable tracing for all tests | `artes --trace` |
160
+ | `-rwt, --reportWithTrace` | Include trace in the report | `artes -rwt` or `artes --reportWithTrace` |
161
+ | `--singleFileReport` | Generate single file Allure report | `artes -r --singleFileReport` |
162
+ | `--zip` | Zip the report folder after generation | `artes -r --zip` |
163
+ | `--logo` | Set a custom logo in the report sidebar | `artes --logo logo.png` |
164
+ | `--brandName` | Set the brand name displayed next to the logo | `artes --brandName 'My Company'` |
165
+ | `--reportName` | Report name on the summary widget | `artes --reportName 'Alma UI'` |
166
+ | `--uploadReport` | Upload the generated report to Artes Reporting System | `artes -r --zip --uploadReport --reporterURL "https://example.com"` |
167
+ | `--reporterURL` | URL of the Artes Reporting System | `artes --uploadReport --reporterURL "https://example.com"` |
168
+ | `--projectName` | Project name in the Artes Reporting System (default: `"Artes Report"`) | `artes --uploadReport --reporterURL "https://example.com" --projectName "My Project"` |
169
+ | `--projectType` | Project type for reporting, e.g., UI, API (default: `"Artes"`) | `artes --uploadReport --reporterURL "https://example.com" --projectType "API"` |
170
+ | `--reportPath` | Path to the report zip file to upload (default: `./report.zip`) | `artes --uploadReport --reporterURL "https://example.com" --reportPath "./my_report.zip"` |
171
+
172
+ ### Browser ( artes browser --help )
173
+
174
+ | Option | Description | Usage Example |
175
+ | --- | --- | --- |
176
+ | `--browser` | Specify browser to use (`chromium`, `firefox`, `webkit`) | `artes --browser chromium` |
177
+ | `--device` | Emulate a specific device (e.g., `"iPhone 13"`) | `artes --device "iPhone 13"` |
178
+ | `--maxScreen` | Maximize browser window on launch | `artes --maxScreen` |
179
+ | `--width` | Set browser width (default: `1280`) | `artes --width 1920` |
180
+ | `--height` | Set browser height (default: `720`) | `artes --height 1080` |
181
+
182
+ ### Execution ( artes execution --help )
183
+
184
+ | Option | Description | Usage Example |
185
+ | --- | --- | --- |
186
+ | `--headless` | Run browser in headless mode | `artes --headless` |
187
+ | `--baseURL` | Set base URL for the tests | `artes --baseURL "https://example.com"` |
188
+ | `--offline` | Run browser in offline mode | `artes --offline` |
189
+ | `--features` | Specify feature file paths to run (comma-separated) | `artes --features "tests/features/Alma,tests/features/Banan.feature"` |
190
+ | `--stepDef` | Specify step definition file paths to use (comma-separated) | `artes --stepDef "tests/steps/login.js,tests/steps/home.js"` |
191
+ | `--tags` | Run tests with specified Cucumber tags | `artes --tags "@smoke and not @wip"` |
192
+ | `--env` | Set the environment for the test run | `artes --env "dev"` |
193
+ | `--saveVar` | Set variables from CLI | `artes --saveVar '{"armud":20,"banana":200}'` |
194
+ | `--parallel` | Run tests in parallel mode | `artes --parallel 3` |
195
+ | `--retry` | Retry failed tests | `artes --retry 2` |
196
+ | `--rerun` | Rerun only failed tests from previous run | `artes --rerun @rerun.txt` |
197
+ | `--dryRun` | Perform a dry run without executing tests | `artes --dryRun` |
198
+ | `--percentage` | Set minimum success percentage to pass test run (default: `0`) | `artes --percentage 85` |
199
+ | `--timeout` | Set timeout for each test step in seconds (default: `30`) | `artes --timeout 10` |
200
+ | `--slowMo` | Slow down execution for clear view (default: `0`) | `artes --slowMo 1` |
201
+
202
+ ### AI Bug Reporter ( artes ai --help )
187
203
 
188
204
  | Option | Description | Usage Example |
189
205
  | --- | --- | --- |
190
- | 🤖 `--ai` | Enable AI-generated bug reports and test summaries | `artes --ai` |
191
- | 🧠 `--aiModel` | AI model to use for report generation | `artes --ai --aiModel "gemini 2.5 flash"` |
192
- | 🔑 `--aiKey` | API key for the selected AI provider | `artes --ai --aiKey "your-api-key"` |
193
- | 🔗 `--aiURL` | Local AI endpoint URL (e.g. Ollama, LM Studio). Overrides `--aiModel` and `--aiKey` when set | `artes --ai --aiURL "http://localhost:11434/api/chat"` |
194
- | 🌍 `--aiLanguage` | Language for AI-generated reports (default: `"English"`) | `artes --ai --aiLanguage "Azerbaijani"` |
195
- | 🔢 --maxTokens | Maximum tokens for AI response output (default: 4000) | artes --ai --maxTokens 8000 |
196
- | 📋 `--maxReports` | Maximum number of AI reports to generate per test run (default: `10`) | `artes --ai --maxReports 5` |
206
+ | `--ai` | Enable AI-generated bug reports and test summaries | `artes --ai` |
207
+ | `--aiModel` | AI model to use for report generation | `artes --ai --aiModel "gemini 2.5 flash"` |
208
+ | `--aiKey` | API key for the selected AI provider | `artes --ai --aiKey "your-api-key"` |
209
+ | `--aiURL` | Local AI endpoint URL (e.g., Ollama, LM Studio). Overrides `--aiModel` and `--aiKey` when set | `artes --ai --aiURL "http://localhost:11434/api/chat"` |
210
+ | `--aiLanguage` | Language for AI-generated reports (default: `"English"`) | `artes --ai --aiLanguage "Azerbaijani"` |
211
+ | `--maxTokens` | Maximum tokens for AI-generated reports (default: `4000`) | `artes --ai --maxTokens 8000` |
212
+ | `--maxReports` | Maximum number of AI reports to generate per test run (default: `10`) | `artes --ai --maxReports 5` |
197
213
 
198
214
 
199
215
  \*\* To just run the tests: <br>
package/executer.js CHANGED
@@ -3,24 +3,25 @@ const {
3
3
  showHelp,
4
4
  showAIHelp,
5
5
  showVersion,
6
+ showBrowserHelp,
7
+ showExecutionHelp,
8
+ showReportingHelp,
6
9
  createProject,
7
10
  runTests,
8
11
  generateReport,
9
12
  cleanUp,
10
13
  } = require("./src/helper/executers/exporter");
14
+
11
15
  const { logPomWarnings } = require("./src/helper/controller/pomCollector");
12
- const fs = require("fs");
13
- const path = require("path");
14
- const {
15
- testCoverageCalculator,
16
- } = require("./src/helper/controller/testCoverageCalculator");
16
+ const { testCoverageCalculator } = require("./src/helper/controller/testCoverageCalculator");
17
17
  const { getExecutor } = require("./src/helper/controller/getExecutor");
18
- const {
19
- findDuplicateTestNames,
20
- } = require("./src/helper/controller/findDuplicateTestNames");
18
+ const { findDuplicateTestNames } = require("./src/helper/controller/findDuplicateTestNames");
21
19
  const { getEnvInfo } = require("artes/src/helper/controller/getEnvInfo");
22
20
  const { uploadReport } = require("./src/helper/controller/reportUploader");
23
21
 
22
+ const fs = require("fs");
23
+ const path = require("path");
24
+
24
25
  const artesConfigPath = path.resolve(process.cwd(), "artes.config.js");
25
26
 
26
27
  let artesConfig = {};
@@ -31,256 +32,217 @@ if (fs.existsSync(artesConfigPath)) {
31
32
 
32
33
  const args = process.argv.slice(2);
33
34
 
35
+ const set = (key, value) => { if (value) process.env[key] = value; };
36
+
34
37
  const getArgValue = (flag) => {
35
38
  const index = args.indexOf(flag);
36
39
  return index >= 0 ? args[index + 1] : undefined;
37
40
  };
38
41
 
42
+
39
43
  const flags = {
40
- help: args.includes("-h") || args.includes("--help"),
44
+ // Main
45
+ help: args.includes("-h") || args.includes("--help"),
41
46
  version: args.includes("-v") || args.includes("--version"),
42
- create: args.includes("-c") || args.includes("--create"),
47
+ create: args.includes("-c") || args.includes("--create"),
43
48
  createYes: args.includes("-y") || args.includes("--yes"),
44
49
  noDeps: args.includes("--noDeps"),
45
- report: args.includes("-r") || args.includes("--report"),
46
- reportSuccess: args.includes("--reportSuccess"),
47
- trace: args.includes("-t") || args.includes("--trace"),
48
- reportWithTrace: args.includes("-rwt") || args.includes("--reportWithTrace"),
50
+
51
+ // Sub-command help pages
52
+ reportHelp: (args[0] === "report" && args.includes("--help")),
53
+ browserHelp: (args[0] === "browser" && args.includes("--help")),
54
+ executionHelp: (args[0] === "execution" && args.includes("--help")),
55
+ aiHelp: (args[0] === "ai" && args.includes("--help")),
56
+
57
+ // Reporting
58
+ report: args.includes("-r") || args.includes("--report"),
59
+ reportSuccess: args.includes("--reportSuccess"),
60
+ reportWithTrace: args.includes("-rwt") || args.includes("--reportWithTrace"),
61
+ trace: args.includes("--trace"),
49
62
  singleFileReport: args.includes("--singleFileReport"),
50
- customLogo: args.includes("--logo"),
51
- customBrandName: args.includes("--brandName"),
52
- customReportName: args.includes("--reportName"),
53
- zip: args.includes("--zip"),
54
- uploadReport: args.includes("--uploadReport"),
55
- reporterURL: args.includes("--reporterURL"),
56
- projectName: args.includes("--projectName"),
57
- projectType: args.includes("--projectType"),
58
- reportPath: args.includes("--reportPath"),
59
- aiHelp: args.includes("--aiHelp"),
60
- ai: args.includes("--ai"),
61
- aiURL: args.includes("--aiURL"),
62
- aiModel: args.includes("--aiModel"),
63
- aiKey: args.includes("--aiKey"),
64
- aiLanguage: args.includes("--aiLanguage"),
65
- maxTokens: args.includes("--maxTokens"),
66
- maxReports: args.includes("--maxReports"),
67
- features: args.includes("--features"),
68
- stepDef: args.includes("--stepDef"),
69
- tags: args.includes("--tags"),
70
- env: args.includes("--env"),
71
- saveVar: args.includes("--saveVar"),
72
- headless: args.includes("--headless"),
73
- parallel: args.includes("--parallel"),
74
- retry: args.includes("--retry"),
75
- rerun: args.includes("--rerun"),
76
- dryRun: args.includes("--dryRun"),
63
+ zip: args.includes("--zip"),
64
+ logo: args.includes("--logo"),
65
+ brandName: args.includes("--brandName"),
66
+ reportName: args.includes("--reportName"),
67
+ uploadReport: args.includes("--uploadReport"),
68
+ reporterURL: args.includes("--reporterURL"),
69
+ projectName: args.includes("--projectName"),
70
+ projectType: args.includes("--projectType"),
71
+ reportPath: args.includes("--reportPath"),
72
+
73
+ // Browser & Environment
74
+ browser: args.includes("--browser"),
75
+ device: args.includes("--device"),
76
+ maxScreen: args.includes("--maxScreen"),
77
+ width: args.includes("--width"),
78
+ height: args.includes("--height"),
79
+
80
+ // Execution
81
+ baseURL: args.includes("--baseURL"),
82
+ env: args.includes("--env"),
83
+ headless: args.includes("--headless"),
84
+ offline: args.includes("--offline"),
85
+ features: args.includes("--features"),
86
+ stepDef: args.includes("--stepDef"),
87
+ tags: args.includes("--tags"),
88
+ parallel: args.includes("--parallel"),
89
+ retry: args.includes("--retry"),
90
+ rerun: args.includes("--rerun"),
91
+ dryRun: args.includes("--dryRun"),
77
92
  percentage: args.includes("--percentage"),
78
- browser: args.includes("--browser"),
79
- offline: args.includes("--offline"),
80
- device: args.includes("--device"),
81
- baseURL: args.includes("--baseURL"),
82
- maximizeScreen: args.includes("--maxScreen"),
83
- width: args.includes("--width"),
84
- height: args.includes("--height"),
85
- timeout: args.includes("--timeout"),
86
- slowMo: args.includes("--slowMo"),
93
+ timeout: args.includes("--timeout"),
94
+ slowMo: args.includes("--slowMo"),
95
+ saveVar: args.includes("--saveVar"),
96
+
97
+ // AI
98
+ ai: args.includes("--ai"),
99
+ aiModel: args.includes("--aiModel"),
100
+ aiKey: args.includes("--aiKey"),
101
+ aiURL: args.includes("--aiURL"),
102
+ aiLanguage: args.includes("--aiLanguage"),
103
+ maxTokens: args.includes("--maxTokens"),
104
+ maxReports: args.includes("--maxReports"),
87
105
  };
88
106
 
89
- const env = getArgValue("--env");
90
- const vars = getArgValue("--saveVar");
91
- const reporterURL = getArgValue("--reporterURL");
92
- const projectType = getArgValue("--projectType");
93
- const projectName = getArgValue("--projectName");
94
- const reportPath = getArgValue("--reportPath");
95
- const logo = getArgValue("--logo");
96
- const brandName = getArgValue("--brandName");
97
- const reportName = getArgValue("--reportName");
98
- const ai = args.includes("--ai");
99
- const aiURL = getArgValue("--aiURL");
100
- const aiModel = getArgValue("--aiModel");
101
- const aiKey = getArgValue("--aiKey");
102
- const aiLanguage = getArgValue("--aiLanguage");
103
- const maxTokens = getArgValue("--maxTokens")
104
- const maxReports = getArgValue("--maxReports");
107
+ const shouldReport = flags.reportWithTrace || artesConfig.reportWithTrace || flags.report || artesConfig.report;
108
+
109
+ // Reporting & Branding
110
+ const logo = getArgValue("--logo");
111
+ const brandName = getArgValue("--brandName");
112
+ const reportName = getArgValue("--reportName");
113
+ const reporterURL = getArgValue("--reporterURL");
114
+ const projectName = getArgValue("--projectName");
115
+ const projectType = getArgValue("--projectType");
116
+ const reportPath = getArgValue("--reportPath");
117
+
118
+ // Browser & Environment
119
+ const browser = getArgValue("--browser");
120
+ const baseURL = getArgValue("--baseURL");
121
+ const device = getArgValue("--device");
122
+ const width = getArgValue("--width");
123
+ const height = getArgValue("--height");
124
+
125
+ // Execution
126
+ const env = getArgValue("--env");
105
127
  const featureFiles = getArgValue("--features");
106
128
  const features = flags.features && featureFiles;
107
- const stepDef = getArgValue("--stepDef");
108
- const tags = getArgValue("--tags");
109
- const parallel = getArgValue("--parallel");
110
- const retry = getArgValue("--retry");
111
- const rerun = getArgValue("--rerun");
112
- const percentage = getArgValue("--percentage");
113
- const browser = getArgValue("--browser");
114
- const device = getArgValue("--device");
115
- const baseURL = getArgValue("--baseURL");
116
- const width = getArgValue("--width");
117
- const height = getArgValue("--height");
118
- const timeout = getArgValue("--timeout");
119
- const slowMo = getArgValue("--slowMo");
120
-
121
- flags.env ? (process.env.ENV = env) : "";
122
-
123
- vars ? (process.env.VARS = vars) : "";
124
-
125
- flags.reportWithTrace ||
126
- artesConfig.reportWithTrace ||
127
- flags.report ||
128
- artesConfig.report
129
- ? (process.env.REPORT_FORMAT = JSON.stringify([
130
- "allure-cucumberjs/reporter:./allure-results",
131
- ]))
132
- : "";
133
-
134
- flags.customLogo ? (process.env.LOGO = logo) : "";
135
- flags.customBrandName ? (process.env.BRAND_NAME = brandName) : "";
136
- flags.customReportName ? (process.env.REPORT_NAME = reportName) : "";
137
-
138
- flags.reportSuccess ? (process.env.REPORT_SUCCESS = true) : "";
139
-
140
- flags.tags && console.log("Running tags:", tags);
141
- flags.tags ? (process.env.RUN_TAGS = JSON.stringify(tags)) : "";
142
-
143
- flags.features && console.log("Running features:", features);
144
- flags.features ? (process.env.FEATURES = features) : "";
145
-
146
- flags.stepDef && console.log("Running step definitions:", flags.stepDef);
147
- flags.stepDef ? (process.env.STEP_DEFINITIONS = stepDef) : "";
148
-
149
- flags.report ? (process.env.REPORT = true) : "";
150
-
151
- flags.trace ? (process.env.TRACE = true) : "";
152
-
153
- flags.reportWithTrace
154
- ? (process.env.REPORT_WITH_TRACE = true)
155
- : (process.env.REPORT_WITH_TRACE = false);
156
-
157
- flags.singleFileReport
158
- ? (process.env.SINGLE_FILE_REPORT = true)
159
- : (process.env.SINGLE_FILE_REPORT = false);
160
-
161
- flags.zip ? (process.env.ZIP = true) : (process.env.ZIP = false);
162
-
163
- flags.ai ? (process.env.AI = ai) : (process.env.AI = false);
164
- flags.aiURL ? (process.env.AI_URL = aiURL) : "";
165
- flags.aiModel ? (process.env.AI_MODEL = aiModel) : "";
166
- flags.aiKey ? (process.env.AI_KEY = aiKey) : "";
167
- flags.aiLanguage ? (process.env.AI_LANGUAGE = aiLanguage) : "";
168
- flags.maxTokens ? (process.env.MAX_TOKENS = maxTokens) : "";
169
- flags.maxReports ? (process.env.MAX_REPORTS = maxReports) : "";
170
-
171
- flags.headless &&
172
- console.log("Running mode:", flags.headless ? "headless" : "headed");
173
- flags.headless ? (process.env.MODE = JSON.stringify(true)) : false;
174
-
175
- flags.parallel ? (process.env.PARALLEL = parallel) : "";
176
-
177
- flags.retry ? (process.env.RETRY = retry) : "";
178
-
179
- flags.rerun ? (process.env.RERUN = rerun) : "";
180
-
181
- flags.dryRun ? (process.env.DRYRUN = flags.dryRun) : "";
182
-
183
- flags.percentage ? (process.env.PERCENTAGE = percentage) : "";
184
-
185
- flags.browser && console.log("Running browser:", browser);
186
- flags.browser ? (process.env.BROWSER = JSON.stringify(browser)) : "";
187
-
188
- flags.browser && console.log("Running mode:", flags.offline && "Offline");
189
- flags.offline ? (process.env.OFFLINE = true) : "";
190
-
191
- flags.device && console.log("Running device:", device);
192
- flags.device ? (process.env.DEVICE = JSON.stringify(device)) : "";
193
-
194
- flags.baseURL ? (process.env.BASE_URL = JSON.stringify(baseURL)) : "";
195
-
196
- flags.maximizeScreen
197
- ? (process.env.MAXIMIZE_SCREEN = flags.maximizeScreen)
198
- : "";
129
+ const stepDef = getArgValue("--stepDef");
130
+ const tags = getArgValue("--tags");
131
+ const parallel = getArgValue("--parallel");
132
+ const retry = getArgValue("--retry");
133
+ const rerun = getArgValue("--rerun");
134
+ const percentage = getArgValue("--percentage");
135
+ const timeout = getArgValue("--timeout");
136
+ const slowMo = getArgValue("--slowMo");
137
+ const vars = getArgValue("--saveVar");
138
+
139
+ // AI
140
+ const aiModel = getArgValue("--aiModel");
141
+ const aiKey = getArgValue("--aiKey");
142
+ const aiURL = getArgValue("--aiURL");
143
+ const aiLanguage = getArgValue("--aiLanguage");
144
+ const maxTokens = getArgValue("--maxTokens");
145
+ const maxReports = getArgValue("--maxReports");
199
146
 
200
- flags.width && console.log("Running width:", width);
201
- flags.width ? (process.env.WIDTH = width) : "";
202
147
 
203
- flags.height && console.log("Running height:", height);
204
- flags.height ? (process.env.HEIGHT = height) : "";
205
148
 
206
- flags.timeout ? (process.env.TIMEOUT = timeout) : "";
149
+ // Reporting & Branding
150
+ set("REPORT", flags.report);
151
+ set("REPORT_SUCCESS", flags.reportSuccess);
152
+ set("SINGLE_FILE_REPORT", flags.singleFileReport);
153
+ set("REPORT_WITH_TRACE", flags.reportWithTrace);
154
+ set("TRACE", flags.trace);
155
+ set("ZIP", flags.zip);
156
+ set("LOGO", logo);
157
+ set("BRAND_NAME", brandName);
158
+ set("REPORT_NAME", reportName);
159
+
160
+ if (shouldReport) { process.env.REPORT_FORMAT = JSON.stringify(["allure-cucumberjs/reporter:./allure-results"]) }
161
+
162
+ set("REPORTER_URL", reporterURL);
163
+ set("PROJECT_NAME", projectName);
164
+ set("PROJECT_TYPE", projectType);
165
+ set("REPORT_PATH", reportPath);
166
+
167
+ // Browser & Environment
168
+ set("BROWSER", browser);
169
+ set("BASE_URL", baseURL ? JSON.stringify(baseURL) : null);
170
+ set("DEVICE", device ? JSON.stringify(device) : null);
171
+ set("MODE", flags.headless ? JSON.stringify(true) : null);
172
+ set("OFFLINE", flags.offline);
173
+ set("MAXIMIZE_SCREEN", flags.maxScreen);
174
+ set("WIDTH", width);
175
+ set("HEIGHT", height);
176
+
177
+ // Execution
178
+ set("ENV", env);
179
+ set("VARS", vars);
180
+ set("FEATURES", features);
181
+ set("STEP_DEFINITIONS", stepDef);
182
+ set("RUN_TAGS", tags ? JSON.stringify(tags) : null);
183
+ set("PARALLEL", parallel);
184
+ set("RETRY", retry);
185
+ set("RERUN", rerun);
186
+ set("DRYRUN", flags.dryRun);
187
+ set("PERCENTAGE", percentage);
188
+ set("TIMEOUT", timeout);
189
+ set("SLOWMO", slowMo);
190
+
191
+ // AI
192
+ set("AI", flags.ai);
193
+ set("AI_URL", aiURL);
194
+ set("AI_MODEL", aiModel);
195
+ set("AI_KEY", aiKey);
196
+ set("AI_LANGUAGE", aiLanguage);
197
+ set("MAX_TOKENS", maxTokens);
198
+ set("MAX_REPORTS", maxReports);
207
199
 
208
- flags.slowMo ? (process.env.SLOWMO = slowMo) : "";
209
200
 
210
201
  async function main() {
202
+ if (flags.reportHelp) return showReportingHelp();
203
+ if (flags.browserHelp) return showBrowserHelp();
204
+ if (flags.executionHelp) return showExecutionHelp();
205
+ if (flags.aiHelp) return showAIHelp();
206
+
211
207
  if (flags.help) return showHelp();
212
- if (flags.aiHelp) return showAIHelp();
213
208
  if (flags.version) return showVersion();
214
209
  if (flags.create) return createProject(flags.createYes, flags.noDeps);
215
210
 
211
+
216
212
  runTests();
217
213
 
218
- const testCoverage = testCoverageCalculator();
214
+ const testPercentage = process.env.PERCENTAGE ? Number(process.env.PERCENTAGE) : artesConfig.testPercentage || 0;
215
+
216
+ const testCoverage = testCoverageCalculator({ percentage: testPercentage });
219
217
 
218
+ if (!testCoverage) {
219
+ cleanUp();
220
+ process.exit(1);
221
+ }
222
+
220
223
  if (testCoverage.totalTests === 0) {
221
- console.log("\x1b[33mNo tests were run (0 scenarios). Skipping report generation and upload.\x1b[0m");
222
224
  cleanUp();
223
225
  process.exit(process.env.EXIT_CODE);
224
226
  }
225
-
227
+
226
228
  logPomWarnings();
227
229
 
228
230
  findDuplicateTestNames();
229
231
 
230
- const testPercentage = process.env.PERCENTAGE
231
- ? Number(process.env.PERCENTAGE)
232
- : artesConfig.testPercentage || 0;
233
-
234
- if (testPercentage > 0) {
235
- const meetsThreshold = testCoverage.percentage >= testPercentage;
236
-
237
- if (meetsThreshold) {
238
- console.log(
239
- `\x1b[32mTests passed required ${testPercentage}% success rate with ${testCoverage.percentage.toFixed(2)}%!\x1b[0m`,
240
- );
241
- process.env.EXIT_CODE = parseInt(0, 10);
242
- } else {
243
- console.log(
244
- `\x1b[31mTests failed required ${testPercentage}% success rate with ${testCoverage.percentage.toFixed(2)}%!\x1b[0m`,
245
- );
246
- process.env.EXIT_CODE = parseInt(1, 10);
247
- }
248
- }
249
-
250
- const source = path.join(
251
- process.cwd(),
252
- "node_modules",
253
- "artes",
254
- "@rerun.txt",
255
- );
232
+ const source = path.join(process.cwd(), "node_modules", "artes", "@rerun.txt" );
256
233
  const destination = path.join(process.cwd(), "@rerun.txt");
234
+ if (fs.existsSync(source)) { fs.renameSync(source, destination)}
257
235
 
258
- if (fs.existsSync(source)) {
259
- fs.renameSync(source, destination);
260
- }
261
-
262
- if (
263
- flags.reportWithTrace ||
264
- artesConfig.reportWithTrace ||
265
- flags.report ||
266
- artesConfig.report
267
- ) {
236
+ if (shouldReport) {
268
237
  getExecutor();
269
238
  getEnvInfo();
270
239
  generateReport();
271
240
  }
272
241
 
273
-
274
- if (
275
- !(process.env.TRACE === "true"
276
- ? process.env.TRACE
277
- : artesConfig.trace || false)
278
- ) {
279
- fs.rmSync(path.join(process.cwd(), "traces"), {
280
- recursive: true,
281
- force: true,
282
- });
283
- }
242
+ const traceEnabled = process.env.TRACE === "true" || artesConfig.trace || false;
243
+ if (!traceEnabled) {
244
+ fs.rmSync(path.join(process.cwd(), "traces"), { recursive: true, force: true });
245
+ }
284
246
 
285
247
  try {
286
248
  if (flags.uploadReport || artesConfig.uploadReport) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "artes",
3
- "version": "1.7.3",
3
+ "version": "1.7.5",
4
4
  "description": "The simplest way to automate UI and API tests using Cucumber-style steps.",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -8,31 +8,30 @@ const { PNG } = require("pngjs");
8
8
  const { moduleConfig } = require("artes/src/helper/imports/commons");
9
9
 
10
10
  async function screenComparer(baselineFilename, screenshotFn, options = {}) {
11
- const { maxDiffPercent = 0.01, threshold = 0.1 } = options;
11
+ const { maxDiffPercent = 0.01, threshold = 0.1, comparePath } = options;
12
12
 
13
13
  const baselinePath = path.join(moduleConfig.projectPath, baselineFilename);
14
- const actualPath = path.join(
15
- moduleConfig.projectPath,
16
- "visualComparison",
17
- `actual_${baselineFilename}`,
18
- );
14
+
15
+ const actualPath = comparePath
16
+ ? path.join(moduleConfig.projectPath, comparePath)
17
+ : path.join(moduleConfig.projectPath, "visualComparison", `actual_${baselineFilename}`);
18
+
19
19
  const diffPath = path.join(
20
20
  moduleConfig.projectPath,
21
21
  "visualComparison",
22
22
  `diff_${baselineFilename}`,
23
23
  );
24
24
 
25
- await screenshotFn(actualPath);
26
-
27
- const baselineMeta = await sharp(baselinePath).metadata();
28
- const actualMeta = await sharp(actualPath).metadata();
25
+ const visualComparisonDir = path.join(moduleConfig.projectPath, "visualComparison");
26
+ if (!fs.existsSync(visualComparisonDir)) {
27
+ fs.mkdirSync(visualComparisonDir, { recursive: true });
28
+ }
29
29
 
30
- // if (baselineMeta.width !== actualMeta.width || baselineMeta.height !== actualMeta.height) {
31
- // console.warn(`⚠️ Dimension mismatch! Baseline: ${baselineMeta.width}x${baselineMeta.height} | Actual: ${actualMeta.width}x${actualMeta.height}`);
32
- // }
30
+ if (!comparePath) {
31
+ await screenshotFn(actualPath);
32
+ }
33
33
 
34
- const width = actualMeta.width;
35
- const height = actualMeta.height;
34
+ const { width, height } = await sharp(actualPath).metadata();
36
35
 
37
36
  const baselineBuffer = await sharp(baselinePath)
38
37
  .resize(width, height, { fit: "fill" })
@@ -59,44 +58,34 @@ async function screenComparer(baselineFilename, screenshotFn, options = {}) {
59
58
 
60
59
  fs.writeFileSync(diffPath, PNG.sync.write(diffImg));
61
60
 
62
- const totalPixels = width * height;
61
+ const totalPixels = width * height;
63
62
  const mismatchRatio = mismatchedPixels / totalPixels;
64
63
 
65
- const expectedBase64 = (
66
- await sharp(baselinePath)
67
- .resize(width, height, { fit: "fill" })
68
- .png()
69
- .toBuffer()
70
- ).toString("base64");
71
- const actualBase64 = (await sharp(actualPath).png().toBuffer()).toString(
72
- "base64",
73
- );
74
- const diffBase64 = (await sharp(diffPath).png().toBuffer()).toString(
75
- "base64",
76
- );
64
+ const expectedBase64 = (await sharp(baselinePath).resize(width, height, { fit: "fill" }).png().toBuffer()).toString("base64");
65
+ const actualBase64 = (await sharp(actualPath).png().toBuffer()).toString("base64");
66
+ const diffBase64 = (await sharp(diffPath).png().toBuffer()).toString("base64");
77
67
 
78
68
  const content = JSON.stringify({
79
69
  expected: `data:image/png;base64,${expectedBase64}`,
80
- actual: `data:image/png;base64,${actualBase64}`,
81
- diff: `data:image/png;base64,${diffBase64}`,
70
+ actual: `data:image/png;base64,${actualBase64}`,
71
+ diff: `data:image/png;base64,${diffBase64}`,
82
72
  });
83
73
 
84
74
  await allure.attachment(
85
75
  "Screenshot diff details",
86
- ` Mismatched pixels: ${mismatchedPixels} / ${totalPixels} (${(mismatchRatio * 100).toFixed(2)}%) Max allowed: ${maxDiffPercent * 100}%`,
76
+ `Mismatched pixels: ${mismatchedPixels} / ${totalPixels} (${(mismatchRatio * 100).toFixed(2)}%) Max allowed: ${maxDiffPercent * 100}%`,
87
77
  "text/plain",
88
78
  );
79
+
89
80
  await allure.attachment(
90
81
  "Screenshot diff",
91
82
  content,
92
83
  "application/vnd.allure.image.diff",
93
84
  );
94
85
 
95
- if (fs.existsSync(path.join(moduleConfig.projectPath, "visualComparison")))
96
- fs.rmSync(path.join(moduleConfig.projectPath, "visualComparison"), {
97
- recursive: true,
98
- force: true,
99
- });
86
+ if (fs.existsSync(visualComparisonDir)) {
87
+ fs.rmSync(visualComparisonDir, { recursive: true, force: true });
88
+ }
100
89
 
101
90
  if (mismatchRatio > maxDiffPercent) {
102
91
  throw new Error(
@@ -105,4 +94,4 @@ async function screenComparer(baselineFilename, screenshotFn, options = {}) {
105
94
  }
106
95
  }
107
96
 
108
- module.exports = { screenComparer };
97
+ module.exports = { screenComparer };
@@ -1,7 +1,7 @@
1
1
  const fs = require("fs");
2
2
  const path = require("path");
3
3
 
4
- function testCoverageCalculator({ silent = false } = {}) {
4
+ function testCoverageCalculator({ silent = false, percentage = 0 } = {}) {
5
5
  const testStatusFile = path.join(
6
6
  process.cwd(),
7
7
  "node_modules",
@@ -67,6 +67,22 @@ function testCoverageCalculator({ silent = false } = {}) {
67
67
  }
68
68
  });
69
69
 
70
+ const result = {
71
+ percentage: ((total - notPassed) / total) * 100,
72
+ totalTests: total,
73
+ notPassed,
74
+ passed: total - notPassed,
75
+ latestStatuses: Object.fromEntries(
76
+ Object.entries(map).map(([id, data]) => [id, data.latest.status]),
77
+ ),
78
+ };
79
+
80
+ if (!silent && result.totalTests === 0) {
81
+ console.log("\x1b[33mNo tests were run (0 scenarios).\x1b[0m");
82
+ process.env.EXIT_CODE = 1;
83
+ return result;
84
+ }
85
+
70
86
  if (!silent && retriedTests.length > 0) {
71
87
  console.warn(`\n\x1b[33mRetried ${retriedTests.length} test cases:`);
72
88
  retriedTests.forEach((t) => {
@@ -76,15 +92,20 @@ function testCoverageCalculator({ silent = false } = {}) {
76
92
  console.log("");
77
93
  }
78
94
 
79
- return {
80
- percentage: ((total - notPassed) / total) * 100,
81
- totalTests: total,
82
- notPassed,
83
- passed: total - notPassed,
84
- latestStatuses: Object.fromEntries(
85
- Object.entries(map).map(([id, data]) => [id, data.latest.status]),
86
- ),
87
- };
95
+ if (!silent && percentage > 0) {
96
+ const meetsThreshold = result.percentage >= percentage;
97
+
98
+ if (meetsThreshold) {
99
+ console.log(`\x1b[32mTests passed required ${percentage}% success rate with ${result.percentage.toFixed(2)}%!\x1b[0m`);
100
+ process.env.EXIT_CODE = 0;
101
+ } else {
102
+ console.log(`\x1b[31mTests failed required ${percentage}% success rate with ${result.percentage.toFixed(2)}%!\x1b[0m`);
103
+ process.env.EXIT_CODE = 1;
104
+ }
105
+ }
106
+
107
+
108
+ return result
88
109
  }
89
110
 
90
111
  module.exports = { testCoverageCalculator };
@@ -1,4 +1,4 @@
1
- const { showHelp, showAIHelp } = require("./helper");
1
+ const { showHelp, showBrowserHelp, showExecutionHelp, showReportingHelp, showAIHelp } = require("./helper");
2
2
  const { createProject } = require("./projectCreator");
3
3
  const { generateReport } = require("./reportGenerator");
4
4
  const { runTests } = require("./testRunner");
@@ -10,6 +10,9 @@ module.exports = {
10
10
  generateReport,
11
11
  runTests,
12
12
  showHelp,
13
+ showBrowserHelp,
14
+ showExecutionHelp,
15
+ showReportingHelp,
13
16
  showAIHelp,
14
17
  showVersion,
15
18
  cleanUp,
@@ -1,168 +1,194 @@
1
1
  function showHelp() {
2
- console.log(`
3
- 🚀 Artes - Playwright Test Runner
4
-
5
- Description:
6
- Artes is a test runner for Playwright that executes Cucumber tests
7
- and can generate Allure reports.
8
-
9
- Usage:
2
+ console.log(`
3
+ Artes CLI
4
+
5
+ Usage:
10
6
  npx artes [options]
11
-
7
+
12
8
  Options:
13
- 🆘 -h, --help Show this help message
14
- Usage: artes -h or artes --help
15
-
16
- 🏷️ -v, --version Show current version of artes
17
- Usage: artes -v or artes --version
18
-
19
- 🏗️ -c, --create Create example project with artes
20
- Usage: artes -c or artes --create
21
-
22
- -y, --yes Skip confirmation prompt for creating example project
23
- Usage: artes -c -y or artes --create --yes
24
-
25
- 🚫 --noDeps Skip installing dependencies when creating example project
26
- Usage: artes -c --noDeps or artes --create --noDeps
27
-
28
- 📊 -r, --report Run tests and generate Allure report
29
- Usage: artes -r or artes --report
30
-
31
- ✅ --reportSuccess Generate screenshot and video record with also successful tests
32
- Usage: artes --reportSuccess
33
-
34
- ⚡ --trace Enable tracing for all tests
35
- Usage: artes --trace
36
-
37
- 🔍 -rwt, --reportWithTrace Include trace in the report
38
- Usage: artes --reportWithTrace
39
-
40
- 📄 --singleFileReport Generate single file Allure report
41
- Usage: artes -r --singleFileReport
42
-
43
- 🗜️ --zip Zip the report folder after generation
44
- Usage: artes -r --zip
45
-
46
- --uploadReport Upload the generated report to a Artes Reporting System
47
- Usage: artes --uploadReport --reporterURL "https://example.com/upload"
48
-
49
- --reporterURL URL of the Artes Reporting System to upload the report
50
- Usage: artes --uploadReport --reporterURL "https://example.com/upload"
51
-
52
- --projectName Name of the project in the Artes Reporting System (default: "Artes Report")
53
- Usage: artes --uploadReport --reporterURL "https://example.com/upload" --projectName "My Project"
54
-
55
- --projectType Type of the project (e.g., UI, API) for reporting purposes (default: "Artes")
56
- Usage: artes --uploadReport --reporterURL "https://example.com/upload" --projectType "API"
57
-
58
- --reportPath Path to the report zip or html file to be uploaded (default: ./report.zip)
59
- Usage: artes --uploadReport --reporterURL "https://example.com/upload" --reportPath "./my_report.zip"
60
-
61
- 🖼️ --logo Set a custom logo in the report sidebar
62
- Usage: artes --logo logo.png
63
-
64
- 🏢 --brandName Set the brand name displayed next to the logo in the report sidebar
65
- Usage: artes --brandName 'My Company'
66
-
67
- 📄 --reportName Report name displayed on the summary widget and in the Artes Reporting System
68
- Usage: artes --reportName 'Alma UI'
69
-
70
- 📁 --features Specify one or more feature files' relative paths to run (comma-separated)
71
- Usage: artes --features "tests/features/Alma, tests/features/Banan.feature"
72
-
73
- 📜 --stepDef Specify one or more step definition files' relative paths to use (comma-separated)
74
- Usage: artes --stepDef "tests/steps/login.js, tests/steps/home.js"
75
-
76
- 🔖 --tags Run tests with specified Cucumber tags
77
- Usage: artes --tags "@smoke and not @wip"
78
-
79
- 🌐 --env Set environment for the test run
80
- Usage: artes --env "dev"
81
-
82
- --saveVar Set variables from cli
83
- artes --saveVar '{"armud":20,"banana":200}'
84
-
85
- 🕶️ --headless Run browser in headless mode
86
- Usage: artes --headless
87
-
88
- ⚡ --parallel Run tests in parallel mode
89
- Usage: artes --parallel 3
90
-
91
- 🔁 --retry Retry failed tests
92
- Usage: artes --retry 2
93
-
94
- 🔄 --rerun Rerun only the failed tests from previous run
95
- Usage: artes --rerun @rerun.txt
96
-
97
- 🎭 --dryRun Perform a dry run without executing tests
98
- Usage: artes --dryRun
99
-
100
- 📈 --percentage Set minimum success percentage to pass test run
101
- Usage: artes --percentage 85
102
-
103
- 🌐 --browser Specify browser to use (chromium, firefox, webkit)
104
- Usage: artes --browser chromium
105
-
106
- --offline Run browser in offline mode
107
- Usage: artes --offline
108
-
109
- 📱 --device Emulate specific device (e.g., "iPhone 13")
110
- Usage: artes --device "iPhone 13"
111
-
112
- 🌐 --baseURL Set base URL for the tests
113
- Usage: artes --baseURL "https://example.com"
114
-
115
- 📏 --maxScreen Maximize browser window
116
- Usage: artes --maxScreen
117
-
118
- 📐 --width Set browser width (default: 1280)
119
- Usage: artes --width 1920
120
-
121
- 📏 --height Set browser height (default: 720)
122
- Usage: artes --height 1080
123
-
124
- ⏱️ --timeout Set timeout for each test step (default: 30 seconds)
125
- Usage: artes --timeout 10
126
-
127
- 🐢 --slowMo Slow down text execution for clear view (default: 0 seconds)
128
- Usage: artes --slowMo 1
129
- `);
130
- }
131
-
132
-
133
- function showAIHelp() {
134
- console.log(`
135
- 🚀 Artes AI Bug reporter
136
-
137
- Usage:
9
+ -h, --help Show this help message
10
+ -v, --version Show current version of artes
11
+ -c, --create Create example artes project
12
+ -y, --yes Skip confirmation prompt when creating a project
13
+ --noDeps Create project without installing dependencies
14
+
15
+ For more options, use:
16
+ artes report --help Reporting & branding options
17
+ artes browser --help Browser & environment options
18
+ artes execution --help Execution control options
19
+ artes ai --help AI bug reporter options
20
+ `);
21
+ }
22
+
23
+ function showReportingHelp() {
24
+ console.log(`
25
+ Artes CLI - Reporting & Branding
26
+
27
+ Usage:
138
28
  npx artes [options]
139
-
29
+
30
+ Options:
31
+ -r, --report Run tests and generate Allure report
32
+ Usage: artes -r or artes --report
33
+
34
+ --reportSuccess Generate screenshot and video with successful tests too
35
+ Usage: artes --reportSuccess
36
+
37
+ -rwt, --reportWithTrace Include trace in the report
38
+ Usage: artes --reportWithTrace
39
+
40
+ --trace Enable tracing for all tests
41
+ Usage: artes --trace
42
+
43
+ --singleFileReport Generate single file Allure report
44
+ Usage: artes -r --singleFileReport
45
+
46
+ --zip Zip the report folder after generation
47
+ Usage: artes -r --zip
48
+
49
+ --logo Set a custom logo in the report sidebar
50
+ Usage: artes --logo logo.png
51
+
52
+ --brandName Set the brand name displayed next to the logo
53
+ Usage: artes --brandName 'My Company'
54
+
55
+ --reportName Report name on the summary widget
56
+ Usage: artes --reportName 'Alma UI'
57
+
58
+ --uploadReport Upload the generated report to Artes Reporting System
59
+ Usage: artes --uploadReport --reporterURL "https://example.com/upload"
60
+
61
+ --reporterURL URL of the Artes Reporting System
62
+ Usage: artes --uploadReport --reporterURL "https://example.com/upload"
63
+
64
+ --projectName Project name in the Artes Reporting System (default: "Artes Report")
65
+ Usage: artes --uploadReport --reporterURL "https://example.com/upload" --projectName "My Project"
66
+
67
+ --projectType Project type for reporting, e.g., UI, API (default: "Artes")
68
+ Usage: artes --uploadReport --reporterURL "https://example.com/upload" --projectType "API"
69
+
70
+ --reportPath Path to the report zip or html file to upload (default: ./report.zip)
71
+ Usage: artes --uploadReport --reporterURL "https://example.com/upload" --reportPath "./my_report.zip"
72
+ `);
73
+ }
74
+
75
+ function showBrowserHelp() {
76
+ console.log(`
77
+ Artes CLI - Browser & Environment
78
+
79
+ Usage:
80
+ npx artes [options]
81
+
82
+ Options:
83
+ --browser Specify browser to use (chromium, firefox, webkit)
84
+ Usage: artes --browser chromium
85
+
86
+ --device Emulate a specific device (e.g., "iPhone 13")
87
+ Usage: artes --device "iPhone 13"
88
+
89
+ --maxScreen Maximize browser window
90
+ Usage: artes --maxScreen
91
+
92
+ --width Set browser width (default: 1280)
93
+ Usage: artes --width 1920
94
+
95
+ --height Set browser height (default: 720)
96
+ Usage: artes --height 1080
97
+ `);
98
+ }
99
+
100
+ function showExecutionHelp() {
101
+ console.log(`
102
+ Artes CLI - Execution
103
+
104
+ Usage:
105
+ npx artes [options]
106
+
140
107
  Options:
141
108
 
142
- 🤖 --ai Enable AI-generated bug reports and test summaries
143
- Usage: artes --ai
144
-
145
- 🧠 --aiModel AI model to use for report generation
146
- Supported: "gpt-4o", "gemini 2.5 flash", "claude sonnet", "mistral large"
147
- Usage: artes --ai --aiModel "gemini 2.5 flash"
148
-
149
- 🔑 --aiKey API key for the selected AI provider
150
- Usage: artes --ai --aiKey "your-api-key"
151
-
152
- 🔗 --aiURL Local AI endpoint URL (e.g., Ollama, LM Studio). Overrides --aiModel and --aiKey when set
153
- Usage: artes --ai --aiURL "http://localhost:11434/api/chat"
154
-
155
- 🌍 --aiLanguage Language for AI-generated reports (default: "English")
156
- Usage: artes --ai --aiLanguage "Azerbaijani"
157
-
158
- 🔢 --maxTokens Maximum tokens for AI-generated reports (default: 4000)
159
- Usage: artes --ai --maxTokens 8000
160
-
161
- 📋 --maxReports Maximum number of AI reports to generate per test run (default: 10)
162
- Usage: artes --ai --maxReports 5
163
- `);
164
- }
165
-
166
- module.exports = {
167
- showHelp, showAIHelp
168
- };
109
+ --headless Run browser in headless mode
110
+ Usage: artes --headless
111
+
112
+ --baseURL Set base URL for the tests
113
+ Usage: artes --baseURL "https://example.com"
114
+
115
+ --env Set environment for the test run
116
+ Usage: artes --env "dev"
117
+
118
+ --offline Run browser in offline mode
119
+ Usage: artes --offline
120
+
121
+ --features Specify feature file paths to run (comma-separated)
122
+ Usage: artes --features "tests/features/Alma, tests/features/Banan.feature"
123
+
124
+ --stepDef Specify step definition file paths to use (comma-separated)
125
+ Usage: artes --stepDef "tests/steps/login.js, tests/steps/home.js"
126
+
127
+ --tags Run tests with specified Cucumber tags
128
+ Usage: artes --tags "@smoke and not @wip"
129
+
130
+ --parallel Run tests in parallel mode
131
+ Usage: artes --parallel 3
132
+
133
+ --retry Retry failed tests
134
+ Usage: artes --retry 2
135
+
136
+ --rerun Rerun only failed tests from previous run
137
+ Usage: artes --rerun @rerun.txt
138
+
139
+ --dryRun Perform a dry run without executing tests
140
+ Usage: artes --dryRun
141
+
142
+ --percentage Set minimum success percentage to pass test run
143
+ Usage: artes --percentage 85
144
+
145
+ --timeout Set timeout for each test step (default: 30 seconds)
146
+ Usage: artes --timeout 10
147
+
148
+ --slowMo Slow down execution for clear view (default: 0)
149
+ Usage: artes --slowMo 1
150
+
151
+ --saveVar Set variables from CLI
152
+ Usage: artes --saveVar '{"armud":20,"banana":200}'
153
+ `);
154
+ }
155
+
156
+ function showAIHelp() {
157
+ console.log(`
158
+ Artes CLI - AI Bug Reporter
159
+
160
+ Usage:
161
+ npx artes [options]
162
+
163
+ Options:
164
+ --ai Enable AI-generated bug reports and test summaries
165
+ Usage: artes --ai
166
+
167
+ --aiModel AI model to use for report generation.
168
+ (For supported AI models: https://github.com/4gayev1/Artes/blob/main/docs/aiProviders.md)
169
+ Usage: artes --ai --aiModel "gemini 2.5 flash"
170
+
171
+ --aiKey API key for the selected AI provider
172
+ Usage: artes --ai --aiKey "your-api-key"
173
+
174
+ --aiURL Local AI endpoint URL (e.g., Ollama, LM Studio). Overrides --aiModel and --aiKey when set
175
+ Usage: artes --ai --aiURL "http://localhost:11434/api/chat"
176
+
177
+ --aiLanguage Language for AI-generated reports (default: "English")
178
+ Usage: artes --ai --aiLanguage "Azerbaijani"
179
+
180
+ --maxTokens Maximum tokens for AI-generated reports (default: 4000)
181
+ Usage: artes --ai --maxTokens 8000
182
+
183
+ --maxReports Maximum number of AI reports to generate per test run (default: 10)
184
+ Usage: artes --ai --maxReports 5
185
+ `);
186
+ }
187
+
188
+ module.exports = {
189
+ showHelp,
190
+ showReportingHelp,
191
+ showBrowserHelp,
192
+ showExecutionHelp,
193
+ showAIHelp
194
+ };
@@ -9,7 +9,7 @@ const {
9
9
  } = require("../helper/imports/commons");
10
10
  const {
11
11
  screenComparer,
12
- } = require("artes/src/helper/controller/screenComparer");
12
+ } = require("../helper/controller/screenComparer");
13
13
  const { assert, frame } = require("../helper/stepFunctions/exporter");
14
14
  const Ajv = require("ajv");
15
15
 
@@ -399,6 +399,29 @@ Then(
399
399
  },
400
400
  );
401
401
 
402
+
403
+ Then(
404
+ "User expects that {string} screenshot match with {string} screenshot",
405
+ async function (ss1, ss2) {
406
+ await screenComparer(
407
+ ss1,
408
+ null,
409
+ { maxDiffPercent: 0.01, comparePath: ss2 },
410
+ );
411
+ },
412
+ );
413
+
414
+ Then(
415
+ "User expects that {string} screenshot match with {string} screenshot with {float}% difference",
416
+ async function (ss1, ss2, maxDiff) {
417
+ await screenComparer(
418
+ ss1,
419
+ null,
420
+ { maxDiffPercent: maxDiff / 100, comparePath: ss2 },
421
+ );
422
+ },
423
+ );
424
+
402
425
  // Check if a selector should have specific text
403
426
  Then(
404
427
  "User expects {string} should match {string} text",