有人可以帮我解决 '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:过时的元素引用:元素未附加到页面文档
我尝试了很多方法都没有成功:
- Thread.sleep();
- 试一试;
- 在循环中尝试捕获;
- 在循环中再次找到项目;
- driver.navigate().refresh();
这是因为您的元素暂时无法访问或已从 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"));
}
}
我有一个有 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:过时的元素引用:元素未附加到页面文档
我尝试了很多方法都没有成功:
- Thread.sleep();
- 试一试;
- 在循环中尝试捕获;
- 在循环中再次找到项目;
- driver.navigate().refresh();
这是因为您的元素暂时无法访问或已从 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"));
}
}