Skip to content

ref(browser-tests): Add waitForMetricRequest helper#20002

Open
logaretm wants to merge 1 commit intodevelopfrom
feat/refactor-wait-for-metrics
Open

ref(browser-tests): Add waitForMetricRequest helper#20002
logaretm wants to merge 1 commit intodevelopfrom
feat/refactor-wait-for-metrics

Conversation

@logaretm
Copy link
Member

@logaretm logaretm commented Mar 26, 2026

Summary

  • Adds a shared waitForMetricRequest helper to browser integration test utils, following the same page.waitForRequest pattern as waitForErrorRequest, waitForTransactionRequest, etc.
  • Refactors element timing tests to use waitForMetricRequest instead of a custom createMetricCollector with polling-based waitForIdentifiers
  • The new helper accumulates SerializedMetric[] across envelope requests and resolves when the callback returns true for the full collected set

Closes #20005 (added automatically)

…ent timing tests

Replace custom createMetricCollector/waitForIdentifiers polling pattern
with a shared waitForMetricRequest helper that matches existing waitFor
patterns (waitForErrorRequest, waitForTransactionRequest, etc.).

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Copilot AI review requested due to automatic review settings March 26, 2026 19:38
@github-actions
Copy link
Contributor

github-actions bot commented Mar 26, 2026

Semver Impact of This PR

🟢 Patch (bug fixes)

📋 Changelog Preview

This is how your changes will appear in the changelog.
Entries from this PR are highlighted with a left border (blockquote style).


New Features ✨

  • (browser) Replace element timing spans with metrics by logaretm in #19869
  • (node) Add nodeRuntimeMetricsIntegration by chargome in #19923
  • (nuxt) Support parametrized SSR routes in Nuxt 5 by s1gr1d in #19977

Bug Fixes 🐛

  • (e2e) Pin @opentelemetry/api to 1.9.0 in ts3.8 test app by logaretm in #19992
  • (node) Ensure startNewTrace propagates traceId in OTel environments by logaretm in #19963
  • (opentelemetry) Convert seconds timestamps in span.end() to milliseconds by logaretm in #19958

Documentation 📚

  • (release) Update publishing-a-release.md by nicohrubec in #19982

Internal Changes 🔧

Core

  • Introduce instrumented method registry for AI integrations by nicohrubec in #19981
  • Consolidate getOperationName into one shared utility by nicohrubec in #19971

Other

  • (browser-tests) Add waitForMetricRequest helper by logaretm in #20002
  • (deno) Expand Deno E2E test coverage by chargome in #19957

🤖 This preview updates automatically when you update the PR.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a reusable Playwright helper to await and collect metrics from Sentry envelope requests, and refactors the element timing browser integration tests to use this helper instead of custom request listeners + polling.

Changes:

  • Added waitForMetricRequest(page, callback?) to accumulate SerializedMetric[] across trace_metric envelope requests and resolve once the callback condition is met.
  • Refactored element timing metrics tests to use waitForMetricRequest (removing the bespoke collector/polling loop).

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
dev-packages/browser-integration-tests/utils/helpers.ts Introduces waitForMetricRequest to parse metric containers from envelopes and accumulate metrics until a condition is satisfied.
dev-packages/browser-integration-tests/suites/tracing/metrics/element-timing/test.ts Replaces custom metric collection + polling with waitForMetricRequest in pageload and navigation scenarios.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 86 to +91
await page.goto(url);

// Wait for pageload element timing metrics to arrive before navigating
await collector.waitForIdentifiers(['image-fast', 'text1']);

// Reset so we only capture post-navigation metrics
collector.reset();
await waitForMetricRequest(page, metrics =>
metrics.some(m => m.name === 'ui.element.render_time' && getIdentifier(m) === 'image-fast'),
);
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

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

waitForMetricRequest only observes future requests. In this test it’s awaited after page.goto(url), so the pageload metric envelope could already have been sent during navigation, leading to a hang/timeout. Create the waitForMetricRequest(...) promise before calling page.goto, and await them together (similar to the first test).

Copilot uses AI. Check for mistakes.
Comment on lines 93 to +100
// Trigger navigation
await page.locator('#button1').click();

// Wait for navigation element timing metrics
await collector.waitForIdentifiers(['navigation-image', 'navigation-text']);
const navigationMetrics = await waitForMetricRequest(page, metrics => {
const seen = new Set(metrics.filter(m => m.name === 'ui.element.render_time').map(getIdentifier));
return seen.has('navigation-image') && seen.has('navigation-text');
});
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

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

waitForMetricRequest is started after the click. If the click-triggered navigation flushes metrics quickly (or if Playwright waits for navigation during click()), the relevant envelope request can happen before the waiter is registered, making this flaky. Start waitForMetricRequest(...) before click() and await both (e.g. via Promise.all).

Copilot uses AI. Check for mistakes.
@github-actions
Copy link
Contributor

size-limit report 📦

⚠️ Warning: Base artifact is not the latest one, because the latest workflow run is not done yet. This may lead to incorrect results. Try to re-run all tests to get up to date results.

Path Size % Change Change
@sentry/browser 25.69 kB +0.2% +49 B 🔺
@sentry/browser - with treeshaking flags 24.17 kB +0.14% +33 B 🔺
@sentry/browser (incl. Tracing) 42.17 kB -1.04% -443 B 🔽
@sentry/browser (incl. Tracing, Profiling) 46.79 kB -1.03% -485 B 🔽
@sentry/browser (incl. Tracing, Replay) 80.98 kB -0.55% -440 B 🔽
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 70.6 kB -0.57% -398 B 🔽
@sentry/browser (incl. Tracing, Replay with Canvas) 85.7 kB -0.49% -422 B 🔽
@sentry/browser (incl. Tracing, Replay, Feedback) 97.97 kB -0.42% -406 B 🔽
@sentry/browser (incl. Feedback) 42.48 kB +0.08% +30 B 🔺
@sentry/browser (incl. sendFeedback) 30.35 kB +0.15% +44 B 🔺
@sentry/browser (incl. FeedbackAsync) 35.4 kB +0.12% +39 B 🔺
@sentry/browser (incl. Metrics) 26.96 kB +0.14% +37 B 🔺
@sentry/browser (incl. Logs) 27.1 kB +0.12% +32 B 🔺
@sentry/browser (incl. Metrics & Logs) 27.78 kB +0.15% +39 B 🔺
@sentry/react 27.45 kB +0.22% +58 B 🔺
@sentry/react (incl. Tracing) 44.52 kB -0.96% -429 B 🔽
@sentry/vue 30.13 kB +0.16% +46 B 🔺
@sentry/vue (incl. Tracing) 44.08 kB -0.92% -405 B 🔽
@sentry/svelte 25.7 kB +0.16% +40 B 🔺
CDN Bundle 28.39 kB +0.41% +114 B 🔺
CDN Bundle (incl. Tracing) 43.2 kB -0.72% -311 B 🔽
CDN Bundle (incl. Logs, Metrics) 29.76 kB +2.12% +617 B 🔺
CDN Bundle (incl. Tracing, Logs, Metrics) 44.25 kB -0.25% -107 B 🔽
CDN Bundle (incl. Replay, Logs, Metrics) 68.56 kB +0.52% +348 B 🔺
CDN Bundle (incl. Tracing, Replay) 80.08 kB -0.32% -253 B 🔽
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 81.16 kB -0.1% -74 B 🔽
CDN Bundle (incl. Tracing, Replay, Feedback) 85.62 kB -0.3% -254 B 🔽
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 86.67 kB -0.11% -95 B 🔽
CDN Bundle - uncompressed 82.93 kB +0.37% +304 B 🔺
CDN Bundle (incl. Tracing) - uncompressed 128.07 kB -0.39% -489 B 🔽
CDN Bundle (incl. Logs, Metrics) - uncompressed 87.07 kB +1.85% +1.58 kB 🔺
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 131.48 kB +0.05% +55 B 🔺
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 210.06 kB +0.45% +934 B 🔺
CDN Bundle (incl. Tracing, Replay) - uncompressed 244.95 kB -0.19% -464 B 🔽
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 248.34 kB +0.04% +80 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 257.86 kB -0.18% -464 B 🔽
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 261.25 kB +0.04% +80 B 🔺
@sentry/nextjs (client) 46.93 kB -0.93% -438 B 🔽
@sentry/sveltekit (client) 42.67 kB -0.94% -401 B 🔽
@sentry/node-core 56.51 kB +0.3% +165 B 🔺
@sentry/node 173.55 kB +0.23% +392 B 🔺
@sentry/node - without tracing 96.54 kB +0.2% +192 B 🔺
@sentry/aws-serverless 113.54 kB +0.18% +201 B 🔺

View base workflow run

* and resolves when the callback returns true for the full set of collected metrics.
* If no callback is provided, resolves on the first request containing metrics.
*/
export function waitForMetricRequest(
Copy link
Member

Choose a reason for hiding this comment

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

super-l: given we return Promise<SerializedMetric[]>, wdyt about just calling this waitForMetrics? I went with this pattern for streamed spans (example, though your collection mechanism is much more sophisticated :D).

Besides, I think the waitForErrorRequest et al. helpers actually return a Promise<Request<Event>> which was a bit cumbersome to work with in most cases. So I personally prefer this pattern of directly returning the metrics much more.

No strong feelings, just a suggestion!


// Reset so we only capture post-navigation metrics
collector.reset();
await waitForMetricRequest(page, metrics =>
Copy link
Member

Choose a reason for hiding this comment

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

m: This is a valid catch from copilot: we should start listening for metrics before going to the URL (or clicking below) and after the respective action await the promise.

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.

ref(browser-tests): Add waitForMetricRequest helper

3 participants