@lifeonlars/prime-yggdrasil 0.2.3 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/radius.css CHANGED
@@ -27,11 +27,11 @@
27
27
  --radius-charts-medium: 8px; /* donut charts, tree maps */
28
28
  --radius-charts-small: 2px; /* segments of stacked charts */
29
29
 
30
- /* Special radius */
31
- --radius-full: 9999px; /* fully rounded elements (pills, avatars) */
32
30
 
33
31
  /* ==================== Generic Radius Scale ==================== */
34
- /* For direct use in custom components following 4px grid */
32
+
33
+ /* Generally not used, however included for edge cases for direct use in
34
+ custom coponents, blocks or compositions to ensure 4px grid adherence */
35
35
 
36
36
  --radius-none: 0;
37
37
  --radius-sm: 4px; /* Small elements, tight corners */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lifeonlars/prime-yggdrasil",
3
- "version": "0.2.3",
3
+ "version": "0.2.4",
4
4
  "type": "module",
5
5
  "description": "AI-agent-friendly PrimeReact design system for component-driven development with semantic tokens and dark mode support",
6
6
  "keywords": [
@@ -54,8 +54,6 @@
54
54
  "preview": "vite preview",
55
55
  "test": "vitest run",
56
56
  "test:watch": "vitest",
57
- "test:storybook": "test-storybook",
58
- "test:storybook:watch": "test-storybook --watch",
59
57
  "test:contrast": "node scripts/test-contrast.js",
60
58
  "test:contrast:vitest": "vitest run tests/contrast.test.ts",
61
59
  "test:contrast:watch": "vitest tests/contrast.test.ts",
@@ -83,7 +81,6 @@
83
81
  "@storybook/addon-onboarding": "^10.1.11",
84
82
  "@storybook/addon-vitest": "^10.1.11",
85
83
  "@storybook/react-vite": "^10.1.11",
86
- "@storybook/test-runner": "^0.24.2",
87
84
  "@testing-library/jest-dom": "^6.9.1",
88
85
  "@testing-library/react": "^16.3.1",
89
86
  "@testing-library/user-event": "^14.6.1",
@@ -1,352 +0,0 @@
1
- # Storybook Testing Guide
2
-
3
- This guide explains how to test components in Prime Yggdrasil using Storybook's Vitest addon.
4
-
5
- ## Overview
6
-
7
- Prime Yggdrasil uses `@storybook/addon-vitest` for component testing. This allows you to:
8
- - Write tests alongside your stories
9
- - Test components in a real browser environment
10
- - Use Vitest's familiar testing API
11
- - Run tests in watch mode for development
12
-
13
- ## Setup
14
-
15
- The testing infrastructure is already configured:
16
-
17
- ### Files
18
- - `.storybook/vitest.config.ts` - Vitest configuration for Storybook
19
- - `.storybook/vitest.setup.ts` - Test setup and Storybook project annotations
20
- - `package.json` - Test scripts
21
-
22
- ### Scripts
23
- ```bash
24
- # Run all Storybook tests once
25
- npm run test:storybook
26
-
27
- # Run tests in watch mode (auto-rerun on changes)
28
- npm run test:storybook:watch
29
- ```
30
-
31
- ## Writing Tests
32
-
33
- ### Basic Test Structure
34
-
35
- Tests are written using Vitest's `expect` API inside your story files:
36
-
37
- ```tsx
38
- import { test, expect } from '@storybook/test';
39
- import type { Meta, StoryObj } from '@storybook/react-vite';
40
- import { Button } from 'primereact/button';
41
-
42
- const meta = {
43
- title: 'Button/Button',
44
- component: Button,
45
- } satisfies Meta<typeof Button>;
46
-
47
- export default meta;
48
- type Story = StoryObj<typeof meta>;
49
-
50
- export const Primary: Story = {
51
- args: {
52
- label: 'Click me',
53
- },
54
- };
55
-
56
- // Test the Primary story
57
- test('Primary button renders correctly', async ({ mount }) => {
58
- const component = await mount(<Primary.component {...Primary.args} />);
59
- const button = await component.getByRole('button');
60
-
61
- await expect(button).toBeInTheDocument();
62
- await expect(button).toHaveTextContent('Click me');
63
- });
64
- ```
65
-
66
- ### Testing Interactive Components
67
-
68
- For components with state (like Checkbox, RadioButton, etc.):
69
-
70
- ```tsx
71
- import { test, expect } from '@storybook/test';
72
- import { userEvent } from '@storybook/test';
73
-
74
- export const Default: Story = {
75
- render: () => {
76
- const [checked, setChecked] = useState(false);
77
- return (
78
- <Checkbox checked={checked} onChange={(e) => setChecked(e.checked)} />
79
- );
80
- },
81
- };
82
-
83
- test('Checkbox toggles on click', async ({ mount, page }) => {
84
- await mount(<Default.component />);
85
-
86
- const checkbox = page.getByRole('checkbox');
87
-
88
- // Initially unchecked
89
- await expect(checkbox).not.toBeChecked();
90
-
91
- // Click to check
92
- await userEvent.click(checkbox);
93
- await expect(checkbox).toBeChecked();
94
-
95
- // Click again to uncheck
96
- await userEvent.click(checkbox);
97
- await expect(checkbox).not.toBeChecked();
98
- });
99
- ```
100
-
101
- ### Testing Theme Switching
102
-
103
- Test components in both light and dark modes:
104
-
105
- ```tsx
106
- test('Button renders in dark mode', async ({ mount, page }) => {
107
- // Set dark mode
108
- await page.evaluate(() => {
109
- document.documentElement.setAttribute('data-theme', 'dark');
110
- });
111
-
112
- await mount(<Primary.component {...Primary.args} />);
113
-
114
- const button = page.getByRole('button');
115
- const bgColor = await button.evaluate((el) =>
116
- getComputedStyle(el).backgroundColor
117
- );
118
-
119
- // Dark mode should have darker background
120
- await expect(bgColor).toBeTruthy();
121
- });
122
- ```
123
-
124
- ### Testing Accessibility
125
-
126
- Use built-in a11y assertions:
127
-
128
- ```tsx
129
- import { test, expect } from '@storybook/test';
130
-
131
- test('Button is accessible', async ({ mount, page }) => {
132
- await mount(<Primary.component {...Primary.args} />);
133
-
134
- const button = page.getByRole('button');
135
-
136
- // Check ARIA attributes
137
- await expect(button).toBeEnabled();
138
- await expect(button).toBeVisible();
139
- await expect(button).toHaveAccessibleName('Click me');
140
- });
141
- ```
142
-
143
- ## Best Practices
144
-
145
- ### 1. Test One Concern Per Test
146
- ```tsx
147
- // Good
148
- test('renders with label', async ({ mount }) => { /* ... */ });
149
- test('responds to click', async ({ mount }) => { /* ... */ });
150
-
151
- // Avoid
152
- test('renders and clicks', async ({ mount }) => { /* ... */ });
153
- ```
154
-
155
- ### 2. Use Semantic Queries
156
- ```tsx
157
- // Good - semantic and accessible
158
- const button = page.getByRole('button', { name: 'Submit' });
159
- const heading = page.getByRole('heading', { level: 1 });
160
-
161
- // Avoid - fragile
162
- const button = page.locator('.p-button');
163
- ```
164
-
165
- ### 3. Test User Behavior, Not Implementation
166
- ```tsx
167
- // Good - tests what user sees/does
168
- test('shows error message on invalid input', async ({ mount, page }) => {
169
- await mount(<Form />);
170
- await page.getByRole('button', { name: 'Submit' }).click();
171
- await expect(page.getByText('Required field')).toBeVisible();
172
- });
173
-
174
- // Avoid - tests implementation details
175
- test('sets error state to true', async ({ mount }) => {
176
- const { rerender } = await mount(<Form />);
177
- // Don't test internal state
178
- });
179
- ```
180
-
181
- ### 4. Keep Tests Fast
182
- - Use `mount` instead of full page loads
183
- - Mock external API calls
184
- - Avoid unnecessary `waitFor` delays
185
-
186
- ### 5. Test Across Themes
187
- ```tsx
188
- test.each(['light', 'dark'])('renders in %s mode', async (theme, { mount, page }) => {
189
- await page.evaluate((t) => {
190
- document.documentElement.setAttribute('data-theme', t);
191
- }, theme);
192
-
193
- await mount(<Component />);
194
- // Test rendering...
195
- });
196
- ```
197
-
198
- ## Common Patterns
199
-
200
- ### Testing Forms
201
-
202
- ```tsx
203
- test('form submission', async ({ mount, page }) => {
204
- await mount(<FormStory />);
205
-
206
- // Fill in fields
207
- await page.getByLabel('Email').fill('user@example.com');
208
- await page.getByLabel('Password').fill('password123');
209
-
210
- // Submit
211
- await page.getByRole('button', { name: 'Sign In' }).click();
212
-
213
- // Verify result
214
- await expect(page.getByText('Welcome!')).toBeVisible();
215
- });
216
- ```
217
-
218
- ### Testing Dropdowns
219
-
220
- ```tsx
221
- test('dropdown selection', async ({ mount, page }) => {
222
- await mount(<DropdownStory />);
223
-
224
- const dropdown = page.getByRole('combobox');
225
- await dropdown.click();
226
-
227
- // Select option
228
- await page.getByRole('option', { name: 'New York' }).click();
229
-
230
- // Verify selection
231
- await expect(dropdown).toHaveValue('NY');
232
- });
233
- ```
234
-
235
- ### Testing Modals/Dialogs
236
-
237
- ```tsx
238
- test('dialog opens and closes', async ({ mount, page }) => {
239
- await mount(<DialogStory />);
240
-
241
- // Open dialog
242
- await page.getByRole('button', { name: 'Open' }).click();
243
-
244
- const dialog = page.getByRole('dialog');
245
- await expect(dialog).toBeVisible();
246
-
247
- // Close dialog
248
- await dialog.getByRole('button', { name: 'Close' }).click();
249
- await expect(dialog).not.toBeVisible();
250
- });
251
- ```
252
-
253
- ## Debugging Tests
254
-
255
- ### Run in headed mode
256
- ```bash
257
- # See the browser while tests run
258
- npm run test:storybook:watch
259
- # Then in the Vitest UI, enable "headed" mode
260
- ```
261
-
262
- ### Use page.pause()
263
- ```tsx
264
- test('debug test', async ({ mount, page }) => {
265
- await mount(<Component />);
266
-
267
- await page.pause(); // Opens Playwright Inspector
268
-
269
- // Test continues...
270
- });
271
- ```
272
-
273
- ### Screenshot on failure
274
- ```tsx
275
- test('visual test', async ({ mount, page }) => {
276
- await mount(<Component />);
277
-
278
- try {
279
- await expect(page.getByRole('button')).toBeVisible();
280
- } catch (error) {
281
- await page.screenshot({ path: 'test-failure.png' });
282
- throw error;
283
- }
284
- });
285
- ```
286
-
287
- ## Continuous Integration
288
-
289
- For CI/CD pipelines:
290
-
291
- ```yaml
292
- # .github/workflows/test.yml
293
- - name: Install dependencies
294
- run: npm ci
295
-
296
- - name: Install Playwright browsers
297
- run: npx playwright install --with-deps chromium
298
-
299
- - name: Run Storybook tests
300
- run: npm run test:storybook
301
- ```
302
-
303
- ## Troubleshooting
304
-
305
- ### "Failed to start test runner process"
306
-
307
- This usually means:
308
- 1. Playwright browsers aren't installed: `npx playwright install chromium`
309
- 2. Port conflict: Close other Storybook instances
310
- 3. Timeout: Increase timeout in vitest.config.ts
311
-
312
- ### Tests timing out
313
-
314
- Increase test timeout:
315
- ```ts
316
- // .storybook/vitest.config.ts
317
- export default defineConfig({
318
- test: {
319
- testTimeout: 30000, // 30 seconds
320
- },
321
- });
322
- ```
323
-
324
- ### Theme styles not applying
325
-
326
- Ensure YggdrasilProvider is wrapping your component:
327
- ```tsx
328
- // In your story
329
- export const Default: Story = {
330
- decorators: [
331
- (Story) => (
332
- <YggdrasilProvider ripple={true}>
333
- <Story />
334
- </YggdrasilProvider>
335
- ),
336
- ],
337
- };
338
- ```
339
-
340
- ## Resources
341
-
342
- - [Storybook Test Addon Docs](https://storybook.js.org/docs/writing-tests/test-addon)
343
- - [Vitest API](https://vitest.dev/api/)
344
- - [Playwright Test API](https://playwright.dev/docs/api/class-test)
345
- - [Testing Library Queries](https://testing-library.com/docs/queries/about)
346
-
347
- ## Next Steps
348
-
349
- 1. Add tests to existing stories
350
- 2. Set up CI pipeline to run tests
351
- 3. Add visual regression testing with Chromatic
352
- 4. Configure test coverage reporting