Ozzy
Ozzy

Reputation: 39

Cypress: TypeError window.parent.$ is not a function

I'm a newbie to Cypress, and a test I am writing has produced the following error:

TypeError window.parent.$ is not a function

I don't really understand what this is telling me and using:

Cypress.on('uncaught:exception', (err, runnable) => {
   return false
})

Does prevent the test from insta-failing, but I believe this exception is causing me pain when trying to select items from dropdown menus etc.

As you can see there literally nothing to this test:

it('Log in to SUT', function () {
    cy.get('#username').type('xxxx');
    cy.get('#password').type('xxxx');

    cy.get('#btnLogin').click();
})

However, once the login button is clicked I get the error I described.

Incidentally, the following cypress.json config causes Cypress runner to not find my test at all!

{
   "modifyObstructiveCode": false
}

Any guidance or suggestions would be most appreciated!

Upvotes: 1

Views: 2793

Answers (2)

brunoff
brunoff

Reputation: 4209

If it happens even without Cypress involved then the problem probably is that you have a page with an iframe and the iframe parent document probably has no jquery loaded and the child has it loaded and the child acts as his parent has. If that's the case since the page script fails by its own, you have to change the documents being tested not the test script.

Since you have two documents involved, you can solve the problem from the parent or from the child. I believe that from the child is easier. By changing the child, you can push the jquery reference from the child to the parent.

In the child document, before window.parent.$ invocation but after jquery is already loaded use this:

window.parent.$ = $;

I believe it is cleaner and probably more efficient than using the same script tag like <script type="text/javascript" src="https://code.jquery.com/jquery-3.6.0.slim.js"></script> also in the parent, referencing this way twice that would eventually consume more resources from the browser.

The alternative solution, pulling the child reference from the parent $ = document.getElementById("childiframeid").contentWindow.$ is more prone to problems because you have to do in the correct timing, when the child iframe is already loaded as well as its jquery, but before it could invoke document.parent.$.

Another solution would be replacing the jquery for vanilla javascript - replace document.parent.$('...').x for document.parent.getElement('...').y. but in this case you will need to adapt (x and y will be a little different).

Upvotes: 1

olore
olore

Reputation: 4847

The message about window.parent.$ sounds like you are testing a login form that is usually embedded in an iframe. If you load the same page in your browser, do you get the same error when clicking login?

You'll want to test the entire page (with frames and all) so that the scripts on the page continue to function.

You can read about working with IFrames in Cypress

Upvotes: 3

Related Questions