Home > Back-end >  Unable to click element despite the xpath being accurate
Unable to click element despite the xpath being accurate

Time:10-05

I am trying to click the first element from a data table on the dashboard, as soon as I login to the system, but somehow the test case is shown passed after login only, and the record on the data table on the dashboard remains unclicked.

Here is my implementation

Xpath on another file HomePage for the records in data table enter image description here


    public final List<WebElement> listStudentsWhoMetGoals = 
                driver.findElements(By.xpath("(//*[@id='table-propeller'])[4]//td[@data-title='Top Student']//a"));

Code to click the first record in the table


public void clickFirstStudent()
    {
        if(listStudentsWhoMetGoals.size() > 0)
        {
            ExplicitWaitFactory.performExplicitWaitForList
                     (WaitStrategy.CLICKABLE, listStudentsWhoMetGoals);
            listStudentsWhoMetGoals.get(0).click();
            return new StudentTabPage();
        }
        else
        {
            DriverManager.getWebDriver().quit();
        }
    }

Test case execution


    LoginPage loginPage = new LoginPage();
                    loginPage.clickLoginButton().setUserName("admin").setPassword("xyzabc").clickSubmit().
                    clickFirstStudent();

Explicit factory code


    public class ExplicitWaitFactory 
    {
        public static WebElement performExplicitWait(WaitStrategy wait, By by)
        {
            WebElement element = null;
            if(wait == WaitStrategy.CLICKABLE)
            {
                element = new WebDriverWait(DriverManager.getWebDriver(), FrameworkConstants.getExplicitwait())
                .until(ExpectedConditions.elementToBeClickable(by));
            }
            else if(wait == WaitStrategy.VISIBLE)
            {
                element = new WebDriverWait(DriverManager.getWebDriver(), FrameworkConstants.getExplicitwait())
                .until(ExpectedConditions.visibilityOfElementLocated(by));
            }
            else if(wait == WaitStrategy.PRESENCE)
            {
                element = new WebDriverWait(DriverManager.getWebDriver(), FrameworkConstants.getExplicitwait())
                .until(ExpectedConditions.presenceOfElementLocated(by));
            }
            else if(wait == WaitStrategy.NONE)
            {
                element = DriverManager.getWebDriver().findElement(by);
            }
            return element;
        }

The test case passes right after login and doesn't even call the method to click the record, however if I select another element on the dashboard it gets clicked and action happens, but there is something wrong particularly with this case where I am unable to select the first record from the table

And if I select hardcoded first value from the table I am able to click it but that is not my motive, I wish to have all the values in a list and then click the first one.

CodePudding user response:

  1. Your xpath isn't looking reliable but may work.
  2. Ideally I would have used Explicit waits for this.

so instead of

public final List<WebElement> listStudentsWhoMetGoals = 
driver.findElements(By.xpath("(//*[@id='table-propeller'])[4]//td[@data-title='Top Student']//a"));

try this

public final List<WebElement> listStudentsWhoMetGoals = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.xpath("(//*[@id='table-propeller'])[4]//td[@data-title='Top Student']//a")));
  1. findElement uses implicit wait

By implicitly waiting, WebDriver polls the DOM for a certain duration when trying to find any element. This can be useful when certain elements on the webpage are not available immediately and need some time to load.

Please include the below line

driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

in case you want to rely on findElement. But I would argue with you why ? why not explicit waits.

Warning:

Do not mix implicit and explicit waits. Doing so can cause unpredictable wait times. For example, setting an implicit wait of 10 seconds and an explicit wait of 15 seconds could cause a timeout to occur after 20 seconds.

Also remember there are 4 ways to click in Java-Selenium bindings, Also I see you are looking to click on first element.

Code trial 1 :

Thread.sleep(5);
driver.findElement(By.xpath("(//*[@id='table-propeller'])[4]//td[@data-title='Top Student']//a")).click();

Code trial 2 :

new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("(//*[@id='table-propeller'])[4]//td[@data-title='Top Student']//a"))).click();

Code trial 3 :

Thread.sleep(5);
WebElement button = driver.findElement(By.xpath("(//*[@id='table-propeller'])[4]//td[@data-title='Top Student']//a"));
((JavascriptExecutor)driver).executeScript("arguments[0].click();", button);

Code trial 4 :

Thread.sleep(5);
WebElement button  = driver.findElement(By.xpath("(//*[@id='table-propeller'])[4]//td[@data-title='Top Student']//a"));
new Actions(driver).moveToElement(button).click().build().perform();
  • Related