Today in this post, I will show you how to handle Synchronization in Selenium Webdriver. I am 200% sure that you are also not happy with the wait provided by Selenium, which does not serve our purpose.
Selenium has less number of sync method which actually makes your Selenium script unstable and most of the time Selenium scripts fails only for synchronization. Please check official wait classes provided by Selenium for sync issues.
Different type of Wait in Selenium
What is Synchronization in Selenium Webdriver
Every application now days contains some AJAX call which receives the response from the server then it displays on an application.
You must have tried implicit wait, explicit wait and fluent wait in Selenium but as per my experience, it does not full fill my requirement. If you have ever thought of how it works then you must be having one thing in mind it checks the element in DOM and it returns the element or it will throw an exception.
Solution for Synchronization in Selenium Webdriver
Recently I created a small method, which actually does the same thing, and it works like a charm. I used my own created method and I noticed my most of the selenium scripts working fine without fail.
How below method works.
You need to pass three parameter
1- Driver- pass the driver reference, which will find the element.
2- Xpath – pass the xpath of the element, which you want to find of the page.
3- Time- pass the time it will keep polling after each second and if max limit exceeds then it will throw null pointer exception.
Above method will return you the WebElement then you can play with the element like do any operation based on your requirement.
Library to solve Synchronization in Selenium Webdriver
import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; public class Utility { public static WebElement isElementPresnt(WebDriver driver,String xpath,int time) { WebElement ele = null; for(int i=0;i<time;i++) { try{ ele=driver.findElement(By.xpath(xpath)); break; } catch(Exception e) { try { Thread.sleep(1000); } catch (InterruptedException e1) { System.out.println("Waiting for element to appear on DOM"); } } } return ele; } }
Now you can use above method in your test script.
import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxDriver; import org.testng.annotations.Test; import Library.Utility; public class SearchBus { @Test public void checkBuses() { WebDriver driver=new FirefoxDriver(); driver.manage().window().maximize(); driver.get("https://www.redbus.in/"); Utility.isElementPresnt(driver,".//*[@id='txtSource']", 20).sendKeys("Bangalore"); Utility.isElementPresnt(driver,".//*[@id='txtDestination']", 20).sendKeys("Chennai"); } }
Hope you will implement this method in your framework.
Kindly share your feedback on comment section.
Shweta says
Thank you Mukesh for a customised method for thread.sleep. very useful
Harish says
Hi Mukesh,
WebElement isElementPresnt(WebDriver driver,String xpath,int time)
Here TIME is of type “int”, this means driver will attempt “10” times or find element in “10” seconds?
Mukesh Otwani says
Hi Harish,
Here, time is number of max number of times you want to run loop in order to proceed through webelement operation iff any exception erupts while doing driver.findElement
Harish says
Thank you Mukesh for timely response.
Your Selenium blog contents and videos are very helpful. Very happy 🙂
Mukesh Otwani says
Hi Harish,
Happy to read from you…
Neeraj Kumar says
Please explain me about brake. ie how it is working in this code…
Mukesh Otwani says
Hi Neeraj,
Break will immediately stop the for loop.
Preetish Kumar Mahato says
org.openqa.selenium.StaleElementReferenceException: stale element reference: element is not attached to the page document
Mukesh how to solve this?
Mukesh Otwani says
Hi Preetish,
below link will help http://learn-automation.com/how-to-solve-stale-element-reference-exception-in-selenium-webdriver/
santhosh says
Hi Mukesh,
The above function is working fine only by declaring WebDriver as static
is it possible to achieve without using static keyword.
Mukesh Otwani says
Hi Santosh,
If you dont want method as static then you can have to create object of that class and then you have to call.
Ritesh kumar says
Hello sir ,
How to handle the below exception org.openqa.selenium.remote.UnreachableBrowserException i am running a script on grid.
See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Exception in thread “main” org.openqa.selenium.remote.UnreachableBrowserException: Could not start a new session. Possible causes are invalid address of the remote server or browser start-up failure.
Build info: version: ‘2.52.0’, revision: ‘4c2593c’, time: ‘2016-02-11 19:03:33’
System info: host: ‘Ritesh_Testing’, ip: ‘192.168.1.789’, os.name: ‘Windows 7’, os.arch: ‘amd64’, os.version: ‘6.1’, java.version: ‘1.7.0_79’
Driver info: driver.version: RemoteWebDriver
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:665)
at org.openqa.selenium.remote.RemoteWebDriver.startSession(RemoteWebDriver.java:249)
at org.openqa.selenium.remote.RemoteWebDriver.(RemoteWebDriver.java:131)
at org.openqa.selenium.remote.RemoteWebDriver.(RemoteWebDriver.java:158)
at Read_excel.Read.main(Read.java:59)
Caused by: org.apache.http.conn.HttpHostConnectException: Connect to 192.168.122.1:5566 [/192.168.122.1] failed: Connection timed out: connect
at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:151)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:353)
at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:380)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:71)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:55)
at org.openqa.selenium.remote.internal.ApacheHttpClient.fallBackExecute(ApacheHttpClient.java:144)
at org.openqa.selenium.remote.internal.ApacheHttpClient.execute(ApacheHttpClient.java:90)
at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:142)
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:644)
… 4 more
Caused by: java.net.ConnectException: Connection timed out: connect
at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source)
at java.net.AbstractPlainSocketImpl.connect(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at org.apache.http.conn.socket.PlainConnectionSocketFactory.connectSocket(PlainConnectionSocketFactory.java:74)
at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:134)
Mukesh Otwani says
Hi Ritesh,
Kindly check the browser is up and running or not.
Premkumar says
in case if its apart from xpath like id , classname and link text how can i pass that in utuilty class
Mukesh Otwani says
Hi Prem,
Above lib only for XPath you can write for id , name and other locator as well.
Gaurav Lad says
Hi Prem,
You can make a change in ‘isElementPresnt’ in ‘Utility’ and add one more parameter of locator type
Ex.:
public static WebElement isElementPresnt(WebDriver driver, String locator_type, String locator, int time)
After doing this you also need to change code in try-catch
Under ‘for’ loop you need to check which ‘locator_type’ is passed and based on this we will do findElement
Like:
for(int i=0;i<time;i++)
{
if(locator_type=='xpath')
try{
ele=driver.findElement(By.xpath(xpath));
break;
}
else (locator_type=='id')
try{
ele=driver.findElement(By.id(id));
break;
}
And So on…….
And now we will be calling this method with type of the locator we are passing,
Ex.:
Utility.isElementPresnt(driver, xpath, ".//*[@id='txtSource']", 20).sendKeys("Bangalore");
Utility.isElementPresnt(driver, id, "#txtSource", 20).sendKeys("Bangalore");
same can be done for other ways of finding element, for cssSelector, className, LinkText etc.
Mukesh Otwani says
Thanks Gaurav
Ritesh kumar says
will this function can also handle the staleElementRefrenceException???
Mukesh Otwani says
Yes