Search code examples
angularjscypressowl-date-time

Cypress: cannot find elements in calendar popup


I cannot interact with the date picker (popup) in my Cypress tests.

I tried .find() and .get() on every div class but each time it says Timed out retrying after 4000ms: Expected to find element: .cdk-overlay-container, but never found it

This is my test code:

      cy.get('#signup-step-pers-details').within(() => {
        cy.get('[name="firstName"]').type(user.firstName)
        .get('[name="surname"]').type(user.lastName)
        .get('#select-gender').click()
        .get('.ng-dropdown-panel-items').contains(user.gender, {matchCase: false}).click()
        .get('#input-dateOfBirth').click()
        .find('.owl-dt-popup').click()
        .get('.owl-calendar-year').contains(2002).click()

I tried adding some wait time but that didn't help either.

enter image description here


Solution

  • @KKhan is correct, the Angular Date Time Picker opens in a cdk-overlay-container at the foot of the document.

    More detail on the layout:

    <body>
      ...
      <div id="signup-step-pers-details>
        ...
        <div id="input-dateOfBirth"></div>
      </div>
      ...
    
      <div class="cdk-overlay-container">
        <owl-date-time-container>
          ...
        </owl-date-time-container>
      </div>
    
    </body>
    

    Using cy.get('#signup-step-pers-details').within(() => { restricts commands inside to that section of the DOM, but the owl-date-time-container is outside of that.

    You can use this approach Cypress how to temporarily escape from a cy.within()

    cy.get('#signup-step-pers-details').within(() => {
    
      // cy.root() === #signup-step-pers-details
      cy.get('[name="firstName"]').type(user.firstName)
        .get('[name="surname"]').type(user.lastName)
        .get('#select-gender').click()
        .get('.ng-dropdown-panel-items').contains(user.gender, {matchCase: false}).click()
        .get('#input-dateOfBirth').click()
    
      // shift cy.root() to date-time-picker
      cy.document().its('body').find('owl-date-time-container').within(() => {
        cy.get('button.owl-dt-control-period-button').click()
        cy.contains('2002').click()
        cy.contains('Aug').click()
        cy.contains('23').click()
      })
    
      // back to cy.root() === #signup-step-pers-details
      cy.get('#select-nationality').click()
    })
    

    Note I've used .owl-dt-control-period-button which is correct for the current version of Angular Date Time Picker, but perhaps you have an older version that requires .owl-calendar-year.