October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsPC HealthRecommendedCrashes, freezes, slowdowns? Check your PC nowSpot repairable issues before they interrupt work.Check PCOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk5 min

How to Use App-Emitted Events in Cypress End-to-End Tests

Hook an observer to your app’s actual event interface, capture startup events with onBeforeLoad, and assert meaningful payload fields without brittle tests.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

To test an event your application emits, attach a spy or listener to the app’s actual event interface, perform the UI action, and assert the meaningful parts of the event. If startup emissions matter, install the observer in cy.visit()’s onBeforeLoad callback so it is in place before application code runs.

First identify which events you want to observe

Cypress’s event APIs cover more than one stream. Your application may expose events through a method such as window.postMessage, a custom DOM event, or an app-specific event emitter. Cypress also emits its own runner and lifecycle events, including events such as window:before:load, window:load, and uncaught:exception. These are distinct: to verify app behavior, observe the interface through which your app emits; to inspect Cypress lifecycle or runner behavior, use Cypress’s event APIs. See the Cypress catalog of events.

As an Amazon Associate I earn from qualifying purchases.

Cypress does not automatically record every arbitrary custom event. There is no universal listener that can observe all app event architectures. The right hook depends on the interface your application actually uses.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Capture startup events before the app runs

If the event may be emitted during startup, set up the observer in cy.visit()’s onBeforeLoad callback. Cypress runs this callback before application code, making it suitable for spying on built-in window methods before the app can call them. A later cy.window() call gives access to the live AUT window, but startup emissions may already have happened.

cy.visit('/', {
  onBeforeLoad(win) {
    cy.spy(win, 'postMessage').as('postMessage')
  },
})

cy.get('.new-todo').type('learn testing{enter}')
cy.get('.todo-list li').should('have.length', 1)
cy.get('@postMessage').should('be.called')

This pattern spies on postMessage, an example used by Cypress in a Redux/Kuker tutorial published March 20, 2019. It illustrates observing one app’s instrumentation interface; it does not mean every application uses Kuker or should adopt it. The tutorial’s example also checks calls and arguments, while avoiding brittle comparisons of entire event objects when values such as timestamps vary. See Cypress’s application-event tutorial.

Choose the observer that matches the app interface

Need Approach Trade-off
Observe a method call while leaving its behavior intact cy.spy(object, method) Install it before the first call if startup emissions matter.
Replace a method to control behavior, such as forcing an error or supplying a callback cy.stub(object, method) A stub changes behavior, so it is not the right choice when verifying that the real method runs.
Inspect the current application window after navigation cy.window() It can be too late to observe emissions that occurred during startup.
Invoke a DOM event handler with a specific event .trigger(eventName, options) It dispatches the event but does not perform the browser’s default action.
Observe Cypress lifecycle or runner events cy.on() or Cypress.on() Choose based on listener lifetime; Cypress event callbacks run outside the normal command queue.

A spy records calls while allowing the original method to run; a stub replaces the function. Cypress documents both in its stubs, spies, and clocks guide, with API detail in cy.stub().

For an app-owned custom DOM event or emitter, register an observer on that specific interface before the relevant action, capture the event or payload, then assert in the test body. If you access the AUT window with cy.window(), Cypress documents the command and custom window typing in cy.window().

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Assert the event contract, not incidental details

Alias a spy so Cypress can retry its assertion, perform the action through the UI, and check the call and the payload fields that matter. Prefer stable contract fields—for example, an action type or item identifier—over whole-object equality when payloads include timestamps or other volatile metadata. Assert a call count when the expected number is part of the behavior, and inspect arguments when the payload itself matters.

Keep an event assertion tied to a reason. It can verify a meaningful contract, such as emitted state or action order, but assertions on internal events can couple an end-to-end test to implementation details. When the user-facing outcome matters, pair the event assertion with a visible UI assertion, as in the example’s check that a todo appears.

Use Cypress event listeners with the right scope

cy.on() listeners are scoped to the current test. Cypress.on() listeners persist beyond a single test, so registering them repeatedly can accumulate listeners. Also, Cypress event callbacks run outside the normal command queue: do not issue Cypress commands or assertions from inside the callback. Instead, capture the relevant data in the callback and assert against it later in the test body. The event catalog documents these scope and callback constraints.

Dispatching an event is not the same as observing one

Use .trigger() when the test’s purpose is to invoke a handler with a particular event. It does not reproduce the browser’s default action, so it is not a substitute for normal Cypress interactions in a user flow where browser behavior matters. For example, typing and pressing Enter exercises the interaction path in the sample; triggering a key event only invokes the relevant handler. See cy.trigger().

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshoot missed or unreliable event assertions

  • The spy records no startup call: move its setup into onBeforeLoad; attaching it after navigation may miss a call made during app initialization.
  • The spy is attached to the wrong target: confirm which object and method the app actually uses. A postMessage spy cannot observe a custom DOM event or a separate app emitter.
  • A stub makes the app behave differently: use a spy when the goal is observation and the original method must still run.
  • The payload assertion fails intermittently: inspect the arguments and assert stable fields rather than comparing metadata such as changing timestamps.
  • A Cypress command fails inside a listener: store data in the callback and make assertions later in the test’s command chain.
  • A synthetic event does not reproduce a real interaction: use the normal Cypress action when the browser’s default behavior is part of what you need to test.

Or skip the browser setup

For capturing a page screenshot rather than testing an app-emitted event, ScreenshotNeo offers a one-request screenshot API; it does not replace Cypress’s event-observation workflow. Cookie banners, popups, and chat widgets are removed before the shot. Bot checks, blank pages, and failed loads are never billed; an MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots a month with no card, and paid plans start at $5 for 3,000. See the ScreenshotNeo docs.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

ScreenshotNeo also returns a page verdict and billing status in response headers. Sign up for 1,000 free screenshots a month, with no card required.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Outdated Drivers Are Slowing You DownFree scan - exact matches
Windows Errors? Fix Them Before They SpreadFree repair scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.