Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions .github/CHROMATIC_SETUP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Chromatic Visual Regression Testing

This repository uses Chromatic for automated visual regression testing of Storybook components.

## Setup Complete βœ…

The following has been configured:

- βœ… Chromatic CLI installed (`chromatic@13.3.0`)
- βœ… GitHub Actions workflow (`.github/workflows/chromatic.yml`)
- βœ… Configuration file (`chromatic.config.json`)
- βœ… Project token added to GitHub Secrets
- βœ… Documentation updated

## How It Works

### On Pull Requests
1. Chromatic captures snapshots of all Storybook stories
2. Compares snapshots to the baseline from `main`
3. Posts visual diffs as PR comments
4. Build passes (won't block merge even with visual changes)
5. Developers review changes in Chromatic UI

### On Main Branch
- Changes are automatically accepted as the new baseline
- All future PRs compare against this baseline

## TurboSnap Optimization

**TurboSnap** is enabled to speed up builds:
- Only captures snapshots for changed stories
- Typical build time: ~30 seconds
- Requires full git history (`fetch-depth: 0`)

## Commands

```bash
# Run Chromatic locally (requires CHROMATIC_PROJECT_TOKEN env var)
bun run chromatic

# Build Storybook
bun run build-storybook

# Run Storybook dev server
bun run storybook
```

## Configuration Files

- `.github/workflows/chromatic.yml` - CI workflow
- `chromatic.config.json` - Chromatic settings
- `STORYBOOK.md` - Full Storybook documentation

## Accessing Chromatic

Visit https://www.chromatic.com/ and log in with your GitHub account to:
- View detailed visual diffs
- Approve/reject changes
- See build history
- Manage baselines

## Complements E2E Tests

Chromatic works alongside your existing e2e tests:
- **Chromatic**: Tests visual appearance of isolated components
- **E2E tests**: Test behavior and user interactions
- **No overlap**: Different concerns with minimal maintenance burden

## Free for Open Source

This project qualifies for Chromatic's free open source plan with unlimited builds.

33 changes: 33 additions & 0 deletions .github/workflows/chromatic.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: Chromatic

on:
push:
branches: [main]
pull_request:
branches: ["**"]

jobs:
chromatic:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0 # Required for Chromatic TurboSnap

- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest

- name: Install dependencies
run: bun install --frozen-lockfile

- name: Publish to Chromatic
uses: chromaui/action@latest
with:
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
buildScriptName: build-storybook
onlyChanged: true # Only test changed stories (TurboSnap)
exitZeroOnChanges: true # Don't fail on visual changes
autoAcceptChanges: main # Auto-accept changes on main branch
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,8 @@ docs/vercel/
# Profiling
**.cpuprofile
profile.txt

*storybook.log
storybook-static
chromatic-*.log
build-storybook.log
20 changes: 20 additions & 0 deletions .storybook/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type { StorybookConfig } from '@storybook/react-vite';

const config: StorybookConfig = {
"stories": [
"../src/**/*.mdx",
"../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"
],
"addons": [
"@chromatic-com/storybook",
"@storybook/addon-docs",
"@storybook/addon-onboarding",
"@storybook/addon-a11y",
"@storybook/addon-vitest"
],
"framework": {
"name": "@storybook/react-vite",
"options": {}
}
};
export default config;
6 changes: 6 additions & 0 deletions .storybook/manager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { addons } from '@storybook/manager-api';
import { themes } from '@storybook/theming';

addons.setConfig({
theme: themes.dark,
});
67 changes: 67 additions & 0 deletions .storybook/preview.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import type { Preview } from '@storybook/react-vite'
import { themes } from '@storybook/theming';
import { Global, css } from '@emotion/react';
import { GlobalColors } from '../src/styles/colors';
import { GlobalFonts } from '../src/styles/fonts';
import React from 'react';

// Base styles matching the app
const globalStyles = css`
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

body {
font-family: var(--font-primary);
font-size: 14px;
line-height: 1.5;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: var(--color-text);
}

code {
font-family: var(--font-monospace);
}
`;

const preview: Preview = {
parameters: {
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/i,
},
},
backgrounds: {
default: 'dark',
values: [
{
name: 'dark',
value: 'hsl(0 0% 12%)',
},
{
name: 'light',
value: '#ffffff',
},
],
},
docs: {
theme: themes.dark,
},
},
decorators: [
(Story) => (
<>
<GlobalColors />
<GlobalFonts />
<Global styles={globalStyles} />
<Story />
</>
),
],
};

export default preview;
109 changes: 109 additions & 0 deletions STORYBOOK.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# Storybook

This project uses [Storybook](https://storybook.js.org/) for component development and documentation.

## Running Storybook

To start Storybook in development mode:

```bash
bun run storybook
```

This will start Storybook on http://localhost:6006

## Building Storybook

To build a static version of Storybook:

```bash
bun run build-storybook
```

The output will be in the `storybook-static` directory.

## Creating Stories

Stories are located next to their components with the `.stories.tsx` extension.

Example structure:

```
src/components/Messages/
β”œβ”€β”€ AssistantMessage.tsx
└── AssistantMessage.stories.tsx
```

### Example Story

```typescript
import type { Meta, StoryObj } from "@storybook/react";
import { MyComponent } from "./MyComponent";

const meta = {
title: "Category/MyComponent",
component: MyComponent,
parameters: {
layout: "padded",
},
tags: ["autodocs"],
} satisfies Meta<typeof MyComponent>;

export default meta;
type Story = StoryObj<typeof meta>;

export const Default: Story = {
args: {
// component props
},
};
```

## Current Stories

- **Messages/AssistantMessage**: Various states of assistant messages including streaming, partial, with models, etc.

## Configuration

- `.storybook/main.ts` - Main Storybook configuration
- `.storybook/preview.tsx` - Preview configuration with global styles and dark theme for docs
- `.storybook/manager.ts` - Manager (UI chrome) configuration with dark theme

## Theme

Storybook is configured with a dark theme to match the application:

- Dark UI chrome (sidebar, toolbar, etc.)
- Dark documentation pages
- Dark canvas background (`hsl(0 0% 12%)`) matching the app's `--color-background`

## Visual Regression Testing with Chromatic

This project uses [Chromatic](https://www.chromatic.com/) for automated visual regression testing.

### How it works

- **On PRs**: Chromatic captures snapshots of all stories and compares them to the baseline
- **On main**: Changes are automatically accepted as the new baseline
- **TurboSnap**: Only changed stories are tested, making builds fast (~30s typical)

### Running Chromatic locally

```bash
bun run chromatic
```

You'll need a `CHROMATIC_PROJECT_TOKEN` environment variable set.

### CI Integration

Chromatic runs automatically in CI via `.github/workflows/chromatic.yml`:

- Runs on all PRs and pushes to main
- Visual diffs are shown inline in PR comments
- Won't fail the build on visual changes (for review)

### Configuration

- `chromatic.config.json` - Chromatic settings (TurboSnap, skip patterns, etc.)
- See [Chromatic docs](https://www.chromatic.com/docs/) for more options
Loading