Skip to content

Commit c39e1dd

Browse files
add e2e test and fix streaming
1 parent 0d4222a commit c39e1dd

File tree

21 files changed

+699
-31
lines changed

21 files changed

+699
-31
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
node_modules
2+
package-lock.json
3+
yarn.lock
4+
5+
.DS_Store
6+
.cache
7+
.env
8+
.vercel
9+
.output
10+
/build/
11+
/api/
12+
/server/build
13+
/public/build# Sentry Config File
14+
.env.sentry-build-plugin
15+
/test-results/
16+
/playwright-report/
17+
/blob-report/
18+
/playwright/.cache/
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
**/build
2+
**/public
3+
pnpm-lock.yaml
4+
routeTree.gen.ts
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
{
2+
"name": "tanstack-react-start-e2e-query-integration",
3+
"private": true,
4+
"sideEffects": false,
5+
"type": "module",
6+
"scripts": {
7+
"dev": "vite dev --port 3000",
8+
"dev:e2e": "vite dev",
9+
"build": "vite build && tsc --noEmit",
10+
"start": "node .output/server/index.mjs",
11+
"test:e2e": "playwright test --project=chromium"
12+
},
13+
"dependencies": {
14+
"@tanstack/react-query": "^5.66.0",
15+
"@tanstack/react-query-devtools": "^5.66.0",
16+
"@tanstack/react-router": "workspace:^",
17+
"@tanstack/react-router-devtools": "workspace:^",
18+
"@tanstack/react-router-ssr-query": "workspace:^",
19+
"@tanstack/react-start": "workspace:^",
20+
"react": "^19.0.0",
21+
"react-dom": "^19.0.0",
22+
"tailwind-merge": "^2.6.0",
23+
"vite": "^6.3.5",
24+
"zod": "^3.24.2"
25+
},
26+
"devDependencies": {
27+
"@playwright/test": "^1.50.1",
28+
"@tanstack/router-e2e-utils": "workspace:^",
29+
"@types/node": "^22.10.2",
30+
"@types/react": "^19.0.8",
31+
"@types/react-dom": "^19.0.3",
32+
"@vitejs/plugin-react": "^4.3.4",
33+
"autoprefixer": "^10.4.20",
34+
"postcss": "^8.5.1",
35+
"tailwindcss": "^3.4.17",
36+
"typescript": "^5.7.2",
37+
"vite-tsconfig-paths": "^5.1.4"
38+
}
39+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { defineConfig, devices } from '@playwright/test'
2+
import { derivePort } from '@tanstack/router-e2e-utils'
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 && PORT=${PORT} VITE_SERVER_PORT=${PORT} pnpm start`,
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+
})
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export default {
2+
plugins: {
3+
tailwindcss: {},
4+
autoprefixer: {},
5+
},
6+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { queryOptions } from "@tanstack/react-query"
2+
3+
export const makeQueryOptions = (key: string) => queryOptions({
4+
queryKey: ['e2e-test-query-integration', key],
5+
queryFn: async () => {
6+
console.log('fetching query data')
7+
await new Promise<void>((resolve) => {
8+
setTimeout(resolve, 500)
9+
})
10+
const result = typeof window !== 'undefined' ? 'client' : 'server'
11+
console.log('query data result', result)
12+
return result
13+
},
14+
staleTime: Infinity,
15+
})
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
/* eslint-disable */
2+
3+
// @ts-nocheck
4+
5+
// noinspection JSUnusedGlobalSymbols
6+
7+
// This file was automatically generated by TanStack Router.
8+
// You should NOT make any changes in this file as it will be overwritten.
9+
// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.
10+
11+
import { Route as rootRouteImport } from './routes/__root'
12+
import { Route as UseSuspenseQueryRouteImport } from './routes/useSuspenseQuery'
13+
import { Route as UseQueryRouteImport } from './routes/useQuery'
14+
import { Route as IndexRouteImport } from './routes/index'
15+
import { Route as LoaderFetchQueryTypeRouteImport } from './routes/loader-fetchQuery/$type'
16+
17+
const UseSuspenseQueryRoute = UseSuspenseQueryRouteImport.update({
18+
id: '/useSuspenseQuery',
19+
path: '/useSuspenseQuery',
20+
getParentRoute: () => rootRouteImport,
21+
} as any)
22+
const UseQueryRoute = UseQueryRouteImport.update({
23+
id: '/useQuery',
24+
path: '/useQuery',
25+
getParentRoute: () => rootRouteImport,
26+
} as any)
27+
const IndexRoute = IndexRouteImport.update({
28+
id: '/',
29+
path: '/',
30+
getParentRoute: () => rootRouteImport,
31+
} as any)
32+
const LoaderFetchQueryTypeRoute = LoaderFetchQueryTypeRouteImport.update({
33+
id: '/loader-fetchQuery/$type',
34+
path: '/loader-fetchQuery/$type',
35+
getParentRoute: () => rootRouteImport,
36+
} as any)
37+
38+
export interface FileRoutesByFullPath {
39+
'/': typeof IndexRoute
40+
'/useQuery': typeof UseQueryRoute
41+
'/useSuspenseQuery': typeof UseSuspenseQueryRoute
42+
'/loader-fetchQuery/$type': typeof LoaderFetchQueryTypeRoute
43+
}
44+
export interface FileRoutesByTo {
45+
'/': typeof IndexRoute
46+
'/useQuery': typeof UseQueryRoute
47+
'/useSuspenseQuery': typeof UseSuspenseQueryRoute
48+
'/loader-fetchQuery/$type': typeof LoaderFetchQueryTypeRoute
49+
}
50+
export interface FileRoutesById {
51+
__root__: typeof rootRouteImport
52+
'/': typeof IndexRoute
53+
'/useQuery': typeof UseQueryRoute
54+
'/useSuspenseQuery': typeof UseSuspenseQueryRoute
55+
'/loader-fetchQuery/$type': typeof LoaderFetchQueryTypeRoute
56+
}
57+
export interface FileRouteTypes {
58+
fileRoutesByFullPath: FileRoutesByFullPath
59+
fullPaths:
60+
| '/'
61+
| '/useQuery'
62+
| '/useSuspenseQuery'
63+
| '/loader-fetchQuery/$type'
64+
fileRoutesByTo: FileRoutesByTo
65+
to: '/' | '/useQuery' | '/useSuspenseQuery' | '/loader-fetchQuery/$type'
66+
id:
67+
| '__root__'
68+
| '/'
69+
| '/useQuery'
70+
| '/useSuspenseQuery'
71+
| '/loader-fetchQuery/$type'
72+
fileRoutesById: FileRoutesById
73+
}
74+
export interface RootRouteChildren {
75+
IndexRoute: typeof IndexRoute
76+
UseQueryRoute: typeof UseQueryRoute
77+
UseSuspenseQueryRoute: typeof UseSuspenseQueryRoute
78+
LoaderFetchQueryTypeRoute: typeof LoaderFetchQueryTypeRoute
79+
}
80+
81+
declare module '@tanstack/react-router' {
82+
interface FileRoutesByPath {
83+
'/useSuspenseQuery': {
84+
id: '/useSuspenseQuery'
85+
path: '/useSuspenseQuery'
86+
fullPath: '/useSuspenseQuery'
87+
preLoaderRoute: typeof UseSuspenseQueryRouteImport
88+
parentRoute: typeof rootRouteImport
89+
}
90+
'/useQuery': {
91+
id: '/useQuery'
92+
path: '/useQuery'
93+
fullPath: '/useQuery'
94+
preLoaderRoute: typeof UseQueryRouteImport
95+
parentRoute: typeof rootRouteImport
96+
}
97+
'/': {
98+
id: '/'
99+
path: '/'
100+
fullPath: '/'
101+
preLoaderRoute: typeof IndexRouteImport
102+
parentRoute: typeof rootRouteImport
103+
}
104+
'/loader-fetchQuery/$type': {
105+
id: '/loader-fetchQuery/$type'
106+
path: '/loader-fetchQuery/$type'
107+
fullPath: '/loader-fetchQuery/$type'
108+
preLoaderRoute: typeof LoaderFetchQueryTypeRouteImport
109+
parentRoute: typeof rootRouteImport
110+
}
111+
}
112+
}
113+
114+
const rootRouteChildren: RootRouteChildren = {
115+
IndexRoute: IndexRoute,
116+
UseQueryRoute: UseQueryRoute,
117+
UseSuspenseQueryRoute: UseSuspenseQueryRoute,
118+
LoaderFetchQueryTypeRoute: LoaderFetchQueryTypeRoute,
119+
}
120+
export const routeTree = rootRouteImport
121+
._addFileChildren(rootRouteChildren)
122+
._addFileTypes<FileRouteTypes>()
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { QueryClient } from '@tanstack/react-query'
2+
import { createRouter as createTanStackRouter } from '@tanstack/react-router'
3+
import { setupRouterSsrQueryIntegration } from '@tanstack/react-router-ssr-query'
4+
import { routeTree } from './routeTree.gen'
5+
6+
export function createRouter() {
7+
const queryClient = new QueryClient()
8+
const router = createTanStackRouter({
9+
routeTree,
10+
context: { queryClient },
11+
scrollRestoration: true,
12+
defaultPreload: 'intent',
13+
})
14+
setupRouterSsrQueryIntegration({
15+
router,
16+
queryClient,
17+
})
18+
return router
19+
}
20+
21+
declare module '@tanstack/react-router' {
22+
interface Register {
23+
router: ReturnType<typeof createRouter>
24+
}
25+
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/// <reference types="vite/client" />
2+
import {
3+
HeadContent,
4+
Link,
5+
Scripts,
6+
createRootRouteWithContext,
7+
} from '@tanstack/react-router'
8+
import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
9+
import { TanStackRouterDevtoolsInProd } from '@tanstack/react-router-devtools'
10+
import * as React from 'react'
11+
import type { QueryClient } from '@tanstack/react-query'
12+
import appCss from '~/styles/app.css?url'
13+
14+
export const Route = createRootRouteWithContext<{
15+
queryClient: QueryClient
16+
}>()({
17+
head: () => ({
18+
meta: [
19+
{
20+
charSet: 'utf-8',
21+
},
22+
],
23+
links: [{ rel: 'stylesheet', href: appCss }],
24+
}),
25+
shellComponent: RootDocument,
26+
})
27+
28+
function RootDocument({ children }: { children: React.ReactNode }) {
29+
return (
30+
<html>
31+
<head>
32+
<HeadContent />
33+
</head>
34+
<body>
35+
<div className="p-2 flex gap-2 text-lg">
36+
<Link
37+
to="/"
38+
activeProps={{
39+
className: 'font-bold',
40+
}}
41+
>
42+
Home
43+
</Link>{' '}
44+
<Link
45+
to="/loader-fetchQuery/$type"
46+
params={{ type: 'sync' }}
47+
activeProps={{
48+
className: 'font-bold',
49+
}}
50+
>
51+
fetchQuery (sync)
52+
</Link>{' '}
53+
<Link
54+
to="/loader-fetchQuery/$type"
55+
params={{ type: 'async' }}
56+
activeProps={{
57+
className: 'font-bold',
58+
}}
59+
>
60+
fetchQuery (async)
61+
</Link>{' '}
62+
<Link
63+
to="/useQuery"
64+
activeProps={{
65+
className: 'font-bold',
66+
}}
67+
>
68+
useQuery
69+
</Link>{' '}
70+
<Link
71+
to="/useSuspenseQuery"
72+
activeProps={{
73+
className: 'font-bold',
74+
}}
75+
>
76+
useSuspenseQuery
77+
</Link>{' '}
78+
</div>
79+
<hr />
80+
{children}
81+
<TanStackRouterDevtoolsInProd position="bottom-right" />
82+
<ReactQueryDevtools buttonPosition="bottom-left" />
83+
<Scripts />
84+
</body>
85+
</html>
86+
)
87+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { createFileRoute } from '@tanstack/react-router'
2+
3+
export const Route = createFileRoute('/')({
4+
component: Home,
5+
})
6+
7+
function Home() {
8+
return (
9+
<div className="p-2">
10+
<h3>Query Integration E2E tests</h3>
11+
</div>
12+
)
13+
}

0 commit comments

Comments
 (0)