用Selenium WebDriver C#和带有值的Web窗体读取Excel文件

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

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

请参阅下面的方法的代码。

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

您应该逐个处理每个列以执行FindElement。 我调整了你的代码,使它更加灵活。

首先你注意到我通过为每个引入一个lamba函数来推广你使用的XPathexpression式:

 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 } 

因此,第一列将与您的webform上名为FirmName的input元素相匹配,第二列将与Firstname等匹配

请注意,在Excel表格中实现这个映射不会太困难,所以这个代码会被进一步推广,但是我把它作为读者的一个练习。

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

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