Files
test-samurai-vitest-runner/reporter/test_samurai_vitest_reporter.js
M.Schirmer 3f31707f01
Some checks failed
tests / test (push) Failing after 7s
initialize with first claude code interation
2026-04-20 08:06:22 +02:00

87 lines
2.2 KiB
JavaScript

/**
* test_samurai_vitest_reporter.js
*
* Custom Vitest 2.x reporter for test-samurai.
*
* Emits one line per completed test case to stdout:
* TSAMURAI_RESULT <json>
*
* Payload schema:
* {
* name: string -- Describe-hierarchy + test title joined with "/"
* status: "passed" | "failed" | "skipped"
* file: string | null -- absolute file path
* location: { line: number, column: number } | null
* output: string[] -- error messages / stack traces (failures only)
* }
*/
const RESULT_PREFIX = 'TSAMURAI_RESULT ';
export default class TestSamuraiVitestReporter {
onTestCaseResult(testCase) {
const name = buildListingName(testCase);
const status = mapStatus(testCase.result?.state);
const output = buildOutput(testCase);
const payload = {
name,
status,
file: testCase.file?.filepath ?? null,
location: testCase.location ?? null,
output,
};
process.stdout.write(`${RESULT_PREFIX}${JSON.stringify(payload)}\n`);
}
}
/**
* Builds a slash-separated name from the describe hierarchy.
* E.g. describe('MyComponent') > describe('renders') > it('the button')
* → "MyComponent/renders/the button"
*/
function buildListingName(testCase) {
const parts = [testCase.name];
let current = testCase.parent;
while (current && current.type === 'suite') {
parts.unshift(current.name);
current = current.parent;
}
return parts.filter(Boolean).join('/');
}
/**
* Maps Vitest result states to test-samurai status strings.
*/
function mapStatus(state) {
const map = {
pass: 'passed',
fail: 'failed',
skip: 'skipped',
todo: 'skipped',
};
return map[state] ?? 'skipped';
}
/**
* Collects error messages and stack traces for failed tests.
*/
function buildOutput(testCase) {
const lines = [];
const errors = testCase.result?.errors ?? [];
for (const err of errors) {
if (typeof err.message === 'string' && err.message.length > 0) {
err.message.split('\n').forEach((line) => {
if (line !== '') lines.push(line);
});
}
if (typeof err.stack === 'string' && err.stack.length > 0) {
err.stack.split('\n').forEach((line) => {
if (line !== '') lines.push(line);
});
}
}
return lines;
}