or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration.mddom-wrapper.mdindex.mdmounting.mdutilities.mdvue-wrapper.md

utilities.mddocs/

0

# Testing Utilities

1

2

Helper functions and utilities for common testing scenarios, including promise resolution, component lifecycle management, server-side rendering, and error handling.

3

4

## Capabilities

5

6

### Promise Resolution

7

8

Utility for flushing all pending promises in the microtask queue, essential for testing async operations.

9

10

```typescript { .api }

11

/**

12

* Flush all pending promises in the microtask queue

13

* Ensures all async operations complete before continuing test execution

14

* @returns Promise that resolves after all pending promises are flushed

15

*/

16

function flushPromises(): Promise<void>;

17

```

18

19

**Usage Examples:**

20

21

```typescript

22

import { mount, flushPromises } from "@vue/test-utils";

23

24

test('async operation handling', async () => {

25

const wrapper = mount(AsyncComponent);

26

27

// Trigger async operation

28

await wrapper.find('button').trigger('click');

29

30

// Wait for all promises to resolve

31

await flushPromises();

32

33

// Now safe to make assertions on async results

34

expect(wrapper.text()).toContain('Async data loaded');

35

});

36

37

test('API call with delay', async () => {

38

const wrapper = mount(ApiComponent);

39

40

// Component makes API call on mount

41

await flushPromises();

42

43

// API response should now be processed

44

expect(wrapper.find('.loading').exists()).toBe(false);

45

expect(wrapper.find('.data').exists()).toBe(true);

46

});

47

```

48

49

### Automatic Component Cleanup

50

51

Utilities for automatically unmounting components after tests to prevent memory leaks and test interference.

52

53

```typescript { .api }

54

/**

55

* Enable automatic unmounting of components after each test

56

* Integrates with test framework hooks to ensure cleanup

57

* @param hook - Test framework hook function (e.g., afterEach)

58

*/

59

function enableAutoUnmount(hook: (callback: () => void) => void): void;

60

61

/**

62

* Disable automatic unmounting and clear tracked instances

63

* Useful when you need manual control over component lifecycle

64

*/

65

function disableAutoUnmount(): void;

66

```

67

68

**Usage Examples:**

69

70

```typescript

71

import { enableAutoUnmount, disableAutoUnmount } from "@vue/test-utils";

72

73

// Jest integration

74

enableAutoUnmount(afterEach);

75

76

// Vitest integration

77

import { afterEach } from 'vitest';

78

enableAutoUnmount(afterEach);

79

80

// Mocha integration

81

enableAutoUnmount(afterEach);

82

83

// Manual control

84

describe('manual cleanup tests', () => {

85

beforeAll(() => {

86

disableAutoUnmount();

87

});

88

89

afterEach(() => {

90

// Manual cleanup when needed

91

wrapper?.unmount();

92

});

93

});

94

```

95

96

### Server-Side Rendering

97

98

Utility for testing Vue components in server-side rendering contexts.

99

100

```typescript { .api }

101

/**

102

* Render a Vue component to HTML string for SSR testing

103

* Uses Vue's server renderer without DOM attachment

104

* @param component - Vue component to render

105

* @param options - Mounting options (attachTo not supported)

106

* @returns Promise resolving to HTML string

107

*/

108

function renderToString<T>(

109

component: T,

110

options?: SSRMountingOptions<T>

111

): Promise<string>;

112

113

interface SSRMountingOptions<T> {

114

/** Component props */

115

props?: ComponentProps<T>;

116

/** Component slots */

117

slots?: Record<string, any>;

118

/** Global configuration */

119

global?: GlobalMountOptions;

120

/** Component attributes */

121

attrs?: Record<string, unknown>;

122

/** Component data override */

123

data?(): Record<string, unknown>;

124

// Note: attachTo is not supported in SSR

125

}

126

```

127

128

**Usage Examples:**

129

130

```typescript

131

import { renderToString } from "@vue/test-utils";

132

133

test('SSR rendering', async () => {

134

const html = await renderToString(MyComponent, {

135

props: {

136

title: "SSR Test",

137

items: ["item1", "item2"]

138

},

139

slots: {

140

default: "Slot content"

141

}

142

});

143

144

expect(html).toContain("SSR Test");

145

expect(html).toContain("item1");

146

expect(html).toContain("Slot content");

147

expect(html).not.toContain("data-v-"); // No scoped CSS in SSR

148

});

149

150

test('SSR with global config', async () => {

151

const html = await renderToString(MyComponent, {

152

global: {

153

provide: {

154

theme: 'dark'

155

},

156

components: {

157

'GlobalComponent': StubComponent

158

}

159

}

160

});

161

162

expect(html).toContain('theme-dark');

163

});

164

```

165

166

### Error Wrapper Creation

167

168

Utility for creating error wrapper proxies that provide better error messages for failed element queries.

169

170

```typescript { .api }

171

/**

172

* Create error wrapper proxy for failed find operations

173

* Provides helpful error messages and supports method chaining

174

* @param selector - The selector that failed to match

175

* @returns Proxy that throws on method calls except exists()

176

*/

177

function createWrapperError(selector: string): WrapperLike;

178

179

interface WrapperLike {

180

/** Returns false for error wrappers */

181

exists(): boolean;

182

/** Throws error for any other method calls */

183

[key: string]: any;

184

}

185

```

186

187

**Usage Examples:**

188

189

```typescript

190

import { mount } from "@vue/test-utils";

191

192

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

193

const wrapper = mount(MyComponent);

194

195

// This creates an error wrapper since selector doesn't exist

196

const errorWrapper = wrapper.find('.non-existent');

197

198

// exists() returns false without throwing

199

expect(errorWrapper.exists()).toBe(false);

200

201

// Other methods throw helpful errors

202

expect(() => errorWrapper.text()).toThrow(

203

'Cannot call text on an empty wrapper'

204

);

205

206

expect(() => errorWrapper.trigger('click')).toThrow(

207

'Cannot call trigger on an empty wrapper'

208

);

209

});

210

211

// Practical usage with conditional logic

212

test('conditional element testing', () => {

213

const wrapper = mount(MyComponent);

214

const optionalElement = wrapper.find('.optional-element');

215

216

if (optionalElement.exists()) {

217

expect(optionalElement.text()).toBe('Optional content');

218

}

219

});

220

```

221

222

### RouterLink Stub Component

223

224

Pre-built stub component for Vue Router's RouterLink to simplify router testing.

225

226

```typescript { .api }

227

/**

228

* Stub component for Vue Router's RouterLink

229

* Provides mock router functionality for testing without requiring actual router

230

* Renders as anchor tag by default, supports custom rendering with custom prop

231

*/

232

const RouterLinkStub: Component & {

233

props: {

234

/** Router link destination (route path or route object) */

235

to: string | RouteLocationRaw;

236

/** Enable custom rendering (renders slot content without wrapper) */

237

custom?: boolean;

238

};

239

/** Mock router link composable values */

240

setup(): {

241

/** Mock route object */

242

route: RouteLocationNormalizedLoaded;

243

/** Mock href value */

244

href: string;

245

/** Mock active state */

246

isActive: boolean;

247

/** Mock exact active state */

248

isExactActive: boolean;

249

/** Mock navigation function */

250

navigate: (e?: MouseEvent) => void;

251

};

252

};

253

```

254

255

**Usage Examples:**

256

257

```typescript

258

import { mount, RouterLinkStub } from "@vue/test-utils";

259

260

test('router link interaction', async () => {

261

const wrapper = mount(MyComponent, {

262

global: {

263

stubs: {

264

'router-link': RouterLinkStub

265

}

266

}

267

});

268

269

const routerLink = wrapper.findComponent(RouterLinkStub);

270

expect(routerLink.props('to')).toBe('/target-route');

271

272

// RouterLinkStub provides mock router functionality

273

await routerLink.trigger('click');

274

expect(routerLink.emitted('navigate')).toHaveLength(1);

275

});

276

277

// Global stub configuration

278

import { config, RouterLinkStub } from "@vue/test-utils";

279

280

config.global.stubs = {

281

'router-link': RouterLinkStub

282

};

283

```

284

285

## Integration Patterns

286

287

Common patterns for integrating utilities with different testing frameworks.

288

289

### Jest Integration

290

291

```typescript

292

import { enableAutoUnmount, flushPromises } from "@vue/test-utils";

293

294

// Global setup

295

enableAutoUnmount(afterEach);

296

297

// In tests

298

beforeEach(async () => {

299

// Ensure clean state

300

await flushPromises();

301

});

302

```

303

304

### Vitest Integration

305

306

```typescript

307

import { enableAutoUnmount, flushPromises } from "@vue/test-utils";

308

import { afterEach, beforeEach } from 'vitest';

309

310

enableAutoUnmount(afterEach);

311

312

beforeEach(async () => {

313

await flushPromises();

314

});

315

```

316

317

### Custom Test Helpers

318

319

```typescript

320

import { mount, flushPromises } from "@vue/test-utils";

321

322

// Custom helper combining mounting and promise flushing

323

export async function mountAndFlush(component, options = {}) {

324

const wrapper = mount(component, options);

325

await flushPromises();

326

return wrapper;

327

}

328

329

// Custom helper for SSR testing

330

export async function renderAndTest(component, options = {}) {

331

const html = await renderToString(component, options);

332

return {

333

html,

334

contains: (text) => html.includes(text),

335

hasClass: (className) => html.includes(`class="${className}"`),

336

hasAttribute: (attr, value) => html.includes(`${attr}="${value}"`)

337

};

338

}

339

```

340

341

## Error Handling

342

343

Utility functions handle errors in these scenarios:

344

345

- **flushPromises**: Rarely throws, but may propagate unhandled promise rejections

346

- **enableAutoUnmount**: Throws if hook function is invalid

347

- **renderToString**: Throws if component rendering fails or options are invalid

348

- **createWrapperError**: Creates proxies that throw descriptive errors on method calls

349

350

```typescript

351

import { flushPromises, renderToString } from "@vue/test-utils";

352

353

try {

354

await flushPromises();

355

} catch (error) {

356

// Handle any unhandled promise rejections

357

console.error('Promise flush error:', error);

358

}

359

360

try {

361

const html = await renderToString(BrokenComponent);

362

} catch (error) {

363

console.error('SSR render error:', error.message);

364

}

365

```