在Cypress中如何计算所选项目并获取长度?

205

我开始学习Cypress。 我有一个4行表格(具有datatable类)。 我可以这样验证行数:

cy.get('.datatable').find('tr').each(function(row, i){
        expect(i).to.be.lessThan(4)
})

这样做没问题,但感觉不太方便,因为我只想计算长度而不需要访问行内的内容,我觉得一个操作比四个操作快。

如果我记录选择的内容(不确定怎么称呼):

cy.log(cy.get('.datatable').find('tr'))

输出结果是[object Object],我不太确定如何分解它,这提示我可能在思考这个问题时出现了错误。

如果我尝试:


expect(cy.get('.datatable').find('tr')).to.have.lengthOf(4)

我收到了一个错误信息:AssertionError: expected { Object (chainerId, firstCall) } to have a property 'length'

如果我尝试:

expect(Cypress.$('.datatable > tr')).to.have.lengthOf(4)

我得到了AssertionError: expected { Object (length, prevObject, ...) } to have a length of 4 but got 0,那么至少它在这里有一个长度吗?

如果我记录选择的方法,我会得到Object{4}。 我不确定接下来该怎么做。 看起来这应该是一个非常常见的问题。


我的客户只使用Chrome浏览器(这不是公共应用程序)。我们已经放弃了Cypress,因为我们正在将应用程序转换为Angular,并且现在使用Karma和Jasmine(它们内置于框架中)。我发现Cypress很容易使用,但我没有选择它(也没有选择Angular);然而,我必须说,Cypress的广泛文档可能非常有吸引力。当测试不是您的专长而更像一项琐事时,具有良好示例的广泛文档可以帮助您更快地上手。 - Katharine Osborne
非常感谢你的反馈,Katharine。 - alexrogers
11个回答

276

7
这是一个测试长度的好方法,但你不能用这种方法返回长度。要返回长度,你需要使用 Promise 链 .then(elm => elm.length) - png
看起来 .should('have.length', 4) 检查的是“至少4个”。另一种解决方案,使用 .its('length').should('eq', 4),检查精确相等性。 - NPC
5
问题是“如何计算所选项目并获取其长度?”,而不是“如何检查”——目标是在链接外返回计数。 - Sasha Bond
对于 Cypress.$ 方法,你可以尝试 expect(Cypress.$(".datatable").find('tr').length === 4),但Katarine的建议可能是更好的选择。在Cypress中,最好将使用 Cypress.$ 与其他检查结合使用。 - InvisibleExo
@png 你的意思是我们可以这样获取长度吗?eleLength = cy.get(selector).should('have.length.greaterThan', 0).then(elm => elm.length); - paul

126

你还可以通过其属性获取所选项目的长度,例如:

cy.get('.datatable').find('tr').its('length').should('eq', 4)
cy.get('.datatable').find('tr').its('length').should('be.gte', 4)

除了should('have.length', 4)之外

enter image description here 我测试过Cypress版本3.1.0和3.2.0。


尝试了这些并出现错误:TypeError: $table.find(...).its不是一个函数。 - Steve Staple
@SteveStaple 我又试了一遍最新版本的Cypress,v3.2.0,它仍然可以工作。请查看我的更新答案和截图。 - Yuci
6
出于灵活性的考虑,我更喜欢这种解决方案而不是使用.should('have.length', length)的期望,因为.its('length')提供了更大的断言灵活性,例如大于或小于。 - Mobiletainment
6
只是提醒一下,您也可以使用大于或小于符号与 should 一起使用,就像这样:should('have.length.gte', length) - Matan Bobi

44

如果您想要更灵活并获得动态结果,请使用此选项。

cy.get('.listings-grid')
  .find('.listing')
  .then(listing => {
    const listingCount = Cypress.$(listing).length;
    expect(listing).to.have.length(listingCount);
  });

3
只有在 .then() 内部才能填充 listingCount,无法在外部返回它。.its('length') 也返回链接对象,而不是整数。 - Sasha Bond
1
这个测试会出现不稳定的情况,因为只有最后一个 then 会在超时期间内重试。 - Muhammad bin Yusrat
@SashaBond 为什么不将变量提升到更高的作用域,然后在 .then() 中修改它。这应该可以解决作用域问题。 - sao

20

一个选择是使用"have.length" ...

cy.get('.datatable tr').should('have.length', 4)

...另一种选择是使用should

cy.get('.datatable tr').should(($tr) => {
    expect($tr).to.have.length(4)
})

...或者是同步查询

cy.get('.datatable').then(($table) => {
  // synchronously query to find length of elements
  expect($table.find('td').length).to.equal(4)
})

如果您有动态内容,第一个解决方案是最佳选择 - 否则 .get 将立即工作并返回错误的查找数量,即使实际数字已更改也会等待。此解决方案将等待正确的数字。 - James Cameron

5

Cypress API 文档 .should() 部分,使用 箭头函数:

cy.get('.datatable').find('tr').should(($listOfElements) => {
   expect($listOfElements).to.have.length(4)
   // any other assertions, for example the below one
   // expect($listOfElements).to.have.any.keys('key1', 'key2')
})

这种方法可以让您使用Chai BDD表示法,并在元素列表中断言多个内容。


其他断言可以与.and()链接,参见should.html#Multiple-Assertions。在我看来,更少的噪音。 - user8745435

2
cy
  .get('ul[data-qa="qa-navbar"] li')      // selector 
  .should('have.length', 5)               //  Assertion

8
通常情况下,如果答案包含代码意图的解释以及为什么这样做可以解决问题而不引入其他问题,则答案会更加有帮助。 - DCCoder
看起来这是已接受的答案的重复。考虑给已接受的答案点赞,而不是重新发布它。 - undefined

1
我的用例是比较页面上的“i”图标数量是否与表格行数相匹配。因此,这个解决方案适用于当我想要比较一个选择器的元素数量与另一个选择器时。
cy.get('first element').its('length').then((val)=>{
     cy.get('second element).its('length').should('eq',val)
})

its 之后写入 then 可以捕获所请求的属性(在此情况下是长度),并且在第一个 then 块中,我们通过获取第二个元素的长度来进行比较。

0
  • .children (通过id、class或自定义属性选择器) 返回DOM元素,并在默认命令超时时间内重试。

    cypress配置 defaultCommandTimeout

  • 一旦DOM元素存在并被返回,添加length断言。

<ul data-qa="qa-navbar">
  <li>Home</li>
  <li>About</li>
  <li>Services</li>
  <li>Our Team</li>
  <li>Contact Us</li>
</ul>


    cy
      .get('[data-qa="qa-navbar"]') // selector
      .children() // get direct decendents 
      .should('have.length', 5); // add assertion to have lenght of 5


-1
 - In the element locator "aria-setsize" property to find the "number of items in the current set of listitems or treeitems" can be used.
 - Within ".then" function, for the previously yielded element. Use ".length" jquery as below.
 - To find the list of: Best Sellers in Computers & Accessories, in "Amazon.in" home screen.

it('test', () => {
        cy.visit('https://www.amazon.in/ref=nav_logo')
        cy.wait(3000)
        cy.get('#desktop-5 li[aria-setsize]')
        .then(($el) => {
         const count= $el.length
         cy.log(count)
        })

    })

-1

要获取长度,您需要使用Cypress命令:

    cy.get('[ng-repeat="item in catalog"]').then(($el) => { 
        const itemCount = Cypress.$($el).length;
        cy.log(itemCount)
    })

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接