@crabnebula/webdriverio-cloud-reporter
Version:
WebdriverIO Reporter for CrabNebula Cloud via the CrabNebula Test Runner
81 lines (71 loc) • 2.11 kB
text/typescript
import WDIOReporter, { RunnerStats, TestStats } from "@wdio/reporter";
import type { Reporters } from "@wdio/types";
export class CrabNebulaCloudReporter extends WDIOReporter {
uploading = false;
finishedTests: Array<TestStats> = [];
constructor(options: Partial<Reporters.Options>) {
options = Object.assign(options, { stdout: true });
super(options);
}
get isSynchronised() {
return !this.uploading;
}
uploadReport(sessionId: string) {
const remoteWebdriverUrl = process.env.REMOTE_WEBDRIVER_URL;
if (!remoteWebdriverUrl) {
return;
}
const url = new URL(remoteWebdriverUrl);
url.pathname += `session/${sessionId}/report`;
this.uploading = true;
const upload = async () => {
const reports = [];
for (const test of this.finishedTests) {
const { output, ...stats } = test;
reports.push(stats);
}
this.write("Uploading test report...\n");
const body = JSON.stringify(reports);
await fetch(url, {
method: "POST",
body,
headers: {
"Content-Type": "application/json",
},
signal: AbortSignal.timeout(10000),
}).then((res) => {
if (res.status !== 200) {
return res.text();
}
});
};
upload()
.then(() => {
this.write("Test report uploaded\n");
})
.catch((err) => {
this.write(`Failed to upload test report: ${err.message}\n`);
})
.finally(() => {
this.uploading = false;
});
}
onTestPass(testStats: TestStats) {
this.finishedTests.push(testStats);
}
onTestFail(testStats: TestStats) {
this.finishedTests.push(testStats);
}
onRunnerEnd(runnerStats: RunnerStats) {
if ("sessionId" in runnerStats.capabilities) {
const sessionId = runnerStats.capabilities.sessionId as string;
if (sessionId) {
this.uploadReport(sessionId);
} else {
this.write("Invalid session ID found in capabilities\n");
}
} else {
this.write("No session ID found in capabilities\n");
}
}
}