I'm writing Cypress-tests to a site, that has several modals (newsletter signups inside iframe), popups ("Remember free shipping if X, Y and Z") and overlays.
These elements are quite the problem, since it makes it impossible to 'click field A' and fill it out with text: abcd. Since the overlays opens on top of the whole thing.
Overarching question: How do I get rid of these modals, popups and overlays, so I can interact with the page?
beforeEach, with display: none;I imagined something like this:
cy.get('head').then( (head) => {
let gottenHead = document.head;
let styles = document.createElement('style');
styles.type = 'text/css';
styles.innerHTML = '.iframes-container { display: none !important; }'
gottenHead.appendChild( styles ); // Doesnt work,
head.appendChild( styles ); // Doesnt work
});
Or [this gist here], but that doesn't work either, throwing the error: "Cannot read properties of undefined (reading 'appendChild')" for this line: doc.body.head.appendChild($style);.
Adding a mutation observer, checking if any of the wrapping elements gets added to the dom. And if they do - remove them again.
This just again, doesn't seem like 'The Cypress Way'. So I haven't tried this yet.
This seems like the most organic approach. But I'd actually rather have a lazy option, that simply hides them all, whenever Cypress is running.
But the problem with this is that the 'close'-button is inside an iframe, which Cypress doesn't like interacting with.
I checked Cypress' documentation, but couldn't find any guidelines on how to bypass these modals and popups, weirdly enough.
Update1: Agoff asked what keeps track of, if the modal/popups should show. I tried checking if a cookie was set, a session variable or some local storage. But I couldn't see anything being added, after 'clicking them away'. :-/
Delete the element
cy.get('modal-top-element')
.then($modal => $modal[0].remove)
If it appears in it's own iframe (seems doubtful), delete the iframe.
In the end, it showed that @agoff was actually right. It was save in the local storage.
I wrote these commands that I use to display, save and set the localStorage (using the cypress-localstorage-commands package ):
In Commands:
import "cypress-localstorage-commands"
Cypress.Commands.add( "displayPopupLocalStorage", () => {
cy.getLocalStorage('THECUSTOMLOCALSTORAGEKEY').then( (localStorageContents) => {
cy.log( "THECUSTOMLOCALSTORAGEKEY contents: ");
cy.log( localStorageContents );
})
});
Cypress.Commands.add( "savePopupLocalStorage", () => {
cy.getLocalStorage('THECUSTOMLOCALSTORAGEKEY').then( (localStorageContents) => {
cy.writeFile( "cypress/fixtures/tmp/popup-local-storage.json", localStorageContents );
})
});
Cypress.Commands.add( "setPopupLocalStorage", () => {
cy.fixture( "tmp/popup-local-storage.json", 'utf8' )
.then( (localStorageContents) => {
cy.setLocalStorage('THECUSTOMLOCALSTORAGEKEY', JSON.stringify( localStorageContents ) );
});
});
Tests
it( 'Accept and save pop-up cookies', () => {
cy.visit( "https://example.org" );
// Close popup and save local storage
cy.get( '.popup-wrapper .close-form' ).click()
cy.wait( 500 ); // Needed for the animation to finish, so the localStorage is set
cy.savePopupLocalStorage();
});
it( 'Sets popup cookies and check that header is clickable', () => {
cy.setPopupLocalStorage();
cy.visit( "https://example.org" );
cy.get('.popup-wrapper', { timeout: 10000 }).should('not.exist');
// Verify that it works, by going to a page and ensure that the something is clickable
cy.get( '#header .logo > a' ).then( ($logo) => {
Cypress.dom.isFocusable( $logo );
});
});