test(e2e): Port React Router E2E test apps to span streaming - #23839
test(e2e): Port React Router E2E test apps to span streaming#23839andreiborza wants to merge 1 commit into
Conversation
Removes the `traceLifecycle: 'static'` pin from the 17 React Router E2E test applications and rewrites their specs against streamed span v2 payloads. Adds `react-router-7-framework-static` as a copy of `react-router-7-framework` that keeps the static trace lifecycle, so that path stays covered. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 3 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 3ea1d9b. Configure here.
| getSpanOp(span) === 'resource.script' && | ||
| span.attributes['sentry.origin']?.value === 'auto.resource.browser.metrics', | ||
| ); | ||
| expect(resourceSpans.length).toBeGreaterThanOrEqual(2); |
There was a problem hiding this comment.
Lazy navigation counts pageload scripts
Medium Severity
collectStreamedSpans is started before page.goto('/'), so the later resource.script filter includes pageload bundle spans as well as lazy-navigation chunks. The toBeGreaterThanOrEqual(2) check can pass even when navigation never emits those lazy-route spans, so a regression in lazy navigation instrumentation would go unnoticed. Flagged because the review guidelines require tests to actually cover the behaviour they claim to check.
Triggered by project rule: PR Review Guidelines for Cursor Bot
Reviewed by Cursor Bugbot for commit 3ea1d9b. Configure here.
| await linkElement.click(); | ||
|
|
||
| const spans = await spansPromise; | ||
| const navigationSpan = spans.find(span => span.is_segment)!; |
There was a problem hiding this comment.
Wrong segment picked for navigation
Medium Severity
The wait predicate requires a navigation segment, but the span under test is then selected with spans.find(span => span.is_segment). That envelope can also contain the still-finishing pageload segment, especially here because the click is not sequenced after pageload. Memory-router is most exposed because pageload and navigation share the name /user/:id. Flagged from the review guidelines on flaky waits that are not unique enough when telemetry can arrive in arbitrary order.
Additional Locations (2)
Triggered by project rule: PR Review Guidelines for Cursor Bot
Reviewed by Cursor Bugbot for commit 3ea1d9b. Configure here.
| const childSpans = spans.filter( | ||
| span => !span.is_segment && !(span.attributes['url.full']?.value as string | undefined)?.includes('favicon'), | ||
| ); | ||
| expect(childSpans).toEqual([]); |
There was a problem hiding this comment.
Child-span absence checked too narrowly
Medium Severity
These tests expect navigation to have no child spans, but they only inspect the single envelope that contains the navigation segment. Streamed children flush as they end, often in earlier envelopes, so unexpected children would not be seen and the empty-array assertion would still pass. Flagged because the review guidelines call out relaxed negative assertions that do not actually prove something is absent from the payload.
Additional Locations (2)
Triggered by project rule: PR Review Guidelines for Cursor Bot
Reviewed by Cursor Bugbot for commit 3ea1d9b. Configure here.
|
Superseded by a stack of smaller PRs, same change split by app group:
The top of the stack reproduces this diff exactly. |
size-limit report 📦
|


What
Ports the 17 React Router E2E test applications to span streaming and adds
react-router-7-framework-staticto keep static trace lifecycle coverage.traceLifecycle: 'static'pin from everySentry.initin the 17 appswaitForStreamedSpan/collectStreamedSpans,span.name,getSpanOp,span.attributes)SerializedStreamedSpanfrom@sentry-internal/test-utilsWhy
Span streaming is the default now, so the E2E suite has to exercise it. A few assertions could not carry over unchanged: LCP is a separate
ui.webvital.lcpspan instead oflcp.*attributes on the pageload span, the navigator attributes are renamed (device.memory.estimated_capacity,device.processor_count,network.connection.effective_type,browser.performance.*), mysql spans are named after the query summary,http.clientspans carry only the domain, and spans have no breadcrumbs or tags. Those tests now assert on the attribute that still identifies the case. The static copy drops thelatestbuild variant so it adds one CI job, not two.Closes: #23798