使用 JAVA 数组或列表填充由 Selenium 页面对象模型设计的页面上的文本框

Using JAVA array or list to fill text boxes on a page designed by Selenium Page Object Model

package com.objects;
import java.util.ArrayList;
import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.How;
import org.openqa.selenium.support.PageFactory;
import com.tests.BaseClass;

public class LinkedInHomePage extends BaseClass {

public LinkedInHomePage(WebDriver driver) {
    PageFactory.initElements(driver, this);
}

@FindBy(how = How.ID, using = "firstName-coldRegistrationForm")
public WebElement newFirstNameTexthBox;

@FindBy(how = How.NAME, using = "lastName")
public WebElement newLastNameTexthBox;

@FindBy(how = How.ID, using = "email-coldRegistrationForm")
public WebElement newEmailTexthBox;

@FindBy(how = How.ID, using = "password-coldRegistrationForm")
public WebElement newPasswordTexthBox;

@FindBy(how = How.ID, using = "btn-submit")
public WebElement signUpButton;

public void EnterNewFirstName(String inComingNewFirstName) {
    newFirstNameTexthBox.clear();
    newFirstNameTexthBox.sendKeys(inComingNewFirstName);
}

public void EnterNewLastName(String inComingNewLastName) {
    newLastNameTexthBox.clear();
    newLastNameTexthBox.sendKeys(inComingNewLastName);
}

public void EnterNewEmail(String inComingNewEmail) {
    newEmailTexthBox.clear();
    newEmailTexthBox.sendKeys(inComingNewEmail);
}

public void EnterNewPassword(String inComingNewPassword) {
    newPasswordTexthBox.clear();
    newPasswordTexthBox.sendKeys(inComingNewPassword);
}

public void ClickSignUp() {
    signUpButton.click();
}

public void JoinNow(String FName, String LName, String Email,
        String Password) {
    EnterNewFirstName(FName);
    EnterNewLastName(LName);
    EnterNewEmail(Email);
    EnterNewPassword(Password);
    ClickSignUp();
}

}

如您所见,上面的 JoinNow() 函数采用多个参数,并且运行良好。我想使用数组或列表来减少 参数的数量,然后使用循环来填充文本框。我想完成类似下面的事情,但是因为我使用的是页面对象模型设计,所以不能使用 findElement。

@SuppressWarnings("unchecked")
protected void JoinNow(String... var) {
    List<MyElements> inputElements = new ArrayList<MyElements>();
    inputElements.add((MyElements) driver.findElement(By
            .id("firstName-coldRegistrationForm")));
    inputElements.add((MyElements) driver.findElement(By.id("lastName")));
    inputElements.add((MyElements) driver.findElement(By
            .id("email-coldRegistrationForm")));
    inputElements.add((MyElements) driver.findElement(By
            .id("password-coldRegistrationForm")));

    for (int i = 0; i < var.length; i++) {
        ((WebElement) inputElements.get(i)).sendKeys(var[i]);
    }
}

在创建页面对象模型时,您需要考虑几个事项。根据您的操作方式(通过使用@FindBy),有时您最终会得到陈旧的数据。为了获得更好的结果,您应该像下面这样定义您的 ID,并使用它们来获取您的 Webelement。这就是我设计它的方式。定义所有 By.id 并将其放入列表中,然后使用下面的函数对其进行简化。

定义者: static final By FNAME_REGFORM_BY_ID = By.id("firstName-coldRegistrationForm");

public void fillTextBoxes(List<By> bys, List<String> valuesToPopulate) {
    List<WebElement> webelements = new ChromeDriver().findElements(By.cssSelector("input[type=text]"));
    for (int i = 0; i < bys.size(); i++) {
        new ChromeDriver().findElement(bys.get(i)).sendKeys(valuesToPopulate.get(i));
    }
}

编辑:为了更好地理解,fillTextBoxes 等同于 joinNow。

List<String> values=new LiskedList<String>();
Values.add("emailid");
values.add("firstname");

List<By> bys=new LinkedList<By>();
bys.add(FNAME_REGFORM_BY_ID);
bys.add(EMAIL_ID_By_ID);

public void joinNow(List<By> bys, List<String> values) {
    List<WebElement> webelements = new ChromeDriver().findElements(By.cssSelector("input[type=text]"));
    for (int i = 0; i < bys.size(); i++) {
        new ChromeDriver().findElement(bys.get(i)).sendKeys(valuesToPopulate.get(i));
    }
}

不要使用带注释的@FindBy(how = How.ID, using = "email-coldRegistrationForm") 等,因为这会减慢执行速度并为您提供陈旧的数据。 FindBy 往往会变慢,因为整个页面对象只有在所有元素都可用后才会完全初始化。像我提到的那样尝试使用 Static By。我们 运行 遇到性能问题并开始从带注释的 Findby 切换。

根据要求,这里有一个示例实现。您可能需要根据您的项目要求进行调整,但这应该开始了。

您的页面 Class(为了我的缘故重命名为 SO)。

public class SO {

    WebDriver driver;

    static final By FNAME_REGFORM_BY_ID = By.id("firstName-coldRegistrationForm");
    static final By LNAME_REGFORM_BY_NAME = By.className("lastName");
    static final By EMAIL_REGFORM_BY_ID = By.id("email-coldRegistrationForm");
    static final By PWD_REGFORM_BY_ID = By.id("password-coldRegistrationForm");
    static final By SUBMIT_REGFORM_BY_ID = By.id("btn-submit");

    public SO(WebDriver driver) {
        this.driver = driver;
    }

    public List<By> getAllInput() {
        List<By> bys = new LinkedList<By>();
        bys.add(FNAME_REGFORM_BY_ID);
        bys.add(LNAME_REGFORM_BY_NAME);
        bys.add(LNAME_REGFORM_BY_NAME);
        bys.add(LNAME_REGFORM_BY_NAME);
        bys.add(LNAME_REGFORM_BY_NAME);
        return bys;
    }

    public void joinNow(List<String> values) {
        PageFactory.initElements(this.driver, HotelDetailsPage.class);
        List<By> bys = this.getAllInput();
        List<WebElement> webElements = this.driver.findElements(By.cssSelector("input[type=text]"));
        for (int i = 0; i < bys.size(); i++) {
            new ChromeDriver().findElement(bys.get(i)).sendKeys(values.get(i));
        }
    }

    public SO open(final String url) {
        this.driver.get(url);
        return this;
    }
}

测试方法:

   @Test
public void testForm() {
    WebDriver driver = new FirefoxDriver();
    SO so = new SO(driver);
    SO soPage = so.open("your app url");

    List<String> values = new LinkedList<String>();
    values.add("firstname");
    values.add("lastName");
    values.add("emailId");
    values.add("password");
    values.add("id");
    soPage.joinNow(values);
}

为什么不发送 MapJoinNow 方法。我建议您保持 PageObject 模式不变。我相信这在长期内更具可读性和可维护性

Map<String,String> data  = new HashMap<String,String>();
data.put("firstname", "George");
data.put("lastname", "Clooney");
data.put("email", "George@xyz.com");
data.put("password", "Dontguess");
JoinNow(data);

protected void JoinNow(Map<String,String> data) {
    firstNameElement.sendKeys(data.get("firstname"));
    lastNameElement.sendKeys(data.get("lastname"));
    emailElement.sendKeys(data.get("email"));
    passwordElement.sendKeys(data.get("password"));
}

另一种方式如下:

HashMap<WebElement, String> d = new HashMap<WebElement, String>();
d.put(newFirstNameTexthBox, "Michael");
d.put(newLastNameTexthBox, "Johnson");
d.put(newEmailTexthBox, "a@b.com");
d.put(newPasswordTexthBox, "Michael123$");
joinNow(d); 


protected void JoinNow(Map<WebElement,String> data) {
    for (Entry<WebElement, String> objValue : data.entrySet())
        objValue.getKey().sendKeys(objValue.getValue());
}