Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { ReactNode } from 'react';
import { useEffect, type ReactNode } from 'react';
import { Outlet, createRootRoute, HeadContent, Scripts } from '@tanstack/react-router';

export const Route = createRootRoute({
Expand All @@ -20,6 +20,14 @@ export const Route = createRootRoute({
});

function RootComponent() {
// Mark the document as hydrated so tests can wait for React to attach event
// handlers before clicking. `toBeVisible()` only confirms the SSR HTML is
// rendered; on slow CI runs Playwright can click before hydration completes,
// the onClick handler isn't yet attached, and tests asserting on the
// resulting client-side error time out (see #20641, #20685, #20867).
useEffect(() => {
document.documentElement.setAttribute('data-hydrated', 'true');
}, []);
return (
<RootDocument>
<Outlet />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ test('Sends client-side error to Sentry with auto-instrumentation', async ({ pag

await page.goto(`/`);

// Wait for React to hydrate (see __root.tsx) before clicking — the SSR HTML
// renders the button before the onClick handler is attached, and clicking
// pre-hydration would fire no handler and produce no error.
await page.locator('html[data-hydrated="true"]').waitFor();

await expect(page.locator('button').filter({ hasText: 'Break the client' })).toBeVisible();

await page.locator('button').filter({ hasText: 'Break the client' }).click();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ test('Sends client-side errors through the configured tunnel route', async ({ pa
await page.goto('/');
const pageOrigin = new URL(page.url()).origin;

// Wait for React to hydrate (see __root.tsx) before clicking — the SSR HTML
// renders the button before the onClick handler is attached, and clicking
// pre-hydration would fire no handler and produce no error.
await page.locator('html[data-hydrated="true"]').waitFor();

await expect(page.locator('button').filter({ hasText: 'Break the client' })).toBeVisible();

const managedTunnelResponsePromise = page.waitForResponse(response => {
Expand Down
Loading