繁体   English   中英

selenium - 通用 function 使用嵌套的linkedhashmap在网页中输入测试数据 - 如何处理单选按钮

[英]selenium - generic function to enter test data in webpage using nested linkedhashmap - how to handle radio buttons

我在基于 POM 的混合框架中使用 Selenium 和 Java。 我正在尝试开发一个通用的 function 来在网页中输入数据。 function 接受带有键(weblement)和值(要输入的测试数据)对的linkedhashmap。 到目前为止它工作正常。 但我被困在如何处理单选按钮上。 单选按钮是 Web 元素列表,我不知道如何将它们传递给这个通用的 function。

例如,如果我的单选按钮具有以下 dom:

<div class='radio'>
  <label>
  <input type='radio' name='hosting' value='yes'> "Yes"
  </label>
</div>
<div class='radio'>
  <label>
  <input type='radio' name='hosting' value='no'> "No"
  </label>
</div>

在正常情况下,我会创建一个 WebElement 列表,遍历它们并对它们执行操作。 但是由于我正在编写一个接受 LinkedHashMap 的通用 function 我如何将这个 WebElements 列表传递给它? 当我们创建 map 时,密钥始终是唯一的。 这里 key 将针对一组具有不同值的对象重复。

以下是我的通用 function 的代码。

package seleniumeasy.qa.Util;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Set;

import org.apache.commons.io.FileUtils;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;
import org.testng.ITestContext;
import org.testng.Reporter;
import org.testng.annotations.DataProvider;

import io.qameta.allure.Allure;
import seleniumeasy.qa.Base.Base;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

public class commonUtil extends Base {
    
    public static String sConfigPath = "\\src\\main\\java\\seleniumeasy\\qa\\Config\\config.properties";
    public static String sScreenShotFolderPath = "\\Screenshots";
    
    public static int iImplicitWait = 30;
    
    
    public static void EnterData(LinkedHashMap<WebElement, String> sEnterDataList)
    {
        //Map<String,String> sData = nsew HashMap<String,String>();
        
        for(Entry<WebElement, String> element:sEnterDataList.entrySet())
        {
            System.out.println("Element key is: " + element.getKey().toString());
            if(element.getKey().toString().contains("Select"))
            {
                Select comboSelect = new Select(element.getKey());
                comboSelect.selectByVisibleText(element.getValue());
            }
            if(element.getKey().toString().contains("radio"))
            {
                Select comboSelect = new Select(element.getKey());
                comboSelect.selectByVisibleText(element.getValue());
            }
            else
            {
                element.getKey().sendKeys(element.getValue());
            }
        }
        
    }


}

以下是我的页面 class 中的代码,我在其中调用 EnterData function。

package seleniumeasy.qa.Page;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.Select;

import io.qameta.allure.Allure;
import io.qameta.allure.Step;
import seleniumeasy.qa.Base.Base;

public class InputFormValidationPage extends Base
{
    @FindBy(name="first_name")
    static WebElement txtFirstName;
    
    @FindBy(name="last_name")
    static WebElement txtLastName;
    
    @FindBy(name="email")
    static WebElement txtEmail;
    
    @FindBy(name="phone")
    static WebElement txtPhone;
    
    @FindBy(name="address")
    static WebElement txtAddress;
    
    @FindBy(name="city")
    static WebElement txtCity;
    
    @FindBy(css="Select[name='state']")
    static WebElement comboSelect;
    
    @FindBy(name="zip")
    static WebElement txtZip;
    
    @FindBy(name="website")
    static WebElement txtWebsite;
    
    @FindBy(css="input[type='radio']")
    static List<WebElement> selectHosting;

    @FindBy(name="comment")
    static WebElement txtComment;

    @FindBy(css="button[type='submit']")
    static WebElement btnSubmit;
    
    public InputFormValidationPage()
    {
        PageFactory.initElements(driver, this);
    }
    
    @Step("Insert data")
    public void submitInputForm(String sTestCaseNo,String sFirstName,String sLastName,String sEmail,String sPhone,String sAddress,String sCity,String sState,String sZip,String sWebsite,String sHosting,String sComment)
    {
        
        Map<WebElement,String> sEnterDataList = new LinkedHashMap<WebElement,String>();
                
        
        /*txtFirstName.sendKeys(sFirstName);
        txtLastName.sendKeys(sLastName);
        txtEmail.sendKeys(sEmail);
        txtPhone.sendKeys(sPhone);
        txtAddress.sendKeys(sAddress);
        txtCity.sendKeys(sCity);*/
        
        //System.out.println("The type of State Combo is: " + comboSelect.getAttribute("type"));
        //Select sComboSelect = new Select(driver.findElement(By.cssSelector("Select[name='state']")));
        
        /*sComboSelect.selectByVisibleText(sState);
        //comboState.selectByVisibleText(sState);
        txtZip.sendKeys(sZip);;
        txtWebsite.sendKeys(sWebsite);;
        for(WebElement element:selectHosting)
        {
            if(element.getText().equalsIgnoreCase(sHosting))
                if(!element.isSelected())
                    element.click();
        }
        txtComment.sendKeys(sComment);;
        Allure.step("Click Submit After Adding Data");
        btnSubmit.click();
        
        */

        sEnterDataList.put(txtFirstName, sFirstName);
        sEnterDataList.put(txtLastName, sLastName);
        sEnterDataList.put(txtEmail, sEmail);
        sEnterDataList.put(txtPhone, sPhone);
        sEnterDataList.put(txtAddress, sAddress);
        sEnterDataList.put(txtCity, sCity);
        sEnterDataList.put(comboSelect, sState);
        sEnterDataList.put(txtZip, sZip);
        sEnterDataList.put(txtWebsite, sWebsite);
        //sEnterDataList.put((WebElement) selectHosting, sHosting);
        //sEnterDataList.put((WebElement) selectHosting, sHosting);
        sEnterDataList.put(txtComment, sComment);
        sEnterDataList.put(btnSubmit, "");
        seleniumeasy.qa.Util.commonUtil.EnterData((LinkedHashMap<WebElement, String>) sEnterDataList);
    }
}

这是我的测试页面,它使用 DataProvider 连接到我的 excel 数据库并获取记录,然后将这些记录作为测试数据传递给我的页面 class。

package seleniumeasy.test.Tests;

import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;
import org.testng.asserts.SoftAssert;

import io.qameta.allure.Allure;
import io.qameta.allure.Description;
import junit.framework.TestListener;
import seleniumeasy.qa.Base.Base;
import seleniumeasy.qa.Page.InputFormValidationPage;
import seleniumeasy.qa.Page.managePopupWindowPage;
import seleniumeasy.qa.Util.excelDataUtil;

//@Listeners(seleniumeasy.qa.Util.TestListener.class)
public class InputFormValidationTest extends Base{

    InputFormValidationPage obj;
    managePopupWindowPage mObj;
    
    @BeforeMethod
    public void setUP()
    {
        Init();
        
        mObj = new managePopupWindowPage();
        obj = mObj.clickInputFormSubmitMenu();      
    }
    @Description("Data Driven Test to insert new records - Excel")
    @Test(dataProvider="getInputData",description="Data driven test using excel to insert records in the system")
    public void validateInputForm(String sTestCaseNo,String sFirstName,String sLastName,String sEmail,String sPhone,String sAddress,String sCity,String sState,String sZip,String sWebsite,String sHosting,String sComment)
    {
        
        //System.out.println(sTestCaseNo + "-" + sFirstName + "-" + sLastName+ "-"+ sEmail+ "-" + sPhone+ "-" +sAddress + "-" +sCity + "-" + sState + "-" +  sZip + "-" +  sWebsite + "-" +  sHosting + "-" +  sComment);
        obj.submitInputForm(sTestCaseNo, sFirstName, sLastName, sEmail, sPhone, sAddress, sCity, sState, sZip, sWebsite, sHosting, sComment);
        Allure.step("Verification after insertion of record");
    }
    @AfterMethod
    public void tearDown()
    {
        driver.close();
        driver.quit();
    }
    
    @DataProvider
    public Object[][] getInputData()
    {
        Object data[][] = excelDataUtil.readExcelFile("InputFormValidationData");
        //System.out.println("Data inside data provider is as followes:");
        //System.out.println(data.toString());
        return data;
    }
    
    
}

请注意,到目前为止,这一切正常,因为我评论了将单选按钮添加到列表中的代码。 它适用于 textfield、textarea 和 combobox 对象。 我只是不知道如何处理具有公共键但值不同的单选按钮。 地图只接受唯一键。

是否可以将 web 元素列表作为 LinkedHashMap 的一部分发送?

请提出建议

与其直接传递元素值的 LinkedHashMap,不如传递一个包装器 class 来封装 LinkedHashMap,以便它可以使用List<WebElement>WebElement参数重载LinkedHashMap.put()方法。 一般来说,这将允许您拥有更健壮的代码,并且可以轻松调整每种 WebElement 类型。

void put(WebElement webElement, String value)方法将直接保存值,而void put(List<WebElement> webElements, String value)方法将(在单选元素的情况下)仅保存包含给定 String 值的WebElement

例子:

class FormData {

    private Map<WebElement, String> map;

    public FormData() {
        this.map = new LinkedHashMap<WebElement, String>();
    }
    
    public FormData(final LinkedHashMap<WebElement, String> map) {
        this.map = map;
    }
    
    public void put(final WebElement webElement, final String value) {
        this.map.put(webElement, value);
    }
    
    public void put(final List<WebElement> webElements, final String value) throws Exception {
        /* You might want to restrict this block of code to only radio buttons */
        WebElement element = this.map
                                 .stream()
                                 .filter((key, val) -> value.equals(val))
                                 .findFirst()
                                 .orElseThrow(new Exception("Radio with value: " + value + " not found!"));
        this.put(element, value);
    }
    
    // getters and setters omitted

}

然后在您的submitInputForm方法中:

FormData sEnterDataList = new FormData();
// ...
sEnterDataList.put(selectHosting, sHosting);
seleniumeasy.qa.Util.commonUtil.EnterData(sEnterDataList);

暂无
暂无

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

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