当前位置: 首页 > 知识库问答 >
问题:

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

司寇灵均
2023-03-14

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

如果我的单选按钮有以下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>

在正常情况下,我会创建一个WebElements列表,遍历它们并对它们执行操作。但是,由于我正在编写一个接受LinkedHashMap的泛型函数,我如何将这个WebElements列表传递给它呢?当我们创建地图时,键总是唯一的。Here键将对一组具有不同值的对象重复。

下面是我的泛型函数的代码。

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());
            }
        }
        
    }


}

下面是我调用EnterData函数的Page类中的代码。

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数据库并获取记录,然后将这些记录作为testdata传递给我的page类。

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对象。我只是不知道如何处理单选按钮,这将有共同的键,但不同的值。Maps只接受唯一键。

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

请提供建议

共有1个答案

通寂离
2023-03-14

与直接传递元素值的LinkedHashMap不同,我宁愿传递一个封装LinkedHashMap的包装类,这样它就可以用列表 <webelement>webElement参数重载LinkedHashMap.put()方法。一般而言,这将允许您拥有一个更健壮的代码,可以轻松地对每个WebElement类型进行调整。

void put(webelementwebelement,String value)方法将直接保存值,而void put(list webElements,String value) 方法(如果是无线电元素)将只保存包含给定字符串值的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(e -> /* find radio with given value */)
                                 .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);
 类似资料:
  • 我正在使用asp构建一个web api。netwebapi 2,对于我的文档,我选择了swagger。 我遇到的问题是我的一个api方法采用嵌套数组(另一个数组中的字符串数组)。在postman中手动测试时,当我键入以下内容时效果很好: 但是在swagger-ui中,我只输入一个字段,每行只有一个参数。这使得我不能为每个嵌套数组输入两个值。 结果应如下所示 (json): 这是我通过上面的查询参数

  • 我试图解析一个OpenAPI JSON文件,并访问值来构建一个rest模型类。我尝试使用对象映射器解析JSON文件,并将其发送到一个接收

  • 问题内容: 在TDD(测试驱动开发)开发过程中,如何处理测试数据?假设有一个场景,解析日志文件以获取所需的列。对于强大的测试,我该如何准备测试数据?对我来说,将此类文件定位到测试类文件是否正确? 问题答案: 例如,Maven对用于处理测试数据的文件夹结构使用约定: 如果您使用maven进行构建,则需要将测试资源放置在正确的文件夹中,如果您使用其他内容进行构建,则您可能希望使用此结构,因为它不仅仅是

  • 我的目标是从HTTP源获取JSON数据并使用AVRO序列化将其存储在Kafka主题中。 使用Kafka Connect和一个HTTP源连接器以及一堆SMT,我成功地创建了一个连接数据结构,当使用StringConverter写入主题时,它是这样的: 结构{base=stations,cod=200,coord=Struct{lat=54.0,lon=9.0},dt=163210605} 因此,JS

  • 关于函数使用,与带来的问题。 函数 函数主要给数据提供处理与转换方便。 大多数SQL实现的函数 用于处理文本串(删除,充值,大小写转换) 用于在数值的数据上进行算术(返回绝对值,代数运算)操作。 用于处理日期时间值并从这些值中提取特定成份。 返回DBMS正使用的特殊信息(用户登录信息)。 文本处理函数 使用UPPER()函数来转换大小写。 mysql> SELECT vend_name, UPPE