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);
Related
driver.get("MyURL");
System.out.println("URL is opened");
executeAutoItScript(scriptFileLocation);
when i open the URL i get an Authentication Required pop up.
To handle that I am using AutoIt script. But the problem is As soon as the first command
(driver.get("MyURL");)
is executed, Chrome will get open and the
Authentication pop up appears. And i have observed that the second line
System.out.println("URL is opened");
is not being executed. I debugged it and observed that the
control is not given to next line from
driver.get("MyURL");
and it hangs
there. I changed driver.get("MyURL"); to driver.navigate().to("MyURL"); but
there is no luck. Could anyone please help me to resolve this. Attached is
the pop up screenshot.
As per your code trials and the browser snapshot, it seems that the Browser Client (i.e. the Google Chrome Browser) is not returning back the control to the WebDriver instance and subsequently Selenium Java Client can't achieve the state of 'document.readyState' equal to "complete". Hence neither your next line of code:
System.out.println("URL is opened");
is getting executed, nor the AutoIt Script in next line:
executeAutoItScript(scriptFileLocation);
Solution
It is not clear from your question about the source of this Authentication Popup. Perhaps following the discussion Selenium - Basic Authentication via url you can pass the username and password being embedded within the URL as follows:
driver.get("http://admin:admin123#MyURL");
From: http://selenium-python.readthedocs.io/navigating.html
WebDriver will wait until the page has fully loaded (that is, the onload event has fired) before returning control to your test or script. It’s worth noting that if your page uses a lot of AJAX on load then WebDriver may not know when it has completely loaded. If you need to ensure such pages are fully loaded then you can use waits.
So, in this case your webpage is not fully loaded since it requires authentication. Here is what you can do
driver.get("MyURL");
executeAutoItScript(scriptFileLocation);
Thread.sleep(2000);// to wait for autoit script, you can also use other wait explicit wait
//Assert statement
System.out.println("URL is opened");
->First define the page load time for the driver.
->By using try-catch time out exception invoke the url.
->After that use robot class key events or key events class to enter the authentication details
Try the below one if any queries do lemme know:
driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);
try{
driver.navigate().to("yourURL");
}
catch(TimeoutException te){
System.out.println(te);
System.out.println("Line went to Upto that Link");
after this you could proceed with the authentication pop-up code.
Do lemme know if you have any queries.
This helped me:
InternetExplorerOptions options = new InternetExplorerOptions();
options.setCapability("initialBrowserUrl", "about:blank");
options.setPageLoadStrategy(PageLoadStrategy.NONE);
WebDriver driver = new InternetExplorerDriver(options);
driver.manage().deleteAllCookies();
driver.manage().window().maximize();
driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);
driver.get(url);
//execute AutoItScript goes here
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.
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")));
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