Getting Started with Vignet
WARNING
Vignet is still in alpha, so not all frameworks or functionality is yet supported. Please file requests and issues via github, or better yet, chat with me in discord!
Requirements
You should be using Vitest and Vite 8+. It also expects that your app is written in TypeScript. It may work with plain JavaScript, but this has not been verified.
Vignet does not support Jest tests!
Supported frameworks
Eventually, our goal is to have Vignet support all major frameworks that Vite is generally used with. But for now this is still a work in progress. Here are the current state of various frameworks:
| Framework | Current State | Example |
|---|---|---|
| React | Works | in main repo |
| Angular | Does not yet support angular templates | |
| Next.js | Not yet supported | |
| Vue | Probably works, but not yet tested | |
| Svelte | Not yet supported |
Steps
1. Install
Install via pnpm (recommended):
pnpm i -D @vignet/vignet
Or npm:
npm i -D @vignet/vignet
2. Extend Vitest's TaskMeta interface for Vignet
This is required so the typescript compiler recognizes the task metadata passed to Vitest tests that denote which tests will render through Vignet
import 'vitest';
declare module 'vitest' {
interface TaskMeta {
vignet?: {
name: string;
};
}
}3. Annotate Vignet tests with task metadata
This works with both test:
import { test, expect } from 'vitest';
import { render, screen } from '@testing-library/react';
test('primary', { meta: { vignet: { name: 'Primary Button' } } }, () => {
render(<Button label='Submit' />)
expect(screen.getByRole('button', { name: label })).toBeTruthy()
})and it syntax:
it('shows loading state', { meta: { vignet: { name: 'Loading Weather Widget' } } }, () => {
vi.mocked(getCurrentWeather).mockReturnValue(new Promise(() => { }))
render(<WeatherWidget city="London" />)
expect(screen.getByRole('progressbar')).toBeInTheDocument()
expect(screen.getByText('Fetching weather for London…')).toBeInTheDocument()
})4. Run Vignet
You can run Vignet as a Vite dev server:
pnpm vignetOr optionally build as a static web app that can be served:
pnpm vignet buildNote that static builds do not currently support vi.mock() functionality (documented here) and may have other unknown limitations.
Optional: parameterizing inputs
WARNING
The input parameterization API is still very much in exploration until we converge on the best way to support this.
Like Storybook, Vignet supports parameterizing inputs so a user can modify that value in the Vignet UI and dynamically see how it changes. You can do this by using the param() function:
import { param } from '@vignet/vignet';
//
it('shows weather data', { meta: { vignet: { name: 'Weather Widget with data' } } }, async () => {
// Parameterize these inputs
const city = param('city', 'London', { label: 'City' })
const temperatureC = param('temperatureC', 18, { label: 'Temperature (°C)' })
const description = param('description', 'Partly cloudy', { label: 'Description' })
vi.mocked(getCurrentWeather).mockResolvedValue({ city, temperatureC, description })
render(<WeatherWidget city={city} />)
await screen.findByText(city)
expect(screen.getByText(`${temperatureC}°C`)).toBeInTheDocument()
expect(screen.getByText(description)).toBeInTheDocument()
})