froth-webdriverio-framework 7.0.119-dev1.1 ā 7.0.119-dev1.10
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 +245 -0
- package/allure-report-utils/allure-helper.js +226 -0
- package/allure-report-utils/froth-report.js +142 -0
- package/allure-report-utils/generate-allure-report.js +167 -0
- package/allure-report-utils/open-allure-report.js +97 -0
- package/allure-screenshots/Recorded_Scripts_Recorded_test_steps_success.png +0 -0
- package/allure-screenshots/Recorded_Scripts_Recorded_test_steps_success_2026-06-19T08-07-53-694Z.png +0 -0
- package/allure-screenshots/Recorded_Scripts_Recorded_test_steps_success_2026-06-19T08-10-50-605Z.png +0 -0
- package/allure-screenshots/action_001_setWindowSize_2026-06-19T08-10-35-850Z.png +0 -0
- package/allure-screenshots/action_001_url.png +0 -0
- package/allure-screenshots/action_002_click.png +0 -0
- package/allure-screenshots/action_002_url_2026-06-19T08-10-37-002Z.png +0 -0
- package/allure-screenshots/action_003_clearValue.png +0 -0
- package/allure-screenshots/action_003_setValue.png +0 -0
- package/allure-screenshots/action_003_waitForExist_2026-06-19T08-10-42-230Z.png +0 -0
- package/allure-screenshots/action_004_click.png +0 -0
- package/allure-screenshots/action_004_waitForExist_2026-06-19T08-10-42-353Z.png +0 -0
- package/allure-screenshots/action_005_clearValue.png +0 -0
- package/allure-screenshots/action_005_click_2026-06-19T08-10-43-186Z.png +0 -0
- package/allure-screenshots/action_005_setValue.png +0 -0
- package/allure-screenshots/action_006_click_2026-06-19T08-10-43-301Z.png +0 -0
- package/allure-screenshots/action_007_clearValue_2026-06-19T08-10-43-974Z.png +0 -0
- package/allure-screenshots/action_008_clearValue_2026-06-19T08-10-44-058Z.png +0 -0
- package/allure-screenshots/action_009_addValue_2026-06-19T08-10-44-559Z.png +0 -0
- package/allure-screenshots/action_010_addValue_2026-06-19T08-10-44-656Z.png +0 -0
- package/allure-screenshots/action_011_setValue_2026-06-19T08-10-44-779Z.png +0 -0
- package/allure-screenshots/action_012_setValue_2026-06-19T08-10-44-905Z.png +0 -0
- package/allure-screenshots/action_013_click_2026-06-19T08-10-45-787Z.png +0 -0
- package/allure-screenshots/action_014_click_2026-06-19T08-10-45-892Z.png +0 -0
- package/allure-screenshots/action_015_clearValue_2026-06-19T08-10-46-549Z.png +0 -0
- package/allure-screenshots/action_016_clearValue_2026-06-19T08-10-46-635Z.png +0 -0
- package/allure-screenshots/action_017_addValue_2026-06-19T08-10-46-868Z.png +0 -0
- package/allure-screenshots/action_018_addValue_2026-06-19T08-10-46-997Z.png +0 -0
- package/allure-screenshots/action_019_setValue_2026-06-19T08-10-47-080Z.png +0 -0
- package/allure-screenshots/action_020_setValue_2026-06-19T08-10-47-163Z.png +0 -0
- package/allure-screenshots/action_021_click_2026-06-19T08-10-47-377Z.png +0 -0
- package/allure-screenshots/action_022_click_2026-06-19T08-10-47-472Z.png +0 -0
- package/froth_configs/base.config.js +47 -3
- package/froth_configs/commonhook.js +53 -0
- package/froth_configs/local/mobile.config.js +57 -9
- package/froth_configs/local/web.config.js +139 -33
- package/froth_configs/screenshot-service.js +157 -0
- package/froth_configs/wdio.common.conf.js +112 -1
- package/package.json +62 -50
package/README.md
ADDED
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
# README.md
|
|
2
|
+
|
|
3
|
+
## Project Overview
|
|
4
|
+
|
|
5
|
+
**Version:** 9.0.5-ytlc
|
|
6
|
+
|
|
7
|
+
**Repository:** https://github.com/RoboticoDigitalProjects/froth-webdriverio.git
|
|
8
|
+
|
|
9
|
+
This is a WebdriverIO test automation framework (FROTH - "froth-webdriverio-framework") that supports web, Android, and iOS testing on both BrowserStack and local environments. The framework integrates with a Froth TestOps backend API for execution tracking, reporting, and test data management.
|
|
10
|
+
|
|
11
|
+
## Commands
|
|
12
|
+
|
|
13
|
+
### Running Tests
|
|
14
|
+
|
|
15
|
+
Tests are run using the WebdriverIO CLI. The framework uses `wdio.common.conf.js` directly without requiring platform-specific config files.
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# Lint code
|
|
19
|
+
npm run lint
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### Viewing Test Results
|
|
23
|
+
|
|
24
|
+
#### Local Execution Reports (Automatic)
|
|
25
|
+
|
|
26
|
+
When running tests with `PLATFORM=local`, the framework **automatically generates Mochawesome HTML reports** after test execution completes:
|
|
27
|
+
|
|
28
|
+
- Reports are saved in: `./reports/mochawesome/`
|
|
29
|
+
- Each execution gets a **unique report directory** using `BROWSERSTACK_BUILD_NAME` and timestamp
|
|
30
|
+
- Format: `./reports/mochawesome/{BUILD_NAME}-{YYYY-MM-DD}/mochawesome.html`
|
|
31
|
+
- Reports **auto-open in browser** after generation
|
|
32
|
+
|
|
33
|
+
**Example:**
|
|
34
|
+
```bash
|
|
35
|
+
# Run tests with unique build name
|
|
36
|
+
BROWSERSTACK_BUILD_NAME="Web_Login_Test_20250619" \
|
|
37
|
+
PLATFORM=local \
|
|
38
|
+
YML_NAME="./ymls/browserstack/web/TOASTER_CHECK.yml" \
|
|
39
|
+
SUITE="./web_suites/Login_RD.js" \
|
|
40
|
+
npx wdio ./froth_configs/wdio.common.conf.js
|
|
41
|
+
|
|
42
|
+
# ā
Report generates automatically after execution completes!
|
|
43
|
+
# š Location: ./reports/mochawesome/Web_Login_Test_20250619-2025-06-19/mochawesome.html
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**Manual report generation (if needed):**
|
|
47
|
+
```bash
|
|
48
|
+
# Generate latest report manually
|
|
49
|
+
npm run generate:report
|
|
50
|
+
|
|
51
|
+
# Generate all available reports
|
|
52
|
+
npm run generate:report:all
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
#### BrowserStack Execution Reports
|
|
56
|
+
|
|
57
|
+
For BrowserStack execution, test results are tracked via the Froth TestOps API. The framework automatically:
|
|
58
|
+
- Updates execution status for each test script
|
|
59
|
+
- Calculates total execution time
|
|
60
|
+
- Posts results back to TestOps via `updateScriptExecutionStatus` and `updateExecuitonDetails`
|
|
61
|
+
- Tracks BrowserStack session information
|
|
62
|
+
|
|
63
|
+
View detailed results and execution logs in your Froth TestOps dashboard using the `EXECUTION_ID`.
|
|
64
|
+
|
|
65
|
+
### Running Tests
|
|
66
|
+
|
|
67
|
+
Tests are run by specifying environment variables and the config file:
|
|
68
|
+
|
|
69
|
+
**Local execution (using BrowserStack from local machine):**
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
EXECUTION_ID=12995 \
|
|
73
|
+
ORGANISATION_DOMAIN_URL='https://api.frothtestops.com' \
|
|
74
|
+
BROWSERSTACK_BUILD_NAME="Web_Build- api-module-testing_2345_20260619" \
|
|
75
|
+
PLATFORM=local \
|
|
76
|
+
YML_NAME="./ymls/browserstack/web/TOASTER_CHECK.yml" \
|
|
77
|
+
SUITE="./web_suites/Login_RD.js" \
|
|
78
|
+
API_TOKEN="" \
|
|
79
|
+
CICD_RUN_ID=1 \
|
|
80
|
+
npx wdio ./froth_configs/wdio.common.conf.js
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
**BrowserStack execution:**
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
SUITE=./android_suites/samplesuite_x.js \
|
|
87
|
+
YML_NAME=./ymls/browserstack/android/android_pixel8.yml \
|
|
88
|
+
PLATFORM=browserstack \
|
|
89
|
+
EXECUTION_ID=123 \
|
|
90
|
+
API_TOKEN=your_token \
|
|
91
|
+
ORGANISATION_DOMAIN_URL=https://api.frothtestops.com \
|
|
92
|
+
npx wdio ./froth_configs/wdio.common.conf.js
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Architecture
|
|
96
|
+
|
|
97
|
+
### Configuration Hierarchy
|
|
98
|
+
|
|
99
|
+
The framework uses a multi-layered configuration system:
|
|
100
|
+
|
|
101
|
+
1. __Base Configuration__ (`froth_configs/base.config.js`): Contains framework settings, specs path, timeouts, and Mocha options. Initializes a global `BUFFER` using `node-localstorage` for cross-module state sharing.
|
|
102
|
+
2. __Common Configuration__ (`froth_configs/wdio.common.conf.js`): Acts as the entry point. It:
|
|
103
|
+
|
|
104
|
+
- Loads capabilities from a YAML file specified by `YML_NAME`
|
|
105
|
+
- Decodes BrowserStack credentials from base64
|
|
106
|
+
- Determines platform (web vs mobile) based on `platformName` in capabilities
|
|
107
|
+
- Merges base config with platform-specific config
|
|
108
|
+
|
|
109
|
+
3. __Platform-Specific Configs__ (`froth_configs/browserstack/` and `froth_configs/local/`):
|
|
110
|
+
|
|
111
|
+
- `web.config.js`: BrowserStack web testing configuration
|
|
112
|
+
- `mobile.config.js`: BrowserStack mobile (Android/iOS) testing configuration
|
|
113
|
+
- Supports `BS_UPLOAD_MEDIA` for injecting media files into tests
|
|
114
|
+
|
|
115
|
+
### Test Lifecycle and Hooks
|
|
116
|
+
|
|
117
|
+
All test lifecycle hooks are defined in `froth_configs/commonhook.js`:
|
|
118
|
+
|
|
119
|
+
- **onPrepare**: Initializes environment variables, execution details, suite details, and test data via `setallDatailinBuffer.js`. Registers global error handlers.
|
|
120
|
+
- **beforeSession**: Validates test syntax, configures BrowserStack capabilities, sets app path for mobile testing
|
|
121
|
+
- **beforeSuite**: Fetches BrowserStack session details, updates CICD run ID
|
|
122
|
+
- **beforeTest/afterTest**: Updates individual script execution status via API
|
|
123
|
+
- **afterSession**: Calculates total execution time, updates final execution status
|
|
124
|
+
- **onComplete**: Clears the BUFFER storage
|
|
125
|
+
|
|
126
|
+
### Directory Structure
|
|
127
|
+
|
|
128
|
+
```ini
|
|
129
|
+
froth_common_actions/ # Reusable test utilities and actions
|
|
130
|
+
āāā Utils.js # Central export point for all utilities
|
|
131
|
+
āāā scroll.js # Scrolling helpers (scrollToEnd, scrollDownToView, etc.)
|
|
132
|
+
āāā swipe.js # Gesture helpers (swipeUp, swipeDown, swipeWithCoordinates)
|
|
133
|
+
āāā click.js # Click helpers (clickIfVisible, doubleClick)
|
|
134
|
+
āāā assert.js # Assertion helpers (assertText, assertAttributeValue)
|
|
135
|
+
āāā random.js # Random data generators (RANDOMTEXT, RNDNUMBER, etc.)
|
|
136
|
+
āāā storeToBuffer.js # Buffer storage helpers for runtime data
|
|
137
|
+
āāā dbValidator.js # Database field validation
|
|
138
|
+
āāā ... # Other common actions
|
|
139
|
+
|
|
140
|
+
froth_api_calls/ # API integration layer
|
|
141
|
+
āāā loginapi.js # Authentication token retrieval
|
|
142
|
+
āāā getexecutionDetails.js # Fetch/update execution details via TestOps API
|
|
143
|
+
āāā getsuiteDetails.js # Fetch test suite and script mappings
|
|
144
|
+
āāā readTestdata.js # Fetch test data by ID
|
|
145
|
+
āāā browsersatckSessionInfo.js # BrowserStack session management
|
|
146
|
+
|
|
147
|
+
froth_configs/ # Configuration files
|
|
148
|
+
āāā base.config.js
|
|
149
|
+
āāā wdio.common.conf.js
|
|
150
|
+
āāā commonhook.js
|
|
151
|
+
āāā setallDatailinBuffer.js
|
|
152
|
+
āāā browserstack/ # BrowserStack-specific configs
|
|
153
|
+
āāā local/ # Local execution configs
|
|
154
|
+
|
|
155
|
+
android/ # Android test scripts
|
|
156
|
+
android_suites/ # Android suite definitions (array of test files)
|
|
157
|
+
web/ # Web test scripts
|
|
158
|
+
web_suites/ # Web suite definitions
|
|
159
|
+
ymls/browserstack/ # Capability YAML files for different devices/browsers
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Test Data Flow
|
|
163
|
+
|
|
164
|
+
1. Environment variables are loaded in `setallDatailinBuffer.js` during `onPrepare`
|
|
165
|
+
2. Global state is stored in `BUFFER` (node-localstorage at `./buffer_storage`)
|
|
166
|
+
3. Execution details are fetched from the Froth TestOps API
|
|
167
|
+
4. Test scripts access data via `BUFFER.getItem()` / `BUFFER.setItem()`
|
|
168
|
+
5. Results are posted back to the API via `updateScriptExecutionStatus` and `updateExecuitonDetails`
|
|
169
|
+
|
|
170
|
+
### Test Suite Pattern
|
|
171
|
+
|
|
172
|
+
Suites are defined as simple modules exporting a `tests` array:
|
|
173
|
+
|
|
174
|
+
```javascript
|
|
175
|
+
// Example: android_suites/samplesuite_x.js
|
|
176
|
+
module.exports = {
|
|
177
|
+
tests: [
|
|
178
|
+
'/absolute/path/to/android/test_script.js'
|
|
179
|
+
]
|
|
180
|
+
};
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Common Actions Usage
|
|
184
|
+
|
|
185
|
+
Tests import utilities from the Utils export:
|
|
186
|
+
|
|
187
|
+
```javascript
|
|
188
|
+
const Util = require('../froth_common_actions/Utils');
|
|
189
|
+
|
|
190
|
+
// Scrolling
|
|
191
|
+
await Util.scrollToEnd(2, 3);
|
|
192
|
+
await Util.scrollDownToView("Some Text");
|
|
193
|
+
|
|
194
|
+
// Swiping
|
|
195
|
+
await Util.swipeWithCoordinates(x1, y1, x2, y2);
|
|
196
|
+
|
|
197
|
+
// Random data
|
|
198
|
+
const randomText = Util.randomtext(10);
|
|
199
|
+
const randomNumber = Util.randomnumber(100, 999);
|
|
200
|
+
|
|
201
|
+
// Buffer storage
|
|
202
|
+
Util.storetext('key', 'value');
|
|
203
|
+
const value = BUFFER.getItem('key');
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## Required Environment Variables
|
|
207
|
+
|
|
208
|
+
| Variable | Description | Example |
|
|
209
|
+
|----------|-------------|---------|
|
|
210
|
+
| `YML_NAME` | Path to capability YAML file | `./ymls/browserstack/android/android_pixel8.yml` |
|
|
211
|
+
| `SUITE` | Path to suite file | `./android_suites/samplesuite_x.js` |
|
|
212
|
+
| `PLATFORM` | `local` for local execution, `browserstack` or `browserstacklocal` for BrowserStack | `local` or `browserstack` |
|
|
213
|
+
| `EXECUTION_ID` | Test execution ID from TestOps | `12995` |
|
|
214
|
+
| `API_TOKEN` | Authentication token for TestOps API | `eyJhbG...` |
|
|
215
|
+
| `ORGANISATION_DOMAIN_URL` | Froth TestOps API base URL | `https://api.frothtestops.com` |
|
|
216
|
+
| `CICD_RUN_ID` | CI/CD pipeline run ID (optional) | `1` |
|
|
217
|
+
| `BROWSERSTACK_BUILD_NAME` | Build name for BrowserStack session tracking | `Web_Build- api-module-testing_2345_20260619` |
|
|
218
|
+
| `BS_UPLOAD_MEDIA` | Comma-separated media URLs for BrowserStack (optional) | `url1,url2` |
|
|
219
|
+
|
|
220
|
+
## Capability YAML Format
|
|
221
|
+
|
|
222
|
+
YAML files define device/browser capabilities. Example for Android:
|
|
223
|
+
|
|
224
|
+
```yaml
|
|
225
|
+
userName: "bs_username"
|
|
226
|
+
accessKey: "base64_encoded_key"
|
|
227
|
+
platformName: "Android"
|
|
228
|
+
deviceName: "Samsung Galaxy S22 Ultra"
|
|
229
|
+
platformVersion: "12.0"
|
|
230
|
+
debug: true
|
|
231
|
+
networkLogs: true
|
|
232
|
+
interactiveDebugging: false
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
## Important Notes
|
|
236
|
+
|
|
237
|
+
- The framework uses `node-localstorage` to create a global `BUFFER` accessible across all modules
|
|
238
|
+
- All API responses from TestOps are AES-decrypted via `aesEncryptionDecryption.js`
|
|
239
|
+
- Test scripts map to TestOps via filename (script name must match `scriptName` in suite details)
|
|
240
|
+
- Mobile tests use Appium selectors like `id:com.example:id/elementId` and `-android uiautomator:...`
|
|
241
|
+
- Web tests use standard WebdriverIO selectors (`$`, `$$`)
|
|
242
|
+
- Framework supports both BrowserStack App Automate (mobile) and Automate (web) sessions
|
|
243
|
+
- **PLATFORM variable:**
|
|
244
|
+
- Use `PLATFORM=local` when executing tests from your local machine (even when targeting BrowserStack devices)
|
|
245
|
+
- Use `PLATFORM=browserstack` or `PLATFORM=browserstacklocal` when running from BrowserStack infrastructure
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Allure Helper Utility for WebDriverIO
|
|
6
|
+
* Provides methods to add steps, screenshots, and attachments to Allure reports
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
class AllureHelper {
|
|
10
|
+
/**
|
|
11
|
+
* Add a step to the Allure report
|
|
12
|
+
* @param {string} name - Step name
|
|
13
|
+
* @param {Function} stepFn - Step function to execute
|
|
14
|
+
*/
|
|
15
|
+
static async step(name, stepFn) {
|
|
16
|
+
const allure = require('@wdio/allure-reporter').default;
|
|
17
|
+
|
|
18
|
+
console.log(`š Step: ${name}`);
|
|
19
|
+
|
|
20
|
+
// Create a step in Allure
|
|
21
|
+
allure.startStep(name);
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
// Execute the step function
|
|
25
|
+
await stepFn();
|
|
26
|
+
allure.endStep('passed');
|
|
27
|
+
} catch (error) {
|
|
28
|
+
allure.endStep('failed');
|
|
29
|
+
throw error;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Add a description step
|
|
35
|
+
* @param {string} text - Description text
|
|
36
|
+
*/
|
|
37
|
+
static description(text) {
|
|
38
|
+
const allure = require('@wdio/allure-reporter').default;
|
|
39
|
+
console.log(`š ${text}`);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Capture and attach screenshot to Allure report
|
|
44
|
+
* @param {string} screenshotName - Name for the screenshot
|
|
45
|
+
*/
|
|
46
|
+
static async captureScreenshot(screenshotName = 'screenshot') {
|
|
47
|
+
try {
|
|
48
|
+
// Ensure screenshot directory exists
|
|
49
|
+
const screenshotDir = './allure-screenshots';
|
|
50
|
+
if (!fs.existsSync(screenshotDir)) {
|
|
51
|
+
fs.mkdirSync(screenshotDir, { recursive: true });
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Take screenshot and save to file
|
|
55
|
+
const screenshotPath = path.join(screenshotDir, `${screenshotName}.png`);
|
|
56
|
+
await browser.saveScreenshot(screenshotPath);
|
|
57
|
+
|
|
58
|
+
// Read the screenshot
|
|
59
|
+
if (fs.existsSync(screenshotPath)) {
|
|
60
|
+
const imageBuffer = fs.readFileSync(screenshotPath);
|
|
61
|
+
|
|
62
|
+
// Attach to Allure using the proper method
|
|
63
|
+
const allure = require('@wdio/allure-reporter').default;
|
|
64
|
+
allure.addAttachment(screenshotName, imageBuffer, 'image/png');
|
|
65
|
+
|
|
66
|
+
console.log(`šø Screenshot captured: ${screenshotName}`);
|
|
67
|
+
} else {
|
|
68
|
+
console.warn(`ā ļø Screenshot file not found: ${screenshotPath}`);
|
|
69
|
+
}
|
|
70
|
+
} catch (error) {
|
|
71
|
+
console.error(`ā Error capturing screenshot: ${error.message}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Add text attachment to Allure report
|
|
77
|
+
* @param {string} name - Attachment name
|
|
78
|
+
* @param {string} text - Text content
|
|
79
|
+
* @param {string} mimeType - MIME type (default: text/plain)
|
|
80
|
+
*/
|
|
81
|
+
static addAttachment(name, text, mimeType = 'text/plain') {
|
|
82
|
+
const allure = require('@wdio/allure-reporter').default;
|
|
83
|
+
allure.addAttachment(name, text, mimeType);
|
|
84
|
+
console.log(`š Attachment added: ${name}`);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Add severity level to test
|
|
89
|
+
* @param {string} level - Severity level (blocker, critical, normal, minor, trivial)
|
|
90
|
+
*/
|
|
91
|
+
static severity(level = 'normal') {
|
|
92
|
+
const allure = require('@wdio/allure-reporter').default;
|
|
93
|
+
allure.addArgument('severity', level);
|
|
94
|
+
console.log(`š Severity: ${level}`);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Add epic label
|
|
99
|
+
* @param {string} epic - Epic name
|
|
100
|
+
*/
|
|
101
|
+
static epic(epic) {
|
|
102
|
+
const allure = require('@wdio/allure-reporter').default;
|
|
103
|
+
allure.addArgument('epic', epic);
|
|
104
|
+
console.log(`š Epic: ${epic}`);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Add feature label
|
|
109
|
+
* @param {string} feature - Feature name
|
|
110
|
+
*/
|
|
111
|
+
static feature(feature) {
|
|
112
|
+
const allure = require('@wdio/allure-reporter').default;
|
|
113
|
+
allure.addArgument('feature', feature);
|
|
114
|
+
console.log(`ā Feature: ${feature}`);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Add story label
|
|
119
|
+
* @param {string} story - Story name
|
|
120
|
+
*/
|
|
121
|
+
static story(story) {
|
|
122
|
+
const allure = require('@wdio/allure-reporter').default;
|
|
123
|
+
allure.addArgument('story', story);
|
|
124
|
+
console.log(`š Story: ${story}`);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Add test ID/TC tag
|
|
129
|
+
* @param {string} testId - Test ID
|
|
130
|
+
*/
|
|
131
|
+
static testId(testId) {
|
|
132
|
+
const allure = require('@wdio/allure-reporter').default;
|
|
133
|
+
allure.addArgument('testId', testId);
|
|
134
|
+
console.log(`š·ļø Test ID: ${testId}`);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Capture screenshot on test failure
|
|
139
|
+
*/
|
|
140
|
+
static async captureOnFailure() {
|
|
141
|
+
const allure = require('@wdio/allure-reporter').default;
|
|
142
|
+
|
|
143
|
+
try {
|
|
144
|
+
const testName = expect.getState().currentTestName || 'test';
|
|
145
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
146
|
+
const screenshotName = `${testName}-failure-${timestamp}`;
|
|
147
|
+
|
|
148
|
+
await this.captureScreenshot(screenshotName);
|
|
149
|
+
} catch (error) {
|
|
150
|
+
console.error(`ā Error capturing failure screenshot: ${error.message}`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Add environment information to report
|
|
156
|
+
* @param {object} envInfo - Environment information object
|
|
157
|
+
*/
|
|
158
|
+
static addEnvironment(envInfo) {
|
|
159
|
+
const allure = require('@wdio/allure-reporter').default;
|
|
160
|
+
|
|
161
|
+
Object.entries(envInfo).forEach(([key, value]) => {
|
|
162
|
+
allure.addArgument(`env:${key}`, value);
|
|
163
|
+
console.log(`š Environment: ${key} = ${value}`);
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Log text as a step
|
|
169
|
+
* @param {string} message - Log message
|
|
170
|
+
*/
|
|
171
|
+
static log(message) {
|
|
172
|
+
const allure = require('@wdio/allure-reporter').default;
|
|
173
|
+
allure.addStep(message);
|
|
174
|
+
console.log(`š ${message}`);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Take a screenshot and attach it as an attachment (simpler method)
|
|
179
|
+
* @param {string} name - Attachment name
|
|
180
|
+
*/
|
|
181
|
+
static async attachScreenshot(name = 'screenshot') {
|
|
182
|
+
try {
|
|
183
|
+
// Take screenshot to buffer
|
|
184
|
+
const screenshot = await browser.takeScreenshot();
|
|
185
|
+
|
|
186
|
+
// Attach directly to Allure
|
|
187
|
+
const allure = require('@wdio/allure-reporter').default;
|
|
188
|
+
const buffer = Buffer.from(screenshot, 'base64');
|
|
189
|
+
allure.addAttachment(name, buffer, 'image/png');
|
|
190
|
+
|
|
191
|
+
console.log(`šø Screenshot attached: ${name}`);
|
|
192
|
+
} catch (error) {
|
|
193
|
+
console.error(`ā Error attaching screenshot: ${error.message}`);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Add screenshot attachment with detailed logging
|
|
199
|
+
* @param {string} stepName - Name of the current step
|
|
200
|
+
* @param {string} description - Description of what the screenshot shows
|
|
201
|
+
*/
|
|
202
|
+
static async screenshot(stepName, description = 'Screenshot') {
|
|
203
|
+
try {
|
|
204
|
+
const allure = require('@wdio/allure-reporter').default;
|
|
205
|
+
|
|
206
|
+
// Start step if not already in one
|
|
207
|
+
allure.startStep(description);
|
|
208
|
+
|
|
209
|
+
// Take screenshot
|
|
210
|
+
const screenshot = await browser.takeScreenshot();
|
|
211
|
+
const buffer = Buffer.from(screenshot, 'base64');
|
|
212
|
+
|
|
213
|
+
// Attach screenshot to the step
|
|
214
|
+
allure.addAttachment(description, buffer, 'image/png');
|
|
215
|
+
|
|
216
|
+
// End the step
|
|
217
|
+
allure.endStep('passed');
|
|
218
|
+
|
|
219
|
+
console.log(`šø Screenshot attached for step: ${stepName}`);
|
|
220
|
+
} catch (error) {
|
|
221
|
+
console.error(`ā Error with screenshot: ${error.message}`);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
module.exports = AllureHelper;
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Froth Allure Report CLI
|
|
5
|
+
* Usage:
|
|
6
|
+
* npx froth-report open - Open the latest Allure report in browser
|
|
7
|
+
* npx froth-report generate - Generate Allure HTML report from results
|
|
8
|
+
* npx froth-report - Shows help
|
|
9
|
+
*
|
|
10
|
+
* Works from any project folder that has the framework installed.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const fs = require('fs');
|
|
14
|
+
const path = require('path');
|
|
15
|
+
const { execSync } = require('child_process');
|
|
16
|
+
|
|
17
|
+
// Commands
|
|
18
|
+
const command = process.argv[2];
|
|
19
|
+
|
|
20
|
+
function showHelp() {
|
|
21
|
+
console.log(`
|
|
22
|
+
šÆ Froth Allure Report CLI
|
|
23
|
+
============================
|
|
24
|
+
|
|
25
|
+
Usage:
|
|
26
|
+
npx froth-report open Open the latest Allure report in browser (http://localhost:8080)
|
|
27
|
+
npx froth-report generate Generate Allure HTML report from test results
|
|
28
|
+
npx froth-report help Show this help message
|
|
29
|
+
|
|
30
|
+
Examples:
|
|
31
|
+
npx froth-report open
|
|
32
|
+
npx froth-report generate
|
|
33
|
+
|
|
34
|
+
The report must be in: ./reports/allure/ (relative to current folder)
|
|
35
|
+
`);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function findLatestReport() {
|
|
39
|
+
const REPORTS_DIR = './reports/allure';
|
|
40
|
+
if (!fs.existsSync(REPORTS_DIR)) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const directories = fs.readdirSync(REPORTS_DIR)
|
|
45
|
+
.map(file => path.join(REPORTS_DIR, file))
|
|
46
|
+
.filter(file => fs.statSync(file).isDirectory())
|
|
47
|
+
.filter(file => {
|
|
48
|
+
// Check if any subdirectory ending with _report exists
|
|
49
|
+
try {
|
|
50
|
+
const subdirs = fs.readdirSync(file)
|
|
51
|
+
.map(sub => path.join(file, sub))
|
|
52
|
+
.filter(sub => {
|
|
53
|
+
const stat = fs.statSync(sub);
|
|
54
|
+
return stat.isDirectory() && path.basename(sub).endsWith('_report');
|
|
55
|
+
});
|
|
56
|
+
return subdirs.length > 0;
|
|
57
|
+
} catch (e) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
})
|
|
61
|
+
.sort((a, b) => fs.statSync(b).mtimeMs - fs.statSync(a).mtimeMs);
|
|
62
|
+
|
|
63
|
+
return directories.length > 0 ? directories[0] : null;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function openReport() {
|
|
67
|
+
const reportDir = findLatestReport();
|
|
68
|
+
|
|
69
|
+
if (!reportDir) {
|
|
70
|
+
console.log('ā No Allure HTML reports found.');
|
|
71
|
+
console.log('š” Run tests first. Reports are generated in: ./reports/allure/');
|
|
72
|
+
console.log('š” Or generate manually: npx froth-report generate');
|
|
73
|
+
process.exit(1);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Find the report folder ending with _report
|
|
77
|
+
const reportSubdirs = fs.readdirSync(reportDir)
|
|
78
|
+
.map(sub => path.join(reportDir, sub))
|
|
79
|
+
.filter(sub => {
|
|
80
|
+
const stat = fs.statSync(sub);
|
|
81
|
+
return stat.isDirectory() && path.basename(sub).endsWith('_report');
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
if (reportSubdirs.length === 0) {
|
|
85
|
+
console.log('ā No HTML report found in:', reportDir);
|
|
86
|
+
console.log('š” Generate it first: npx froth-report generate');
|
|
87
|
+
process.exit(1);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const htmlReportPath = reportSubdirs[0];
|
|
91
|
+
const indexPath = path.join(htmlReportPath, 'index.html');
|
|
92
|
+
|
|
93
|
+
console.log('šÆ Opening Allure Report');
|
|
94
|
+
console.log('========================\n');
|
|
95
|
+
console.log(`š Report location: ${htmlReportPath}`);
|
|
96
|
+
console.log(`š·ļø Build: ${path.basename(reportDir)}\n`);
|
|
97
|
+
console.log('š Opening report in browser on http://localhost:8080');
|
|
98
|
+
console.log('š” Press Ctrl+C to stop the server\n');
|
|
99
|
+
|
|
100
|
+
try {
|
|
101
|
+
execSync(`npx allure open ${htmlReportPath} --port 8080`, { stdio: 'inherit' });
|
|
102
|
+
} catch (error) {
|
|
103
|
+
console.error(`ā Error opening report: ${error.message}`);
|
|
104
|
+
console.log(`\nš” To view manually, open: file://${path.resolve(indexPath)}`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function generateReport() {
|
|
109
|
+
// Run the generate-allure-report.js script
|
|
110
|
+
const scriptPath = path.resolve(__dirname, 'generate-allure-report.js');
|
|
111
|
+
|
|
112
|
+
if (!fs.existsSync(scriptPath)) {
|
|
113
|
+
console.log('ā Report generator script not found:', scriptPath);
|
|
114
|
+
process.exit(1);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
try {
|
|
118
|
+
execSync(`node "${scriptPath}"`, { stdio: 'inherit' });
|
|
119
|
+
} catch (error) {
|
|
120
|
+
console.error(`ā Error generating report: ${error.message}`);
|
|
121
|
+
process.exit(1);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Main
|
|
126
|
+
switch (command) {
|
|
127
|
+
case 'open':
|
|
128
|
+
openReport();
|
|
129
|
+
break;
|
|
130
|
+
case 'generate':
|
|
131
|
+
generateReport();
|
|
132
|
+
break;
|
|
133
|
+
case 'help':
|
|
134
|
+
case '--help':
|
|
135
|
+
case '-h':
|
|
136
|
+
showHelp();
|
|
137
|
+
break;
|
|
138
|
+
default:
|
|
139
|
+
console.log('\nšÆ Froth Allure Report CLI\n');
|
|
140
|
+
showHelp();
|
|
141
|
+
break;
|
|
142
|
+
}
|