[英]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.