or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

axe-test.mdconfiguration.mdimage-snapshot.mdindex.mdpuppeteer-test.md

image-snapshot.mddocs/

0

# Image Snapshot Testing

1

2

Automated visual regression testing through screenshot capture and comparison using jest-image-snapshot integration.

3

4

## Capabilities

5

6

### Image Snapshot Function

7

8

Creates a test function that captures screenshots of Storybook stories and compares them against stored baseline images.

9

10

```typescript { .api }

11

/**

12

* Creates a test function for automated visual regression testing

13

* @param customConfig - Optional configuration to override defaults

14

* @returns Test function that captures and compares screenshots

15

*/

16

function imageSnapshot(customConfig?: Partial<ImageSnapshotConfig>): TestFunction;

17

18

interface ImageSnapshotConfig extends CommonConfig {

19

/** Function to provide jest-image-snapshot matching options */

20

getMatchOptions: (options: Options) => MatchImageSnapshotOptions | undefined;

21

/** Function to provide Puppeteer screenshot options */

22

getScreenshotOptions: (options: Options) => Base64ScreenShotOptions;

23

/** Hook executed before screenshot capture */

24

beforeScreenshot: (page: Page, options: Options) => Promise<void | ElementHandle>;

25

/** Hook executed after screenshot capture */

26

afterScreenshot: (options: { image: string | void | Buffer; context: Context }) => Promise<void>;

27

}

28

29

interface Base64ScreenShotOptions extends ScreenshotOptions {

30

encoding: 'base64';

31

}

32

```

33

34

**Usage Examples:**

35

36

```typescript

37

import initStoryshots from '@storybook/addon-storyshots';

38

import { imageSnapshot } from '@storybook/addon-storyshots-puppeteer';

39

40

// Basic image snapshot testing

41

initStoryshots({

42

suite: 'Image storyshots',

43

test: imageSnapshot()

44

});

45

46

// With custom match options for jest-image-snapshot

47

initStoryshots({

48

suite: 'Visual regression',

49

test: imageSnapshot({

50

storybookUrl: 'http://localhost:6006',

51

getMatchOptions: ({ context: { kind, story } }) => ({

52

failureThreshold: 0.2,

53

failureThresholdType: 'percent',

54

customSnapshotIdentifier: `${kind}-${story}`

55

})

56

})

57

});

58

```

59

60

### Screenshot Configuration

61

62

Configure Puppeteer screenshot options for precise image capture control.

63

64

```typescript { .api }

65

/**

66

* Function type for providing screenshot options

67

* @param options - Test context and URL information

68

* @returns Screenshot options with base64 encoding

69

*/

70

type GetScreenshotOptions = (options: Options) => Base64ScreenShotOptions;

71

72

interface Base64ScreenShotOptions extends ScreenshotOptions {

73

encoding: 'base64';

74

fullPage?: boolean;

75

clip?: {

76

x: number;

77

y: number;

78

width: number;

79

height: number;

80

};

81

omitBackground?: boolean;

82

quality?: number;

83

type?: 'jpeg' | 'png' | 'webp';

84

}

85

```

86

87

**Usage Examples:**

88

89

```typescript

90

// Custom screenshot options

91

const getScreenshotOptions = ({ context, url }) => ({

92

encoding: 'base64',

93

fullPage: false, // Viewport only

94

type: 'png',

95

omitBackground: true

96

});

97

98

initStoryshots({

99

suite: 'Viewport screenshots',

100

test: imageSnapshot({

101

storybookUrl: 'http://localhost:6006',

102

getScreenshotOptions

103

})

104

});

105

106

// Element-specific screenshots

107

const getScreenshotOptions = ({ context }) => ({

108

encoding: 'base64',

109

fullPage: false,

110

clip: { x: 0, y: 0, width: 800, height: 600 }

111

});

112

```

113

114

### Jest Image Snapshot Integration

115

116

Configure jest-image-snapshot matching behavior for visual comparison.

117

118

```typescript { .api }

119

/**

120

* Function type for providing jest-image-snapshot options

121

* @param options - Test context and URL information

122

* @returns Configuration for image comparison

123

*/

124

type GetMatchOptions = (options: Options) => MatchImageSnapshotOptions | undefined;

125

126

interface MatchImageSnapshotOptions {

127

/** Threshold for pixel differences (0-1) */

128

failureThreshold?: number;

129

/** Type of threshold: 'pixel' | 'percent' */

130

failureThresholdType?: 'pixel' | 'percent';

131

/** Custom snapshot identifier */

132

customSnapshotIdentifier?: string;

133

/** Custom snapshots directory */

134

customSnapshotsDir?: string;

135

/** Custom diff directory */

136

customDiffDir?: string;

137

/** Update snapshots mode */

138

updateSnapshot?: boolean;

139

/** Allow size mismatch */

140

allowSizeMismatch?: boolean;

141

}

142

```

143

144

**Usage Examples:**

145

146

```typescript

147

// Strict visual comparison

148

const getMatchOptions = ({ context: { kind, story } }) => ({

149

failureThreshold: 0.01,

150

failureThresholdType: 'percent',

151

customSnapshotIdentifier: `${kind.replace(/\s+/g, '-')}-${story}`

152

});

153

154

// Relaxed comparison for dynamic content

155

const getMatchOptions = ({ context }) => ({

156

failureThreshold: 0.5,

157

failureThresholdType: 'percent',

158

allowSizeMismatch: true

159

});

160

```

161

162

### Screenshot Lifecycle Hooks

163

164

Control screenshot timing and processing with before and after hooks.

165

166

```typescript { .api }

167

/**

168

* Hook executed before screenshot capture

169

* @param page - Puppeteer page instance

170

* @param options - Test context and URL information

171

* @returns Promise resolving to void or ElementHandle for element screenshots

172

*/

173

type BeforeScreenshot = (page: Page, options: Options) => Promise<void | ElementHandle>;

174

175

/**

176

* Hook executed after screenshot capture

177

* @param params - Screenshot result and context

178

* @returns Promise for post-processing

179

*/

180

type AfterScreenshot = (params: {

181

image: string | void | Buffer;

182

context: Context;

183

}) => Promise<void>;

184

```

185

186

**Usage Examples:**

187

188

```typescript

189

// Wait for animations before screenshot

190

const beforeScreenshot = async (page, { context }) => {

191

// Wait for loading spinners to disappear

192

await page.waitForSelector('.loading', { hidden: true });

193

194

// Trigger hover state for interactive elements

195

if (context.story.includes('hover')) {

196

await page.hover('[data-testid="button"]');

197

}

198

199

// Additional delay for animations

200

await page.waitForTimeout(500);

201

};

202

203

// Screenshot specific element only

204

const beforeScreenshot = async (page) => {

205

return await page.$('#storybook-root > *');

206

};

207

208

// Save screenshot to custom location

209

const afterScreenshot = async ({ image, context }) => {

210

if (image) {

211

const filename = `custom-${context.kind}-${context.story}.png`;

212

require('fs').writeFileSync(`./screenshots/${filename}`, image, 'base64');

213

}

214

};

215

216

initStoryshots({

217

suite: 'Custom lifecycle',

218

test: imageSnapshot({

219

beforeScreenshot,

220

afterScreenshot

221

})

222

});

223

```

224

225

### Default Configuration

226

227

Default values provide full-page screenshots with base64 encoding.

228

229

```typescript { .api }

230

const defaultImageSnapshotConfig: ImageSnapshotConfig = {

231

...defaultCommonConfig,

232

getMatchOptions: () => undefined,

233

getScreenshotOptions: () => ({ fullPage: true, encoding: 'base64' }),

234

beforeScreenshot: () => Promise.resolve(),

235

afterScreenshot: () => Promise.resolve(),

236

};

237

```

238

239

### Jest Integration

240

241

The function automatically extends Jest's expect with toMatchImageSnapshot matcher.

242

243

```typescript { .api }

244

// Automatic Jest extension

245

expect.extend({ toMatchImageSnapshot });

246

247

// Usage in test execution

248

expect(image).toMatchImageSnapshot(matchOptions);

249

```