通过在Selenium Webdriver中单独传递对象定位器来查找对象定位器类型的最佳方法

时间:2013-03-06 09:25:45

标签: selenium webdriver

他们是否可以通过单独传递对象定位器来找到对象定位器类型。 例如我需要点击登录按钮,其中id=loginclassname=loginbuttonxpath=//input[@name='login']。我需要构建方法,我将只传递objectlocator(id或name)作为输入,并且它的类型(id或name)应该在方法中决定,如果它包含//那么type应该是of xpath等。

我需要传递objectLocator(),它返回findElement()

的类型
WebElement element = driver.findElement(objectLocator());

5 个答案:

答案 0 :(得分:2)

我认为它不是现成的,你必须实现自己的逻辑。

唯一的问题是,假设你想通过linktext进行搜索。根据您的用例,您可以在对象仓库中指定“这是我的链接文本” 现在你怎么知道它是一个id,一个名字或一个linktext?

对于xpath,您可以检查它是否以/开头,然后是xpath。如果它唯一的id或名称,那么你可以使用ByIdorName,但我认为使用css和linktext会变得棘手。

我能想到的一件事是你可以建立某种约定,比如它是在你的lcoator定义之前的linktext与linktext = blah blah然后你拆分并使用它。

答案 1 :(得分:1)

执行此操作的现代方法是使用PageFactoryPageObjects

以下是一个快速而又脏的方法,它将使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;
    }
}

答案 2 :(得分:1)

我发现将所有定位器存储为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();
}

我也使用其他类的静态Bys:

public void clickLogin() {
   driver.findElement(LoginPage.SUBMIT_BUTTON).click();
}

答案 3 :(得分:0)

看起来您正在寻找此解决方案,因为您在某些属性文件或xml中的代码之外的某个位置维护了对象存储库。

Using gui maps has lot of disadvantages like,

- 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

您正在寻找的是增加一层复杂性,这在我看来并不是必需的。自动化浏览器本身就是一项挑战,编写可维护的测试自动化代码至关重要。

在页面对象中使用PageFactory

- 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

我之前使用过gui地图并且经常苦苦挣扎。切换到页面工厂让我意识到使用对象存储库是一个糟糕的主意!

答案 4 :(得分:0)

这应该用于定位元素。我已经举了三层深的例子。

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