Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to listen global events with Cypress?

Tags:

cypress

We have an application that polls the server periodically until a task is completed. We fire a global event so that Cypress can catch and find out if the task is finished but we had trouble using document.addEventListener on Cypress. Here's what we're doing:

document.addEventListener('queryEnd', () => {
    cy.get('.chart').should('be.visible')
    cy.get('.table').should('be.visible')
  })

However; when we use it in a spec, it doesn't work expected and we're not able to catch it. Also, Cypress doesn't wait for the test and runs afterEach without waiting for the callback to run.

like image 997
burak emre Avatar asked Apr 08 '19 23:04

burak emre


People also ask

How do you handle uncaught exceptions in Cypress?

Listen for uncaught exceptions and prevent Cypress from failing the test. Listen for alert or confirm calls and change the confirm behavior. Listen for window:before:load events and modify the window before any of your app code runs between page transitions.

How do you catch a mistake in Cypress?

Handling Error in Cypress Unlike other Javascript-Based Frameworks, Cypress doesn't allow you to use the try and catch block to handle the exception. Cypress provides a special mechanism for handling exceptions in your code. Handling different types of Exceptions such as: Exception from Webpage Under Test.

How do you know if an element is present in Cypress?

Conditionally check whether an element has certain text: get('body'). then(($body) => { // synchronously ask for the body's text // and do something based on whether it includes // another string if ($body. text(). includes('some string')) { // yup found it cy.


1 Answers

The reason why your code isn't working like you expect is because in Cypress, your tests run in a separate frame than your application under test (AUT). The event you're waiting for will never fire inside of Cypress's document.

To get the document of the AUT, use cy.document() like this:

cy.document()
.then($document => {
  // now $document is a reference to the AUT Document
  $document.addEventListener(...)
})

To make Cypress wait for your event before continuing, you can just wrap it in a Cypress.Promise. The Cypress docs have an example about waiting for a Promise to complete. For your queryEnd event, it would look something like this:

cy.document() // get a handle for the document
.then($document => {
  return new Cypress.Promise(resolve => { // Cypress will wait for this Promise to resolve
    const onQueryEnd = () => {
      $document.removeEventListener('queryEnd', onQueryEnd) // cleanup
      resolve() // resolve and allow Cypress to continue
    }
    $document.addEventListener('queryEnd', onQueryEnd)
  })
})
.then(() => {
  cy.get('.chart').should('be.visible')
  cy.get('.table').should('be.visible')
})
like image 55
Zach Bloomquist Avatar answered Sep 28 '22 07:09

Zach Bloomquist