I have set the timeouts in webdriver as follows:
driver.manage().timeouts().pageLoadTimeout(timeoutSeconds, TimeUnit.SECONDS);
driver.manage().timeouts().setScriptTimeout(timeoutSeconds, TimeUnit.SECONDS);
But the webdriver sometimes gets stuck on "transfering data from somewebsite.somedomain.com..." and does not throw a Timeout exception.
Why is that happening and how do I get rid of this situation?
I am using selenium webdriver version 2.45.0
Hi Try if any explicit wait works, ie: Load\navigate to the page, and use explicit wait on any of the UI object on that page.
Like:
WebElement MydynamicElement = (new WebDriverWait(driver, 25))
.until(ExpectedConditions.presenceOfElementLocated("By some locator")));
Related
I am trying to access a website using Selenium WebDriver, but the website will keep loading although I can still interact with it. (The website is nitrotype.com if you are wondering.) I think it is because driver.get() waits until the page is fully loaded. Can I bypass this until just a certain element loads ?
TL;DR
How do I bypass the driver.get() waiting until a site is completely loaded before proceeding?
Look into page load strategy: https://www.selenium.dev/documentation/en/webdriver/page_loading_strategy/
Normal, Eager & None are your options. I suggest you combine your strategy with the proper explicit wait.
NORMAL
normal This will make Selenium WebDriver to wait for the entire page
is loaded. When set to normal, Selenium WebDriver waits until the load
event fire is returned.
By default normal is set to browser if none is provided.
EAGER
eager This will make Selenium WebDriver to wait until the initial HTML
document has been completely loaded and parsed, and discards loading
of stylesheets, images and subframes.
When set to eager, Selenium WebDriver waits until DOMContentLoaded
event fire is returned.
NONE
none When set to none Selenium WebDriver only waits until the initial
page is downloaded.
To implement:
public class pageLoadStrategy {
public static void main(String[] args) {
ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
WebDriver driver = new ChromeDriver(chromeOptions);
try {
// Navigate to Url
driver.get("https://google.com");
} finally {
driver.quit();
}
}
}
Here is my selenium web driver initialization for firefox browser.
driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
driver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);
Even though I gave implicit wait selenium not waiting for the element. It is throwing the not found exception immediately. If I put Thread.sleep then it is working fine without any issues. But putting Thread.sleep everywhere the test case contains now more Thread.sleep than the actual test case code. Can anyone suggest me the right way to do this?
in that case you should use ExplicitWait to wait for an specific element to be visible or present, because it's not a good practice tosleep the thread. I'll recommend to use:
WebDriver driver wait = new WebDriverWait(driver, "time here");
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(xPath)));
I have been trying to automate a browser operation via selenium, the goal is - google.com will be opened, gmail text will be searched and the first link will be clicked and opened. The code used is --
public static void main(String[] args) {
WebDriver driver= new FirefoxDriver();
driver.get("https://www.google.co.in");
driver.manage().window().maximize();
WebElement searchbox= driver.findElement(By.id("lst-ib"));
searchbox.sendKeys("gmail");
driver.findElement(By.name("btnG")).click();
driver.findElement(By.xpath("//ol[#id='rso']//div[1]//div[1]//div//h3//a")).click();
}
but nothing is happening, I am getting an error -
error-Exception in thread "main"
org.openqa.selenium.NoSuchElementException: Unable to locate element:
{"method":"xpath","selector":"//ol[#id='rso']//div[1]//div[1]//div//h3//a"}
where am I doing wrong ?
Following Xpath in your code is in wrong format:
driver.findElement(By.xpath("//ol[#id='rso']//div[1]//div[1]//div//h3//a")).click();
Please use the following Xpath is will work perfectly.
WebDriver driver= new FirefoxDriver();
driver.get("https://www.google.co.in");
driver.manage().window().maximize();
WebElement searchbox= driver.findElement(By.id("lst-ib"));
searchbox.sendKeys("gmail");
driver.findElement(By.name("btnG")).click();
driver.findElement(By.xpath("//ol[#id='rso']/div[1]/div[1]/div/h3/a")).click();
Xpath what I modified is.
driver.findElement(By.xpath("//ol[#id='rso']/div[1]/div[1]/div/h3/a")).click();
i am seeing my dynamic id are been used, it not recommended to use dynamic ids[as it will be keep changing], also use necessary wait conditions to avoid such exceptions
driver.findElement(By.id("lst-ib")); //lst-ib is dynamic value.
i tried to replicate your scenario, no issues observed, please find the coding below,
package testclasses;
import org.openqa.selenium.*;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.interactions.Action;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.*;
import org.testng.annotations.*;
public class classa extends classparent {
#Test
public void methoda() throws InterruptedException {
driver.manage().window().maximize();
driver.get("https://www.google.co.in/");
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//a[contains(text(),'Gmail')]")));
WebElement close = driver.findElement(By.xpath("//a[contains(text(),'Gmail')]"));
if(close.isDisplayed()){
System.out.println("element is visible " +close);
close.click();
}
else{
System.out.println("element is not visible " +close);
}
}
}
console output,
TestNG] Running:
C:\Users\Mohan Raj S\AppData\Local\Temp\testng-eclipse-1635948262\testng-customsuite.xml
element is visible [[FirefoxDriver: firefox on WINDOWS (6d5bc9d3-cdff-4831-991a-69d7d7ce3d36)] -> xpath: //a[contains(text(),'Gmail')]]
PASSED: methoda
===============================================
Default test
Tests run: 1, Failures: 0, Skips: 0
===============================================
===============================================
Default suite
Total tests run: 1, Failures: 0, Skips: 0
===============================================
You are getting error because you are trying to click the first link (gmail) even before its loaded. Update your code to implement a wait until the element loads after you search for something and click on the search button. There are many types of wait available in Selenium, use explicit waits to wait between two actions and it's my most preferable method. Here's how -
driver.findElement(By.name("btnG")).click();
(new WebDriverWait(driver, 10)).until(ExpectedConditions.presenceOfElementLocated(By.xpath("//ol[#id='rso']//div[1]//div[1]//div//h3//a"))).click(); //explicitly wait for the element to load and then click
More about Explicit Waits
Another better way to handle this is to wait for the element to appear and keep polling the page if the element showed up using Fluent waits. Here's how -
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(30, TimeUnit.SECONDS)
.pollingEvery(5, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class); //create a fluent wait object
wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//ol[#id='rso']//div[1]//div[1]//div//h3//a"))).click(); //fluent wait until element loads
More about Fluent Waits
You can also use an implicit wait time. which waits for a predefined time after each and every action that selenium performs. But it's again a non preferable one as it can throw errors at times when performance of the webpage is slow. Here's how -
WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); //implicitly wait until element loads for predefined time
driver.get("https://www.google.co.in");
More about Implicit Waits
However, the easiest one that solves your issue is to use a simple sleep() method, which i don't prefer is using the sleep() method. I don't prefer it is because it can throw errors at times when elements take longer time to load, because selenium waits for a predefined time that you specify, which is a bad standard of coding. Here's how -
driver.findElement(By.name("btnG")).click();
Thread.sleep(5000); //Use sleep() method to wait for a predefined time
driver.findElement(By.xpath("//ol[#id='rso']//div[1]//div[1]//div//h3//a")).click();
Hope it helps.
The get(url) method waits for the web page to be fully loaded. If the page has a lot of stuff on it, loading can be very slow.
Is there a way to navigate to the target web page and wait only for the WebElement of interest? (i.e. not the banners, ads, etc.)
Thanks!
You can use Page load timeout. As far as I know, this is definitely supported by FirefoxDriver and InternetExplorerDriver, though I'm not sure about other drivers.
driver.manage().timeouts().pageLoadTimeout(0, TimeUnit.MILLISECONDS);
try {
driver.get("http://google.com");
} catch (TimeoutException ignored) {
// expected, ok
}
Or you can do a nonblocking page load with JavaScript:
private JavascriptExecutor js;
// I like to do this right after driver is instantiated
if (driver instanceof JavascriptExecutor) {
js = (JavascriptExecutor)driver;
}
// later, in the test, instead of driver.get("http://google.com");
js.executeScript("window.location.href = 'http://google.com'");
Both these examples load Google, but they return the control over the driver instance back to you immediatelly instead of waiting for the whole page to load. You can then simply wait for the one element you're looking for.
In case you didn't want this functionality just on the WebDriver#get(), but on you wanted a nonblocking click(), too, you can do one of these:
Use the page load timeout as shown above.
Use The Advanced User Interactions API (JavaDocs)
WebElement element = driver.findElement(By.whatever("anything"));
new Actions(driver).click(element).perform();
Use JavaScript again:
WebElement element = driver.findElement(By.whatever("anything"));
js.executeScript("arguments[0].click()", element);
Following url may help you.
Temporarily bypassing implicit waits with WebDriver
https://code.google.com/p/selenium/issues/detail?id=4993
I'm creating an API based on Selenium API for our system that is controlled through the web-browser (similar to the way you control routers and switches).
One of the things that happens in this API is checking whether certain elements exist on the page (depending on the setting, they may or may not exit, for example, text box or some status).
I have this line:
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
I had it working just fine until when at one point in time, I ran it, and the driver.findElement(By....); has never timed out (the element was missing from the web-page)... The longest I have waited was somewhere about half-an hour.
I'm running Ubuntu 12.04 x64 as my host, Windows 7 as my guest, and on it I have my Selenium API and the code written in Java that controls out product. When I port the same code to another Windows VM or even to a different work station, it works fine. Not on my particular VM though.
Tried "reinstalling" eclipse, reimported Selenium JARs, pulled the latest working code from the server... Nothing works...
What are your thoughts, fellas?
Will appreciate any response. Thanks.
first of all try using fluentWait to wait for all the AJAX on the page:
public WebElement fluentWait(final By locator){
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(30, TimeUnit.SECONDS)
.pollingEvery(5, TimeUnit.SECONDS)
.ignoring(org.openqa.selenium.NoSuchElementException.class);
WebElement foo = wait.until(
new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return driver.findElement(locator);
}
}
);
return foo; } ;
fluentWait(By.xpath(....blablabla..)).click();
//fluentWait(By.xpath(....blablabla..)).getText();
Secondly, try using Thead.sleep(1000); as alternative to
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);