通过在SeleniumWebDriver中单独传递对象定位器来查找对象定位器类型的最佳方法
是通过单独传递对象定位器来查找对象定位器类型的任何方法。 例如,我需要单击一个登录按钮,其中的通过在SeleniumWebDriver中单独传递对象定位器来查找对象定位器类型的最佳方法,selenium,webdriver,Selenium,Webdriver,是通过单独传递对象定位器来查找对象定位器类型的任何方法。 例如,我需要单击一个登录按钮,其中的id=login,classname=loginbutton或xpath=//input[@name='login']。我需要构建一个方法,在这个方法中,我将只传递objectlocator(id或名称)作为输入,它的类型(id或名称)应该在方法中确定,比如如果它包含/,那么类型应该是xpath等 我需要将objectLocator()传递给findElement() 我不认为它是现成的,你必须实现你自
id=login
,classname=loginbutton
或xpath=//input[@name='login']
。我需要构建一个方法,在这个方法中,我将只传递objectlocator(id或名称)作为输入,它的类型(id或名称)应该在方法中确定,比如如果它包含/
,那么类型应该是xpath等
我需要将objectLocator()传递给findElement()
我不认为它是现成的,你必须实现你自己的逻辑 唯一的问题是,假设你想通过链接文本进行搜索。根据您的用例,您将在对象repo中指定“这是我的链接文本”。
现在,您如何知道它是一个id、名称或链接文本 对于xpath,您可以检查它是否以/开头,然后是xpath。如果它是唯一的id或名称,那么您可以使用ByIdorName,但我认为使用css和linktext会变得很棘手
我能想到的一件事是,你可以建立一些约定,比如如果它是linktext,在你的lcoator定义之前用linktext=blah blah blah,然后你分割并使用它。我认为它不是现成的,你必须实现你自己的逻辑 唯一的问题是,假设你想通过链接文本进行搜索。根据您的用例,您将在对象repo中指定“这是我的链接文本”。
现在,您如何知道它是一个id、名称或链接文本 对于xpath,您可以检查它是否以/开头,然后是xpath。如果它是唯一的id或名称,那么您可以使用ByIdorName,但我认为使用css和linktext会变得很棘手
我能想到的一件事是,你可以建立一些约定,比如如果它是linktext,在你的lcoator定义之前用linktext=blah blah blah,然后你分割并使用它。实现这一点的现代方法是使用 以下是将selenium定位器字符串适配到WebDriver定位器的快速而肮脏的方法
public enum LocatorType {
CLASSNAME, CSS, ID, LINK, NAME, TAGNAME, XPATH ;
}
public WebElement objectLocator(LocatorType type, String ref) {
switch(type) {
case ID:
return this.webDriver.findElement(By.id(ref));
case CLASSNAME:
return this.webDriver.findElement(By.className(ref));
case XPATH:
return this.webDriver.findElement(By.xpath(ref));
case CSS:
return this.webDriver.findElement(By.cssSelector(ref));
case LINK:
return this.webDriver.findElement(By.linkText(ref));
case NAME:
return this.webDriver.findElement(By.name(ref));
case TAGNAME:
return this.webDriver.findElement(By.tagName(ref));
}
return null;
}
public WebElement objectLocator(String identifier) {
String typeString = identifier.substring(0, identifier.indexOf('='));
String ref = identifier.substring(identifier.indexOf('=')+1, identifier.length());
if (typeString.toLowerCase().contains("classname")) {
return objectLocator(LocatorType.CLASSNAME, ref);
} else if (typeString.toLowerCase().contains("css")) {
return objectLocator(LocatorType.CSS, ref);
} else if (typeString.toLowerCase().contains("id")) {
return objectLocator(LocatorType.ID, ref);
} else if (typeString.toLowerCase().contains("link")) {
return objectLocator(LocatorType.LINK, ref);
} else if (typeString.toLowerCase().contains("name")) {
return objectLocator(LocatorType.NAME, ref);
} else if (typeString.toLowerCase().contains("tagname")) {
return objectLocator(LocatorType.TAGNAME, ref);
} else if (typeString.toLowerCase().contains("xpath")) {
return objectLocator(LocatorType.XPATH, ref);
} else {
return null;
}
}
实现这一点的现代方法是使用和 以下是将selenium定位器字符串适配到WebDriver定位器的快速而肮脏的方法
public enum LocatorType {
CLASSNAME, CSS, ID, LINK, NAME, TAGNAME, XPATH ;
}
public WebElement objectLocator(LocatorType type, String ref) {
switch(type) {
case ID:
return this.webDriver.findElement(By.id(ref));
case CLASSNAME:
return this.webDriver.findElement(By.className(ref));
case XPATH:
return this.webDriver.findElement(By.xpath(ref));
case CSS:
return this.webDriver.findElement(By.cssSelector(ref));
case LINK:
return this.webDriver.findElement(By.linkText(ref));
case NAME:
return this.webDriver.findElement(By.name(ref));
case TAGNAME:
return this.webDriver.findElement(By.tagName(ref));
}
return null;
}
public WebElement objectLocator(String identifier) {
String typeString = identifier.substring(0, identifier.indexOf('='));
String ref = identifier.substring(identifier.indexOf('=')+1, identifier.length());
if (typeString.toLowerCase().contains("classname")) {
return objectLocator(LocatorType.CLASSNAME, ref);
} else if (typeString.toLowerCase().contains("css")) {
return objectLocator(LocatorType.CSS, ref);
} else if (typeString.toLowerCase().contains("id")) {
return objectLocator(LocatorType.ID, ref);
} else if (typeString.toLowerCase().contains("link")) {
return objectLocator(LocatorType.LINK, ref);
} else if (typeString.toLowerCase().contains("name")) {
return objectLocator(LocatorType.NAME, ref);
} else if (typeString.toLowerCase().contains("tagname")) {
return objectLocator(LocatorType.TAGNAME, ref);
} else if (typeString.toLowerCase().contains("xpath")) {
return objectLocator(LocatorType.XPATH, ref);
} else {
return null;
}
}
我发现将所有定位器存储为By对象非常有用,可以直接使用By,也可以根据需要将By传递到方法中。例如:
By passwordField= By.id("login");
By userNameField = By.name("username");
By submitButton = By.xpath("\\myxpath\div[2]");
public void clickLogin() {
driver.findElement(submitButton).click();
}
我还使用其他类的静态BY:
public void clickLogin() {
driver.findElement(LoginPage.SUBMIT_BUTTON).click();
}
我发现将所有定位器存储为By对象非常有用,可以直接使用By,也可以根据需要将By传递到方法中。例如:
By passwordField= By.id("login");
By userNameField = By.name("username");
By submitButton = By.xpath("\\myxpath\div[2]");
public void clickLogin() {
driver.findElement(submitButton).click();
}
我还使用其他类的静态BY:
public void clickLogin() {
driver.findElement(LoginPage.SUBMIT_BUTTON).click();
}
看起来您正在寻找这个解决方案,因为您在某种属性文件或xml中的代码之外维护了一个对象存储库
使用gui映射有很多缺点,比如,
- maintain an external file with a list of locators
- parse locator files to read keys (you can abstract this but still an overhead)
- when writing PageObjects you need to switch back and forth from Page to gui map
- possibility of multiple duplicate locators in gui maps
- object repo grows over time and becomes impossible to maintain
- debugging is far more difficult
你想要的是增加一层复杂性,这在我看来是不必要的。自动化浏览器本身就是一个挑战,编写可维护的测试自动化代码至关重要
在页面对象中使用
- Natural place for your locators are Page Objects themselves.
- Locators easily accessible in page objects for review or correction
- No need for explicit driver.findElement, with @FindBy you get that for free
- modern Java and awesome annotations make page objects look beautiful & readable
我以前使用过图形用户界面地图,并为此付出了很多努力。切换到PageFactory让我意识到使用对象存储库是个糟糕的主意 看起来您正在寻找此解决方案,因为您在某种属性文件或xml中的代码之外维护了一个对象存储库
使用gui映射有很多缺点,比如,
- maintain an external file with a list of locators
- parse locator files to read keys (you can abstract this but still an overhead)
- when writing PageObjects you need to switch back and forth from Page to gui map
- possibility of multiple duplicate locators in gui maps
- object repo grows over time and becomes impossible to maintain
- debugging is far more difficult
你想要的是增加一层复杂性,这在我看来是不必要的。自动化浏览器本身就是一个挑战,编写可维护的测试自动化代码至关重要
在页面对象中使用
- Natural place for your locators are Page Objects themselves.
- Locators easily accessible in page objects for review or correction
- No need for explicit driver.findElement, with @FindBy you get that for free
- modern Java and awesome annotations make page objects look beautiful & readable
我以前使用过图形用户界面地图,并为此付出了很多努力。切换到PageFactory让我意识到使用对象存储库是个糟糕的主意 这应该可以定位元素。我已经给出了3层深的例子
public WebElement findElement(String locator){
WebElement w = null;
try{
return (driver.findElement(By.id(locator)));
}catch(Exception e1){
try{
return ( driver.findElement(By.name(locator)));
}catch(Exception e2){
try{
return (driver.findElement(By.xpath(locator)));
}catch(Exception e3){
System.out.println("Cound not find a locator");
e3.printStackTrace();
}
}
}
return(w);
}
public void type(String locator, String value){
try{
WebElement w= findElement(locator);
w.sendKeys(""+value);
Thread.sleep(sleepTime);
}catch(Exception e){
e.printStackTrace();
}
}
-Vinay这应该用于定位元件。我已经给出了3层深的例子
public WebElement findElement(String locator){
WebElement w = null;
try{
return (driver.findElement(By.id(locator)));
}catch(Exception e1){
try{
return ( driver.findElement(By.name(locator)));
}catch(Exception e2){
try{
return (driver.findElement(By.xpath(locator)));
}catch(Exception e3){
System.out.println("Cound not find a locator");
e3.printStackTrace();
}
}
}
return(w);
}
public void type(String locator, String value){
try{
WebElement w= findElement(locator);
w.sendKeys(""+value);
Thread.sleep(sleepTime);
}catch(Exception e){
e.printStackTrace();
}
}
-Vinay这没有任何意义……为什么要传入id、类和xpath值?您的代码如何决定使用哪一个?如果您有这些值中的任何一个,为什么不能像正常情况一样将它们传递到
.findElement()
方法中?我维护一个对象存储库,其中包含逻辑名称及其定位器,最终用户将仅使用定位器更新对象repo,我的代码应该具有决定其类型的智能。他们有办法吗?这太过分了。不要这样做。使用PageFactory!这没有任何意义……为什么要传入id、类和xpath值?您的代码如何决定使用哪一个?如果您有这些值中的任何一个,为什么不能像正常情况一样将它们传递到.findElement()
方法中?我维护一个对象存储库,其中包含逻辑名称及其定位器,最终用户将仅使用定位器更新对象repo,我的代码应该具有决定其类型的智能。他们有办法吗?这太过分了。不要这样做。使用PageFactory!嗯。。就连我现在的想法都是一样的。。只是想知道有没有更好的方法…-)耶。。就连我现在的想法都是一样的。。我只是想知道有什么更好的方法:-)通过对象添加到Java集合(如HashMap或TreeMap)是灵活而强大的工具。通过对象添加到Java集合(如HashMap或TreeMap)也是灵活而强大的工具。