【问题标题】:How Does WebElement.equals() Method Check for Equality?WebElement.equals() 方法如何检查相等性?
【发布时间】:2016-12-24 10:53:51
【问题描述】:

我有超过 1 个 XPath 指向一个 Web 元素,我想确定这两个元素是否等效(即,如果我对两个 Web 元素执行操作 sendKeys() 或 click(),则该操作将在相同的网络元素)目前我正在使用以下方法检查是否相等:

    WebElement element1 = driver.findElement(By.xpath(".//*[@id='ap_email']"));
    WebElement element2 = driver.findElement(By.xpath(".//*[@type='email']"));


    System.out.println(element1.equals(element2));

只要两个 XPath 都指向同一个元素,这将返回 true。

但是,我不确定该方法如何确定相等性?是否存在两个 Web 元素实际上相同的情况(即,对它们执行的任何操作都将在同一个 Web 元素上执行)但方法显示它们不同?还是反过来?

我正在尝试开发一种万无一失的方法来确定两个网络元素是否相等。

我正在使用 Java 和 Selenium。

【问题讨论】:

  • WebElement 是一个接口。您需要确定您拥有的实际对象的类型。然后,您可以在线查找该对象的源代码以查看 equals() 实现

标签: java selenium xpath


【解决方案1】:

但是,我不确定该方法如何确定相等性?

驱动程序为文档中遇到的每个HTMLElement 对象生成一个引用,并始终为HTMLElement 对象返回相同的引用。

此引用存储在客户端的WebElement.id 属性中,与定位器使用的id 属性无关。

因此,要确定两个WebElement 之间的相等性,客户端只需测试存储在WebElement.id 中的引用。

是否存在两种网页元素实际上相同但方法显示它们不同的情况?

从技术上讲,不,它永远不会发生,如果是这样,那将是一个严重的问题。

但这有点取决于您的意思。例如,一个按钮在两个不同的时刻可能看起来相同,但可能已被一个相同的按钮替换,这会生成一个新的参考。重新加载页面或某些部分时会出现这种情况:

  driver.get("http://stackoverflow.com/");

  WebElement elementA = driver.findElement(By.cssSelector("#logo"));
  WebElement elementB = driver.findElement(By.cssSelector("#logo"));

  boolean same1 = elementA.equals(elementB);  // return true

  elementB.click();  // reloads the page, all the previous web element are now obsolete

  WebElement elementC = driver.findElement(By.cssSelector("#logo"));

  boolean same2 = elementA.Equals(elementC);  // return false

【讨论】:

    【解决方案2】:

    以下是实现WebElement接口的RemoteWebElement中的equals实现。

    根据此方法,如果两个元素的 id 相同,则将它们视为相等,其中 id 是从浏览器返回的 findElement 响应。因此,如果我们使用 2 个不同的 xpath 执行 findElement,您可以检查返回响应的元素的 id 属性。如果两个 id 相同,则将它们视为相同元素,否则将它们视为不同元素。

    public boolean equals(Object obj) {
    if (!(obj instanceof WebElement)) {
      return false;
    }
    
    WebElement other = (WebElement) obj;
    while (other instanceof WrapsElement) {
      other = ((WrapsElement) other).getWrappedElement();
    }
    
    if (!(other instanceof RemoteWebElement)) {
      return false;
    }
    
    RemoteWebElement otherRemoteWebElement = (RemoteWebElement) other;
    
    return id.equals(otherRemoteWebElement.id);
    

    }

    【讨论】:

      【解决方案3】:

      RemoteWebElement 是实现 WebElement 的类。 equals 方法比较 id 变量,它是一个字符串。如果您创建两个 WebElement,即使它们指向同一个元素,它们的 id 值也会不同。 Infact id 也用作哈希码。您可以通过打印出两个元素的 id 来检查。

      【讨论】:

      • 谢谢。并非所有 Web 元素都有 ID(例如 Entropay.com 上的用户名和密码字段) RemoteWebElement 在这种情况下如何比较它们?
      • 这与html上的CSS id无关。此 ID 在 RemoteWebElement 类中生成。在此处查看源代码 - grepcode.com/file/repo1.maven.org/maven2/…
      • 您还提到“如果您创建两个 Web 元素,即使它们指向同一个元素,它们的 id 值也会不同”,但情况似乎并非如此。在我之前在主帖中的示例中,有两个完全不同的 Web 元素(element1 和 element2),equals() 方法返回 true。此外,如果 RemoteWebElement 不比较网页上的 HTML/CSS id,那么他们实际上在比较什么。我的意思是他们根据什么决定两个元素相同/不同?
      • 你是对的,他们有相同的 id。所以我猜equals方法即使是由不同的方法创建的也会起作用。
      猜你喜欢
      • 2011-04-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多