or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

assertions.mddom-testing.mdindex.mdmocking.md

index.mddocs/

0

# Storybook Test

1

2

The `@storybook/test` package provides instrumented testing utilities specifically designed for Storybook stories' play functions. It exports enhanced versions of popular testing libraries including @vitest/spy, @vitest/expect, @testing-library/dom, and @testing-library/user-event, with instrumentation that enables debugging capabilities in the addon-interactions panel.

3

4

## Package Information

5

6

- **Package Name**: @storybook/test

7

- **Package Type**: npm

8

- **Language**: TypeScript

9

- **Installation**: `npm install -D @storybook/test`

10

11

## Core Imports

12

13

```typescript

14

import { expect, fn, userEvent, within } from '@storybook/test';

15

```

16

17

For CommonJS:

18

19

```javascript

20

const { expect, fn, userEvent, within } = require('@storybook/test');

21

```

22

23

## Basic Usage

24

25

```typescript

26

import { expect, fn, userEvent, within } from '@storybook/test';

27

import { Button } from './Button';

28

29

export default {

30

component: Button,

31

args: {

32

onClick: fn(),

33

},

34

};

35

36

export const Demo = {

37

play: async ({ args, canvasElement }) => {

38

const canvas = within(canvasElement);

39

await userEvent.click(canvas.getByRole('button'));

40

await expect(args.onClick).toHaveBeenCalled();

41

},

42

};

43

```

44

45

## Architecture

46

47

Storybook Test is built around several key components:

48

49

- **Instrumentation Layer**: All functions are wrapped with Storybook's instrumenter for addon-interactions debugging

50

- **Assertion Engine**: Enhanced expect function based on @vitest/expect and chai with testing-library matchers

51

- **Mock System**: Reactive spy and mock functions that integrate with Storybook's interaction tracking

52

- **DOM Testing**: Complete testing-library integration for DOM querying and user interaction simulation

53

- **Auto-Enhancement**: Automatic story argument processing to wrap actions in spies and enhance contexts

54

55

## Capabilities

56

57

### Assertions

58

59

Powerful assertion library based on @vitest/expect with testing-library DOM matchers and full chai compatibility.

60

61

```typescript { .api }

62

interface Expect extends AsymmetricMatchersContaining {

63

<T>(actual: T, message?: string): Assertion<T>;

64

unreachable(message?: string): Promise<never>;

65

soft<T>(actual: T, message?: string): Assertion<T>;

66

extend(expects: MatchersObject): void;

67

assertions(expected: number): Promise<void>;

68

hasAssertions(): Promise<void>;

69

anything(): any;

70

any(constructor: unknown): any;

71

getState(): MatcherState;

72

setState(state: Partial<MatcherState>): void;

73

not: AsymmetricMatchersContaining;

74

}

75

```

76

77

[Assertions](./assertions.md)

78

79

### Mocking and Spying

80

81

Mock functions and spies with reactive instrumentation for Storybook integration. Includes automatic cleanup and enhanced debugging.

82

83

```typescript { .api }

84

function fn<T extends Procedure = Procedure>(implementation?: T): Mock<T>;

85

function spyOn<T, K extends keyof T>(

86

object: T,

87

method: K

88

): MockInstance;

89

90

function clearAllMocks(): void;

91

function resetAllMocks(): void;

92

function restoreAllMocks(): void;

93

function onMockCall(callback: Listener): () => void;

94

```

95

96

[Mocking and Spying](./mocking.md)

97

98

### DOM Testing

99

100

Complete DOM testing utilities including queries, user interactions, and async utilities. All functions are instrumented for Storybook debugging.

101

102

```typescript { .api }

103

// Query functions (get, find, query variants)

104

function getByRole(container: HTMLElement, role: string, options?: ByRoleOptions): HTMLElement;

105

function findByText(container: HTMLElement, text: string, options?: SelectorMatcherOptions): Promise<HTMLElement>;

106

function queryByTestId(container: HTMLElement, testId: string, options?: MatcherOptions): HTMLElement | null;

107

108

// Scoping utility

109

function within(element: HTMLElement): BoundFunctions<typeof queries>;

110

111

// User interactions

112

interface UserEvent {

113

click(element: Element, options?: ClickOptions): Promise<void>;

114

type(element: Element, text: string, options?: TypeOptions): Promise<void>;

115

clear(element: Element): Promise<void>;

116

selectOptions(element: Element, values: string | string[]): Promise<void>;

117

upload(element: Element, file: File | File[]): Promise<void>;

118

}

119

120

// Async utilities

121

function waitFor<T>(callback: () => T | Promise<T>, options?: WaitForOptions): Promise<T>;

122

function waitForElementToBeRemoved(callback: () => Element | Element[]): Promise<void>;

123

```

124

125

[DOM Testing](./dom-testing.md)

126

127

## Types

128

129

### Core Types

130

131

```typescript { .api }

132

type Procedure = (...args: any[]) => any;

133

134

type MockV2<T extends Procedure> = MockInstance<Parameters<T>, ReturnType<T>> & T;

135

136

type Mock<T extends Procedure | any[] = any[], R = any> = T extends Procedure

137

? MockV2<T>

138

: T extends any[]

139

? MockV2<(...args: T) => R>

140

: never;

141

142

interface MockInstance<TArgs extends any[] = any[], TReturns = any> {

143

getMockName(): string;

144

mockName(name: string): this;

145

mockClear(): this;

146

mockReset(): this;

147

mockRestore(): void;

148

mockImplementation(fn?: (...args: TArgs) => TReturns): this;

149

mockImplementationOnce(fn: (...args: TArgs) => TReturns): this;

150

mockReturnValue(value: TReturns): this;

151

mockReturnValueOnce(value: TReturns): this;

152

mockResolvedValue(value: Awaited<TReturns>): this;

153

mockResolvedValueOnce(value: Awaited<TReturns>): this;

154

mockRejectedValue(value: any): this;

155

mockRejectedValueOnce(value: any): this;

156

}

157

158

// Jest-compatible assertion types

159

interface JestAssertion<T = any> {

160

toBe(expected: T): void;

161

toEqual(expected: T): void;

162

toStrictEqual(expected: T): void;

163

toContain(expected: any): void;

164

toHaveLength(expected: number): void;

165

// ... other Jest matchers

166

}

167

168

// Testing Library DOM matchers

169

interface TestingLibraryMatchers<R, T> {

170

toBeInTheDocument(): R;

171

toBeVisible(): R;

172

toBeEmpty(): R;

173

toBeDisabled(): R;

174

toBeEnabled(): R;

175

toBeRequired(): R;

176

toBeValid(): R;

177

toBeInvalid(): R;

178

toHaveAttribute(attr: string, value?: string): R;

179

toHaveClass(...classNames: string[]): R;

180

toHaveStyle(css: string | Record<string, any>): R;

181

toHaveTextContent(text: string | RegExp): R;

182

toHaveValue(value: string | string[] | number): R;

183

toHaveDisplayValue(value: string | RegExp | Array<string | RegExp>): R;

184

toBeChecked(): R;

185

toHaveFormValues(expectedValues: Record<string, any>): R;

186

toHaveFocus(): R;

187

toHaveAccessibleName(expectedAccessibleName?: string | RegExp): R;

188

toHaveAccessibleDescription(expectedAccessibleDescription?: string | RegExp): R;

189

toHaveErrorMessage(expectedErrorMessage?: string | RegExp): R;

190

}

191

192

// Expect static type

193

interface ExpectStatic {

194

<T>(actual: T): JestAssertion<T>;

195

stringContaining(expected: string): any;

196

arrayContaining<T = any>(expected: readonly T[]): any;

197

objectContaining(expected: Record<string, any>): any;

198

any(constructor: any): any;

199

anything(): any;

200

}

201

202

// Utility types

203

type Promisify<Fn> = Fn extends (...args: infer A) => infer R

204

? (...args: A) => R extends Promise<any> ? R : Promise<R>

205

: Fn;

206

207

type PromisifyObject<O> = { [K in keyof O]: Promisify<O[K]> };

208

209

interface Assertion<T> extends PromisifyObject<JestAssertion<T>>, TestingLibraryMatchers<ReturnType<ExpectStatic['stringContaining']>, Promise<void>> {

210

toHaveBeenCalledOnce(): Promise<void>;

211

toSatisfy<E>(matcher: (value: E) => boolean, message?: string): Promise<void>;

212

resolves: Assertion<T>;

213

rejects: Assertion<T>;

214

not: Assertion<T>;

215

}

216

217

type BoundFunctions<T> = {

218

[K in keyof T]: T[K] extends (...args: any[]) => any

219

? (...args: Parameters<T[K]>) => ReturnType<T[K]>

220

: T[K];

221

};

222

223

// DOM Testing option types

224

interface MatcherOptions {

225

exact?: boolean;

226

normalizer?: (text: string) => string;

227

}

228

229

interface SelectorMatcherOptions extends MatcherOptions {

230

selector?: string;

231

}

232

233

interface ByRoleOptions extends MatcherOptions {

234

checked?: boolean;

235

selected?: boolean;

236

expanded?: boolean;

237

pressed?: boolean;

238

level?: number;

239

name?: string | RegExp;

240

description?: string | RegExp;

241

}

242

243

interface WaitForOptions {

244

timeout?: number;

245

interval?: number;

246

onTimeout?: (error: Error) => Error;

247

mutationObserverOptions?: MutationObserverInit;

248

}

249

250

interface ClickOptions {

251

altKey?: boolean;

252

button?: number;

253

buttons?: number;

254

clientX?: number;

255

clientY?: number;

256

ctrlKey?: boolean;

257

detail?: number;

258

metaKey?: boolean;

259

relatedTarget?: Element | null;

260

screenX?: number;

261

screenY?: number;

262

shiftKey?: boolean;

263

}

264

265

interface TypeOptions {

266

delay?: number;

267

skipClick?: boolean;

268

skipAutoClose?: boolean;

269

initialSelectionStart?: number;

270

initialSelectionEnd?: number;

271

}

272

```

273

274

### Utility Types

275

276

```typescript { .api }

277

type MaybeMocked<T> = T & {

278

[K in keyof T]: T[K] extends (...args: any[]) => any

279

? MockInstance<Parameters<T[K]>, ReturnType<T[K]>>

280

: T[K];

281

};

282

283

type MaybeMockedDeep<T> = T & {

284

[K in keyof T]: T[K] extends (...args: any[]) => any

285

? MockInstance<Parameters<T[K]>, ReturnType<T[K]>>

286

: MaybeMockedDeep<T[K]>;

287

};

288

289

type MaybePartiallyMocked<T> = {

290

[K in keyof T]?: T[K] extends (...args: any[]) => any

291

? MockInstance<Parameters<T[K]>, ReturnType<T[K]>>

292

: T[K];

293

};

294

295

type MaybePartiallyMockedDeep<T> = {

296

[K in keyof T]?: T[K] extends (...args: any[]) => any

297

? MockInstance<Parameters<T[K]>, ReturnType<T[K]>>

298

: MaybePartiallyMockedDeep<T[K]>;

299

};

300

301

type Promisify<Fn> = Fn extends (...args: infer A) => infer R

302

? (...args: A) => R extends Promise<any> ? R : Promise<R>

303

: Fn;

304

305

type PromisifyObject<O> = { [K in keyof O]: Promisify<O[K]> };

306

```