Selenium-Webdriver Ruby --> How to Wait for Images to Be Fully Loaded After Click

How to wait for next page being loaded with Capybara and Selenium?

Unfortunately, you don't want to wait for page reload. Since, for instance, now post appears after page reload. In a while it might appear without full page reload. If you do, explain your circumstances, please.

I say unfortunately since if we ignore what was said above, if we really need to wait for page reload for some reason, the idea from the old answer is better than any other I've seen in the internets.

So, what you care is that post has appeared on the page. Which brings us to the following code:

test 'create post' do
visit url
fill_in the_form
click_on 'Create'
assert_selector '.post'
post = Post.first
img = page.find '.post .image'
assert_equal post.file.thumb.url, URI(img[:src]).path
end

old answer

Inspired by these great article, link and comment. According to one of capybara's authors, this is the only legitimate use case for wait_until he's heard of in Capybara. Asserting on model objects, that is.

def wait_until
Timeout.timeout(Capybara.default_max_wait_time) do
sleep(0.1) until value = yield
value
end
end


def wait_for_page_reload
id = find('html').native.ref
yield
wait_until { find('html').native.ref != id }
end

test 'create post' do
visit url
fill_in the_form
wait_for_page_load do
click_on 'Create'
end
post = Post.first
img = page.find '.post .image'
assert_equal post.file.thumb.url, URI(img[:src]).path
end

This is a bit hacky. But it works. It waits until html element's internal id changes.

Wait for an image to load using Capybara SitePrism

img elements have a complete property that indicates whether the image is loaded or not. Therefore something along the lines of

start = Time.now
while true
break if find('img.some_class')['complete']
if Time.now > start + 5.seconds
fail "Image still not loaded"
end
sleep 0.1
end

would wait up to 5 seconds for the image to finish loading, assuming the img element is already on the page.

This could also be implemented as a custom selector with something along the lines of

Capybara.add_selector(:loaded_image) do
css { |locator_class| "img.#{locator_class}" }
filter(:loaded, default: true, boolean: true) { |node, value| not(value ^ node['complete']) }
end

which could then be called as

find(:loaded_image, 'some_class')

*** Note: I haven't actually tried the custom selector code, but it should be close enough to provide guidance

Wait until page is loaded with Selenium WebDriver for Python

The webdriver will wait for a page to load by default via .get() method.

As you may be looking for some specific element as @user227215 said, you should use WebDriverWait to wait for an element located in your page:

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException

browser = webdriver.Firefox()
browser.get("url")
delay = 3 # seconds
try:
myElem = WebDriverWait(browser, delay).until(EC.presence_of_element_located((By.ID, 'IdOfMyElement')))
print "Page is ready!"
except TimeoutException:
print "Loading took too much time!"

I have used it for checking alerts. You can use any other type methods to find the locator.

EDIT 1:

I should mention that the webdriver will wait for a page to load by default. It does not wait for loading inside frames or for ajax requests. It means when you use .get('url'), your browser will wait until the page is completely loaded and then go to the next command in the code. But when you are posting an ajax request, webdriver does not wait and it's your responsibility to wait an appropriate amount of time for the page or a part of page to load; so there is a module named expected_conditions.

selenium-webdriver and wait for page to load

This is how the Selenium docs () suggest:

require 'rubygems'
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :firefox
driver.get "http://google.com"

element = driver.find_element :name => "q"
element.send_keys "Cheese!"
element.submit

puts "Page title is #{driver.title}"

wait = Selenium::WebDriver::Wait.new(:timeout => 10)
wait.until { driver.title.downcase.start_with? "cheese!" }

puts "Page title is #{driver.title}"
driver.quit

If that is not an option you can try the suggestion from this SO post though it would require some Javascript on top of the Ruby/Rails.

It seems that wait.until is being/has been phased out. The new suggested process it to look for the page to have an element you know will be there:

expect(page).to have_selector '#main_div_id'

Selenium wait until document is ready

Try this code:

  driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);

The above code will wait up to 10 seconds for page loading. If the page loading exceeds the time it will throw the TimeoutException. You catch the exception and do your needs. I am not sure whether it quits the page loading after the exception thrown. i didn't try this code yet. Want to just try it.

This is an implicit wait. If you set this once it will have the scope until the Web Driver instance destroy.

See the documentation for WebDriver.Timeouts for more info.



Related Topics



Leave a reply



Submit