-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
test: share React Start basic mode e2e suite #7060
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
348dee4
76ccac8
3a2f65c
7e63efc
d9e233f
7bcaafd
c4fc282
c3a875b
467ba15
4c48439
95ae7e1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| node_modules | ||
|
|
||
| /test-results/ | ||
| /playwright-report/ | ||
| /blob-report/ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| { | ||
| "name": "tanstack-react-start-e2e-basic-prerender", | ||
| "private": true, | ||
| "sideEffects": false, | ||
| "type": "module", | ||
| "scripts": { | ||
| "test:e2e:startDummyServer": "node -e 'import(\"../basic-test-suite/src/setup/global.setup.ts\").then(m => m.default())' & node -e 'import(\"../basic-test-suite/src/setup/waitForDummyServer.ts\").then(m => m.default())'", | ||
| "test:e2e:stopDummyServer": "node -e 'import(\"../basic-test-suite/src/setup/global.teardown.ts\").then(m => m.default())'", | ||
| "test:e2e": "rm -rf port*.txt; MODE=prerender playwright test --project=chromium" | ||
| }, | ||
| "devDependencies": { | ||
| "@playwright/test": "^1.50.1", | ||
| "@tanstack/router-e2e-utils": "workspace:^", | ||
| "tanstack-react-start-e2e-basic": "workspace:*", | ||
| "tanstack-react-start-e2e-basic-test-suite": "workspace:*" | ||
| }, | ||
| "nx": { | ||
| "targets": { | ||
| "test:e2e": { | ||
| "parallelism": false | ||
| } | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| import { defineConfig, devices } from '@playwright/test' | ||
| import { | ||
| getDummyServerPort, | ||
| getTestServerPort, | ||
| } from '@tanstack/router-e2e-utils' | ||
| import packageJson from './package.json' with { type: 'json' } | ||
|
|
||
| const PORT = await getTestServerPort(packageJson.name) | ||
| const START_PORT = await getTestServerPort(`${packageJson.name}_start`) | ||
| const EXTERNAL_PORT = await getDummyServerPort(packageJson.name) | ||
| const baseURL = `http://localhost:${PORT}` | ||
|
|
||
| export default defineConfig({ | ||
| testDir: '../basic-test-suite/src', | ||
| workers: 1, | ||
| reporter: [['line']], | ||
|
|
||
| globalTeardown: '../basic-test-suite/src/setup/global.teardown.ts', | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Description: Check getPackageName implementation to verify it resolves correctly
# Find and display getPackageName implementation
fd -t f 'getPackageName.ts' e2e/react-start/basic-test-suite --exec cat {}
echo "---"
# Check if it reads from cwd or has hardcoded values
rg -n 'getPackageName|packageJson|process.cwd' e2e/react-start/basic-test-suite/src/utils/Repository: TanStack/router Length of output: 1276 🏁 Script executed: # Check the full playwright.config.ts to see how packageJson is loaded
cat -n e2e/react-start/basic-prerender/playwright.config.ts | head -25Repository: TanStack/router Length of output: 912 🏁 Script executed: # Check the package.json in basic-prerender to see its name
cat e2e/react-start/basic-prerender/package.json | jq '.name'Repository: TanStack/router Length of output: 101 🏁 Script executed: # Check the package.json at the repo root to compare names
cat package.json | jq '.name'Repository: TanStack/router Length of output: 65 🏁 Script executed: # Check global.teardown.ts to see exactly how it uses getPackageName
cat -n e2e/react-start/basic-test-suite/src/setup/global.teardown.tsRepository: TanStack/router Length of output: 352 Fix package name mismatch between server startup and teardown. The dummy server port is allocated using Either pass the package name to the teardown function, or ensure 🤖 Prompt for AI Agents |
||
|
|
||
| use: { | ||
| baseURL, | ||
| }, | ||
|
|
||
| webServer: { | ||
| command: | ||
| 'pnpm run test:e2e:startDummyServer && pnpm --dir ../basic build:prerender && pnpm --dir ../basic start', | ||
| url: baseURL, | ||
| reuseExistingServer: !process.env.CI, | ||
| stdout: 'pipe', | ||
| env: { | ||
| MODE: 'prerender', | ||
| VITE_NODE_ENV: 'test', | ||
| VITE_EXTERNAL_PORT: String(EXTERNAL_PORT), | ||
| VITE_SERVER_PORT: String(PORT), | ||
| START_PORT: String(START_PORT), | ||
| PORT: String(PORT), | ||
| }, | ||
| }, | ||
|
|
||
| projects: [ | ||
| { | ||
| name: 'chromium', | ||
| use: { | ||
| ...devices['Desktop Chrome'], | ||
| }, | ||
| }, | ||
| ], | ||
| }) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| node_modules | ||
|
|
||
| /test-results/ | ||
| /playwright-report/ | ||
| /blob-report/ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| { | ||
| "name": "tanstack-react-start-e2e-basic-preview", | ||
| "private": true, | ||
| "sideEffects": false, | ||
| "type": "module", | ||
| "scripts": { | ||
| "test:e2e:startDummyServer": "node -e 'import(\"../basic-test-suite/src/setup/global.setup.ts\").then(m => m.default())' & node -e 'import(\"../basic-test-suite/src/setup/waitForDummyServer.ts\").then(m => m.default())'", | ||
| "test:e2e:stopDummyServer": "node -e 'import(\"../basic-test-suite/src/setup/global.teardown.ts\").then(m => m.default())'", | ||
| "test:e2e": "rm -rf port*.txt; MODE=preview playwright test --project=chromium" | ||
| }, | ||
| "devDependencies": { | ||
| "@playwright/test": "^1.50.1", | ||
| "@tanstack/router-e2e-utils": "workspace:^", | ||
| "tanstack-react-start-e2e-basic": "workspace:*", | ||
| "tanstack-react-start-e2e-basic-test-suite": "workspace:*" | ||
| }, | ||
| "nx": { | ||
| "targets": { | ||
| "test:e2e": { | ||
| "parallelism": false | ||
| } | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| import { defineConfig, devices } from '@playwright/test' | ||
| import { | ||
| getDummyServerPort, | ||
| getTestServerPort, | ||
| } from '@tanstack/router-e2e-utils' | ||
| import packageJson from './package.json' with { type: 'json' } | ||
|
|
||
| const PORT = await getTestServerPort(packageJson.name) | ||
| const START_PORT = await getTestServerPort(`${packageJson.name}_start`) | ||
| const EXTERNAL_PORT = await getDummyServerPort(packageJson.name) | ||
| const baseURL = `http://localhost:${PORT}` | ||
|
|
||
| export default defineConfig({ | ||
| testDir: '../basic-test-suite/src', | ||
| workers: 1, | ||
| reporter: [['line']], | ||
|
|
||
| globalTeardown: '../basic-test-suite/src/setup/global.teardown.ts', | ||
|
|
||
| use: { | ||
| baseURL, | ||
| }, | ||
|
|
||
| webServer: { | ||
| command: `pnpm run test:e2e:startDummyServer && pnpm --dir ../basic build && pnpm --dir ../basic preview --port ${PORT}`, | ||
| url: baseURL, | ||
| reuseExistingServer: !process.env.CI, | ||
| stdout: 'pipe', | ||
| env: { | ||
| MODE: 'preview', | ||
| VITE_NODE_ENV: 'test', | ||
| VITE_EXTERNAL_PORT: String(EXTERNAL_PORT), | ||
| VITE_SERVER_PORT: String(PORT), | ||
| START_PORT: String(START_PORT), | ||
| PORT: String(PORT), | ||
| }, | ||
| }, | ||
|
|
||
| projects: [ | ||
| { | ||
| name: 'chromium', | ||
| use: { | ||
| ...devices['Desktop Chrome'], | ||
| }, | ||
| }, | ||
| ], | ||
| }) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| node_modules | ||
|
|
||
| /test-results/ | ||
| /playwright-report/ | ||
| /blob-report/ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| { | ||
| "name": "tanstack-react-start-e2e-basic-spa", | ||
| "private": true, | ||
| "sideEffects": false, | ||
| "type": "module", | ||
| "scripts": { | ||
| "test:e2e:startDummyServer": "node -e 'import(\"../basic-test-suite/src/setup/global.setup.ts\").then(m => m.default())' & node -e 'import(\"../basic-test-suite/src/setup/waitForDummyServer.ts\").then(m => m.default())'", | ||
| "test:e2e:stopDummyServer": "node -e 'import(\"../basic-test-suite/src/setup/global.teardown.ts\").then(m => m.default())'", | ||
| "test:e2e": "rm -rf port*.txt; MODE=spa playwright test --project=chromium" | ||
| }, | ||
| "devDependencies": { | ||
| "@playwright/test": "^1.50.1", | ||
| "@tanstack/router-e2e-utils": "workspace:^", | ||
| "tanstack-react-start-e2e-basic": "workspace:*", | ||
| "tanstack-react-start-e2e-basic-test-suite": "workspace:*" | ||
| }, | ||
| "nx": { | ||
| "targets": { | ||
| "test:e2e": { | ||
| "parallelism": false | ||
| } | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| import { defineConfig, devices } from '@playwright/test' | ||
| import { | ||
| getDummyServerPort, | ||
| getTestServerPort, | ||
| } from '@tanstack/router-e2e-utils' | ||
| import packageJson from './package.json' with { type: 'json' } | ||
|
|
||
| const PORT = await getTestServerPort(packageJson.name) | ||
| const START_PORT = await getTestServerPort(`${packageJson.name}_start`) | ||
| const EXTERNAL_PORT = await getDummyServerPort(packageJson.name) | ||
| const baseURL = `http://localhost:${PORT}` | ||
|
|
||
| export default defineConfig({ | ||
| testDir: '../basic-test-suite/src', | ||
| workers: 1, | ||
| reporter: [['line']], | ||
|
|
||
| globalTeardown: '../basic-test-suite/src/setup/global.teardown.ts', | ||
|
|
||
| use: { | ||
| baseURL, | ||
| }, | ||
|
|
||
| webServer: { | ||
| command: | ||
| 'pnpm run test:e2e:startDummyServer && pnpm --dir ../basic build:spa && pnpm --dir ../basic start', | ||
| url: baseURL, | ||
| reuseExistingServer: !process.env.CI, | ||
| stdout: 'pipe', | ||
| env: { | ||
| MODE: 'spa', | ||
| VITE_NODE_ENV: 'test', | ||
| VITE_EXTERNAL_PORT: String(EXTERNAL_PORT), | ||
| VITE_SERVER_PORT: String(PORT), | ||
| START_PORT: String(START_PORT), | ||
| PORT: String(PORT), | ||
| }, | ||
| }, | ||
|
|
||
| projects: [ | ||
| { | ||
| name: 'chromium', | ||
| use: { | ||
| ...devices['Desktop Chrome'], | ||
| }, | ||
| }, | ||
| ], | ||
| }) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| node_modules | ||
|
|
||
| /test-results/ | ||
| /playwright-report/ | ||
| /blob-report/ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| { | ||
| "name": "tanstack-react-start-e2e-basic-test-suite", | ||
| "private": true, | ||
| "sideEffects": false, | ||
| "type": "module", | ||
| "devDependencies": { | ||
| "@playwright/test": "^1.50.1", | ||
| "@tanstack/router-e2e-utils": "workspace:*", | ||
| "@types/node": "^22.10.2", | ||
| "combinate": "^1.1.11" | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| import { e2eStartDummyServer } from '@tanstack/router-e2e-utils' | ||
| import { getPackageName } from '../utils/getPackageName.ts' | ||
|
|
||
| export default async function setup() { | ||
| await e2eStartDummyServer(getPackageName()) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| import { e2eStopDummyServer } from '@tanstack/router-e2e-utils' | ||
| import { getPackageName } from '../utils/getPackageName.ts' | ||
|
|
||
| export default async function teardown() { | ||
| try { | ||
| await e2eStopDummyServer(getPackageName()) | ||
| } catch {} | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| import { getDummyServerPort } from '@tanstack/router-e2e-utils' | ||
| import { getPackageName } from '../utils/getPackageName.ts' | ||
|
|
||
| const timeoutMs = 10_000 | ||
| const retryIntervalMs = 100 | ||
|
|
||
| export default async function waitForDummyServer() { | ||
| const port = await getDummyServerPort(getPackageName()) | ||
| const deadline = Date.now() + timeoutMs | ||
|
|
||
| while (Date.now() < deadline) { | ||
| try { | ||
| const response = await fetch(`http://localhost:${port}/`) | ||
|
|
||
| if (response.ok) { | ||
| return | ||
| } | ||
| } catch {} | ||
|
|
||
| await new Promise((resolve) => setTimeout(resolve, retryIntervalMs)) | ||
| } | ||
|
|
||
| throw new Error(`Timed out waiting for dummy server on port ${port}`) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| import { join } from 'node:path' | ||
| import { getPackageName } from './getPackageName.ts' | ||
|
|
||
| export function getBasicAppRoot() { | ||
| return getPackageName() === 'tanstack-react-start-e2e-basic' | ||
| ? process.cwd() | ||
| : join(process.cwd(), '../basic') | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| import { readFileSync } from 'node:fs' | ||
| import { join } from 'node:path' | ||
|
|
||
| let packageName: string | undefined | ||
|
|
||
| export function getPackageName() { | ||
| if (!packageName) { | ||
| const packageJson = JSON.parse( | ||
| readFileSync(join(process.cwd(), 'package.json'), 'utf-8'), | ||
| ) as { name: string } | ||
|
|
||
| packageName = packageJson.name | ||
| } | ||
|
|
||
| return packageName | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| export const isPrerender: boolean = process.env.MODE === 'prerender' |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| export const isPreview: boolean = process.env.MODE === 'preview' |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| export const isSpaMode: boolean = process.env.MODE === 'spa' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Keep the prerender dummy-server lifecycle in this workspace.
Line 10 allocates
EXTERNAL_PORTfromtanstack-react-start-e2e-basic-prerender, but Line 27 starts/stops the dummy server viapnpm --dir ../basic .... Those scripts resolve their package/port-*.txtstate from../basic, so the dummy server can bind a different port than the one injected asVITE_EXTERNAL_PORT. The prerender build then talks to a port that no dummy server is serving.🐛 Suggested fix
webServer: { command: - 'pnpm --dir ../basic run test:e2e:startDummyServer && pnpm --dir ../basic build:prerender && pnpm --dir ../basic run test:e2e:stopDummyServer && pnpm --dir ../basic start', + 'node -e \'import("../basic-test-suite/src/setup/global.setup.ts").then((m) => m.default())\' & node -e \'import("../basic-test-suite/src/setup/waitForDummyServer.ts").then((m) => m.default())\' && pnpm --dir ../basic build:prerender && node -e \'import("../basic-test-suite/src/setup/global.teardown.ts").then((m) => m.default())\' && pnpm --dir ../basic start',Also applies to: 25-37
🤖 Prompt for AI Agents