java - List<Map<String,String>> 迭代 WebElement 变量

标签 java for-loop selenium-webdriver datatable cucumber

我正在使用 cucumber 数据表:

When I populate a field with a new value
      | FieldName  | FieldValue |
      | Name | Joe Blogs |
      | Email address | jblogs@gmail.com |
      | Phone 1 | 04 555 6666 |
      | Phone 2 | 0800 123 4567 |
      | SMS Phone | 023 222 333 |
      | Fax number | 09 888 9999 |
      | Location | Bermuda Triangle |

使用以下 java 类:

@When("^I populate a field with a new value$")
    public void ShouldPopulateFieldsWithValues(DataTable arg1) throws Throwable {
        List<Map<String,String>> data=arg1.asMaps(String.class,String.class);
        //Declare a string variable for NAME and assign it's value
        String profileNameTextboxValue = data.get(0).get("FieldValue");
        //Find the profile NAME text box
        WebElement profileNameTextbox = driver.findElement(By.id("name"));
        //Clear the value from the profile NAME text box
        profileNameTextbox.clear();
        //Send the string value to the profile NAME text box
        profileNameTextbox.sendKeys(profileNameTextboxValue);

        //Declare a string variable for EMAIL and assign it's value
        String profileEmailValue = data.get(1).get("FieldValue");
        //Find the profile EMAIL text box
        WebElement profileEmailTextbox = driver.findElement(By.id("email"));
        //Clear the value from the profile EMAIL text box
        profileEmailTextbox.clear();
        //Send the string value to the profile EMAIL text box
        profileEmailTextbox.sendKeys(profileEmailValue);

        //Declare a string variable for PHONE1 and assign it's value
        String profilePhone1Value = data.get(2).get("FieldValue");
        //Find the profile PHONE1 text box
        WebElement profilePhone1Textbox = driver.findElement(By.id("phone"));
        //Clear the value from the profile PHONE1 text box
        profilePhone1Textbox.clear();
        //Send the string value to the profile PHONE1 text box
        profilePhone1Textbox.sendKeys(profilePhone1Value);

        //Declare a string variable for PHONE2 and assign it's value
        String profilePhone2Value = data.get(3).get("FieldValue");
        //Find the profile PHONE2 text box
        WebElement profilePhone2Textbox = driver.findElement(By.id("phone2"));
        //Clear the value from the profile PHONE2 text box
        profilePhone2Textbox.clear();
        //Send the string value to the profile PHONE2 text box
        profilePhone2Textbox.sendKeys(profilePhone2Value);

        //Declare a string variable for SMS Phone and assign it's value
        String profileSMSValue = data.get(4).get("FieldValue");
        //Find the profile sms phone text box
        WebElement profileSMSTextbox = driver.findElement(By.id("sms_phone"));
        //Clear the value from the profile sms phone text box
        profileSMSTextbox.clear();
        //Send the string value to the profile sms phone text box
        profileSMSTextbox.sendKeys(profileSMSValue);

        //Declare a string variable for Fax Number and assign it's value
        String profileFaxValue = data.get(5).get("FieldValue");
        //Find the profile fax text box
        WebElement profileFaxTextbox = driver.findElement(By.id("fax"));
        //Clear the value from the profile fax text box
        profileFaxTextbox.clear();
        //Send the string value to the profile fax text box
        profileFaxTextbox.sendKeys(profileFaxValue);

        //Declare a string variable for Location and assign it's value
        String profileLocationValue = data.get(6).get("FieldValue");
        //Find the profile Location text box
        WebElement profileLocationTextbox = driver.findElement(By.id("location"));
        //Clear the value from the profile Location text box
        profileLocationTextbox.clear();
        //Send the string value to the profile Location text box
        profileLocationTextbox.sendKeys(profileLocationValue);
}

上面的代码可以工作,但是肯定有更有效的方法来编写java类吗?

我希望能够找到一种方法,使用数据表中的不同值来迭代 WebElement 变量。有办法做到这一点吗?

我找到了两个代码示例,我将尝试并调整它们,但不太确定如何将它们组合在一起..

第一个例子:

for (Map.Entry<String, String> entry : countries.entrySet()) {
        String key = entry.getKey();
        String value = entry.getValue();
        // ...
        }

第二个例子:

List<Map<String, Object>> list; // this is what you have already

    for (Map<String, Object> map : list) {
    for (Map.Entry<String, Object> entry : map.entrySet()) {
    String key = entry.getKey();
    Object value = entry.getValue();
    }
    }

注意:我是 java/编码新手,对代码的任何批评都会有所帮助..

@homaxto,根据指示,我创建了以下 bean 类 Person..

public class Person implements java.io.Serializable {

    // Properties
        private String Username;
        private String Name;
        private String Email;
        private String Phone1;
        private String Phone2;
        private String SMS;
        private String Fax;
        private String Location;
        private String Address;
        private String Zip;
        private String PayPal;

    // Getters
        public String getUsername() { return Username; }
        public String getName() { return Name; }
        public String getEmail() { return Email; }
        public String getPhone1() { return Phone1; }
        public String getPhone2() { return Phone2; }
        public String  getSMS() { return SMS; }
        public String getFax() { return Fax; }
        public String getLocation() {return Location; }
        public String getAddress() { return Address; }
        public String getZip() { return Zip; }
        public String getPaypalEmail() { return PayPal; }

    // Setters
    public void setUsername() { this.Username = Username; }
    public void setName() { this.Name = Name; }
    public void setEmail() { this.Email = Email; }
    public void setPhone1() { this.Phone1 = Phone1; }
    public void setPhone2() { this.Phone2 = Phone2; }
    public void setSMS() { this.SMS = SMS; }
    public void setFax() { this.Fax = Fax; }
    public void setLocation() {this.Location = Location; }
    public void setAddress() { this.Address = Address; }
    public void setZip() { this.Zip = Zip; }
    public void setPaypalEmail() { this.PayPal = PayPal; }
}

我的数据表如下:

Feature: Update my personal details
  As a Property Manager
  I want to update my personal details
  So that I can be reached by my customers

  @wip
  Scenario: Update my personal details
    Given I am logged in to my account
    Given I have navigated to the change profile tab
    When I populate a field with a new value
    | Username | Name        | Email         | Phone1     | Phone2       | SMS   | Fax  | Location         | Address        | Zip  | PayPal |
    | testy    | Test Logger | testerslog1@gmail.com | 04 555 6666 | 0800 123 4567 | 029 295 495 | 04 888 9999 | Bermuda Triangle | 5 Pokemon Lane | 9999 | testersLog1@gmail.com |
    Then I click save

最佳答案

我会做如下的事情。为此,您必须使用输入元素的 ID 作为第一列中的值。 如果您的数据表中必须有较少的依赖项,您可以在步骤实现中映射它并在使用它之前查找它。 另外,您不需要标题行,并且只需要跳过第一行即可。

@When("^I populate a field with a new value$")
    public void ShouldPopulateFieldsWithValues(DataTable dataTable) throws Throwable {
        List<List<String>> rows = dataTable.asLists(String.class);
        // Either quit having a header in your datatable or remove the first row
        rows.remove(0);
        for (List<String> row : rows) {
            String fieldName = row.get(0);
            String fieldValue = row.get(1);

            // Use the IDs as name in your datatable
            WebElement profileNameTextbox = webdriver.findElement(By.id(fieldName));
            profileNameTextbox.clear();
            profileNameTextbox.sendKeys(fieldValue);
        }
    }

解决此问题的另一种方法可能是翻转将字段名作为列名的表。

When I populate a field with a new value
  | Name      | Email address    | Phone 1     | Phone 2       | SMS Phone   | Fax number  | Location         |
  | Joe Blogs | jblogs@gmail.com | 04 555 6666 | 0800 123 4567 | 023 222 333 | 09 888 9999 | Bermuda Triangle |

通过此设计,您可以创建一个 bean 类“Person”,其中每列都有 getter 和 setter。 Cucumber 将执行 camel-casing 并自动调用名为 setEmailAddress() 等的方法。因此,如果标题列名为“电子邮件地址”,那么 Cucumber 将调用名为 setEmailAddress 的方法,其值为 jblogs@gmail.com
这将为您提供以下实现签名

@When("^I populate a field with a new value$")
    public void iPopulateAFieldWithANewValue(List<Person> persons) throws Throwable {
    for (Person p : persons) {
        ...
    }
}

正如您所见,这很容易允许多行数据。 哪一个最适合您的情况完全取决于您,我只是想展示您拥有的另一种选项,该选项没有详细记录。

关于java - List<Map<String,String>> 迭代 WebElement 变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35908185/

相关文章:

java - BufferedWriter 如何不覆盖已保存的文本?

java - 将日期时间对象转换为字符串

java - 当我对我之前在代码中执行过的同一 WebElement 执行 click() 时,出现空指针异常

java - For 循环在 if 情况下不运行

java - 在java中使用for循环打印星号三角形

python - 使用 Selenium 从没有 ID 或类的列表中抓取文本

javascript - Node.js Selenium IPv6 问题(SocketException 协议(protocol)系列不可用)

java - 如何在 JTextArea 或 JTextPane 中显示多个插入符号

java - 如何在java 8流上使用foreach循环进行迭代

python - 减小 pyinstaller exe 的大小