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

Capybara.string treats newlines as meaningful #2402

Open
mockdeep opened this issue Oct 2, 2020 · 7 comments
Open

Capybara.string treats newlines as meaningful #2402

mockdeep opened this issue Oct 2, 2020 · 7 comments

Comments

@mockdeep
Copy link

mockdeep commented Oct 2, 2020

Meta

Capybara Version: 3.0 - 3.33.0
Driver Information (and browser if relevant): Not relevant, using Capybara.string

Expected Behavior

Capybara.string should ignore newlines (\n) in content. In Capybara 2.18 the following works:

html = "<p>\nThanks,\nSonya Signer\n</p>"

Capybara.string(html).has_text? "Thanks, Sonya Signer"
#=> true

Actual Behavior

Capybara.string treats newlines in HTML as meaningful content as of Capybara 3.0:

html = "<p>\nThanks,\nSonya Signer\n</p>"

Capybara.string(html).has_text? "Thanks, Sonya Signer"
#=> false
@twalpole
Copy link
Member

twalpole commented Oct 5, 2020

This is because Capybara 3 changed the text method to return something that should more closely match what the browser actually shows on screen. However, the Capybara::Simple class isn't doing as much as others (RackTest for instance) to clean up and parse that stuff. I guess the fact that no one else has commented shows how rarely Capybara.string is actually used since use cases in system/feature testing for it are pretty limited. Not sure whether or not we should change this currently but for now you should be able to pass the normalize_ws option to get what I believe you're expecting.

Capybara.string(html).has_text? "Thanks, Sonya Signer", normalize_ws: true

@mockdeep
Copy link
Author

mockdeep commented Oct 5, 2020

Okay, we'll give that a try. We're not actually calling Capybara.string directly, but using them implicitly in view specs like:

expect(rendered).to have_text("Thanks, Sonya Signer")

I guess we'll have to figure out a monkey patch of some sort to handle it.

@twalpole
Copy link
Member

twalpole commented Oct 6, 2020

You should be able to set Capybara.default_normalize_ws = true for your view specs for Capybara 3.x - you'll probably want to reset it to false for feature/system tests though since that setting will most likely go away in Capybara 4.x

@mockdeep
Copy link
Author

mockdeep commented Oct 6, 2020

@twalpole is there an alternative that is forward compatible with Capybara 4.x? Or do we just need to kill our view specs?

@twalpole
Copy link
Member

twalpole commented Oct 6, 2020

@mockdeep Probably not -- but that probably means I need to fix what Capybara::Simple is doing. Capybara.default_normalize_ws = true (and the normalize_ws option) was a temporary way to allow people with 2.x specs to run on 3.x, without updating their tests, but will be going away in 4.x. This is because text should be tested for the way the browser displays it (Capybara::Simple is obviously wrong on this currently). The real question is how to implement any Capybara::Simple changes now without breaking any tests that depend on the current behavior.

@mockdeep
Copy link
Author

mockdeep commented Oct 7, 2020

The real question is how to implement any Capybara::Simple changes now without breaking any tests that depend on the current behavior.

Well, being that we're the only people on earth affected by this, it may not end up being a problem. That being said, maybe you could somehow use the normalize_ws option or something like it to transition people to the "fixed" version of Capybara::Simple. e.g.:

  • add an option specific to Capybara::Simple, defaulting it to false
  • add a warning that it will change to the true behavior for Capybara::Simple in the next major version
  • remove it in the next major version and normalize whitespace?

@davidalejandroaguilar
Copy link

Just want to mention that testing something like:

<div>
  <span>Hello</span>
  <span>World</span>
</div>

With:

expect(page).to have_text("Hello World")

Does not work unless normalize_ws is added. Which is surprising because "Hello World" is what users see on screen.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants