Set up frontend test infrastructure
Install @testing-library/react, @testing-library/jest-dom, @testing-library/user-event, and jsdom. Configure Vitest with globals, jsdom environment, and a setup file importing jest-dom matchers. Add a custom render helper wrapping components with QueryClientProvider and MemoryRouter. Exclude e2e/ from vitest. Smoke test covers formatEvolutionMethod. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,11 +1,11 @@
|
|||||||
---
|
---
|
||||||
# nuzlocke-tracker-d8cp
|
# nuzlocke-tracker-d8cp
|
||||||
title: Set up frontend test infrastructure
|
title: Set up frontend test infrastructure
|
||||||
status: draft
|
status: completed
|
||||||
type: task
|
type: task
|
||||||
priority: normal
|
priority: normal
|
||||||
created_at: 2026-02-10T09:33:33Z
|
created_at: 2026-02-10T09:33:33Z
|
||||||
updated_at: 2026-02-10T09:34:00Z
|
updated_at: 2026-02-21T12:32:34Z
|
||||||
parent: nuzlocke-tracker-yzpb
|
parent: nuzlocke-tracker-yzpb
|
||||||
blocking:
|
blocking:
|
||||||
- nuzlocke-tracker-ee9s
|
- nuzlocke-tracker-ee9s
|
||||||
@@ -16,14 +16,14 @@ Set up the test infrastructure for the React/TypeScript frontend. No testing too
|
|||||||
|
|
||||||
## Checklist
|
## Checklist
|
||||||
|
|
||||||
- [ ] Install Vitest, @testing-library/react, @testing-library/jest-dom, @testing-library/user-event, jsdom
|
- [x] Install Vitest, @testing-library/react, @testing-library/jest-dom, @testing-library/user-event, jsdom
|
||||||
- [ ] Configure Vitest in `vite.config.ts` or a dedicated `vitest.config.ts`
|
- [x] Configure Vitest in `vite.config.ts` or a dedicated `vitest.config.ts`
|
||||||
- [ ] Set up jsdom as the test environment
|
- [x] Set up jsdom as the test environment
|
||||||
- [ ] Create a test setup file (e.g. `src/test/setup.ts`) that imports @testing-library/jest-dom matchers
|
- [x] Create a test setup file (e.g. `src/test/setup.ts`) that imports @testing-library/jest-dom matchers
|
||||||
- [ ] Create test utility helpers (e.g. render wrapper with providers — QueryClientProvider, BrowserRouter)
|
- [x] Create test utility helpers (e.g. render wrapper with providers — QueryClientProvider, BrowserRouter)
|
||||||
- [ ] Add a \`test\` script to package.json
|
- [x] Add a \`test\` script to package.json
|
||||||
- [ ] Verify the setup by writing a simple smoke test
|
- [x] Verify the setup by writing a simple smoke test
|
||||||
- [ ] Set up MSW (Mock Service Worker) or a similar API mocking strategy for hook/component tests
|
- [x] Set up MSW (Mock Service Worker) or a similar API mocking strategy for hook/component tests — using `vi.mock` instead; MSW deferred until needed
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ Add comprehensive unit and integration test coverage to both the backend (FastAP
|
|||||||
|
|
||||||
- [x] Backend test infrastructure is set up (conftest, fixtures, test DB)
|
- [x] Backend test infrastructure is set up (conftest, fixtures, test DB)
|
||||||
- [ ] Backend schemas and services have unit test coverage
|
- [ ] Backend schemas and services have unit test coverage
|
||||||
- [ ] Backend API endpoints have integration test coverage
|
- [x] Backend API endpoints have integration test coverage
|
||||||
- [ ] Frontend test infrastructure is set up (Vitest, RTL)
|
- [x] Frontend test infrastructure is set up (Vitest, RTL)
|
||||||
- [ ] Frontend utilities and hooks have unit test coverage
|
- [ ] Frontend utilities and hooks have unit test coverage
|
||||||
- [ ] Frontend components have basic render/interaction tests
|
- [ ] Frontend components have basic render/interaction tests
|
||||||
847
frontend/package-lock.json
generated
847
frontend/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -29,10 +29,14 @@
|
|||||||
"@axe-core/playwright": "4.11.1",
|
"@axe-core/playwright": "4.11.1",
|
||||||
"@playwright/test": "1.58.2",
|
"@playwright/test": "1.58.2",
|
||||||
"@tailwindcss/vite": "4.1.18",
|
"@tailwindcss/vite": "4.1.18",
|
||||||
|
"@testing-library/jest-dom": "^6.9.1",
|
||||||
|
"@testing-library/react": "^16.3.2",
|
||||||
|
"@testing-library/user-event": "^14.6.1",
|
||||||
"@types/node": "24.10.10",
|
"@types/node": "24.10.10",
|
||||||
"@types/react": "19.2.11",
|
"@types/react": "19.2.11",
|
||||||
"@types/react-dom": "19.2.3",
|
"@types/react-dom": "19.2.3",
|
||||||
"@vitejs/plugin-react": "5.1.3",
|
"@vitejs/plugin-react": "5.1.3",
|
||||||
|
"jsdom": "^28.1.0",
|
||||||
"oxfmt": "0.33.0",
|
"oxfmt": "0.33.0",
|
||||||
"oxlint": "1.48.0",
|
"oxlint": "1.48.0",
|
||||||
"tailwindcss": "4.1.18",
|
"tailwindcss": "4.1.18",
|
||||||
|
|||||||
1
frontend/src/test/setup.ts
Normal file
1
frontend/src/test/setup.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
import '@testing-library/jest-dom'
|
||||||
29
frontend/src/test/utils.tsx
Normal file
29
frontend/src/test/utils.tsx
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
||||||
|
import { render, type RenderOptions } from '@testing-library/react'
|
||||||
|
import { type ReactElement } from 'react'
|
||||||
|
import { MemoryRouter } from 'react-router-dom'
|
||||||
|
|
||||||
|
export function createTestQueryClient(): QueryClient {
|
||||||
|
return new QueryClient({
|
||||||
|
defaultOptions: {
|
||||||
|
queries: { retry: false, gcTime: Infinity },
|
||||||
|
mutations: { retry: false },
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function AllProviders({ children }: { children: React.ReactNode }) {
|
||||||
|
const queryClient = createTestQueryClient()
|
||||||
|
return (
|
||||||
|
<QueryClientProvider client={queryClient}>
|
||||||
|
<MemoryRouter>{children}</MemoryRouter>
|
||||||
|
</QueryClientProvider>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function customRender(ui: ReactElement, options?: Omit<RenderOptions, 'wrapper'>) {
|
||||||
|
return render(ui, { wrapper: AllProviders, ...options })
|
||||||
|
}
|
||||||
|
|
||||||
|
export * from '@testing-library/react'
|
||||||
|
export { customRender as render }
|
||||||
51
frontend/src/utils/formatEvolution.test.ts
Normal file
51
frontend/src/utils/formatEvolution.test.ts
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
import { formatEvolutionMethod } from './formatEvolution'
|
||||||
|
|
||||||
|
const base = { minLevel: null, item: null, heldItem: null, condition: null }
|
||||||
|
|
||||||
|
describe('formatEvolutionMethod', () => {
|
||||||
|
it('formats level-up with a min level', () => {
|
||||||
|
expect(formatEvolutionMethod({ ...base, trigger: 'level-up', minLevel: 16 })).toBe('Level 16')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('formats level-up without a min level', () => {
|
||||||
|
expect(formatEvolutionMethod({ ...base, trigger: 'level-up' })).toBe('Level up')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('formats use-item trigger', () => {
|
||||||
|
expect(formatEvolutionMethod({ ...base, trigger: 'use-item', item: 'fire-stone' })).toBe(
|
||||||
|
'Fire Stone'
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('formats trade trigger', () => {
|
||||||
|
expect(formatEvolutionMethod({ ...base, trigger: 'trade' })).toBe('Trade')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('formats unknown trigger by capitalizing words', () => {
|
||||||
|
expect(formatEvolutionMethod({ ...base, trigger: 'shed-skin' })).toBe('Shed Skin')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('appends held item', () => {
|
||||||
|
expect(formatEvolutionMethod({ ...base, trigger: 'trade', heldItem: 'metal-coat' })).toBe(
|
||||||
|
'Trade, holding Metal Coat'
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('appends condition', () => {
|
||||||
|
expect(
|
||||||
|
formatEvolutionMethod({ ...base, trigger: 'level-up', minLevel: 20, condition: 'at night' })
|
||||||
|
).toBe('Level 20, at night')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('combines all parts', () => {
|
||||||
|
expect(
|
||||||
|
formatEvolutionMethod({
|
||||||
|
trigger: 'level-up',
|
||||||
|
minLevel: 25,
|
||||||
|
item: null,
|
||||||
|
heldItem: 'kings-rock',
|
||||||
|
condition: 'high friendship',
|
||||||
|
})
|
||||||
|
).toBe('Level 25, holding Kings Rock, high friendship')
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
"useDefineForClassFields": true,
|
"useDefineForClassFields": true,
|
||||||
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
||||||
"module": "ESNext",
|
"module": "ESNext",
|
||||||
"types": ["vite/client"],
|
"types": ["vite/client", "vitest/globals", "@testing-library/jest-dom"],
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
|
|
||||||
/* Bundler mode */
|
/* Bundler mode */
|
||||||
|
|||||||
@@ -8,6 +8,9 @@ export default defineConfig({
|
|||||||
plugins: [react(), tailwindcss()],
|
plugins: [react(), tailwindcss()],
|
||||||
test: {
|
test: {
|
||||||
environment: 'jsdom',
|
environment: 'jsdom',
|
||||||
|
globals: true,
|
||||||
|
setupFiles: ['./src/test/setup.ts'],
|
||||||
|
exclude: ['**/node_modules/**', '**/e2e/**'],
|
||||||
},
|
},
|
||||||
server: {
|
server: {
|
||||||
proxy: {
|
proxy: {
|
||||||
|
|||||||
Reference in New Issue
Block a user