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