If your HTML happens to have whitespace in the tag, e.g., <div> foo </div>
, that text will not impact how the user sees the page, unless it is a <pre>
element. I don't think that the 'have.text'
assertion should fail just because it found ' foo '
when it was expecting 'foo'
.
If you're not willing to change this (since it is technically a breaking change), maybe there should be a have.text.trimmed
?
should('have.text', ...)
fails if the HTML contains whitespace, even if that whitespace doesn't impact the rendered content.
should('have.text', ...)
should ignore leading and trailing whitespace for elements that won't render it. Elements like pre
(and elements with certain white-space
css values) should still consider leading and trailing whitespace.
3.2.0
There's a related feature request here for making cy.contains()
strip newlines: #92
Recently I added a .text()
command to https://github.com/Lakitna/cypress-commands .
.text()
will trim whitespace and provides some whitespace options.
.text() command proposal: https://github.com/cypress-io/cypress/issues/630
It is nice to have the text()
trim the string but is it possible to chain assertions with text()
?
What I did was to add a custom command like:
Cypress.Commands.add(
'shouldHaveTrimmedText',
{
prevSubject: true,
},
(subject, equalTo) => {
if (isNaN(equalTo)) {
expect(subject.text()).to.eq(equalTo);
} else {
expect(parseInt(subject.text())).to.eq(equalTo);
}
return subject;
},
);
And now I can do:
cy
.get('.some-class')
.shouldHaveTrimmedText('whatever');
One way to go about it is:
cy.get('...').should($el => expect($el.text().trim()).to.equal('...'));
It is nice to have the
text()
trim the string but is it possible to chain assertions withtext()
?
Yes, .text()
as it exists in cypress-commands
awaits all its upcoming assertions via the same API as the default Cypress commands. This way it has the same behaviour as commands you're familiar with like .get()
.
cy.get('...')
.text()
.should('equal', 'foo');
I also encountered the same issue so I use:
cy.get('.message').should('contain.text', message)
the same issue as above - cypres 4.x
The problem with contains is it matches any substring.
Given:
<div> Tag1, Tag2 </div>
cy.get('div').should('have.text', 'Tag1, Tag2');
should pass (trims whitespace)
cy.get('div').should('have.text', 'Tag1');
should fail because of the extra text
Given that the cypress matchers are Chai, I'm not sure if we'd have to extend Chai or cypress to implement this.
This seems to work:
cy.get("div").invoke("text").then((text) => text.trim()).should("equal", "Tag1");
I'm not sure how to turn that into a custom command though.
@loren138 Have you seen these posts?
https://github.com/cypress-io/cypress/issues/3887#issuecomment-482277997
https://github.com/cypress-io/cypress/issues/3887#issuecomment-533880136
We try to keep the number of external packages as low as possible in our project so we can add our own custom commands but are not likely to use third party command packages.
This seems to work as a slight modification on https://github.com/cypress-io/cypress/issues/3887#issuecomment-522962482 but I don't think it's as flexible since it doesn't have the jQuery helper, but I can't figure out how to use invoke
in the custom command.
Cypress.Commands.add(
"shouldHaveTrimmedText",
{ prevSubject: true },
(subject, equalTo) => {
expect(subject.text().trim()).to.eq(equalTo);
return subject;
},
);
It shouldn't be difficult to copy .text()
from cypress-commands
. Why reinvent the wheel?
Most helpful comment
I also encountered the same issue so I use: