UNPKG

@storybook/addon-vitest

Version:
185 lines (179 loc) 6.39 kB
import { Vitest, TestSpecification, TestProject, WorkspaceProject, ResolvedCoverageOptions } from 'vitest/node'; import { ReportBase, Visitor, ReportNode } from 'istanbul-lib-report'; import { ThrottledFunction } from './function/throttle.js'; import { TestResult } from 'vitest/dist/node.js'; import { experimental_UniversalStore } from 'storybook/internal/core-server'; import { API_HashEntry, PreviewAnnotation, StoryId, Options, StatusStoreByTypeId, TestProviderStoreById } from 'storybook/internal/types'; import { Report } from 'storybook/preview-api'; interface VitestError extends Error { VITEST_TEST_PATH?: string; VITEST_TEST_NAME?: string; stacks?: Array<{ line: number; column: number; file: string; method: string; }>; } type ErrorLike = { message: string; name?: string; stack?: string; cause?: ErrorLike; }; type RunTrigger = 'run-all' | 'global' | 'watch' | Extract<API_HashEntry['type'], string>; type StoreState = { config: { coverage: boolean; a11y: boolean; }; watching: boolean; cancelling: boolean; indexUrl: string | undefined; previewAnnotations: PreviewAnnotation[]; fatalError: { message: string | undefined; error: ErrorLike; } | undefined; currentRun: { triggeredBy: RunTrigger | undefined; config: StoreState['config']; componentTestCount: { success: number; error: number; }; a11yCount: { success: number; warning: number; error: number; }; totalTestCount: number | undefined; storyIds: StoryId[] | undefined; startedAt: number | undefined; finishedAt: number | undefined; unhandledErrors: VitestError[]; coverageSummary: { status: 'positive' | 'warning' | 'negative' | 'unknown'; percentage: number; } | undefined; }; }; type TriggerRunEvent = { type: 'TRIGGER_RUN'; payload: { storyIds?: string[] | undefined; triggeredBy: RunTrigger; }; }; type CancelRunEvent = { type: 'CANCEL_RUN'; }; type ToggleWatchingEvent = { type: 'TOGGLE_WATCHING'; payload: { to: boolean; }; }; type FatalErrorEvent = { type: 'FATAL_ERROR'; payload: { message: string; error: ErrorLike; }; }; type TestRunCompletedEvent = { type: 'TEST_RUN_COMPLETED'; payload: StoreState['currentRun']; }; type StoreEvent = TriggerRunEvent | CancelRunEvent | FatalErrorEvent | ToggleWatchingEvent | TestRunCompletedEvent; declare class VitestManager { private testManager; vitest: Vitest | null; vitestStartupCounter: number; vitestRestartPromise: Promise<void> | null; runningPromise: Promise<any> | null; constructor(testManager: TestManager); startVitest({ coverage }: { coverage: boolean; }): Promise<void>; restartVitest({ coverage }: { coverage: boolean; }): Promise<void>; private resetGlobalTestNamePattern; private updateLastChanged; private fetchStories; private filterTestSpecifications; runTests(runPayload: TriggerRunEvent['payload']): Promise<void>; cancelCurrentRun(): Promise<void>; getStorybookTestSpecifications(): Promise<TestSpecification[]>; runAffectedTestsAfterChange(changedFilePath: string, event: 'change' | 'add'): Promise<void>; private getTestDependencies; registerVitestConfigListener(): Promise<void>; setupWatchers(): Promise<void>; isStorybookProject(project: TestProject | WorkspaceProject): boolean; } type TestManagerOptions = { storybookOptions: Options; store: experimental_UniversalStore<StoreState, StoreEvent>; componentTestStatusStore: StatusStoreByTypeId; a11yStatusStore: StatusStoreByTypeId; testProviderStore: TestProviderStoreById; onError?: (message: string, error: Error) => void; onReady?: () => void; }; declare class TestManager { store: TestManagerOptions['store']; vitestManager: VitestManager; private componentTestStatusStore; private a11yStatusStore; private testProviderStore; private onReady?; storybookOptions: Options; private batchedTestCaseResults; constructor(options: TestManagerOptions); handleTriggerRunEvent(event: TriggerRunEvent): Promise<void>; handleCancelEvent(): Promise<void>; runTestsWithState({ storyIds, triggeredBy, callback, }: { storyIds?: string[]; triggeredBy: RunTrigger; callback: () => Promise<void>; }): Promise<void>; onTestModuleCollected(collectedTestCount: number): void; onTestCaseResult(result: { storyId?: string; testResult: TestResult; reports?: Report[]; }): void; /** * Throttled function to process batched test case results. * * This function: * * 1. Takes all batched test case results and clears the batch * 2. Updates the store state with new test counts (component tests and a11y tests) * 3. Adjusts the totalTestCount if more tests were run than initially anticipated * 4. Creates status objects for component tests and updates the component test status store * 5. Creates status objects for a11y tests (if any) and updates the a11y status store * * The throttling (500ms) is necessary as the channel would otherwise get overwhelmed with events, * eventually causing the manager and dev server to lose connection. */ throttledFlushTestCaseResults: ThrottledFunction<() => void>; onTestRunEnd(endResult: { totalTestCount: number; unhandledErrors: VitestError[]; }): void; onCoverageCollected(coverageSummary: StoreState['currentRun']['coverageSummary']): void; reportFatalError(message: string, error: Error | any): Promise<void>; static start(options: TestManagerOptions): Promise<TestManager>; } type StorybookCoverageReporterOptions = { testManager: TestManager; coverageOptions: ResolvedCoverageOptions<'v8'> | undefined; }; declare class StorybookCoverageReporter extends ReportBase implements Partial<Visitor> { #private; constructor(opts: StorybookCoverageReporterOptions); onSummary(node: ReportNode): void; } export { StorybookCoverageReporterOptions, StorybookCoverageReporter as default };