如何使用 cypress 检查元素内部文本的相等性?

Posted

技术标签:

【中文标题】如何使用 cypress 检查元素内部文本的相等性?【英文标题】:How do you check the equality of the inner text of a element using cypress? 【发布时间】:2019-02-25 02:40:21 【问题描述】:

我有一个 div,里面有另一个 div,我想检查 div 内部文本的相等性。我已经想出了如何使用invoke('text') 函数来做到这一点,但我想知道这是否是最好的方法。所以我的问题是:

it('the channel name should contain be Anakin Skywaler', () => 
  //This works but can we be more specific with our selector
  cy.get("[data-test-id='Skywalker,Anakin']").should('contain', 'Skywalker,Anakin');
)

it('the channel name should equal Skywalker,Anakin', () => 
  cy.get("[data-test-id='Skywalker,Anakin']").find('.channel-name').invoke('text').then((text) => 
    expect(text.trim()).equal('Skywalker,Anakin')
  );
);

请忽略星球大战参考!

【问题讨论】:

【参考方案1】:

你可以检查一个字符串是否包含在 div 的某个地方:

cy.get("[data-test-id='Skywalker,Anakin']").contains('Skywalker,Anakin');

或者,如果您需要确保 div 只包含 指定的文本而不包含其他任何内容,您可以标记这个额外的断言:

cy.get("[data-test-id='Skywalker,Anakin']").contains('Skywalker,Anakin').should((elem) => 
    expect(elem.text()).to.equal('Skywalker,Anakin');
);

解释:

// Get the data
cy.get("[data-test-id='Skywalker,Anakin']")

        // Get the child or children of the previous command that
        // contain the text - this command fails if no child
        // element is found containing the given text
        .contains('Skywalker,Anakin');
// These two lines are explained above
cy.get("[data-test-id='Skywalker,Anakin']")
        .contains('Skywalker,Anakin')

        // Like a .then(), except the contents are retried until
        // all contained assertions are successful or until the
        // command times out
        .should((elem) => 

            // Expect the element's text to exactly equal the
            // string, not just contain it
            expect(elem.text()).to.equal('Skywalker,Anakin');
        );

【讨论】:

我不喜欢使用包含,我认为在这种情况下,您应该检查它是否正是它应该是的。因此,我喜欢您的第二个选项,但我希望它没有包含。你有什么不使用包含的选项吗?感谢您的回答。【参考方案2】:

我认为目前这是最好的选择,因为它不检查包含。我希望有一段更短的代码来做到这一点。

it('the channel name should equal Skywalker,Anakin', () => 

    cy.get("[data-test-id='Skywalker,Anakin']").find('.channel-name').invoke('text').then((text) => 
        expect(text.trim()).equal('Skywalker,Anakin')
    );
);

【讨论】:

【参考方案3】:

我想你可以简化一下。

假设您的 html 如下所示:

<div data-test-id="Skywalker,Anakin">
  <div class=".channel-name">Skywalker,Anakin</div>
</div>

你可以这样写你的断言:

cy.get('[data-test-id="Skywalker,Anakin"]').should(
  "have.text",
  "Skywalker,Anakin"
);

这对我来说已经过去了,如果我将 HTML 修改为 Skywalker,Anakin 1,它会如您所料那样失败。 Cypress 使用 have.text 查看渲染出来的内容,因此它不会担心任何标记,只需查看结果。

这不适用于修剪。您需要添加一个回调来进行修剪。

cy.get('[data-test-id="Skywalker,Anakin"]').should(($div) => 
  expect($div.text().trim()).equal("Skywalker,Anakin");
);

【讨论】:

它对我有用,在我的 html 中,类 channel-name 是天行者的孙子,anankin div 并且确实有效。也知道我永远不会那样设置 data-test-id,这是我们的一些实际代码,我必须处理给定的内容,我希望它是 ID 属性,值是整数字符串..但这是另一个讨论.. 见:github.com/cypress-io/cypress/issues/3887【参考方案4】:

以下是检查元素中字符串的完全匹配或部分匹配的方法:

//matches exact text of result string
cy.get("[data-test-id='Skywalker,Anakin']").should('have.text', 'Skywalker,Anakin');

//matches partial text of result string
cy.get("[data-test-id='Skywalker,Anakin']")
.text()
.then(value => 
        cy.log("Text value is :", value);
        expect(value).to.include('Anakin');
);

其中text()command.js 文件中定义如下:

Cypress.Commands.add("text",  prevSubject: true , (subject, options) => 
  return subject.text();
);

【讨论】:

【参考方案5】:

不敢相信我没有看到神奇的柏树.should 匹配之一。我还使用 typescript cypress,它提供了很好的查找/智能感知。

使用应该。但是,这些是完全匹配的文本,可能有很多空格
cy.get("[data-test-id='Skywalker,Anakin']")
        .should("have.text", "Skywalker,Anakin")
        .should("have.attr", "data-test-id","Skywalker,Anakin'")

添加新命令会更好,例如 shouldHaveTrimmedText 我从https://github.com/cypress-io/cypress/issues/3887#issuecomment-522962482得到它 但下面是让它工作的设置也可以使用 typescript 查找

commands.ts

Cypress.Commands.add(
    'shouldHaveTrimmedText',
    
        prevSubject: true,
    ,
    (subject, equalTo) => 
        if (isNaN(equalTo)) 
            expect(subject.text().trim().replace(/  +/g, ' ')).to.eq(equalTo);
         else 
            expect(parseInt(subject.text())).to.eq(equalTo);
        
        return subject;
    ,
);

cypress/support/index.d.ts

Cypress.Commands.add(
    'shouldHaveTrimmedText',
    
        prevSubject: true,
    ,
    (subject, equalTo) => 
        if (isNaN(equalTo)) 
            // removes double spaces and ending spaces, does not remove special characters such as tabs or \n
            expect(subject.text().trim().replace(/  +/g, ' ')).to.eq(equalTo);
         else 
            expect(parseInt(subject.text())).to.eq(equalTo);
        
        return subject;
    ,
);

tsconfig


"types": ["cypress","./cypress/support"]
// or "typeRoots": ... but not both

cy.get("[data-test-id='Skywalker,Anakin']")
        .shouldHaveTrimmedText("Skywalker,Anakin")

【讨论】:

以上是关于如何使用 cypress 检查元素内部文本的相等性?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Cypress.io 检查元素是不是存在

检查两个数组之间的相等性[重复]

如何散列和检查具有循环引用的对象的相等性

我如何等待列表中的每个元素使用 cypress 更新为特定文本

如何在 C++ 中逐个元素地比较两个向量的相等性?

如何检查排列是不是具有相等的奇偶性?