Java 如何获取当前web元素的定位器?
需求是获取当前web元素的定位器(By) 对于我的项目,我正在实现自定义元素。因此,对于HTML选择元素,将有一个类SelectElement,对于HTML选项元素,将有一个类OptioneElement 要实现自定义元素,我使用此存储库中的Java 如何获取当前web元素的定位器?,java,selenium,selenium-webdriver,Java,Selenium,Selenium Webdriver,需求是获取当前web元素的定位器(By) 对于我的项目,我正在实现自定义元素。因此,对于HTML选择元素,将有一个类SelectElement,对于HTML选项元素,将有一个类OptioneElement 要实现自定义元素,我使用此存储库中的CustomWebElement类: 我想检索selectElementInstance.getOptions(),它应该返回List而不是List 下面是我想做的: 1) 我正在使用findElements(…)方法获取List 2) 在这个列表中,我逐一
CustomWebElement
类:
我想检索selectElementInstance.getOptions()
,它应该返回List
而不是List
下面是我想做的:
1) 我正在使用findElements(…)
方法获取List
2) 在这个列表中,我逐一迭代元素
3) 无论我得到哪个WebElement
,我都希望为此元素检索By的实例
4) 有了By instance和WebDriver
实例,我可以使用构造函数super(WebDriver-driver,By)
创建自定义元素
下面我给出了我的代码示例:
List<WebElement> myList = driver.findElement(By.xpath("//select[@id ='abcd']/*"));
ListIterator<WebElement> simpleChildIterator = myList.listIterator();
List<OptionElement> options = new ArrayList<OptionElement>();
while(simpleChildIterator.hasNext())
{
By l = simpleChildIterator.next().getBy();//I want locator for same element
//Here I can now create Instance of OptionElement to add to List<OptionElement>
OptionElement o = new OptionElement(driver, l);
options.add(o);
}
但这之所以有效,是因为PageFactory的神奇之处在于它的initElements()
调用
当我愿意在我的SelectElement
类上定义一个新方法List getOptions()
时,我希望在没有PageFactory参与的情况下也能使用同样的方法
我希望问题已经清楚了,因为我已经做了几次编辑
感谢@Muzzamil建议WebDriver应该是singleton。我已经从我的问题中删除了这一点。还感谢@Pranav用select和option元素举例说明我的问题。这是一个更好的例子来解释。好的,这里有一个非常脏的解决方案-请不要在生产中使用它,而只是作为您具体问题的想法: 因此,首先可以为web驱动程序创建类:
public class WebDr {
private ChromeDriver driver;
public WebDr(ChromeDriver driver) {
this.driver = driver;
}
public void get(final String url) {
this.driver.get(url);
}
public WebEl getElem(By by) {
return new WebEl(driver.findElement(by), this.driver);
}
}
另外,这里是WebElement的类:
public class WebEl {
private WebElement elem;
private WebDriver driver;
public WebEl(WebElement elem, WebDriver driver) {
this.elem = elem;
this.driver = driver;
}
public WebDriver getDriver() {
return this.driver;
}
}
最后,在代码中,您可以执行以下类似操作:
public class MainCl {
public static void main(String[] args) throws Exception {
System.setProperty("webdriver.chrome.driver", "C:\\***\\chromedriver.exe");
WebDr driver = new WebDr(new ChromeDriver());
driver.get("https://www.google.com/");
Thread.sleep(5000);
WebEl myElem = driver.getElem(By.name("q"));
System.out.println(myElem.getDriver());
}
}
当然,对于WebEl列表也可以这样做。好的,这里有一个非常肮脏的解决方案-请不要在生产中使用它,而只是作为您具体问题的想法: 因此,首先可以为web驱动程序创建类:
public class WebDr {
private ChromeDriver driver;
public WebDr(ChromeDriver driver) {
this.driver = driver;
}
public void get(final String url) {
this.driver.get(url);
}
public WebEl getElem(By by) {
return new WebEl(driver.findElement(by), this.driver);
}
}
另外,这里是WebElement的类:
public class WebEl {
private WebElement elem;
private WebDriver driver;
public WebEl(WebElement elem, WebDriver driver) {
this.elem = elem;
this.driver = driver;
}
public WebDriver getDriver() {
return this.driver;
}
}
最后,在代码中,您可以执行以下类似操作:
public class MainCl {
public static void main(String[] args) throws Exception {
System.setProperty("webdriver.chrome.driver", "C:\\***\\chromedriver.exe");
WebDr driver = new WebDr(new ChromeDriver());
driver.get("https://www.google.com/");
Thread.sleep(5000);
WebEl myElem = driver.getElem(By.name("q"));
System.out.println(myElem.getDriver());
}
}
当然,对于WebEl列表也可以这样做。所以基本上您需要
中的元素。您可以尝试以下方法:
private By getByFromElement(WebElement element) {
By by = null;
String[] selectorWithValue= (element.toString().split("->")[1].replaceFirst("(?s)(.*)\\]", "$1" + "")).split(":");
String selector = selectorWithValue[0].trim();
String value = selectorWithValue[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;
}
所以基本上你需要By
element fromwebElement
。您可以尝试以下方法:
private By getByFromElement(WebElement element) {
By by = null;
String[] selectorWithValue= (element.toString().split("->")[1].replaceFirst("(?s)(.*)\\]", "$1" + "")).split(":");
String selector = selectorWithValue[0].trim();
String value = selectorWithValue[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;
}
用例到底是什么?根据WebElement的说法,并没有这样的方法,因为元素并没有绑定到某个特定的驱动程序。但您可能要做的是以某种方式创建一些实现默认WebElement的类。这是否回答了您的问题@Muzzamil我想获取当前元素的驱动程序和定位器,如果我能够获得它,我必须使用反射API创建子类的新实例。我仍然会问为什么需要webElement的驱动程序实例?按照我的观点,没有必要获取驱动程序实例,因为通常我们只保留单个驱动程序实例。此外,您可以使用Singleton设计模式获取单个驱动程序实例,这样您就可以使用公共驱动程序实例,因为它每次都是单个实例,不需要从webElement获取。具体的用例是什么?根据webElement的说法,没有这样的方法,因为元素没有绑定到特定的驱动程序。但您可能要做的是以某种方式创建一些实现默认WebElement的类。这是否回答了您的问题@Muzzamil我想获取当前元素的驱动程序和定位器,如果我能够获得它,我必须使用反射API创建子类的新实例。我仍然会问为什么需要webElement的驱动程序实例?按照我的观点,没有必要获取驱动程序实例,因为通常我们只保留单个驱动程序实例。此外,您可以使用Singleton设计模式获取单个驱动程序实例,这样您就可以使用公共驱动程序实例,因为它每次都是单个实例,不需要从webElement获取。如果它符合您的目的,您可以接受它作为答案。它可以帮助将来有类似问题的人。如果它符合你的目的,你可以接受它作为答案。它可以帮助将来有类似问题的人。