Skip to content

feat: track caught errors and error locations in step traces - #696

Merged
PhenX merged 2 commits into
mainfrom
claude/happy-knuth-hf0f50
Sep 29, 2026
Merged

PhenX merged 2 commits into
mainfrom
claude/happy-knuth-hf0f50

Conversation

@PhenX

@PhenX PhenX commented Sep 29, 2026

Copy link
Copy Markdown
Collaborator

What & why

This change adds support for tracking errors that tests catch and recover from (e.g., probes in try/catch blocks, retried toPass attempts), as well as precise error locations in step traces. The reporter now marks these recovered errors distinctly from fatal failures, allowing the UI to display them as muted rather than as the primary failure.

Key additions:

  • Error locations: Steps now track where errors were thrown (file:line:col), enabling precise error attribution
  • Recovered errors: A new recovered flag marks errors the test caught and continued from, distinguishing them from fatal failures
  • Failure role classification: New stepFailureRoles() function identifies which steps are the actual failure vs. caught errors vs. enclosing steps
  • Code location matching: sameCodeLocation() utility compares error locations across different representations (parsed objects or strings)

The failing step is now defined as the innermost step of the failing chain that carries the execution's own error, not just any error. This allows proper handling of multi-error scenarios where some errors are caught and others are fatal.

How was it tested

  • Added comprehensive unit tests in step-tree.test.ts covering:
    • Caught probe failures with recovery marks
    • Same-message probe failures (multiple caught errors with identical messages)
    • Soft assertion failures
    • Teardown failures after body completion
    • toPass retry failures
    • All test shapes (marked/unmarked, with/without depth)
  • Added fixture data in playwright-steps.ts with real Playwright 1.63 trace examples
  • Added trace fixture data in caught-error-traces.ts for trace parsing tests
  • Updated timeline-rows.test.ts to verify recovered steps are marked correctly
  • Updated trace-parser.test.ts to handle new trace action fields (parentId, location)
  • Updated dom-snapshot.test.ts to test snapshot extraction from runner actions

Checklist

  • PR title follows Conventional Commits (feat: ...)
  • Tests added for new behavior (step failure role classification, recovered error marking)
  • Docs updated in comments and JSDoc for new fields and functions

https://claude.ai/code/session_01MmFBpnCmRPzkjMedY3A6GZ

A test that catches an assertion error and goes on (an optional dialog
probed in a try/catch, a retried toPass attempt) still records that
assertion as an errored step and an errored trace action. The timeline,
the trace evidence, the clues and the AI context all took the first
errored step or action as "the failure", so they pointed at the caught
probe while the headline named the real error.

- Reporter: flattened steps keep where each error was thrown, and a step
  whose error matches none of the test's errors (first line, then
  location) is marked `recovered`. Blob-report imports do the same.
- Core: `failingStepIndex` takes the execution's error text. It skips
  recovered steps, walks each failing chain down through the steps that
  carry its error, prefers the chain thrown where the error text points,
  then one matching the error's first line, else the last failing chain
  of the body. `stepFailureRoles` tells the failing step, the steps
  around it, a second failure (soft assertion, failing teardown) and a
  caught error apart. Headline helpers pass the error through.
- Trace: the failing action is the one whose error matches a test-level
  `error` event, called where its stack points, the innermost of them;
  else the latest errored runner action. Snapshots, the call stack and
  the fallback ARIA tree read the page-side call a runner action drove.
- Timeline: the failing row, the window and the auto-opened section
  follow the fatal step; a caught error is greyed out and marked as
  such, and never counts as a section failure.
- AI context: "Failed Steps" lists the failing chain first and labels
  caught errors; "Steps" and "Actions Leading to Failure" mark them.

Fixes #695

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MmFBpnCmRPzkjMedY3A6GZ
The page at the failing step now sits in the step's own block on the
timeline table (it was a separate full-width row under it), and it adds
the trace's DOM snapshot of the same moment as the screenshot: the
failing action's after-phase DOM next to its after-phase screenshot, the
failure-time DOM next to the run's own failure screenshot.

- `dom-snapshot` and `dom-snapshot-frame` take optional `callId` and
  `phase` query parameters naming the action snapshot to render first,
  falling back to the failure-time one; the demo mirrors them.
- The scaled, sandboxed page render moves out of the page structure card
  into `DomSnapshotFrame` and `useDomSnapshot`, shared by both. The stage
  never sizes its container, so a table cell keeps its width.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MmFBpnCmRPzkjMedY3A6GZ
@github-actions

Copy link
Copy Markdown
Contributor

Coverage Report for Reporter (./packages/reporter)

Status Category Percentage Covered / Total
🔵 Lines 76.47% 3911 / 5114
🔵 Statements 74.91% 4480 / 5980
🔵 Functions 79.66% 752 / 944
🔵 Branches 68.9% 3215 / 4666
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
packages/reporter/src/public/reporter.ts 79.22% 66.97% 75% 83.06% 162-163, 166-167, 172, 186-188, 205-214, 250-251, 313, 332, 425, 429, 433-437, 448, 451-452, 460, 463-464, 473, 476-478, 492-499, 507, 522, 526, 582
Generated in workflow #2278 for commit dd25109 by the Vitest Coverage Report Action

@github-actions

Copy link
Copy Markdown
Contributor

Coverage Report for Application (./apps/application)

Status Category Percentage Covered / Total
🔵 Lines 63.27% 18119 / 28634
🔵 Statements 61.66% 21181 / 34351
🔵 Functions 63.5% 4101 / 6458
🔵 Branches 53.98% 15888 / 29431
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
apps/application/app/composables/useDomSnapshot.ts 0% 0% 0% 0% 34-71
apps/application/app/utils/help-content.ts 100% 100% 100% 100%
apps/application/app/utils/timeline-rows.ts 100% 86.95% 100% 100%
apps/application/server/utils/ai-context.ts 24.2% 19.91% 24.11% 25.33% 82-90, 181-450, 462-463, 465, 466, 467, 468, 469, 501, 516-905, 924-1023, 1057-1256, 1315, 1335, 1381, 1388, 1408, 1450-1632, 1687-1707, 1765-1766, 1769, 1775, 1802, 1813, 1816, 1819-1829, 1839, 1844, 1851, 1861-1871, 1876-1880, 1902-1915, 1972, 1988, 2047, 2069-2137, 2169-3065
apps/application/server/utils/blob-report.ts 91.58% 62.91% 100% 98.82% 146, 155, 180, 205, 212-215, 252, 262, 264, 275, 282, 288, 308, 320, 333, 390, 407, 427, 530
apps/application/server/utils/dom-snapshot-render.ts 95.72% 93.02% 97.61% 97.89% 57, 135, 149, 191, 195, 385, 426, 526, 560, 571
apps/application/server/utils/dom-snapshot.ts 82.3% 72.41% 93.33% 88.76% 63, 76-78, 106, 114, 125, 128, 143, 163, 167, 172, 186, 189, 223, 227, 229, 243, 305-313
apps/application/server/utils/run-json-types.ts 0% 0% 0% 0%
apps/application/server/utils/trace-events.ts 96.96% 78.44% 93.1% 97.91% 216, 276, 378, 392, 436, 573-576, 632
apps/application/server/utils/trace-evidence.ts 42.5% 39.47% 56.66% 43.61% 40-45, 94, 101-102, 109-125, 139-234, 275, 290
apps/application/server/utils/trace-insights.ts 73.35% 63.42% 74.13% 78% 54, 64, 66, 70, 72, 118, 143, 184, 187, 203-204, 231-250, 266, 270, 274, 284, 338, 340, 396, 534, 536, 537, 610, 652, 655, 657, 679, 685, 757-866
apps/application/server/utils/trace-parser.ts 64.95% 63.54% 52.94% 68% 23-92, 126, 237-242
apps/application/shared/failure-timeline.ts 98.02% 86.93% 100% 99.4% 242, 282, 313
apps/application/shared/failure-verdict.ts 95.83% 85.24% 100% 100% 132
apps/application/shared/handlers/failure-clusters.ts 30.18% 28.86% 31.42% 32.12% 31, 54, 81, 145, 211, 280-776, 827, 831
apps/application/shared/handlers/test-cases.ts 66.96% 57.59% 52.45% 74.44% 58, 184-202, 216, 235-238, 257-263, 270-276, 354-365, 385-390, 402-407, 414-430, 462, 564-666, 681, 682-683, 704, 716-728, 752-800, 869-877, 897, 898, 899, 900-918, 935, 942, 1012-1019, 1045, 1075, 1078, 1091-1098, 1105-1106, 1113-1120, 1126, 1145-1155, 1218
Generated in workflow #2278 for commit dd25109 by the Vitest Coverage Report Action

@PhenX
PhenX merged commit aaba845 into main Sep 29, 2026
36 checks passed
@PhenX
PhenX deleted the claude/happy-knuth-hf0f50 branch September 29, 2026 14:19
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.

2 participants