我在Mac 10.12.3上使用chrome 56和chromedriver 2.27时遇到了问题,虽然我尝试了几个不同版本的驱动程序和几个不同版本的浏览器,并且遇到了同样的问题。在UI中,我可以非常清楚地看到阻挡层已经清除,但是硒仍然认为它没有。等待阻止层清除后(只看浏览器),如果我捕获了driver.getPageSource()的结果,我就得到了旧的'页面源,而不是新的页面源(删除了阻止层)。当我将旧页面源视为html doc时,我可以看到阻塞层。当我查看测试结束时拍摄的屏幕截图时,显然没有阻挡层,并且对DOM的手动检查显示该元素已被移除。不知何故,selenium似乎正在缓存旧的页面源,并且无法识别何时从DOM中删除了一个元素。我似乎无法在不完全重新加载页面的情况下强制它刷新缓存的(?)html。我想避免重新加载页面,因为这会使阻塞层是否被正确删除的测试失效。
我尝试使用阻塞层元素获取一些信息(使用像element.isDisplayed()或element.getLocation()这样的良性信息),这些信息仍然表现得好像元素仍然存在。
如何处理此问题的任何建议将不胜感激。
答案 0 :(得分:2)
如果您的目标是点击该项目而不管阻止图层的状态,您可以使用内联javascript来点击元素。示例代码如下。
try {
e.click();
} catch (org.openqa.selenium.WebDriverException E1) {
((JavascriptExecutor) driver).executeScript("arguments[0].click();", e.findElements(By.xpath(".//a")).get(0));
}
答案 1 :(得分:1)
在通过GWT弹出面板运行Selenium测试时,我遇到了同样的问题。
有时动画无法完成,弹出窗口和后面的玻璃留在DOM上。
发生这种情况时,我尝试从dom中删除这两个元素,但结果却很奇怪(从dom中删除了其他元素!!)。
最后,我实现了这些函数,它们隐藏了这两个元素并更改了className,以使它们不再困扰我们(请参见下面的代码)
waitForPopupOpeningAnimationFinished():应在应该打开弹出窗口的单击后启动
waitForPopupClosingAnimationFinished():在单击弹出按钮后应关闭弹出窗口才能启动
// 200 is the animation time of the popup, we wait a lot more, see com.google.gwt.user.client.ui.PopupPanel.ANIMATION_DURATION
public static final int POPUP_ANIMATION_WAIT_TIME = 300;
public static final String CLASS_GWT_DIALOG_BOX = "gwt-DialogBox";
public static final String X_POPUP = "//div[@class='" + CLASS_GWT_DIALOG_BOX + "']";
public static final By BY_POPUP = By.xpath(X_POPUP);
public static final String X_POPUP_TOTALLY_OPENED_LOCATOR = "//div[contains(@class, '" + CLASS_GWT_DIALOG_BOX + "') and contains(@style, 'clip: rect(auto, auto, auto, auto);')]";
public static final By BY_POPUP_TOTALLY_OPENED_LOCATOR = By.xpath(X_POPUP_TOTALLY_OPENED_LOCATOR);
private static final String CLASS_GWT_POPUP_PANEL_GLASS = "gwt-PopupPanelGlass";
private static final By BY_GLASS_PANEL = By.xpath("//div[contains(@class, '" + CLASS_GWT_POPUP_PANEL_GLASS + "')]");
public void waitForPopupOpeningAnimationFinished() {
LOGGER.info("waitForPopupOpeningAnimationFinished");
try {
waiter.withTimeout(Duration.ofMillis(POPUP_ANIMATION_WAIT_TIME)).until(ExpectedConditions.visibilityOfElementLocated(BY_POPUP_TOTALLY_OPENED_LOCATOR));
} catch (TimeoutException e) {
LOGGER.info("Forcing popup to be visible");
try {
js.executeScript("var elementsToBeRemoved = document.getElementsByClassName('" + CLASS_GWT_DIALOG_BOX + "');" //
+ "if(elementsToBeRemoved.length>0){" //
+ "elementsToBeRemoved[0].style.overflow='visible';" //
+ "elementsToBeRemoved[0].style.clip='rect(auto,auto,auto,auto)';" //
+ "}");
} catch (JavascriptException e2) {
LOGGER.warn("Could not find popup to force to be open", e2.getCause());
}
}
}
public void waitForPopupClosingAnimationFinished() {
try {
LOGGER.info("waitForPopupClosingAnimationFinished");
waiter.withTimeout(Duration.ofMillis(POPUP_ANIMATION_WAIT_TIME)).until(ExpectedConditions.invisibilityOfElementLocated(BY_POPUP));
waiter.withTimeout(Duration.ofMillis(POPUP_ANIMATION_WAIT_TIME)).until(ExpectedConditions.invisibilityOfElementLocated(BY_GLASS_PANEL));
} catch (TimeoutException e) {
LOGGER.info("Waiting for popup closing did not work as expected, forcing it");
javascriptRemovalOfElementByClassName(CLASS_GWT_DIALOG_BOX);
javascriptRemovalOfElementByClassName(CLASS_GWT_POPUP_PANEL_GLASS);
}
}
private void javascriptRemovalOfElementByClassName(String className) {
LOGGER.info("javascriptRemovalOfElementByClassName : {}", className);
try {
js.executeScript("var elementsToBeRemoved = document.getElementsByClassName('" + className + "');" //
+ "if(elementsToBeRemoved.length>0){" //
+ "elementsToBeRemoved[0].style.visibility = 'hidden';" //
+ "elementsToBeRemoved[0].style.display = 'none';" //
+ "elementsToBeRemoved[0].className='shouldHaveBeenRemovedFromDom';" //
+ "}");
LOGGER.info("Successfully removal of element with class {}", className);
} catch (JavascriptException jse) {
LOGGER.info("Apparently element with class {}} does not exists, we are good to go : {}", className, jse.toString());
}
}
public void waitForPopupClosingAnimationFinished() {
try {
LOGGER.info("waitForPopupClosingAnimationFinished");
waiter.withTimeout(Duration.ofMillis(POPUP_ANIMATION_WAIT_TIME)).until(ExpectedConditions.invisibilityOfElementLocated(BY_POPUP));
waiter.withTimeout(Duration.ofMillis(POPUP_ANIMATION_WAIT_TIME)).until(ExpectedConditions.invisibilityOfElementLocated(BY_GLASS_PANEL));
} catch (TimeoutException e) {
LOGGER.info("Waiting for popup closing did not work as expected, forcing it");
javascriptRemovalOfElementByClassName(CLASS_GWT_DIALOG_BOX);
javascriptRemovalOfElementByClassName(CLASS_GWT_POPUP_PANEL_GLASS);
}
}
答案 2 :(得分:0)
我在扩展/折叠TreeNode动画时也遇到了同样的问题,因此我实现了以下功能,以便在节点扩展/折叠后启动:
private static final String X_EXPANDING_TREE_NODE =
"//div[contains(@role, 'treeitem') and @aria-expanded='true']/div[contains(@style, 'overflow: hidden;') and contains(@style, 'height:') and contains(@style, 'position: relative;')]/div[contains(@style, 'top:') and contains(@style, 'position: relative;')]";
private static final By BY_EXPANDING_TREE_NODE = By.xpath(X_EXPANDING_TREE_NODE);
private static final String X_COLLAPSING_TREE_NODE =
"//div[contains(@role, 'treeitem') and @aria-expanded='false']/following:div[contains(@style, 'overflow: hidden;') and contains(@style, 'height:') and contains(@style, 'position: relative;')]/div[contains(@style, 'top:') and contains(@style, 'position: relative;')]";
private static final By BY_COLLAPSING_TREE_NODE = By.xpath(X_COLLAPSING_TREE_NODE);
/**
* When a report tree node is expanding or collapsing is loading, we can see stuff like
* <div style="overflow: hidden; height: 1px; position: relative;">
* <div style="top: -122px; position: relative;">
* <p>
* We wait for it do disappear
* <p>
* or we force it to animation finished like this for expanding:
*
* <div style="overflow: hidden;">
* <div style="">
*
* or we force it to animation finished like this for collapsing:
*
* <div style="overflow: hidden; display : none;">
* <div style="">
*/
public void waitForTreeNodeExpandedAndCollapsed() {
waitForTreeNodeExpanded();
waitForTreeNodeCollapsed();
}
public void waitForTreeNodeExpanded(){
waitForTreeNode(true);
}
public void waitForTreeNodeCollapsed(){
waitForTreeNode(false);
}
private void waitForTreeNode(boolean expanding) {
try {
waiter.withTimeout(Duration.ofSeconds(2)).until(ExpectedConditions.invisibilityOfElementLocated(expanding?BY_EXPANDING_TREE_NODE:BY_COLLAPSING_TREE_NODE ));
} catch (TimeoutException e) {
boolean noJavascriptException = false;
while (!noJavascriptException) { // While javascript throw error like InvalidStateError, we continue
try {
LOGGER.info("Waiting for tree expand or collapse did not work as expected, forcing it");
js.executeScript("while(true){" //
+ "var iterator = document.evaluate(\"" + (expanding?X_EXPANDING_TREE_NODE:X_COLLAPSING_TREE_NODE) + "\",document, null, XPathResult.UNORDERED_NODE_ITERATOR_TYPE, null );" //
+ "var thisNode = iterator.iterateNext();" //
+ "if(thisNode) {" //
+ "thisNode.parentNode.style='overflow: hidden;" + (expanding?"":"display: none;") + "';"//
+ "thisNode.style='';"
+ "thisNode = iterator.iterateNext();" //
+ "}else {" //
+ "break;" //
+ "}" //
+ "}");
noJavascriptException = true;
} catch (Exception e2) {
LOGGER.info("Javascript pb", e2.getCause());
}
}
}
}