我有一个下拉菜单,其标记如下:
<li>
<a href="#">Services</a>
<div class="menu-drop">
<a href="#">Service 1</a>
<a href="#">Service 2</a>
</div>
</li>
<li>
<a href="#">Operations</a>
<div class="menu-drop">
<a href="#">Operation 1</a>
<a href="#">Operation 2</a>
</div>
</li>
链接&#34;服务&#34;和&#34;运营&#34;是菜单项,悬停在其上会显示带有两个子菜单项的下拉列表。
现在,如果我必须使用WebDriver点击&#34;服务1&#34;链接,我将不得不徘徊在&#34;服务&#34;菜单选项,然后单击&#34;服务1&#34;。
我使用以下代码执行此操作:
WebElement menu = driver.findElement(By.linkText("Services"));
Actions builder = new Actions(driver);
builder.moveToElement(menu).build().perform();
WebElement li = menu.findElement(By.xpath("ancestor::li"));
WebElement menuDrop = li.findElement(By.className("menu-drop"));
WebElement subMenuLink = menuDrop.findElement(By.linkText("Service 1"));
subLink.click();
顺便说一句,我使用Eclipse来开发我的框架。
现在,只有当我在eclipse中调试它时,上面的代码才能正常工作。这意味着,我在这里给出的代码片段的第一行旁边有一个断点,然后按F6并继续这样做,它完全正常。
但是当我没有,也就是说,当我运行没有断点的代码时,它就不起作用了。发生的是,执行悬停,但只执行了几分之一秒,以及后续行
WebElement subMenuLink = menuDrop.findElement(By.linkText("Service 1"));
返回没有这样的元素异常。
可能是什么问题?
答案 0 :(得分:1)
如果这在调试模式下有效,则意味着它可能是同步问题。您甚至可能在DOM更新之前尝试单击该元素。你发现的工作可能只是一个误报。当您将鼠标移动到活动窗口时,可能会加载DOM,这就是为什么您可以单击该元素。
你尝试过这样的事吗?
WebDriverWait wait = new WebDriverWait(driver,30);
WebElement menu = driver.findElement(By.linkText("Services"));
Actions builder = new Actions(driver);
builder.moveToElement(menu).build().perform();
wait.until(ExpectedConditions.elementToBeClickable(By.linkText("Service 1"))).click();
编辑#1 试试这个,
builder.moveToElement(menu).click(driver.findElement(By.linkText("Service 1"))).perform();
如果你获得了NoSuchElementException
的linkText,那么你必须使用WebDriverWait
,因为你试图在它实际出现在DOM之前找到该元素。在这种情况下,请尝试以下。
builder.moveToElement(menu).click(wait.until(ExpectedConditions.elementToBeClickable(By.linkText("Service 1")))).perform();
答案 1 :(得分:0)
请试试以下内容:
action.moveToElement(menu).moveToElement(subMenuLink).click().build().perform();
答案 2 :(得分:0)
确定。我想到了。但我不能说它是解决方案还是解决方法。后者似乎更具吸引力。
我偶然发现了这个链接
Issue with losing focus of “hover” command when the mouse is outside of the active window
根据那里讨论的内容,我只是将我的真实鼠标光标移动到运行测试的活动窗口中的一个点(任意点),并且它有效。
这肯定很有趣,但如果有人可以说明问题的确切原因并帮助我找到解决方案,我会感激不尽。
答案 3 :(得分:0)
我也面临同样的问题。使用javascript作为解决方法。
public static void mouseHoverJScript(WebElement HoverElement) {
try {
if (isElementPresent(HoverElement)) {
String mouseOverScript = "if(document.createEvent){var evObj = document.createEvent('MouseEvents');evObj.initEvent('mouseover',true, false); arguments[0].dispatchEvent(evObj);} else if(document.createEventObject) { arguments[0].fireEvent('onmouseover');}";
((JavascriptExecutor) Selenium.webDriver).executeScript(mouseOverScript,HoverElement);
} else {
System.out.println("Element was not visible to hover " + "\n");
}
} catch (StaleElementReferenceException e) {
System.out.println("Element with " + HoverElement
+ "is not attached to the page document"
+ e.getStackTrace());
} catch (NoSuchElementException e) {
System.out.println("Element " + HoverElement + " was not found in DOM"
+ e.getStackTrace());
} catch (Exception e) {
e.printStackTrace();
System.out.println("Error occurred while hovering"
+ e.getStackTrace());
}
}
public static boolean isElementPresent(WebElement element) {
boolean flag = false;
try {
if (element.isDisplayed()
|| element.isEnabled())
flag = true;
} catch (NoSuchElementException e) {
flag = false;
} catch (StaleElementReferenceException e) {
flag = false;
}
return flag;
}
答案 4 :(得分:0)
我遇到了同样的问题,原因是元素还没有,DOM没有及时更新,所以我让它在一些driver.findelements()之前插入一个thread.sleep(),就像这样:
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
driver.findElement(By.xpath("<xpath_here>").click();
我知道这不是最美丽的方式,但即使使用WebdriverWait也失败了,它给我带来了一些痛苦。