5

I'm using Cucumber with Capybara. I've noticed that suddenly, after a bundle install, that I'm getting failed tests now where new line characters are appearing in strings as part of the text.

Example error:

RSpec::Expectations::ExpectationNotMetError: expected to find text "Longview Road Clase Swansea SA6 7JL" in "Skip to main content\nGOV.UK\nDigital tachograph card\n......."

In the past, those new line characters weren't there. I'm struggling to track down which gem is causing this.

Is there a way to stop this without needing to do a strip on every string of text I extract from the webpage?

Some gem versions:

Capybara - 2.18 Rspec-expectations - 3.7.0 Cucumber - 2.4.0

Tom
  • 1,055
  • 1
  • 14
  • 29
  • What's the full text? Since I cannot see "Longview Road Clase Swansea SA6 7JL" in "Skip to main content\nGOV.UK\nDigital tachograph card\n......." – fabdurso Aug 01 '18 at 12:59

1 Answers1

12

Are you sure you're on Capybara 2.18? This is a behavior that changed in Capybara 3 where drivers are now expected to return text closer to what is displayed to the user - https://github.com/teamcapybara/capybara/blob/master/UPGRADING.md#node. If you really aren't using Capybara 3.x then you probably updated whatever driver you're using with Capybara and it is no longer supporting Capybara 2.x behavior.

If you are now on Capybara 3.x then you'll either need to change your tests to check for what is actually displayed (which is a more correct checking of things on the page) or you can use Capybara 3.5+ release which adds a normalize_ws option to the text/content matchers so you can write

expect(element).to have_text('Longview Road Clase Swansea SA6 7JL', normalize_ws: true)

to replicate more 2.x like behavior

Thomas Walpole
  • 48,548
  • 5
  • 64
  • 78
  • Thank you, Tom. I'll try 3.5 today and see how I get on with it. – Tom Aug 02 '18 at 07:50
  • 1
    Interesting you say that checking for whitespace "is a more correct checking of things on the page". Given that we're checking HTML elements where whitespace is not rendered, I don't see that this is "more correct". I find it to be the opposite... Thanks for the heads up on normalize_ws – Jonathon Horsman Aug 27 '18 at 17:28
  • @JonathonHorsman Yes -- if you have some text you expect to appear on one line then checking for "some text" vs "some\ntext" is only correct when whitespace is not normalized/collapsed to single spaces. When the whitespace is normalized "some\ntext" would become "some text" and therefore not differentiable. – Thomas Walpole Aug 27 '18 at 17:33
  • @JonathonHorsman The other thing to understand is we're not talking about about the whitespace in the HTML document -- we're talking about the whitespace as displayed in the browser -- ie

    some
    text

    --- for the

    element - `element.text` will return "some\ntext" -- if compared with 'normalize_ws' it will be treated as "some text". Another example would be

    some  text

    - `text` will return "some text" (with two spaces between 'some' and 'text' as would be shown in the browser, with normalize_ws it will be treated as a single space.

    – Thomas Walpole Aug 27 '18 at 17:36
  • Thanks @ThomasWalpole - unfortunately normalize_ws doesn't seem to work for has_link which means if I have a link some text I used to be able to match on has_link("some text") now it doesn't work at all. has_link("some\ntext") doesn't work either... – Jonathon Horsman Aug 28 '18 at 19:41
  • @JonathonHorsman That wouldn't actually be affected by normalize_ws at all since `has_link` is implemented purely via XPath - (also assume you mean `has_link?` and not 'has_link' since Capybara doesn't provide a 'has_link' method) My guess is your link has changed or isn't actually visible on the page, or you are actually calling 'has_link' and it's some other method not provided by Capybara. It's also not really anything to do with this question since it's about `text` and `have_text`. – Thomas Walpole Aug 28 '18 at 19:53
  • The only change was I upgraded from Capybara 2.6 to 3.3 and some tests started failing. Where it previously matched on have_text, have_css or have_link with nested elements, it now no longer matches, since new lines now appear. – Jonathon Horsman Aug 29 '18 at 20:35
  • @JonathonHorsman `have_text`, and `have_css` with a `:text` option should have broken - It's a documented change in 3.3 - `have_link` is purely XPath and shouldn't have changed (although 2.6 is really old and 3.3 isn't the latest) -- if you have an example that does file an issue on the Capybara project with an example that reproduces the issue. – Thomas Walpole Aug 30 '18 at 00:41
  • @ThomasWalpole is there more documentation on how `have_text` has changed? I am wondering if there is a way to override the method so that it ignores line breaks, the way it used to do in Capybara 2.x edit: Nevermind, I will give the `normalize_ws` option a try. – Phil Oct 15 '18 at 15:20
  • 4
    I've set `Capybara.default_normalize_ws = true` in my `spec_helper` and I'm all good now. I understand the update, but I feel a though defaulting to `true` on release would have broken fewer specs all around. – Phil Oct 15 '18 at 15:31
  • @Phil The option didn’t exist in 3.0 and the whole reason for Major version releases is because they have breaking changes. – Thomas Walpole Oct 15 '18 at 15:53