diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-tasks-and-animation-frame-enabled-static/test.ts b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-tasks-and-animation-frame-enabled-static/test.ts index 5881bf8b3ba0..72fce94d9815 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-tasks-and-animation-frame-enabled-static/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-tasks-and-animation-frame-enabled-static/test.ts @@ -10,7 +10,12 @@ import { import type { Route } from '@playwright/test'; import { expect } from '@playwright/test'; import { sentryTest } from '../../../../utils/fixtures'; -import { envelopeRequestParser, shouldSkipTracingTest, waitForTransactionRequest } from '../../../../utils/helpers'; +import { + envelopeRequestParser, + shouldSkipTracingTest, + waitForNextFrame, + waitForTransactionRequest, +} from '../../../../utils/helpers'; sentryTest( 'should capture long animation frame for top-level script.', @@ -83,8 +88,11 @@ sentryTest( await page.goto(url); - // trigger long animation frame function - await page.getByRole('button').click(); + // Separate mousedown and click into different frames so LoAF reports the click handler. + await page.getByRole('button').hover(); + await page.mouse.down(); + await waitForNextFrame(page); + await page.mouse.up(); const eventData = envelopeRequestParser(await promise); diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-tasks-and-animation-frame-enabled/test.ts b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-tasks-and-animation-frame-enabled/test.ts index 6a2638a61c45..93abdb679273 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-tasks-and-animation-frame-enabled/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-tasks-and-animation-frame-enabled/test.ts @@ -9,7 +9,7 @@ import { import type { Route } from '@playwright/test'; import { expect } from '@playwright/test'; import { sentryTest } from '../../../../utils/fixtures'; -import { shouldSkipTracingTest } from '../../../../utils/helpers'; +import { shouldSkipTracingTest, waitForNextFrame } from '../../../../utils/helpers'; import { collectStreamedSpans, getSpanOp, waitForStreamedSpan } from '../../../../utils/spanUtils'; sentryTest( @@ -83,8 +83,11 @@ sentryTest('captures long animation frame span for event listener.', async ({ br await page.goto(url); - // trigger long animation frame function - await page.getByRole('button').click(); + // Separate mousedown and click into different frames so LoAF reports the click handler. + await page.getByRole('button').hover(); + await page.mouse.down(); + await waitForNextFrame(page); + await page.mouse.up(); const pageloadSpan = await pageloadSpanPromise; await page.evaluate(() => (window as any).Sentry.flush()); diff --git a/dev-packages/browser-integration-tests/utils/helpers.ts b/dev-packages/browser-integration-tests/utils/helpers.ts index 90b3deae3cb9..60df3fd96eb2 100644 --- a/dev-packages/browser-integration-tests/utils/helpers.ts +++ b/dev-packages/browser-integration-tests/utils/helpers.ts @@ -564,6 +564,15 @@ export async function waitForLcpCandidate(page: Page, selector: string): Promise }); } +/** + * Resolves after the current frame has been presented (double rAF). + */ +export async function waitForNextFrame(page: Page): Promise { + await page.evaluate( + () => new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(() => resolve()))), + ); +} + export async function hidePage(page: Page, interactionSelector?: string): Promise { // web-vitals processes an interaction's event entries in `requestIdleCallback(..., { timeout: // 1000 })`, and Chromium only reaches idle here once that timeout elapses. Hiding before that