Selenium ignore if element not present - selenium

I have the below code for my selenium, where I need to click on carousel icons and get all the images one by one, but sometimes that carousel doesn't have more than one image and thus arrow icon is not present and clickable.
new WebDriverWait(driver, 40).until(ExpectedConditions.elementToBeClickable(By.cssSelector(".arrow-icon "))).click();
How can I handle the exception where the element is not clickable ??

Two ways to fix it
Use findElements that would return a list of web element if found otherwise size of list will be 0
try {
if (driver.findElements(By.cssSelector(".arrow-icon ")).size() > 0 ) {
System.out.println("Size is > 0 so there must be at least one web element, do some interaction below like click etc");
new WebDriverWait(driver, 40).until(ExpectedConditions.elementToBeClickable(By.cssSelector(".arrow-icon "))).click();
}
else {
System.out.println("Size is 0, so web element must not be present, do something here that would make it available");
}
}
catch (Exception e) {
// TODO: handle exception
}
Use risky code inside directly try
try {
new WebDriverWait(driver, 40).until(ExpectedConditions.elementToBeClickable(By.cssSelector(".arrow-icon "))).click();
}
catch (Exception e) {
// TODO: handle exception
}

Related

I am trying to automate Flipkart where while trying to click on submenu of the header menu it is getting detaching from the DOM, how to handle this?

The submenus are getting appeared in the DOM only when we hover over the main menu.
So after hovering over main menu using Actions class the submenus are coming, but then again when I am trying to get into the submenu it is getting detached from the DOM.
Please help me on this.
public void goToMenTopWearSectionFromFashion() throws InterruptedException
{
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
Actions act=new Actions(driver);
try {
act.moveToElement(FashionHeaderLink).perform();
}
catch(Exception e)
{
act.moveToElement(driver.findElement(By.xpath("//div[#class='_1psGvi SLyWEo']//div[text()='Fashion']"))).perform();
}
try {
if(driver.findElement(By.xpath("//*[#class='_3XS_gI _7qr1OC']//a[1]")).isDisplayed())
{
System.out.println(driver.findElement(By.xpath("//*[#class='_3XS_gI _7qr1OC']//a[1]")).isDisplayed());
driver.findElement(By.xpath("//*[#class='_3XS_gI _7qr1OC']//a[1]")).click();
}
}catch(Exception e) {e.printStackTrace();}
}
After the hover, trying to move to click on Men's Top Wear was sometimes causing it to disappear along the way. I experienced the same by hand if I moved diagonally rather than straight down. Instead,in your 2nd try block you can do the following:
if(driver.findElement(By.linkText("Men's Top Wear")).isDisplayed())
{
String urlSave = driver.findElement(By.linkText("Men's Top Wear")).getAttribute("href");
driver.get(urlSave);
}
Probably it would work with your locator, too.

Unable to click on 16th element from sub menu list

Because its lying beneath the page and when we scroll down, then we can see the elements, how to handle this kind of scenarios?
You can use the following method. It will scroll down untill it reaches the given element.
public static void scrollToReachAnElement(String xpath){
try {
WebElement element = d.findElement(By.xpath(xpath));
((JavascriptExecutor) d).executeScript("arguments[0].scrollIntoView(true);", element);
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
You can use following function of your Selenium driver for scrolling into view
executeScript(JavaScript code here to scroll down)
JavaScript code can be
"arguments[0].scrollIntoView()", your16thWebElement
Or
"window.scrollTo(0, document.body.scrollHeight);"
or any other JavaScript code to scroll down

stale element exception : click on report link in page then back button and so on

AS shown in the image : i want to click on each link one by one , on clicking :window does not gets change but it refresh.
clicking in the report link navigate to the next page, where clicking on back link it navigates back to the same page.
once it take back to the same page , locator no longer identify the next report link & throws stale element exception
public void getreports(String reportname) throws Exception
List<WebElement> li=driver.findElements(By.xpath(".//tbody/tr/th/following::
tr/td//div/a"));
for(WebElement e: li) {
if(reportname.equalsIgnoreCase(e.getText())) {
utilities.wait_control(e);
e.click();
break;
}
else if(reportname.equalsIgnoreCase("all"))
{
utilities.wait_control(e);
e.click();
NetReports ld = PageFactory.initElements(driver, NetReports .class);
ld.Netsubcategoryreport_backbutton.click();
Thread.sleep(2000);
} }
I think you just need a small adjustment to your loop:
String selector = ".//tbody/tr/th/following::tr/td//div/a";
List<WebElement> li=driver.findElements(By.xpath(selector));
for (int i = 0; i < li.length; i++) {
li=driver.findElements(By.xpath(selector));
WebElement e = li.get(i);
//Rest of your logic goes here
}
StaleElementReferenceException -
As the name suggests this exception occurs when the element stale, which means the element reference on which you are trying to take a action upon is no longer available on the page or has changed. 
To avoid this exception, try to find the element as and when you need to
take an action upon it rather than getting the element at some point of code
and then reusing it at different places.

Selenium : Handle a window that popups up randomly

We have a feature that collects customer feedback. For this , when the user logs out , a window pops up up randomly - not every time for every customer.
I want to handle this in my automation code.
Currently, at the log out, I'm expecting a window and switching to it and that code is failing when the popup window doesn't show up.
What's the best way to handle this .
This is what I have so far ...
public static void waitForNumberOfWindowsToEqual(final int numberOfWindows) {
ExpectedCondition<Boolean> expectation = new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
return (driver.getWindowHandles().size() == numberOfWindows);
}
};
WebDriverWait wait = new WebDriverWait(driver, BrowserFactory.explicitWait);
wait.until(expectation);
}
I would handle the absence of popup window with a try/catch. Here is an example:
try {
WebDriverWait winwait = new WebDriverWait(driver, 3);
String mainWindow = driver.getWindowHandle();
// wait for 2 windows and get the handles
Set<String> handles = winwait.until((WebDriver drv) -> {
Set<String> items = drv.getWindowHandles();
return items.size() == 2 ? items : null;
});
// set the context on the last opened window
handles.remove(mainWindow);
driver.switchTo().window(handles.iterator().next());
// close the window
driver.close();
// set the context back to the main window
driver.switchTo().window(mainWindow);
} catch (TimeoutException ex) {
System.out.println("No window present within 3 seconds");
}
If possible, the ideal thing to do would be to have a look through the source to work out whether the popup window will appear, however if this isn't achievable you could take the following approach:
// Get the number of windows open before clicking the log out button.
int numberOfWindowsBeforeLogOut = driver.getWindowHandles().size();
// Click the log out button.
logOutButton.click();
// Check how many windows are open after clicking the log out button.
int numberOfWindowsAfterLogOut = driver.getWindowHandles().size();
// Now compare the number of windows before and after clicking the log out
// button in a condition statement.
if (numberOfWindowsBeforeLogOut < numberOfWindowsAfterLogOut) {
// If there is a new window available, switch to it.
driver.switchTo().window(titleOrWindowHandle);
}
In case you don't get the required window, the code will throw a TimeoutException. So, put wait.until(expectation) inside a try block and catch the exception. In code,
try {
wait.until(expectation);
} catch (TimeoutException ex) {
System.out.println("Nowindow This Time");
}

Selenium Webdriver cannot click on modal dialog when the window is not in focus

I have 2 browsers open and Selenium Webdriver can switch between these two. One window is in foreground and other is in background. And in the workflow, a modal dialog opens up in the background window and thus webdriver cannot perform any actions on it. Is there any possible solution apart from getting the background window into foreground?
I am using C#.
Loop through your window handles and check for you modal dialog to appear.
string current_window = driver.CurrentWindowHandle;
foreach (string window in driver.WindowHandles)
{
driver.SwitchTo().Window(window);
if (GetModal())
{
//do actions here
break;
}
}
driver.SwitchTo().Window(current_window); //To put you back where you started.
private bool GetModal()
{
Try
{
IWebElement modal = driver.FindElementByXPath("");
return true;
}
catch
{
return false;
}
}
Based on what you put this should work. If you can't find the modal then there is probably a different issue than just the window not being in focus. If you are worried about other errors then I would say catch only the specific error in the catch and let everything else float up ElementNotFound exception.
I am using below code
try{
//your code which will generate Modal Dialog
} catch (Exception e) {
if (e.getMessage().contains("Modal dialog present")) {//For Handling modal dialog in firefox
(new Robot()).keyPress(java.awt.event.KeyEvent.VK_ESCAPE);
(new Robot()).keyRelease(java.awt.event.KeyEvent.VK_ESCAPE);
}else if(e.getMessage().contains("unexpected alert open")){//For Handling modal dialog in chrome
driver.switchTo().alert().accept();
}
}