尽管 xpath 准确,但无法单击元素

Unable to click element despite the xpath being accurate

我试图在登录系统后立即单击仪表板上数据 table 中的第一个元素,但不知何故测试用例仅在登录后显示通过,并且记录在仪表板上的数据 table 保持未点击状态。

这是我的实现

数据中记录的另一个文件主页上的 Xpath table


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

单击 table

中第一条记录的代码

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

测试用例执行


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

显式工厂代码


    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;
        }

测试用例在登录后立即通过,甚至没有调用方法来单击记录,但是如果我 select 仪表板上的另一个元素被单击并发生操作,但出现了错误特别是在这种情况下,我无法 select 来自 table

的第一条记录

如果我 select 从 table 中硬编码第一个值,我可以点击它,但这不是我的动机,我希望将所有值都放在一个列表中,然后点击第一个.

  1. 您的 xpath 看起来不可靠但可能有效。
  2. 理想情况下,我会为此使用显式等待。

所以而不是

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

试试这个

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 使用 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.

请包括以下行

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

如果你想依赖 findElement。但我会和你争论为什么?为什么不显式等待。

警告:

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.

还请记住,在 Java-Selenium 绑定 中有 4 种点击方式,我还看到您希望点击第一个元素。

代码试用 1 :

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

代码试用 2 :

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

代码试用 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);

代码试用 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();

问题已经有了很好的答案,但我只是在更正您的 ExplicitWaitFactory 代码。

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));
            }
        }
     }

方法参数是 WaitStrategyBy 但你正在传递 List<WebElement> 如下所示,

 ExplicitWaitFactory.performExplicitWaitForList
                     (WaitStrategy.CLICKABLE, listStudentsWhoMetGoals);

不接受无效参数类型并更改以下内容以使其工作,

更新检查:

 ExplicitWaitFactory.performExplicitWaitForList
                     (WaitStrategy.CLICKABLE, listStudentsWhoMetGoals.get(0));
           

更新方法:

public class ExplicitWaitFactory 
    {
        public static WebElement performExplicitWait(WaitStrategy wait, WebElement ele)
        {
            WebElement element = null;
            if(wait == WaitStrategy.CLICKABLE)
            {
                element = new WebDriverWait(DriverManager.getWebDriver(), FrameworkConstants.getExplicitwait())
                .until(ExpectedConditions.elementToBeClickable(ele));
            }
        }
     }