or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

async-utilities.mdconfiguration.mdevents.mdindex.mdqueries.mdscoping.mduser-interactions.md

events.mddocs/

0

# Event Handling

1

2

Direct DOM event triggering capabilities for lower-level interaction testing, with full instrumentation support. The `fireEvent` object provides methods for dispatching DOM events directly, useful for testing edge cases and low-level interactions.

3

4

## Capabilities

5

6

### Fire Event Object

7

8

Main interface for triggering DOM events directly. All fireEvent methods are instrumented for Storybook interaction tracking.

9

10

```typescript { .api }

11

/**

12

* Fire DOM events directly on elements

13

* All methods are instrumented for Storybook interaction tracking

14

*/

15

interface FireEvent {

16

/**

17

* Dispatch a custom event on an element

18

* @param element - Target element

19

* @param event - Event object to dispatch

20

* @returns Boolean indicating if event was not cancelled

21

*/

22

(element: Element, event: Event): boolean;

23

24

/**

25

* Fire a click event

26

* @param element - Element to click

27

* @param options - Mouse event options

28

* @returns Boolean indicating if event was not cancelled

29

*/

30

click(element: Element, options?: MouseEventInit): boolean;

31

32

/**

33

* Fire a double-click event

34

* @param element - Element to double-click

35

* @param options - Mouse event options

36

* @returns Boolean indicating if event was not cancelled

37

*/

38

dblClick(element: Element, options?: MouseEventInit): boolean;

39

40

/**

41

* Fire a mouse down event

42

* @param element - Target element

43

* @param options - Mouse event options

44

* @returns Boolean indicating if event was not cancelled

45

*/

46

mouseDown(element: Element, options?: MouseEventInit): boolean;

47

48

/**

49

* Fire a mouse up event

50

* @param element - Target element

51

* @param options - Mouse event options

52

* @returns Boolean indicating if event was not cancelled

53

*/

54

mouseUp(element: Element, options?: MouseEventInit): boolean;

55

56

/**

57

* Fire a mouse enter event

58

* @param element - Target element

59

* @param options - Mouse event options

60

* @returns Boolean indicating if event was not cancelled

61

*/

62

mouseEnter(element: Element, options?: MouseEventInit): boolean;

63

64

/**

65

* Fire a mouse leave event

66

* @param element - Target element

67

* @param options - Mouse event options

68

* @returns Boolean indicating if event was not cancelled

69

*/

70

mouseLeave(element: Element, options?: MouseEventInit): boolean;

71

72

/**

73

* Fire a mouse move event

74

* @param element - Target element

75

* @param options - Mouse event options

76

* @returns Boolean indicating if event was not cancelled

77

*/

78

mouseMove(element: Element, options?: MouseEventInit): boolean;

79

80

/**

81

* Fire a mouse over event

82

* @param element - Target element

83

* @param options - Mouse event options

84

* @returns Boolean indicating if event was not cancelled

85

*/

86

mouseOver(element: Element, options?: MouseEventInit): boolean;

87

88

/**

89

* Fire a mouse out event

90

* @param element - Target element

91

* @param options - Mouse event options

92

* @returns Boolean indicating if event was not cancelled

93

*/

94

mouseOut(element: Element, options?: MouseEventInit): boolean;

95

96

/**

97

* Fire a change event (for form elements)

98

* @param element - Form element

99

* @param options - Event options

100

* @returns Boolean indicating if event was not cancelled

101

*/

102

change(element: Element, options?: EventInit): boolean;

103

104

/**

105

* Fire an input event (for form elements)

106

* @param element - Form element

107

* @param options - Event options

108

* @returns Boolean indicating if event was not cancelled

109

*/

110

input(element: Element, options?: EventInit): boolean;

111

112

/**

113

* Fire a focus event

114

* @param element - Element to focus

115

* @param options - Focus event options

116

* @returns Boolean indicating if event was not cancelled

117

*/

118

focus(element: Element, options?: FocusEventInit): boolean;

119

120

/**

121

* Fire a blur event

122

* @param element - Element to blur

123

* @param options - Focus event options

124

* @returns Boolean indicating if event was not cancelled

125

*/

126

blur(element: Element, options?: FocusEventInit): boolean;

127

128

/**

129

* Fire a focus-in event

130

* @param element - Target element

131

* @param options - Focus event options

132

* @returns Boolean indicating if event was not cancelled

133

*/

134

focusIn(element: Element, options?: FocusEventInit): boolean;

135

136

/**

137

* Fire a focus-out event

138

* @param element - Target element

139

* @param options - Focus event options

140

* @returns Boolean indicating if event was not cancelled

141

*/

142

focusOut(element: Element, options?: FocusEventInit): boolean;

143

144

/**

145

* Fire a key down event

146

* @param element - Target element

147

* @param options - Keyboard event options

148

* @returns Boolean indicating if event was not cancelled

149

*/

150

keyDown(element: Element, options?: KeyboardEventInit): boolean;

151

152

/**

153

* Fire a key up event

154

* @param element - Target element

155

* @param options - Keyboard event options

156

* @returns Boolean indicating if event was not cancelled

157

*/

158

keyUp(element: Element, options?: KeyboardEventInit): boolean;

159

160

/**

161

* Fire a key press event (deprecated but available)

162

* @param element - Target element

163

* @param options - Keyboard event options

164

* @returns Boolean indicating if event was not cancelled

165

*/

166

keyPress(element: Element, options?: KeyboardEventInit): boolean;

167

168

/**

169

* Fire a submit event on a form

170

* @param element - Form element

171

* @param options - Event options

172

* @returns Boolean indicating if event was not cancelled

173

*/

174

submit(element: Element, options?: EventInit): boolean;

175

176

/**

177

* Fire a reset event on a form

178

* @param element - Form element

179

* @param options - Event options

180

* @returns Boolean indicating if event was not cancelled

181

*/

182

reset(element: Element, options?: EventInit): boolean;

183

184

/**

185

* Fire a select event on an input

186

* @param element - Input element

187

* @param options - Event options

188

* @returns Boolean indicating if event was not cancelled

189

*/

190

select(element: Element, options?: EventInit): boolean;

191

192

/**

193

* Fire a scroll event

194

* @param element - Scrollable element

195

* @param options - Event options

196

* @returns Boolean indicating if event was not cancelled

197

*/

198

scroll(element: Element, options?: EventInit): boolean;

199

200

/**

201

* Fire a wheel event

202

* @param element - Target element

203

* @param options - Wheel event options

204

* @returns Boolean indicating if event was not cancelled

205

*/

206

wheel(element: Element, options?: WheelEventInit): boolean;

207

208

/**

209

* Fire a context menu event (right-click)

210

* @param element - Target element

211

* @param options - Mouse event options

212

* @returns Boolean indicating if event was not cancelled

213

*/

214

contextMenu(element: Element, options?: MouseEventInit): boolean;

215

216

/**

217

* Fire a drag event

218

* @param element - Target element

219

* @param options - Drag event options

220

* @returns Boolean indicating if event was not cancelled

221

*/

222

drag(element: Element, options?: DragEventInit): boolean;

223

224

/**

225

* Fire a drag start event

226

* @param element - Target element

227

* @param options - Drag event options

228

* @returns Boolean indicating if event was not cancelled

229

*/

230

dragStart(element: Element, options?: DragEventInit): boolean;

231

232

/**

233

* Fire a drag end event

234

* @param element - Target element

235

* @param options - Drag event options

236

* @returns Boolean indicating if event was not cancelled

237

*/

238

dragEnd(element: Element, options?: DragEventInit): boolean;

239

240

/**

241

* Fire a drag enter event

242

* @param element - Target element

243

* @param options - Drag event options

244

* @returns Boolean indicating if event was not cancelled

245

*/

246

dragEnter(element: Element, options?: DragEventInit): boolean;

247

248

/**

249

* Fire a drag leave event

250

* @param element - Target element

251

* @param options - Drag event options

252

* @returns Boolean indicating if event was not cancelled

253

*/

254

dragLeave(element: Element, options?: DragEventInit): boolean;

255

256

/**

257

* Fire a drag over event

258

* @param element - Target element

259

* @param options - Drag event options

260

* @returns Boolean indicating if event was not cancelled

261

*/

262

dragOver(element: Element, options?: DragEventInit): boolean;

263

264

/**

265

* Fire a drop event

266

* @param element - Target element

267

* @param options - Drag event options

268

* @returns Boolean indicating if event was not cancelled

269

*/

270

drop(element: Element, options?: DragEventInit): boolean;

271

272

/**

273

* Fire a touch start event

274

* @param element - Target element

275

* @param options - Touch event options

276

* @returns Boolean indicating if event was not cancelled

277

*/

278

touchStart(element: Element, options?: TouchEventInit): boolean;

279

280

/**

281

* Fire a touch end event

282

* @param element - Target element

283

* @param options - Touch event options

284

* @returns Boolean indicating if event was not cancelled

285

*/

286

touchEnd(element: Element, options?: TouchEventInit): boolean;

287

288

/**

289

* Fire a touch move event

290

* @param element - Target element

291

* @param options - Touch event options

292

* @returns Boolean indicating if event was not cancelled

293

*/

294

touchMove(element: Element, options?: TouchEventInit): boolean;

295

296

/**

297

* Fire a touch cancel event

298

* @param element - Target element

299

* @param options - Touch event options

300

* @returns Boolean indicating if event was not cancelled

301

*/

302

touchCancel(element: Element, options?: TouchEventInit): boolean;

303

304

/**

305

* Fire a load event

306

* @param element - Target element

307

* @param options - Event options

308

* @returns Boolean indicating if event was not cancelled

309

*/

310

load(element: Element, options?: EventInit): boolean;

311

312

/**

313

* Fire an error event

314

* @param element - Target element

315

* @param options - Event options

316

* @returns Boolean indicating if event was not cancelled

317

*/

318

error(element: Element, options?: EventInit): boolean;

319

320

/**

321

* Fire a resize event

322

* @param element - Target element

323

* @param options - Event options

324

* @returns Boolean indicating if event was not cancelled

325

*/

326

resize(element: Element, options?: EventInit): boolean;

327

}

328

329

declare const fireEvent: FireEvent;

330

```

331

332

### Create Event Function

333

334

Creates DOM event objects that can be dispatched manually.

335

336

```typescript { .api }

337

/**

338

* Create a DOM event object

339

* @param eventType - Type of event to create (e.g., 'click', 'keydown')

340

* @param element - Element the event will be dispatched on

341

* @param options - Event initialization options

342

* @returns Created event object

343

*/

344

function createEvent(

345

eventType: string,

346

element: Element,

347

options?: EventInit

348

): Event;

349

```

350

351

## Usage Examples

352

353

### Basic Event Firing

354

355

```typescript

356

import { within, fireEvent, waitFor } from "@storybook/testing-library";

357

358

export const BasicEventExample = {

359

play: async ({ canvasElement }) => {

360

const canvas = within(canvasElement);

361

362

// Fire a click event

363

const button = canvas.getByRole('button', { name: /click me/i });

364

fireEvent.click(button);

365

366

// Verify the click was handled

367

await waitFor(() => {

368

expect(canvas.getByText(/button clicked/i)).toBeInTheDocument();

369

});

370

}

371

};

372

```

373

374

### Form Events

375

376

```typescript

377

import { within, fireEvent, waitFor } from "@storybook/testing-library";

378

379

export const FormEventsExample = {

380

play: async ({ canvasElement }) => {

381

const canvas = within(canvasElement);

382

383

const input = canvas.getByLabelText(/email/i);

384

385

// Fire focus event

386

fireEvent.focus(input);

387

expect(input).toHaveFocus();

388

389

// Fire input event with value change

390

fireEvent.input(input, { target: { value: 'user@example.com' } });

391

392

// Fire change event

393

fireEvent.change(input, { target: { value: 'user@example.com' } });

394

395

// Fire blur event

396

fireEvent.blur(input);

397

398

// Verify form validation

399

await waitFor(() => {

400

expect(canvas.queryByText(/invalid email/i)).not.toBeInTheDocument();

401

});

402

}

403

};

404

```

405

406

### Keyboard Events

407

408

```typescript

409

import { within, fireEvent, waitFor } from "@storybook/testing-library";

410

411

export const KeyboardEventsExample = {

412

play: async ({ canvasElement }) => {

413

const canvas = within(canvasElement);

414

415

const input = canvas.getByLabelText(/search/i);

416

fireEvent.focus(input);

417

418

// Fire key down events

419

fireEvent.keyDown(input, { key: 'A', code: 'KeyA' });

420

fireEvent.keyDown(input, { key: 'B', code: 'KeyB' });

421

fireEvent.keyDown(input, { key: 'C', code: 'KeyC' });

422

423

// Fire Enter key

424

fireEvent.keyDown(input, { key: 'Enter', code: 'Enter' });

425

426

// Verify search was triggered

427

await waitFor(() => {

428

expect(canvas.getByText(/searching for: ABC/i)).toBeInTheDocument();

429

});

430

}

431

};

432

```

433

434

### Mouse Events

435

436

```typescript

437

import { within, fireEvent, waitFor } from "@storybook/testing-library";

438

439

export const MouseEventsExample = {

440

play: async ({ canvasElement }) => {

441

const canvas = within(canvasElement);

442

443

const draggable = canvas.getByTestId('draggable-item');

444

const dropzone = canvas.getByTestId('drop-zone');

445

446

// Simulate mouse drag

447

fireEvent.mouseDown(draggable, { clientX: 100, clientY: 100 });

448

fireEvent.mouseMove(draggable, { clientX: 150, clientY: 150 });

449

fireEvent.mouseUp(draggable, { clientX: 200, clientY: 200 });

450

451

// Hover events

452

fireEvent.mouseEnter(dropzone);

453

fireEvent.mouseOver(dropzone);

454

fireEvent.mouseLeave(dropzone);

455

456

// Context menu

457

fireEvent.contextMenu(draggable);

458

459

await waitFor(() => {

460

expect(canvas.getByRole('menu')).toBeInTheDocument();

461

});

462

}

463

};

464

```

465

466

### Drag and Drop Events

467

468

```typescript

469

import { within, fireEvent, waitFor } from "@storybook/testing-library";

470

471

export const DragDropExample = {

472

play: async ({ canvasElement }) => {

473

const canvas = within(canvasElement);

474

475

const draggable = canvas.getByTestId('draggable');

476

const dropzone = canvas.getByTestId('dropzone');

477

478

// Start drag operation

479

fireEvent.dragStart(draggable, {

480

dataTransfer: {

481

setData: (format: string, data: string) => {},

482

getData: (format: string) => 'dragged-item'

483

}

484

});

485

486

// Drag over drop zone

487

fireEvent.dragEnter(dropzone);

488

fireEvent.dragOver(dropzone);

489

490

// Complete drop

491

fireEvent.drop(dropzone, {

492

dataTransfer: {

493

getData: (format: string) => 'dragged-item'

494

}

495

});

496

497

fireEvent.dragEnd(draggable);

498

499

// Verify drop was handled

500

await waitFor(() => {

501

expect(canvas.getByText(/item dropped/i)).toBeInTheDocument();

502

});

503

}

504

};

505

```

506

507

### Touch Events

508

509

```typescript

510

import { within, fireEvent, waitFor } from "@storybook/testing-library";

511

512

export const TouchEventsExample = {

513

play: async ({ canvasElement }) => {

514

const canvas = within(canvasElement);

515

516

const touchTarget = canvas.getByTestId('touch-target');

517

518

// Simulate touch interaction

519

fireEvent.touchStart(touchTarget, {

520

touches: [{ clientX: 100, clientY: 100 }]

521

});

522

523

fireEvent.touchMove(touchTarget, {

524

touches: [{ clientX: 150, clientY: 150 }]

525

});

526

527

fireEvent.touchEnd(touchTarget, {

528

changedTouches: [{ clientX: 150, clientY: 150 }]

529

});

530

531

// Verify touch interaction

532

await waitFor(() => {

533

expect(canvas.getByText(/touched/i)).toBeInTheDocument();

534

});

535

}

536

};

537

```

538

539

### Custom Events

540

541

```typescript

542

import { within, fireEvent, createEvent, waitFor } from "@storybook/testing-library";

543

544

export const CustomEventsExample = {

545

play: async ({ canvasElement }) => {

546

const canvas = within(canvasElement);

547

548

const component = canvas.getByTestId('custom-component');

549

550

// Create and fire custom event

551

const customEvent = createEvent('customEvent', component, {

552

bubbles: true,

553

detail: { message: 'Hello from custom event' }

554

});

555

556

fireEvent(component, customEvent);

557

558

// Verify custom event was handled

559

await waitFor(() => {

560

expect(canvas.getByText(/custom event received/i)).toBeInTheDocument();

561

});

562

}

563

};

564

```

565

566

### Event Options and Modifiers

567

568

```typescript

569

import { within, fireEvent } from "@storybook/testing-library";

570

571

export const EventOptionsExample = {

572

play: async ({ canvasElement }) => {

573

const canvas = within(canvasElement);

574

575

const button = canvas.getByRole('button', { name: /special click/i });

576

577

// Click with modifier keys

578

fireEvent.click(button, {

579

ctrlKey: true,

580

shiftKey: true,

581

button: 0, // Left mouse button

582

clientX: 100,

583

clientY: 200

584

});

585

586

// Keyboard event with modifiers

587

const input = canvas.getByLabelText(/shortcut input/i);

588

fireEvent.keyDown(input, {

589

key: 'S',

590

code: 'KeyS',

591

ctrlKey: true,

592

shiftKey: true

593

});

594

}

595

};

596

```

597

598

### Form Submission

599

600

```typescript

601

import { within, fireEvent, waitFor } from "@storybook/testing-library";

602

603

export const FormSubmissionExample = {

604

play: async ({ canvasElement }) => {

605

const canvas = within(canvasElement);

606

607

const form = canvas.getByRole('form');

608

const emailInput = canvas.getByLabelText(/email/i);

609

const passwordInput = canvas.getByLabelText(/password/i);

610

611

// Fill form

612

fireEvent.change(emailInput, { target: { value: 'user@example.com' } });

613

fireEvent.change(passwordInput, { target: { value: 'password123' } });

614

615

// Submit form

616

fireEvent.submit(form);

617

618

// Verify submission

619

await waitFor(() => {

620

expect(canvas.getByText(/form submitted/i)).toBeInTheDocument();

621

});

622

}

623

};

624

```

625

626

### Scroll Events

627

628

```typescript

629

import { within, fireEvent, waitFor } from "@storybook/testing-library";

630

631

export const ScrollEventsExample = {

632

play: async ({ canvasElement }) => {

633

const canvas = within(canvasElement);

634

635

const scrollableContainer = canvas.getByTestId('scrollable');

636

637

// Fire scroll event

638

fireEvent.scroll(scrollableContainer, { target: { scrollY: 100 } });

639

640

// Fire wheel event for mouse wheel scrolling

641

fireEvent.wheel(scrollableContainer, { deltaY: 100 });

642

643

// Verify scroll behavior

644

await waitFor(() => {

645

expect(canvas.getByText(/scrolled/i)).toBeInTheDocument();

646

});

647

}

648

};

649

```

650

651

## When to Use fireEvent vs userEvent

652

653

### Use fireEvent when:

654

- Testing low-level event handling

655

- Need precise control over event properties

656

- Testing edge cases or error conditions

657

- Working with custom events

658

- Need synchronous event firing

659

660

### Use userEvent when:

661

- Simulating realistic user interactions

662

- Testing the complete user experience

663

- Want higher-level interaction methods

664

- Need async behavior that matches real users

665

666

```typescript

667

import { within, fireEvent, userEvent } from "@storybook/testing-library";

668

669

export const ComparisonExample = {

670

play: async ({ canvasElement }) => {

671

const canvas = within(canvasElement);

672

673

const input = canvas.getByLabelText(/username/i);

674

675

// fireEvent - direct, low-level

676

fireEvent.change(input, { target: { value: 'testuser' } });

677

678

// userEvent - realistic, high-level

679

await userEvent.type(input, 'testuser');

680

}

681

};

682

```