I am automating an application were , Explicit wait is not working .
My requirement is to wait for a particular element until it is loaded/ visible or clickable to perform next action.
I tried all the expectedconditions in explicit but it failed. only sleep is working.
One thing that i have noticed is that , web browser is not load but page is loading and hence the explicit functionality doesnt work.
Could some one help me in this?
Please find the attached
Due to the fact that your question is rather general I can only provide a general answer at this point. You could wait until your page as a whole has been loaded before you proceed with the testing. (I would suggest this as you claim to have issues where the browser does not seem to be completely ready when you proceed with your testing)
This can be done using the following code:
IWait<IWebDriver> wait = new OpenQA.Selenium.Support.UI.WebDriverWait(driver, TimeSpan.FromSeconds(30.00));
wait.Until(driver1 => ((IJavaScriptExecutor)driver).ExecuteScript("return document.readyState").Equals("complete"))
*This code is not mine it has been sourced from
Wait for page load in Selenium
Explicit Wait i.e. WebDriverWait is proven & efficient and it is working just perfect in conjunction with ExpectedConditions.
As your requirement is to wait for a particular element until it is loaded/ visible or clickable to perform next action you can use the below block of code :
WebDriver driver = new FirefoxDriver();
driver.get("http://somedomain/url_that_delays_loading");
WebElement myDynamicElement = (new WebDriverWait(driver, 10)).until(ExpectedConditions.elementToBeClickable(By.id("myDynamicElement")));
myDynamicElement.click();
This type of issues occurs when the web element takes little more time to load than usual time. In this case, we have use polling mechanism in the given interval which is fluentWait. Below is the helpful code.
public WebElement fluentWait(final By locator) {
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(10, TimeUnit.SECONDS)
.pollingEvery(1, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class);
WebElement foo = wait.until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver _driver) {
return driver.findElement(locator);
}
});
return foo;
};
There is three type of wait in selenium.
implicit Wait
Explicit Wait
Fluent Wait
Implicit Wait
driver.manage().timeouts().implicitlyWait(TimeOut, TimeUnit.SECONDS);
Explicit wait
WebDriverWait wait = new WebDriverWait(WebDriver,TimeOut);
Fluent Wait
Wait wait = new FluentWait(WebDriver reference).withTimeout(timeout, SECONDS).pollingEvery(timeout, SECONDS).ignoring(Exception.class);
Fore more information how to use all wait with example please go to below URL.
https://trickyautomationworld.blogspot.in/2018/02/implicit-wait-vs-explicit-wait-vs.html
Related
I have a selenium code below which wait for the page to load before the action(click button) is performed. How do I do the same thing with HtmlUnit not HtmlUnitDriver.
driver = new ChromeDriver();
WebDriverWait wait = new WebDriverWait(driver,30);
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//button[text()='couple']"))).click();
I know there is this line of code below in HtmlUnit:
webClient.waitForBackgroundJavaScript();
But does it do the same thing?
No this is not the same.
ExpectedConditions.elementToBeClickable waits until the element is there/visible and enabled.
webClient.waitForBackgroundJavaScript(timeoutMillis) looks only for (async) JavaScript jobs and waits if there are still any that are currently running or waiting in the queue.
I'm automating this website But facing the issue with ExplicitWaitConditions to manage the time.
Scenario is When i click on Login link or Submit button after send username, It shows a loader during the process, once process has completed the loader get removed from DOM.
I have used condition for invisibilityOfElementLocated like below
new WebDriverWait(driver, 60).until(ExpectedConditions.invisibilityOfElementLocated(By.id("loading-bar")));
But this can't predict correct time it taking more time (not exectly 60 sec but around 15-20 or may be 30 sec.) then allow to execute next command.
The same line i have to put before 4 commands to do complete login process. So it seems to consumed around 90 second to do login.
If i do not use Explicitwait or remove Impliciwait wait then script failed all time as loader get click instead of some other element.
The code i tried so far :
WebDriver driver = new FirefoxDriver();
System.out.println("Browser Opened");
driver.manage().window().maximize();
driver.get("https://www.rcontacts.in");
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
System.out.println("URL Opened");
new WebDriverWait(driver, 60).until(ExpectedConditions.invisibilityOfElementLocated(By.id("loading-bar")));
driver.findElement(By.cssSelector(".ng-scope>a span[translate='login.register']")).click();
System.out.println("Register Link Clicked");
driver.findElement(By.name("userId")).sendKeys("9422307801");
new WebDriverWait(driver, 60).until(ExpectedConditions.invisibilityOfElementLocated(By.id("loading-bar")));
driver.findElement(By.xpath("//button[#type='submit']")).click();
System.out.println("Mobile number entered");
new WebDriverWait(driver, 60).until(ExpectedConditions.invisibilityOfElementLocated(By.id("loading-bar")));
Is there any solution that as soon as loader get removed it start performing actions ?
OR is there any way that I can wait until loader element get removed from DOM. Once removed then i can continue the further actions ?.
According to the docs,
WARNING: Do not mix implicit and explicit waits. Doing so can cause unpredictable wait times.
That's likely the cause of your issues. It's recommended to not use implicit waits. I would remove them and then add explicit waits as needed and see how that goes.
I took your code and rewrote it (below) and it's working every time for me.
String url = "https://www.rcontacts.in";
driver.navigate().to(url);
waitForLoader();
driver.findElement(By.cssSelector("span[translate='login.register']")).click();
waitForLoader();
driver.findElement(By.cssSelector("input[name='userId']")).sendKeys("9422307801");
driver.findElement(By.cssSelector("button[translate='common.btns.next']")).click();
The issue I was having at times was that many times the script was jumping ahead. I added code to waitForLoader() to wait for the loader to appear (be visible) and then disappear (be invisible). Once I did that, it worked 100% of the time.
public static void waitForLoader()
{
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.id("loading-bar")));
wait.until(ExpectedConditions.invisibilityOfElementLocated(By.id("loading-bar")));
}
First and foremost, you have induced implicitlyWait() as follows:
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
As well as WebDriverWait() as follows:
new WebDriverWait(driver, 60).until(ExpectedConditions.invisibilityOfElementLocated(By.id("loading-bar")));
As per the documentation of Explicit and Implicit Waits it is clearly mentioned that:
Do not mix implicit and explicit waits. Doing so can cause unpredictable wait times. For example setting an implicit wait of 10 seconds and an explicit wait of 15 seconds, could cause a timeout to occur after 20 seconds.
Again, it seems changing the ExpectedConditions clause from invisibilityOfElementLocated(By.id("loading-bar") to elementToBeClickable(By.xpath("//span[contains(text(),'Register')]") gives me a success rate of 80%. Here is the effective code block on my Windows 8 box:
System.setProperty("webdriver.gecko.driver", "C:\\Utility\\BrowserDrivers\\geckodriver.exe");
WebDriver driver = new FirefoxDriver();
driver.get("https://www.rcontacts.in");
System.out.println("URL Opened");
WebDriverWait wait = new WebDriverWait (driver, 15);
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//span[contains(text(),'Register')]")));
driver.findElement(By.xpath("//span[contains(text(),'Register')]")).click();
System.out.println("Register Link clicked");
Note: Always invoke driver.quit() within tearDown(){} method to close & destroy the WebDriver and Web Client instances gracefully to ensure that no dangling instance of geckodriver is present (through Task Manager) while you initiate the execution.
I'm trying to set a page refresh time out for my selenium test.
What I am trying to do is:
If selenium can not findElement on the page in a number seconds the findElement action will be stop and the page will be refresh.
So I try to use multi-threading in Java to perform this:
one thread is use to count the time out.
and other thread (main thread) will use to execute the action.
The problem is: I can not interrupt the findElement action thread.
These are the list of thread I'm seeing when try to execute my test:
Thread: Attach Listener
Thread: Finalize
Thread: Signal Dispatcher
Thread: Refresh TimeOut Thread
Thread: Thread-6
Thread: Forwarding findElements on session f7fea321-0acd-4df3-904d-52e32decb965 to remote
Thread: Thread-7
Thread: Thread-5
The Thread: main actually change to Thread: Forwarding findElements on session f7fea321-0acd-4df3-904d-52e32decb965 to remote. I will call this thread "findElement thread" for clarification in this question.
When I try to interrupt "findElement thread" the findElement action is still running without any interruption. I have try interrupt another thread (Thread: Thread-5) but it will remove the connection with current web-driver and test will be failed. I don't know if i did anything wrong is that the right thread to be interrupted ?
Thanks for reading this.
Any suggestion would be very much appreciate.
After investigate i found out that this is not possible:
when we use java to call web-driver to perform an selenium action that action will transfer to web-driver to perform and at this point we will not be able to manipulate this action any more let alone the thread that it use to perform this action, because from this point on web-driver control the execution not Java.
A different way to achieve your goal is to simply use the FluentWait API of Selenium and initiate a page refresh every time it polls to find the requested element:
Wait<WebDriver> wait = new FluentWait<>(driver)
.withTimeout(30, TimeUnit.SECONDS)
.pollingEvery(5, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class);
WebElement foo = wait.until(new Function<WebDriver, WebElement>() {
#Override
public WebElement apply(WebDriver driver) {
driver.navigate().refresh();
return driver.findElement(...));
}
});
If you have dynamically loaded elements on the page you should probably also wait for the page to be loaded before calling driver.findElement(...)
I am using Appium to automate an iOS app but met a problem, is there anyone meet the same problem before?
Appium's implicitlyWait API seems to not work. I am using Java and JUnit to run the test, here is the line of code:
driver.manage().timeouts().implicitlyWait(50, TimeUnit.SECONDS);
I have checked the debug info in the appium console, it looks correctly:
info: [debug] Set iOS implicit wait to 50000ms
My Environment:
Latest Appium 1.2.1, Java client library 1.6.1, Selenium Java language binding 2.42.2 and sample app 'UICatalog'provided by Sauce Lab.
Thanks in advance for the reply.
The code you have posted manages the timeout to wait for a maximum of 50 seconds. It doesn't make the driver wait 50 seconds. You can use the wait like:
driver.wait(); //this will wait a max of 50 seconds cuz you said so
If you ask me the proper way you would want to use waiting on Webdriver is:
WebDriverWait wait;
wait = new WebDriverWait(driver, 60);
wait.until(ExpectedConditions.elementToBeClickable(By.id("blabla"));
The code above checks if blabla is clickable until that condition is proved or 60 seconds(stated above) passes the driver waits.
In Appium it is possible to set implicit way in this way:
Java code:
AppiumFieldDecorator decorator = new AppiumFieldDecorator(driver);
decorator.resetImplicitlyWaitTimeOut(50, TimeUnit.SECONDS);
PageFactory.initElements(decorator, this /* refers to current page object class*/);
Such timeout will work for the whole time.
It is not possible (at least I don't know) to change it.
As when web drivers are used you can do this with:
driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS);
// some actions for which you don't want to wait implicitly
driver.manage().timeouts().implicitlyWait(50, TimeUnit.SECONDS);
Try this:
public static void WaitForElementPresent1(String locator, int timeout)
{
WebDriverWait wait = new WebDriverWait(driver, timeout);
try{
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(locator)));
} catch (Exception e){
e.printStackTrace();
}
}
If you are using PageFactory model, you can specify the implicit wait with initElements() method as given below -
PageFactory.initElements(new AppiumFieldDecorator(driver, 10, TimeUnit.SECONDS), this);
I have tried this with Appium 1.6 and it works fine.
The new way of setting the implicit time out is using the code
AppiumFieldDecorator decorator = new AppiumFieldDecorator(mobDriver);
decorator.DEFAULT_IMPLICITLY_WAIT_TIMEOUT = longValue;
decorator.DEFAULT_TIMEUNIT = TimeUnit.TimeUnit ;
Hope this helps
So I know how to use Selenium, and I want to create a chat bot. However, I do not have access to the source code, and the chat is a custom written page.
This page is making GET requests, and then the site is returning the content I want.
I would like to use Selenium to run javascript (which I know how to do), which either waits for the next GET to come back, or returns whatever the latest GET returned.
At that point I can parse out what I don't need.
I have tried looking for a javascript function to do such, but all I can do is find function that listens to the requests, not the responses.
Thanks!
Note: I will remain active on this page for the next while, so if you need code or such, be sure to ask!
how about using fluentWait() mechanism to wait for all ajax:
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...));
//fluentWait(By.cssSelector(...blablabla...));
and then able to make js injection like:
public void jsCodeExecution(String jsCode){
JavascriptExecutor js = (JavascriptExecutor)driver;
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(jsCode);
js.executeScript(stringBuilder.toString());
}
or using jsInjection at once. How does JavaScript handle AJAX responses