Skip to content

Commit 07aba84

Browse files
committed
test(solid-router): generator-cli-only
1 parent 40e3a6b commit 07aba84

25 files changed

+745
-0
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
node_modules
2+
.DS_Store
3+
dist
4+
dist-hash
5+
dist-ssr
6+
*.local
7+
8+
/test-results/
9+
/playwright-report/
10+
/blob-report/
11+
/playwright/.cache/
Lines changed: 12 additions & 0 deletions
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>
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"name": "tanstack-solid-router-e2e-react-generator-cli-only",
3+
"private": true,
4+
"type": "module",
5+
"scripts": {
6+
"dev": "tsr generate && vite --port 3000",
7+
"dev:e2e": "tsr generate && vite",
8+
"build": "tsr generate && vite build && tsc --noEmit",
9+
"serve": "vite preview",
10+
"start": "tsr generate && vite",
11+
"test:e2e": "rm -rf port*.txt; playwright test --project=chromium"
12+
},
13+
"dependencies": {
14+
"@tailwindcss/postcss": "^4.1.15",
15+
"@tanstack/solid-router": "workspace:^",
16+
"@tanstack/solid-router-devtools": "workspace:^",
17+
"@tanstack/router-cli": "workspace:^",
18+
"postcss": "^8.5.1",
19+
"solid-js": "^1.9.9",
20+
"redaxios": "^0.5.1",
21+
"tailwindcss": "^4.1.15"
22+
},
23+
"devDependencies": {
24+
"@playwright/test": "^1.50.1",
25+
"@tanstack/router-e2e-utils": "workspace:^",
26+
"vite-plugin-solid": "^2.11.10",
27+
"vite": "^7.1.7"
28+
}
29+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { defineConfig, devices } from '@playwright/test'
2+
import {
3+
getDummyServerPort,
4+
getTestServerPort,
5+
} from '@tanstack/router-e2e-utils'
6+
import packageJson from './package.json' with { type: 'json' }
7+
8+
const PORT = await getTestServerPort(packageJson.name)
9+
const EXTERNAL_PORT = await getDummyServerPort(packageJson.name)
10+
const baseURL = `http://localhost:${PORT}`
11+
/**
12+
* See https://playwright.dev/docs/test-configuration.
13+
*/
14+
export default defineConfig({
15+
testDir: './tests',
16+
workers: 1,
17+
18+
reporter: [['line']],
19+
20+
globalSetup: './tests/setup/global.setup.ts',
21+
globalTeardown: './tests/setup/global.teardown.ts',
22+
23+
use: {
24+
/* Base URL to use in actions like `await page.goto('/')`. */
25+
baseURL,
26+
},
27+
28+
webServer: {
29+
command: `VITE_NODE_ENV="test" VITE_EXTERNAL_PORT=${EXTERNAL_PORT} VITE_SERVER_PORT=${PORT} pnpm build && VITE_SERVER_PORT=${PORT} pnpm serve --port ${PORT}`,
30+
url: baseURL,
31+
reuseExistingServer: !process.env.CI,
32+
stdout: 'pipe',
33+
},
34+
35+
projects: [
36+
{
37+
name: 'chromium',
38+
use: { ...devices['Desktop Chrome'] },
39+
},
40+
],
41+
})
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export default {
2+
plugins: {
3+
'@tailwindcss/postcss': {},
4+
},
5+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { RouterProvider, createRouter } from '@tanstack/solid-router'
2+
import { render } from 'solid-js/web'
3+
import { routeTree } from './routeTree.gen'
4+
import './styles.css'
5+
6+
// Set up a Router instance
7+
const router = createRouter({
8+
routeTree,
9+
defaultPreload: 'intent',
10+
defaultStaleTime: 5000,
11+
scrollRestoration: true,
12+
})
13+
14+
// Register things for typesafety
15+
declare module '@tanstack/solid-router' {
16+
interface Register {
17+
router: typeof router
18+
}
19+
}
20+
21+
const rootElement = document.getElementById('app')!
22+
23+
if (!rootElement.innerHTML) {
24+
render(() => <RouterProvider router={router} />, rootElement)
25+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import axios from 'redaxios'
2+
3+
export class NotFoundError extends Error {}
4+
5+
type PostType = {
6+
id: string
7+
title: string
8+
body: string
9+
}
10+
11+
let queryURL = 'https://jsonplaceholder.typicode.com'
12+
13+
if (import.meta.env.VITE_NODE_ENV === 'test') {
14+
queryURL = `http://localhost:${import.meta.env.VITE_EXTERNAL_PORT}`
15+
}
16+
17+
export const fetchPosts = async () => {
18+
console.info('Fetching posts...')
19+
return axios
20+
.get<Array<PostType>>(`${queryURL}/posts`)
21+
.then((r) => r.data.slice(0, 10))
22+
}
23+
24+
export const fetchPost = async (postId: string) => {
25+
console.info(`Fetching post with id ${postId}...`)
26+
const post = await axios
27+
.get<PostType>(`${queryURL}/posts/${postId}`)
28+
.then((r) => r.data)
29+
30+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
31+
if (!post) {
32+
throw new NotFoundError(`Post with id "${postId}" not found!`)
33+
}
34+
35+
return post
36+
}
Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
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 PathlessLayoutRouteImport } from './routes/_pathlessLayout'
13+
import { Route as PostsRouteRouteImport } from './routes/posts.route'
14+
import { Route as IndexRouteImport } from './routes/index'
15+
import { Route as PostsIndexRouteImport } from './routes/posts.index'
16+
import { Route as PostsPostIdRouteImport } from './routes/posts.$postId'
17+
import { Route as PathlessLayoutNestedLayoutRouteImport } from './routes/_pathlessLayout/_nested-layout'
18+
import { Route as PathlessLayoutNestedLayoutRouteBRouteImport } from './routes/_pathlessLayout/_nested-layout/route-b'
19+
import { Route as PathlessLayoutNestedLayoutRouteARouteImport } from './routes/_pathlessLayout/_nested-layout/route-a'
20+
21+
const PathlessLayoutRoute = PathlessLayoutRouteImport.update({
22+
id: '/_pathlessLayout',
23+
getParentRoute: () => rootRouteImport,
24+
} as any)
25+
const PostsRouteRoute = PostsRouteRouteImport.update({
26+
id: '/posts',
27+
path: '/posts',
28+
getParentRoute: () => rootRouteImport,
29+
} as any)
30+
const IndexRoute = IndexRouteImport.update({
31+
id: '/',
32+
path: '/',
33+
getParentRoute: () => rootRouteImport,
34+
} as any)
35+
const PostsIndexRoute = PostsIndexRouteImport.update({
36+
id: '/',
37+
path: '/',
38+
getParentRoute: () => PostsRouteRoute,
39+
} as any)
40+
const PostsPostIdRoute = PostsPostIdRouteImport.update({
41+
id: '/$postId',
42+
path: '/$postId',
43+
getParentRoute: () => PostsRouteRoute,
44+
} as any)
45+
const PathlessLayoutNestedLayoutRoute =
46+
PathlessLayoutNestedLayoutRouteImport.update({
47+
id: '/_nested-layout',
48+
getParentRoute: () => PathlessLayoutRoute,
49+
} as any)
50+
const PathlessLayoutNestedLayoutRouteBRoute =
51+
PathlessLayoutNestedLayoutRouteBRouteImport.update({
52+
id: '/route-b',
53+
path: '/route-b',
54+
getParentRoute: () => PathlessLayoutNestedLayoutRoute,
55+
} as any)
56+
const PathlessLayoutNestedLayoutRouteARoute =
57+
PathlessLayoutNestedLayoutRouteARouteImport.update({
58+
id: '/route-a',
59+
path: '/route-a',
60+
getParentRoute: () => PathlessLayoutNestedLayoutRoute,
61+
} as any)
62+
63+
export interface FileRoutesByFullPath {
64+
'/': typeof IndexRoute
65+
'/posts': typeof PostsRouteRouteWithChildren
66+
'/posts/$postId': typeof PostsPostIdRoute
67+
'/posts/': typeof PostsIndexRoute
68+
'/route-a': typeof PathlessLayoutNestedLayoutRouteARoute
69+
'/route-b': typeof PathlessLayoutNestedLayoutRouteBRoute
70+
}
71+
export interface FileRoutesByTo {
72+
'/': typeof IndexRoute
73+
'/posts/$postId': typeof PostsPostIdRoute
74+
'/posts': typeof PostsIndexRoute
75+
'/route-a': typeof PathlessLayoutNestedLayoutRouteARoute
76+
'/route-b': typeof PathlessLayoutNestedLayoutRouteBRoute
77+
}
78+
export interface FileRoutesById {
79+
__root__: typeof rootRouteImport
80+
'/': typeof IndexRoute
81+
'/posts': typeof PostsRouteRouteWithChildren
82+
'/_pathlessLayout': typeof PathlessLayoutRouteWithChildren
83+
'/_pathlessLayout/_nested-layout': typeof PathlessLayoutNestedLayoutRouteWithChildren
84+
'/posts/$postId': typeof PostsPostIdRoute
85+
'/posts/': typeof PostsIndexRoute
86+
'/_pathlessLayout/_nested-layout/route-a': typeof PathlessLayoutNestedLayoutRouteARoute
87+
'/_pathlessLayout/_nested-layout/route-b': typeof PathlessLayoutNestedLayoutRouteBRoute
88+
}
89+
export interface FileRouteTypes {
90+
fileRoutesByFullPath: FileRoutesByFullPath
91+
fullPaths:
92+
| '/'
93+
| '/posts'
94+
| '/posts/$postId'
95+
| '/posts/'
96+
| '/route-a'
97+
| '/route-b'
98+
fileRoutesByTo: FileRoutesByTo
99+
to: '/' | '/posts/$postId' | '/posts' | '/route-a' | '/route-b'
100+
id:
101+
| '__root__'
102+
| '/'
103+
| '/posts'
104+
| '/_pathlessLayout'
105+
| '/_pathlessLayout/_nested-layout'
106+
| '/posts/$postId'
107+
| '/posts/'
108+
| '/_pathlessLayout/_nested-layout/route-a'
109+
| '/_pathlessLayout/_nested-layout/route-b'
110+
fileRoutesById: FileRoutesById
111+
}
112+
export interface RootRouteChildren {
113+
IndexRoute: typeof IndexRoute
114+
PostsRouteRoute: typeof PostsRouteRouteWithChildren
115+
PathlessLayoutRoute: typeof PathlessLayoutRouteWithChildren
116+
}
117+
118+
declare module '@tanstack/solid-router' {
119+
interface FileRoutesByPath {
120+
'/_pathlessLayout': {
121+
id: '/_pathlessLayout'
122+
path: ''
123+
fullPath: ''
124+
preLoaderRoute: typeof PathlessLayoutRouteImport
125+
parentRoute: typeof rootRouteImport
126+
}
127+
'/posts': {
128+
id: '/posts'
129+
path: '/posts'
130+
fullPath: '/posts'
131+
preLoaderRoute: typeof PostsRouteRouteImport
132+
parentRoute: typeof rootRouteImport
133+
}
134+
'/': {
135+
id: '/'
136+
path: '/'
137+
fullPath: '/'
138+
preLoaderRoute: typeof IndexRouteImport
139+
parentRoute: typeof rootRouteImport
140+
}
141+
'/posts/': {
142+
id: '/posts/'
143+
path: '/'
144+
fullPath: '/posts/'
145+
preLoaderRoute: typeof PostsIndexRouteImport
146+
parentRoute: typeof PostsRouteRoute
147+
}
148+
'/posts/$postId': {
149+
id: '/posts/$postId'
150+
path: '/$postId'
151+
fullPath: '/posts/$postId'
152+
preLoaderRoute: typeof PostsPostIdRouteImport
153+
parentRoute: typeof PostsRouteRoute
154+
}
155+
'/_pathlessLayout/_nested-layout': {
156+
id: '/_pathlessLayout/_nested-layout'
157+
path: ''
158+
fullPath: ''
159+
preLoaderRoute: typeof PathlessLayoutNestedLayoutRouteImport
160+
parentRoute: typeof PathlessLayoutRoute
161+
}
162+
'/_pathlessLayout/_nested-layout/route-b': {
163+
id: '/_pathlessLayout/_nested-layout/route-b'
164+
path: '/route-b'
165+
fullPath: '/route-b'
166+
preLoaderRoute: typeof PathlessLayoutNestedLayoutRouteBRouteImport
167+
parentRoute: typeof PathlessLayoutNestedLayoutRoute
168+
}
169+
'/_pathlessLayout/_nested-layout/route-a': {
170+
id: '/_pathlessLayout/_nested-layout/route-a'
171+
path: '/route-a'
172+
fullPath: '/route-a'
173+
preLoaderRoute: typeof PathlessLayoutNestedLayoutRouteARouteImport
174+
parentRoute: typeof PathlessLayoutNestedLayoutRoute
175+
}
176+
}
177+
}
178+
179+
interface PostsRouteRouteChildren {
180+
PostsPostIdRoute: typeof PostsPostIdRoute
181+
PostsIndexRoute: typeof PostsIndexRoute
182+
}
183+
184+
const PostsRouteRouteChildren: PostsRouteRouteChildren = {
185+
PostsPostIdRoute: PostsPostIdRoute,
186+
PostsIndexRoute: PostsIndexRoute,
187+
}
188+
189+
const PostsRouteRouteWithChildren = PostsRouteRoute._addFileChildren(
190+
PostsRouteRouteChildren,
191+
)
192+
193+
interface PathlessLayoutNestedLayoutRouteChildren {
194+
PathlessLayoutNestedLayoutRouteARoute: typeof PathlessLayoutNestedLayoutRouteARoute
195+
PathlessLayoutNestedLayoutRouteBRoute: typeof PathlessLayoutNestedLayoutRouteBRoute
196+
}
197+
198+
const PathlessLayoutNestedLayoutRouteChildren: PathlessLayoutNestedLayoutRouteChildren =
199+
{
200+
PathlessLayoutNestedLayoutRouteARoute:
201+
PathlessLayoutNestedLayoutRouteARoute,
202+
PathlessLayoutNestedLayoutRouteBRoute:
203+
PathlessLayoutNestedLayoutRouteBRoute,
204+
}
205+
206+
const PathlessLayoutNestedLayoutRouteWithChildren =
207+
PathlessLayoutNestedLayoutRoute._addFileChildren(
208+
PathlessLayoutNestedLayoutRouteChildren,
209+
)
210+
211+
interface PathlessLayoutRouteChildren {
212+
PathlessLayoutNestedLayoutRoute: typeof PathlessLayoutNestedLayoutRouteWithChildren
213+
}
214+
215+
const PathlessLayoutRouteChildren: PathlessLayoutRouteChildren = {
216+
PathlessLayoutNestedLayoutRoute: PathlessLayoutNestedLayoutRouteWithChildren,
217+
}
218+
219+
const PathlessLayoutRouteWithChildren = PathlessLayoutRoute._addFileChildren(
220+
PathlessLayoutRouteChildren,
221+
)
222+
223+
const rootRouteChildren: RootRouteChildren = {
224+
IndexRoute: IndexRoute,
225+
PostsRouteRoute: PostsRouteRouteWithChildren,
226+
PathlessLayoutRoute: PathlessLayoutRouteWithChildren,
227+
}
228+
export const routeTree = rootRouteImport
229+
._addFileChildren(rootRouteChildren)
230+
._addFileTypes<FileRouteTypes>()

0 commit comments

Comments
 (0)