Search code examples
cypress

Element for accepting cookies


Hi have this bit of code to click a cookies banner accept when present, my issue is when ran on a server that has this banner turned off if doesn't move on if the length is less than 1 say, I would like it to if the element isn't present to just execute the next step in test.

if (Cypress.$(this.LoginElementLocators.LoginPageLocators.cookies_accept).length > 0) {
  cy.get(this.LoginElementLocators.LoginPageLocators.cookies_accept).click()
}  

At the minute the test fails saying it didn't find the element


Solution

  • The syntax you have used is good, so some other possibilities are:

    The cookie banner gets hidden rather than removed

    If this is the case, the main banner container might have CSS display: none or possibly opacity: 0 if there is a fade animation.

    You would adjust the test by adding :visible to the selector, but you wouldn't use the accept button, rather the cookie banner container - for example:

    const visibleCookieContainer = `${Locators.cookies_container}:visible`
    if (Cypress.$(visibleCookieContainer).length) {    // don't need > 0
      ...
    

    The if() check is happening before the cookie banner container appears

    This is less likely since you mention the test fails saying it didn't find the element, which means the if() statement passes and the cy.get() statement fails.

    You can try polling for the element as per this answer

    const ifElementExists = (selector, attempt = 0) => {
      if (attempt === 100) return null           // wait up to 10 seconds
      if (Cypress.$(selector).length === 0) {
        cy.wait(100, {log:false})                // wait in 100ms chunks
          .then(() => ifElementExists(selector, ++attempt))      
      }
      return cy.get(selector, {log:false})     
    }
    
    ifElementExists(Locators.cookies_accept).then($el => {
      if ($el?.length) {  // null or element
        $el.click()
      }
    })
    

    The cookie banner container may or may not appear

    If the cookie banner appearing is "random", try adding a MutationObserver as per this answer

    function handler(win) {
      const selector = Locators.cookies_accept
      const observer = new MutationObserver(mutations => {
        const addedElement = mutations?[0].addedNodes?[0]
        if (addedElement?.classList.contains(selector)) {
          addedElement.click()
        }
      }
      observer.observe(win.document.body, { childList: true })
    }
    cy.on('window:load', handler)
    

    This waits in the background and fires only when the button appears. Because this is a background handler, it may not get the chance to fire, since javascript is single-threaded.