Skip to content

test(browser): port requests and web vitals to span streaming - #24886

Open
msonnb wants to merge 4 commits into
ms/browser-tests-browser-tracingfrom
ms/browser-tests-requests-web-vitals
Open

msonnb wants to merge 4 commits into
ms/browser-tests-browser-tracingfrom
ms/browser-tests-requests-web-vitals

Conversation

@msonnb

@msonnb msonnb commented Sep 30, 2026 •

Copy link
Copy Markdown
Member

Exercise request instrumentation, web vitals, interactions, and user timing with default span streaming. Retain the existing transaction counterparts for fetch, XHR, resource timing, and TTFB as explicitly pinned *-static suites so the migration preserves coverage of both lifecycles. Check RTT as a span attribute on pageload and navigation.

Fixes #24143

@github-actions

github-actions Bot commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

size-limit report 📦

Path Size % Change Change
@sentry/browser 29.6 kB - -
@sentry/browser - with treeshaking flags 27.75 kB - -
@sentry/browser - with treeshaking flags tracing without tracing 27.65 kB - -
@sentry/browser (incl. Tracing) 51.52 kB - -
@sentry/browser (incl. Tracing + Span Streaming) 51.52 kB - -
@sentry/browser (incl. Tracing, Profiling) 54.5 kB - -
@sentry/browser (incl. Tracing, Replay) 91.23 kB - -
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 80.18 kB - -
@sentry/browser (incl. Tracing, Replay with Canvas) 95.93 kB - -
@sentry/browser (incl. Tracing, Replay, Feedback) 108.89 kB - -
@sentry/browser (incl. Feedback) 47.12 kB - -
@sentry/browser (incl. sendFeedback) 34.65 kB - -
@sentry/browser (incl. FeedbackAsync) 39.76 kB - -
@sentry/browser (incl. Metrics) 30.61 kB - -
@sentry/browser (incl. Logs) 30.89 kB - -
@sentry/browser (incl. Metrics & Logs) 31.55 kB - -
@sentry/react 31.43 kB - -
@sentry/react (incl. Tracing) 53.84 kB - -
@sentry/vue 37.55 kB - -
@sentry/vue (incl. Tracing) 54.4 kB - -
@sentry/svelte 29.63 kB - -
@sentry/remix (Remix 3 client bundle) 56.54 kB - -
CDN Bundle 31.33 kB - -
CDN Bundle (incl. Tracing) 52.07 kB - -
CDN Bundle (incl. Logs, Metrics) 33.56 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) 54.03 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) 74.38 kB - -
CDN Bundle (incl. Tracing, Replay) 89.74 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 91.69 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) 95.9 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 97.87 kB - -
CDN Bundle - uncompressed 92.46 kB - -
CDN Bundle (incl. Tracing) - uncompressed 154.77 kB - -
CDN Bundle (incl. Logs, Metrics) - uncompressed 99.04 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 160.72 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 228.98 kB - -
CDN Bundle (incl. Tracing, Replay) - uncompressed 274.89 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 280.83 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 288.59 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 294.52 kB - -
@sentry/nextjs (client) 56.19 kB - -
@sentry/sveltekit (client) 51.9 kB - -
@sentry/core/server 40.65 kB - -
@sentry/core/browser 13.51 kB - -
@sentry/node 145.57 kB +0.01% +4 B 🔺
@sentry/node/import (ESM hook with diagnostics-channel injection) 83.22 kB - -
@sentry/node - without tracing 93.46 kB +0.01% +2 B 🔺
@sentry/node - without channel injection 123.73 kB +0.02% +16 B 🔺
@sentry/aws-serverless 101.69 kB +0.01% +2 B 🔺
@sentry/cloudflare (withSentry) - minified 209.03 kB - -
@sentry/cloudflare (withSentry) 517.8 kB - -

View base workflow run

@msonnb
msonnb changed the base branch from ms/browser-tests-trace-semantics to ms/browser-tests-browser-tracing October 5, 2026 07:28
@msonnb
msonnb added this pull request to stack #24891 October 5, 2026 07:28
@msonnb
msonnb force-pushed the ms/browser-tests-requests-web-vitals branch from a8d6d9c to 83fab7a Compare October 5, 2026 07:41
@msonnb
msonnb force-pushed the ms/browser-tests-requests-web-vitals branch 2 times, most recently from 5a08efb to dc00794 Compare October 5, 2026 13:23
@msonnb
msonnb force-pushed the ms/browser-tests-requests-web-vitals branch 2 times, most recently from b188ce7 to a064fc9 Compare October 7, 2026 11:27
@msonnb
msonnb marked this pull request as ready for review October 7, 2026 12:33
@msonnb
msonnb requested a review from a team as a code owner October 7, 2026 12:33
@msonnb
msonnb requested review from Lms24 and logaretm and removed request for a team October 7, 2026 12:33

@cursor cursor 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.

Stale Bugbot comment from a previous run.

@msonnb
msonnb force-pushed the ms/browser-tests-requests-web-vitals branch from a064fc9 to 3d541db Compare October 7, 2026 12:50

@cursor cursor 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.

Stale Bugbot comment from a previous run.

@msonnb
msonnb force-pushed the ms/browser-tests-requests-web-vitals branch from 3d541db to 0fa7920 Compare October 7, 2026 13:02

@cursor cursor 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.

Stale Bugbot comment from a previous run.

@msonnb
msonnb force-pushed the ms/browser-tests-requests-web-vitals branch from 0fa7920 to 136bc99 Compare October 7, 2026 13:12

@cursor cursor 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.

Stale Bugbot comment from a previous run.

@msonnb
msonnb force-pushed the ms/browser-tests-requests-web-vitals branch from 136bc99 to 4c8dc91 Compare October 7, 2026 13:25

@cursor cursor 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.

Stale Bugbot comment from a previous run.

msonnb and others added 3 commits October 7, 2026 15:37
@msonnb
msonnb force-pushed the ms/browser-tests-requests-web-vitals branch from 4c8dc91 to 52e9455 Compare October 7, 2026 13:37

@cursor cursor 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.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

There are 3 total unresolved issues (including 2 from previous reviews).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 52e9455. Configure here.

Co-Authored-By: GPT-6 <codex@openai.com>
Comment on lines +35 to +36
expect(lcpSpan.attributes[BROWSER_WEB_VITAL_LCP_ELEMENT]).toEqual({ type: 'string', value: 'body > img' });
expect(lcpSpan.attributes[BROWSER_WEB_VITAL_LCP_SIZE]).toEqual({ type: 'integer', value: 107400 });

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Bug: The LCP test is flaky due to a race condition. It removes a guard for known flakiness and uses a strict assertion that can fail on slow CI machines.
Severity: MEDIUM

Suggested Fix

Reintroduce a mechanism to handle the potential flakiness of LCP element reporting. This could involve using a less strict assertion like expect.stringContaining('body > img') or restoring the conditional logic that checks which element was reported as the LCP before asserting.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location:
dev-packages/browser-integration-tests/suites/tracing/metrics/handlers-lcp/test.ts#L35-L36

Potential issue: The test at `handlers-lcp/test.ts` introduces a race condition.
Previously, the test code included a conditional guard to handle flakiness where the
Largest Contentful Paint (LCP) element could be either an image or a button. This guard
has been removed and replaced with a `waitForFunction` call that waits for the LCP size,
but does not guarantee the LCP element has been finalized. A subsequent button click
finalizes the LCP, but a race condition exists where the button itself can be reported
as the LCP element, causing the new, stricter assertion (`.toEqual({ type: 'string',
value: 'body > img' })`) to fail. This is likely to cause intermittent test failures,
especially in resource-constrained CI environments.

Did we get this right? 👍 / 👎 to inform future reviews.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

the previous test clicked the button immediately, now we wait for the image's size to be reported by the LCP handlers

@Lms24 Lms24 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

m: I'd prefer keeping one transaction test that asserts on the respective web vital being added as a measurement to the pageload span.

Comment on lines -18 to -23
// A plain (non-streamed) `beforeSendSpan` operates on the v1 `SpanJSON`. INP is sent as a v2 span,
// so this verifies the static callback still runs and its changes are carried into the v2 span.
beforeSendSpan: Sentry.withStaticSpan(span => {
if (span.op === 'ui.interaction.click') {
span.description = 'scrubbed';
span.data['custom.attribute'] = 'from-before-send-span';

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

m: I think we should keep this test as "static", since the main objective here is asserting that the INP span goes through beforeSendSpan in the v1 format when span streaming is disabled.

So once we remove transactions, this test can be dropped

Comment on lines +12 to +22
'records connection RTT on pageload and navigation spans',
async ({ getLocalTestUrl, page, browserName }) => {
sentryTest.skip(shouldSkipTracingTest() || browserName !== 'chromium');
const url = await getLocalTestUrl({ testDir: __dirname });
await page.goto(url);

const pageloadRequest = envelopeRequestParser(await pageloadRequestPromise) as Event;

const navigationRequestPromise = waitForTransactionRequest(
page,
event => event.contexts?.trace?.op === 'navigation',
);
await page.goto(`${url}#foo`);

const navigationRequest = envelopeRequestParser(await navigationRequestPromise) as Event;

expect(pageloadRequest.contexts?.trace?.op).toBe('pageload');
expect(navigationRequest.contexts?.trace?.op).toBe('navigation');
const [pageload] = await waitForStreamedSpanAndTraceHeaderOnUrl(page, url);
const [navigation] = await waitForStreamedSpanAndTraceHeaderOnUrl(page, `${url}#foo`);

expect(pageloadRequest.measurements?.['connection.rtt']?.value).toBeDefined();
expect(navigationRequest.measurements?.['connection.rtt']).toBeUndefined();
expect(pageload.attributes[NETWORK_CONNECTION_RTT]).toEqual({ type: 'integer', value: 0 });
expect(navigation.attributes[NETWORK_CONNECTION_RTT]).toEqual(pageload.attributes[NETWORK_CONNECTION_RTT]);
expect(navigation.attributes[BROWSER_WEB_VITAL_FCP_VALUE]).toBeUndefined();
expect(navigation.attributes[BROWSER_WEB_VITAL_TTFB_VALUE]).toBeUndefined();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

hmm actually not sure if sending connction.rtt on navigation spans is an SDK bug or expected behaviour now? probably worth looking into. if it's a bug, I'm also fine with merging the test as-is and fixing it in a follow-up.

expect(streamSpan.end_timestamp).toBeGreaterThan(streamSpan.start_timestamp);
expect(streamSpan.parent_span_id).toBe(requestSpan.parent_span_id);
expect(streamSpan.trace_id).toBe(requestSpan.trace_id);
expect(streamSpan.end_timestamp).toBeGreaterThanOrEqual(streamSpan.start_timestamp);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

l: any reason this assertion got weaker?

Suggested change
expect(streamSpan.end_timestamp).toBeGreaterThanOrEqual(streamSpan.start_timestamp);
expect(streamSpan.end_timestamp).toBeGreaterThan(streamSpan.start_timestamp);

});

expect(requestSpan?.data).not.toHaveProperty('url.fragment');
expect(requestSpan?.attributes).not.toHaveProperty('url.fragment');

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

m: TIL that this check actually asserts that attributes.url.fragment doesn't exist, instead of attributes['url.fragment']. I had no idea 😬

Turns out the correct syntax here is

Suggested change
expect(requestSpan?.attributes).not.toHaveProperty('url.fragment');
expect(requestSpan?.attributes).not.toHaveProperty(['url.fragment']);

Would be amazing if you could go over our tests and check for this pattern. I'm pretty sure we use this more often. But of course as a follow up!

EDIT: Looks like this is "just" a playwright thing. Vitest asserts on the whole key.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This branch has not been deployed

No deployments
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.

browser-integration-tests: port request and web vitals suites to span streaming

3 participants