有人可以帮我解决 'org.openqa.selenium.StaleElementReferenceException:' 我的情况吗?

Can someone help me to solve 'org.openqa.selenium.StaleElementReferenceException:' in my case?

我有一个有 4 行和 4 列的 table。我将第一列中的参数名称与我的 HasMap 参数键进行比较,如果匹配,则我应该单击同一行第四列中的“齿轮”图标。看起来我在第二个参数处理期间丢失了对行的引用。 初始化HashMap并为其添加参数:

Map <String, String> parameters = new HashMap<>();
parameters.put("param1”, "value1”);
parameters.put("param2”, "value2”);

方法代码:

public void setOptionalPluginParameters (Map <String, String> parameters) {

    Map <String, String> sorted_parameters = new TreeMap<String, String>(parameters);
    List <WebElement>  table_rows = driver.findElements(By.className("x-grid3-row"));

    for (WebElement table_row : table_rows) {
            String table_parameter_name = table_row.findElement(By.cssSelector("div.x-grid3-col-2")).getText();
            for (String key : sorted_parameters.keySet())
            {
                if (table_parameter_name.equals(key)) {
                    String parameter_value = sorted_parameters.get(key);
                    System.out.println("Hash value: "+ parameter_value + " By Hash Key: " + key);
                    WebElement gear = table_row.findElement(By.cssSelector("div.x-grid3-col-5 i.fa-gear"));
                    gear.click(); // <------error here during processing second parameter-------->
                    wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("value")));
                    driver.findElement(By.id("value")).clear();
                    driver.findElement(By.id("value")).sendKeys(parameter_value);
                    driver.findElement(By.cssSelector("button[type='submit']")).click();
                    break;
                }
            }
        }

结果:org.openqa.selenium.StaleElementReferenceException:过时的元素引用:元素未附加到页面文档

我尝试了很多方法都没有成功:

这是因为您的元素暂时无法访问或已从 DOM 结构中删除。

这是我遇到这个问题时通常使用的解决方案。尝试第二次加载元素:

try {
   # find element in here
   WebElement gear = table_row.findElement(By.cssSelector("div.x-grid3-col-5 i.fa-gear"));
   gear.click();
}catch(StaleElementReferenceException e){
   # repeat a gain when it catch the error
   WebElement gear = table_row.findElement(By.cssSelector("div.x-grid3-col-5 i.fa-gear"));
   gear.click();
}

过时的元素发生在文档 (HTML) 更改时。所以在你的情况下,你在 for 循环中有一个点击操作。这会修改 html 文档。

这会更改所有元素的引用,因此您必须重新标识所有元素。使用下面的解决方案

public void setOptionalPluginParameters (Map <String, String> parameters) {

    Map <String, String> sorted_parameters = new TreeMap<String, String>(parameters);
    List <WebElement>  table_rows = driver.findElements(By.className("x-grid3-row"));
    WebElement table_row;
    int count=0;
    while (count!=table_rows.size()) {
            table_row = table_rows.get(count);
            count+=1;
            String table_parameter_name = table_row.findElement(By.cssSelector("div.x-grid3-col-2")).getText();
            for (String key : sorted_parameters.keySet())
            {
                if (table_parameter_name.equals(key)) {
                    String parameter_value = sorted_parameters.get(key);
                    System.out.println("Hash value: "+ parameter_value + " By Hash Key: " + key);
                    WebElement gear = table_row.findElement(By.cssSelector("div.x-grid3-col-5 i.fa-gear"));
                    gear.click(); // <------error here during processing second parameter-------->      
                    wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("value")));
                    driver.findElement(By.id("value")).clear();
                    driver.findElement(By.id("value")).sendKeys(parameter_value);
                    driver.findElement(By.cssSelector("button[type='submit']")).click();
                    table_rows = driver.findElements(By.className("x-grid3-row"));
                    break;
                }
            table_rows = driver.findElements(By.className("x-grid3-row"));
            
            }
       }