【问题标题】:Cypress does not select a date on calendar赛普拉斯不在日历上选择日期
【发布时间】:2021-07-27 13:22:47
【问题描述】:

我想使用 cypress 测试日历,但无法选择我需要的日期或任何日期,理想的是动态代码,我可以在其中输入天数,它会选择正确的数字。

我正在使用此代码,但我收到一条错误消息,提示 “无法读取未定义的属性 'includes'”

  let date = new Date()
  date.setDate(date.getDate() + 5)
  let futureDay = date.getDate()
  console.log(futureDay)
  let futureMonth = date.toLocaleString('default', { month: 'long' })
  cy.get('.flatpickr-current-month')
    .invoke('attr', 'flatpickr-monthDropdown-month')
    .then(dateAttribute => {
      if (!dateAttribute.includes(futureMonth)) {
        cy.get('.flatpickr-next-month').click()
      } else {
        cy.get('.dayContainer')
          .contains(futureDay)
          .click()
      }
    })

如有必要,我可以在元素中添加独特的属性(我尝试过,但仍然没有用)。 我很好地尝试了一个更简单的代码:

  cy.get('#inception_date').click()
  cy.get('.flatpickr-days > .dayContainer',)
    .contains('17')
    .click({force: true})
  cy.get('#inception_date')
    .invoke('prop', 'value')
    .should('contain', '2021-07-17')

在此代码中,我收到错误 Timed out retrying after 4000ms: expected '2021-07-27' to include '2021-07-17' 因为它没有选择任何日期,它仍然是今天的日期。

如果是 DOM,我会附上 2 张图片,也许它可以帮助找出我的代码有什么问题。

【问题讨论】:

  • 元素 <div class="flatpickr-current-month"> 上没有 attr flatpickr-monthDropdown-month。 DOM 中的屏幕截图中的“七月”在哪里?这就是您要定位的元素。
  • @SteveZodiac 这里是七月。 <option class="flatpickr-monthDropdown-month" value="6" tabindex="-1">July</option>
  • 不,这只是您打开下拉菜单时显示的选项之一。
  • 我只能在道具中看到选择日期,但在 DOM 中看不到。它显示的唯一不同之处是这里 <span class="flatpickr-day selected" aria-label="July 21, 2021" tabindex="-1">21</span>。如果您选择一天,则只有选择出现在类属性前面
  • 是的,select 持有所选选项的 value 并显示其文本(全部在选择内部,在 DOM 中不可见)。

标签: json cypress flatpickr


【解决方案1】:

看看flatPickrJS的例子,你想要

let date = new Date()                        // July 28 
date.setDate(date.getDate() + 5)             // Aug 2
let futureDay = date.getDate()               // get 2 (integer)
let futureMonth = date.getMonth()            // gets 6 (integer) for July

cy.get('.flatpickr-current-month select')    // <select> is nested inside
  .invoke('val')                             // this is the currently selected month
  .then(dateAttribute => {                   // this is "6" for July (months are 0-based)

    if (+dateAttribute !== futureMonth) {    // +dateAttribute converts string to integer
      cy.get('.flatpickr-next-month').click()  // change month to Aug
    }

    cy.get('.dayContainer')                    // selects Aug 2
      .contains(new RegExp(`^${futureDay}$`))  // which is July 28
      .click()                                 // plus 5 days
  })

cy.get('input.flatpickr')
  .invoke('val')
  .should('eq', '2021-08-02')                  // passes

变更摘要

  • 获取数字 futureMonth 而不是字符串月份名称。

  • 使用.invoke('val')&lt;select&gt;获取当前月份的值。

  • 比较当前月份和未来月份,如果不一样,点击下个月按钮。

  • 将日期容器从} else { 中单击出来,因为您始终需要选择日期。


注意

感谢 @SyedMuhammadAwais 在日期选择代码中发现错误。

使用.contains(futureDay) 进行部分匹配,但日历有时会显示上个月的某些天,但它们被禁用(不可点击)。

因此,如果 futureDay === 6 并且显示上个月的 26 日,则将选择这个禁用的日期并通过测试。

解决方案是使用精确的文本匹配,可以使用这样的正则表达式来完成

.contains(new RegExp(`^${futureDay}$`))

【讨论】:

  • 再过一个月还能用吗?需要可以选择任何月份。
  • 我收到错误 在 4000 毫秒后重试超时:cy.invoke() 出错,因为您的主题上不存在属性:值。 cy.invoke() 等待指定的属性值存在,但它从未存在。
  • 感谢您的帮助,但仍然无法正常工作。我没有收到任何错误,但是 cy.contaibs 找到了我想要的当天,但它仍然选择今天。 &lt;span class="flatpickr-day today selected" aria-label="July 28, 2021" aria-current="date" tabindex="-1"&gt;28&lt;/span&gt; 是如何出现在 DOM 中的 else { cy.get('.flatpickr-days') .contains(futureDay) .click({ force: true })
  • 这是因为您的 if/else 结构中的逻辑无效。当月份发生变化时,您不会选择任何一天。您应该删除 else 部分并始终选择日期。
【解决方案2】:

这是正确的代码,对@Steve Zodiac 的代码进行了一些修改

date.setDate(date.getDate() + 8)
let futureDay = date.getDate()
let futureMonth = date.getMonth()
cy.log(futureDay)               // get 6 (integer)
cy.log(futureMonth)            // gets 7 (integer) for August
cy.get('input[placeholder="Day"]').click({force:true})
cy.wait(5000)
cy.get('.flatpickr-current-month > select > option').eq(0)    
  .invoke('val')                             // this is the currently 
   selected month
  .then(dateAttribute => {                   // this is "6" for July 
                                               (months are 0-based)
    if (+dateAttribute !== futureMonth) {    // +dateAttribute converts string to integer
      cy.get('.flatpickr-next-month').click({force: true}
    }

    cy.get('.dayContainer')                    // selects Aug 6
      .contains(new RegExp(futureDay, "g"))
      .click({force:true})                                 // plus 8 days
  })

【讨论】:

  • cy.get('.flatpickr-current-month &gt; select &gt; option').eq(0) 总是得到一月。
  • cy.wait(5000) 不是必需的。
  • .contains(new RegExp(futureDay, "g")).contains(futureDay)有同样的问题,可能匹配错了日期。
  • 另外,如果您使用的是.click({force: true}),那么很可能该元素被隐藏或禁用(因此是错误的元素)。您不需要强制使用 flatpickr,这样做是一种反模式。
  • cy.get('.flatpickr-current-month > select > option').eq(0) 正在获取当前月份。 DOM 中未显示前几个月。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-01
  • 2021-03-27
  • 2022-01-07
  • 1970-01-01
  • 2021-10-04
相关资源
最近更新 更多