Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 27 additions & 1 deletion src/commands/test.run.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { DRY_RUN_BANNER, resetDryRunBannerForTesting } from '../lib/client-facto
import type { FetchImpl } from '../lib/http.js';
import type { RunResponse, TriggerRunResponse, BatchRunFreshResponse } from '../lib/runs.types.js';
import { takeTelemetryExtras } from '../lib/telemetry.js';
import { runTestRun, runTestRunAll } from './test.js';
import { renderRunResponseText, runTestRun, runTestRunAll } from './test.js';

// ---------------------------------------------------------------------------
// Helpers
Expand Down Expand Up @@ -7203,6 +7203,32 @@ describe('runTestRun — --target-url reachability preflight wiring', () => {
});
});

describe('run card: failed step (#672)', () => {
it('prints failedStepIndex right after failureKind for a failed run', () => {
const lines = renderRunResponseText({ ...makeFailedRun(), failedStepIndex: 4 }).split('\n');
const kind = lines.indexOf('failureKind assertion');
expect(kind).toBeGreaterThanOrEqual(0);
expect(lines[kind + 1]).toBe('failedStepIndex 4');
});

it('prints it for a blocked run too', () => {
const text = renderRunResponseText({ ...makeFailedRun(), status: 'blocked' });
expect(text.split('\n')).toContain('failedStepIndex 2');
});

it('omits the line when the server reported no failed step', () => {
expect(renderRunResponseText({ ...makeFailedRun(), failedStepIndex: null })).not.toContain(
'failedStepIndex',
);
});

it('omits the line for a passed run', () => {
expect(renderRunResponseText({ ...makePassedRun(), failedStepIndex: 2 })).not.toContain(
'failedStepIndex',
);
});
});

describe('gh-output integration on single-test run --wait (Gap A)', () => {
function singleRunHarness(run: RunResponse) {
const { credentialsPath } = makeCreds();
Expand Down
2 changes: 2 additions & 0 deletions src/commands/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7563,6 +7563,8 @@ export function renderRunResponseText(
if (run.startedAt) lines.push(`startedAt ${run.startedAt}`);
if (run.finishedAt) lines.push(`finishedAt ${run.finishedAt}`);
if (run.failureKind) lines.push(`failureKind ${run.failureKind}`);
if ((run.status === 'failed' || run.status === 'blocked') && run.failedStepIndex !== null)
lines.push(`failedStepIndex ${run.failedStepIndex}`);
// D5-UX: show the human error string when status is failed/blocked and
// the backend provided it. Truncate long multi-line errors to the first
// line (≤200 chars) so the text output stays readable. JSON mode is
Expand Down
Loading