Skip to content

Commit c5b3f54

Browse files
authoredJan 31, 2025··
test: e2e test for sentry integration (#3291)
* test: e2e test for sentry integration * fix: use the fixed sentry integration * feat: make sure we have no console errors * chore: turn off actually sending events to sentry this avoids a browser log error, which we check for in the test
1 parent d50d291 commit c5b3f54

13 files changed

+651
-19
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
node_modules
2+
.DS_Store
3+
dist
4+
dist-ssr
5+
*.local
6+
7+
/test-results/
8+
/playwright-report/
9+
/blob-report/
10+
/playwright/.cache/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<title>Vite App</title>
7+
</head>
8+
<body>
9+
<div id="app"></div>
10+
<script type="module" src="/src/main.tsx"></script>
11+
</body>
12+
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"name": "tanstack-router-e2e-sentry-integration",
3+
"private": true,
4+
"type": "module",
5+
"scripts": {
6+
"dev": "vite --port 3000",
7+
"dev:e2e": "vite",
8+
"build": "vite build && tsc --noEmit",
9+
"serve": "vite preview",
10+
"start": "vite",
11+
"test:e2e": "playwright test --project=chromium"
12+
},
13+
"dependencies": {
14+
"@sentry/react": "^8.53.0",
15+
"@sentry/tracing": "^7.120.3",
16+
"@sentry/vite-plugin": "^3.1.1",
17+
"@tanstack/react-router": "workspace:^",
18+
"@tanstack/router-devtools": "workspace:^",
19+
"react": "^18.2.0",
20+
"react-dom": "^18.2.0",
21+
"redaxios": "^0.5.1",
22+
"postcss": "^8.5.1",
23+
"autoprefixer": "^10.4.20",
24+
"tailwindcss": "^3.4.17"
25+
},
26+
"devDependencies": {
27+
"@playwright/test": "^1.50.0",
28+
"@types/react": "^18.2.47",
29+
"@types/react-dom": "^18.2.18",
30+
"@vitejs/plugin-react": "^4.3.4",
31+
"vite": "^6.0.11"
32+
}
33+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { defineConfig, devices } from '@playwright/test'
2+
import { derivePort } from '../../utils.js'
3+
import packageJson from './package.json' with { type: 'json' }
4+
5+
const PORT = derivePort(packageJson.name)
6+
const baseURL = `http://localhost:${PORT}`
7+
/**
8+
* See https://playwright.dev/docs/test-configuration.
9+
*/
10+
export default defineConfig({
11+
testDir: './tests',
12+
workers: 1,
13+
14+
reporter: [['line']],
15+
16+
use: {
17+
/* Base URL to use in actions like `await page.goto('/')`. */
18+
baseURL,
19+
},
20+
21+
webServer: {
22+
command: `VITE_SERVER_PORT=${PORT} pnpm build && VITE_SERVER_PORT=${PORT} pnpm start --port ${PORT}`,
23+
url: baseURL,
24+
reuseExistingServer: !process.env.CI,
25+
stdout: 'pipe',
26+
},
27+
28+
projects: [
29+
{
30+
name: 'chromium',
31+
use: { ...devices['Desktop Chrome'] },
32+
},
33+
],
34+
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export default {
2+
plugins: {
3+
tailwindcss: {},
4+
autoprefixer: {},
5+
},
6+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import ReactDOM from 'react-dom/client'
2+
import * as Sentry from '@sentry/react'
3+
import {
4+
Link,
5+
Outlet,
6+
RouterProvider,
7+
createRootRoute,
8+
createRoute,
9+
createRouter,
10+
} from '@tanstack/react-router'
11+
import { TanStackRouterDevtools } from '@tanstack/router-devtools'
12+
import './styles.css'
13+
14+
const rootRoute = createRootRoute({
15+
component: RootComponent,
16+
notFoundComponent: () => {
17+
return (
18+
<div>
19+
<p>This is the notFoundComponent configured on root route</p>
20+
<Link to="/">Start Over</Link>
21+
</div>
22+
)
23+
},
24+
})
25+
26+
function RootComponent() {
27+
return (
28+
<>
29+
<div className="p-2 flex gap-2 text-lg border-b">
30+
<Link
31+
to="/"
32+
activeProps={{
33+
className: 'font-bold',
34+
}}
35+
activeOptions={{ exact: true }}
36+
>
37+
Home
38+
</Link>
39+
</div>
40+
<Outlet />
41+
<TanStackRouterDevtools position="bottom-right" />
42+
</>
43+
)
44+
}
45+
const indexRoute = createRoute({
46+
getParentRoute: () => rootRoute,
47+
path: '/',
48+
component: IndexComponent,
49+
})
50+
51+
function IndexComponent() {
52+
return (
53+
<div className="p-2">
54+
<h3>Welcome Home!</h3>
55+
</div>
56+
)
57+
}
58+
59+
const routeTree = rootRoute.addChildren([indexRoute])
60+
61+
// Set up a Router instance
62+
const router = createRouter({
63+
routeTree,
64+
defaultPreload: 'intent',
65+
defaultStaleTime: 5000,
66+
})
67+
68+
// Register things for typesafety
69+
declare module '@tanstack/react-router' {
70+
interface Register {
71+
router: typeof router
72+
}
73+
}
74+
75+
Sentry.init({
76+
dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0',
77+
integrations: [Sentry.tanstackRouterBrowserTracingIntegration(router)],
78+
transport: () => ({
79+
send: (): Promise<any> => Promise.resolve(),
80+
flush: () => Promise.resolve(true),
81+
}),
82+
tracesSampleRate: 0.2,
83+
sendClientReports: false,
84+
})
85+
86+
const rootElement = document.getElementById('app')!
87+
88+
if (!rootElement.innerHTML) {
89+
const root = ReactDOM.createRoot(rootElement)
90+
91+
root.render(<RouterProvider router={router} />)
92+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
@tailwind base;
2+
@tailwind components;
3+
@tailwind utilities;
4+
5+
html {
6+
color-scheme: light dark;
7+
}
8+
* {
9+
@apply border-gray-200 dark:border-gray-800;
10+
}
11+
body {
12+
@apply bg-gray-50 text-gray-950 dark:bg-gray-900 dark:text-gray-200;
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/** @type {import('tailwindcss').Config} */
2+
export default {
3+
content: ['./src/**/*.{js,jsx,ts,tsx}', './index.html'],
4+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { expect } from '@playwright/test'
2+
3+
import { test } from './fixture'
4+
5+
test.beforeEach(async ({ page }) => {
6+
await page.goto('/')
7+
})
8+
9+
test('should load', async ({ page }) => {
10+
await expect(page.getByRole('heading')).toContainText('Welcome Home!')
11+
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { test as base, expect } from '@playwright/test'
2+
3+
export interface TestFixtureOptions {
4+
whitelistErrors: Array<RegExp | string>
5+
}
6+
export const test = base.extend<TestFixtureOptions>({
7+
whitelistErrors: [[], { option: true }],
8+
page: async ({ page, whitelistErrors }, use) => {
9+
const errorMessages: Array<string> = []
10+
page.on('console', (m) => {
11+
if (m.type() === 'error') {
12+
const text = m.text()
13+
for (const whitelistError of whitelistErrors) {
14+
if (
15+
(typeof whitelistError === 'string' &&
16+
text.includes(whitelistError)) ||
17+
(whitelistError instanceof RegExp && whitelistError.test(text))
18+
) {
19+
return
20+
}
21+
}
22+
errorMessages.push(text)
23+
}
24+
})
25+
await use(page)
26+
expect(errorMessages).toEqual([])
27+
},
28+
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"compilerOptions": {
3+
"strict": true,
4+
"esModuleInterop": true,
5+
"jsx": "react-jsx",
6+
"target": "ESNext",
7+
"moduleResolution": "Bundler",
8+
"module": "ESNext",
9+
"resolveJsonModule": true,
10+
"allowJs": true,
11+
"skipLibCheck": true
12+
},
13+
"exclude": ["node_modules", "dist"]
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { defineConfig } from 'vite'
2+
import react from '@vitejs/plugin-react'
3+
import { sentryVitePlugin } from '@sentry/vite-plugin'
4+
5+
// https://vitejs.dev/config/
6+
export default defineConfig({
7+
plugins: [react(), sentryVitePlugin()],
8+
})

‎pnpm-lock.yaml

+386-19
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)
Please sign in to comment.