diff --git a/dev-packages/e2e-tests/test-applications/hydrogen-react-router-7/tests/client-errors.test.ts b/dev-packages/e2e-tests/test-applications/hydrogen-react-router-7/tests/client-errors.test.ts index a14347cdc519..db87e3c0b11b 100644 --- a/dev-packages/e2e-tests/test-applications/hydrogen-react-router-7/tests/client-errors.test.ts +++ b/dev-packages/e2e-tests/test-applications/hydrogen-react-router-7/tests/client-errors.test.ts @@ -1,13 +1,22 @@ import { expect, test } from '@playwright/test'; -import { waitForError } from '@sentry-internal/test-utils'; +import { waitForError, waitForTransaction } from '@sentry-internal/test-utils'; test('Sends a client-side exception to Sentry', async ({ page }) => { + // The pageload transaction only completes once the client SDK and the router have hydrated. + // Awaiting it before clicking guarantees the button's onClick handler is attached — a click that + // lands before hydration would do nothing, and the exception would never be captured. + const pageloadTransactionPromise = waitForTransaction('hydrogen-react-router-7', transactionEvent => { + return transactionEvent.contexts?.trace?.op === 'pageload' && transactionEvent.transaction === '/'; + }); + const errorPromise = waitForError('hydrogen-react-router-7', errorEvent => { return errorEvent.exception?.values?.[0].value === 'I am an error!'; }); await page.goto('/'); + await pageloadTransactionPromise; + const exceptionButton = page.locator('id=exception-button'); await exceptionButton.click(); @@ -17,12 +26,19 @@ test('Sends a client-side exception to Sentry', async ({ page }) => { }); test('Sends a client-side ErrorBoundary exception to Sentry', async ({ page }) => { + // Wait for hydration (see above) before clicking, so the button's onClick handler is attached. + const pageloadTransactionPromise = waitForTransaction('hydrogen-react-router-7', transactionEvent => { + return transactionEvent.contexts?.trace?.op === 'pageload' && transactionEvent.transaction === '/client-error'; + }); + const errorPromise = waitForError('hydrogen-react-router-7', errorEvent => { return errorEvent.exception?.values?.[0].value === 'Sentry React Component Error'; }); await page.goto('/client-error'); + await pageloadTransactionPromise; + const throwButton = page.locator('id=throw-on-click'); await throwButton.click(); diff --git a/dev-packages/e2e-tests/test-applications/hydrogen-react-router-7/tests/client-transactions.test.ts b/dev-packages/e2e-tests/test-applications/hydrogen-react-router-7/tests/client-transactions.test.ts index 1adb44011d07..a23e49338f2c 100644 --- a/dev-packages/e2e-tests/test-applications/hydrogen-react-router-7/tests/client-transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/hydrogen-react-router-7/tests/client-transactions.test.ts @@ -14,12 +14,22 @@ test('Sends a pageload transaction to Sentry', async ({ page }) => { }); test('Sends a navigation transaction to Sentry', async ({ page }) => { + // Wait for the initial pageload transaction first. This ensures the client SDK and router are fully + // hydrated before we click the link. Clicking before hydration completes makes the `` behave + // like a plain anchor, triggering a full page navigation (a `pageload` transaction) instead of a + // client-side `navigation` one, which makes this test flaky. + const pageloadTransactionPromise = waitForTransaction('hydrogen-react-router-7', transactionEvent => { + return transactionEvent.contexts?.trace?.op === 'pageload' && transactionEvent.transaction === '/'; + }); + const transactionPromise = waitForTransaction('hydrogen-react-router-7', transactionEvent => { return transactionEvent.contexts?.trace?.op === 'navigation' && transactionEvent.transaction === '/user/:id'; }); await page.goto('/'); + await pageloadTransactionPromise; + const linkElement = page.locator('id=navigation'); await linkElement.click();