我正在编写Cypress测试,我们的应用程序有一堆表单,它们都遵循一个特定的模式,首先是本地验证,然后是提交时的服务器验证.如果出现服务器错误,它会呼叫setCustomValidityreportValidity()

我遇到的问题是我想要编写一个如下所示的测试:

cy.intercept('POST', '/api**').as('apiRequest')

// ...test code to fill in fields

// Here I'm clearing the field I care about
cy.wrap($input).clear()

// The actual input I care about
cy.get('[name=zip]').type('00000')

cy.get('form [type=submit]').click()

cy.wait('@apiRequest').then((interception) => {
  cy.get('[name=zip]').then(($input) => {
    expect($input[0].validationMessage).to.eq(errorMessage)
  })
})

然而,问题是在实际的应用程序代码中,expect($input[0].validationMessage).to.eq(errorMessage)行是在onComplete回调之前调用的.它看起来类似于:

function submitHandler() {
   // This is what is intercepted by Cypress
   makeAnApiCall({
    variables: {
      input: {
        // ...
      },
    },
    onCompleted(response) {
      const addressResponse = response.createAddress
      
      // ... the rest of the handling logic. If there are errors...
      // This runs AFTER the cy.intercept callback is run so tests fail
      addressResponse?.messages.forEach((message) => {
        elementArray[message.field]?.setCustomValidity(message.help)
        elementArray[message.field]?.reportValidity()
      })
    },
    onError(error) {
      // ...
    },
  })
}

您可以在上面看到API调用完成后的报告调用.这是有道理的,因为Cypress 可能是为了监视它而包装它,其他等待它完成的人被称为after间谍回调.

我唯一的 idea 就是听间谍说:

cy.spy($input[0], 'reportValidity').as('validitySpy')
cy.wait('@validitySpy').then(() => {/* check validation here */})

但这不起作用或不受支持.总的来说,我是不是做错了,或者我应该怎么做?最好不要将数据属性注入DOM以跟踪API请求的状态.

推荐答案

你可能只需要把.then()改成.should().这将使您重试预期,并有足够的时间触发onComplete处理程序.

cy.wait('@apiRequest').then((interception) => {
  cy.get('[name=zip]').should(($input) => {
    expect($input[0].validationMessage).to.eq(errorMessage)
  })
})

您也不需要在回调中执行断言,Intercept Wait命令将等待拦截.

cy.wait('@apiRequest')

cy.get('[name=zip]').should(($input) => {
  expect($input[0].validationMessage).to.eq(errorMessage)
})

还有一个建议(但这并不是真正的改进),您可以使用流畅的语法

cy.wait('@apiRequest')

cy.get('[name=zip]')
  .its('validationMessage')
  .should('eq', errorMessage)

Javascript相关问答推荐

如何制作删除按钮以从列表中删除该项目所属的项目?

React对话框模式在用户单击预期按钮之前出现

在JavaScript中检索一些文本

react 路由加载程序行为

窗口.getComputedStyle()在MutationObserver中不起作用

传递一个大对象以在Express布局中呈现

单击子元素时关闭父元素(JS)

判断表格单元格中是否存在文本框

为什么这个JS模块在TypeScript中使用默认属性导入?""

在这种情况下,如何 for each 元素添加id?

无法读取未定义错误的属性路径名''

查询参数未在我的Next.js应用路由接口中定义

如果没有页面重新加载Angular ,innerHTML属性绑定不会更新

JS Animate()方法未按预期工作

将范围 Select 器添加到HighChart面积图

如何使用抽屉屏幕及其子屏幕/组件的上下文?

P5.js中矩形内的圆弧

如果我的列有条件,我如何呈现图标?

在单击按钮时生成多个表单时的处理状态

TabNavigator和StackNavigator之间的Reaction Native中的导航问题