首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何验证是否从Cypress中的表中选择了正确的用户(html-table /角材料)

如何验证是否从Cypress中的表中选择了正确的用户(html-table /角材料)
EN

Stack Overflow用户
提问于 2020-07-13 23:33:11
回答 3查看 2K关注 0票数 4

我试图删除一个特定的用户,如果我想要的用户不存在,我宁愿测试失败,然后删除另一个用户。

问题是,我似乎找不到一种方法来验证复选框在我想要的用户旁边。我一直在使用.each() nest来首先找到用户Mandy,然后选择具有相同索引的复选框。

HTML:

注意,我正在尝试删除用户"Mandy“,虽然我可以使用下面的代码来选择她,但这取决于测试到这个阶段的速度,实际上它可能会删除第一个用户。

删除Mandy Smith的当前代码:

代码语言:javascript
复制
         // looks for the checkbox related to Mandy Smith User
          cy.get('input[type="checkbox"]')
            .each(($elem, index) => {
                if(index === 2) {
                  cy.wrap($elem).click({force:true});
                }
            });

虽然这通常会抓住她,取决于过滤器被清除的速度,它实际上可以选择自动用户删除。我当然不想这样,我想找到一种很好的方法来验证Mandy的索引,并将其应用到她的复选框中。

复选框是动态的,因此它将根据单击的内容进行迭代,所以我不想选择带有标签“#mat-复选框-11”的确切复选框,因为在我查看代码时,它恰好是这样的,但是前面是5。

我认为这会让我找到索引并将其应用到复选框中:

代码语言:javascript
复制
// looks for the checkbox related to Mandy Smith User
    it(`should select Mandy, through verification that it's her index`, () => {
        cy.get('.mat-column-name.ng-star-inserted')
          .each(($name, i) => {
            if($name === 'Mandy Smith') {
                let dex = i;
                cy.get('input[type="checkbox"]')
                  .each(($elem, index) => {
                    if(index === dex) {
                        cy.wrap($elem).click({force:true});
                    }
                });
            }
        });
    });

这实际上只是删除自动用户而不是。

我确实运行了一些测试,并发现它返回的字符串是“Automated”。因此,尽管我正在遍历表,但它似乎同时拉出了两个文本字段。当所有的类名都相同时,我是不是遗漏了一些关于如何抓取一组文本的东西?

这意味着它删除了第一个用户,因为if语句将显示Mandy,然后选择第一个自动用户,而不是第二个用户Mandy。也许我需要知道如何从每个同名的类中获取文本。

我不知道,我现在有点不知所措了。

编辑:我发现我可以在if语句中调用文本,但是它永远不会在if语句中得到。我检查了它产生了什么,并把它粘贴到我的if中,但它仍然不起作用。下面是获取元素innerText的代码,它是用来与单词进行比较的。有什么原因不去评估真相吗?

代码语言:javascript
复制
    it(`should select Mandy, through verification that it's her`, () => {
        cy.get('.mat-cell.cdk-cell.text-capitalize.cdk-column-name.mat-column-name')
          .each(($name, i) => {
            //let columnText = ($name).invoke('text');
            if(cy.get($name).invoke('text') === ' Mandy Smith ') {
                cy.log('it made it inside the if');
            }
        });
    });

编辑7/15/2020:下面是整个表的图像。黄色箭头是她的行,右边是用户1的行。绿色箭头是她的复选框,红箭头是她名字列中的名字。

谢谢大家的留言。我今天要处理它,测试各种评论,看看是否能找到解决方案。请随时给予反馈,因为我会检查一整天。

解决了问题--谢谢--这里的每个人都有答案,我和一位高级开发人员通了电话,在看到我在做什么之后,他给我做了一些事情。感谢老生常谈,感谢他出色的回答,以及后续@eric99,感谢他为我提供了更多的帮助。你们两个是摇滚明星。

答案

代码语言:javascript
复制
    it(`should select Mandy Smith with contains only`, () => {
        cy.contains('td', 'Mandy Smith').siblings().eq(0).children().eq(0).click();
    });
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-07-14 12:25:51

编辑:查看@eric99下面的附加答案,以获得一个很好的解释。

cy.get('.mat-column-name.ng-star-inserted').contains('mandy smith')

如果名称是那些只匹配一个元素的.mat-column-name元素中的唯一标识符,则应该返回您要查找的基本元素。

从这里开始,您应该可以自信地做您想做的任何事情,比如导航到子/兄弟/父元素,找到一个可单击的元素(例如复选框),做出其他断言等等。这是假设输入字段与name列有某种关系,即两个元素都存在于同一行或父元素中。

如果两个元素(名称列和复选框输入)都位于同一行,则不需要遍历get()返回的每个元素,只需直接跳到包含所需内容的元素,然后导航到位于同一行元素中的同级input元素。

例如,如果您的html结构类似于此:

代码语言:javascript
复制
<tr tid='the-rowest-of-rows'>
  <td tid='the-checkist-of-checkboxes'><input tid='bam' ...></td>
  <td tid='name-column'>The mandiest Mandy Smith</td>
</tr>   

那么你的选择器就会看起来像。

代码语言:javascript
复制
cy.get('[tid=name-column]').contains('Mandy Smith')
  .siblings('[tid=the-checkist-of-checkboxes]')
  .find('[tid=bam]')
  .click()

(注意:我使用的是tid,而不是get()中的类选择器)

因为我不太清楚您的组件是如何设置的(我们需要围绕这个示例的原始html,包括示例中缺少的input ),所以我猜它应该是这样的。

根据您的html布局方式,这种关系可能会有所不同,您可能需要兄弟姐妹、父级或其中的某些变体/混合体。然而,这一切的要点是:

tl;dr:使用get().contains()检索Mandy元素。根据需要从那里导航到子/兄弟/父元素。

进一步读:

作为附带说明,为了进一步阅读,我建议查阅:

特别注意使用tid来选择元素。按班选通常是个坏主意。然而,更重要的是,tid可以帮助您在这里工作。根据您的前端框架,您可以动态地将一个tid直接添加到您想要单击的元素中,该元素将与您正在搜索的名称(即<input tid='input-${name.last}'>)相关联,这将直接导致您单击money。

此外,如果您对有关if语句不像预期那样工作的更多信息感兴趣,那么下面是一个非常棒的阅读:

我希望这对你有意义。很抱歉写了本书。如果这没有意义,或者你有任何问题,我很乐意回答它们。

票数 1
EN

Stack Overflow用户

发布于 2020-07-15 07:21:53

@OldSchool的解释是正确的,但你没有正确地理解它。

在你展示的评论中

代码语言:javascript
复制
cy.get('.mat-cell.cdk-cell.text-capitalize.cdk-column-name.mat-column-name')
  .invoke('text')                // REMOVE THIS COMMAND
  .contains('Mandy Smith');

问题是,在选择多个元素的invoke('text')之后,将连接所有这些元素的所有文本--(即name列中的所有单元格)。

相反,.get().contains('Mandy')选择包含'Mandy‘的单个单元格,然后使用sibling()限制下一个部分(查找复选框)以该表行仅为

如果页面上只有一个表,我将使用以下选项,因为它是最短的,并且使用Cypress选择器的能力达到最大效果。

Soultion

代码语言:javascript
复制
cy.contains('td', 'Mandy Smith')
  .siblings('td')   // get all sibling cells in the 'Mandy Smith' row
  .find('input')    // find the input within these cells
  .click();

Note,如果以异步方式获取表数据,则cy.contains(selector, content)cy.get(selector).contains(content)更可取,因为第一次重试直到内容到达为止。

在对进行测试之后,我修改了上面的代码,使用了示例“表与选择”(搜索位于第二行的“氦”)。

事实证明,.siblings(selector)中使用的选择器不能处理与.get(selector)相同的复杂性,例如

代码语言:javascript
复制
.get('td input')      // succeeds and finds all input cells

.siblings('td input') // fails to find the input, although it does exist

因此,使用.siblings('td').find('input')可以到达正确的位置。

来自.find()文档

获取特定选择器的子类DOM元素

也就是说,.find()将搜索限制在前一个主题(即同级单元格)中。

此操作在角材料网格示例页面上进行。如果您仍然没有运气,请将前两行的实际html发布为文本而不是图片,我将进行调查。

如果页面上有多个网格,则需要增强选择器,以便最初将其缩小到所需的网格。

探索性测试

Cypress有一个整洁的特性,允许您在DOM片段上实验不同的命令。

  • 将您正在处理的HTML片段复制到一个新的.html文件中,将该文件放在/cypress文件夹下,例如/cypress/myFragment.html
  • 片段html文件的内容不需要是一个完整的HTML文档,您可以省略标题和正文标记。在本例中,您需要一个<table>标记、一个<tbody>标记,并在前两行之间粘贴,这对于本实验来说就足够了。(别忘了关闭</table></tbody>)。
  • 编写一个访问HTML片段的实验性规范,例如cy.visit('cypress/myFragment.html')。Cypress将加载与完整HTML页面相同的内容。
  • 使用您想要实验的命令遵循cy.visit(),例如上面的解决方案代码。
  • 只运行该规范并调整命令,直到它们正常工作为止。
票数 2
EN

Stack Overflow用户

发布于 2020-07-14 10:29:11

也许我可以建议另一种方法,比如使用柏树xpath。首先安装如下:https://www.npmjs.com/package/cypress-xpath

然后,如果其中包含文本、Mandy等,则可以使用xpath选择复选框。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62885882

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档