获取已找到的WebElement的By定位器

问题描述 投票:16回答:5

是否有一种优雅的方式来获取Selenium WebElement的By定位器,我已经找到/识别出来了?

要清楚这个问题:我想要用“定位器”来查找元素。在这种情况下,我对特定属性或特定定位器(如css-locator)不感兴趣。

我知道我可以解析WebElement的toString()方法的结果:

WebElement element = driver.findElement(By.id("myPreciousElement"));
System.out.println(element.toString());

输出将是例如:

[[FirefoxDriver:WINDOWS(....)上的firefox] - > id:myPreciousElement]

如果你通过xpath找到你的元素:

WebElement element = driver.findElement(By.xpath("//div[@someId = 'someValue']"));
System.out.println(element.toString());

然后你的输出将是:

[[FirefoxDriver:WINDOWS(....)上的firefox] - > xpath:// div [@someId ='someValue']]

所以我目前编写了自己的方法来解析这个输出并给我“重新创建”By Locator。

BUT is there a more elegant way already implemented in Selenium to get the By locator used to find the element?

I couldn't find one so far.

如果您确定,没有开箱即用,您能想到API创建者可能无法提供此功能的任何原因吗?

*尽管这与这个问题无关,如果有人想知道为什么你需要这个功能,只需要两个例子:

  • 如果你使用PageFactory,你很可能不会将定位器作为Page类中的成员变量,但是在使用页面元素时可能需要它们。
  • 你正在使用那些只使用没有PageFactory的页面对象模式的人的API,因此希望你交出定位器而不是元素本身。*
java selenium selenium-webdriver pageobjects
5个回答
5
投票

答案是否定的。默认情况下,您无法从以前找到的WebElement中提取By

话虽这么说 - 它可以实现自定义解决方案,但Selenium不提供这种开箱即用的解决方案。

考虑以下内容,关于“为什么”..

By by = By.id("someId");
WebElement e = driver.findElement(by);

你已经拥有了By对象,因此你不需要调用像e.getBy()这样的东西

我可能会在未来实施类似的东西,但没有承诺。再说一次 - 它只是糖。


5
投票

不,没有。我已经实现了一个可能的解决方案作为代理:

public class RefreshableWebElement implements WebElement {

    public RefreshableWebElement(Driver driver, By by) {
        this.driver = driver;
        this.by = by;
    }

    // ...

    public WebElement getElement() {
        return driver.findElement(by);
    }

    public void click() {
        getElement().click();
    }

    // other methods here
}

1
投票

对我来说,与commons-lang3合作

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.7</version>
</dependency>

对于远程Web元素使用方法,如:

protected String getLocator(WebElement element) {
        try {
            Object proxyOrigin = FieldUtils.readField(element, "h", true);
            Object locator = FieldUtils.readField(proxyOrigin, "locator", true);
            Object findBy = FieldUtils.readField(locator, "by", true);
            if (findBy != null) {
                return findBy.toString();
            }
        } catch (IllegalAccessException ignored) {
        }
        return "[unknown]";
    }

0
投票

我编写了这个实用程序函数,它返回定位器策略+定位器值的字符串组合。

private String getLocatorFromWebElement(WebElement element) {

    return element.toString().split("->")[1].replaceFirst("(?s)(.*)\\]", "$1" + "");
}

0
投票

Selenium没有提供优雅的方式。这太可怕了

1)PageObjectPageFactory暗示我们在WebElements类中有Page,但我们没有这些元素的定位器。

2)如果我使用webElement.findElement(By)找到元素作为当前元素的后代,那么即使我将父级的定位符存储在变量中,我也没有这个后代的定位符。

3)如果我使用返回qazxsw poi元素的qazxsw poi函数,那么我没有每个特定元素的定位器。

4)有元素的定位器是有用的,至少因为findElements和定位器作为参数比用List作为参数的ExpectedConditions好得多。

对我来说,Selenium是一个构思错误,实施不佳的图书馆


0
投票

目前,selenium的目的还没有具体的方法。你可以做的是编写自定义方法。只需打印您拥有的webElement,即可获得使用哪种选择器类型和路径的线索。

它看起来像这样

[[ChromeDriver:XP上的chrome(d85e7e220b2ec51b7faf42210816285e)] - > xpath:// input [@ title ='Search']]

现在,您需要做的是提取定位器及其值。你可以尝试这样的事情

`private by getByFromElement(WebElement element){

ExpectedConditions

`

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.