Cypress 通过重试有条件地测试元素存在

Gre*_*son 7 conditional-statements cypress

我阅读了有关赛普拉斯条件测试的文档中的警告,但由于某些原因仍然需要将其应用于特定测试。

我有一个函数可以做到这一点,但由于该函数中缺乏重试,某些选择器无法工作。

如何在条件测试中实现重试并避免不稳定的测试?

这是否有可能,或者一件事可以抵消另一件事吗?

export function elementExists(selector: string): boolean {
  try {
    return Cypress.$(selector).length > 0;
  } catch (error) {
    return false;
}
Run Code Online (Sandbox Code Playgroud)

Fod*_*ody 6

测试元素是否存在的“标准”方法非常简单,但它不会返回 true/false。如果未找到元素,则测试失败。

cy.get(selector).should('exist')
Run Code Online (Sandbox Code Playgroud)

在内部.should()重试元素,直到命令超时完成 - 然后测试失败。

如果您使函数递归,您可以执行相同的操作,但不会失败,而是返回 true/false

function elementExists(selector, attempt = 0) {

  const interval = 100;  // 100ms between tries
  if (attempt * interval > Cypress.config('defaultCommandTimeout')) {
    cy.log(selector, 'not found')
    return cy.wrap(false, {log:false})      
  }

  return cy.get('body', {log:false}).then(($body) => {
    const element = $body.find(selector)
    if (element.length) {
      cy.log(selector, 'found')
      return cy.wrap(true, {log:false}) 
    } else {
      cy.wait(interval, {log:false})  
      return elementExists(selector, ++attempt)
    }
  })
}

elementExists(selector).then(exists => {
  if (exists) {
    ...
  }
})
Run Code Online (Sandbox Code Playgroud)


Tes*_*ick 5

现在使用cypress-if就更容易了

但重试是异步实现的,因此您必须返回一个 Chainable。

export function elementExists(selector: string): Chainable<boolean> {
  return cy.get(selector)
    .if('exist')
    .then(true)
    .else()
    .then(false)
}

elementExists('span#123').then((result: boolean) => 
  if (result) {
    ...
  }
})
Run Code Online (Sandbox Code Playgroud)

上面使用了完整的 API 并且非常易读,但这也应该适合你

export function elementExists(selector: string): Chainable<JQuery<HTMLElement>|undefined> {
  return cy.get(selector).if()
}

elementExists('span#123').then((result: JQuery<HTMLElement>|undefined) => 
  if(result.length) {
    ...
  }
})
Run Code Online (Sandbox Code Playgroud)