Cypress:在日历弹出窗口中找不到元素

问题描述

我无法在 Cypress 测试中与日期选择器(弹出窗口)交互。

我在每个 div 类上都尝试了 .find() 和 .get() 但每次它都说 Timed out retrying after 4000ms: Expected to find element: .cdk-overlay-container,but never found it

这是我的测试代码

      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()

我尝试添加一些等待时间,但这也无济于事。

enter image description here

解决方法

这个序列

.get('#input-dateOfBirth').click()
.find('.owl-dt-popup').click()

希望在 dateOfBirth 控件中找到日期弹出窗口。

您可能只需要

.get('#input-dateOfBirth').click()
.get('.owl-dt-popup').click()

通常,您会看到每个项目的 cy.get(),而不是像您所做的那样将所有获取链接起来。这仍然有效,因为 .get() 总是从 cy.root() 开始搜索,#signup-step-pers-details 将其设置为 .within()

.find() 不同,它从前一个主题开始搜索,即 DOB 控件。

如果您希望日期弹出窗口实际上位于 DOB 输入中,我应该添加 cdk-overlay-container 在弹出窗口可见时添加到 <body></body> 标记的底部(看看 devtools)。

  <div class="cdk-overlay-container">...</div>
</body>
,

您使用 contains 的方法很好,但您可以使用 another syntax 来选择日期:

      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()
        .contains('.owl-calendar-year','2002').click()
,

@KKhan 是正确的,Angular Date Time Picker 在文档底部的 cdk-overlay-container 中打开。

关于布局的更多细节:

<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>

使用 cy.get('#signup-step-pers-details').within(() => { 将命令限制在 DOM 的该部分内,但 owl-date-time-container 不在此范围内。

您可以使用这种方法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()
})

注意我使用了 .owl-dt-control-period-button,它适用于当前版本的 Angular Date Time Picker,但也许您的旧版本需要 .owl-calendar-year。>