我试图找到这件事的解决方案,我花了很多时间,但对我来说几乎不可能做到这一点。
问题:我在 Firefox 中使用 Selenium 和 Java。我需要找到一个元素(列表框)并单击它。因此,代码找到了该元素,但单击操作不起作用。每次在 Google Chrome 中都可以正常工作,但有时在 Firefox 中却可以正常工作(使用相同的 Java 代码有时可以工作,有时则不能)。
程序进入页面时有带有元素的代码部分:
<div id="size-btn" class="size-btn">
<span class="selected-size">SELECCIONA TALLA </span>
<div class="size-select" style="display: none;">
<table>
<tbody>
<tr id="selecsize_2" class="product-size" data-ga-props="{action:'Seleccionar_Producto', opt_label:'Escoger_Talla'}" data-catentryid="1051607">
<tr id="selecsize_3" class="product-size" data-ga-props="{action:'Seleccionar_Producto', opt_label:'Escoger_Talla'}" data-catentryid="1051608">
<tr id="selecsize_4" class="product-size" data-ga-props="{action:'Seleccionar_Producto', opt_label:'Escoger_Talla'}" data-catentryid="1051609">
<tr id="selecsize_5" class="product-size" data-ga-props="{action:'Seleccionar_Producto', opt_label:'Escoger_Talla'}" data-catentryid="1051610">
</tbody>
</table>
<button class="size-guide gaViewEvent gaTrack" data-ga-props="{action:'Seleccionar_Talla', opt_label:'Guia_de_tallas'}" data-href="http://www.anyweb.com/webapp/wcs/stores/servlet/ProductGuideSizeAjaxView?catalogId=24052&categoryId=358056&langId=-5&productId=1047599&storeId=10701">Guía de tallas</button>
</div>
</div>
点击元素时,代码部分会发生变化:
<div id="size-btn" class="size-btn opened">
我尝试了很多解决方案,有时它可以工作,但下次运行该程序时,它又不起作用了。
一些解决方案:
它找到元素,但不运行单击操作。我检查了 xpath 和 cssSelector,并且在这些表达式中找到了独特的元素。
driver.findElement(By.xpath("//div[@id='size-btn' and not(contains(@class,'opened'))]/span")).click(); // Also checked with By.cssSelector("span.selected-size")
我以为是因为时间原因,所以我尝试用这种方式解决它。
WebElement we = driver.findElement(By.xpath("//div[@id='size-btn' and not(contains(@class,'opened'))]/span")); // By.cssSelector("span.selected-size")
Thread.sleep(3000);
we.click();
最后,我有点绝望,我创建了一个新函数来尝试执行此操作近 60 次,寻找元素代码上的更改,如果有任何更改,就尝试再次执行单击操作。
clickAndWaitWhileElementIsNotPresent(By.xpath("//div[@id='size-btn' and not(contains(@class,'opened'))]/span"),By.xpath("//div[@class='size-btn opened']/span")); // By.cssSelector("span.selected-size")
private void clickAndWaitWhileElementIsNotPresent(By by1, By by2) throws Exception {
for (int second = 0;; second++) {
if (second >= 60)
fail("timeout");
try {
if (isElementPresent(by2))
{
break;
}
else
{
driver.findElement(by1).click();
}
} catch (Exception e) {
}
Thread.sleep(1000);
}
}
有元素的图像:
有人知道该怎么做吗?
最后我找到了一个适用于 Firefox 和 Google Chrome 的答案。
WebElement we = this.driver.findElement(By.id("size-btn"));
JavascriptExecutor executor = (JavascriptExecutor) driver;
executor.executeScript("arguments[0].click();", we);
waitForElementPresent(By.xpath("//div[@id='size-btn' and contains(@class,'opened')]/span"));
我不确定你为什么使用这个Xpath,如果你可以自由地更改Xpath,那么使用selenium IDE记录元素并使用
Xpath::position
下拉列表中的target
(它选择相对于html标题的唯一路径),它将解决动态定位器的问题。并尝试下面提到的事件。
1- 使用
clickAt
。
2- 使用
fireevent(focus)
,然后单击。有时会发生背景中的某些元素正在加载,当它加载时,焦点移动到那里,因此 elementNotVisible 错误。
3- 使用
mouseDownRight
。
我在 Firefox 中也遇到同样的问题。诀窍是单击按钮内部的文本而不是按钮本身。
我有一些解决方案,用机器人创建一个类,将 TAB 事件键放在那里,然后调用该类。它的作用类似于将焦点返回到页面。对于某些拉索,页面失去焦点并且永远找不到那个按钮。
Robot robot;
try {
robot = new Robot();
robot.keyPress(KeyEvent.VK_TAB);
robot.keyRelease(KeyEvent.VK_TAB);
} catch (AWTException e) {e.printStackTrace();}
您可以尝试使用 org.openqa.selenium.interactions 中的 Actions 类:
WebElement element = driver.findElement(By.id("size-btn"));
Actions builder = new Actions(driver);
builder.moveToElement(element).click(element);
builder.perform();
Actions actions = new Actions(driver);
actions.moveToElement(element);
actions.click(element);
Action action = actions.build();
action.perform();
这对我有用。
@Override
public void hoverElement() {
actions.moveToElement(element).pause(Duration.ofSeconds(1)).perform();
}
你有什么想法吗?对于这个行动。 “执行”不起作用。