Reputation: 14026
On my web page, page loads but sub-tabs of page aren't clickable for 20 seconds (sometimes more than this). Page contents are -
<nav id="subTabHeaders">
<div class="selected" data-name="ab">AB</div>
<div class="" data-name="cd">CD</div>
<div class="" data-name="ef">EF</div>
<div class="" data-name="gh">GH</div>
</nav>
I've to click on sub-tab, hence I tried this in following way - Put sleep & then element.click But sleep is not ideal way to deal because sometimes it may happen that sub-tab element is clickable before or after the time given to sleep.
Using sleep, I did following -
element = WAIT.until { driver.find_element(:xpath, ".//*[@id='subTabHeaders']/div[3]")}
sleep 20
element.click
If element is clickable after more than the sleep time & we click on element immediate after sleep time expires, (I mean (using above code) suppose element becomes clickable after 30 seconds but we click on element immediate after 20 seconds), actual click action doesn't happen & also click doesn't return any error.
Is there Ruby method to check whether element is clickable or not? So that we'll get to know when to click.
Upvotes: 4
Views: 16210
Reputation: 3901
Here is what I use - to test if the link is clickable, else go to another URL:
if (logOutLink.Exists() && ExpectedConditions.ElementToBeClickable(logOutLink).Equals(true))
{
logOutLink.Click();
}
else
{
Browser.Goto("/");
}
Upvotes: 0
Reputation: 3256
From the ruby bindings page: (see driver examples)
# wait for a specific element to show up
wait = Selenium::WebDriver::Wait.new(:timeout => 10) # seconds
wait.until { driver.find_element(:id => "foo") }
So ordinarily you could do something like:
wait = Selenium::WebDriver::Wait.new(:timeout => 40)
wait.until do
element = driver.find_element(:xpath, ".//*[@id='subTabHeaders']/div[3]")
element.click
end
Or more succinctly
wait = Selenium::WebDriver::Wait.new(:timeout => 40)
wait.until { driver.find_element(:xpath, ".//*[@id='subTabHeaders']/div[3]").click }
However, since you say that the click doesn't raise an error, it sounds like the click is in fact working, just your page isn't really ready to display that tab. I'm guessing there's some async javascript going on here.
So what you can try is inside the wait block, check that the click caused the desired change. I'm guessing, but you could try something like:
wait = Selenium::WebDriver::Wait.new(:timeout => 40)
wait.until do
driver.find_element(:xpath, ".//*[@id='subTabHeaders']/div[3]").click
driver.find_element(:xpath, ".//*[@id='subTabHeaders']/div[3][@class='selected']")
end
The important thing here is that #until will wait and repeat until the block gets a true result or the timeout is exceeded.
Upvotes: 4
Reputation: 96454
How about
WebDriverWait wait = new WebDriverWait(driver,30);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id(subTabHeaders)));
Upvotes: 1
Reputation: 118261
Hope it would help you:
begin
element = WAIT.until { driver.find_element(:xpath, ".//*[@id='subTabHeaders']/div[3]")}
sleep 20
element.click
rescue Selenium::WebDriver::Error::StaleElementReferenceError
p "Indicates that a reference to an element is now “stale” - the element no longer appears in the DOM of the page."
end
OR
you could try this one:
begin
wait = Selenium::WebDriver::Wait.new(:timeout => 10) # seconds
wait.until { driver.title.include? "page title" }
driver.find_element(:xpath, ".//*[@id='subTabHeaders']/div[3]")}.click
rescue Selenium::WebDriver::Error::StaleElementReferenceError
p "element is not present"
end
Upvotes: 0