Skip to content

Instantly share code, notes, and snippets.

@LeeCheneler
Created October 6, 2021 09:37
Show Gist options
  • Save LeeCheneler/404069487014cef3d01b5d8948b14be2 to your computer and use it in GitHub Desktop.
Save LeeCheneler/404069487014cef3d01b5d8948b14be2 to your computer and use it in GitHub Desktop.
Publish testcafe JSON report to confluence page
/* eslint-disable import/no-unresolved */
import axios from 'axios';
import prettyMs from 'pretty-ms';
import report from './report.json';
const assertEnvVar = (name: string) => {
if (!process.env[name]) {
throw new Error(`Environment variable ${name} is not set`);
}
};
assertEnvVar('CONFLUENCE_BASE_URL');
assertEnvVar('CONFLUENCE_USER');
assertEnvVar('CONFLUENCE_TOKEN');
assertEnvVar('CONFLUENCE_REPORT_PAGE_TITLE');
assertEnvVar('CONFLUENCE_REPORT_PAGE_ID');
const formatDate = (date: Date) =>
new Intl.DateTimeFormat('en-GB', {
dateStyle: 'short',
timeStyle: 'short',
}).format(date);
const createHtmlBuilder = () => {
let html = '';
const builder = {
append: (snippet: string) => {
html = `${html}\n${snippet}`;
return builder;
},
build: () => html,
};
return builder;
};
const formatReport = () => {
const builder = createHtmlBuilder();
// basic test run info
const start = formatDate(new Date(report.startTime));
const end = formatDate(new Date(report.endTime));
const overviewResultEmoji = report.passed === report.total ? '✅' : '❌';
const overViewResults = `${report.passed} / ${report.total} ${overviewResultEmoji}`;
builder.append(`
<p>This page is auto generated from a Limio e2e test pipeline.</p>
<table>
<tbody>
<tr>
<td colspan="1"><b>Start time</b></td>
<td colspan="2">${start}</td>
</tr>
<tr>
<td colspan="1"><b>End time</b></td>
<td colspan="2">${end}</td>
</tr>
<tr>
<td colspan="1"><b>User agents</b></td>
<td colspan="2">${report.userAgents.join()}</td>
</tr>
<tr>
<td colspan="1"><b>Results</b></td>
<td colspan="2">${overViewResults}</td>
</tr>
</tbody>
</table>`);
// fixtures
for (const fixture of report.fixtures) {
builder.append(`
<h2>${fixture.name}</h2>
<table>
<tbody>`);
for (const test of fixture.tests) {
if (test.skipped) {
builder.append(
`<tr>
<td colspan="1">🟡</td>
<td colspan="7">${test.name}</td>
<td colspan="2"></td>
</tr>`
);
} else {
const testResultEmoji = test.errs.length === 0 ? '🟢' : '🔴';
builder.append(
`<tr>
<td colspan="1">${testResultEmoji}</td>
<td colspan="7">${test.name}</td>
<td colspan="2">${prettyMs(test.durationMs)}</td>
</tr>`
);
}
}
builder.append(`
</tbody>
</table>`);
}
return builder.build();
};
const run = async () => {
const authorization = `Basic ${Buffer.from(
`${process.env.CONFLUENCE_USER}:${process.env.CONFLUENCE_TOKEN}`
).toString('base64')}`;
const pageApiUrl = `${process.env.CONFLUENCE_BASE_URL}/wiki/rest/api/content/${process.env.CONFLUENCE_REPORT_PAGE_ID}`;
const readResponse = await axios.get<{ version: { number: number } }>(
pageApiUrl,
{
headers: {
authorization,
},
}
);
const updateResponse = await axios.put(
pageApiUrl,
{
version: {
number: readResponse.data.version.number + 1,
},
title: process.env.CONFLUENCE_REPORT_PAGE_TITLE,
type: 'page',
body: {
storage: {
value: formatReport(),
representation: 'storage',
},
},
},
{
headers: {
authorization,
},
}
);
if (updateResponse.status >= 400) {
throw new Error(JSON.stringify(updateResponse.data, null, 2));
}
};
run();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment