How can I stop webdriver execution till my condition satisfy - java

I am doing automation for one application and need little help .
Scenario is in our application when we update/add something we are showing Loading image till it complete process. And in my webdriver it is not able to find next element until this loading image completes.
So I want to set condition like till there is loading image , stop execution and dont try to find next element , once loading image hide then find for next element. so How here I can stop web driver execution till loading image there.
I am trying something like :
WebElement loading = driver.findElement(By.id(AppConstants.loadingimg));
while(loading.isDisplayed()){
//What to put here to stop web driver execution for a while
}
I already tried all type of WAIT but not working for me in proper way so I want solution with above condition.

//What to put here to stop web driver execution for a while
As you said you already tried all type of WAIT and it's not working , So
In order to stop execution for a while you can make your thread to SLEEP
try{
Thread.sleep(timeYouWantToWait); // time in millis
}catch(InterruptedException e){
e.printStackTrace();
}

Related

Why Thread.sleep(200000) is not waiting my script up to that amount of time?)

Myy application is bit slow during that step and I need to wait for all elements to be loaded for 2 minutes so I have given Thread.sleep(200000) but the script is not waiting that long and it is giving me
UnreachableBrowserException and shows Error Connecting with remote browser. It may have died.
I am using Selenium 4 alpha version and ChromeDriver also 4 version. Please help. Demo Code below:
#And("user clicks on Go button and waits for the members to display")
public void user_clicks_on_go_andwaits()
{
memberPage.clickGo();
Thread.sleep(200000);
// after this step a list of element displays and I need to select one in the below step
}
#And("user selects {int} member")
public void select_member(int memberId)
{
memberPage.selectMember(memberId);
//selectMember method is defined in the page object.
}
Dont use thred in selenium automation (That is not good practice) Please use webdriver wait in selenium
Thread sleep force your automation program
create method for wait and use anywhere in your program
**//Following code is method of wait**
private static WebElement waitForElement(By locator,int timeout)
{
WebElement element=new WebDriverWait(driver,timeout).until(ExpectedConditions.presenceOfElementLocated(locator));
return element;
}
//If you want wait for particular element you can use that wait method which you are written in program
**waitForElement(By.id(""),20);**
//Here 20 is in milliseconds and you can use any web element to wait with any locators

How to wait until loading window close or visible false

I have developed selenium automation framework using JAVA and I facing a problem.
When I click on any button say Filter or clear filter application display a loading window and after that, we are able to perform next action.
i have added following code to wait until loading window visible false but its not working.
wait.until(ExpectedConditions.invisibilityOf(webElement));
System.out.println("Wait Untill Loading Window Closed");
existFlag=true;
in web element i passing that loading window XPATH. Every time code not wait for window to be closed start clicking on button and throw exception
unknown error: Element ... is not clickable at point (178, 391). Other element would receive the click:
I also added code for click
wait.until(ExpectedConditions.elementToBeClickable(webElement));
webElement.click();
return true;
Please help how i can wait till loading window close.
You should use implicit wait for this purpose. Add this statement for setting Implicit wait on driver object , after initialising the driver instance.
driver.manage().timeouts().implicitlyWait(Integer.parseInt("30"),TimeUnit.SECONDS);
You can use this :
wait.until(ExpectedConditions.visibilityOfElementLocated(webElement));
webElement.click();
You can write you personal waiter. I guess, you will got a few cases when you will see this scroller. For example you can try use next approach:
public void waitIfScrollerStillVisibe(int seconds, By locator) {
int counter = 0;
while (!isElemenyVisible(locator)) {
if (counter == seconds) {
new throw ElementIsNotVisibleException();
}
else {
Thread.sleep(seconds);
counter++;
}
}
}

How to Deal with ElementNotFound Exception in Selenium WebDriver

Overview : I have already prepared the automation script in Selenium Web driver script in Java which will login into a website and make the selections automatically and once the selections are completed it will run the report.
What I want : I am facing issue while optimizing my automation script.
Brief Explanation : Actually I am familiar with different kinds of wait we are using in Selenium but all those wait i.e implicit,explicit or fluent wait didn't able to help me out in making the code more optimized.Currently I am using Thread.sleep() method everywhere in order to run the script completely without any fail but I know this should not be best practice to be get followed because sometime Elements loads fast and sometime slow because of that either my Script execution took long time or failed based on Element availability.I created one separate method for Webdriver wait and Which I can call for various webelements whenever I needed in my main script but this approach also sometime works or sometime not even though I am passing 800 Second as Time period to wait but if I use Thread.sleep(5000) it will work without any issue not sure why ??
What I want to be have a separate method for wait which can be called in main script whenever required and I want my script to be worked flawless the moment webeelment visible just like what we human do when we interacting with any web.
Note : I have tried ExpectedCondition methods like elementtobeclickable, visibilityOfElementLocated,presenceofElementLocated all of them sometime these work but sometime won't.
Separate Method of wait I have created
public static WebElement waiting(WebDriver driver,String path){
WebDriverWait wait = new WebDriverWait(driver,800);
WebElement element=wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath(path)));
return element;
}
Piece of main code where I am calling this Method.
if(nam.equals("Some name"))
{
WebElement e=driver.findElement(By.xpath("1st Webelement path"));
e.click();
System.out.println("Value clicked under First Drop Down is:"+e);
Listing.waiting(driver,"2nd WebElement xpath").click();
//Thread.sleep(5000);
//driver.findElement(By.xpath("2nd WebElement xpath")).click();
System.out.println("Second Dropdown clicked");
}
When I commenting the Thread.sleep() then it will throw the ElementNotFound exception even though I have used 800 Seconds in Webdriver wait method but the moment I removed the comment from Thread.sleep() method it will work.
Kindly Help me in getting the reusable and useful wait method which I can call several times in my main code.
Thanks in Advance !!
This usually works for me (not FluentWait though):
WebDriverWait wait = new WebDriverWait(driver, TIMEOUT);
ExpectedCondition elementIsDisplayed = new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver arg0) {
try {
webElement.isDisplayed();
return true;
}
catch (NoSuchElementException e ) {
return false;
}
catch (StaleElementReferenceException f) {
return false;
}
}
};
wait.until(elementIsDisplayed);
Of course, setup TIMEOUT with the amount of time you want to wait for the element to be found (that is in seconds).

Selenium stop page load as soon as expected element exist

I created few test cases on Selenium using Java. Unfortunately when I click an element on the page, before I could move on to any other action, I have to wait till the page loads.
I have tried driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);. Unfortunately this creates another problem. Even if the page loads, it waits 30 seconds before it started testing on the page.
What I found the best way is to send ESCAPE key to stop page load.
Is there anyway I could check if an element exists and when it does, send ESCAPE key to the browser to stop page load?
This part is bugging my mind as I have to wait till page loads before Java reads the next line of the code so I can't send ESCAPE key to browser till the page actually stops loading.
Edit
I have just tried using a new thread to do the job but it seems driver is completely locked out, can't do any process on it before page stops loading.
I'm out of ideas for the moment but I believe there should be a way.
Using timeouts() is causing whole test case to stop.
First I'd like to say this isn't a best practice. The selenium click method states that if the click triggers a page load, selenium will do its best to block until the page is loaded. Instead of clicking via the click method you could try sending the click event via JavaScript. Then wait for the element like normal.
You can try driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS); It is supposed to throw an error after timeout is over. I have never used it but maybe you can try and catch this error and continue with your test. But your page could end up in an unstable state with everything not loading and test interacts with elements.
I did it in C#, scenario is the same elsewhere.
Define driver like this:
var firefoxOptions = new FirefoxOptions();
firefoxOptions.PageLoadStrategy = PageLoadStrategy.None;
driver = new FirefoxDriver(firefoxOptions);
PageLoadStrategy.None means when open a URL, continue to next line regardless of the results and do not wait to load the page.
Usually, it takes some seconds to load a page and element appears, suppose I'm waiting for email_user element to appears:
int user_emailID = 0, popupAlert = 0;
do
{
float timeToWait = 0;
driver.Navigate().GoToUrl("https://stackoverflow.com");
do
{
await Task.Delay(500);
timeToWait += 0.5F;
user_emailID = driver.FindElements(By.XPath("//input[#id=\'user_email\']")).Count;
}
while (user_emailID == 0 && timeToWait < 10);
if (user_emailID == 1)
{
//Element exists now!do something and don't wait for page to load completely
}
}
while (user_emailID != 1);
More explanation: when open a URL, first loop check the presence of element every 0.5 second, if it appears, the loop stops. If after 10 seconds it couldn't find the element, the page will reloaded !!
Hope this get you the idea.
Remember, exception must not happen in your codes !!

Webdriver, detect DOM changing and wait for it

I am using Webdriver in Java and I encountered an issue repeatedly that I can't find a proper solution yet.
It is to do with doing actions on a page that will cause this page DOM to change (for example, Javascript lightbox), then my JUnit test is expecting new elements after the DOM change but my test is getting the old DOM element.
To give you an example, I have a scenario as below.
First of all click “Add item” button in the below image and the light box appears:
Then fill in all the item details and click "Add & Close". You will see the screen below:
Notice that now there is an info message Your item ... has been added.
Now I put keywords in the Search text box and hit enter and the info message will be changed to below:
In my JUnit test, the flow is like below:
....
itemDetailsPage.clickAddAndClose();
itemDetailsPage.searchItemBy("Electricity");
assertEquals("Your search for 'electricity' returned 2 results.",
itemDetailsPage.getInfoMsg());
....
Now this test is not very robust, because if the network is slow, most of the times, getInfoMsg() will return the previous info message Your item ... has been added instead of the latest info message, which causes the test to fail. Just a side note that these two info message have share the same html element id.
The solution I am trying to implement here are:
add explicit wait in clickAddAndClose()
So it looks something like:
public void clickAddAndClose() {
...
clickWhenReady(driver, By.id(addAndCloseButtonId));
...
waitForElementByLocator(driver,By.id(itemInfoMsgId),10);
}
The second wait proves to be useless because, itemInfoMsgId already exist when the user added the item from the add item lightbox.
add waitForPageLoaded() method at the end of clickAddAndClose() to try to wait for the page to finish reloading. The generic method for waitForPageLoaded() below:
public void waitForPageLoaded(WebDriver driver) {
ExpectedCondition<Boolean> expectation = new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
return ((JavascriptExecutor) driver).executeScript(
"return document.readyState").equals("complete");
}
};
Wait<WebDriver> wait = new WebDriverWait(driver, 30);
try {
wait.until(expectation);
} catch (Throwable error) {
assertFalse("Timeout waiting for Page Load Request to complete.",
true);
}
}
I am expect at the end of clickAddAndClose(), it will see this page is still being updated so it will wait until the info message has been updated. But this does not seem to work either.
That leaves me to the last choice will is to add a thread sleep at the end of clickAddAndClose(). I want to avoid using it.
Is there a generic way of solving this kind of problem? How do I detect that the page DOM is still changing and tell Webdriver to wait until it finishes refreshing?
Waiting for the page to be loaded won't work if (as it seems to be the case) your page is being modified by AJAX operations.
Instead of waiting for the page to load, wait for the condition you are testing to become true. This way, you give the AJAX operation time to execute and if your there is a problem you will get an error when the time out occurs.
I usually use the Python bindings for Selenium and it has been quite a while since I wrote Java code but I believe it would look something like this, with X being replaced with a type appropriate for the itemDetailsPage object:
new FluentWait<X>(itemDetailsPage)
.until(new Function<X, Boolean>() {
public Boolean apply(X itemDetailsPage) {
return "Your search for 'electricity' returned 2 results." == itemDetailsPage.getInfoMsg();
};
});
Seems like you need to wait until ajax has finished its job. In a similar situation I've used a method similar to waitForJQueryProcessing described here. Take a look, it might help.

Categories