Skip to content

Commit 8c8824a

Browse files
committed
artifact addition
1 parent 7a34ff7 commit 8c8824a

5 files changed

Lines changed: 644 additions & 14 deletions

File tree

browserstack-report-action/dist/index.js

Lines changed: 330 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38202,7 +38202,7 @@ async function run() {
3820238202
pollingInterval
3820338203
);
3820438204

38205-
await ReportProcessor.processReport(reportData);
38205+
await ReportProcessor.processReport(reportData, buildName);
3820638206
} catch (error) {
3820738207
core.setFailed(`Action failed: ${error.message}`);
3820838208
}
@@ -38291,7 +38291,6 @@ class MockReportService {
3829138291
build_uuid: 'mock-build-123',
3829238292
report: {
3829338293
basic_html: `
38294-
<html>
3829538294
<body>
3829638295

3829738296
<h2>Build Insights</h2>
@@ -38402,8 +38401,257 @@ class MockReportService {
3840238401
</table>
3840338402

3840438403
</body>
38405-
</html>
38406-
`
38404+
`,
38405+
rich_html: `<body>
38406+
38407+
<h2>Build Insights</h2>
38408+
38409+
<div class="grid-container">
38410+
<div class="metric-card">
38411+
<h1>5</h1>
38412+
<p>All</p>
38413+
</div>
38414+
<div class="metric-card passed">
38415+
<h1>2</h1>
38416+
<p>Passed</p>
38417+
</div>
38418+
<div class="metric-card failed">
38419+
<h1>2</h1>
38420+
<p>Failed</p>
38421+
</div>
38422+
<div class="metric-card skipped">
38423+
<h1>1</h1>
38424+
<p>Skipped</p>
38425+
</div>
38426+
<div class="metric-card unknown">
38427+
<h1>0</h1>
38428+
<p>Unknown</p>
38429+
</div>
38430+
</div>
38431+
38432+
<div class="grid-metrics">
38433+
<div class="metric-box">
38434+
<h2>New Failures</h2>
38435+
<h4><a href="<https://observability.browserstack.com/projects/WDIO+Cucumber+GH/builds/Sanity+Only+Chrome/4052?tab=insights>" target="_blank">View</a></h4>
38436+
</div>
38437+
<div class="metric-box">
38438+
<h2>Always Failing</h2>
38439+
<h4><a href="<https://observability.browserstack.com/projects/WDIO+Cucumber+GH/builds/Sanity+Only+Chrome/4052?tab=insights>" target="_blank">View</a></h4>
38440+
</div>
38441+
<div class="metric-box">
38442+
<h2>Flaky Test</h2>
38443+
<h4><a href="<https://observability.browserstack.com/projects/WDIO+Cucumber+GH/builds/Sanity+Only+Chrome/4052?tab=insights>" target="_blank">View</a></h4>
38444+
</div>
38445+
<div class="metric-box">
38446+
<h2>Muted Tests</h2>
38447+
<h4><a href="<https://observability.browserstack.com/projects/WDIO+Cucumber+GH/builds/Sanity+Only+Chrome/4052?tab=insights>" target="_blank">View</a></h4>
38448+
</div>
38449+
<div class="metric-box">
38450+
<h2>Unique Errors</h2>
38451+
<h4><a href="<https://observability.browserstack.com/projects/WDIO+Cucumber+GH/builds/Sanity+Only+Chrome/4052?tab=insights>" target="_blank">View</a></h4>
38452+
</div>
38453+
<div class="metric-box">
38454+
<h2>Performance Anomaly</h2>
38455+
<h4><a href="<https://observability.browserstack.com/projects/WDIO+Cucumber+GH/builds/Sanity+Only+Chrome/4052?tab=insights>" target="_blank">View</a></h4>
38456+
</div>
38457+
</div>
38458+
38459+
<div class="w3-panel w3-light-grey w3-border w3-round">
38460+
<p>Note: Click view or add report timeout in plugin settings to see build insights above.</p>
38461+
</div>
38462+
<br>
38463+
38464+
<h2>Test List</h2>
38465+
38466+
<table>
38467+
<thead>
38468+
<tr>
38469+
<th>Test Name</th>
38470+
<th>Status</th>
38471+
<th>Test History</th>
38472+
<th>Browser/Device</th>
38473+
<th>OS</th>
38474+
<th>Duration</th>
38475+
</tr>
38476+
</thead>
38477+
<tbody>
38478+
<tr>
38479+
<td class="test-link"><a href="<https://observability.browserstack.com/projects/WDIO+Cucumber+GH/builds/Sanity+Only+Chrome/4052?tab=tests&details=1327748286>" target="_blank">Refresh API User token - Step not defined</a></td>
38480+
<td class="status-skipped">Skipped</td>
38481+
<td class="test-history"><a href="<https://observability.browserstack.com/projects/WDIO+Cucumber+GH/builds/Sanity+Only+Chrome/4052?tab=tests&details=1327748286&utm_medium=cicd&utm_source=jenkins>" target="_blank">View History</a></td>
38482+
<td>Chrome 135</td>
38483+
<td>OS X</td>
38484+
<td>92s</td>
38485+
</tr>
38486+
<tr>
38487+
<td class="test-link"><a href="#">Delete Account via API - Step Pending</a></td>
38488+
<td class="status-failed">Failed</td>
38489+
<td class="test-history"><a href="#">View History</a></td>
38490+
<td>Google Pixel 7</td>
38491+
<td>Android 12</td>
38492+
<td>180s</td>
38493+
</tr>
38494+
<tr>
38495+
<td class="test-link"><a href="#">BStack Demo API</a></td>
38496+
<td class="status-passed">Passed</td>
38497+
<td class="test-history"><a href="#">View History</a></td>
38498+
<td>Samsung Galaxy Tab S8</td>
38499+
<td>Android 12</td>
38500+
<td>134s</td>
38501+
</tr>
38502+
<tr>
38503+
<td class="test-link"><a href="#">Verify API Create Account (fred, password789)</a></td>
38504+
<td class="status-failed">Failed</td>
38505+
<td class="test-history"><a href="#">View History</a></td>
38506+
<td>iPhone 14 Pro</td>
38507+
<td>iOS 15.5</td>
38508+
<td>221s</td>
38509+
</tr>
38510+
<tr>
38511+
<td class="test-link"><a href="#">Verify API User Address</a></td>
38512+
<td class="status-passed">Passed</td>
38513+
<td class="test-history"><a href="#">View History</a></td>
38514+
<td>Chrome 135</td>
38515+
<td>Windows 11</td>
38516+
<td>102s</td>
38517+
</tr>
38518+
</tbody>
38519+
</table>
38520+
38521+
</body>`,
38522+
rich_css: `body {
38523+
font-family: 'Arial', sans-serif;
38524+
background-color: #f8f9fb;
38525+
padding: 20px;
38526+
}
38527+
38528+
h2 {
38529+
margin-top: 5px;
38530+
margin-bottom: 15px;
38531+
color: #2b3e50;
38532+
}
38533+
38534+
.grid-container {
38535+
display: grid;
38536+
grid-template-columns: repeat(5, 1fr);
38537+
gap: 10px;
38538+
margin-bottom: 30px;
38539+
max-width: 1000px;
38540+
}
38541+
38542+
.metric-card {
38543+
background-color: white;
38544+
border-radius: 8px;
38545+
padding: 20px;
38546+
text-align: center;
38547+
box-shadow: 0 0 4px rgba(0, 0, 0, 0.05);
38548+
}
38549+
38550+
.metric-card h1 {
38551+
margin: 0;
38552+
font-size: 32px;
38553+
}
38554+
38555+
.passed {
38556+
color: green;
38557+
}
38558+
38559+
.failed {
38560+
color: red;
38561+
}
38562+
38563+
.skipped,
38564+
.unknown {
38565+
color: #6c757d;
38566+
}
38567+
38568+
.grid-metrics {
38569+
display: grid;
38570+
grid-template-columns: repeat(3, 1fr);
38571+
gap: 10px;
38572+
max-width: 1000px;
38573+
}
38574+
38575+
.metric-box {
38576+
background-color: white;
38577+
border-radius: 8px;
38578+
padding: 20px;
38579+
box-shadow: 0 0 4px rgba(0, 0, 0, 0.05);
38580+
}
38581+
38582+
.metric-box h2 {
38583+
font-size: 20px;
38584+
margin-bottom: 10px;
38585+
}
38586+
38587+
.metric-box h1 {
38588+
font-size: 28px;
38589+
margin: 0;
38590+
}
38591+
38592+
38593+
38594+
.metric-box p {
38595+
font-size: 14px;
38596+
color: #666;
38597+
margin: 8px 0 0;
38598+
}
38599+
38600+
table {
38601+
width: 100%;
38602+
border-collapse: collapse;
38603+
background-color: white;
38604+
border-radius: 8px;
38605+
overflow: hidden;
38606+
box-shadow: 0 0 4px rgba(0, 0, 0, 0.05);
38607+
}
38608+
38609+
th,
38610+
td {
38611+
padding: 12px 16px;
38612+
border-bottom: 1px solid #eee;
38613+
text-align: left;
38614+
font-size: 14px;
38615+
}
38616+
38617+
th {
38618+
background-color: #f1f3f5;
38619+
font-weight: bold;
38620+
}
38621+
38622+
tr:last-child td {
38623+
border-bottom: none;
38624+
}
38625+
38626+
.status-passed {
38627+
color: green;
38628+
font-weight: bold;
38629+
}
38630+
38631+
.status-failed {
38632+
color: red;
38633+
font-weight: bold;
38634+
}
38635+
38636+
.status-skipped {
38637+
color: #6c757d;
38638+
font-weight: bold;
38639+
}
38640+
38641+
.test-link a {
38642+
text-decoration: none;
38643+
color: #007bff;
38644+
}
38645+
38646+
.test-history a {
38647+
text-decoration: none;
38648+
color: #007bff;
38649+
}
38650+
38651+
.metric-box a {
38652+
text-decoration: none;
38653+
color: #007bff;
38654+
}`
3840738655
}
3840838656
};
3840938657
}
@@ -38421,20 +38669,25 @@ module.exports = new MockReportService(); // Export singleton instance
3842138669

3842238670

3842338671
const core = __nccwpck_require__(7484);
38672+
const ArtifactManager = __nccwpck_require__(197);
3842438673

3842538674
class ReportProcessor {
38426-
static async processReport(reportData) {
38675+
static async processReport(reportData, buildName) {
3842738676
try {
3842838677
const summary = core.summary;
3842938678
await summary.addHeading('BrowserStack Test Report');
3843038679

38431-
// Process report content - both success and error cases come in report_html
3843238680
if (reportData?.report?.basic_html) {
38433-
await summary.addRaw(reportData?.report?.basic_html);
38681+
await summary.addRaw(`<html>${reportData.report.basic_html}</html>`);
38682+
3843438683
} else {
3843538684
await summary.addRaw('⚠️ No report content available');
3843638685
}
3843738686

38687+
if(reportData?.report?.rich_html) {
38688+
const report = `<!DOCTYPE html> <html><head><style>${reportData?.report?.rich_css}</style></head> ${reportData?.report?.rich_html}</html>`;
38689+
await ArtifactManager.saveReportAsArtifact(report, buildName);
38690+
}
3843838691

3843938692
return summary.write();
3844038693
} catch (error) {
@@ -38554,6 +38807,68 @@ class ReportService {
3855438807
module.exports = ReportService;
3855538808

3855638809

38810+
/***/ }),
38811+
38812+
/***/ 197:
38813+
/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
38814+
38815+
"use strict";
38816+
38817+
38818+
const fs = __nccwpck_require__(9896);
38819+
const path = __nccwpck_require__(6928);
38820+
const core = __nccwpck_require__(7484);
38821+
const artifact = __nccwpck_require__(1841);
38822+
38823+
class ArtifactManager {
38824+
static async saveReportAsArtifact(report, buildName) {
38825+
if (!report) {
38826+
core.debug('No HTML content available to save as artifact');
38827+
return '';
38828+
}
38829+
38830+
try {
38831+
// Create artifacts directory
38832+
const artifactDir = path.join(process.env.GITHUB_WORKSPACE || '.', 'browserstack-artifacts');
38833+
fs.mkdirSync(artifactDir, { recursive: true });
38834+
38835+
// Create HTML file
38836+
const sanitizedBuildName = buildName.replace(/[^a-z0-9]/gi, '_').toLowerCase();
38837+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
38838+
const fileName = `browserstack-report-${sanitizedBuildName}-${timestamp}.html`;
38839+
const filePath = path.join(artifactDir, fileName);
38840+
38841+
// Write content
38842+
fs.writeFileSync(filePath, report);
38843+
38844+
// Upload as artifact
38845+
const artifactClient = artifact.create();
38846+
const artifactName = `browserstack-report-${sanitizedBuildName}`;
38847+
38848+
const uploadResult = await artifactClient.uploadArtifact(
38849+
artifactName,
38850+
[filePath],
38851+
artifactDir,
38852+
{ continueOnError: true }
38853+
);
38854+
38855+
if (uploadResult.failedItems.length > 0) {
38856+
core.warning(`Failed to upload artifacts: ${uploadResult.failedItems.join(', ')}`);
38857+
return '';
38858+
}
38859+
38860+
core.info(`Report saved as artifact: ${artifactName}`);
38861+
return `${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}/artifacts/${uploadResult.artifactId}`;
38862+
} catch (error) {
38863+
core.warning(`Failed to save artifact: ${error.message}`);
38864+
return '';
38865+
}
38866+
}
38867+
}
38868+
38869+
module.exports = ArtifactManager;
38870+
38871+
3855738872
/***/ }),
3855838873

3855938874
/***/ 933:
@@ -38578,6 +38893,14 @@ class TimeoutManager {
3857838893
module.exports = TimeoutManager;
3857938894

3858038895

38896+
/***/ }),
38897+
38898+
/***/ 1841:
38899+
/***/ ((module) => {
38900+
38901+
module.exports = eval("require")("@actions/artifact");
38902+
38903+
3858138904
/***/ }),
3858238905

3858338906
/***/ 2078:

browserstack-report-action/src/main.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ async function run() {
4444
pollingInterval
4545
);
4646

47-
await ReportProcessor.processReport(reportData);
47+
await ReportProcessor.processReport(reportData, buildName);
4848
} catch (error) {
4949
core.setFailed(`Action failed: ${error.message}`);
5050
}

0 commit comments

Comments
 (0)