From e357116024b4646bfaa7dd30e91abe5f9df6c2e6 Mon Sep 17 00:00:00 2001 From: Charles Bochet Date: Wed, 10 Jun 2026 17:00:21 +0200 Subject: [PATCH] fix(ui): freeze framer-motion in Argos runs to stop flaky visual diffs (#21412) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Problem twenty-ui Argos visual tests are flaky — `Loader`, `CircularProgressBar`, `ProgressBar` get flagged as changed with no relevant code change. ## Cause Argos screenshots use Playwright's `animations: "disabled"`, which only freezes CSS animations. These components animate via framer-motion (main-thread rAF), so each run captures a different frame. ## Fix Set `MotionGlobalConfig.skipAnimations = true` in the Vitest setup of both UI packages — freezes framer-motion to a deterministic state during Argos runs only (interactive Storybook unaffected). Removes the now-redundant per-story `disableSnapshot` opt-outs. Note: removing `CircularProgressBar`'s opt-out adds new baselines (one-time Argos approval, not flakiness). --- packages/twenty-ui-deprecated/.storybook/vitest.setup.ts | 7 +++++++ .../components/__stories__/CircularProgressBar.stories.tsx | 3 --- .../components/__stories__/ProgressBar.stories.tsx | 3 --- packages/twenty-ui/.storybook/vitest.setup.ts | 7 +++++++ 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/packages/twenty-ui-deprecated/.storybook/vitest.setup.ts b/packages/twenty-ui-deprecated/.storybook/vitest.setup.ts index 8b25f1ffbb..512a7f55d2 100644 --- a/packages/twenty-ui-deprecated/.storybook/vitest.setup.ts +++ b/packages/twenty-ui-deprecated/.storybook/vitest.setup.ts @@ -1,5 +1,12 @@ import { setProjectAnnotations } from '@storybook/react-vite'; +import { MotionGlobalConfig } from 'framer-motion'; import * as projectAnnotations from './preview'; +// Freeze framer-motion so Argos screenshots are deterministic. Playwright's +// `animations: "disabled"` only halts CSS animations/transitions, not +// framer-motion's main-thread (rAF) animations, so loaders/spinners were +// captured mid-frame and flagged as visual changes on every run. +MotionGlobalConfig.skipAnimations = true; + // Apply Storybook's preview configuration to Vitest runs. setProjectAnnotations([projectAnnotations]); diff --git a/packages/twenty-ui-deprecated/src/feedback/progress-bar/components/__stories__/CircularProgressBar.stories.tsx b/packages/twenty-ui-deprecated/src/feedback/progress-bar/components/__stories__/CircularProgressBar.stories.tsx index 8bdd4eaa70..297b49c054 100644 --- a/packages/twenty-ui-deprecated/src/feedback/progress-bar/components/__stories__/CircularProgressBar.stories.tsx +++ b/packages/twenty-ui-deprecated/src/feedback/progress-bar/components/__stories__/CircularProgressBar.stories.tsx @@ -10,9 +10,6 @@ const meta: Meta = { args: { size: 50, }, - parameters: { - chromatic: { disableSnapshot: true }, - }, }; export default meta; diff --git a/packages/twenty-ui-deprecated/src/feedback/progress-bar/components/__stories__/ProgressBar.stories.tsx b/packages/twenty-ui-deprecated/src/feedback/progress-bar/components/__stories__/ProgressBar.stories.tsx index 83b71be965..8c63e2a0a9 100644 --- a/packages/twenty-ui-deprecated/src/feedback/progress-bar/components/__stories__/ProgressBar.stories.tsx +++ b/packages/twenty-ui-deprecated/src/feedback/progress-bar/components/__stories__/ProgressBar.stories.tsx @@ -42,7 +42,4 @@ export const Animated: Story = { return ; }, ], - parameters: { - chromatic: { disableSnapshot: true }, - }, }; diff --git a/packages/twenty-ui/.storybook/vitest.setup.ts b/packages/twenty-ui/.storybook/vitest.setup.ts index 8b25f1ffbb..512a7f55d2 100644 --- a/packages/twenty-ui/.storybook/vitest.setup.ts +++ b/packages/twenty-ui/.storybook/vitest.setup.ts @@ -1,5 +1,12 @@ import { setProjectAnnotations } from '@storybook/react-vite'; +import { MotionGlobalConfig } from 'framer-motion'; import * as projectAnnotations from './preview'; +// Freeze framer-motion so Argos screenshots are deterministic. Playwright's +// `animations: "disabled"` only halts CSS animations/transitions, not +// framer-motion's main-thread (rAF) animations, so loaders/spinners were +// captured mid-frame and flagged as visual changes on every run. +MotionGlobalConfig.skipAnimations = true; + // Apply Storybook's preview configuration to Vitest runs. setProjectAnnotations([projectAnnotations]);