Skip to content
Closed
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
11 changes: 11 additions & 0 deletions e2e/react-router/basic-auth/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
node_modules
.DS_Store
dist
dist-hash
dist-ssr
*.local

/test-results/
/playwright-report/
/blob-report/
/playwright/.cache/
12 changes: 12 additions & 0 deletions e2e/react-router/basic-auth/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
31 changes: 31 additions & 0 deletions e2e/react-router/basic-auth/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"name": "tanstack-router-e2e-react-basic-auth",
"private": true,
"type": "module",
"scripts": {
"dev": "vite --port 3000",
"dev:e2e": "vite",
"build": "vite build && tsc --noEmit",
"serve": "vite preview",
"start": "vite",
"test:e2e": "playwright test --project=chromium"
},
"dependencies": {
"@tanstack/react-router": "workspace:^",
"@tanstack/react-router-devtools": "workspace:^",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"redaxios": "^0.5.1",
"postcss": "^8.5.1",
"autoprefixer": "^10.4.20",
"tailwindcss": "^3.4.17"
},
"devDependencies": {
"@playwright/test": "^1.50.1",
"@tanstack/router-e2e-utils": "workspace:^",
"@types/react": "^19.0.8",
"@types/react-dom": "^19.0.3",
"@vitejs/plugin-react": "^4.3.4",
"vite": "^6.1.0"
}
}
34 changes: 34 additions & 0 deletions e2e/react-router/basic-auth/playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { defineConfig, devices } from '@playwright/test'
import { derivePort } from '@tanstack/router-e2e-utils'
import packageJson from './package.json' with { type: 'json' }

const PORT = derivePort(packageJson.name)
const baseURL = `http://localhost:${PORT}`
/**
* See https://playwright.dev/docs/test-configuration.
*/
export default defineConfig({
testDir: './tests',
workers: 1,

reporter: [['line']],

use: {
/* Base URL to use in actions like `await page.goto('/')`. */
baseURL,
},

webServer: {
command: `VITE_SERVER_PORT=${PORT} pnpm build && VITE_SERVER_PORT=${PORT} pnpm serve --port ${PORT}`,
url: baseURL,
reuseExistingServer: !process.env.CI,
stdout: 'pipe',
},

projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},
],
})
6 changes: 6 additions & 0 deletions e2e/react-router/basic-auth/postcss.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
77 changes: 77 additions & 0 deletions e2e/react-router/basic-auth/src/auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { useMemo, useState } from 'react'

export type AuthUser = {
id: string
name: string
}

export type AuthState =
| {
type: 'authenticated'
user: AuthUser
}
| {
type: 'unauthenticated'
hasLoggedIn: boolean
}

export type AuthHandle = {
login: (userId: string) => Promise<void>
logout: () => Promise<void>
}

export const initialAuthState: AuthState = {
type: 'unauthenticated',
hasLoggedIn: false,
}

export const initialAuthHandle: AuthHandle = {
login: () => Promise.resolve(),
logout: () => Promise.resolve(),
}

export function useAuth(): readonly [AuthState, AuthHandle] {
const [authState, setAuthState] = useState<AuthState>({
type: 'unauthenticated',
hasLoggedIn: false,
})

const login = async (userId: string) =>
new Promise<void>((resolve) => {
// Delay the login with a setTimeout to simulate a network request,
// and make sure any actions in response are not batched as part of
// a React request handler.
setTimeout(() => {
setAuthState({
type: 'authenticated',
user: {
id: userId,
name: `User #${userId}`,
},
})
resolve()
}, 500)
})

const logout = async () =>
new Promise<void>((resolve) => {
setTimeout(() => {
setAuthState((currentState) => ({
type: 'unauthenticated',
hasLoggedIn:
currentState.type === 'authenticated' || currentState.hasLoggedIn,
}))
resolve()
})
})

const authHandle = useMemo<AuthHandle>(
() => ({
login,
logout,
}),
[login, logout],
)

return [authState, authHandle]
}
Loading
Loading