简体   繁体   English

通过cypress.get()选择HTML中的元素

[英]Select elements in HTML via cypress.get()

I'm using cypress to write some tests against an html site.. 我正在使用赛普拉斯针对html站点编写一些测试。

The following selects me correctly a single tr elements from a table on my HTML site. 以下内容从HTML网站上的表格中正确选择了一个tr元素。 The site contents looks like this: 该站点的内容如下所示:

<tr data-recordid="theId">
  <td...><div ..>Text 1</div></td>
  <td...><div ..>Text 2</div></td>
  <td...><div ..>Text 3</div></td>
</tr>

The following test script snippet selects me correctly the single <tr..> part. 下面的测试脚本片段正确地为我选择了<tr..>部分。

cy.get('tr[data-recordid="theId"]').contains('Text')

Now I want to select the text within the <div>..</div> tags..The first thing I have tried to chain a single call for the first <div>..</div> tag like this: 现在,我想在<div>..</div>标记中选择文本<div>..</div>第一件事,我试图将单个调用链接到第一个<div>..</div>标记,如下所示:

cy.get('tr[data-recordid="theId"]').get('div').contains('Text')

which does not work as I expected. 这不符合我的预期。 The get() calls a chained jQuery calls (Based on the Docs of cypress). get()调用链接的jQuery调用(基于cypress的Docs)。 So it looks like I misunderstand how things work in JQuery. 因此,似乎我误解了JQuery中的工作方式。

What I'm expecting is how I can check all div elements like this (Not working): 我期望的是如何检查所有这样的div元素(不起作用):

cy.get('tr[data-recordid="theId"]')..SomeHowMagic
  .get('td[alt="xyz"]".get('div').contains('Text 1')
  .get('td...').get('div').contains('Text 2')
  .get('td...').get('div').contains('Text 3')

Any idea how to get forward a step? 知道如何前进吗? Missing any information just make a comment. 缺少任何信息只需发表评论。

Let's clarify a few things: 让我们澄清一些事情:

1) If you are just wanting to ASSERT that the div's contain the given text then this is the best possible and most precise way to do this: 1)如果您只是想断言div包含给定的文本,那么这是执行此操作的最佳方法:

cy.get('tr[data-recordid="theId"]').should(($tr) => {
  const $divs = $tr.find('div') // find all the divs

  expect($divs.eq(0)).to.contain('Text 1')
  expect($divs.eq(1)).to.contain('Text 2')
  expect($divs.eq(2)).to.contain('Text 2')
})

I can't tell if things need to be this specific. 我无法确定是否需要具体说明。 If you only want to ensure that the $tr contains text you could simplify it down to be: 如果仅要确保$tr包含文本,则可以将其简化为:

cy.get('tr[data-recordid="theId"]').should(($tr) => {
  expect($tr).to.contain('Text 1')
  expect($tr).to.contain('Text 2')
  expect($tr).to.contain('Text 2')
})

Why do it this way? 为什么要这样呢?

  • Using a .should() function will not change the subject. 使用.should()函数不会更改主题。 Your $tr will continue to be the subject going forward. 您的$tr将继续成为未来的主题。
  • Cypress will wait until all of the assertions in the .should() callback pass, and continually retry until they do. 赛普拉斯将一直等到.should()回调传递中的所有断言为止,并不断重试直到断言。 That guarantees you the state of multiple elements is correct before proceeding. 这样可以确保您在继续操作之前,多个元素的状态是正确的。

2) However if you just care that Cypress finds the text and you don't mind the subject being changed you could do this: 2)但是,如果您只是想让赛普拉斯找到文本,并且不介意更改主题,可以这样做:

cy.get('tr[data-recordid="theId"]').within(() => {
  cy.contains('Text 1') // changes the subject to the <div>
  cy.contains('Text 2') // changes the subject to the <div>
  cy.contains('Text 3') // changes the subject to the <div>
})

This is different than the first example because instead of an explicit assertion you are simply changing the subject to whatever element the text is found in. Cypress's default assertion on cy.contains() is to retry so ultimately the behavior is the same, except you are additionally changing the subject. 这与第一个示例不同,因为您无需将显式声明更改为仅将主题更改为在文本中找到的任何元素。赛普拉斯对cy.contains()的默认声明是重试,因此最终行为是相同的,除了您另外正在改变主题。

If even this is too complicated you could also just do this: 如果这太复杂了,您也可以这样做:

cy.get('tr[data-recordid="theId"] div').contains('Text 1')
cy.get('tr[data-recordid="theId"] div').contains('Text 2')
cy.get('tr[data-recordid="theId"] div').contains('Text 3')

Your original question was also using chained cy.get() which does not drill into subjects. 您最初的问题还使用了不深入主题的链接cy.get() For that to happen use .find() 为此,请使用.find()

cy.get('a').get('span') // each cy.get() queries from the root
cy.get('a').find('span') // the .find() queries from the <a>

One final note: you suggested solution does not work. 最后一点:您建议的解决方案不起作用。 cy.get() does not accept a callback function, and if you look at your Command Log you will not see those 3 cy.contains from ever being invoked. cy.get()不接受回调函数,如果您查看命令日志,将永远不会看到这3个cy.contains In other words, they are not running. 换句话说,它们没有运行。 That's why its passing. 这就是它过去的原因。

So after more experimenting I found a solution: 因此,经过更多的实验,我找到了一个解决方案:

cy.get('tr[data-recordid="TheId"]>td> div', function() {
  cy.contains('Text 1').end()
  cy.contains('Text 2').end()
  cy.contains('Text 3').end()
})

If someone else has a better solution please post it here. 如果其他人有更好的解决方案,请在此处发布。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM