2016-08-10css
1 关键字驱动概述
2 框架更改总览
3 框架更改详解
3.1 解析新增页面目录
3.2 解析新增测试用例目录
3.3 解析自动生成代码
3.4 读取用例excel数据,定位元素,并进行操做
3.5 更改SeleniumUtil.java java
源代码:autotestKeywordDrive.zipweb
返回apache
关键字驱动测试(Keyword-driven testing),也叫作表格驱动测试或者基于行为词的测试。windows
关键字驱动究竟是什么样的?数组
见图3,动做也就是关键字,好比你选择了“点击”操做,就意味着这步骤会执行一个元素点击操做。浏览器
关键子驱动是如何实现的:cookie
问:那么如何定义动做?网络
答:在框架设计的时候会专门设计一个类,来实现各类“动做”的具体内容。当你在excel中读取了一个“动做”以后,框架会自动解析这个“动做”背后的事情。在测试框架中这个类的名字叫作:SuperAction.java。
问:如何定义和解析元素定位?
答:见图2,每一个页面是一个excel,全部元素的定位方式和定位值都保存在里面
问:如何用例存储?
答:见图3,一个excel就是一个模块,而后这个excel文件中一个sheet就是这个模块中的一条用例
问:Excel文件如何执行测试?
答:excel文件存储用例,但excel只是文件,如何调用测试入口呢?其实在关键字驱动框架中,有一个用例生成类(TestCaseFactoryForSingle.java,TestCaseFactoryForAll.java),它能够遍历全部excel的全部sheet,生产一条条用例类,见图6
关键字优缺点:
图1 关键子驱动与数据驱动比较
在原来的框架下更改,以下图所示
page: 存储页面元素的目录,在此目录下每一个页面是一个excel,会替换原先框架的com.demo.test.pages包,如图1所示。
图2 page 元素定位excel
testcase:存储测试用例的目录,每一个模块一个excel文件,每一个excel文件中的sheet是一条测试用例,会替换原先框架的com.demo.test.pageshelper包和data目录,如图4所示。
图3 用例Login的Actions
测试用例excel是用于存储测试用例步骤(如图4所示)、步骤中涉及的动做(如图3所示)和测试数据(如图4所示)等内容,命名规则以下:
注意:测试用例excel文件sheet“001_LoginSuccessFunction”中的“动做”列(如图4所示),这列是经过sheet“Actions”中的“动做名称”列来赋值的:
图5 用例excel替换pagehelper类和data excel
自动生成代码TestCaseFactoryForSingle.java代码以下
package com.demo.test.utils; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileWriter; import java.io.IOException; import java.util.Scanner; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.testng.Assert; import jxl.read.biff.BiffException; /** * * @author xy-incito-wy * @Description 自动生成测试代码的工具类,生成指定模块的用例 * */ public class TestCaseFactoryForSingle { public static void main(String[] args) { //测试代码包路径,若是你的测试代码目录不同请在这里修改 final String caseFolder = "src/com/demo/test/testcases/"; //源文件 File sourceFile = null; //sheet的名字 String sheetName = null; //功能模块名字 String functionName = null; //sheet的号码 int sheetNum = 0; try { @SuppressWarnings("resource") //从控制台能够输入 Scanner s = new Scanner(System.in); System.out.println("请输入模块名称(不要按回车键,输入完成以后请再按回车键):"); functionName = s.nextLine();// 输入模块名字 functionName = functionName.replaceFirst( functionName.substring(0, 1), functionName.substring(0, 1).toLowerCase()); // 若是包名不存在,就新建 File functionPackage = new File(caseFolder + "/" + functionName); if (functionPackage.exists()) { System.out.println(functionName + "包已经存在,自动跳过!"); System.out.println("正在生成用例到" + functionName + "包下,请稍等..."); } else { functionPackage.mkdir(); System.out.println(functionName + "包已建立!"); System.out.println("正在生成用例到" + functionName + "包下,请稍等..."); } for (int j = 0; j < getSheetNum(getExcelRelativePath(functionName)); j++) { // 根据传入的模块文件路径得到模块中sheet数量 也就是用例个数 if (j == getSheetNum(getExcelRelativePath(functionName)) - 1) { //若是只有一个sheet的时候(只有Value的状况下),跳出循环不进行自动生成代码操做,由于没有能够生成的。 break; } try { sheetName = getSheetName(j + 1, getExcelRelativePath(functionName)); // 取得sheetName,因为第一个sheet是values,因此从j+1开始 sheetNum = getSheetNum(getExcelRelativePath(functionName)); } catch (BiffException e1) { e1.printStackTrace(); } sourceFile = new File(caseFolder + functionName.toLowerCase() + File.separator + functionName.replaceFirst(functionName.substring( 0, 1), functionName.substring(0, 1) .toUpperCase()) + "Page_" + sheetName + "_Test.java");// 建立测试用例源码,指定存放路径 FileWriter writer = new FileWriter(sourceFile); // 生成测试用例代码的头文件 writer.write("package com.demo.test.testcases." + functionName + "; \n" + "import org.testng.annotations.Test; \n" + "import com.demo.test.base.BaseParpare; \n " + "import com.demo.test.utils.SuperAction; \n" + "public class " + functionName.replaceFirst(functionName.substring( 0, 1), functionName.substring(0, 1) .toUpperCase()) + "Page_" + sheetName + "_Test extends BaseParpare{ \n"); // @Test的主体部分,也就是测试用例的方法 String firstLetter = sheetName.substring( sheetName.indexOf("_") + 1).substring(0, 1); String others = sheetName.substring( sheetName.indexOf("_") + 1).substring(1); String function = firstLetter.toLowerCase() + others; writer.write("@Test \n" + " public void" + " " + function + "() { \n" + "SuperAction.parseExcel(\"" + functionName.replaceFirst(functionName.substring( 0, 1), functionName.substring(0, 1) .toUpperCase()) + "\",\"" + sheetName + "\",seleniumUtil);\n" + " }\n"); // 代码结尾大括号 writer.write("}"); writer.close(); } } catch (IOException e) { Assert.fail("IO异常", e); } System.out.println("模块[" + functionName + "] 的用例已经生成完毕,共计:" + (sheetNum - 1) + "条,请到" + caseFolder + functionName.toLowerCase() + "路径下查阅!"); } /** * 得到excel的相对路径 * * @param 循环模块名称的角标 * @return 获得对应index的模块名字 */ public static String getExcelRelativePath(String functionName) { String dir = "res/testcase"; String path = ""; // get file list where the path has File file = new File(dir+File.separator+functionName+".xlsx"); // get the folder list path = file.getPath(); return path; } /** * 得到当前excel的sheet数量 - 每一个模块的用例数 * * @param filePath * 文件路径 * @return 得到excel的sheet数量 * @throws FileNotFoundException * @throws IOException */ public static int getSheetNum(String filePath) throws FileNotFoundException, IOException { int casesNum = 0; XSSFWorkbook workbook = new XSSFWorkbook(new FileInputStream(new File( filePath))); casesNum = workbook.getNumberOfSheets(); return casesNum; } /** * * @param sheetIndex * sheet的位置 * @param filePath * excel文件路径相对的 * @return 返回sheet的名字 * @throws BiffException * @throws IOException */ public static String getSheetName(int sheetIndex, String filePath) throws BiffException, IOException { String casesName = ""; XSSFWorkbook workbook = new XSSFWorkbook(new FileInputStream(filePath)); casesName = workbook.getSheetName(sheetIndex); return casesName; } }
TestCaseFactoryForSingle.java这个类,这个类主要是用于生成指定模块的测试用例,这个类有一个main方法,当你执行以后,会提示你输入要生成测试代码的模块。这里的模块的名字就是testcase目录下的excel文件名字(不包含后缀),而后回车,
此时回到src/com/demo/test/testcases/login包下查看,一条用例生成了 LoginPage_001_LoginSuccessFunction_Test.java,如图5所示.
在pom.xml中,添加jar依赖
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.10-FINAL</version> </dependency>
图6 自动生成代码
SuperAction.java代码以下:
package com.demo.test.utils; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.util.Iterator; import org.apache.log4j.Logger; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.openqa.selenium.Alert; import org.openqa.selenium.By; import org.testng.Assert; /** * * @Description 把Selenium操做的变成关键字操做 * */ public class SuperAction { public static Logger logger = Logger.getLogger(SuperAction.class.getName()); //static String pageFilePath = "res/page/PageElements.xlsx"; static String pageFileDir = "res/page/"; public static Alert a = null; /** * * @param locateWay 定位方式 * @param locateValue 定位的方式的具体值 * @return 定位的方式(By) */ public static By getLocateWay(String locateWay,String locateValue){ By elementLocator=null; if(locateWay.equalsIgnoreCase("xpath")){ elementLocator=By.xpath(locateValue); } else if(locateWay.equalsIgnoreCase("className")){ elementLocator=By.className(locateValue); } else if(locateWay.equalsIgnoreCase("id")){ elementLocator=By.id(locateValue); } else if(locateWay.equalsIgnoreCase("linktext")){ elementLocator=By.linkText(locateValue); } else if(locateWay.equalsIgnoreCase("name")){ elementLocator=By.name(locateValue); } else if(locateWay.equalsIgnoreCase("css")){ elementLocator=By.cssSelector(locateValue); } else if(locateWay.equalsIgnoreCase("tagname")){ elementLocator=By.tagName(locateValue); } else{ Assert.fail("你选择的定位方式:["+locateWay+"] 不被支持!"); } return elementLocator; } /** * * @param sheet - 测试用例表中的sheet * @param rowIndex - 测试用例表中的行index * @param locateColumnIndex - 测试用例表中的定位列的index * @return 从page表中 返回定位方式和定位值 * @Description 根据testcase中的元素定位列,去取得page页中的 定位方式和定位值 */ public static String[] getPageElementLocator(Sheet sheet,int rowIndex,int locateColumnIndex,String pageName){ XSSFWorkbook pageBook = null; //定位方式 String elementLocatorWay = null; //定位值 String elementLocatorValue = null; //sheet表 Sheet pageSheet = null; //page excel路径 String pageFilePath = pageFileDir+pageName+".xlsx"; //获取定位列的值 String locator = sheet.getRow(rowIndex).getCell(locateColumnIndex).getStringCellValue(); //用.分割开元素定位值 String locatorSplit[] = locator.split("\\."); try { pageBook = new XSSFWorkbook(new FileInputStream(new File(pageFilePath))); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } pageSheet = pageBook.getSheetAt(0); //取得第一个sheet int pageRowNum = pageSheet.getPhysicalNumberOfRows();//得到这个sheet的实际有效行数 for (int j = 0; j < pageRowNum; j++) { //若是获取到的别名和指定的别名相同,就存储当前行的定位值和定位方式 if(pageSheet.getRow(j).getCell(0).getStringCellValue().equalsIgnoreCase(locatorSplit[1])){ elementLocatorWay = pageSheet.getRow(j).getCell(1).getStringCellValue(); elementLocatorValue = pageSheet.getRow(j).getCell(2).getStringCellValue(); break; } } return new String[]{elementLocatorWay,elementLocatorValue}; } /** * @param founction * excel文件的名字 * @param caseName * excel中sheet的名字 * @param seleniumUtil * 引用seleniumUtil * @Description 读取excel中每一个sheet的操做步骤,进而生成测试用例 * */ public static void parseExcel(String founction, String caseName, SeleniumUtil seleniumUtil) { FileInputStream filePath = null; XSSFWorkbook workbook = null; String locateSplit[] = null;//页面sheet中的定位方式和定位值拆解 String locator = null;//用例页面的定位列 String file = "res/testcase/" + founction + ".xlsx"; try { filePath = new FileInputStream(file);// 读取功能模块 } catch (FileNotFoundException e) { logger.error("文件:" + file + "不存在"); Assert.fail("文件:" + file + "不存在"); } try { workbook = new XSSFWorkbook(filePath); } catch (IOException e) { logger.error("IO异常"); Assert.fail("IO异常"); } /**取得指定的case名字*/ Sheet sheet = workbook.getSheet(caseName); /**得到的实际行数*/ int rows = sheet.getPhysicalNumberOfRows(); /** excel中的测试数据*/ String testData = null; //获取首行的单元格数 int cellsNumInOneRow = sheet.getRow(0).getPhysicalNumberOfCells(); //声明一个数组存储列值的角标 String column[] = new String[cellsNumInOneRow]; //声明一个迭代器 Iterator<Cell> cell = sheet.getRow(0).iterator(); int ii =0; while(cell.hasNext()){ column[ii]= String.valueOf(cell.next()); ii++; } //定义动做列的角标 int actionColumnIndex =0; //定义元素定位列的角标 int locateColumnIndex = 0; //定义测试数据列的角标 int testDataColumnIndex = 0; //动态获取这几个关键列所在位置 for (int i = 0; i < column.length; i++) { if(column[i].equals("动做")){ actionColumnIndex = i; } if(column[i].equals("元素定位")){ locateColumnIndex = i; } if(column[i].equals("测试数据")){ testDataColumnIndex = i; } } // 循环每行的操做,根据switch来判断每行的操做是什么,而后转换成具体的代码,从第二行开始循环,由于第一行是列的说明数据。 for (int i = 1; i < rows; i++) { logger.info("正在解析excel:["+founction+".xlsx]中的sheet(用例):["+caseName+"]的第"+i+"行步骤..."); String action = sheet.getRow(i).getCell(actionColumnIndex).getStringCellValue(); Row row = sheet.getRow(i); if (row != null) { switch (action) { case "打开连接": testData = sheet.getRow(i).getCell(testDataColumnIndex).getStringCellValue(); seleniumUtil.get(testData); break; case "导航连接": testData = sheet.getRow(i).getCell(testDataColumnIndex).getStringCellValue(); seleniumUtil.get(testData); break; case "输入": //先设置Cell的类型,而后就能够把纯数字做为String类型读进来了 sheet.getRow(i).getCell(testDataColumnIndex).setCellType(Cell.CELL_TYPE_STRING); testData = sheet.getRow(i).getCell(testDataColumnIndex).getStringCellValue(); //测试数据 locator = sheet.getRow(i).getCell(locateColumnIndex).getStringCellValue();//获取步骤中的元素定位 //locator.split("\\.")[0]分离出页面名称,好比HomePage.个人单据,提取出HomePage locateSplit = getPageElementLocator(sheet, i, locateColumnIndex,locator.split("\\.")[0]); //找到定位方式、定位值 seleniumUtil.type(getLocateWay(locateSplit[0], locateSplit[1]), testData); break; case "点击": locator = sheet.getRow(i).getCell(locateColumnIndex).getStringCellValue();//获取步骤中的定位 //locator.split("\\.")[0]分离出页面名称,好比HomePage.个人单据,提取出HomePage locateSplit = getPageElementLocator(sheet, i, locateColumnIndex,locator.split("\\.")[0]); seleniumUtil.click(getLocateWay(locateSplit[0], locateSplit[1])); break; case "暂停": //先设置Cell的类型,而后就能够把纯数字做为String类型读进来了 sheet.getRow(i).getCell(testDataColumnIndex).setCellType(Cell.CELL_TYPE_STRING); testData = sheet.getRow(i).getCell(testDataColumnIndex).getStringCellValue(); seleniumUtil.pause(Integer.parseInt(testData)); break; case "等待元素": //先设置Cell的类型,而后就能够把纯数字做为String类型读进来了 sheet.getRow(i).getCell(testDataColumnIndex).setCellType(Cell.CELL_TYPE_STRING); testData = sheet.getRow(i).getCell(testDataColumnIndex).getStringCellValue(); locator = sheet.getRow(i).getCell(locateColumnIndex).getStringCellValue();//获取步骤中的定位 //locator.split("\\.")[0]分离出页面名称,好比HomePage.个人单据,提取出HomePage locateSplit = getPageElementLocator(sheet, i, locateColumnIndex,locator.split("\\.")[0]); seleniumUtil.waitForElementToLoad(Integer.parseInt(testData), getLocateWay(locateSplit[0], locateSplit[1])); break; case "查找元素(尝试3次)": //先设置Cell的类型,而后就能够把纯数字做为String类型读进来了 sheet.getRow(i).getCell(testDataColumnIndex).setCellType(Cell.CELL_TYPE_STRING); testData = sheet.getRow(i).getCell(testDataColumnIndex).getStringCellValue(); locator = sheet.getRow(i).getCell(locateColumnIndex).getStringCellValue();//获取步骤中的定位 //locator.split("\\.")[0]分离出页面名称,好比HomePage.个人单据,提取出HomePage locateSplit = getPageElementLocator(sheet, i, locateColumnIndex,locator.split("\\.")[0]); seleniumUtil.FindElementUtil3TimesTry(Integer.parseInt(testData), getLocateWay(locateSplit[0], locateSplit[1])); break; case "清除": locator = sheet.getRow(i).getCell(locateColumnIndex).getStringCellValue();//获取步骤中的定位 //locator.split("\\.")[0]分离出页面名称,好比HomePage.个人单据,提取出HomePage locateSplit = getPageElementLocator(sheet, i, locateColumnIndex,locator.split("\\.")[0]); seleniumUtil.clear(getLocateWay(locateSplit[0], locateSplit[1])); break; case "进入iFrame": locator = sheet.getRow(i).getCell(locateColumnIndex).getStringCellValue();//获取步骤中的定位 //locator.split("\\.")[0]分离出页面名称,好比HomePage.个人单据,提取出HomePage locateSplit = getPageElementLocator(sheet, i, locateColumnIndex,locator.split("\\.")[0]); seleniumUtil.switchFrame(getLocateWay(locateSplit[0], locateSplit[1])); break; case "跳出iFrame": seleniumUtil.outFrame(); break; case "选择下拉列表 - Text": //先设置Cell的类型,而后就能够把纯数字做为String类型读进来了 sheet.getRow(i).getCell(testDataColumnIndex).setCellType(Cell.CELL_TYPE_STRING); testData = sheet.getRow(i).getCell(testDataColumnIndex).getStringCellValue(); locator = sheet.getRow(i).getCell(locateColumnIndex).getStringCellValue();//获取步骤中的定位 //locator.split("\\.")[0]分离出页面名称,好比HomePage.个人单据,提取出HomePage locateSplit = getPageElementLocator(sheet, i, locateColumnIndex,locator.split("\\.")[0]); seleniumUtil.selectByText(getLocateWay(locateSplit[0], locateSplit[1]), testData); break; case "选择下拉列表 - Index": //先设置Cell的类型,而后就能够把纯数字做为String类型读进来了 sheet.getRow(i).getCell(testDataColumnIndex).setCellType(Cell.CELL_TYPE_STRING); testData = sheet.getRow(i).getCell(testDataColumnIndex).getStringCellValue(); locator = sheet.getRow(i).getCell(locateColumnIndex).getStringCellValue();//获取步骤中的定位 //locator.split("\\.")[0]分离出页面名称,好比HomePage.个人单据,提取出HomePage locateSplit = getPageElementLocator(sheet, i, locateColumnIndex,locator.split("\\.")[0]); seleniumUtil.selectByIndex(getLocateWay(locateSplit[0], locateSplit[1]), Integer.parseInt(testData)); break; case "选择下拉列表 - Value": //先设置Cell的类型,而后就能够把纯数字做为String类型读进来了 sheet.getRow(i).getCell(testDataColumnIndex).setCellType(Cell.CELL_TYPE_STRING); testData = sheet.getRow(i).getCell(testDataColumnIndex).getStringCellValue(); locator = sheet.getRow(i).getCell(locateColumnIndex).getStringCellValue();//获取步骤中的定位 //locator.split("\\.")[0]分离出页面名称,好比HomePage.个人单据,提取出HomePage locateSplit = getPageElementLocator(sheet, i, locateColumnIndex,locator.split("\\.")[0]); seleniumUtil.selectByValue(getLocateWay(locateSplit[0], locateSplit[1]),testData ); break; case "检查文本 - 属性": testData = sheet.getRow(i).getCell(testDataColumnIndex).getStringCellValue(); locator = sheet.getRow(i).getCell(locateColumnIndex).getStringCellValue();//获取步骤中的定位 //locator.split("\\.")[0]分离出页面名称,好比HomePage.个人单据,提取出HomePage locateSplit = getPageElementLocator(sheet, i, locateColumnIndex,locator.split("\\.")[0]); String[] Datas = testData.split(","); seleniumUtil.isTextCorrect(seleniumUtil.getAttributeText(getLocateWay(locateSplit[0], locateSplit[1]), Datas[0]),Datas[1]); break; case "得到网页标题": testData = sheet.getRow(i).getCell(testDataColumnIndex).getStringCellValue(); seleniumUtil.isTextCorrect(seleniumUtil.getTitle(),testData); break; case "页面的URL是否正确": testData = sheet.getRow(i).getCell(testDataColumnIndex).getStringCellValue(); seleniumUtil.isTextCorrect(seleniumUtil.getPageURL(), testData); break; case "检查文本": testData = sheet.getRow(i).getCell(testDataColumnIndex).getStringCellValue(); locator = sheet.getRow(i).getCell(locateColumnIndex).getStringCellValue();//获取步骤中的定位 //locator.split("\\.")[0]分离出页面名称,好比HomePage.个人单据,提取出HomePage locateSplit = getPageElementLocator(sheet, i, locateColumnIndex,locator.split("\\.")[0]); seleniumUtil.isTextCorrect(seleniumUtil.getText(getLocateWay(locateSplit[0], locateSplit[1])), testData); break; case "进入Tab": //须要改进,第二个窗口的driver问题 locator = sheet.getRow(i).getCell(locateColumnIndex).getStringCellValue();//获取步骤中的定位 //locator.split("\\.")[0]分离出页面名称,好比HomePage.个人单据,提取出HomePage locateSplit = getPageElementLocator(sheet, i, locateColumnIndex,locator.split("\\.")[0]); seleniumUtil.switchNewWindow(getLocateWay(locateSplit[0], locateSplit[1])); break; case "跳出Tab": seleniumUtil.backToOriginalWindow(); break; case "接受alert弹窗": //先设置Cell的类型,而后就能够把纯数字做为String类型读进来了 sheet.getRow(i).getCell(testDataColumnIndex).setCellType(Cell.CELL_TYPE_STRING); testData = sheet.getRow(i).getCell(testDataColumnIndex).getStringCellValue(); a = seleniumUtil.switchToPromptedAlertAfterWait(Long.parseLong(testData)); a.accept(); break; case "取消alert弹窗": //先设置Cell的类型,而后就能够把纯数字做为String类型读进来了 sheet.getRow(i).getCell(testDataColumnIndex).setCellType(Cell.CELL_TYPE_STRING); testData = sheet.getRow(i).getCell(testDataColumnIndex).getStringCellValue(); a = seleniumUtil.switchToPromptedAlertAfterWait(Long.parseLong(testData)); a.dismiss(); break; case "执行JS点击": locator = sheet.getRow(i).getCell(locateColumnIndex).getStringCellValue();//获取步骤中的定位 //locator.split("\\.")[0]分离出页面名称,好比HomePage.个人单据,提取出HomePage locateSplit = getPageElementLocator(sheet, i, locateColumnIndex,locator.split("\\.")[0]); seleniumUtil.executeJS("arguments[0].click();", seleniumUtil.findElementBy(getLocateWay(locateSplit[0], locateSplit[1]))); break; case "刷新页面": seleniumUtil.refresh(); break; case "前进页面": seleniumUtil.back(); break; case "后退页面": seleniumUtil.forward(); break; case "上传文件": testData = sheet.getRow(i).getCell(testDataColumnIndex).getStringCellValue(); String uploadValues[] = testData.split(","); seleniumUtil.handleUpload(uploadValues[0], new File(uploadValues[1])); break; case "元素被启用": locator = sheet.getRow(i).getCell(locateColumnIndex).getStringCellValue();//获取步骤中的定位 //locator.split("\\.")[0]分离出页面名称,好比HomePage.个人单据,提取出HomePage locateSplit = getPageElementLocator(sheet, i, locateColumnIndex,locator.split("\\.")[0]); if(seleniumUtil.isEnabled(getLocateWay(locateSplit[0], locateSplit[1]))){ logger.info(getLocateWay(locateSplit[0], locateSplit[1])+"元素被启用"); }else{ Assert.fail(getLocateWay(locateSplit[0], locateSplit[1])+":没有被启用"); } break; case "元素未启用": locator = sheet.getRow(i).getCell(locateColumnIndex).getStringCellValue();//获取步骤中的定位 //locator.split("\\.")[0]分离出页面名称,好比HomePage.个人单据,提取出HomePage locateSplit = getPageElementLocator(sheet, i, locateColumnIndex,locator.split("\\.")[0]); if(seleniumUtil.isEnabled(getLocateWay(locateSplit[0], locateSplit[1]))){ Assert.fail(getLocateWay(locateSplit[0], locateSplit[1])+"元素被启用"); }else{ logger.info(getLocateWay(locateSplit[0], locateSplit[1])+":没有被启用"); } break; case "验证首页菜单栏文本": locator = sheet.getRow(i).getCell(locateColumnIndex).getStringCellValue();//获取步骤中的定位 //locator.split("\\.")[0]分离出页面名称,好比HomePage.个人单据,提取出HomePage locateSplit = getPageElementLocator(sheet, i, locateColumnIndex,locator.split("\\.")[0]); testData = sheet.getRow(i).getCell(testDataColumnIndex).getStringCellValue(); String menus[] = testData.split(","); for (int i1 = 0; i1 < menus.length; i1++) { seleniumUtil.isTextCorrect(seleniumUtil.findElementsBy(getLocateWay(locateSplit[0], locateSplit[1])).get(i1).getText().trim().toLowerCase(), menus[i1].toLowerCase()); } break; default: logger.error("你输入的操做:["+action+"]不被支持,请自行添加"); Assert.fail("你输入的操做:["+action+"]不被支持,请自行添加"); } } } } }
SeleniumUtil.java代码以下:
package com.demo.test.utils; import java.awt.AWTException; import java.awt.Robot; import java.awt.event.KeyEvent; import java.io.File; import java.util.Calendar; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.concurrent.TimeUnit; import org.apache.log4j.Logger; import org.openqa.selenium.Alert; import org.openqa.selenium.By; import org.openqa.selenium.Cookie; import org.openqa.selenium.Dimension; import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.Keys; import org.openqa.selenium.NoAlertPresentException; import org.openqa.selenium.NoSuchElementException; import org.openqa.selenium.StaleElementReferenceException; import org.openqa.selenium.TimeoutException; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.interactions.Actions; import org.openqa.selenium.support.ui.ExpectedCondition; import org.openqa.selenium.support.ui.Select; import org.openqa.selenium.support.ui.WebDriverWait; import org.testng.Assert; import org.testng.ITestContext; import org.testng.ITestResult; /** * @Description 包装全部selenium的操做以及通用方法,简化用例中代码量 * */ public class SeleniumUtil { /** 使用Log4j,第一步就是获取日志记录器,这个记录器将负责控制日志信息 */ public static Logger logger = Logger.getLogger(SeleniumUtil.class.getName()); public ITestResult it = null; public WebDriver driver = null; public WebDriver window = null; public String current_handles=""; /*** * 启动浏览器并打开页面 * */ public void launchBrowser(String browserName, ITestContext context,String webUrl,int timeOut) { SelectBrowser select = new SelectBrowser(); driver = select.selectExplorerByName(browserName, context); try { maxWindow(browserName); waitForPageLoading(timeOut); get(webUrl); } catch (TimeoutException e) { logger.warn("注意:页面没有彻底加载出来,刷新重试!!"); refresh(); JavascriptExecutor js = (JavascriptExecutor)driver; String status= (String)js.executeScript("return document.readyState"); logger.info("打印状态:"+status); } } /** * 最大化浏览器操做 * */ public void maxWindow(String browserName) { logger.info("最大化浏览器:" + browserName); driver.manage().window().maximize(); } /** * 设定浏览器窗口大小: 设置浏览器窗口的大小有下面两个比较常见的用途:<br> * 一、在统一的浏览器大小下运行用例,能够比较容易的跟一些基于图像比对的工具进行结合 * ,提高测试的灵活性及广泛适用性。好比能够跟sikuli结合,使用sikuli操做flash;<br> * 二、在不一样的浏览器大小下访问测试站点,对测试页面截图并保存,而后观察或使用图像比对工具对被测页面的前端样式进行评测。 * 好比能够将浏览器设置成移动端大小(320x480),而后访问移动站点,对其样式进行评估;<br> * */ public void setBrowserSize(int width, int height) { driver.manage().window().setSize(new Dimension(width, height)); } /** * 包装查找元素的方法 element * */ public WebElement findElementBy(By by) { return driver.findElement(by); } /** * 包装查找元素的方法 elements * */ public List<WebElement> findElementsBy(By by) { return driver.findElements(by); } /**导航连接到url*/ public void navigateTargetUrl(String url){ driver.navigate().to(url); logger.info("导航到:"+url); } /** * 包装点击操做- By * */ public void click(By byElement) { try { clickTheClickable(byElement, System.currentTimeMillis(), 2500); } catch (StaleElementReferenceException e) { logger.error("The element you clicked:[" + byElement + "] is no longer exist!"); Assert.fail("The element you clicked:[" + byElement + "] is no longer exist!"); } catch (Exception e) { logger.error("Failed to click element [" + byElement + "]"); Assert.fail("Failed to click element [" + byElement + "]",e); } logger.info("点击元素 [" + byElement + "]"); } public boolean isEnabled(By by){ return driver.findElement(by).isEnabled(); } /**提交*/ public void submit(WebElement w){ try{ w.submit(); }catch(Exception e){ logger.error("在元素:"+w+"作的提交操做失败"); Assert.fail("在元素:"+w+"作的提交操做失败"); } logger.info("在元素:"+w+"作了提交操做"); } /** * 包装点击操做 -webelment * */ public void click(WebElement element) { try { element.click(); } catch (StaleElementReferenceException e) { logger.error("The element you clicked:[" + element.toString() + "] is no longer exist!"); Assert.fail("The element you clicked:[" + element.toString() + "] is no longer exist!"); } catch (Exception e) { logger.error("Failed to click element [" + element.toString() + "]"); Assert.fail("Failed to click element [" + element.toString() + "]",e); } logger.info("点击元素 [" + element.toString() + "]"); } /** 不能点击时候重试点击操做 */ public void clickTheClickable(By byElement, long startTime, int timeOut) throws Exception { try { findElementBy(byElement).click(); } catch (Exception e) { if (System.currentTimeMillis() - startTime > timeOut) { logger.warn(byElement+ " is unclickable"); throw new Exception(e); } else { Thread.sleep(500); logger.warn(byElement + " is unclickable, try again"); clickTheClickable(byElement, startTime, timeOut); } } } /** * 得到页面的标题 * */ public String getTitle() { return driver.getTitle(); } /** * 得到元素的文本 * */ public String getText(By elementLocator) { return driver.findElement(elementLocator).getText().trim(); } /** * 得到元素 属性的文本 * */ public String getAttributeText(By elementLocator, String attribute) { return driver.findElement(elementLocator).getAttribute(attribute).trim(); } /** * 包装清除操做 * */ public void clear(By byElement) { try { findElementBy(byElement).clear(); } catch (Exception e) { logger.error("清除元素 [" + byElement + "] 上的内容失败!"); } logger.info("清除元素 [" + byElement + "]上的内容"); } /** * 向输入框输入内容 * */ public void type(By byElement, String key) { try { findElementBy(byElement).sendKeys(key); } catch (Exception e) { e.printStackTrace(); logger.error("输入 [" + key + "] 到 元素[" + byElement + "]失败"); Assert.fail("输入 [" + key + "] 到 元素[" + byElement + "]失败",e); } logger.info("输入:[" + key + "] 到 [" + byElement + "]"); } /** * 模拟键盘操做的,好比Ctrl+A,Ctrl+C等 参数详解:<br> * 一、WebElement element - 要被操做的元素 <br> * 二、Keys key- 键盘上的功能键 好比ctrl ,alt等 <br> * 三、String keyword - 键盘上的字母 * */ public void pressKeysOnKeyboard(WebElement element, Keys key, String keyword) { element.sendKeys(Keys.chord(key, keyword)); } /** * 在给定的时间内去查找元素,若是没找到则超时,抛出异常 * */ public void waitForElementToLoad(int timeOut, final By By) { logger.info("开始查找元素[" + By + "]"); try { (new WebDriverWait(driver, timeOut)).until(new ExpectedCondition<Boolean>() { public Boolean apply(WebDriver driver) { WebElement element = driver.findElement(By); return element.isDisplayed(); } }); } catch (TimeoutException e) { logger.error("超时!! " + timeOut + " 秒以后还没找到元素 [" + By + "]"); Assert.fail("超时!! " + timeOut + " 秒以后还没找到元素 [" + By + "]"); } logger.info("找到了元素 [" + By + "]"); } /** * 在给定的时间内查询元素,共尝试三次,若是第三次仍是找不到就报错,这就多是网页性能问题了,响应速度不够 * */ public void FindElementUtil3TimesTry(int timeOut, final By By ) { int find=0; int notFindTimes = 0; boolean flag = true; while(flag){ if(notFindTimes==3){ logger.error("尝试了3次查找都未查找到元素:"+By+"请检查是否是网络或者网站性能问题(响应速度不够)"); Assert.fail("尝试了3次查找都未查找到元素:"+By+"请检查是否是网络或者网站性能问题(响应速度不够)"); } logger.info("开始第"+(notFindTimes+1)+"次查找元素[" + By + "]"); try { (new WebDriverWait(driver, timeOut)).until(new ExpectedCondition<Boolean>() { public Boolean apply(WebDriver driver) { WebElement element = driver.findElement(By); return element.isDisplayed(); } }); find++; } catch (TimeoutException e) { logger.warn("超时!! " + timeOut + " 秒以后还没找到元素 [" + By + "],这是第"+(notFindTimes+1)+"次查找!"); notFindTimes++; if(notFindTimes<3){ refresh(); } } if(notFindTimes>0&find!=1){ flag = true; }else{ flag = false; } } logger.info("找到了元素 [" + By + "]"); } /** * 判断文本是否是和需求要求的文本一致 * **/ public void isTextCorrect(String actual, String expected) { try { Assert.assertEquals(actual, expected); } catch (AssertionError e) { logger.error("指望的文字是 [" + expected + "] 可是找到了 [" + actual + "]"); Assert.fail("指望的文字是 [" + expected + "] 可是找到了 [" + actual + "]"); } logger.info("找到了指望的文字: [" + expected + "]"); } /** * 判断编辑框是否是可编辑 * */ public void isInputEdit(WebElement element) { } /** * 等待alert出现 * */ public Alert switchToPromptedAlertAfterWait(long waitMillisecondsForAlert) throws NoAlertPresentException { final int ONE_ROUND_WAIT = 200; NoAlertPresentException lastException = null; long endTime = System.currentTimeMillis() + waitMillisecondsForAlert; for (long i = 0; i < waitMillisecondsForAlert; i += ONE_ROUND_WAIT) { try { Alert alert = driver.switchTo().alert(); return alert; } catch (NoAlertPresentException e) { lastException = e; } try { Thread.sleep(ONE_ROUND_WAIT); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } if (System.currentTimeMillis() > endTime) { break; } } throw lastException; } /** * 暂停当前用例的执行,暂停的时间为:sleepTime * */ public void pause(int sleepTime) { if (sleepTime <= 0) { return; } try { TimeUnit.SECONDS.sleep(sleepTime); logger.info("暂停:"+sleepTime+"秒"); } catch (InterruptedException e) { e.printStackTrace(); } } /** * 退出 * */ public void quit() { driver.quit(); } /** * 切换frame - 根据String类型(frame名字) * */ public void inFrame(String frameId) { driver.switchTo().frame(frameId); } /** * 切换frame - 根据frame在当前页面中的顺序来定位 * */ public void inFrame(int frameNum) { driver.switchTo().frame(frameNum); } /** * 切换frame - 根据页面元素定位 * */ public void switchFrame(By byElement) { try { logger.info("Start switching to frame [" + byElement + "]"); driver.switchTo().frame(findElementBy(byElement)); } catch (Exception e) { logger.info("Switch to frame [" + byElement + "] failed"); Assert.fail("Switch to frame [" + byElement + "] failed"); } logger.info("Switch to frame [" + byElement + "] successed"); } /** * 选择下拉选项 -根据value * */ public void selectByValue(By by, String value) { Select s = new Select(driver.findElement(by)); s.selectByValue(value); } /** * 选择下拉选项 -根据index角标 * */ public void selectByIndex(By by, int index) { Select s = new Select(driver.findElement(by)); s.selectByIndex(index); } /** 检查checkbox是否是勾选 */ public boolean doesCheckboxSelected(By elementLocator) { if (findElementBy(elementLocator).isSelected() == true) { logger.info("CheckBox: " + getLocatorByElement(findElementBy(elementLocator), ">") + " 被勾选"); return true; } else logger.info("CheckBox: " + getLocatorByElement(findElementBy(elementLocator), ">") + " 没有被勾选"); return false; } /** * 选择下拉选项 -根据文本内容 * */ public void selectByText(By by, String text) { Select s = new Select(driver.findElement(by)); s.selectByVisibleText(text); logger.info("你选择了:"+text); } /** * 得到当前select选择的值 * */ public String getCurrentSelectValue(By by){ Select s = new Select(driver.findElement(by)); WebElement e = s.getFirstSelectedOption(); return e.getText().trim(); } /** * 获取下拉列表的全部选项 * @param By:By元素对象 * @return 返回全部下拉列表中的选项,如option1,option2,…… * */ public String getSelectOption(By by) { String value = null; Select s = new Select(driver.findElement(by)); List<WebElement> options = s.getOptions(); for(int i = 0 ; i< options.size() ; i++){ value = value + "," + options.get(i).getText(); } return value.replace("null,",""); } /** * 执行JavaScript 方法 * */ public void executeJS(String js) { ((JavascriptExecutor) driver).executeScript(js); logger.info("执行JavaScript语句:[" + js + "]"); } /** * 得到输入框的值 这个方法 是针对某些input输入框 没有value属性,可是又想取得input的 值得方法 * */ public String getInputValue(String chose,String choseValue) { String value = null; switch(chose.toLowerCase()){ case "name": String jsName = "return document.getElementsByName('"+choseValue+"')[0].value;"; //把JS执行的值 返回出去 value = (String)((JavascriptExecutor) driver).executeScript(jsName); break; case "id": String jsId = "return document.getElementById('"+choseValue+"').value;"; //把JS执行的值 返回出去 value = (String)((JavascriptExecutor) driver).executeScript(jsId); break; default: logger.error("未定义的chose:"+chose); Assert.fail("未定义的chose:"+chose); } return value; } /** * 执行JavaScript 方法和对象 * 用法:seleniumUtil.executeJS("arguments[0].click();", seleniumUtil.findElementBy(MyOrdersPage.MOP_TAB_ORDERCLOSE)); * */ public void executeJS(String js, Object... args) { ((JavascriptExecutor) driver).executeScript(js, args); logger.info("执行JavaScript语句:[" + js + "]"); } /** * get方法包装 * */ public void get(String url) { driver.get(url); logger.info("打开测试页面:[" + url + "]"); } /** * close方法包装 * */ public void close() { driver.close(); } /** * 刷新方法包装 * */ public void refresh() { driver.navigate().refresh(); logger.info("页面刷新成功!"); } /** * 后退方法包装 * */ public void back() { driver.navigate().back(); } /** * 前进方法包装 * */ public void forward() { driver.navigate().forward(); } /** * 包装selenium模拟鼠标操做 - 鼠标移动到指定元素 * */ public void mouseMoveToElement(By by) { Actions builder = new Actions(driver); Actions mouse = builder.moveToElement(driver.findElement(by)); mouse.perform(); } /** * 包装selenium模拟鼠标操做 - 鼠标移动到指定元素 * */ public void mouseMoveToElement(WebElement element) { Actions builder = new Actions(driver); Actions mouse = builder.moveToElement(element); mouse.perform(); } /** * 包装selenium模拟鼠标操做 - 鼠标右击 * */ public void mouseRightClick(By element) { Actions builder = new Actions(driver); Actions mouse = builder.contextClick(findElementBy(element)); mouse.perform(); } /** * 添加cookies,作自动登录的必要方法 * */ public void addCookies(int sleepTime) { pause(sleepTime); Set<Cookie> cookies = driver.manage().getCookies(); for (Cookie c : cookies) { System.out.println(c.getName() + "->" + c.getValue()); if (c.getName().equals("logisticSessionid")) { Cookie cook = new Cookie(c.getName(), c.getValue()); driver.manage().addCookie(cook); System.out.println(c.getName() + "->" + c.getValue()); System.out.println("添加成功"); } else { System.out.println("没有找到logisticSessionid"); } } } /** 得到CSS value */ public String getCSSValue(WebElement e, String key) { return e.getCssValue(key); } /** 使用testng的assetTrue方法 */ public void assertTrue(WebElement e, String content) { String str = e.getText(); Assert.assertTrue(str.contains(content), "字符串数组中不含有:" + content); } /** 跳出frame */ public void outFrame() { driver.switchTo().defaultContent(); } // webdriver中能够设置不少的超时时间 /** implicitlyWait。识别对象时的超时时间。过了这个时间若是对象还没找到的话就会抛出NoSuchElement异常 */ public void implicitlyWait(int timeOut) { driver.manage().timeouts().implicitlyWait(timeOut, TimeUnit.SECONDS); } /** setScriptTimeout。异步脚本的超时时间。webdriver能够异步执行脚本,这个是设置异步执行脚本脚本返回结果的超时时间 */ public void setScriptTimeout(int timeOut) { driver.manage().timeouts().setScriptTimeout(timeOut, TimeUnit.SECONDS); } /** * pageLoadTimeout。页面加载时的超时时间。由于webdriver会等页面加载完毕在进行后面的操做, * 因此若是页面在这个超时时间内没有加载完成,那么webdriver就会抛出异常 */ public void waitForPageLoading(int pageLoadTime) { driver.manage().timeouts().pageLoadTimeout(pageLoadTime, TimeUnit.SECONDS); } /** 根据元素来获取此元素的定位值 */ public String getLocatorByElement(WebElement element, String expectText) { String text = element.toString(); String expect = null; try { expect = text.substring(text.indexOf(expectText) + 1, text.length() - 1); } catch (Exception e) { e.printStackTrace(); logger.error("failed to find the string [" + expectText + "]"); } return expect; } /** * 获取当前页面的URL * */ public String getPageURL(){ return driver.getCurrentUrl(); } /** * 这是一堆相同的elements中 选择 其中方的 一个 而后在这个选定的中 继续定位 * */ public WebElement getOneElement(By bys, By by, int index) { return findElementsBy(bys).get(index).findElement(by); } /** * 上传文件,须要点击弹出上传照片的窗口才行 * * @param brower * 使用的浏览器名称 * @param file * 须要上传的文件及文件名 */ public void handleUpload(String browser, File file) { String filePath = file.getAbsolutePath(); String executeFile = "res/script/autoit/Upload.exe"; String cmd = "\"" + executeFile + "\"" + " " + "\"" + browser + "\"" + " " + "\"" + filePath + "\""; try { Process p = Runtime.getRuntime().exec(cmd); p.waitFor(); } catch (Exception e) { e.printStackTrace(); } } /** * @Description 对于windows GUI弹出框,要求输入用户名和密码时, * seleniumm不能直接操做,须要借助http://modifyusername:modifypassword@yoururl 这种方法 * * */ public void loginOnWinGUI(String username, String password, String url) { driver.get(username + ":" + password + "@" + url); } /** 检查元素是否显示 */ public boolean isDisplayed(WebElement element) { boolean isDisplay = false; if (element.isDisplayed()) { logger.info("The element: [" + getLocatorByElement(element, ">") + "] is displayed"); isDisplay = true; } else if (element.isDisplayed() == false) { logger.warn("The element: [" + getLocatorByElement(element, ">") + "] is not displayed"); isDisplay = false; } return isDisplay; } /**检查元素是否是存在*/ public boolean doesElementsExist(By byElement){ try{ findElementBy(byElement); return true; }catch(NoSuchElementException nee){ return false; } } /** 检查元素是否被勾选 */ public boolean isSelected(WebElement element) { boolean flag = false; if (element.isSelected() == true) { logger.info("The element: [" + getLocatorByElement(element, ">") + "] is selected"); flag = true; } else if (element.isSelected() == false) { logger.info("The element: [" + getLocatorByElement(element, ">") + "] is not selected"); flag = false; } return flag; } /** * 判断实际文本时候包含指望文本 * * @param actual * 实际文本 * @param expect * 指望文本 */ public void isContains(String actual, String expect) { try { Assert.assertTrue(actual.contains(expect)); } catch (AssertionError e) { logger.error("The [" + actual + "] is not contains [" + expect + "]"); Assert.fail("The [" + actual + "] is not contains [" + expect + "]"); } logger.info("The [" + actual + "] is contains [" + expect + "]"); } /** * 判断实际文本,不包含指望文本 * * @param actual * 实际文本 * @param expect * 指望文本 */ public void isNotContains(String actual, String expect) { try { Assert.assertFalse(actual.contains(expect)); } catch (AssertionError e) { logger.error("The [" + actual + "] is contains [" + expect + "]"); Assert.fail("The [" + actual + "] is contains [" + expect + "]"); } logger.info("The [" + actual + "] is not contains [" + expect + "]"); } /** 得到屏幕的分辨率 - 宽 */ public double getScreenWidth() { return java.awt.Toolkit.getDefaultToolkit().getScreenSize().getWidth(); } /**进入新窗口*/ public void switchNewWindow(By byElement){ //获取当前页面句柄 current_handles = driver.getWindowHandle(); //点击某个连接会弹出一个新窗口 click(byElement); //接下来会有新的窗口打开,获取全部窗口句柄 Set<String> all_handles = driver.getWindowHandles(); //循环判断,把当前句柄从全部句柄中移除,剩下的就是你想要的新窗口 Iterator<String> it = all_handles.iterator(); while(it.hasNext()){ if(current_handles == it.next()) continue; //跳入新窗口,并得到新窗口的driver - newWindow window = driver.switchTo().window(it.next()); } } /**回到原始窗口*/ public void backToOriginalWindow(){ window.close(); driver.switchTo().window(current_handles); } /**中止页面加载*/ public void stopLoad(){ pause(1); Robot r; try { r = new Robot(); r.keyPress(KeyEvent.VK_ESCAPE); logger.info("按下了Esc键"); r.keyRelease(KeyEvent.VK_ESCAPE); logger.info("松开了Esc键"); } catch (AWTException e) { e.printStackTrace(); } logger.info("正在中止页面加载..."); } /**获取系统时间*/ public int getDate(String getOption){ Calendar a=Calendar.getInstance(); int result=0; switch(getOption){ case "年": result = a.get(Calendar.YEAR); break; case "月": result = a.get(Calendar.MONTH)+1; break; case "日": result = a.get(Calendar.DATE); break; default: Assert.fail("只支持输入年、月、日。你输入了:"+getOption); } return result; } /**判断alert是否出现*/ public boolean isAlertPresent(){ try { driver.switchTo().alert(); logger.info("alert出现"); return true; } catch (NoAlertPresentException Ex) { logger.warn("alert没有出现"); return false; } } /**CMP干部绩效管理系统登陆操做*/ public void loginCMP(String username,String password){ FindElementUtil3TimesTry(30, By.id("account")); FindElementUtil3TimesTry(30, By.id("password")); FindElementUtil3TimesTry(30, By.id("bLogin")); type(By.id("account"),username); type(By.id("password"),password); click(By.id("bLogin")); } /** * 在多个相同元素中,定位到指定的元素 * @param by * @param index * @return */ public WebElement getOneElement(By by, int index) { List<WebElement> element = driver.findElements(by); return element.get(index); } /** * 获取指定table某一整列的值 */ public String getColumnText(By by){ String values = null; List<WebElement> elements = findElementsBy(by); for(WebElement e: elements){ String value = e.getText(); if(value.length() > 0){ values = values + "," + value; } } return values.replace("null,", ""); } /** * 获取指定table某一行的值 * @param index:行号,行号从1开始(0表明table的表头) */ public String getRowText(By by, int index){ String values = null; List<WebElement> rows = findElementsBy(by); //tr对象 WebElement row = rows.get(index); if(row.findElements(By.tagName("td")).size()>0){ List<WebElement> cells = row.findElements(By.tagName("td")); //td对象 for(WebElement cell:cells){ String value = cell.getText(); if(value.length() > 0){ values = values + "," + value; } } } return values.replace("null,", ""); } /** * 获取指定table个单元格的值 * @param index:行号,行号从1开始(0表明table的表头) */ public String getCellText(By by, int RowID, int ColID){ String value = null; //获得table元素对象 WebElement table = driver.findElement(by); //获得table表中全部行对象,并获得所要查询的行对象。 List<WebElement> rows = table.findElements(By.tagName("tr")); WebElement theRow = rows.get(RowID); //调用getCell方法获得对应的列对象,而后获得要查询的文本。 value = getCell(theRow, ColID).getText(); return value.replace("null,", ""); } /** * * @param Row: 一行的对象 * @param ColID:对应列 * @return */ private WebElement getCell(WebElement Row,int ColID){ List<WebElement> cells; WebElement target = null; //列里面有"<th>"、"<td>"两种标签,因此分开处理。 if(Row.findElements(By.tagName("th")).size()>0){ cells = Row.findElements(By.tagName("th")); target = cells.get(ColID); } if(Row.findElements(By.tagName("td")).size()>0){ cells = Row.findElements(By.tagName("td")); target = cells.get(ColID); } return target; } /** * 在给定的时间内去查找元素,若是没找到则超时,抛出异常 * */ public boolean isShown(int timeOut, final By By) { boolean flag = true; logger.info("开始查找元素[" + By + "]"); try { (new WebDriverWait(driver, timeOut)).until(new ExpectedCondition<Boolean>() { public Boolean apply(WebDriver driver) { WebElement element = driver.findElement(By); return element.isDisplayed(); } }); } catch (TimeoutException e) { flag = false; } return flag; } /**页面过长时候滑动页面 window.scrollTo(左边距,上边距); */ public void scrollPage(int x,int y){ String js ="window.scrollTo("+x+","+y+");"; ((JavascriptExecutor)driver).executeScript(js); } }