Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cy.contains() improvements: normalizing whitespaces, case-sensi… #5653

Merged
merged 16 commits into from
Jan 30, 2020

Conversation

sainthkh
Copy link
Contributor

@sainthkh sainthkh commented Nov 11, 2019

These 2 are fixed together because the implementation for one can affect the other.

User facing changelog

  • When there are multiple white spaces, it is replaced to a single white space except in <pre> tag.
  • Added matchCase option to cy.contains().

Additional details

Why was this change necessary?

issue #92

Sometimes when I issue .contains() commands with text I expect to be found, it doesn't match my element as expected due to extra whitespace/new lines in my element.

HTML

<h1>hello
world</h1>

Test

cy.contains("hello world") 
// CypressError: Timed out retrying: Expected to find content: 'hello world' but never did.
issue #2785

We can currently use regex, but in some cases, we need Cypress's out-of-the-box option.

What is affected by this change?

cy.contains() can do more things like ignoring multiple spaces and case-sensitivity.

Any implementation details to explain?

A new contains implementation has been added.

How has the user experience changed?

Screenshot from 2019-11-11 17-54-59

PR Tasks

Documentation and type definition tasks will be started when this PR is ready and reviewed.

@cypress-bot
Copy link
Contributor

cypress-bot bot commented Nov 11, 2019

Thanks for the contribution! Below are some guidelines Cypress uses when doing PR reviews.

  • Please write [WIP] in the title of your Pull Request if your PR is not ready for review - someone will review your PR as soon as the [WIP] is removed.
  • Please familiarize yourself with the PR Review Checklist and feel free to make updates on your PR based on these guidelines.

PR Review Checklist

If any of the following requirements can't be met, leave a comment in the review selecting 'Request changes', otherwise 'Approve'.

User Experience

  • The feature/bugfix is self-documenting from within the product.
  • The change provides the end user with a way to fix their problem (no dead ends).

Functionality

  • The code works and performs its intended function with the correct logic.
  • Performance has been factored in (for example, the code cleans up after itself to not cause memory leaks).
  • The code guards against edge cases and invalid input and has tests to cover it.

Maintainability

  • The code is readable (too many nested 'if's are a bad sign).
  • Names used for variables, methods, etc, clearly describe their function.
  • The code is easy to understood and there are relevant comments explaining.
  • New algorithms are documented in the code with link(s) to external docs (flowcharts, w3c, chrome, firefox).
  • There are comments containing link(s) to the addressed issue (in tests and code).

Quality

  • The change does not reimplement code.
  • There's not a module from the ecosystem that should be used instead.
  • There is no redundant or duplicate code.
  • There are no irrelevant comments left in the code.
  • Tests are testing the code’s intended functionality in the best way possible.

Internal

  • The original issue has been tagged with a release in ZenHub.

@sainthkh sainthkh force-pushed the issue-92-fix branch 2 times, most recently from 2222f86 to 3caf09b Compare December 3, 2019 03:58
@sainthkh sainthkh marked this pull request as ready for review December 3, 2019 03:59
@sainthkh sainthkh changed the title [wip] cy.contains() improvements: normalizing whitespaces, case-sensitivity. (Waiting for #5643) cy.contains() improvements: normalizing whitespaces, case-sensitivity. Dec 3, 2019
@sainthkh sainthkh changed the title cy.contains() improvements: normalizing whitespaces, case-sensitivity. wip cy.contains() improvements: normalizing whitespaces, case-sensitivity. Dec 3, 2019
@sainthkh sainthkh changed the title wip cy.contains() improvements: normalizing whitespaces, case-sensitivity. cy.contains() improvements: normalizing whitespaces, case-sensitivity. Dec 3, 2019
@jennifer-shehane jennifer-shehane requested a review from a team December 19, 2019 06:37
@chrisbreiding
Copy link
Contributor

Is it possible this is a breaking change? Could a user have tests that rely on the old behavior and they will fail once this is introduced? Just need to know so that we can hold off on releasing this until the next major version of Cypress.

@sainthkh
Copy link
Contributor Author

sainthkh commented Jan 7, 2020

@chrisbreiding #2785 doesn't break anything but #92 can be a breaking change. Then, should I change the target branch to v4.0-release?

@jennifer-shehane
Copy link
Member

@sainthkh Yes, breaking changes should target v4.0-release release

@jennifer-shehane jennifer-shehane added the type: breaking change Requires a new major release version label Jan 7, 2020
@sainthkh sainthkh changed the base branch from develop to v4.0-release January 7, 2020 07:20
@sainthkh
Copy link
Contributor Author

sainthkh commented Jan 7, 2020

Rebased and tests all passed.

@chrisbreiding
Copy link
Contributor

I think the only thing left for this is to update the documentation. @sainthkh Can you open a PR targeting cypress-io/cypress-documentation#1710? Please update the cy.contains() page to detail this new behavior and update the 4.0 migration guide with an example of a test that will break with this change and how to fix it.

@sainthkh
Copy link
Contributor Author

  1. Added option type for cy.contains().
  2. Wrote documentation at Cypress issue#92: cy.contains() doc. cypress-documentation#2397
  3. Added a new test for leading/trailing whitespaces.

@jennifer-shehane jennifer-shehane requested review from jennifer-shehane and chrisbreiding and removed request for a team January 15, 2020 06:23
const normalizeWhitespaces = (elem) => {
let testText = elem.textContent || elem.innerText || $.text(elem)

if (elem.tagName === 'PRE') {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why the exception for pre tags? I mean, I can kind of get the logic, but it does seem strange to make an exception for a single tag and this not be documented anywhere. I guess that's my concern. Someone opening an issue one day like, 'this is working differently here' and we have this undocumented exception.

Copy link
Contributor Author

@sainthkh sainthkh Jan 15, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pre tag preserves whitespaces like this:

https://codepen.io/sainthkh/pen/jOEpzmX

So, it is the exception. Because I thought it reflects how browsers work.

Do you think we need a section for this behavior in contains() documentation?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah...probably adding a section in the Notes of the .contains() doc so that people can find this somehow. There's are other exception notes in there.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about elements styled with white-space: pre;?
We have cases where upgrading to Cypress 4 breaks tests where we're explicitily want to vaildate that the whitespace is present as it is rendered. Should there be a flag allowing override of this behaviour?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mariusnn It's going on #6411.

Copy link
Member

@jennifer-shehane jennifer-shehane left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • I ran our Dashboard tests through this branch since we have about 1,000 uses of .contains() in there. I didn't see anything really strange pop up. It doesn't even seem to be breaking any of our usecases - probably because we've avoided asserting on newlines before.
  • I functionally tested this on a few examples and it seems to be working as intended.

It feels a bit weird that this test case passes...

// <h1>hello world</h1>
cy.contains(/Hello World/i, { matchCase: true }) 

Also the exception of the <pre> tag seems a bit weird as undocumented behavior as mentioned in another comment.

@sainthkh
Copy link
Contributor Author

sainthkh commented Jan 15, 2020

// <h1>hello world</h1>
cy.contains(/Hello World/i, { matchCase: true }) 

In this case, how about throwing an error?:

cy.contains() option `matchCase` and regex flag conflicts. 

@sainthkh
Copy link
Contributor Author

sainthkh commented Jan 16, 2020

Now, an error is thrown for cy.contains(/Hello World/i, { matchCase: true })

@sainthkh
Copy link
Contributor Author

sainthkh commented Jan 28, 2020

Fixed how error message is thrown. But it fails a lot because of "Error: Resolution method is overspecified. Specify a callback or return a Promise; not both."

It was introduced in bcc48f2. Needs to find way to fix it.

Opened an issue at #6260.

@jennifer-shehane
Copy link
Member

Yah, the 4.0 branch is broken atm, so trying to fix that up to get these tests passing.

@chrisbreiding chrisbreiding changed the title cy.contains() improvements: normalizing whitespaces, case-sensitivity. cy.contains() improvements: normalizing whitespaces, case-sensi… Jan 30, 2020
@chrisbreiding chrisbreiding merged commit 7ff91ed into cypress-io:v4.0-release Jan 30, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: breaking change Requires a new major release version
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants