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
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const { execSync } = require('child_process');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Generate Allure HTML report automatically after test execution
|
|
7
|
+
* Uses BROWSERSTACK_BUILD_NAME environment variable for report naming
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const REPORTS_DIR = './reports/allure';
|
|
11
|
+
const OUTPUT_DIR = './allure-report';
|
|
12
|
+
|
|
13
|
+
function findLatestReportDir() {
|
|
14
|
+
if (!fs.existsSync(REPORTS_DIR)) {
|
|
15
|
+
console.log('โ No Allure reports directory found.');
|
|
16
|
+
console.log('๐ก Reports are generated in: ./reports/allure/');
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const directories = fs.readdirSync(REPORTS_DIR)
|
|
21
|
+
.map(file => path.join(REPORTS_DIR, file))
|
|
22
|
+
.filter(file => {
|
|
23
|
+
const stat = fs.statSync(file);
|
|
24
|
+
return stat.isDirectory();
|
|
25
|
+
})
|
|
26
|
+
.sort((a, b) => {
|
|
27
|
+
// Sort by modification time, newest first
|
|
28
|
+
return fs.statSync(b).mtimeMs - fs.statSync(a).mtimeMs;
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
return directories.length > 0 ? directories[0] : null;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function generateAllureReport(reportDir) {
|
|
35
|
+
try {
|
|
36
|
+
console.log('๐ฏ Allure Report Generator');
|
|
37
|
+
console.log('================================\n');
|
|
38
|
+
console.log(`๐ Using results from: ${reportDir}`);
|
|
39
|
+
console.log(`๐ท๏ธ Build Name: ${process.env.BROWSERSTACK_BUILD_NAME || 'local-build'}\n`);
|
|
40
|
+
|
|
41
|
+
// Get directory name and extract build name (remove timestamp)
|
|
42
|
+
const dirName = path.basename(reportDir);
|
|
43
|
+
const timestampIndex = dirName.lastIndexOf('-');
|
|
44
|
+
const buildName = timestampIndex > 0 ? dirName.substring(0, timestampIndex) : dirName;
|
|
45
|
+
|
|
46
|
+
// Generate HTML report folder named after build name
|
|
47
|
+
const reportFolderName = buildName + '_report';
|
|
48
|
+
const outputDir = path.join(reportDir, reportFolderName);
|
|
49
|
+
|
|
50
|
+
// Clean existing report directory if it exists
|
|
51
|
+
if (fs.existsSync(outputDir)) {
|
|
52
|
+
console.log('๐งน Cleaning existing report directory...');
|
|
53
|
+
fs.rmSync(outputDir, { recursive: true, force: true });
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Generate Allure HTML report
|
|
57
|
+
console.log('๐ Generating Allure HTML report...');
|
|
58
|
+
console.log(`๐ Report folder: ${reportFolderName}\n`);
|
|
59
|
+
const historyPath = path.join(reportDir, 'history');
|
|
60
|
+
|
|
61
|
+
let command = `npx allure generate ${reportDir} -o ${outputDir} --clean`;
|
|
62
|
+
|
|
63
|
+
// Add history if available
|
|
64
|
+
if (fs.existsSync(historyPath)) {
|
|
65
|
+
command = `npx allure generate ${reportDir} -o ${outputDir} --clean --history ${historyPath}`;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
execSync(command, { stdio: 'inherit' });
|
|
69
|
+
|
|
70
|
+
// Create a simple server start script in the report folder
|
|
71
|
+
const startScriptPath = path.join(outputDir, 'start-server.sh');
|
|
72
|
+
const startScriptContent = `#!/bin/bash
|
|
73
|
+
echo "๐ Starting Allure Report Server..."
|
|
74
|
+
echo "๐ Report: ${outputDir}"
|
|
75
|
+
echo "๐ Open: http://localhost:8080"
|
|
76
|
+
echo ""
|
|
77
|
+
echo "Press Ctrl+C to stop the server"
|
|
78
|
+
echo ""
|
|
79
|
+
npx allure open "${outputDir}" --port 8080
|
|
80
|
+
`;
|
|
81
|
+
fs.writeFileSync(startScriptPath, startScriptContent, { mode: 0o755 });
|
|
82
|
+
|
|
83
|
+
// Create a Windows batch file
|
|
84
|
+
const batchScriptPath = path.join(outputDir, 'start-server.bat');
|
|
85
|
+
const batchScriptContent = `@echo off
|
|
86
|
+
echo ๐ Starting Allure Report Server...
|
|
87
|
+
echo ๐ Report: ${outputDir}
|
|
88
|
+
echo ๐ Open: http://localhost:8080
|
|
89
|
+
echo.
|
|
90
|
+
echo Press Ctrl+C to stop the server
|
|
91
|
+
echo.
|
|
92
|
+
npx allure open "${outputDir}" --port 8080
|
|
93
|
+
`;
|
|
94
|
+
fs.writeFileSync(batchScriptPath, batchScriptContent);
|
|
95
|
+
|
|
96
|
+
// Create a README
|
|
97
|
+
const readmePath = path.join(outputDir, 'README.md');
|
|
98
|
+
const readmeContent = `# Allure Test Report
|
|
99
|
+
|
|
100
|
+
## ๐ How to View This Report
|
|
101
|
+
|
|
102
|
+
### Option 1: Double-click the start script (Easiest)
|
|
103
|
+
- **Mac/Linux:** Double-click \`start-server.sh\`
|
|
104
|
+
- **Windows:** Double-click \`start-server.bat\`
|
|
105
|
+
- Report will open at: http://localhost:8080
|
|
106
|
+
|
|
107
|
+
### Option 2: Use npm script
|
|
108
|
+
From the project root, run:
|
|
109
|
+
\`\`\`bash
|
|
110
|
+
npm run report:open
|
|
111
|
+
\`\`\`
|
|
112
|
+
|
|
113
|
+
### Option 3: Manual command
|
|
114
|
+
\`\`\`bash
|
|
115
|
+
npx allure open "${outputDir}" --port 8080
|
|
116
|
+
\`\`\`
|
|
117
|
+
|
|
118
|
+
## โ Why can't I just open index.html?
|
|
119
|
+
|
|
120
|
+
Allure reports use JavaScript to dynamically load test data from JSON files.
|
|
121
|
+
When you open index.html directly (file:// protocol), browsers block this for security reasons (CORS).
|
|
122
|
+
|
|
123
|
+
You need a web server to view the report properly - that's what the start scripts do!
|
|
124
|
+
|
|
125
|
+
## ๐ Test Results
|
|
126
|
+
|
|
127
|
+
- **Build Name:** ${process.env.BROWSERSTACK_BUILD_NAME || 'local-build'}
|
|
128
|
+
- **Generated:** ${new Date().toISOString()}
|
|
129
|
+
- **Report Location:** ${outputDir}
|
|
130
|
+
`;
|
|
131
|
+
|
|
132
|
+
fs.writeFileSync(readmePath, readmeContent);
|
|
133
|
+
|
|
134
|
+
console.log('\nโ
Allure report generated successfully!');
|
|
135
|
+
console.log(`๐ Location: ${path.resolve(outputDir)}`);
|
|
136
|
+
console.log(`๐ Results directory: ${path.resolve(reportDir)}`);
|
|
137
|
+
console.log('\n๐ To view the report:');
|
|
138
|
+
console.log(' 1. Run: npx froth-report open');
|
|
139
|
+
console.log(' 2. Or double-click: start-server.sh (Mac/Linux) / start-server.bat (Windows)');
|
|
140
|
+
console.log(' 3. Report opens at: http://localhost:8080');
|
|
141
|
+
console.log('\n๐ก Press Ctrl+C to stop the server when done viewing.');
|
|
142
|
+
|
|
143
|
+
return true;
|
|
144
|
+
} catch (error) {
|
|
145
|
+
console.error(`โ Error generating report: ${error.message}`);
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function main() {
|
|
151
|
+
const reportDir = findLatestReportDir();
|
|
152
|
+
|
|
153
|
+
if (!reportDir) {
|
|
154
|
+
console.log('โ No Allure results found. Please run tests first.');
|
|
155
|
+
console.log('๐ก Results are saved in: ./reports/allure/');
|
|
156
|
+
process.exit(1);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
generateAllureReport(reportDir);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Run the script
|
|
163
|
+
if (require.main === module) {
|
|
164
|
+
main();
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
module.exports = { generateAllureReport, findLatestReportDir };
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const { execSync } = require('child_process');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Find and open the latest Allure HTML report
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const REPORTS_DIR = './reports/allure';
|
|
10
|
+
|
|
11
|
+
function findLatestReport() {
|
|
12
|
+
if (!fs.existsSync(REPORTS_DIR)) {
|
|
13
|
+
console.log('โ No Allure reports directory found.');
|
|
14
|
+
console.log('๐ก Reports are generated in: ./reports/allure/');
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const directories = fs.readdirSync(REPORTS_DIR)
|
|
19
|
+
.map(file => path.join(REPORTS_DIR, file))
|
|
20
|
+
.filter(file => fs.statSync(file).isDirectory())
|
|
21
|
+
.filter(file => {
|
|
22
|
+
// Check if any subdirectory ending with _report exists
|
|
23
|
+
const subdirs = fs.readdirSync(file)
|
|
24
|
+
.map(sub => path.join(file, sub))
|
|
25
|
+
.filter(sub => {
|
|
26
|
+
const stat = fs.statSync(sub);
|
|
27
|
+
return stat.isDirectory() && path.basename(sub).endsWith('_report');
|
|
28
|
+
});
|
|
29
|
+
return subdirs.length > 0;
|
|
30
|
+
})
|
|
31
|
+
.sort((a, b) => {
|
|
32
|
+
return fs.statSync(b).mtimeMs - fs.statSync(a).mtimeMs;
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
return directories.length > 0 ? directories[0] : null;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function openReport(reportDir) {
|
|
39
|
+
// Find the report folder ending with _report
|
|
40
|
+
const reportSubdirs = fs.readdirSync(reportDir)
|
|
41
|
+
.map(sub => path.join(reportDir, sub))
|
|
42
|
+
.filter(sub => {
|
|
43
|
+
const stat = fs.statSync(sub);
|
|
44
|
+
return stat.isDirectory() && path.basename(sub).endsWith('_report');
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
if (reportSubdirs.length === 0) {
|
|
48
|
+
console.log('โ No HTML report found in:', reportDir);
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const htmlReportPath = reportSubdirs[0];
|
|
53
|
+
const indexPath = path.join(htmlReportPath, 'index.html');
|
|
54
|
+
|
|
55
|
+
if (!fs.existsSync(indexPath)) {
|
|
56
|
+
console.log('โ No index.html found at:', indexPath);
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
try {
|
|
61
|
+
console.log('๐ฏ Opening Allure Report');
|
|
62
|
+
console.log('========================\n');
|
|
63
|
+
console.log(`๐ Report location: ${htmlReportPath}`);
|
|
64
|
+
console.log(`๐ท๏ธ Build: ${path.basename(reportDir)}\n`);
|
|
65
|
+
|
|
66
|
+
// Use Allure CLI to open the report
|
|
67
|
+
console.log('๐ Opening report in browser on http://localhost:8080');
|
|
68
|
+
console.log('๐ก Press Ctrl+C to stop the server\n');
|
|
69
|
+
|
|
70
|
+
execSync(`npx allure open ${htmlReportPath} --port 8080`, { stdio: 'inherit' });
|
|
71
|
+
|
|
72
|
+
return true;
|
|
73
|
+
} catch (error) {
|
|
74
|
+
console.error(`โ Error opening report: ${error.message}`);
|
|
75
|
+
console.log(`\n๐ก To view manually, open: file://${path.resolve(indexPath)}`);
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function main() {
|
|
81
|
+
const reportDir = findLatestReport();
|
|
82
|
+
|
|
83
|
+
if (!reportDir) {
|
|
84
|
+
console.log('โ No Allure HTML reports found. Please run tests first.');
|
|
85
|
+
console.log('๐ก Reports are generated in: ./reports/allure/');
|
|
86
|
+
process.exit(1);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
openReport(reportDir);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Run the script
|
|
93
|
+
if (require.main === module) {
|
|
94
|
+
main();
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
module.exports = { findLatestReport, openReport };
|
package/allure-screenshots/Recorded_Scripts_Recorded_test_steps_success_2026-06-19T08-07-53-694Z.png
ADDED
|
Binary file
|
package/allure-screenshots/Recorded_Scripts_Recorded_test_steps_success_2026-06-19T08-10-50-605Z.png
ADDED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -11,13 +11,11 @@ module.exports = {
|
|
|
11
11
|
specs: require(SUITE_FILE).tests,
|
|
12
12
|
exclude: [],
|
|
13
13
|
|
|
14
|
-
|
|
15
14
|
logLevel: 'info',
|
|
16
15
|
coloredLogs: true,
|
|
17
16
|
screenshotPath: './errorShots/',
|
|
18
17
|
baseUrl: '',
|
|
19
18
|
|
|
20
|
-
|
|
21
19
|
waitforTimeout: 90000,
|
|
22
20
|
connectionRetryTimeout: 90000,
|
|
23
21
|
connectionRetryCount: 3,
|
|
@@ -27,5 +25,51 @@ module.exports = {
|
|
|
27
25
|
mochaOpts: {
|
|
28
26
|
ui: 'bdd',
|
|
29
27
|
timeout: 300000
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
// Enable screenshot capture for Allure (WDIO built-in)
|
|
31
|
+
screenshotOnSave: true,
|
|
32
|
+
|
|
33
|
+
// Test hooks
|
|
34
|
+
before: async function() {
|
|
35
|
+
console.log('๐ง BEFORE hook triggered in base config');
|
|
36
|
+
},
|
|
37
|
+
|
|
38
|
+
// Capture final screenshot directly in the report folder
|
|
39
|
+
after: async function(results) {
|
|
40
|
+
console.log('๐ง AFTER hook triggered in base config');
|
|
41
|
+
|
|
42
|
+
// Only process if running locally
|
|
43
|
+
if (process.env.PLATFORM === 'local') {
|
|
44
|
+
try {
|
|
45
|
+
const fs = require('fs');
|
|
46
|
+
const nodePath = require('path');
|
|
47
|
+
|
|
48
|
+
// Find the most recent Allure results directory
|
|
49
|
+
const reportsBaseDir = './reports/allure';
|
|
50
|
+
if (fs.existsSync(reportsBaseDir)) {
|
|
51
|
+
const dirs = fs.readdirSync(reportsBaseDir)
|
|
52
|
+
.map(file => nodePath.join(reportsBaseDir, file))
|
|
53
|
+
.filter(file => fs.statSync(file).isDirectory())
|
|
54
|
+
.sort((a, b) => fs.statSync(b).mtimeMs - fs.statSync(a).mtimeMs);
|
|
55
|
+
|
|
56
|
+
if (dirs.length > 0) {
|
|
57
|
+
const latestDir = dirs[0];
|
|
58
|
+
console.log(`๐ Report directory: ${latestDir}`);
|
|
59
|
+
|
|
60
|
+
// Save final screenshot directly to the report directory
|
|
61
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
62
|
+
const screenshotName = `Test_Suite_Completion_${timestamp}.png`;
|
|
63
|
+
const screenshotPath = nodePath.join(latestDir, screenshotName);
|
|
64
|
+
|
|
65
|
+
console.log(`๐ธ Saving final screenshot directly to report: ${screenshotName}`);
|
|
66
|
+
await browser.saveScreenshot(screenshotPath);
|
|
67
|
+
console.log(`โ
Screenshot saved in report folder: ${screenshotName}`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
} catch (error) {
|
|
71
|
+
console.error('โ Error saving screenshot to report folder:', error.message);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
30
74
|
}
|
|
31
|
-
};
|
|
75
|
+
};
|
|
@@ -90,6 +90,52 @@ async function pushComment(msg) {
|
|
|
90
90
|
if (!global.TEST_COMMENTS) global.TEST_COMMENTS = [];
|
|
91
91
|
global.TEST_COMMENTS.push(msg);
|
|
92
92
|
}
|
|
93
|
+
|
|
94
|
+
/* ----------------- AUTO REPORT GENERATION ----------------- */
|
|
95
|
+
async function generateLocalReport() {
|
|
96
|
+
try {
|
|
97
|
+
const buildName = process.env.BROWSERSTACK_BUILD_NAME || 'local-build';
|
|
98
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-').split('T')[0];
|
|
99
|
+
const reportDir = `./reports/mochawesome/${buildName}-${timestamp}`;
|
|
100
|
+
const jsonFile = path.join(process.cwd(), reportDir, 'mochawesome.json');
|
|
101
|
+
|
|
102
|
+
// Check if JSON report exists
|
|
103
|
+
if (!fs.existsSync(jsonFile)) {
|
|
104
|
+
console.log(`โ ๏ธ No JSON report found at: ${jsonFile}`);
|
|
105
|
+
console.log('๐ก Skipping report generation. Ensure tests ran successfully.');
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
console.log(`๐ Generating HTML report from: ${jsonFile}`);
|
|
110
|
+
|
|
111
|
+
// Use marge to generate HTML report
|
|
112
|
+
const { execSync } = require('child_process');
|
|
113
|
+
execSync(`npx marge "${jsonFile}" -o "${reportDir}"`, {
|
|
114
|
+
stdio: 'inherit',
|
|
115
|
+
cwd: process.cwd()
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
const htmlFile = path.join(reportDir, 'mochawesome.html');
|
|
119
|
+
console.log(`โ
HTML report generated successfully!`);
|
|
120
|
+
console.log(`๐ Location: ${htmlFile}`);
|
|
121
|
+
|
|
122
|
+
// Auto-open report in browser
|
|
123
|
+
if (fs.existsSync(htmlFile)) {
|
|
124
|
+
console.log(`๐ Opening report in browser...`);
|
|
125
|
+
try {
|
|
126
|
+
const openCommand = process.platform === 'darwin' ? 'open' :
|
|
127
|
+
process.platform === 'win32' ? 'start' :
|
|
128
|
+
'xdg-open';
|
|
129
|
+
execSync(`${openCommand} "${htmlFile}"`, { stdio: 'ignore' });
|
|
130
|
+
} catch (error) {
|
|
131
|
+
console.log(`๐ก To view report manually, open: ${htmlFile}`);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
} catch (error) {
|
|
135
|
+
console.error(`โ Error generating local report: ${error.message}`);
|
|
136
|
+
// Don't fail the entire process if report generation fails
|
|
137
|
+
}
|
|
138
|
+
}
|
|
93
139
|
/* ------------------ COMMON CONFIG ------------------ */
|
|
94
140
|
|
|
95
141
|
const commonHooks = {
|
|
@@ -348,6 +394,13 @@ const commonHooks = {
|
|
|
348
394
|
|
|
349
395
|
await safeUpdateExecution();
|
|
350
396
|
BUFFER.clear();
|
|
397
|
+
|
|
398
|
+
// Auto-generate HTML report for local execution
|
|
399
|
+
if (process.env.PLATFORM === 'local') {
|
|
400
|
+
console.log('๐ Generating local test report...');
|
|
401
|
+
await generateLocalReport();
|
|
402
|
+
}
|
|
403
|
+
|
|
351
404
|
return exitCode;
|
|
352
405
|
},
|
|
353
406
|
|
|
@@ -1,11 +1,59 @@
|
|
|
1
|
-
module.exports = () =>
|
|
2
|
-
|
|
1
|
+
module.exports = () => {
|
|
2
|
+
// Generate unique report directory using BROWSERSTACK_BUILD_NAME
|
|
3
|
+
const buildName = process.env.BROWSERSTACK_BUILD_NAME || 'local-mobile-build';
|
|
4
|
+
// Remove spaces and special characters from build name for folder name - use underscores
|
|
5
|
+
const cleanBuildName = buildName.replace(/[^a-zA-Z0-9_]/g, '_');
|
|
6
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-').split('T')[0]; // YYYY-MM-DD format
|
|
7
|
+
const uniqueReportDir = `./reports/allure/${cleanBuildName}-${timestamp}`;
|
|
3
8
|
|
|
9
|
+
console.log(`๐ฑ Mobile local execution configured`);
|
|
10
|
+
console.log(`๐ Allure results will be saved in: ${uniqueReportDir}`);
|
|
11
|
+
console.log(`๐ก Report will be generated automatically after execution completes`);
|
|
4
12
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
13
|
+
return {
|
|
14
|
+
services: [
|
|
15
|
+
'appium',
|
|
16
|
+
// Real-time screenshot capture (works even if execution stopped mid-way)
|
|
17
|
+
[require('../screenshot-service').ScreenshotService]
|
|
18
|
+
],
|
|
19
|
+
|
|
20
|
+
capabilities: [{
|
|
21
|
+
platformName: 'Android',
|
|
22
|
+
'appium:deviceName': 'Android Emulator',
|
|
23
|
+
'appium:automationName': 'UiAutomator2',
|
|
24
|
+
'appium:app': process.env.LOCAL_APP_PATH
|
|
25
|
+
}],
|
|
26
|
+
|
|
27
|
+
// Allure Reporter Configuration
|
|
28
|
+
reporters: [
|
|
29
|
+
['allure', {
|
|
30
|
+
outputDir: uniqueReportDir,
|
|
31
|
+
disableWebdriverStepsReporting: false, // Enable step reporting
|
|
32
|
+
disableWebdriverScreenshotsReporting: false, // Enable automatic screenshot capture
|
|
33
|
+
useCucumberStepReporter: false,
|
|
34
|
+
disableMochaHooks: false,
|
|
35
|
+
allureCode: true,
|
|
36
|
+
captureAllureScreenshots: true
|
|
37
|
+
}]
|
|
38
|
+
],
|
|
39
|
+
|
|
40
|
+
// Auto-generate report after execution completes
|
|
41
|
+
onComplete: async function(exitCode, config, capabilities, results) {
|
|
42
|
+
const { execSync } = require('child_process');
|
|
43
|
+
const nodePath = require('path');
|
|
44
|
+
try {
|
|
45
|
+
// Add a small delay to ensure Allure finishes writing all files
|
|
46
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
47
|
+
|
|
48
|
+
// Resolve script path relative to framework package (works from any CWD)
|
|
49
|
+
const scriptPath = nodePath.resolve(__dirname, '../../allure-report-utils/generate-allure-report.js');
|
|
50
|
+
|
|
51
|
+
console.log('\n๐ฏ Generating Allure report...');
|
|
52
|
+
execSync(`node "${scriptPath}"`, { stdio: 'inherit', cwd: process.cwd() });
|
|
53
|
+
console.log('โ
Report generation complete!');
|
|
54
|
+
} catch (error) {
|
|
55
|
+
console.error('โ Error generating report:', error.message);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
};
|