1

我有一个用 C# 编写的 Selenium WebDriver 脚本,它从 Excel 电子表格中读取一些值,然后使用该行中的值来填写 Web 表单。我现在面临的挑战是它从 Excel 文件中获取第一个单元格值并将其输入到表单中的所有字段中,然后获取下一个值并执行相同的操作,依此类推。

我怎样才能使它取第一个值,添加到表单中的第一个(命名字段),取第二个值和第二个命名字段等等。

请参阅下面的方法代码。

public void FillForm()
//Function reads entries from an Excel spreadsheet then uses values to populate and fill the form
{

    Excel.Application xlApp;
    Excel.Workbook xlWorkBook;
    Excel.Worksheet xlWorkSheet;
    Excel.Range xlrange;

    string xlString;
    int xlRowCnt = 0;
    int xlColCnt = 0;

    xlApp = new Excel.Application();
    //Open Excel file
    xlWorkBook = xlApp.Workbooks.Open(@"D:\Projects\Data\MSI_Data_file.xlsx", 0, true, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
    xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);

    //This gives the used cells in the sheet

    xlrange = xlWorkSheet.UsedRange;


    for (xlRowCnt = 1; xlRowCnt <= xlrange.Rows.Count; xlRowCnt++)
    {
        for (xlColCnt = 1; xlColCnt <= xlrange.Columns.Count; xlColCnt++)
        {
            xlString = (string)(xlrange.Cells[xlRowCnt, xlColCnt] as Excel.Range).Value2;
            driver.FindElement(By.XPath("//input[contains(@name, 'FirmName')]")).SendKeys(xlString);
            driver.FindElement(By.XPath("//input[contains(@name, 'FirstName')]")).SendKeys(xlString);
            driver.FindElement(By.XPath("//input[contains(@name, 'LastName')]")).SendKeys(xlString);
            driver.FindElement(By.XPath("//input[contains(@name, 'Email')]")).SendKeys(xlString);
            driver.FindElement(By.XPath("//input[contains(@name, 'FirmAddress')]")).SendKeys(xlString);
            driver.FindElement(By.XPath("//select[@id= 'ddlCountry']")).SendKeys(xlString);
            driver.FindElement(By.XPath("//input[contains(@name, 'PhoneNumber')]")).SendKeys(xlString);
            driver.FindElement(By.XPath("//input[contains(@name, 'FaxNumber')]")).SendKeys(xlString);
            driver.FindElement(By.XPath("//input[contains(@name, 'Website')]")).SendKeys(xlString);
            driver.FindElement(By.XPath("//textarea[contains(@name, 'Comments')]")).SendKeys(xlString);
            driver.FindElement(By.XPath("//input[@id='chkFirm_Service_Accounting']")).Click();
            driver.FindElement(By.XPath("//select[contains(@name, 'LeadSource')]")).SendKeys(xlString);

            //save screenshot of completed form
            SaveScreenShot("CompleteForm");

            driver.FindElement(By.XPath("//a[contains(text(), 'Submit')]")).Click();

            //Take screenshot of successful form submission
            SaveScreenShot("Submission_Success");


            driver.FindElement(By.XPath("//a[contains(text(), 'click here')]")).Click();

        }
    }
}
4

1 回答 1

0

您应该一次处理每一列以执行 FindElement。我已经修改了您的代码并使其更加灵活。

首先,您注意到我通过为每个表达式引入一个 Lamba 函数来概括您使用的 XPath 表达式:

Func<string,string> inputName = (id) => String.Format("//input[contains(@name, '{0}')]", id);

然后,当我们将列映射到正确的 XPath 时,我们可以稍后重用这些。正如您在最终代码中看到的那样,我有 5 个。

接下来,我List<string>为 Excel 中的每一列添加了一个简单的要使用的字段:

var fields = new List<string> {
    inputName("FirmName"),
    inputName("FirstName"),
    // many more
 }

因此,第一列将与您的网络表单上名为FirmName的输入元素匹配,第二列将与Firstname等匹配。

请注意,在您的 Excel 表中实现此映射并不难,因此此代码将被进一步概括,但我将其作为练习留给读者。

一旦我们有了我们的,我们可以简单地通过对索引器中的fields简单调用来获取要使用的 XPath 的每一列:List<string>

// this will give you the correct XPath
var xpath = fields[xlColCnt -1]; 

唯一需要注意的是,在 Excel 中,列从 1 开始,而在 C# 中,一般索引是从 0 开始的,因此是 -1。

将它们放在一起将为您提供最终实现:

public void FillForm()
//Function reads entries from an Excel spreadsheet then uses values to populate and fill the form
{

    string xlString;
    int xlRowCnt = 0;
    int xlColCnt = 0;

    var xlApp = new Application();
    //Open Excel file
    var xlWorkBook = xlApp.Workbooks.Open(@"MSI_Data_file.xlsx", 0, true, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
    var xlWorkSheet = (Worksheet)xlWorkBook.Worksheets.get_Item(1);

    //This gives the used cells in the sheet

    var xlrange = xlWorkSheet.UsedRange;

    // XPath formatters for each 
    Func<string,string> inputName = (id) => String.Format("//input[contains(@name, '{0}')]", id);
    Func<string, string> inputId = (id) => String.Format("//input[@id='{0}']", id);
    Func <string, string> selectId = (id) => String.Format("//select[@id= '{0}']", id);
    Func<string, string> selectName = (id) => String.Format("//select[contains(@name, '{0}')]", id);
    Func<string, string> textareaName = (id) => String.Format("//textarea[contains(@name, '{0}')]", id);

    // map a fieldname to an Xpath formatter
    // Order of the fields is important!
    var fields = new List<string> {
        inputName("FirmName"),
        inputName("FirstName"),
        inputName("LastName"),
        inputName("Email"),
        inputName("FirmAddress"),
        selectId("ddlCountry"),
        inputName("PhoneNumber"),
        inputName("FaxNumber"),
        inputName("Website"),
        textareaName("Comments"),
        inputId("chkFirm_Service_Accounting"),
        selectName("LeadSource"),
    };
    // handle all rows
    for (xlRowCnt = 1; xlRowCnt <= xlrange.Rows.Count; xlRowCnt++)
    {
        // handle each column, based on the column number
        for (xlColCnt = 1; xlColCnt <= xlrange.Columns.Count; xlColCnt++)
        {
            var value = xlrange.Cells[xlRowCnt, xlColCnt].Value2;
            // if value contains a double or a date, this will still work
            xlString = (value ?? "").ToString();

            // this will give you the correct XPath
            var xpath = fields[xlColCnt -1]; 
            // find 
            driver.FindElement(By.XPath(xpath)).SendKeys(xlString);
        }

        //save screenshot of completed form
        SaveScreenShot("CompleteForm");
        driver.FindElement(By.XPath("//a[contains(text(), 'Submit')]")).Click();
        //Take screenshot of successful form submission
        SaveScreenShot("Submission_Success");
        driver.FindElement(By.XPath("//a[contains(text(), 'click here')]")).Click();
    }
}
于 2017-06-13T19:09:10.283 回答