Make flaky Storybook stories deterministic for Argos (animations + lazy-load) (#21609)
Follow-up to #21594. A set of stories were still flagged flaky by Argos after the data/image/date fixes. The remaining causes are **animation** and **lazy-load timing**, not data. Argos's screenshot stabilization waits for fonts and images and disables CSS animations at capture, but it does **not** stop JS-driven animations (react-spring) or wait for `React.lazy` chunks to load. Two global, test-only changes in the Storybook Vitest setup, plus an `optimizeDeps` entry: **1. Disable JS animations (charts).** GraphWidgetLineChart (incl. `--catalog`) and the pie chart draw via `@react-spring/web` (`useAnimatedPath`/`useArcsTransition`, used by nivo), so they get captured mid-draw. - `Globals.assign({ skipAnimation: true })` from `@react-spring/web` (single hoisted instance → covers nivo), mirroring the existing `MotionGlobalConfig.skipAnimations`. - A global CSS rule zeroing animation/transition durations (belt-and-suspenders for the pre-capture window). - `@react-spring/web` added to `optimizeDeps.include` (next to `@nivo/*`) so importing it in the setup file doesn't trigger a mid-run Vite re-optimization. **2. Pre-warm lazy chunks.** RichTextFieldInput (BlockNote editor), AiChatMessage (`react-markdown`/`remark-gfm`), and AppNavigationDrawer (favorites/workspace section dispatchers) lazy-load behind `Suspense`; the snapshot could capture the skeleton fallback instead of the loaded content. Pre-warming the chunks at setup time (same pattern already used for the workflow-step mock) caches them before stories render. The settings object-about form was already covered by the framer-motion/CSS animation disable.
This commit is contained in:
@@ -1,12 +1,30 @@
|
||||
import { Globals } from '@react-spring/web';
|
||||
import { setProjectAnnotations } from '@storybook/react-vite';
|
||||
import { MotionGlobalConfig } from 'framer-motion';
|
||||
import * as projectAnnotations from './preview';
|
||||
|
||||
MotionGlobalConfig.skipAnimations = true;
|
||||
Globals.assign({ skipAnimation: true });
|
||||
|
||||
// Pre-warm the dynamic import used by WorkflowStepDecorator so the
|
||||
// module is cached before any test runs (avoids flaky timeouts in CI).
|
||||
const disableCssAnimationsStyle = document.createElement('style');
|
||||
disableCssAnimationsStyle.innerHTML = `*, *::before, *::after {
|
||||
animation-duration: 0s !important;
|
||||
animation-delay: 0s !important;
|
||||
transition-duration: 0s !important;
|
||||
transition-delay: 0s !important;
|
||||
}`;
|
||||
document.head.appendChild(disableCssAnimationsStyle);
|
||||
|
||||
// Pre-warm the dynamic imports used by lazy() story components so the
|
||||
// modules are cached before any test runs (avoids flaky timeouts and Argos
|
||||
// screenshots that capture a Suspense skeleton instead of the loaded content).
|
||||
import('~/testing/utils/getTestEnrichedObjectMetadataItemsMock');
|
||||
import('react-markdown');
|
||||
import('remark-gfm');
|
||||
import('@/activities/components/ActivityRichTextEditor');
|
||||
import('@/object-record/record-field/ui/meta-types/input/components/RichTextFieldEditor');
|
||||
import('@/navigation-menu-item/display/sections/favorites/components/FavoritesSectionDispatcher');
|
||||
import('@/navigation-menu-item/display/sections/workspace/components/WorkspaceSectionDispatcher');
|
||||
|
||||
// This is an important step to apply the right configuration when testing your stories.
|
||||
// More info at: https://storybook.js.org/docs/api/portable-stories/portable-stories-vitest#setprojectannotations
|
||||
|
||||
@@ -154,6 +154,7 @@ export default defineConfig(({ mode }) => {
|
||||
'@nivo/pie',
|
||||
'@nivo/line',
|
||||
'@nivo/arcs',
|
||||
'@react-spring/web',
|
||||
'd3-shape',
|
||||
],
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user