Skip to content

Commit 923d855

Browse files
authored
chore: migrate tests to Vitest with Storybook interaction tests (#224)
* feat: migrate tests to Vitest with Storybook interaction tests - Replace web-test-runner with Vitest 4.x + @storybook/addon-vitest - Convert stories from JS to TypeScript with play functions - Add autocomplete-keybindings.ts for keyboard handling - Add shadow-dom-testing-library for shadow DOM queries - Add global keybindings decorator in .storybook/preview.js - Remove @open-wc/testing and @types/mocha dependencies - Keep existing Playwright E2E visual tests BREAKING CHANGE: Test infrastructure changed from web-test-runner to Vitest * chore: include e2e tests in npm test script * feat: add interaction tests to story play functions - Add userEvent interactions to test keyboard navigation and selection - Create InteractionTest stories for comprehensive E2E-style tests - Keep Basic stories with read-only assertions for visual regression tests - Add eslint override to disable max-lines for stories folder - Test coverage: chip removal, item selection, no-results message, exclude toggle * chore: enable autodocs for all stories * chore: reorder stories - Autocomplete before Excluding * fix: enable autodocs via tags for Storybook 10 * refactor: remove keybindings infrastructure (to be added later) * test: migrate removed tests to Vitest unit tests and Storybook interaction tests - Add unit tests for pure functions (search, mark) in test/utils.test.ts (11 tests) - Extract pure functions to src/autocomplete/pure.ts for jsdom testability - Add Storybook test stories for listbox (7 tests) and autocomplete (11 tests) - Configure vitest with 'unit' project for jsdom-based tests - Add jsdom dependency for unit testing pure functions - Update eslint config for test files * test: add missing coverage for external search, valueProperty, onSelect, keyboard edge cases Add 10 new test stories to close coverage gaps from the @web/test-runner migration: Autocomplete (4 stories): - ExternalSearchMode: verifies client-side filtering is bypassed - ValueProperty: verifies deduplication by valueProperty (id) - OnSelectCallback: verifies onSelect receives (item, meta) - Limit1DisablesBackspace: verifies use-keys disables when limit=1 Listbox (6 stories): - KeyboardDownCycling: ArrowDown wraps from last to first item - KeyboardUpNavigation: ArrowDown then ArrowUp returns to original - HighlightAndEnter: mouseenter sets highlight, Enter selects it - EnterDefaultIndex0: Enter with implicit defaultIndex=0 - CtrlAltIgnoresKeys: Ctrl+Alt modifier combo is ignored - LegacyKeyNames: legacy 'Down'/'Up' key names are handled * ci: remove separate playwright workflow, run e2e via npm test * refactor: merge pure.ts back into util.ts, move useNotify into use-autocomplete
1 parent 2829483 commit 923d855

26 files changed

+2616
-1555
lines changed

.github/workflows/playwright.yml

Lines changed: 0 additions & 35 deletions
This file was deleted.

.storybook/main.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
/** @type { import('@storybook/web-components-vite').StorybookConfig } */
22
const config = {
33
stories: ['../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
4+
addons: ['@storybook/addon-docs', '@storybook/addon-vitest'],
45
framework: {
56
name: '@storybook/web-components-vite',
67
options: {},
78
},
89
docs: {
9-
autodocs: 'tag',
10+
autodocs: true,
1011
},
1112
};
1213

.storybook/preview.js

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { html } from '@pionjs/pion';
2+
import i18next from 'i18next';
3+
import { within as withinShadow } from 'shadow-dom-testing-library';
4+
5+
// Initialize i18next for the autocomplete component
6+
i18next.init({
7+
lng: 'en',
8+
resources: {
9+
en: {
10+
translation: {
11+
'No results found': 'No results found',
12+
},
13+
},
14+
},
15+
});
16+
17+
export default {
18+
tags: ['autodocs'],
19+
parameters: {
20+
options: {
21+
storySort: {
22+
order: ['Autocomplete', 'Autocomplete Excluding', 'Tests'],
23+
},
24+
},
25+
docs: {
26+
source: {
27+
excludeDecorators: true,
28+
type: 'code',
29+
transform: (source) => {
30+
const match = source.match(/html`([\s\S]*?)`/u);
31+
return match?.[1]?.trim() ?? source;
32+
},
33+
},
34+
},
35+
},
36+
// Augment the canvas with shadow-dom-testing-library queries
37+
beforeEach({ canvasElement, canvas }) {
38+
Object.assign(canvas, { ...withinShadow(canvasElement) });
39+
},
40+
decorators: [
41+
(story) => {
42+
return html`
43+
<style>
44+
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@100;300;400;500&display=swap');
45+
46+
.story-root {
47+
font-family: 'Inter', sans-serif;
48+
padding: 16px;
49+
min-height: 100%;
50+
}
51+
52+
cosmoz-autocomplete,
53+
cosmoz-listbox,
54+
cosmoz-autocomplete-excluding {
55+
font-family: 'Inter', sans-serif;
56+
}
57+
</style>
58+
<div class="story-root">${story()}</div>
59+
`;
60+
},
61+
],
62+
};

.storybook/vitest.setup.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import { setProjectAnnotations } from '@storybook/web-components-vite';
2+
import * as previewAnnotations from './preview';
3+
4+
setProjectAnnotations([previewAnnotations]);

eslint.config.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,17 @@ export default [
1111
'import/group-exports': 0,
1212
},
1313
},
14+
{
15+
files: ['stories/**/*.ts'],
16+
rules: {
17+
'max-lines': 'off',
18+
},
19+
},
20+
{
21+
files: ['test/**/*.test.ts'],
22+
rules: {
23+
'max-lines': 'off',
24+
'max-lines-per-function': 'off',
25+
},
26+
},
1427
];

0 commit comments

Comments
 (0)