Skip to content

Cypress Component Event Not Triggering Fix

DodaTech Updated 2026-06-24 2 min read

In this tutorial, you'll learn about Cypress Component Event Not Triggering Fix. We cover key concepts, practical examples, and best practices.

Your component's event handler isn't called when you interact with it — cy.spy reports 0 calls even after clicking the element.

The Problem

// WRONG — spy created after component mounted
const onClick = cy.stub();

cy.mount(<Button onClick={onClick} />);
cy.get('button').click();

expect(onClick).to.be.called; // Might fail — timing issue

The stub might not be connected properly, or the event assertion runs before the click completes.

Step-by-Step Fix

1. Pass spy as prop and assert after interaction

// RIGHT — spy passed as prop
import Button from './Button';

it('calls onClick handler', () => {
  const onClick = cy.stub().as('onClick');

  cy.mount(<Button onClick={onClick}>Click me</Button>);
  cy.get('button').click();

  cy.get('@onClick').should('be.calledOnce');
});

2. Verify event arguments

// RIGHT — check event arguments
it('passes event to handler', () => {
  const onChange = cy.stub().as('onChange');

  cy.mount(<Input onChange={onChange} />);
  cy.get('input').type('hello');

  cy.get('@onChange').should('be.calledWith', Cypress.sinon.match.has('target'));
});

3. Test custom event emissions

// RIGHT — custom component events
it('emits custom event', () => {
  const onSubmit = cy.stub().as('onSubmit');

  cy.mount(<Form onSubmit={onSubmit} />);
  cy.get('form').submit();

  cy.get('@onSubmit').should('be.calledOnce');
});

4. Test event prevention

// RIGHT — preventDefault testing
it('prevents default form submission', () => {
  const onSubmit = cy.stub().callsFake((e) => e.preventDefault());

  cy.mount(<Form onSubmit={onSubmit} />);
  cy.get('button[type="submit"]').click();

  cy.get('@onSubmit').should('be.calledOnce');
});

Expected output:

  ✓ calls onClick handler
  ✓ passes event to handler
  ✓ emits custom event

Prevention Tips

  • Use cy.stub().as('alias') for event handler assertions
  • Assert with cy.get('@alias').should('be.called')
  • Check event arguments with <a href="/testing-qa/cypress/">Cypress</a>.sinon.match
  • Test both successful and prevented events
  • Clean up event handlers between tests

Common Mistakes with component event

  1. Mixing let bindings with <- bindings in do notation, producing type errors
  2. Overlapping type class instances that cause GHC to reject the program with ambiguous dispatch errors
  3. Non-exhaustive pattern matches that compile with warnings then crash at runtime

These mistakes appear frequently in real-world CYPRESS code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.

Practice Exercise

Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.

This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.

FAQ

### Why does cy.spy not detect the event?

The spy might be attached to the wrong instance. Spy on the prop directly: const spy = cy.spy(); cy.mount(<Component onClick={spy} />). Or use cy.stub() and alias it.

How do I test that an event handler was NOT called?

Use negative assertion: cy.get('@handler').should('not.be.called'). This is useful for testing that certain interactions don't trigger side effects.

Can I test native DOM events like focus or blur?

Yes. Use cy.get('input').focus() and cy.get('input').blur() to trigger these events. Spy on the onFocus and onBlur handlers passed as props.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro