Skip to content

fix(dry-run): include failed run-scoped step sample#218

Open
JerryNee wants to merge 4 commits into
TestSprite:mainfrom
JerryNee:fix/dry-run-run-step-sample
Open

fix(dry-run): include failed run-scoped step sample#218
JerryNee wants to merge 4 commits into
TestSprite:mainfrom
JerryNee:fix/dry-run-run-step-sample

Conversation

@JerryNee

@JerryNee JerryNee commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Replaces accidentally closed PR #198.

Adds a dry-run path that demonstrates failed run-scoped step output without breaking the default test wait --dry-run happy path.

After reviewer feedback on the original PR, this uses a sentinel run id approach:

  • default GET /runs/{runId} dry-run sample stays terminal passed
  • GET /runs/run_failed_sample returns the failed run-scoped sample
  • test steps --run-id run_failed_sample --dry-run demonstrates the failed step mapping offline

Related issue

Fixes #197

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update

Testing

Previously validated on the original PR branch with:

  • npm test -- src/lib/dry-run/samples.test.ts src/commands/test.test.ts
  • npm run typecheck
  • npm run format:check
  • npm run lint
  • NO_COLOR= npm test

Notes for reviewers

This keeps wait flows on the default passed sample while still giving agents a documented failed run-scoped step sample for dry-run exploration.

Summary by CodeRabbit

  • New Features
    • Added dry-run sample support for a failed run, including step-level failure details in the output.
  • Bug Fixes
    • Improved dry-run run lookup to return the correct failed-run payload for the matching run ID.
    • Ensured failed steps are consistently annotated (failure status, assertion type, and error text), and sample resolution follows first-match behavior.
  • Tests
    • Added regression coverage for failed-run dry-runs and for dry-run sample resolution/selection behavior.

@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 456c6392-67f8-4dea-8337-949946f8d86a

📥 Commits

Reviewing files that changed from the base of the PR and between 6c7a0e0 and 43e47fc.

📒 Files selected for processing (1)
  • src/lib/dry-run/samples.ts

Walkthrough

Adds a failed run-scoped dry-run sample, updates sample lookup to return it, and adds tests covering failed-step fields, registry ordering, and dry-run command output.

Changes

Failed run sample fixture and integration

Layer / File(s) Summary
Failed and passed run sample fixtures
src/lib/dry-run/samples.ts
Adds SAMPLE_FAILED_RUN_ID, defines passedRunSample and failedRunSample, updates the GET /runs/{runId} mapping, adds the failed-run sentinel mapping, and keeps matched sample bodies lazy in findSample.
Sample registry and run shape tests
src/lib/dry-run/samples.test.ts
Adds coverage for findSample('GET', .../runs/run_failed_sample) and for registry ordering between the sentinel entry and the generic GET /runs/{runId} entry.
Dry-run command output test
src/commands/test.test.ts
Adds a runSteps dry-run case for --run-id run_failed_sample that checks failed-step status, type, contributor flags, and the serialized error field.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

  • TestSprite/testsprite-cli#167: Both changes cover run-scoped step metadata, including failed-step error and stepType handling in dry-run-adjacent flows.

Suggested reviewers: ruili-testsprite, zeshi-du

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately describes the main dry-run sample change.
Linked Issues check ✅ Passed The changes add a failed run-scoped dry-run sample and focused tests that verify failedStepIndex, error text, and related run fields as requested in #197.
Out of Scope Changes check ✅ Passed The additional sample-selection and lazy-factory adjustment appears directly tied to supporting the new dry-run fixture behavior, not unrelated scope.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/lib/dry-run/samples.ts (1)

858-879: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Special-casing the sentinel run id inline in the generic lookup couples findSample to one specific fixture.

The pathOnly === /runs/${SAMPLE_FAILED_RUN_ID} check embeds fixture-specific knowledge directly in the otherwise generic table-lookup loop. As more failure-scenario sentinels are added (per the pattern this PR establishes), this branch will grow with more ad-hoc string comparisons. Consider registering a dedicated ENTRIES item with an exact-path pattern for the sentinel (ordered before the generic {runId} entry) so findSample stays a pure table lookup and new failure fixtures are added purely via data, not control flow.

♻️ Sketch of a data-driven alternative
+entry('getRun', 'GET', `/runs/${SAMPLE_FAILED_RUN_ID}`, failedRunSample),
 entry('getRun', 'GET', '/runs/{runId}', passedRunSample),
   for (const e of ENTRIES) {
     if (e.method === upper && e.pattern.test(pathOnly)) {
-      const body =
-        e.operationId === 'getRun' && pathOnly === `/runs/${SAMPLE_FAILED_RUN_ID}`
-          ? failedRunSample
-          : e.body(requestBody);
-      return { ...e, body: () => body };
+      const body = e.body(requestBody);
+      return { ...e, body: () => body };
     }
   }

Note: this requires the exact-path entry to be tested/ordered before the generic template so the more specific match wins — worth verifying ENTRIES iteration order and pattern specificity before applying.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/dry-run/samples.ts` around lines 858 - 879, `findSample` is coupling
generic lookup logic to the `SAMPLE_FAILED_RUN_ID` fixture via an inline
`pathOnly === \`/runs/${SAMPLE_FAILED_RUN_ID}\`` check. Move this special case
into the `ENTRIES` data by adding a dedicated exact-path entry for the failed
run sentinel and place it before the generic `{runId}` pattern so it wins during
iteration. Keep `findSample` as a pure table lookup that just selects the first
matching entry and resolves `body` from `ENTRIES` without fixture-specific
branching.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/lib/dry-run/samples.ts`:
- Around line 348-398: `passedRunSample` in `samples.ts` is internally
inconsistent because `stepSummary.total/completed/passedCount` says 8 while the
`steps` array only contains 2 entries. Update `passedRunSample` so the summary
counts match the actual number of step objects, or expand the `steps` array to
the full set implied by `stepSummary`; keep the sample aligned with the
`RunResponse` contract used by `test steps --run-id <id> --dry-run`.

---

Nitpick comments:
In `@src/lib/dry-run/samples.ts`:
- Around line 858-879: `findSample` is coupling generic lookup logic to the
`SAMPLE_FAILED_RUN_ID` fixture via an inline `pathOnly ===
\`/runs/${SAMPLE_FAILED_RUN_ID}\`` check. Move this special case into the
`ENTRIES` data by adding a dedicated exact-path entry for the failed run
sentinel and place it before the generic `{runId}` pattern so it wins during
iteration. Keep `findSample` as a pure table lookup that just selects the first
matching entry and resolves `body` from `ENTRIES` without fixture-specific
branching.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 57f5b497-528a-4c65-aa01-a1b27fcd814f

📥 Commits

Reviewing files that changed from the base of the PR and between 3305dfa and 9179281.

📒 Files selected for processing (3)
  • src/commands/test.test.ts
  • src/lib/dry-run/samples.test.ts
  • src/lib/dry-run/samples.ts

Comment thread src/lib/dry-run/samples.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/lib/dry-run/samples.ts (1)

866-877: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Body is now eagerly computed even when callers never invoke .body().

The change resolves e.body(requestBody) unconditionally on every match, then rebinds it into a closure. For pure/cheap factories this is harmless, but if any entry.body factory has side effects or is expensive, this changes evaluation semantics from lazy (invoked at call site) to eager (invoked inside findSample).

Given the current fixtures are simple literal returns, this is low risk, but worth a quick scan for any factory with side effects.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/dry-run/samples.ts` around lines 866 - 877, The `findSample`
implementation in `src/lib/dry-run/samples.ts` now eagerly evaluates
`e.body(requestBody)` before returning the matched entry, which changes `body`
from lazy to eager execution. Update the matching logic so `body` is only
resolved when callers actually invoke it, or verify and document that every
`ENTRY.body` factory is side-effect free and cheap; use the `findSample` loop
and `ENTRY.body` rebinding as the key spots to inspect.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/lib/dry-run/samples.ts`:
- Around line 866-877: The `findSample` implementation in
`src/lib/dry-run/samples.ts` now eagerly evaluates `e.body(requestBody)` before
returning the matched entry, which changes `body` from lazy to eager execution.
Update the matching logic so `body` is only resolved when callers actually
invoke it, or verify and document that every `ENTRY.body` factory is side-effect
free and cheap; use the `findSample` loop and `ENTRY.body` rebinding as the key
spots to inspect.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 9c984bd0-3bf9-45f3-84fe-fd4891518e1e

📥 Commits

Reviewing files that changed from the base of the PR and between 9179281 and 6c7a0e0.

📒 Files selected for processing (2)
  • src/lib/dry-run/samples.test.ts
  • src/lib/dry-run/samples.ts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Hackathon] dry-run run sample should include a failed run-scoped step

1 participant