🐾
NutriPaw
Planes nutricionales para clínicas veterinarias

Regresión Visual Automatizada
con Chromatic + Storybook

Configuración completa de pruebas visuales para detectar cambios en UI antes del merge. 48 snapshots automáticos en cada PR.

Chromatic Storybook 8 GitHub Actions React 18 + TypeScript
48
Snapshots por PR
5
Componentes
4
Modos (light/dark × 2vp)
Pipeline CI/CD
📤
Push / PR
Developer abre PR con cambios en un componente
✓ Trigger
⚙️
npm ci + Build
GitHub Actions instala deps y compila Storybook
✓ ~45s
📸
Chromatic Snapshots
Captura 48 snapshots (4 modos × 5 componentes × variantes)
⟳ ~90s
🔍
Diff Visual
Compara contra baseline. Detecta píxeles cambiados
✓ Auto
👁️
Revisión Diseño
Diseñador aprueba/rechaza cambios en Chromatic UI
⏳ Manual
Merge Desbloqueado
Status check verde — PR listo para merge
✓ Auto
Componentes en Storybook
🐕
Max
Golden Retriever · Plan Pro
1.240 kcal/día
Plan Básico ✓
Plan Pro
Plan Elite
🐾 NutriPaw · Dashboard
Modos de Captura (chromatic modes)
Modo Tema Viewport Componentes Snapshots
light desktop ☀️ Light 1280px Button, PetCard, NutritionBadge, Dropdown, DashboardHeader 12
dark desktop 🌙 Dark 1280px Button, PetCard, NutritionBadge, Dropdown, DashboardHeader 12
light mobile ☀️ Light 375px Button, PetCard, NutritionBadge, Dropdown 10
dark mobile 🌙 Dark 375px Button, PetCard, NutritionBadge, Dropdown 10
Total por PR: 48 snapshots
Código de Configuración
.github/workflows/chromatic.yml YAML
name: Chromatic Visual Tests
on: push

jobs:
  chromatic:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm ci
      - uses: chromaui/action@latest
        with:
          projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
          autoAcceptChanges: main
          onlyChanged: true
chromatic.config.js JS
module.exports = {
  projectToken: process.env.CHROMATIC_PROJECT_TOKEN,
  autoAcceptChanges: 'main',    // auto-acepta en main
  exitZeroOnChanges: true,
  onlyChanged: true,           // TurboSnap — ahorra créditos
  skip: 'dependabot/**',
};
src/components/Button.stories.tsx TSX
import type { Meta, StoryObj } from '@storybook/react';
import { Button } from './Button';

const meta: Meta<typeof Button> = {
  component: Button,
  parameters: {
    chromatic: {
      viewports: [375, 768, 1280],
      delay: 300,
      diffThreshold: 0.063,
    },
  },
};

export const NutritionBadgeAnimated: Story = {
  parameters: {
    chromatic: {
      disableSnapshot: true, // omite animaciones
    },
  },
};
.storybook/modes.ts TS
export const allModes = {
  'light desktop': {
    theme: 'light', viewport: 1280
  },
  'dark desktop': {
    theme: 'dark', viewport: 1280
  },
  'light mobile': {
    theme: 'light', viewport: 375
  },
  'dark mobile': {
    theme: 'dark', viewport: 375
  },
};
Estado del PR — GitHub Status Checks
feat(ui): actualizar color primario del Button a #6C47FF
feature/button-rebrand → main · 3 cambios · 1 componente afectado
🔀
CI Build
npm ci + Storybook build — 43s
Pasó
TypeScript · ESLint
Sin errores de tipo ni lint
Pasó
📸
Chromatic — UI Tests
12 cambios detectados en Button · Esperando revisión de @diana.ux
Pendiente revisión
🚫
Chromatic — UI Review
Aprobación de diseñadora requerida antes del merge
Bloqueado
Diff Visual Detectado — Button (Primary)
✖ Antes — baseline (main)
Color: #5B39E0 · padding: 10px 20px · border-radius: 7px
✔ Después — PR feature/button-rebrand
Color: #6C47FF · padding: 10px 22px · shadow: 0 3px 10px rgba(108,71,255,.45)
🔬 Overlay Chromatic — píxeles cambiados resaltados
+2px padding
color shift
Píxeles cambiados: 847 / 38.400 total · Umbral: 6.3% · Cambio: 2.2% — dentro del umbral pero requiere revisión manual