首页 > 解决方案 > 代码在调试模式下工作,但在 JAVA 中正常执行时不工作

问题描述

在这个演示站点上尝试了下面的代码,我从产品列表中找到了一个产品,然后尝试单击它的复选框。正常执行时会显示 StaleElementException,但在调试模式下执行时会成功执行。有什么解决办法吗?

例外是:

Exception in thread "main" org.openqa.selenium.StaleElementReferenceException: stale element reference: element is not attached to the page document at
org.openqa.selenium.remote.service.DriverCommandExecutor.execute(DriverCommandExecutor.java:83) at
org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:552) at
org.openqa.selenium.remote.RemoteWebElement.execute(RemoteWebElement.java:285) at
org.openqa.selenium.remote.RemoteWebElement.getText(RemoteWebElement.java:166) at
TC.ss1.main(ss1.java:82) 

代码是:

    driver.get("https://www.nopcommerce.com/en/demo");
    Webdriver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
    Webdriver.manage().window().maximize();
    Webdriver.findElement(By.xpath("//a[@class='btn admin-button']")).click();
    
    Set<String> id =driver.getWindowHandles();
    Iterator<String> it=id.iterator();
    String ParentWindow = it.next();
    String ChildWindow = it.next();
    Webdriver.switchTo().window(ChildWindow);
    System.out.println(driver.getTitle());
    
    WebElement URL = driver.findElement(By.xpath("//div[@class='title']"));
    Assert.assertTrue(URL.isDisplayed());
    
    Webdriver.findElement(By.id("Email")).isDisplayed();
    Webdriver.findElement(By.id("Password")).isDisplayed();
    Webdriver.findElement(By.xpath("//input[@value='Log in']")).click();
    Thread.sleep(2000);
    
    Webdriver.findElement(By.xpath("//ul[@class='sidebar-menu tree']/li[2]")).click();
    Thread.sleep(2000);
    Webdriver.findElement(By.xpath("//a[@href='/Admin/Product/List']")).click();
    Thread.sleep(3000);
    
    Select dropdown = new Select(driver.findElement(By.name("products-grid_length")));
    dropdown.selectByVisibleText("7");
    Thread.sleep(2000);
    List<WebElement> Productname = driver.findElements(By.xpath("//tr[@role='row']//td[3]");
    int page=0;
    for(int i=1;i<Productname.size();i++)
    {
        page++;
        Thread.sleep(2000);
        String title = Productname.get(i).getText();
        if(!title.equals("Custom T-Shirt"))
        {
            driver.findElement(By.xpath("//i[@class='k-icon k-i-arrow-e']")).click();
            break;
        }
        else
        {
            driver.findElement(By.xpath("//*[@id='products-grid']/tbody/tr[4]/td[1]/input")).click();
            break;
        }
    }
    
    List<WebElement> Productname1 = driver.findElements(By.xpath("//tr[@role='row']//td[3]"));
    for(int j=1;j<Productname1.size();j++)
    {
        //page++;
        Thread.sleep(2000);
        String title1 = Productname1.get(j).getText();
        if(title1.equals("Custom T-Shirt"))
        {
            driver.findElement(By.xpath("//*[@id='products-grid']/tbody/tr[4]/td[1]/input")).click();
            break;
        }   
    }
    }}

标签: javaselenium

解决方案


陈旧元素异常:

基本上,当您尝试访问下一页上的相同列表时。先前捕获的 Web 元素不再被视为引用,并且那些引用的 Web 元素将抛出 Exception "Stale Element Exception"。请参阅下面的代码,因为您正在使用存储在List<WebElement> Productname1列表中的相同引用来访问不存在或由于页面刷新或 dom 更改而更改的 Web 元素。

List<WebElement> Productname = driver.findElements(By.xpath("//tr[@role='row']//td[3]"));

List<WebElement> Productname1 = driver.findElements(By.xpath("//tr[@role='row']//td[3]"));

基本上,当所有元素都加载到 DOM 中时,Web 元素会获得一个引用的 Web 元素,并且一旦DOM重新加载更改,那么早先捕获的 Web 元素不再被视为引用,并且那些引用的 Web 元素将抛出错误Stale Element Exception

当您尝试与过时的 WebElement 交互时,会引发 StaleElementException。

解决方案:

解决此问题的简单技巧是在页面刷新/更改或移动到下一页时更新 Weblement 列表。

    List<WebElement> Productname = driver.findElements(By.xpath("//tr[@role='row']//td[3]"));
        int page=0;
        for(int i=1;i<Productname.size();i++)
        {
            page++;
            Thread.sleep(2000);
//Update reference
            Productname = driver.findElements(By.xpath("//tr[@role='row']//td[3]"));
            String title = Productname.get(i).getText();
            if(!title.equals("Custom T-Shirt"))
            {
                driver.findElement(By.xpath("//i[@class='k-icon k-i-arrow-e']")).click();
                break;
            }
            else
            {
                driver.findElement(By.xpath("//*[@id='products-grid']/tbody/tr[4]/td[1]/input")).click();
                break;
            }
        }

        List<WebElement> Productname1 = driver.findElements(By.xpath("//tr[@role='row']//td[3]"));
        for(int j=0;j<Productname1.size();j++)
        {
            //page++;
            Thread.sleep(2000);
//Update reference
            Productname1 = driver.findElements(By.xpath("//tr[@role='row']//td[3]"));
            String title1 = Productname1.get(j).getText();
            if(title1.equals("Custom T-Shirt"))
            {
                driver.findElement(By.xpath("//*[@id='products-grid']/tbody/tr[4]/td[1]/input")).click();
                break;
            }   
        }

推荐阅读