简体   繁体   English

在这种情况下如何返回WebElement

[英]How to return a WebElement in this scenario

I wanted to utilize page objects and following is what i am looking at: 我想利用页面对象,以下是我正在查看的内容:

I have created a package 'pageObjects' and created a class 'HomePage' with element like below: 我创建了一个包'pageObjects'并创建了一个类'HomePage',其元素如下所示:

public class HomePage 
{
    private static WebElement element=null;

    public static WebElement txt_UserName(WebDriver driver)
    {
        element=driver.findElement(By.name("userName"));
        return element;
    }
}

Here in my Test Case, when i use HomePage.txt_UserName(driver).sendKeys("uday") lets enter the username as "Uday". 在我的测试用例中,当我使用HomePage.txt_UserName(driver).sendKeys("uday") ,请输入用户名“ Uday”。 This works perfect. 这很完美。

But what i need to implement above in a method like enterValue("HomePage.txt_UserName","Uday") 但是我需要在上面像enterValue(“ HomePage.txt_UserName”,“ Uday”)这样的方法中实现

public void enterValue(String strObjID,String strValue)
{
  //How should i use the above parameter here?? Something like below should work
  strObjID(driver).sendKeys(strValue);

}

Based on your comment I think you should not write a generic cucumber step definition which handle all types of input fields. 根据您的评论,我认为您不应编写处理所有类型输入字段的通用黄瓜步骤定义。 This makes it very hard to read and understand your feature files. 这使得很难阅读和理解功能文件。 Writing HTML ID or CSS selector into your HTML does not fulfil BDD because you write requirements at first and because of this you can not know which IDs you are using. 将HTML ID或CSS选择器写入HTML不能满足BDD的要求,因为您一开始就编写了要求,因此您无法知道所使用的ID。 Look at the principles of BDD . 看一下BDD原理

Remember, that the purpose of a feature file is to link a requirement, written as user story, to your test code. 请记住,功能文件的目的是将以用户故事形式编写的需求链接到测试代码。 So write your feature files like your user stories. 因此,请像您的用户故事一样编写功能文件。 For example: 例如:

Given I loaded the home page
When I enter my username <username>
And I enter my password <password>
And I press the login in button
Then I should be redirected to <some url>

Based on that, you should implement the page object pattern thoroughly. 基于此,您应该彻底实现页面对象模式 Here is an example: 这是一个例子:

public class HomePage {
    private final WebElement usernameElement;
    // declare more page elements here

    public HomePage(WebDriver driver) {
        usernameElement = driver.findElement(By.name("userName"));
        // init more page elements here
    }

    public void enterUsername(String username) {
        usernameElement.sendKeys(username)
    }

    // more handler here: e.g. public void enterPassword(String password) ...
}

In your cucumber step definition you can then use the page object: 在黄瓜步骤定义中,您可以使用页面对象:

@Then("^I enter my username \"(.+)\"$")
public void I_enter_my_username(String username) {
    homepage.enterUsername(username);
}

This pattern allows a good understanding of your feature files and how they are connected to your test code. 通过此模式,您可以很好地了解功能文件以及它们如何与测试代码连接。

Please don't make a generic function. 请不要执行一般功能。 If your form has 50 elements, you will have to deal with all 50 at some point anyway. 如果您的表单有50个元素,那么无论如何您都必须处理所有50个元素。 The better practice is to put all the code in the page object rather than the test case script. 更好的做法是将所有代码放在页面对象中,而不是在测试用例脚本中。 You should not require a consumer (script writer) to have knowledge of the HTML of the page. 您不应该要求使用者(脚本编写者)具有页面HTML的知识。 They should be able to call a simple function like login(username, password) ... not enterValue("some crazy XPath", "my name") and enterValue("some other crazy XPath", "my password") . 他们应该能够调用一个简单的函数,例如login(username, password) ...而不是enterValue("some crazy XPath", "my name")enterValue("some other crazy XPath", "my password") People that come along later are not going to be able to tell what each line does which will make debugging much harder and more time consuming. 后来的人们将无法分辨每条线的工作,这将使调试变得更加困难和耗时。

I agree with Schrieveslaach but I would take a slightly different approach. 我同意Schrieveslaach,但我会采取略有不同的方法。 I would say that you should bundle the elements into actions that a user would perform on the page. 我要说的是,您应该将元素捆绑为用户将在页面上执行的操作。 For example, instead of enterUsername() and enterPassword() and clickLogin() , use login(username, password) that fills in the username and password and clicks the login button. 例如,不是使用enterUsername()enterPassword()clickLogin()clickLogin()使用login(username, password)填写用户名和密码,然后单击登录按钮。 That will simplify the API of your page object and only expose necessary actions. 这将简化页面对象的API,并且仅公开必要的操作。 Who is going to fill in a username but not a password? 谁来填写用户名而不是密码? There will be times where you will want to fill in some fields but not others, maybe for negative testing, in those cases you can pass in empty string for some fields and accomplish this. 有时候,您可能希望填写某些字段,而不要填写其他字段,也许是为了进行负面测试,在这种情况下,您可以为某些字段传递空字符串并完成此操作。

Don't deal with WebElements or XPaths outside PageObjects. 不要处理PageObjects之外的WebElement或XPath。 The purpose of a pageobject is to encapsulate all the page identifier complexity and return user friendly outputs. 页面对象的目的是封装所有页面标识符的复杂性并返回用户友好的输出。 You should be able to call a simple action like login("username", "password") without ever dealing with Xpaths, CSS selectors outside. 您应该能够调用诸如login(“ username”,“ password”)之类的简单操作,而无需处理外部的Xpath和CSS选择器。

If you're looking to wrap some of Selenium's more complex functions (getDriver, etc), use an AbstractPageObject to provide more generic functions which all the PageObjects inherit from, or make static functions in a common class. 如果要包装Selenium的一些更复杂的函数(getDriver等),请使用AbstractPageObject提供所有PageObjects继承的更通用的函数,或在一个通用类中创建静态函数。

If you are interacting with a large number of identifiers on your pageObject, and this is undesirable, you have a few different ways of dealing with this: 如果您正在与pageObject上的大量标识符进行交互,而这是不希望的,那么您可以通过几种不同的方式来处理:

1) Split your page object up into smaller page objects 1)将页面对象拆分为较小的页面对象

Page objects do not have to represent a single webpage, so much as a collection of related elements on a page. 页面对象不必代表单个网页,就像页面上相关元素的集合一样。 Your menu could be a single pageobject, or a table. 您的菜单可以是单个页面对象,也可以是一个表。 If you wish to represent the hierarchy you can include it as an public object on the parent page, eg: 如果希望表示层次结构,则可以将其作为公共对象包含在父页面上,例如:

public class HomepageObject {

    public MenuPageObject menuPageObject;

    private By element1 = By.id("element-1");
    private By element2 = By.id("element-2");

    public void clickElement1() {
        click(element1);
    }

    ...

}

That way you can access the menu by using eg: 这样,您可以使用以下命令访问菜单:

 homepage.menuPageObject.clickStuff() 

The other advantage this has if you have repeated elements on lots of pages, you don't have to keep on including them! 如果您在许多页面上重复了元素,那么这还有另一个好处,您不必继续添加它们!

2) Make your identifiers more generic 2)使您的标识符更通用

Alternatively, your elements may be similar, and you can refer to them by a single identifier. 或者,您的元素可能相似,您可以通过单个标识符来引用它们。 The following snippet of code deals with a potentially large list of stuff which share similar IDs. 下面的代码片段处理的是共享相似ID的潜在清单。 I've used Java 8 streams in this example, but you can just use a foreach loop if you find it easier. 在此示例中,我使用了Java 8流,但是如果发现更简单,则可以使用foreach循环。

    private By displayedStuff = By.cssSelector("p[id^='stuff-number-']");

    public Optional<String> getStuff(String stuffText){

         // get a list of the elements
         List<WebElement> stuffList = getDriver().findElements(displayedStuff)

         // return the element text which matches stuffText
         return stuffList.stream()
              .map(e -> e.getText())
              .filter(e -> e.contains(stuffText))
              .findFirst();
    }

Your stufflist could be anything: buttons, tables, dropdowns.. there is probably a lot of repetition on your page if you've got that number of elements. 您的填充列表可以是任何东西:按钮,表格,下拉列表..如果您具有该数量的元素,则页面上可能会有很多重复。 Unless your developers are handcoding 100 unique elements too? 除非您的开发人员也手动编码100个独特元素?

3) Consider cutting down the number of elements you have on a page. 3)考虑减少页面上的元素数量。

If you don't want to deal with 100 different elements, consider how your users might feel! 如果您不想处理100个不同的元素,请考虑用户的感受!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM