Capybara should have_content is not waiting long enough
So I am writing an acceptance test using capybara. The scenario was to connect our newsletter system to external mail service.
We will get redirected to our external service page to request access to the external mail service. And we will be redirected back to our system page when succeed.
When "I grant authorization" do fill_in "username", :with => "myapp" fill_in "password", :with => "secret" click_button "Allow Access" end Then "I should see 'Connection Established'" do page.should have_content "Connection Established" end And "I should see that I'm connected to Sample External Service" do page.should have_content "Connection Established: Sample External Service" page.should have_content "Deactivate Sample External Service syncing" end
But if I am not using
sleep before the
page.should have_content "Connection Established". The spec will fail. From what I know, using sleep is not the best practice, because it will make our test run slow.
How to make it waiting until it got redirected back to our system
There are 3 ways to adjust the maximum amount of time Capybaras methods will wait for their expectations to be true/elements to exist
Capybara.default_max_wait_time = <seconds> - This is the global setting which should be set high enough for the vast majority of your method calls
Capybara.using_wait_time(<seconds>) do ... end - This temporarily changes
default_max_wait_time inside the block and then returns it to its original setting when done. This makes sense when you have a number of methods you want to call with a new wait time, or you need to call a helper method with the wait time set to a different value.
:wait option - All Capybara finder and expectation methods accept a
:wait option which will change the maximum wait time for that method call. This makes sense to use when you have a specific case that requires a bit more waiting than normal
# This will wait up to 10 seconds for the content to exist in the page page.should have_content "Connection Established: Sample External Service", wait: 10
Note: In the future when posting questions it is generally helpful if you provide the full exact error message you get as part of your question.
You can use Capybara.using_wait_time(seconds) to temporarily change the value of
Capybara.default_max_wait_time for special cases:
Capybara.using_wait_time(10) do page.should have_content "Connection Established" end
For page transitions, I like to wait for the URL to change first, and then wait for content on the page. It gives you a more specific error if the redirect fails, and it naturally splits the long wait into two chunks. With two opportunities to hit
default_max_wait_time, the timeout is potentially doubled without actually changing it. If it's still not enough, you can always pass a custom timeout into
have_current_path with the
expect(page).to have_current_path("externalservice.com") expect(page).to have_content("Connection Established")
There might be a
page.should equivalent, but I think the official guidance is to move to the
expect syntax, since the
should syntax was deprecated.
Automatically Wait for AJAX with Capybara, expect(page).to have_css('.username', text: 'Gabe B-W'). But there are times when that's not enough. For example, in this code: visit users_path� Capybara Version: 2.10.1 Driver Information (and browser if relevant): selenium-webdriver 2.53.4 with Firefox 47.0.1 on OS X Sierra. Expected Behavior. Improve waiting for the window to resize. Here is how it could work for maximize (but similar technique could be applied to resize_window_to).
You can use
capybara_watcher gem, it is an elegant way of waiting for the
pege to have a change in its content.
Check it out on RubyGems.org
wait_until_content_has "Connection Established" do |text| page.should have_content text end
The perks of using this is that the sleep time is the actual time the page takes to have a change and you can configure it to exit after the second you choose if the page didn't change.
And as long as your needs are not being met, you’re not going to feel happy or fulfilled or secure in the relationship. So how long you’re willing to wait for them to meet your needs depends on the value you put on your time, the value you put on your needs, and your sense of urgency around having those needs met.
If we wait until we're ready, we'll be waiting for the rest of our lives. Lemony Snicket Whatever we are waiting for -- peace of mind, contentment, grace, the inner awareness of simple abundance -- it will surely come to us, but only when we are ready to receive it with an open and grateful heart.
You know you’ve waited long enough when you’ve spent more than you’re willing to spend. You know you’ve waited long enough when the cost of waiting is greater than what you’re waiting for. It’s like waiting to be seated at a restaurant. Except dating and relationships are much higher stakes.
- Like most other Capybara methods
have_current_pathcan take a
:waitoption, to override the maximum wait for that matcher, so there is no need to increase
default_max_wait_timejust for one long duration redirect.
- Hi thanks all, I will try this first and let you know the result
- I have tried but it will work only when I add a
waitoption in have_current_path matcher