Webdriver fails to click element after a WebDriverWait - java

First, I was facing an issue that selenium webdriver was not always finding the element and clicking, and I found that WebDriverWait should solve the problem. So, I used this code, for instance:
WebDriverWait wait = new WebDriverWait(driver, 20);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("html/body/div[1]/aside/div/nav/ul/li[3]/a"))).click();
But now I am having a timeout issue, Observing the test to run, I can see that the element is being hover(because it changes the color), but webdriver is not clicking.
Does anyone have tips on how to solve this?

I would recommend refactoring like this, to separate the wait from the click event. Otherwise, its hard to diagnose the cause of your click failure:
WebDriverWait wait = new WebDriverWait(driver, 20);
By locator = By.xpath(".//ul/li[3]/a");
WebElement we = wait.until(ExpectedConditions.visibilityOfElementLocated(locator))
.ignoring(NoSuchElementException.class);
try {
we.click();
} catch (WebDriverException wde)
{
LOGGER.info("Click failed.", wde);
}

Put the wait and then try JavascriptExecutor to click on your element
WebElement element= driver.findElement(YOUR Locator);
JavascriptExecutor executor = (JavascriptExecutor) driver;
executor.executeScript("arguments[0].click();", element);
Hope it will help you :)

Related

Element Clickable in Java Selenium

I'm trying to click on Calendar but everytime I try to click on the calendar the error pop up as "element click intercepted: Element is not clickable at point (293, 1317)
<input type="text" name="form_fields[travel_comp_date]" id="form-field-travel_comp_date"
class="elementor-field elementor-size-sm elementor-field-textual elementor-date-field
flatpickr-input" placeholder="Date of travel"
pattern="[0-9]{4}-[0-9]{2}-[0-9]{2}" readonly="readonly">
Here's my code:
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5));
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//input[#name='form_fields[travel_comp_date]']")));
driver.findElement(By.xpath("//input[#name='form_fields[travel_comp_date]']")).click();
Can someone please help me correcting this.
Please try the following code with explicit wait and let me know if it works for you:
enter code here
driver.get("https://www.path2usa.com/travel-companion/");
WebElement dateTravel =
driver.findElement(By.xpath("//input[#id='form-field-
travel_comp_date']"));
driver.manage().window().maximize();
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("window.scrollBy(0,1000)");
WebDriverWait wait = new WebDriverWait(driver,
Duration.ofSeconds(5));
js.executeScript("arguments[0].scrollIntoView();", dateTravel);
wait.until(ExpectedConditions.visibilityOf(dateTravel));
if(dateTravel.isDisplayed())
{
js.executeScript("document.getElementById('form-field-
travel_comp_date').value='12/20/2023'");
}
The element you are trying to access is out of the initially presented view port.
In order to click it you first need to scroll the page to bring that element into the visible view port and only after that you will be able to click on it.
Please try this:
JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("window.scrollTo(0, document.body.scrollHeight)");
Or this
JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("window.scrollBy(0,600)");
After that try performing your code

Button not clickable consistently in Selenium Java

I am trying to click a button in selenium java code and it is not clicking all the time. Apparently this is pretty common issue.
I tried below few solutions:
HTML Code :
<button class="btn btn--action btn--border-white btn--my__calculate" style="display: inline-block;">Final Figure</button>
Solution 1:
WebElement btnWorkout = webDriver.findElement(By.cssSelector(".btn--my__calculate"));
if (btnWorkout.isDisplayed() && btnWorkout.isEnabled()) {
btnWorkout.click();
}
Solution 2 :
WebDriverWait wait = new WebDriverWait(webDriver, 10);
WebElement btnWorkout = wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector(".btn--my__calculate")));
btnWorkout.click();
Solution 3:
WebElement btnWorkout = webDriver.findElement(By.cssSelector(".btn--my__calculate"));
JavascriptExecutor executor = (JavascriptExecutor) webDriver;
executor.executeScript("arguments[0].click();", btnWorkout);
None of them worked for me.
Other strange thing is above step passes without an error and button doesn't click as expected
Induce WebDriverWait And Following Xapth.
Try following options.
Option1:
WebDriverWait wait = new WebDriverWait(webDriver, 20);
WebElement btnWorkout=wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//button[#class='btn btn--action btn--border-white btn--my__calculate'][text()='Final Figure']")));
btnWorkout.click();
Option2: Use Action class
WebDriverWait wait = new WebDriverWait(webDriver, 20);
WebElement btnWorkout=wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//button[#class='btn btn--action btn--border-white btn--my__calculate'][text()='Final Figure']")));
Actions action=new Actions(webDriver);
action.moveToElement(btnWorkout).click().build().perform();
Option3: Use JavaScript Executor
WebDriverWait wait = new WebDriverWait(webDriver, 20);
WebElement btnWorkout=wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//button[#class='btn btn--action btn--border-white btn--my__calculate'][text()='Final Figure']")));
JavascriptExecutor executor = (JavascriptExecutor) webDriver;
executor.executeScript("arguments[0].click();", btnWorkout);
Curious that the executeScript() option didn't work for you. Keep using your WebDriverWait from option 2, but instead of the click() method, try using Action Chains. I'm not sure how to write this in Java, but it'll be something like this:
Actions action = new Actions(driver);
action.move_to_element(btnWorkout).click(btnWorkout).perform();
Maybe you have another hidden element with same CSS (class). You can try capture the element by linkText or partialLinkText like this:
WebElement btnWorkout = webDriver.findElement(By.linkText("Final Figure"));

Stale Element Exception, Element not Clickable,Element Click Intercepted & No Such Element error displayed Alternately by same element

I am trying to select multiple filers available in https://www.jabong.com/find/men's-black-jeans using Automation(Firefox).
However, after selecting the first option (Gender), I am unable to proceed.
I faced the Element click intercepted and tried Fluent Wait which lead to Stale Element Exception.
If I remove the Fluent wait or use implicit wait, I sometimes get the Element found exception.
To add to the confusion, sometimes the code runs properly without any wait and am able to select multiple options, but that is rare
public void case9() {
driver.get("https://www.jabong.com/");
WebElement SearchBox = driver.findElement(By.xpath("//*[#id=\"search\"]"));
SearchBox.sendKeys("men's black jeans");
Actions actn = new Actions (driver);
actn.sendKeys(SearchBox, Keys.ENTER).build().perform();
driver.manage().timeouts().implicitlyWait(34, TimeUnit.SECONDS);
driver.findElement(By.xpath("//*[#id=\"allFilterPopupTop\"]")).click();
driver.manage().timeouts().implicitlyWait(34, TimeUnit.SECONDS);
driver.findElement(By.xpath("/html/body/section[1]/div/section/section[1]/div/div[2]/div[2]/ul/li[1]/div[3]/div/div[2]/label[1]/div/input")).click();
driver.findElement(By.xpath("//*[#id=\"Brand\"]")).click();
WebDriverWait wait1 = new WebDriverWait(driver,61);
WebElement brand1 =
driver.findElement(By.xpath("xpath for element"));
wait1.until(ExpectedConditions.elementToBeClickable(brand1));
brand1.click();
driver.findElement(By.xpath("xpath for element")).click();
driver.findElement(By.xpath("//[#id=\"Global_Size\"]")).click();
WebElement Size =
driver.findElement(By.xpath("xpath for element"));
wait1.until(ExpectedConditions.elementToBeClickable(Size));
Size.click();
driver.findElement(By.xpath("//*[#id=\"Fit\"]")).click();
driver.manage().timeouts().implicitlyWait(61, TimeUnit.SECONDS);
driver.findElement(By.xpath("xpath for element")).click();
driver.findElement(By.xpath("//*[#id=\"Fade\"]")).click();
driver.manage().timeouts().implicitlyWait(61, TimeUnit.SECONDS);
[#id=\"applyFIlters\"]")).click();
}
I just tried and this code works fine.
driver.get("https://www.jabong.com/");
WebElement searchBox = driver.findElement(By.cssSelector("#search"));
searchBox.sendKeys("men's black jeans");
WebElement searchIcon = driver.findElement(By.cssSelector("#top-search-input > div.search-containter > span"));
searchIcon.click();
WebElement firstCheckBox = driver.findElement(By.id("boys"));
firstCheckBox.click();

How to click on the button as per the HTML provided?

This is the html code for the button in the pop up ( pop up has a lead gen form) -
<button id="getCoupon" class="fetch" data-bind="click: submitForm" type="submit">Fetch Coupon</button>
This is the script which I have written in JAVA in Eclipse. I am able to fill the name, Email and Phone number but I'm not able to click on the button -
driver.findElement(By.id("getCoupon")).click();
As per the comment and URL, you have shared :
You can try with this code :
public class Pawan {
static WebDriver driver ;
public static void main(String[] args) throws InterruptedException {
System.setProperty("webdriver.chrome.driver", "C:\\Users\\user**\\Downloads\\chromedriver_win32\\chromedriver.exe");
driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get("http://vets.cm.qa.preview.vca.webstagesite.com/free-first-exam");
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("input[value='/santa-monica']~div.select-btn"))).click();
wait.until(ExpectedConditions.elementToBeClickable(By.id("fName"))).sendKeys("Pawan");
wait.until(ExpectedConditions.elementToBeClickable(By.id("lName"))).sendKeys("Sharma");
wait.until(ExpectedConditions.elementToBeClickable(By.id("email"))).sendKeys("ps12#gmail.com");
wait.until(ExpectedConditions.elementToBeClickable(By.id("zip"))).sendKeys("90404");
wait.until(ExpectedConditions.elementToBeClickable(By.id("phone"))).sendKeys("9697989900");
JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("window.scrollBy(0,100)", "");
wait.until(ExpectedConditions.elementToBeClickable(By.id("getCoupon"))).click();
}
}
As per your HTML code, your id is : "getCoupon",
whereas in code you mentioned id as : "getCouponFetch". Please correct and it should work. Code -
driver.findElement(By.id("getCoupon")).click();
If selenium click don't work, use below Java Script click code :
WebElement element = driver.findElement(By.id("getCoupon")); JavascriptExecutor executor = (JavascriptExecutor)driver; executor.executeScript("arguments[0].click();", element);
Firstly, what kind of error did you get??
Try using implicit wait if your getting "NoSuchElementException" like below:
driver.manage().timeOuts().implicitlywait(30,TimeUnit.SECONDS);
Then try using the below way to locate that button:
driver.findElementByXpath("text()[contains(.,'Fetch Coupon')]").click();
As per the HTML you have shared to click() on the button you have to induce WebDriverWait for the desired element to be clickable and you can use either of the following solutions:
cssSelector:
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("button.fetch#getCoupon"))).click();
xpath:
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//button[#class='fetch' and #id='getCoupon'][contains(.,'Fetch Coupon')]"))).click();
Update
As an alternative you can use the executeScript() method to invoke the click() as follows:
Using cssSelector:
WebElement fetch_coupon = new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("button.fetch#getCoupon")));
((JavascriptExecutor)driver).executeScript("arguments[0].click();", fetch_coupon);
Using xpath:
WebElement fetch_coupon = new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//button[#class='fetch' and #id='getCoupon'][contains(.,'Fetch Coupon')]")));
((JavascriptExecutor)driver).executeScript("arguments[0].click();", fetch_coupon);

Element not visible exception - even if different Selenium waits are used

I am trying to automate functional testing of a web application using Selenium and Java. In my application there are several menus. When clicked on a particular menu, a drop down of sub menus appear
click to view screenshot of menu
I use below code to click sub menu
driver.findElement(By.xpath("id=menu")).click();
driver.findElement(By.xpath("id=sub_menu_a")).click();
but the issue is that it throws a 'ElementNotVisibleException' at the second line. The same happens even if I use implicit wait
driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
explicit wait
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.xpath("id=sub_menu_a")));
and fluent wait.
Wait<WebDriver> fluentWait=new FluentWait<WebDriver>(driver)
.withTimeout(60, TimeUnit.SECONDS)
.pollingEvery(2, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class,ElementNotVisibleException.class);
WebElement element=fluentWait.until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver){
driver.findElement(By.xpath("id=menu"));
return driver.findElement(By.xpath("id=sub_menu_a"));
}
});
element.click();
but no luck. But the code works fine if add sleep time using
Thread.sleep(sleeptime);
before and after the first line of code. But it is not a permanent solution since the page load time may vary depend on the network speed and the data in the page. Is there any other solution?
Try this
WebElement menu=driver.findElement(By.xpath("id=menu"));
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", menu);
WebElement subMenu=driver.findElement(By.xpath("id=sub_menu_a"));
executor.executeScript("arguments[0].click();", subMenu);
Hope this work
Try to use Actions class and see if it works or not ...
driver.findElement(By.xpath("id=menu")).click();
WebElement subMenu=driver.findElement(By.xpath("id=sub_menu_a"));
Actions myaction = new Actions(driver);
myaction.moveToElement(subMenu);
WebDriverWait wait = new WebDriverWait(driver, 15);
wait.until(ExpectedConditions.elementToBeClickable(subMenu));
myaction.click().perform();
Fluent waits should work fine.
Try using something like this:
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver).withTimeout(10, TimeUnit.SECONDS).ignoring(NoSuchElementException.class);
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("id=sub_menu_a")));
but I would go for css Selectors they are perfect for html pages.
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver).withTimeout(10, TimeUnit.SECONDS).ignoring(NoSuchElementException.class);
wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#sub_menu_a")));
Or if your sub_menu_a is a child of menu I would go for
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver).withTimeout(10, TimeUnit.SECONDS).ignoring(NoSuchElementException.class);
wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#menu #sub_menu_a")));
Could you try
WebDriverWait wait = new WebDriverWait(driver, 15);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("id=sub_menu_a")));
Also it would be better if you can give html to find the right xpath as I think better XPATH will yield the result of click on the submenu.
Long time ago I have the similar issue (don't remember the exact case so indeed your HTML page snipped would be helpful) so I was forced to use Thread.sleep()
To avoid long waits will propose something like this method:
static void waitAndClick(WebDriver driver, By by, int attempts, int sleep) throws InterruptedException {
for (int i = 0; i < attempts; i++) {
WebElement element = null;
try {
element = driver.findElement(by);
} catch (NoSuchElementException e) {
// Do nothing
}
if (element == null) {
int time = sleep * (i + 1);
Thread.sleep(time);
} else {
element.click();
break;
}
}
throw new NoSuchElementException("Error");
}
It's not a 100% complete solution but just an idea.

Categories

Resources