MCPcopy Create free account
hub / github.com/TestSprite/testsprite-cli / runSteps

Function runSteps

src/commands/test.ts:3528–3627  ·  view source on GitHub ↗
(
  opts: StepsOptions,
  deps: TestDeps = {},
)

Source from the content-addressed store, hash-verified

3526}
3527
3528export async function runSteps(
3529 opts: StepsOptions,
3530 deps: TestDeps = {},
3531): Promise<Page<CliTestStep>> {
3532 const out = makeOutput(opts.output, deps);
3533 const client = makeClient(opts, deps);
3534 const stderrFn = deps.stderr ?? ((line: string) => process.stderr.write(`${line}\n`));
3535
3536 // When --run-id is supplied, use the authoritative run-scoped endpoint
3537 // `GET /runs/{runId}?includeSteps=true` instead of client-filtering the
3538 // cumulative `/tests/{id}/steps` response. The cumulative FE Portal step
3539 // rows don't reliably carry per-run `runIdIfAvailable`, so the old
3540 // client-side filter always returned empty — even for completed runs.
3541 if (opts.runId !== undefined) {
3542 // 404 → NOT_FOUND (exit 4) — unknown or cross-tenant runId.
3543 // All other errors propagate unchanged (auth, transport, etc.).
3544 const run = await client.getRun(opts.runId, { includeSteps: true });
3545
3546 // Restore the implicit test-scoping the old `/tests/{testId}/steps` path
3547 // had: a runId belonging to a DIFFERENT test (same tenant) must not leak
3548 // that other test's steps under `test steps <thisTestId> --run-id <id>`.
3549 // Skipped under --dry-run — the canned sample's testId is fixed, not the
3550 // caller's argument, so a real comparison would always (falsely) mismatch.
3551 if (!opts.dryRun && run.testId !== opts.testId) {
3552 throw ApiError.fromEnvelope(
3553 {
3554 code: 'NOT_FOUND',
3555 message: `Run ${opts.runId} does not belong to test ${opts.testId} (it belongs to ${run.testId}). Use 'testsprite test steps ${run.testId} --run-id ${opts.runId}' or drop --run-id.`,
3556 },
3557 404,
3558 );
3559 }
3560
3561 const rawSteps = run.steps ?? [];
3562 const items: CliTestStep[] = rawSteps.map(s => mapRunStepToCliTestStep(s, run));
3563 const page: Page<CliTestStep> = { items, nextToken: null };
3564
3565 if (items.length === 0) {
3566 // The run exists but has no recorded step rows yet (e.g. a fast
3567 // code-replay run that finished before any steps were written).
3568 if (opts.output === 'json') {
3569 out.print(page, data => renderStepsText(data as Page<CliTestStep>));
3570 } else {
3571 stderrFn(
3572 `[advisory] No step records found for run ${opts.runId}. ` +
3573 `The run may have completed before steps were written, or this run type does not record per-step data. ` +
3574 `For the full failure bundle use: testsprite test artifact get ${opts.runId}`,
3575 );
3576 }
3577 return page;
3578 }
3579
3580 out.print(page, data => renderStepsText(data as Page<CliTestStep>));
3581 return page;
3582 }
3583
3584 // Bare `test steps <id>` (no --run-id): cumulative path — byte-identical to
3585 // the original behavior. Pagination flags are honored here.

Callers 3

p4-schema.test.tsFile · 0.85
test.test.tsFile · 0.85
createTestCommandFunction · 0.85

Calls 9

mapRunStepToCliTestStepFunction · 0.85
renderStepsTextFunction · 0.85
validatePaginationFlagsFunction · 0.85
fromEnvelopeMethod · 0.80
printMethod · 0.80
makeOutputFunction · 0.70
makeClientFunction · 0.70
getRunMethod · 0.65
getMethod · 0.65

Tested by

no test coverage detected