At Nebulab we are encouraged in spending Fridays on open source projects, and I simply love it.
A few Fridays ago I started working on a flaky spec that failed often on Solidus CI builds. This is pretty annoying as flaky failures mean the test suite must be run again with the usual consequences of uncertainty of results, wasted time, longer queues, wasted CPU time, CO2 buildup, seven years of famine and hordes of locusts (not necessarily in this order).
Most of the times flaky specs happen on Selenium tests, where JS interactions
may take a bit more time to complete and some parts of the HTML may not be yet
present or visible (want another example from Solidus codebase?
Here you are). But this time it was different: the spec
Rack::Test, which is usually very deterministic by nature, no
This is the relevant code of the tentative spec:
it "can sort desc" do within_table(table_id) do click_link sort_link, exact: false expect(page).to have_selector '.sort_link.desc' end end
It basically clicks on the sorting triangle icon visible in this screenshot:
and checks that the triangle sorting direction has changed (this happens with a page refresh, no JS involved):
Quite surprisingly, this spec fails with the current version of Capybara (3.13.2):
expected to find css ".sort_link.desc" within #<Capybara::Node::Element tag="table" path="/html/body/div/div/div/fieldset/table"> but there were no matches
If you change Capybara driver to Firefox or Chrome, for example by changing the first line to:
it "can sort desc”, :js do
then the spec passes without errors, so it must be an issue with
After digging a bit inside Capybara source code I confirmed that what happens
here is that the Capybara node that represents the HTML of the selected table
is not refreshed after the page reload, so changes that happen within that
block are not visible.
There’s an easy workaround that solves this issue: you just need to close the
within block after clicking the link and reopening it before checking the
page, actively forcing Capybara to reload the HTML block from the table:
it "can sort desc" do within_table(table_id) do click_link sort_link, exact: false end within_table(table_id) do expect(page).to have_selector '.sort_link.desc' end end
I won’t claim to be the first man on earth that encountered this issue, but I think it’s quite rare as nobody here at Nebulab had seen this before, and also a few internet searches did not bring any results to me. This bug is barely worth noticing, the fix is very simple and makes perfect sense: if you need the node to be updated, just close and reopen the block.
Still, I decided it was worth digging a bit deeper and notify the Capybara team about the issue. After a few days they fixed it.
I think this is a good example of OSS cooperation between different projects, this kind of interactions are good for the community as they lead to improvements that will benefit everybody.
If you have an apple and I have an apple and we exchange these apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
I think that software is more like ideas than apples, as it’s much easier to do good to others while still pursuing your (selfish) interest: if I share my apple with you, we both have only half an apple. But if I write some software and share it with you, then we both can benefit from the code.