or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

browser-apis.mdcanvas-context.mdindex.mdsetup.mdtest-utilities.md
tile.json

test-utilities.mddocs/

0

# Test Utilities

1

2

Special testing methods added to CanvasRenderingContext2D for Jest testing. These methods track canvas operations and provide utilities for snapshot testing, assertions, and debugging canvas behavior in tests. All tracking methods record operations with transformation state and relevant properties.

3

4

## Capabilities

5

6

### Event Tracking

7

8

Methods for tracking all canvas context operations including property changes and method calls.

9

10

```javascript { .api }

11

/**

12

* Get all the events associated with this CanvasRenderingContext2D object

13

* Records every property set and method call with transformation state

14

* @returns Array of all canvas context events since creation or last clear

15

*/

16

__getEvents(): CanvasRenderingContext2DEvent[];

17

18

/**

19

* Clear all the events associated with this CanvasRenderingContext2D object

20

* Resets the event tracking array to empty state

21

*/

22

__clearEvents(): void;

23

```

24

25

**Usage Examples:**

26

27

```javascript

28

const canvas = document.createElement('canvas');

29

const ctx = canvas.getContext('2d');

30

31

// Perform some canvas operations

32

ctx.fillStyle = '#ff0000';

33

ctx.fillRect(10, 10, 100, 100);

34

ctx.strokeStyle = '#00ff00';

35

ctx.lineWidth = 2;

36

ctx.strokeRect(20, 20, 80, 80);

37

38

// Get all events for snapshot testing

39

const events = ctx.__getEvents();

40

expect(events).toMatchSnapshot();

41

42

// Clear events for next test phase

43

ctx.__clearEvents();

44

expect(ctx.__getEvents()).toHaveLength(0);

45

```

46

47

### Draw Call Tracking

48

49

Methods for tracking actual drawing operations (operations that modify pixels on the canvas).

50

51

```javascript { .api }

52

/**

53

* Get all the successful draw calls associated with this CanvasRenderingContext2D object

54

* Only includes operations that actually draw pixels: fill, stroke, fillText, strokeText, drawImage

55

* @returns Array of draw call events with transformation state and properties

56

*/

57

__getDrawCalls(): CanvasRenderingContext2DEvent[];

58

59

/**

60

* Clear all the successful draw calls associated with this CanvasRenderingContext2D object

61

* Resets the draw calls tracking array to empty state

62

*/

63

__clearDrawCalls(): void;

64

```

65

66

**Usage Examples:**

67

68

```javascript

69

const canvas = document.createElement('canvas');

70

const ctx = canvas.getContext('2d');

71

72

// Non-drawing operations (not tracked in draw calls)

73

ctx.beginPath();

74

ctx.moveTo(10, 10);

75

ctx.lineTo(100, 100);

76

ctx.fillStyle = '#ff0000';

77

78

// Drawing operations (tracked in draw calls)

79

ctx.fill();

80

ctx.fillText('Hello', 50, 50);

81

82

// Get only the actual draw operations

83

const drawCalls = ctx.__getDrawCalls();

84

expect(drawCalls).toHaveLength(2);

85

expect(drawCalls[0].type).toBe('fill');

86

expect(drawCalls[1].type).toBe('fillText');

87

88

// Clear draw calls

89

ctx.__clearDrawCalls();

90

expect(ctx.__getDrawCalls()).toHaveLength(0);

91

```

92

93

### Path Tracking

94

95

Methods for tracking the current path construction and modification.

96

97

```javascript { .api }

98

/**

99

* Get the current path associated with this CanvasRenderingContext2D object

100

* Returns all path construction commands since the last beginPath call

101

* @returns Array of path events representing the current path state

102

*/

103

__getPath(): CanvasRenderingContext2DEvent[];

104

105

/**

106

* Clears the current path associated with this CanvasRenderingContext2D object

107

* Resets path to a single beginPath event and updates clipping index

108

*/

109

__clearPath(): void;

110

```

111

112

**Usage Examples:**

113

114

```javascript

115

const canvas = document.createElement('canvas');

116

const ctx = canvas.getContext('2d');

117

118

// Build a complex path

119

ctx.beginPath();

120

ctx.arc(50, 50, 20, 0, Math.PI * 2);

121

ctx.moveTo(100, 50);

122

ctx.lineTo(150, 100);

123

ctx.quadraticCurveTo(175, 75, 200, 100);

124

ctx.closePath();

125

126

// Get the path for testing

127

const path = ctx.__getPath();

128

expect(path).toMatchSnapshot();

129

expect(path[0].type).toBe('beginPath');

130

expect(path[1].type).toBe('arc');

131

expect(path[2].type).toBe('moveTo');

132

133

// Clear path (resets to beginPath)

134

ctx.__clearPath();

135

const clearedPath = ctx.__getPath();

136

expect(clearedPath).toHaveLength(1);

137

expect(clearedPath[0].type).toBe('beginPath');

138

```

139

140

### Clipping Region Tracking

141

142

Method for tracking clipping operations and the current clipping region.

143

144

```javascript { .api }

145

/**

146

* Obtains the current clipping path

147

* Returns the portion of the current path that represents the clipping region

148

* @returns Array of path events representing the current clipping region

149

*/

150

__getClippingRegion(): CanvasRenderingContext2DEvent[];

151

```

152

153

**Usage Examples:**

154

155

```javascript

156

const canvas = document.createElement('canvas');

157

const ctx = canvas.getContext('2d');

158

159

// Create a clipping path

160

ctx.beginPath();

161

ctx.rect(25, 25, 100, 100);

162

ctx.clip();

163

164

// Add more to the path after clipping

165

ctx.rect(0, 0, 50, 50);

166

167

// Get only the clipping region

168

const clippingRegion = ctx.__getClippingRegion();

169

expect(clippingRegion).toMatchSnapshot();

170

171

// The clipping region cannot be cleared as it's based on stack values

172

// and when the clip() function is called

173

```

174

175

## Event Object Structure

176

177

All tracking methods return arrays of `CanvasRenderingContext2DEvent` objects:

178

179

```javascript { .api }

180

interface CanvasRenderingContext2DEvent {

181

/**

182

* The type of canvas event that occurred (method name or property name)

183

*/

184

type: string;

185

186

/**

187

* Six-element array containing the current transformation matrix state

188

* Format: [a, b, c, d, e, f] representing the transform matrix

189

*/

190

transform: [number, number, number, number, number, number];

191

192

/**

193

* Relevant properties and parameters related to this canvas event

194

* Contains method arguments, property values, and other contextual data

195

*/

196

props: { [key: string]: any };

197

}

198

```

199

200

**Event Type Examples:**

201

202

- Method calls: `"fillRect"`, `"arc"`, `"drawImage"`, `"save"`, `"restore"`

203

- Property sets: `"fillStyle"`, `"lineWidth"`, `"font"`, `"globalAlpha"`

204

- Path operations: `"beginPath"`, `"moveTo"`, `"lineTo"`, `"closePath"`

205

206

**Transform Array:**

207

208

The transform array represents the current transformation matrix as `[a, b, c, d, e, f]` where:

209

- `a` (m11): Horizontal scaling

210

- `b` (m12): Horizontal skewing

211

- `c` (m21): Vertical skewing

212

- `d` (m22): Vertical scaling

213

- `e` (m41): Horizontal translation

214

- `f` (m42): Vertical translation

215

216

**Props Object:**

217

218

Contains relevant data for the operation:

219

- Method arguments: `{ x: 10, y: 20, width: 100, height: 50 }`

220

- Property values: `{ fillStyle: "#ff0000" }`

221

- Additional context: `{ anticlockwise: false, radius: 25 }`

222

223

## Advanced Testing Patterns

224

225

### Snapshot Testing Workflow

226

227

```javascript

228

describe('Canvas drawing operations', () => {

229

let canvas, ctx;

230

231

beforeEach(() => {

232

canvas = document.createElement('canvas');

233

ctx = canvas.getContext('2d');

234

});

235

236

test('complex drawing sequence', () => {

237

// Setup

238

ctx.fillStyle = '#ff0000';

239

ctx.strokeStyle = '#00ff00';

240

ctx.lineWidth = 3;

241

242

// Drawing operations

243

ctx.fillRect(10, 10, 100, 100);

244

ctx.strokeRect(15, 15, 90, 90);

245

246

// Test complete operation sequence

247

expect(ctx.__getEvents()).toMatchSnapshot();

248

249

// Test only actual drawing calls

250

expect(ctx.__getDrawCalls()).toMatchSnapshot();

251

});

252

});

253

```

254

255

### Incremental Testing

256

257

```javascript

258

test('incremental canvas operations', () => {

259

const canvas = document.createElement('canvas');

260

const ctx = canvas.getContext('2d');

261

262

// Phase 1: Setup

263

ctx.fillStyle = '#ff0000';

264

ctx.beginPath();

265

expect(ctx.__getEvents()).toHaveLength(2);

266

267

// Phase 2: Path construction

268

ctx.arc(50, 50, 25, 0, Math.PI * 2);

269

ctx.closePath();

270

expect(ctx.__getPath()).toHaveLength(3); // beginPath, arc, closePath

271

272

// Phase 3: Drawing

273

ctx.__clearEvents(); // Clear setup events

274

ctx.fill();

275

276

const drawCalls = ctx.__getDrawCalls();

277

expect(drawCalls).toHaveLength(1);

278

expect(drawCalls[0].type).toBe('fill');

279

});

280

```

281

282

### Error Validation Testing

283

284

```javascript

285

test('canvas error behavior', () => {

286

const canvas = document.createElement('canvas');

287

const ctx = canvas.getContext('2d');

288

289

// Test parameter validation

290

expect(() => ctx.arc(0, 0, -5, 0, Math.PI)).toThrow(DOMException);

291

expect(() => ctx.arc(0, 0)).toThrow(TypeError);

292

293

// Verify error operations are still tracked

294

const events = ctx.__getEvents();

295

expect(events.some(e => e.type === 'arc')).toBe(true);

296

});

297

```