Selenium中视口元素的验证

11

如何使用Selenium验证元素是否在浏览器视窗(viewport)中可见?

我尝试了以下代码,但是由于页面可以滚动,Point对象(Y值)返回巨大的值。我正在获取元素的尺寸、位置和浏览器的尺寸,并进行比较。

Dimension weD = element.getSize(); //to get the element Dimensions
Point weP = element.getLocation(); // getting the location of the element in the page.

Dimension d = driver.manage().window().getSize(); // To get the browser dimensions
int x = d.getWidth(); //browser width
int y = d.getHeight(); //browser height
int x2 = weD.getWidth() + ewp.getX();
int y2 = weD.getHeight() + ewp.getY();
return x2 <= x && y2 <= y; 

如果有人已经解决了这个问题,你能分享一下解决方案吗?

4个回答

22

直接通过API不可能实现,因此您需要使用脚本注入。

确定元素是否在视口中可见的最佳方法是使用 document.elementFromPoint 获取应该位于该位置的元素。如果它不在视口内,则返回null,如果在视口内,则返回您的元素或其后代。

public static Boolean isVisibleInViewport(WebElement element) {
  WebDriver driver = ((RemoteWebElement)element).getWrappedDriver();

  return (Boolean)((JavascriptExecutor)driver).executeScript(
      "var elem = arguments[0],                 " +
      "  box = elem.getBoundingClientRect(),    " +
      "  cx = box.left + box.width / 2,         " +
      "  cy = box.top + box.height / 2,         " +
      "  e = document.elementFromPoint(cx, cy); " +
      "for (; e; e = e.parentElement) {         " +
      "  if (e === elem)                        " +
      "    return true;                         " +
      "}                                        " +
      "return false;                            "
      , element);
}

1
谢谢Florent B.,它帮助我验证了视口中的元素。 - Madhu Velpuri
不幸的是,它并不总是准确的,因为它只关注元素中间部分而不是顶部。 - dicle
1
@dicle,如果元素的中心可见,则认为该元素可见。如果您想确保元素完全可见,请检查四个角落。 - Florent B.

5

感谢Florent B.的贡献。 转换为Python:

def is_element_visible_in_viewpoint(driver, element) -> bool:
    return driver.execute_script("var elem = arguments[0],                 " 
                                 "  box = elem.getBoundingClientRect(),    " 
                                 "  cx = box.left + box.width / 2,         " 
                                 "  cy = box.top + box.height / 2,         " 
                                 "  e = document.elementFromPoint(cx, cy); " 
                                 "for (; e; e = e.parentElement) {         " 
                                 "  if (e === elem)                        " 
                                 "    return true;                         " 
                                 "}                                        " 
                                 "return false;                            "
                                 , element)

2
感谢Florent B.和Ben Moskovitch。转换为c#:
private bool IsVisibleInViewport(IWebElement element) => (bool)((IJavaScriptExecutor)_webDriver).ExecuteScript("var elem = arguments[0], box = elem.getBoundingClientRect(), cx = box.left + box.width / 2,  cy = box.top + box.height / 2,  e = document.elementFromPoint(cx, cy); for (; e; e = e.parentElement) { if (e === elem) return true;} return false;", element);

其中_webDriver是与此方法相同类中的WebDriver


0

您可以随时检查元素的yth位置

yth = int(driver.execute_script("return document.querySelector('{el_selector}').getBoundingClientRect()".format(el_selector=el_selector)))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接