capybara
capybara copied to clipboard
Capybara.string treats newlines as meaningful
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
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
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.
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
@twalpole is there an alternative that is forward compatible with Capybara 4.x? Or do we just need to kill our view specs?
@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.
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 tofalse
- add a warning that it will change to the
true
behavior forCapybara::Simple
in the next major version - remove it in the next major version and normalize whitespace?
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.