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_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
Example:
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.
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 wait:
parameter.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With