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(...)
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 tell Selenium to wait until it sees an element - Selenium sees it
I tell Selenium to click on this element, it is a button to link to a new page - Selenium click on it.
The problem is that after clicking it, Selenium will then wait until the next page is fully loaded (the page sometimes loads in a second, or waits for ages, I think it's a problem with Zen Desk Live Chat on that page).
When it is fully loaded it will then throw an error and say that the element it clicked on cannot be seen (naturally it can't because it is now on a new page)
I have tried changing the wait time with
driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
however this doesn't help.
I have also tried
wait.until(ExpectedConditions.visibilityOfElementLocated(
By.xpath(element)));
However this has the same problem.
Below is the code I am currently using.
try {
wait.until(ExpectedConditions.visibilityOfElementLocated(
By.xpath(element)));
WebElement we = driver.findElement(By.xpath(element));
we.click();
System.out.println("Clicked: " + element);
}catch (Exception e){
System.out.println(e.getMessage());
}
I expect that once the element has been clicked on, that Selenium just carries on without caring if the next page has loaded up or not.
However what happens is when the 2nd page loads up, sometimes the page gets stuck "waiting for widget-mediator.zopim.com" and Selenium will not progress past the click() line until the the WebDriverWait time has expired (60 seconds)
After the 60 seconds has expired I see this error in the Console Output:
[1561374309.111][SEVERE]: Timed out receiving message from renderer: 60.000
[1561374309.112][SEVERE]: Timed out receiving message from renderer: -0.002
Is something else happening here? Or does Click() wait until the page has loaded, if that click takes it to a new page? If it does is there a way to tell it to stop waiting? I have other code to check if the page has loaded or not, but I don't need Click() to do this.
Thanks in advance.
Selenium’s (or more correctly, WebDriver’s) behavior on click is governed by the W3C WebDriver Specification. In that document, the full algorithm is defined for what happens when an element click is requested. In general, if the click will navigate to a new page, the driver will wait for that new page to be “loaded” (scare quotes intentional) according to the page load strategy until the page load timeout.
The page load strategy defaults to “normal”, or waiting for the document’s readyState to be complete. If you set it to “none” in the capabilities requested during driver instantiation, the driver will not wait at all. Choosing that route would mean you would need to handle all synchronization for pages being loaded. Note there is a third page load strategy, “eager”, but at the time of this writing, not all WebDriver implementations (most notably chromedriver) support it.
You can adjust the page load timeout at runtime in your Selenium code. One approach might be to lower the timeout to a relatively low value for the duration of clicking on this particular element, then restoring it to its prior value afterward. The drawback here is that you will have to catch the timeout exception that is thrown when the page load times out before continuing.
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
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've got a problem with testing in Java. I'm using TestNG & Selenium. I wanted to run a method with annotaion #Test on long period of time, but it stopped in about 5000 seconds. I've tried to set attribute Timeout, but it didn't work for me. How can I control execution time of test method?
Sometimes I've noticed that my test method before stop after around 5000 seconds threw exception "org.openqa.selenium.remote.SessionNotFoundException: Session ID is null".
Use WebDriver Wait and Wait Until Expected Conditions before Performing Any Action on Any Element, So that testcases Never Fails due to Timing Issues
WebDriverWait wait = new WebDriverWait(driver, 80);// Maximum TimeOut
PageUtil.refreshObject(driver, By.linkText("Link_yu_want_to_click"));
wait.until(ExpectedConditions.elementToBeClickable(By.linkText("Link_yu_want_to_click")));