Why does not Explicit Wait work for autosuggest boxes? - selenium

I tried to use ExplicitWait for an autosuggest box but it did not work, so I am using simple Thread.sleep(5000):
/***************************************************************************************/
// The below Thread.sleep(5000) works fine
// Thread.sleep(5000);
// However the below Explicit Wait block does not recognize the element
WebDriverWait wait5000 = new WebDriverWait(driver, 0);
wait5000.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[#class='auto_suggest']/*[#class='title_item']")));
/***************************************************************************************/
WebElement firstItem = driver.findElement(By.xpath("//*[#class='auto_suggest']/*[#class='title_item']"));
firstItem.click();
System.out.println("Done!");
}
}
I can use Thread.sleep(5000) but this is not efficient, because of time loss. Is there any way to introduce an explicit wait for the autosuggest box? How to click the autosuggest box more in a more efficient way?

The 2nd parameter in the constructor is the timeout in milliseconds.
Here WebDriverWait wait5000 = new WebDriverWait(driver, 0); you are passing in 0 - you are giving it a maximum of 0 milliseconds to find the element. You could try increasing the timeout, for example, let it search for the element for up to 5 whole seconds:
WebDriverWait wait5000 = new WebDriverWait(driver, 5000);

Related

How to applied a default wait time to visible or find or display of webElement in selenium except using Implicit wait or webdriver wait

I want to apply a one specification to my selenium test's code as webdriver have to wait for web element to display or load on a webpage for anytime. It should be applicable for a every web element in the code. Is there any way to get this. Instead of applying implict wait or Webdriver wait when ever it required. I can use this specification so that even though in future any webElement take sometimes to get visible it will wait default till it is visible.
You can create a method which receives By as parameter and returns WebElement, and use it for all the element search instead of driver.findElement()
// Java syntax
public WebElement findElement(By by) {
WebDriverWait wait = new WebDriverWait(driver, 30);
WebElement element = wait.until(ExpectedConditions.visibilityOfElementLocated(by));
return element;
}
You can also put WebDriverWait wait = new WebDriverWait(driver, 30); at class level instead of creating a new instance every time.

Wait for element for certain amount of time

I have been experiencing one issue during test automation implementation. Particularly test checks if a hamburger menu is displayed.
So far I defined the element and subelement, and I need to really wait just one second, and not to waste time If I know that element will not be displayed after several seconds.
WebDriverWait wait = new WebDriverWait(getDriver(), 1);
WebElement hamMenu = el.findElement(By.xpath(HAMBURGER_MENU_GENERAL_XPATH));
How to implement the method findElement in the way it will try to find the element in one sec? I do not wish to stay longer... Thanks
Try this -
WebElement elem = new WebDriverWait(driver, 1).until(ExpectedConditions.visibilityOfElementLocated(By.xpath(HAMBURGER_MENU_GENERAL_XPATH)));
If I summarize your requirement is as follows :
Check if a hamburger menu is displayed only for 1 second : You need WebDriverWait with proper ExpectedConditions
Element may/not not be displayed after several seconds : You need to wrapup your code in a try-catch {} block to be able to proceed further in absence of the hamburger.
Youe effective code can be :
try {
WebElement hamburger = new WebDriverWait(getDriver(), 1).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("HAMBURGER_MENU_GENERAL_XPATH")));
System.out.println("Hamburger is displayed in 1 sec");
//rest of your code
} catch (NoSuchElementException e){
System.out.println("Hamburger wasn't displayed in 1 sec");
//rest of your code
}
I got it. Thanks for all hints. This will wait just only for short time which is intended.
public boolean isHamMenuDisplayed(){
getDriver().manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
if (el.findElements(By.xpath(HAMBURGER_MENU_GENERAL_XPATH)).size() == 0)
return false;
else
return true;}

How to handle not clickable condition

I am using implicitly wait in my script, the problem is in one scenario the element is found but it is not in clickable state, in this case I am not able to use explicitly wait. How can I handle this scenario pls help me.
You can use both Implicit Wait & Explicit Wait in your script,
If you want webDriver to wait until element is clickable use Explicit wait before perform click(); action on that element.
String elementid = ""; //put id of element inside " --- ";
WebElement element = driver.findElement(By.id(elementid));
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(ExpectedConditions.elementToBeClickable(element));
element.click();

wait until function not working

I am clicking one element and I am using wait function to identify the next element. This is the wait function.
wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("some xpath")));
After identifying the element, I carry out other actions but when I click for the 1st element it will lead to next page so by the time page loads the wait function is applying for the current page and giving exception. Is there any solution for this? I tried
Browser.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);
before wait but it's not working. It will only work if I use thread.sleep(1000) before wait but I dont want use thread.sleep().
I'm guessing the problem is with the fact that you are using
ExpectedConditions.presenceOfElementLocated(...)
Presence just means that the element is present in the DOM, not that it's visible, enabled, clickable, etc. I would suggest that you change to wait to match what you want to do with the element you are looking for. If you want to click it, wait for it to be clickable. If you want to get text from it, wait for it to be visible, etc.
Another issue may be that you are intending to wait for an element on page 2 but an element matches that locator on page 1. One solution is to find a unique element on page 2, wait for it to be visible, and then wait for your desired element. That way you ensure that you are on the correct page before waiting for the desired element on page 2.
I think there are 2 waits in this situation:
Wait for next page loaded
Wait for specified element loaded in the new page
Below is an option to wait for page loaded:
public void waitForLoad() {
ExpectedCondition<Boolean> condition = webDriver -> webDriver.getCurrentUrl().contains(getPageUrl());
WebDriverWait wait = new WebDriverWait(driver, pageLoadTimeout);
wait.until(condition);
}
Then wait for next element visible:
protected void waitFor(By by) {
ExpectedCondition<Boolean> condition = webDriver -> !webDriver.findElements(by).isEmpty();
WebDriverWait wait = new WebDriverWait(driver, pageLoadTimeout);
wait.until(condition);
}
or using other solutions:
public WebElement elementToBeClickable(By locator, int timeout) {
try {
return getWebDriverFluentWait(timeout)
.until(ExpectedConditions.elementToBeClickable(locator));
} catch (Exception e) {
return null;
}
}
with:
private Wait<WebDriver> getWebDriverFluentWait(int timeout) {
return new FluentWait<WebDriver>(driver)
.withTimeout(timeout, TimeUnit.SECONDS)
.pollingEvery(1, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class);
}
I think you want to click on element, so use elementToBeClickable
WebDriverWait wait=new WebDriverWait(driver, 30);
wait.until(ExpectedConditions.elementToBeClickable(locator))
I also Have the same Problem
But using this I solved
WebElement element = (new WebDriverWait(driver, 30)).until(ExpectedConditions.elementToBeClickable(By.xpath(".//*[#class='IM_overlay']"))); //it will wait 30 second for get this element
element .click();
//You can Do any operator here
If the element that is to be clicked is in the next(new) page, you'll have to use the windows iterator.
You could use this code:
Set <Strings> ids = driver.getWindowHandles();
Iterator <String> it = ids.iterator();
String currentPage = it.next();
String newPage = it.next();
driver.switchTo().window(newPage);//this will switch to the new window. Use your 'wait' condition now and do all the operations
//now to switch back to the previous(current) window, you could use the below code
driver.switchTo().window(currentPage);

How to select a value from a drop down menu

I want to select the option from the drop-down menu. I tried a number of ways but I failed.
I tried:
WebDriverWait wait = new WebDriverWait (driver, 5);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.linkText("iMacs")));
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.presenceOfElementLocated(By.linkText("iMacs")));
waitForElementToBeDisplayed(driver.findElement(By.linkText("iMacs")), 200);
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//a[text()='iMacs']")));
This is my code:
WebElement element = driver.findElement(By.linkText("Product Category"));
Actions action = new Actions(driver);
action.moveToElement(element).perform();
WebDriverWait wait = new WebDriverWait (driver, 5);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.linkText("iMacs")));
WebElement subElement = driver.findElement(By.linkText("iMacs"));
action.moveToElement(subElement);
action.click();
action.perform();
This is my error:
org.openqa.selenium.TimeoutException: Expected condition failed: waiting for visibility of element located by By.linkText: iMacs (tried for 5 second(s) with 500 MILLISECONDS interval)
So you are hovering over some element and then trying to click on specific link? Which driver are you using? Do you actually see that this menu is correctly rendered after hover?
Your code fails on wait.until(ExpectedConditions.visibilityOfElementLocated(By.linkText("iMacs")));
Try with wait.until(ExpectedConditions.presenceOfElementLocated(By.linkText("iMacs"))); instead and see if it fails then (and what exception it throws in that case).
And why are you using Actions API to perform click?
Please check the sendkeys option also. May be this help in your code.
driver.findElement(By.xpath("code']")).sendKeys("testdata");
I tried executing your code in Chrome and it always worked for me. However, as sometimes, it is failing for you, you can put recovery mechanism in your code, as shown below:
WebElement element = driver.findElement(By.linkText("Product Category"));
Actions action = new Actions(driver);
action.moveToElement(element).perform();
WebDriverWait wait = new WebDriverWait (driver, 5);
try {
wait.until(ExpectedConditions.visibilityOfElementLocated(By.linkText("iMacs")));
} catch (WebDriverException we) {
System.out.println("First attempt to wait for visibility of 'iMacs' failed. Retrying...");
action.moveToElement(driver.findElement(By.linkText("Product Category"))).perform();
wait.until(ExpectedConditions.visibilityOfElementLocated(By.linkText("iMacs")));
}
WebElement subElement = driver.findElement(By.linkText("iMacs"));
action.moveToElement(subElement);
action.click();
action.perform();
Above code should always work. Please let me know, if you have any further queries.