Imagine your code is using a lot of instanceof
checks. When running Cypress tests, you might want to also check if a given object is an instance of a given constructor function. The problem is, your specs and the application run in different iframes. Thus a constructor might have the same name (let's say Alert
), but an instance of Alert
from the spec's iframe window is different from an instance of the application's iframe window. Watch my video below for the introduction to this problem and one possible solution
📝 For more, read the the recipe "Be very careful with instanceof assertion" from my Cypress examples site.
In this blog post, I will show a general way of how to avoid this problem if you are making objects yourself from the spec. Let's say we have the following statements in the application and in the Cypress spec files:
1 | // application code in "src" |
If you are importing "Alert" from the spec, that this Alert
function is different from the Alert imported in the application. If the spec calls isAlert
and passes its own objects, the check will fail and return false
1 | // cypress/integration/spec.js |
So how do we ensure the spec has the same Alert reference as the application? By avoiding importing it and instead getting it from the application. Following the approach outlined in the blog post Send Data From The Application To The Cypress Test we do the following in the application:
1 | // application code in "src" |
So when the application loads, it "saves" its Alert
reference on the window
object. From the spec we can get to that reference using the cy.window and cy.its commands. Even if it takes a little for the application to load and set the window.Alert
no problem, the cy.its
command retries automatically until that property is found.
1 | // cypress/integration/spec.js |
Beautiful.