-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
[WIP] Fix flaky spec: Budget Investments - Balloting Phase - Confirm #3036
Conversation
Hi @microweb10. Thank you for this pull request (and bug report)! Unfortunately I couldn't reproduce the issue locally after running the test 60 times on the It looks like the view in So then, if capybara clicks the Since we try to describe feature specs as close to what users do as possible, we try not to execute JavaScript manually during a test. So, if possible, try to keep the original line My suggestion would be either to add an extra line after What do you think? |
@javierm it's curious that you cannot reproduce the failure. For me, it was not the first time I saw the same spec failing. Anyway, I agree and will keep investigating. Hopefully, I will find a good solution 😅 Thanks for the feedback! |
Yes, sometimes these flaky tests are quite a pain to debug. I remember there was one which used to fail on my machine about once every five times (I think it was the one fixed in #2995), but after we added some unrelated code which made requests a bit slower, I couldn't reproduce it on my machine unless I deleted the mentioned code 😄, even though it still failed on Travis builds once in a while. So it looks like depending on our machines we will be able to reproduce different flaky specs 🙄. |
@javierm I don't have very good news 😕 I've tried:
Actually I think the last option is the one we should use. I don't see the point of rendering twice the ballot the user has selected. But I'm still able to reproduce the flaky spec 😓. |
Interesting! How did you check all ballots had been re-rendered? A tip on debugging; you add the following code to config.after(:each, type: :feature) do |example|
if example.exception
save_and_open_page
save_and_open_screenshot
end
end If the screenshots are too small, you can change the size by changing a line in chromeOptions: { args: %w(headless no-sandbox window-size=1200,1600) } Feel free to share the screenshots with the GitHub community 😉. |
To check if all ballots are re-rendered I added the following code at the end of the method Budget::Investment.selected.by_heading(heading.id).each do |budget_investment|
within("#budget_investment_#{budget_investment.id}") { find('.ballot a') }
end Apparently that code works fine cause the method Yeah, I knew about the I attached an example just tested now:
|
Correct me if I'm wrong 🙏. I think the code: Budget::Investment.selected.by_heading(heading.id).each do |budget_investment|
within("#budget_investment_#{budget_investment.id}") { find('.ballot a') }
end Doesn't really check all ballots have been re-rendered, because the Thank you for sharing the screenshot! After seeing it, I'm more confident the problem is related to the |
I'm afraid you are more than right, it doesn't really check it 😅 But, there should be a way, I will keep thinking about it. The funny thing is that I also tried to remove the part that re-render all ballots and only re-render the one selected, but I was still getting failures. Thanks for your help! I will keep investigating 😊 |
That's what really puzzles me about this issue 🤔. |
@javierm Yeah, me too. But I have tested it several times and still get the same flaky spec. After some more investigation I found out that the part that re-renders all the ballots was kind of needed. If removed, specs like The part that is not really needed is the one that re-renders the ballot that has been selected, as all ballots will be re-rendered after. So I removed that part. In a effort to make sure all ballots are re-rendered before clicking the link $("#budget-investments").append("<span id='renderingBallots' />");
$("#progress_bar").html('<%= j render("/budgets/ballot/progress_bar", ballot: @ballot) %>');
$("#sidebar").html('<%= j render("/budgets/investments/sidebar") %>');
$("#<%= dom_id(@investment) %>_ballot").html('<%= j render("/budgets/investments/ballot",
investment: @investment,
investment_ids: @investment_ids,
ballot: @ballot) %>');
$("#renderingBallots").remove(); And making sure there wasn't any span tag with that id before clicking the link. expect(page).to_not have_xpath "//span[@id='renderingBallots']", visible: false But I didn't have any luck. I was still getting the same failure. Looks like something is still executing when Capybara clicks the link, cause I tried to print some outputs for debugging in the controller. And the method So, the only idea I had was to make use of the Well, of course we could reload the page before adding investments to ballot, but it doesn't look like the right thing to do as well 😞 Let me know if you have any idea, cause I'm running out of them 😅 |
That sounds good 👍.
That's what I expected, since that's what always happens in similar flaky specs where links are replaced at the same time capybara tries to click them: no request is sent to the server. I'll let you know if I've got more ideas about how to fix the spec. |
Closing in favor of #3113. |
References
Issue #3035
Explain why the test is flaky
Apparently Capybara can execute a piece of JS before other execution of JS has completely finished.
Explain why your PR fixes it
Using
execute_script
method will addclick()
function to the bottom of JS call stack and the click will be executed after other JS functions are finished except for the ones using async callbacks.Notes
I've executed the test 150 times after the change and passed 100% of the times