Skip to content

Commit dfecb13

Browse files
fix(test): resolve Storybook + Vitest integration issues
- Configure vitest.config.ts with separate projects for unit tests (jsdom) and Storybook tests (Playwright browser) - Add Next.js navigation mocking in .storybook/preview.tsx to fix usePathname/useRouter null errors in stories - Update middleware unit test to match actual regex matcher pattern - Add @gitbox/redux-storage-middleware as workspace dependency - Remove unused lib/redux/middleware/storageMiddleware.ts wrapper - Pre-bundle superjson/lz-string to prevent Vite re-optimization All 199 tests now pass (97 unit + 102 Storybook tests)
1 parent 228075d commit dfecb13

File tree

8 files changed

+55
-33
lines changed

8 files changed

+55
-33
lines changed

.storybook/preview.tsx

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { Preview } from '@storybook/nextjs-vite'
22
import React from 'react'
33

4-
import { initialize, mswDecorator } from 'msw-storybook-addon'
4+
import { initialize, mswLoader } from 'msw-storybook-addon'
55

66
import { Provider as ReduxStoreProvider } from 'react-redux'
77
import { store } from '../lib/redux/store'
@@ -34,16 +34,24 @@ const preview: Preview = {
3434
date: /Date$/i,
3535
},
3636
},
37-
37+
// Default Next.js navigation mocking for components using usePathname/useRouter
38+
nextjs: {
39+
navigation: {
40+
pathname: '/boards',
41+
},
42+
appDirectory: true,
43+
},
3844
a11y: {
3945
// 'todo' - show a11y violations in the test UI only
4046
// 'error' - fail CI on a11y violations
4147
// 'off' - skip a11y checks entirely
4248
test: 'todo',
4349
},
4450
},
51+
// MSW loader must be in loaders (not decorators) to ensure
52+
// service workers are registered before story rendering
53+
loaders: [mswLoader],
4554
decorators: [
46-
mswDecorator,
4755
(Story) => (
4856
<ReduxStoreProvider store={store}>
4957
<Story />

.storybook/vitest.setup.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
1+
/**
2+
* Vitest Setup for Storybook
3+
*
4+
* Configures project annotations for testing stories with Vitest.
5+
* The @storybook/addon-vitest automatically handles the beforeAll hook.
6+
*/
17
import * as a11yAddonAnnotations from '@storybook/addon-a11y/preview'
28
import { setProjectAnnotations } from '@storybook/nextjs-vite'
9+
310
import * as projectAnnotations from './preview'
411

5-
// This is an important step to apply the right configuration when testing your stories.
6-
// More info at: https://storybook.js.org/docs/api/portable-stories/portable-stories-vitest#setprojectannotations
12+
// Apply project annotations for testing stories
13+
// The addon-vitest automatically loads Storybook's beforeAll hook
714
setProjectAnnotations([a11yAddonAnnotations, projectAnnotations])

lib/redux/middleware/storageMiddleware.ts

Lines changed: 0 additions & 15 deletions
This file was deleted.

lib/redux/store.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@
1111
* RTK Query for security reasons (HTTP-only cookie token access).
1212
*/
1313

14+
import { createStorageMiddleware } from '@gitbox/redux-storage-middleware'
1415
import { configureStore } from '@reduxjs/toolkit'
1516
import type { TypedUseSelectorHook } from 'react-redux'
1617
import { useDispatch, useSelector } from 'react-redux'
1718

18-
import { createStorageMiddleware } from './middleware/storageMiddleware'
1919
import authReducer from './slices/authSlice'
2020
import boardReducer from './slices/boardSlice'
2121
import settingsReducer from './slices/settingsSlice'

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
"build-storybook": "storybook build"
2626
},
2727
"dependencies": {
28+
"@gitbox/redux-storage-middleware": "workspace:*",
2829
"@dnd-kit/core": "^6.3.1",
2930
"@dnd-kit/modifiers": "^9.0.0",
3031
"@dnd-kit/sortable": "^10.0.0",

pnpm-lock.yaml

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/unit/middleware.test.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,11 @@ describe('Middleware (middleware.ts)', () => {
3939
const matcher = config.matcher[0]
4040

4141
expect(typeof matcher).toBe('string')
42-
expect(matcher).toContain('_next/static')
43-
expect(matcher).toContain('_next/image')
42+
// Matcher uses negative lookahead to exclude _next, api, and static assets
43+
// Pattern: (?!_next|api|favicon.ico|icons|.*\.(?:svg|png|...))
44+
expect(matcher).toContain('_next')
4445
expect(matcher).toContain('favicon.ico')
46+
expect(matcher).toContain('api')
4547
})
4648
})
4749

vitest.config.ts

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,13 @@ const dirname =
2323

2424
export default defineConfig({
2525
plugins: [react()],
26+
// Pre-bundle dependencies to prevent Vite re-optimization during tests
27+
optimizeDeps: {
28+
include: ['superjson', 'lz-string'],
29+
},
2630
test: {
31+
// Shared configuration
2732
globals: true,
28-
environment: 'jsdom',
29-
setupFiles: ['./tests/setup.ts'],
30-
include: ['tests/unit/**/*.test.ts', 'tests/unit/**/*.test.tsx'],
31-
exclude: ['tests/e2e/**/*', 'node_modules/**/*', 'dist/**/*'],
3233
coverage: {
3334
provider: 'v8',
3435
reporter: ['text', 'json', 'html'],
@@ -41,20 +42,35 @@ export default defineConfig({
4142
'dist/',
4243
],
4344
},
44-
alias: {
45-
'@gitbox/redux-storage-middleware': path.resolve(
46-
dirname,
47-
'tests/__mocks__/@gitbox/redux-storage-middleware.ts',
48-
),
49-
},
45+
// Two separate test projects: unit tests (jsdom) and Storybook (browser)
5046
projects: [
47+
// Unit tests project (jsdom environment)
48+
{
49+
extends: true,
50+
test: {
51+
name: 'unit',
52+
environment: 'jsdom',
53+
include: ['tests/unit/**/*.test.ts', 'tests/unit/**/*.test.tsx'],
54+
exclude: ['tests/e2e/**/*', 'node_modules/**/*', 'dist/**/*'],
55+
setupFiles: ['./tests/setup.ts'],
56+
alias: {
57+
'@gitbox/redux-storage-middleware': path.resolve(
58+
dirname,
59+
'tests/__mocks__/@gitbox/redux-storage-middleware.ts',
60+
),
61+
},
62+
},
63+
},
64+
// Storybook tests project (browser environment with Playwright)
5165
{
5266
extends: true,
5367
plugins: [
5468
// The plugin will run tests for the stories defined in your Storybook config
5569
// See options at: https://storybook.js.org/docs/next/writing-tests/integrations/vitest-addon#storybooktest
5670
storybookTest({
5771
configDir: path.join(dirname, '.storybook'),
72+
// Script to start Storybook (--no-open prevents browser opening)
73+
storybookScript: 'pnpm storybook --no-open',
5874
}),
5975
],
6076
test: {

0 commit comments

Comments
 (0)