Java 获取已找到的 WebElement 的 By 定位器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31676964/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Get the By locator of an already found WebElement
提问by drkthng
Is there an elegant way to get the By locator of a Selenium WebElement, that I already found/identified?
有没有一种优雅的方法来获取我已经找到/识别的 Selenium WebElement 的定位器?
To be clear about the question: I want the "By locator" as used to find the element. I am in this case notinterested in a specific attribute or a specific locator like the css-locator.
要清楚这个问题:我想要用于查找元素的“按定位器”。在这种情况下,我对特定属性或特定定位器(如 css-locator)不感兴趣。
I know that I could parse the result of a WebElement's toString() method:
我知道我可以解析 WebElement 的 toString() 方法的结果:
WebElement element = driver.findElement(By.id("myPreciousElement"));
System.out.println(element.toString());
Output would be for example:
输出将是例如:
[[FirefoxDriver: firefox on WINDOWS (....)] -> id: myPreciousElement]
[[FirefoxDriver: firefox on WINDOWS (....)] -> id: myPreciousElement]
if you found your element by xpath:
如果您通过 xpath 找到您的元素:
WebElement element = driver.findElement(By.xpath("//div[@someId = 'someValue']"));
System.out.println(element.toString());
Then your output will be:
那么你的输出将是:
[[FirefoxDriver: firefox on WINDOWS (....)] -> xpath: //div[@someId = 'someValue']]
[[FirefoxDriver: firefox on WINDOWS (....)] -> xpath: //div[@someId = 'someValue']]
So I currently wrote my own method that parses this output and gives me the "recreated" By locator.
因此,我目前编写了自己的方法来解析此输出并为我提供“重新创建”的定位器。
BUTis there a more elegant way already implemented in Selenium to get the By locator used to find the element?
但是,在 Selenium 中是否已经实现了一种更优雅的方法来获取用于查找元素的 By 定位器?
我至今找不到一个。If you are sure, there is none out of the box, can you think of any reason why the API creators might not provide this functionality?
如果您确定没有开箱即用的功能,您能想到 API 创建者可能不提供此功能的任何原因吗?
*Despite the fact that this has nothing to do with the question, if someone wonders why you would ever need this functionality, just 2 examples:
*尽管这与问题无关,但如果有人想知道您为什么需要此功能,只需举两个示例:
- if you use PageFactory you most likely will not have the locators as as member variables in your Page class, but you might need them later on when working with the page's elements.
- you're working with APIs of people who just use the Page Object Pattern without PageFactory and thus expect you to hand over locators instead of the element itself.*
- 如果您使用 PageFactory,您很可能不会将定位器作为 Page 类中的成员变量,但稍后在处理页面元素时可能需要它们。
- 你正在使用那些只使用页面对象模式而不使用 PageFactory 的人的 API,因此希望你交出定位器而不是元素本身。*
采纳答案by ddavison
Answer is No. You cannot extract a By
from a previously found WebElement by default.
答案是否定的。By
默认情况下,您无法从以前找到的 WebElement 中提取 a 。
That being said - it's possible to implement a custom solution, but Selenium does not offer this out-of-the-box.
话虽如此 - 可以实现自定义解决方案,但 Selenium 不提供这种开箱即用的解决方案。
Consider the following, on "why"..
考虑以下,关于“为什么”..
By by = By.id("someId");
WebElement e = driver.findElement(by);
you already have the By
object, so you wouldn't need to call something like e.getBy()
你已经有了这个By
对象,所以你不需要调用类似的东西e.getBy()
回答by Zymus
No, there's not. I have implemented a possible solution as a proxy:
不,没有。我已经实现了一个可能的解决方案作为代理:
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
}
回答by alexloiko
For me worked with commons-lang3
对我来说,与 commons-lang3 一起工作
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.7</version>
</dependency>
For remote web element use method like:
对于远程 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]";
}
回答by Akash jain
I had written this utility function which returns a string combination of locator strategy + locator value.
我编写了这个实用函数,它返回定位器策略 + 定位器值的字符串组合。
private String getLocatorFromWebElement(WebElement element) {
return element.toString().split("->")[1].replaceFirst("(?s)(.*)\]", "" + "");
}
回答by zer_ik
There is no elegant way provided by Selenium. And this is horrible
Selenium 没有提供优雅的方式。这太可怕了
1) PageObject
and PageFactory
implies that we have WebElements
in Page
classes, but we don't have locators of those elements.
1)PageObject
并PageFactory
暗示我们WebElements
在Page
类中有,但我们没有这些元素的定位器。
2) If I find element as descendant of current element using webElement.findElement(By)
, then I don't have the locator of this descendant even if I stored parent's locator in the variable.
2)如果我使用 找到元素作为当前元素的后代webElement.findElement(By)
,那么即使我将父元素的定位器存储在变量中,我也没有这个后代的定位器。
3) If I use findElements
function that returns List
of elemetns, then I don't have locator for each specific element.
3)如果我使用findElements
返回List
elemetns的函数,那么我没有每个特定元素的定位器。
4) Having locator for element is useful at least because ExpectedConditions
with locator as parameter are much better implemented than ExpectedConditions
with WebElement
as parameter.
4)具有定位器元件是至少有用的,因为ExpectedConditions
与定位器参数被大大优于实现ExpectedConditions
与WebElement
作为参数。
For me Selenium is ill-conceived and poorly implemented library
对我来说,Selenium 是一个构思拙劣且执行不力的库
回答by Sayantan Dey
Currently there is no specific method from selenium's end to do so. What you can do is write your custom method. You will get the clue of what selector type and path is used by just printing the webElement you have.
目前,selenium 还没有具体的方法可以做到这一点。您可以做的是编写自定义方法。只需打印您拥有的 webElement,您就可以获得使用何种选择器类型和路径的线索。
It looks something like this
它看起来像这样
[[ChromeDriver: chrome on XP (d85e7e220b2ec51b7faf42210816285e)] -> xpath: //input[@title='Search']]
[[ChromeDriver: chrome on XP (d85e7e220b2ec51b7faf42210816285e)] -> xpath: //input[@title='Search']]
Now, what you need to do is to extract the locator and its value. You can try something like this
现在,您需要做的是提取定位器及其值。你可以试试这样的
`private By getByFromElement(WebElement element) {
`private By getByFromElement(WebElement element) {
By by = null;
//[[ChromeDriver: chrome on XP (d85e7e220b2ec51b7faf42210816285e)] -> xpath: //input[@title='Search']]
String[] pathVariables = (element.toString().split("->")[1].replaceFirst("(?s)(.*)\]", "" + "")).split(":");
String selector = pathVariables[0].trim();
String value = pathVariables[1].trim();
switch (selector) {
case "id":
by = By.id(value);
break;
case "className":
by = By.className(value);
break;
case "tagName":
by = By.tagName(value);
break;
case "xpath":
by = By.xpath(value);
break;
case "cssSelector":
by = By.cssSelector(value);
break;
case "linkText":
by = By.linkText(value);
break;
case "name":
by = By.name(value);
break;
case "partialLinkText":
by = By.partialLinkText(value);
break;
default:
throw new IllegalStateException("locator : " + selector + " not found!!!");
}
return by;
}
`
`