improve testing speed

This commit is contained in:
seavor 2026-04-20 00:01:25 -05:00
parent 0d7336edc2
commit 5f28d43dff
7 changed files with 731 additions and 325 deletions

View file

@ -9,12 +9,30 @@ import { initReactI18next } from 'react-i18next';
import { DndContext } from '@dnd-kit/core';
import { createTheme, ThemeProvider } from '@mui/material/styles';
// Disables MUI's ripple animation in tests. The ripple fires a deferred
// state update after clicks/focus that would otherwise trigger a noisy
// "update to ForwardRef(TouchRipple) was not wrapped in act(...)" warning.
// Disables MUI's ripple animation AND all component transitions in tests.
// The ripple fires a deferred state update after clicks/focus that would
// trigger a noisy "update to ForwardRef(TouchRipple) was not wrapped in
// act(...)" warning. Transitions (Grow/Fade/Slide used by Menu, Dialog,
// Popover, Tooltip) default to ~225ms, which is pure wait-time in jsdom
// — every portal open paid this cost before. Zeroing `transitions.duration`
// plus the per-component `transitionDuration: 0` override belt-and-braces
// covers the full v9 surface: styled transitions read the theme; component-
// level Transition props need the defaultProps override.
const testTheme = createTheme({
transitions: {
duration: {
shortest: 0, shorter: 0, short: 0,
standard: 0, complex: 0,
enteringScreen: 0, leavingScreen: 0,
},
create: () => 'none',
},
components: {
MuiButtonBase: { defaultProps: { disableRipple: true } },
MuiDialog: { defaultProps: { transitionDuration: 0 } },
MuiMenu: { defaultProps: { transitionDuration: 0 } },
MuiPopover: { defaultProps: { transitionDuration: 0 } },
MuiTooltip: { defaultProps: { enterDelay: 0, leaveDelay: 0 } },
},
});
@ -26,6 +44,20 @@ import { storeMiddlewareOptions } from '../store/store';
import type { RootState } from '../store/store';
import { createMockWebClient } from './mockWebClient';
// Lazy-initialized per test file (vitest isolate: true re-evaluates module
// graph per file). Reused by every `renderWithProviders` call that doesn't
// inject its own webClient, so the ~65 vi.fn() allocations happen once per
// file instead of once per render. The global `afterEach` in setupTests.ts
// runs `vi.clearAllMocks()` which resets call history between tests without
// destroying the fn instances — exactly what we want here.
let defaultWebClient: WebClient | undefined;
function getDefaultWebClient(): WebClient {
if (!defaultWebClient) {
defaultWebClient = createMockWebClient();
}
return defaultWebClient;
}
// Non-empty `resources` registers en-US so `resolvedLanguage` is defined;
// without it MUI warns about out-of-range Select values.
const testI18n = i18n.createInstance();
@ -64,7 +96,7 @@ export function renderWithProviders(
preloadedState,
store = createTestStore(preloadedState),
route = '/',
webClient = createMockWebClient(),
webClient = getDefaultWebClient(),
...renderOptions
}: ExtendedRenderOptions = {},
) {