ElementClickInterceptedException error that I cannot resolve - java

I am getting the following error:
ElementClickInterceptedException: element click intercepted: Element is not clickable at point (288, 833)
When I manually scroll down the page to view the element, selenium finds it and clicks on it, but only if I help it by scrolling down. I have tried different methods to resolve this that I have commented out in the code, but it is still not resolved? How do I resolve this error?
package mypackage;
import java.time.Duration;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import io.github.bonigarcia.wdm.WebDriverManager;
public class DynamicWebTable {
public static void main(String[] args) throws InterruptedException {
WebDriverManager.chromedriver().setup();
WebDriver driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
driver.get("https://demo.opencart.com/admin/");
driver.manage().window().maximize();
WebElement username = driver.findElement(By.id("input-username"));
username.clear();
username.sendKeys("demo");
WebElement password = driver.findElement(By.id("input-password"));
password.clear();
password.sendKeys("demo");
driver.findElement(By.xpath("//button[normalize-space()='Login']")).click();
//Close popup
if(driver.findElement(By.xpath("//div[#class='modal-content']")).isDisplayed()) {
driver.findElement(By.xpath("//button[#class='btn-close']")).click();
}
driver.findElement(By.xpath("//a[normalize-space()='Sales']")).click();
driver.findElement(By.xpath("//a[normalize-space()='Orders']")).click();
//get total no of pages
String textWithTotalPages = driver.findElement(By.xpath("//div[#class='col-sm-6 text-end']")).getText();
int pages = getNumberOfPages(textWithTotalPages);
System.out.println(pages);
//
for(int p = 1; p <= 2; p++) {
WebElement active_page = driver.findElement(By.xpath("//ul[#class='pagination']//li//span"));
System.out.println("Active Page: "+active_page.getText());
Thread.sleep(3000);
//new WebDriverWait(driver, Duration.ofSeconds(10)).until(ExpectedConditions.elementToBeClickable(active_page)).click();
active_page.click();
//Actions actions = new Actions(driver);
//actions.moveToElement(active_page).click().perform();
//JavascriptExecutor e = (JavascriptExecutor)driver;
//e.executeScript("arguments[0].click();", active_page);
//get number of rows
int rows = driver.findElements(By.xpath("//table[#class='table table-bordered table-hover']//tbody/tr")).size();
System.out.println("No of Rows: "+rows);
//read rows from each page
for(int r=1; r<=rows; r++) {
String orderId = driver.findElement(By.xpath("//table[#class='table table-bordered table-hover']//tbody//tr["+r+"]//td[2]")).getText();
String store = driver.findElement(By.xpath("//table[#class='table table-bordered table-hover']//tbody//tr["+r+"]//td[3]")).getText();
String customer = driver.findElement(By.xpath("//table[#class='table table-bordered table-hover']//tbody//tr["+r+"]//td[4]")).getText();
String status = driver.findElement(By.xpath("//table[#class='table table-bordered table-hover']//tbody//tr["+r+"]//td[5]")).getText();
System.out.println(orderId+ " "+store+" "+customer+" "+status);
}
//click next page
String nextPage = Integer.toString(p + 1);
driver.findElement(By.xpath("//ul[#class='pagination']//li//a[text()='"+nextPage+"']")).click();
}
driver.quit();
}
//extract number of pages from String
public static int getNumberOfPages(String text){
return Integer.valueOf(text.substring(text.indexOf("(")+1, text.indexOf("Pages")-1));
}
}

You have to close this pop updriver.findElement(By.xpath("//button[#class='btn-close']")).click
before you execute
driver.findElement(By.xpath("//a[normalize-space()='Sales']")).click();
This will resolve the problem for you. I have tried in WATIR, it's working for me.
Okay, So try writing this code in try catch block.
try{
activePage.click();
}catch(ElementClickInterceptedException e){
}
or scroll down the page and issue the click, it works too
JavascriptExecutor js= (JavascriptExecutor) driver;
js.executeScript("window.scrollTo(0,document.body.scrollHeight)");
Thread.sleep(2000);
activePage.click();

Try the below code, I made 2 changes to your code:
Using JavascriptExecutor, scroll down to the bottom of the page and then perform active_page.click()
In the second iteration since the DOM structure changes,active_page.click() won't work(you may get Stale element reference, Element is not attached to the page document exception), so you need to assign the web element once again
Good luck.
for(int p = 1; p <= 2; p++) {
WebElement active_page = driver.findElement(By.xpath("//ul[#class='pagination']//li//span"));
System.out.println("Active Page: "+active_page.getText());
Thread.sleep(3000);
//below 2 lines will scroll to the bottom of the page
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("window.scrollBy(0,document.body.scrollHeight)");
Thread.sleep(3000);
//assigning web element to active_page once again as the DOM structure has changed
active_page = driver.findElement(By.xpath("//ul[#class='pagination']//li//span"));
active_page.click();

Related

List<WebElement> is not storing all the required elements in selenium

My myntra wishlist has 41 products, of which 19 are out of stock. I tried printing the names of the 'out of stock' products.
'out of stock' elements had a common class name using which I identified the product's name using xpath by traversing through parent and child nodes.
when i validated it in console, it gave the right response. It showed 19 products and when i hovered the mouse pointer it highlighted the out of stock products as expected. Works as expected when i debugged the code too.
But when i hit run, it printed only 7 products, size of the list was 7.
The page initially displays top 20 products and later displays the remaining as we scroll down. Out of the top 20, 7 are out of stock. Could this be a reason. If that is the case, how to handle this scroll event?
Here's the code snippet:
import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class stockout {
public static void main(String[] args) {
System.setProperty("webdriver.chrome.driver", "path of chromedriver.exe");
WebDriver driver = new ChromeDriver();
WebDriverWait w =new WebDriverWait(driver,30);
driver.get(myntra login page);
//enter phone number driver.findElement(By.xpath(("//div[#class='signInContainer']/div[2]/div/input"))).sendKeys(phone number);
driver.findElement(By.cssSelector("div.submitBottomOption")).click();
Thread.sleep(2000);
driver.findElement(By.xpath("//div[#class='bottomeLink']/span")).click();
//enter password
driver.findElement(By.xpath("//input[#type='password']")).sendKeys(password);
driver.findElement(By.cssSelector("button.btn.primary.lg.block.submitButton")).click();
Thread.sleep(4000);
//open wishlist
driver.findElement(By.cssSelector("span.myntraweb-sprite.desktop-iconWishlist.sprites-headerWishlist")).click();
//add out of stock elements to a list
List<WebElement> outofstock = driver.findElements(By.xpath("//img[#class='itemcard-outOfStockItemImage itemcard-itemImage']/parent::picture/parent::a/parent::div/parent::div/div[2]/div/p[1]"));
//explicit wait
w.until(ExpectedConditions.visibilityOfAllElements(outofstock));
System.out.println(outofstock.size());
System.out.println("Items out of stock:");
for (WebElement product: outofstock)
{ System.out.println(product.getText());
}
}
}
Found the solution on the net, but wondering if there's any simpler way to do this. Suggestions are welcomed.
I added this piece of code to scroll down and it worked:
try {
Object lastHeight = ((JavascriptExecutor) driver).executeScript("return document.body.scrollHeight");
while (true) {
((JavascriptExecutor) driver).executeScript("window.scrollTo(0, document.body.scrollHeight);");
Thread.sleep(2000);
Object newHeight = ((JavascriptExecutor) driver).executeScript("return document.body.scrollHeight");
if (newHeight.equals(lastHeight)) {
break;
}
lastHeight = newHeight;
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
You can use the following code if you are expecting a specific number of elements to be present.
new WebDriverWait(driver,10).until(ExpectedConditions.numberOfElementsToBe(By by, 19));

Selenium WebElement.click() refreshes the page instead of going to next screen. No response when WebElement.submit() is used

I am learning Selenium and using jetblue.com for test. When I click on "FIND IT" button in homepage by providing all the required values, the page simply refreshes instead of going to the next screen. Can anyone advise where I am going wrong?
I tried using .click() and submit(). but not the control does not go the next page
package testCases;
import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.interactions.Actions;
import org.testng.annotations.Test;
public class Calendar {
#Test
public void calControl() throws InterruptedException
{
System.setProperty("webdriver.chrome.driver","C:\\chromedriver_win32\\chromedriver.exe");
ChromeOptions options = new ChromeOptions();
options.addArguments("disable-infobars");
options.addArguments("--start-maximized");
WebDriver driver= new ChromeDriver(options);
driver.get("https://www.jetblue.com");
// driver.findElement(By.className("input-group-btn")).click();
Thread.sleep(3000);
// driver.findElement(By.cssSelector("button[class='btn pull-right']")).click();
List<WebElement> count = driver.findElements(By.className("input-group-btn"));
int count1 = driver.findElements(By.className("input-group-btn")).size();
count.get(0).click();
Thread.sleep(3000);
driver.findElement(By.xpath("//table[#class='calendar']//td//span[.=27]")).click();
System.out.println(count1);
for (int i = 0;i<count1;i++)
{
System.out.println(count.get(i).toString());
}
Thread.sleep(3000);
count.get(1).click();
Thread.sleep(3000);
//driver.findElement(By.xpath("//button/span[#class='foreground-sprite-calendarforward']")).click();
List<WebElement> pullRight = driver.findElements(By.cssSelector("button[class='btn pull-right']"));
int count2 = driver.findElements(By.cssSelector("button[class='btn pull-right']")).size();
do
{
pullRight.get(1).click();
} while (driver.findElement(By.xpath("//div/strong[.='March 2018']")).isDisplayed()==false);
List<WebElement> returnDate = driver.findElements(By.xpath("//table[#class='calendar']//td//span[.=8]"));
int returnCount = driver.findElements(By.xpath("//table[#class='calendar']//td//span[.=3]")).size();
returnDate.get(1).click();
//driver.findElement(By.xpath("//input[#class='piejs']")).click(); Find Button
WebElement from = driver.findElement(By.id("jbBookerDepart"));
from.click();
Thread.sleep(2000);
from.sendKeys("DXB");
from.sendKeys(Keys.TAB);
Thread.sleep(2000);
WebElement to = driver.findElement(By.id("jbBookerArrive"));
to.click();
Thread.sleep(2000);
to.sendKeys("SFO");
to.sendKeys(Keys.TAB);
Thread.sleep(2000);
WebElement findButton = driver.findElement(By.xpath("//*[#id='login-search-wrap']/div[3]/div/div[3]/form/input[5]"));
//System.out.println("Value of button:" +driver.findElement(By.xpath("//*[#id='login-search-wrap']/div[3]/div/div[3]/form/input[5]")).toString());
/*Actions a = new Actions(driver);
//a.click(findButton).build().perform();
a.clickAndHold(findButton).doubleClick().build().perform();*/
/*driver.findElement(By.cssSelector("input[value='Find it']")).submit();
driver.findElement(By.xpath("input[value='Find it']")).submit();*/
System.out.println(findButton.isEnabled());
findButton.click();
Thread.sleep(5000);
}
}
That page is probably using anti-selenium software. I debugged your code several times, and here are my observations - I tried do perform some operations by hand, and some by WebDriver, and the result is: If ANY operation is performed by WebDriver, the form will not submit. That even includes opening of the page. They probably set some flag whenever an automated software is performing any action on their page.
Have a look at this answer. I don't know what anti-bot method they may be using, but this could be the first step.

To Pick the First Airport Code from the Auto-populated list in Selenium with java

I have to automate the Flight page for the below URL
URL: https://www.cheapoair.com/deals/business-class-airfares
Enter LAS in the 'Flying From ' Textbox and you will see the list getting displayed and have to select the First Airport code from the auto-populated list matching the Airport Code .
I have to automate using Selenium with java. Could you share the piece of code for it.
Flight image with Autopopulated origin List
Given this select:
<select name="airports" id="airport">
<option value="lax">Los Angeles</option >
<option value="sfo">San Francisco</option >
<option value="pdx">Portland</option >
</select>
...you can select by label text:
Select select = new Select(driver.findElement(By.name("airports")));
select.selectByVisibleText("Portland");
...or by value:
Select select = new Select(driver.findElement(By.name("airports")));
select.selectByValue("pdx");
WebDriver driver=new FirefoxDriver();
driver.manage().window().maximize();
driver.get("https://www.expedia.co.in/Flights");
WebElement textbox=driver.findElement(By.xpath("//input[#id='flight-origin']"));
textbox.clear();
textbox.sendKeys("LAS");
Thread.sleep(4000);
List<WebElement> allOptions = driver.findElements(By.xpath("//div[#id='typeahead-list']"));
int count=allOptions.size();
System.out.println("No of autosuggestions"+count);
for(int i=0;i<count;i++)
{
String text=allOptions.get(i).getText();
System.out.println(text);
}
textbox.sendKeys(Keys.ARROW_DOWN);
textbox.sendKeys(Keys.ENTER);
}
}
Hi please find the solution to above problem
package com.daythree;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class ExpediaProblem {
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
System.setProperty("webdriver.chrome.driver", "F:\\workspace\\...\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
driver.navigate().to("https://www.expedia.co.in/Flights");
driver.findElement(By.id("flight-origin")).click();
// Thread.sleep(3000);
driver.findElement(By.id("flight-origin")).sendKeys("las");
// wait for the suggestions to appear
WebDriverWait wait = new WebDriverWait(driver, 20);
wait.until(ExpectedConditions.visibilityOf(driver.findElement(By.xpath("//*[#role='listbox']/div/li/a/div/div"))));
List<WebElement> suggestions = driver.findElements(By.xpath("//*[#role='listbox']/div/li/a/div/div"));
System.out.println("Size of the suggestions is : " + suggestions);
String val = "Las Vegas, NV, US";
for(int i=0;i<suggestions.size();i++){
// this will print all the suggestions
System.out.println("value is : " + suggestions.get(i).getText());
// now logic to select the option
if(suggestions.get(i).getText().contains(val)){
suggestions.get(i).click();
break;
}
}
}
}

how to locate an element of a page after new data loaded on the same page in selenium webdriver

I am trying to copy the table data of the html page which is loaded on the same page after clicking on the 'Get Table' button on the previous page. However, as the page url is not changing I am getting exception of 'No such element' when trying to locate new elements on newly loaded page. Following is the code I tried:
package com.test.selenium;
import java.util.List;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.Select;
import org.openqa.selenium.support.ui.WebDriverWait;
import junit.framework.Test;
import junit.framework.TestSuite;
public class Example1{
public static void main(String[] args) {
System.setProperty("webdriver.chrome.driver", "D:\\Java Stuff\\Selenium Tutorial\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.get("http://www.oanda.com/currency/table");
WebElement date = driver.findElement(By.name("date"));
date.sendKeys("12/04/10");
WebElement date_frmt = driver.findElement(By.name("date_fmt"));
date_frmt.sendKeys("yy/mm/dd");
WebElement curr = driver.findElement(By.name("exch"));
curr.sendKeys("US Dollar.USD");
Select sel = new Select(driver.findElement(By.name("Currency")));
sel.deselectAll();
List lsize = sel.getOptions();
int count = lsize.size();
for(int j=0;j<count;j++)
{
String lvalue = sel.getOptions().get(j).getText();
sel.selectByVisibleText(lvalue);
}
WebElement crr = driver.findElement(By.name("dest"));
crr.click();
driver.getCurrentUrl();
String table = driver.findElement(By.id("converter_table")).getText();
System.out.println(table);
}
}
According to exception it seems that element not exists on the page, or smth wrong with you xpath. Why you use xpath?! Try css selectors (they are more powerful and stable) =) e.g.
driver.findElement(By.css("#converter_table"));
P.S. if you want to verify that your selector is correct (no matter xpath or css) use dev console in browser (e.g. for css enter $("#converter_table") in console, and if element exists (and this id has no type in the name) then you'll see what this selector will return)). For xpath use $x("xpath")
UPDATE:
Simple solution i think is to add some method which will wait for element, some period of time. Below sample code in C# (test with wait method)
private IWebDriver driver;
[SetUp]
public void SetUp()
{
// Here i just create browser as you (firefox, chrome etc);
driver = CreateBrowser("http://www.oanda.com/currency/table");
}
[TearDown]
public void TearDown()
{
driver.Dispose();
}
[Test]
public void PortTest()
{
var dateElement = driver.FindElement(By.Name("date"));
dateElement.SendKeys("12/04/10");
var dateFrmt = driver.FindElement(By.Name("date_fmt"));
dateFrmt.SendKeys("yy/mm/dd");
var curr = driver.FindElement(By.Name("exch"));
curr.SendKeys("US Dollar.USD");
var crr = driver.FindElement(By.Name("dest"));
crr.Click();
WaitUntilLoad();
var table = driver.FindElement(By.Id("converter_table"));
Console.Write("the text is " + table.Text);
}
public void WaitUntilLoad()
{
int repetitionCount = 0;
bool isLoaded = false;
while (!isLoaded)
{
var table = driver.FindElements(By.Id("converter_table")).Count;
if (table > 0 )
isLoaded = true;
Thread.Sleep(250);
repetitionCount++;
Console.WriteLine("Searching again for element");
if (repetitionCount > 25) break;
}
}
you get NoSuchElement because your xpath seems wrong
try
WebElement myDynamicElement = (new WebDriverWait(driver, 10))
.until(ExpectedConditions.presenceOfElementLocated(By.xpath(".//*[#id='content_section']/table")));
String table = driver.findElement(By.xpath(".//*[#id='content_section']/table")).getText();

Selenium WebDriver - getCssValue() method

I am doing a exercise to use cssGetValue method to retrieve the value from a particular web element's CSS property.
I have 2 questions:
why the cssGetValue method returned value 13px, which web element does the method actually referenced.
1a. I want to get CSS property for section labeled as "By ID". how should I modify my code so I can get CSS property value for id="by-id" section?
I used driver.close() method, but it won't close the browser after the script finished. Please explain to me why driver.close() method didn't work in this case.
Here is my code fragment:
package wd_findElementBy;
import java.util.List;
import org.junit.Test;
import org.junit.Before;
import org.junit.After;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
public class SearchWebElements
{
WebDriver driver = new FirefoxDriver();
private String baseUrl= "http://docs.seleniumhq.org/docs/03_webdriver.jsp#introducing-the-selenium-webdriver-api-by-example";
#Test
public void findElements(){
driver.get(baseUrl);
try{
List<WebElement> elements = driver.findElements(By.id("by-id"));
System.out.println("number of elements: " + elements.size());
for(WebElement ele : elements){
System.out.println(ele.getTagName());
System.out.println("get the text for web element with id='by-id' ");
System.out.println("------------------------------------------------------------");
System.out.println(ele.getText());
System.out.println("------------------------------------------------------------");
System.out.println(ele.getAttribute("id"));
System.out.println(ele.getCssValue("font-size"));
}
}
finally{
//driver.close();
driver.quit();
}
}
}
Yes, all correct.
Here's a screenshot of where to find font-size through Firebug.
Since the ids are supposed to be unique (at least for this page), you don't need findElements to find a list of elements with id by-id and loop through, instead, you use findElement to get the element directly.
try{
WebElement byId = driver.findElement(By.id("by-id"));
System.out.println(byId.getTagName());
System.out.println("get the text for web element with id='by-id' ");
System.out.println("------------------------------------------------------------");
System.out.println(byId.getText());
System.out.println("------------------------------------------------------------");
System.out.println(byId.getAttribute("id"));
System.out.println(byId.getCssValue("font-size"));
}
}
For getting CSS value:
driver.findElement(By.id("by-id")).getCssValue("font-size");//similarly you can use other CSS property such as background-color, font-family etc.
For quit/close the browser after finishing the execution of script:
driver.quit();
public class GetCssValues {
public WebDriver driver;
private By bySearchButton = By.name("btnK");
#BeforeClass
public void setUp() {
driver = new FirefoxDriver();
driver.get("http://www.google.com");
}
#Test(priority=1)
public void getCssValue_ButtonColor() {
WebElement googleSearchBtn = driver.findElement(bySearchButton);
System.out.println("Color of a button before mouse hover: " + googleSearchBtn.getCssValue("color"));
Actions action = new Actions(driver);
action.moveToElement(googleSearchBtn).perform();
System.out.println("Color of a button after mouse hover : " + googleSearchBtn.getCssValue("color"));
}
#Test(priority=2)
public void getCssValue_ButtonFontSize() {
WebElement googleSearchBtn = driver.findElement(bySearchButton);
System.out.println("Font Size of a button " + googleSearchBtn.getCssValue("font-size"));
}
#Test(priority=3)
public void getCssValue_ButtonFontWeight(){
WebElement googleSearchBtn = driver.findElement(bySearchButton);
System.out.println("Font Weight of a button " +getFontWeight(googleSearchBtn) );
}
public String getFontWeight(WebElement element) {
//Output will return as 400 for font-weight : normal, and 700 for font-weight : bold
return element.getCssValue("font-weight");
}
#AfterClass
public void tearDown() {
driver.quit();
}
}
output:
Color of a button before mouse hover: rgba(68, 68, 68, 1)
Color of a button after mouse hover : rgba(34, 34, 34, 1)
Font Size of a button 11px
Font Weight of a button 700
The value is correct. You need access computed section in dev-tools
Add the property name in the getCssValue to get the info regarding same
Some Examples are :-
System.out.println("font-size = "+ele.getCssValue("font-size"));
System.out.println("background = "+ele.getCssValue("background"));
System.out.println("line-height = "+ele.getCssValue("line-height"));
System.out.println("color = "+ele.getCssValue("color"));
System.out.println("font-family = "+ele.getCssValue("font-family"));
Refer:-

Categories