Selenium Web 自动化 - 项目实战(三)

2016-08-10

目录

1 关键字驱动概述
2 框架更改总览
3 框架更改详解
  3.1 解析新增页面目录
  3.2 解析新增测试用例目录
  3.3 解析自动生成代码
  3.4 读取用例excel数据,定位元素,并进行操作
  3.5 更改SeleniumUtil.java

源代码:autotestKeywordDrive.zip

1 关键字驱动概述


返回

关键字驱动测试(Keyword-driven testing),也叫做表格驱动测试或者基于行为词的测试。

关键字驱动到底是什么样的?

见图3,动作也就是关键字,比如你选择了“点击”操作,就意味着这步骤会执行一个元素点击操作。

关键子驱动是如何实现的:

问:那么如何定义动作?

答:在框架设计的时候会专门设计一个类,来实现各种“动作”的具体内容。当你在excel中读取了一个“动作”之后,框架会自动解析这个“动作”背后的事情。在测试框架中这个类的名字叫做:SuperAction.java。

问:如何定义和解析元素定位?

答:见图2,每个页面是一个excel,所有元素的定位方式和定位值都保存在里面

问:如何用例存储?

答:见图3,一个excel就是一个模块,然后这个excel文件中一个sheet就是这个模块中的一条用例

问:Excel文件如何执行测试?

答:excel文件存储用例,但excel只是文件,如何调用测试入口呢?其实在关键字驱动框架中,有一个用例生成类(TestCaseFactoryForSingle.java,TestCaseFactoryForAll.java),它可以遍历所有excel的所有sheet,生产一条条用例类,见图6

关键字优缺点:

  • 优点:只需要自动化测试人员封装好相关关键字操作,就可以提供给黑盒测试人员用,黑盒测试人员只需要掌握元素定位的方式以及对关键字框架的使用即可·条理清晰,很容易上手使用
  • 缺点:需要自动化测试人员花费大量时间提前把关键字框架中的操作提前封装好对于复杂的测试需求,关键字框架对于操作的封装难度较大

2 框架更改总览


返回

在原来的框架下更改,如下图所示

图1 关键子驱动与数据驱动比较

3 框架更改详解


返回

在原来的框架下更改,如下图所示

3.1 解析新增页面目录

page: 存储页面元素的目录,在此目录下每个页面是一个excel,会替换原先框架的com.demo.test.pages包,如图1所示。

图2 page 元素定位excel

3.2 解析新增测试用例目录

testcase:存储测试用例的目录,每个模块一个excel文件,每个excel文件中的sheet是一条测试用例,会替换原先框架的com.demo.test.pageshelper包和data目录,如图4所示。

图3 用例Login的Actions

测试用例excel是用于存储测试用例步骤(如图4所示)、步骤中涉及的动作(如图3所示)和测试数据(如图4所示)等内容,命名规则如下:

  • excel文件命名规则为:“模块名称.xlsx”;
  • excel中第二个sheet命名规则:“001_LoginSuccessFunction”来自原框架测试代码中的部分内容(如图4所示),也就是省略了“页面名称_”:HomePage_和尾部的“_Test”部分:_Test,这两部分省略的部分在生成代码的时候会自动添加。

注意:测试用例excel文件sheet“001_LoginSuccessFunction”中的“动作”列(如图4所示),这列是通过sheet“Actions”中的“动作名称”列来赋值的:

  1. 选择“动作”列,如下图所示,整列已经变灰色,表明整列已经被选中。
  2. 点击excel顶部的“数据”tab -> 数据验证:在数据验证-设置中选择验证条件为:序列并勾选“忽略空值”和“提供下拉箭头”,点击来源最右边的带箭头的按钮,点击sheet 'Actions',选择A2到A26(鼠标左键先点击A2不放,然后拖拽至A26),此时注意数据验证框的变化:=Actions!$A$2:$A$26,点击回车键。

图4 用例Login的执行步骤

图5 用例excel替换pagehelper类和data excel

3.3 解析自动生成代码

自动生成代码TestCaseFactoryForSingle.java代码如下

packagecom.demo.test.utils;importjava.io.File;importjava.io.FileInputStream;importjava.io.FileNotFoundException;importjava.io.FileWriter;importjava.io.IOException;importjava.util.Scanner;importorg.apache.poi.xssf.usermodel.XSSFWorkbook;importorg.testng.Assert;importjxl.read.biff.BiffException;/*** *@authorxy-incito-wy* @Description 自动生成测试代码的工具类,生成指定模块的用例**/
public classTestCaseFactoryForSingle {public static voidmain(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 = newScanner(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= newFile(caseFolder+functionName.toLowerCase()+File.separator+functionName.replaceFirst(functionName.substring(0, 1), functionName.substring(0, 1).toUpperCase())+ "Page_" +sheetName+ "_Test.java");//创建测试用例源码,指定存放路径FileWriter writer = newFileWriter(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 staticString getExcelRelativePath(String functionName) {String dir= "res/testcase";String path= "";//get file list where the path hasFile file = new File(dir+File.separator+functionName+".xlsx");//get the folder listpath =file.getPath();returnpath;}/*** 获得当前excel的sheet数量 - 每个模块的用例数* *@paramfilePath*            文件路径*@return获得excel的sheet数量*@throwsFileNotFoundException*@throwsIOException*/public static intgetSheetNum(String filePath)throwsFileNotFoundException, IOException {int casesNum = 0;XSSFWorkbook workbook= new XSSFWorkbook(new FileInputStream(newFile(filePath)));casesNum=workbook.getNumberOfSheets();returncasesNum;}/*** *@paramsheetIndex*            sheet的位置*@paramfilePath*            excel文件路径相对的*@return返回sheet的名字*@throwsBiffException*@throwsIOException*/public static String getSheetName(intsheetIndex, String filePath)throwsBiffException, IOException {String casesName= "";XSSFWorkbook workbook= new XSSFWorkbook(newFileInputStream(filePath));casesName=workbook.getSheetName(sheetIndex);returncasesName;}}

View Code

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>

View Code

图6 自动生成代码

3.4 读取用例excel数据,定位元素,并进行操作

SuperAction.java代码如下:

packagecom.demo.test.utils;importjava.io.File;importjava.io.FileInputStream;importjava.io.FileNotFoundException;importjava.io.IOException;importjava.util.Iterator;importorg.apache.log4j.Logger;importorg.apache.poi.ss.usermodel.Cell;importorg.apache.poi.ss.usermodel.Row;importorg.apache.poi.ss.usermodel.Sheet;importorg.apache.poi.xssf.usermodel.XSSFWorkbook;importorg.openqa.selenium.Alert;importorg.openqa.selenium.By;importorg.testng.Assert;/*** * @Description 把Selenium操作的变成关键字操作**/
public classSuperAction {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;/*** *@paramlocateWay 定位方式*@paramlocateValue 定位的方式的具体值*@return定位的方式(By)*/public staticBy 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+"] 不被支持!");}returnelementLocator;}/*** *@paramsheet - 测试用例表中的sheet*@paramrowIndex - 测试用例表中的行index*@paramlocateColumnIndex - 测试用例表中的定位列的index*@return从page表中 返回定位方式和定位值* @Description 根据testcase中的元素定位列,去取得page页中的 定位方式和定位值*/public static String[] getPageElementLocator(Sheet sheet,int rowIndex,intlocateColumnIndex,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(newFile(pageFilePath)));}catch(FileNotFoundException e) {e.printStackTrace();}catch(IOException e) {e.printStackTrace();} pageSheet=  pageBook.getSheetAt(0); //取得第一个sheetint 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 newString[]{elementLocatorWay,elementLocatorValue};}/***@paramfounction*            excel文件的名字*@paramcaseName*            excel中sheet的名字*@paramseleniumUtil*            引用seleniumUtil* @Description 读取excel中每个sheet的操作步骤,进而生成测试用例**/public static voidparseExcel(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= newXSSFWorkbook(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[] = newString[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.我的单据,提取出HomePagelocateSplit = 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.我的单据,提取出HomePagelocateSplit = 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.我的单据,提取出HomePagelocateSplit = 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.我的单据,提取出HomePagelocateSplit = 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.我的单据,提取出HomePagelocateSplit = 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.我的单据,提取出HomePagelocateSplit = 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.我的单据,提取出HomePagelocateSplit = 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.我的单据,提取出HomePagelocateSplit = 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.我的单据,提取出HomePagelocateSplit = 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.我的单据,提取出HomePagelocateSplit = 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.我的单据,提取出HomePagelocateSplit = 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.我的单据,提取出HomePagelocateSplit = 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.我的单据,提取出HomePagelocateSplit = 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.我的单据,提取出HomePagelocateSplit = 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.我的单据,提取出HomePagelocateSplit = 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.我的单据,提取出HomePagelocateSplit = 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+"]不被支持,请自行添加");}}}}}

View Code

3.5 更改SeleniumUtil.java

SeleniumUtil.java代码如下:

packagecom.demo.test.utils;importjava.awt.AWTException;importjava.awt.Robot;importjava.awt.event.KeyEvent;importjava.io.File;importjava.util.Calendar;importjava.util.Iterator;importjava.util.List;importjava.util.Set;importjava.util.concurrent.TimeUnit;importorg.apache.log4j.Logger;importorg.openqa.selenium.Alert;importorg.openqa.selenium.By;importorg.openqa.selenium.Cookie;importorg.openqa.selenium.Dimension;importorg.openqa.selenium.JavascriptExecutor;importorg.openqa.selenium.Keys;importorg.openqa.selenium.NoAlertPresentException;importorg.openqa.selenium.NoSuchElementException;importorg.openqa.selenium.StaleElementReferenceException;importorg.openqa.selenium.TimeoutException;importorg.openqa.selenium.WebDriver;importorg.openqa.selenium.WebElement;importorg.openqa.selenium.interactions.Actions;importorg.openqa.selenium.support.ui.ExpectedCondition;importorg.openqa.selenium.support.ui.Select;importorg.openqa.selenium.support.ui.WebDriverWait;importorg.testng.Assert;importorg.testng.ITestContext;importorg.testng.ITestResult;/*** @Description 包装所有selenium的操作以及通用方法,简化用例中代码量**/
public classSeleniumUtil {/**使用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,inttimeOut) {SelectBrowser select= newSelectBrowser();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 voidmaxWindow(String browserName) {logger.info("最大化浏览器:" +browserName);driver.manage().window().maximize();}/*** 设定浏览器窗口大小: 设置浏览器窗口的大小有下面两个比较常见的用途:<br>* 1、在统一的浏览器大小下运行用例,可以比较容易的跟一些基于图像比对的工具进行结合* ,提升测试的灵活性及普遍适用性。比如可以跟sikuli结合,使用sikuli操作flash;<br>* 2、在不同的浏览器大小下访问测试站点,对测试页面截图并保存,然后观察或使用图像比对工具对被测页面的前端样式进行评测。* 比如可以将浏览器设置成移动端大小(320x480),然后访问移动站点,对其样式进行评估;<br>**/public void setBrowserSize(int width, intheight) {driver.manage().window().setSize(newDimension(width, height));}/*** 包装查找元素的方法 element**/publicWebElement findElementBy(By by) {returndriver.findElement(by);}/*** 包装查找元素的方法 elements**/public List<WebElement>findElementsBy(By by) {returndriver.findElements(by);}/**导航链接到url*/public voidnavigateTargetUrl(String url){driver.navigate().to(url);logger.info("导航到:"+url);}/*** 包装点击操作- By**/public voidclick(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 booleanisEnabled(By by){returndriver.findElement(by).isEnabled();}/**提交*/public voidsubmit(WebElement w){try{w.submit();}catch(Exception e){logger.error("在元素:"+w+"做的提交操作失败");Assert.fail("在元素:"+w+"做的提交操作失败");}logger.info("在元素:"+w+"做了提交操作");}/*** 包装点击操作 -webelment**/public voidclick(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) throwsException {try{findElementBy(byElement).click();}catch(Exception e) {if (System.currentTimeMillis() - startTime >timeOut) {logger.warn(byElement+ " is unclickable");throw newException(e);}else{Thread.sleep(500);logger.warn(byElement+ " is unclickable, try again");clickTheClickable(byElement, startTime, timeOut);}}}/*** 获得页面的标题**/publicString getTitle() {returndriver.getTitle();}/*** 获得元素的文本**/publicString getText(By elementLocator) {returndriver.findElement(elementLocator).getText().trim();}/*** 获得元素 属性的文本**/publicString getAttributeText(By elementLocator, String attribute) {returndriver.findElement(elementLocator).getAttribute(attribute).trim();}/*** 包装清除操作**/public voidclear(By byElement) {try{findElementBy(byElement).clear();}catch(Exception e) {logger.error("清除元素 [" + byElement + "] 上的内容失败!");}logger.info("清除元素 [" + byElement  + "]上的内容");}/*** 向输入框输入内容**/public voidtype(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>* 1、WebElement element - 要被操作的元素 <br>* 2、Keys key- 键盘上的功能键 比如ctrl ,alt等 <br>* 3、String keyword - 键盘上的字母**/public voidpressKeysOnKeyboard(WebElement element, Keys key, String keyword) {element.sendKeys(Keys.chord(key, keyword));}/*** 在给定的时间内去查找元素,如果没找到则超时,抛出异常**/public void waitForElementToLoad(int timeOut, finalBy By) {logger.info("开始查找元素[" + By + "]");try{(new WebDriverWait(driver, timeOut)).until(new ExpectedCondition<Boolean>() {publicBoolean apply(WebDriver driver) {WebElement element=driver.findElement(By);returnelement.isDisplayed();}});}catch(TimeoutException e) {logger.error("超时!! " + timeOut + " 秒之后还没找到元素 [" + By + "]");Assert.fail("超时!! " + timeOut + " 秒之后还没找到元素 [" + By + "]");}logger.info("找到了元素 [" + By + "]");}/*** 在给定的时间内查询元素,共尝试三次,如果第三次还是找不到就报错,这就可能是网页性能问题了,响应速度不够**/public void FindElementUtil3TimesTry(int timeOut, finalBy 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>() {publicBoolean apply(WebDriver driver) {WebElement element=driver.findElement(By);returnelement.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 voidisTextCorrect(String actual, String expected) {try{Assert.assertEquals(actual, expected);}catch(AssertionError e) {logger.error("期望的文字是 [" + expected + "] 但是找到了 [" + actual + "]");Assert.fail("期望的文字是 [" + expected + "] 但是找到了 [" + actual + "]");}logger.info("找到了期望的文字: [" + expected + "]");}/*** 判断编辑框是不是可编辑**/public voidisInputEdit(WebElement element) {}/*** 等待alert出现**/public Alert switchToPromptedAlertAfterWait(long waitMillisecondsForAlert) throwsNoAlertPresentException {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();returnalert;}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;}}throwlastException;}/*** 暂停当前用例的执行,暂停的时间为:sleepTime**/public void pause(intsleepTime) {if (sleepTime <= 0) {return;}try{TimeUnit.SECONDS.sleep(sleepTime); logger.info("暂停:"+sleepTime+"秒");}catch(InterruptedException e) {e.printStackTrace();}}/*** 退出**/public voidquit() {driver.quit();}/*** 切换frame - 根据String类型(frame名字)**/public voidinFrame(String frameId) {driver.switchTo().frame(frameId);}/*** 切换frame - 根据frame在当前页面中的顺序来定位**/public void inFrame(intframeNum) {driver.switchTo().frame(frameNum);}/*** 切换frame - 根据页面元素定位**/public voidswitchFrame(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 voidselectByValue(By by, String value) {Select s= newSelect(driver.findElement(by));s.selectByValue(value);}/*** 选择下拉选项 -根据index角标**/public void selectByIndex(By by, intindex) {Select s= newSelect(driver.findElement(by));s.selectByIndex(index);}/**检查checkbox是不是勾选*/public booleandoesCheckboxSelected(By elementLocator) {if (findElementBy(elementLocator).isSelected() == true) {logger.info("CheckBox: " + getLocatorByElement(findElementBy(elementLocator), ">") + " 被勾选");return true;}elselogger.info("CheckBox: " + getLocatorByElement(findElementBy(elementLocator), ">") + " 没有被勾选");return false;}/*** 选择下拉选项 -根据文本内容**/public voidselectByText(By by, String text) {Select s= newSelect(driver.findElement(by));s.selectByVisibleText(text);logger.info("你选择了:"+text);}/*** 获得当前select选择的值**/publicString getCurrentSelectValue(By by){Select s= newSelect(driver.findElement(by));WebElement e=s.getFirstSelectedOption();returne.getText().trim();}/*** 获取下拉列表的所有选项*@paramBy:By元素对象*@return返回所有下拉列表中的选项,如option1,option2,……**/publicString getSelectOption(By by) {String value= null;Select s= newSelect(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 voidexecuteJS(String js) {((JavascriptExecutor) driver).executeScript(js);logger.info("执行JavaScript语句:[" + js + "]");}/*** 获得输入框的值 这个方法 是针对某些input输入框 没有value属性,但是又想取得input的 值得方法**/publicString 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);}returnvalue;}/*** 执行JavaScript 方法和对象* 用法:seleniumUtil.executeJS("arguments[0].click();", seleniumUtil.findElementBy(MyOrdersPage.MOP_TAB_ORDERCLOSE));**/public voidexecuteJS(String js, Object... args) {((JavascriptExecutor) driver).executeScript(js, args);logger.info("执行JavaScript语句:[" + js + "]");}/*** get方法包装**/public voidget(String url) {driver.get(url);logger.info("打开测试页面:[" + url + "]");}/*** close方法包装**/public voidclose() {driver.close();}/*** 刷新方法包装**/public voidrefresh() {driver.navigate().refresh();logger.info("页面刷新成功!");}/*** 后退方法包装**/public voidback() {driver.navigate().back();}/*** 前进方法包装**/public voidforward() {driver.navigate().forward();}/*** 包装selenium模拟鼠标操作 - 鼠标移动到指定元素**/public voidmouseMoveToElement(By by) {Actions builder= newActions(driver);Actions mouse=builder.moveToElement(driver.findElement(by));mouse.perform();}/*** 包装selenium模拟鼠标操作 - 鼠标移动到指定元素**/public voidmouseMoveToElement(WebElement element) {Actions builder= newActions(driver);Actions mouse=builder.moveToElement(element);mouse.perform();}/*** 包装selenium模拟鼠标操作 - 鼠标右击**/public voidmouseRightClick(By element) {Actions builder= newActions(driver);Actions mouse=builder.contextClick(findElementBy(element));mouse.perform();}/*** 添加cookies,做自动登陆的必要方法**/public void addCookies(intsleepTime) {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= newCookie(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*/publicString getCSSValue(WebElement e, String key) {returne.getCssValue(key);}/**使用testng的assetTrue方法*/public voidassertTrue(WebElement e, String content) {String str=e.getText();Assert.assertTrue(str.contains(content),"字符串数组中不含有:" +content);}/**跳出frame*/public voidoutFrame() {driver.switchTo().defaultContent();}//webdriver中可以设置很多的超时时间/**implicitlyWait。识别对象时的超时时间。过了这个时间如果对象还没找到的话就会抛出NoSuchElement异常*/public void implicitlyWait(inttimeOut) {driver.manage().timeouts().implicitlyWait(timeOut, TimeUnit.SECONDS);}/**setScriptTimeout。异步脚本的超时时间。webdriver可以异步执行脚本,这个是设置异步执行脚本脚本返回结果的超时时间*/public void setScriptTimeout(inttimeOut) {driver.manage().timeouts().setScriptTimeout(timeOut, TimeUnit.SECONDS);}/*** pageLoadTimeout。页面加载时的超时时间。因为webdriver会等页面加载完毕在进行后面的操作,* 所以如果页面在这个超时时间内没有加载完成,那么webdriver就会抛出异常*/public void waitForPageLoading(intpageLoadTime) {driver.manage().timeouts().pageLoadTimeout(pageLoadTime, TimeUnit.SECONDS);}/**根据元素来获取此元素的定位值*/publicString 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 + "]");}returnexpect;}/*** 获取当前页面的URL**/publicString getPageURL(){returndriver.getCurrentUrl();}/*** 这是一堆相同的elements中 选择 其中方的 一个 然后在这个选定的中 继续定位**/public WebElement getOneElement(By bys, By by, intindex) {returnfindElementsBy(bys).get(index).findElement(by);}/*** 上传文件,需要点击弹出上传照片的窗口才行* *@parambrower*            使用的浏览器名称*@paramfile*            需要上传的文件及文件名*/public voidhandleUpload(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 voidloginOnWinGUI(String username, String password, String url) {driver.get(username+ ":" + password + "@" +url);}/**检查元素是否显示*/public booleanisDisplayed(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;}returnisDisplay;}/**检查元素是不是存在*/public  booleandoesElementsExist(By byElement){try{findElementBy(byElement);return true;}catch(NoSuchElementException nee){return false;}}/**检查元素是否被勾选*/public booleanisSelected(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;}returnflag;}/*** 判断实际文本时候包含期望文本* *@paramactual*            实际文本*@paramexpect*            期望文本*/public voidisContains(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 + "]");}/*** 判断实际文本,不包含期望文本* *@paramactual*            实际文本*@paramexpect*            期望文本*/public voidisNotContains(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  doublegetScreenWidth() {returnjava.awt.Toolkit.getDefaultToolkit().getScreenSize().getWidth();}/**进入新窗口*/public voidswitchNewWindow(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 - newWindowwindow =driver.switchTo().window(it.next());}}/**回到原始窗口*/public voidbackToOriginalWindow(){window.close();driver.switchTo().window(current_handles);}/**停止页面加载*/public voidstopLoad(){    pause(1);Robot r;try{r= newRobot();r.keyPress(KeyEvent.VK_ESCAPE);logger.info("按下了Esc键");r.keyRelease(KeyEvent.VK_ESCAPE);logger.info("松开了Esc键");}catch(AWTException e) {e.printStackTrace();}logger.info("正在停止页面加载...");}/**获取系统时间*/public intgetDate(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);}returnresult;}/**判断alert是否出现*/public booleanisAlertPresent(){try{driver.switchTo().alert();logger.info("alert出现");return true;}catch(NoAlertPresentException Ex){logger.warn("alert没有出现");return false;}
}/**CMP干部绩效管理系统登录操作*/public voidloginCMP(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"));}/*** 在多个相同元素中,定位到指定的元素*@paramby*@paramindex*@return*/public WebElement getOneElement(By by, intindex) {List<WebElement> element =driver.findElements(by);returnelement.get(index);}/*** 获取指定table某一整列的值*/publicString 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某一行的值*@paramindex:行号,行号从1开始(0代表table的表头)*/public String getRowText(By by, intindex){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个单元格的值*@paramindex:行号,行号从1开始(0代表table的表头)*/public String getCellText(By by, int RowID, intColID){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,", "");}/*** *@paramRow: 一行的对象*@paramColID:对应列*@return*/private WebElement getCell(WebElement Row,intColID){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);}returntarget;}/*** 在给定的时间内去查找元素,如果没找到则超时,抛出异常**/public boolean isShown(int timeOut, finalBy By) {boolean flag = true;logger.info("开始查找元素[" + By + "]");try{(new WebDriverWait(driver, timeOut)).until(new ExpectedCondition<Boolean>() {publicBoolean apply(WebDriver driver) {WebElement element=driver.findElement(By);returnelement.isDisplayed();}});}catch(TimeoutException e) {flag= false;}returnflag;}/**页面过长时候滑动页面 window.scrollTo(左边距,上边距);*/public void scrollPage(int x,inty){String js="window.scrollTo("+x+","+y+");";((JavascriptExecutor)driver).executeScript(js);}}

View Code

转载于:https://www.cnblogs.com/Ming8006/p/5757984.html

Selenium Web 自动化 - 项目实战(三)相关推荐

  1. 软件测试web自动化项目实战——TPshop开源商城系统

    自动化测试流程 目标 1.  熟悉自动化测试的流程 1. 自动化测试的流程 1. 需求分析 2. 挑选适合做自动化测试的功能 3. 设计测试用例 4. 搭建自动化测试环境 [可选] 5. 设计自动化测 ...

  2. java selenium自动化项目实战-入门(1)

    selenium java selenium自动化项目实战 1.[报错]org.openqa.selenium.ElementClickInterceptedException: element cl ...

  3. 【WEB API项目实战干货系列】- API登录与身份验证(三)

    上一篇: [WEB API项目实战干货系列]- 接口文档与在线测试(二) 这篇我们主要来介绍我们如何在API项目中完成API的登录及身份认证. 所以这篇会分为两部分, 登录API, API身份验证. ...

  4. Selenium Web 自动化 - Selenium常用API

    Selenium Web 自动化 - Selenium常用API 2016-08-01 目录 1 对浏览器操作   1.1 用webdriver打开一个浏览器   1.2 最大化浏览器&关闭浏 ...

  5. Selenium Web 自动化 - 如何找到元素

    Selenium Web 自动化 - 如何找到元素 2016-07-29 1. 什么是元素? 元素:http://www.w3school.com.cn/html/html_elements.asp ...

  6. 【WEB API项目实战干货系列】- API访问客户端(WebApiClient适用于MVC/WebForms/WinForm)(四)

    目前最新的代码已经通过Sqlite + NHibernate + Autofac满足了我们基本的Demo需求. 按照既定的要求,我们的API会提供给众多的客户端使用, 这些客户端可以是各种Web站点, ...

  7. WEB前端项目实战/酒仙网开发-李强强-专题视频课程

    WEB前端项目实战/酒仙网开发-204人已学习 课程介绍         WEB前端项目实战/酒仙网开发 课程收益     WEB前端项目实战/酒仙网开发 讲师介绍     李强强 更多讲师课程    ...

  8. 06.简书项目实战三:详情页面和登录功能实现

    简书项目实战三:详情页面和登录功能实现 1. 详情页面布局 这部分的布局比之前的简单多了,就一个标题加上主要内容而已. export default class Detail extends Comp ...

  9. python web自动化元素定位_快速掌握Python Selenium Web自动化:三)在Selenium中定位查找网页元素的诸类方法...

    使用Selenium进行自动化操作,首先要做的就是通过webdriver的get()方法打开一个URL链接. 在打开链接,完成页面加载之后,就可以通过Selenium提供的接口,在页面上进行各种操作了 ...

最新文章

  1. c语言map作为参数传递,C++中map和vector作形参时如何给定默认参数?
  2. 中国电声市场销售分析与投资竞争力研究报告2022版
  3. DGbroker故障切换示例
  4. 【机器学习】 - keras中的模型可视化plot_model模块(含依赖包pydot和graphviz的详细安装过程与注意事项)
  5. BeautifulSoup入门案例
  6. 互联网晚报 | 9月5日 星期日 | 美菜回应大规模裁员;网易云音乐Q2毛利率首次转正;美团展示数字人民币新应用...
  7. 使用SQLyog创建简单的触发器
  8. 任务调度的合理性 (25 分)(拓扑排序)
  9. centos7.0 配置mysql_Centos7.0配置MySQL主从服务器
  10. Android车牌识别sdk开发包,【车牌识别SDK 车牌识别SDK开发包 车牌识别系统】 - 太平洋安防网...
  11. 训练深度学习模型时电脑自动重启
  12. 辩证法——自然观、自然科学方法论和科学观
  13. go语言循环基础练习
  14. uAvionix 获得 FAA 批准进行 C 波段测试,并继续在几个新地点推出 SkyLine C2
  15. 微信小程序——拍照、压缩转换base64(不留存照片在本地相册)
  16. arctanx麦克劳林公式推导过程_点到线的距离公式推导过程
  17. RTL88x2bu网卡驱动Kali安装及部分问题解决
  18. 使用audacity生成单声道音频
  19. PMP备考之路 - PMBOK第一章(引论)
  20. c语言实验报告绘制钟表,单片机时钟程序实验报告

热门文章

  1. 运行第一个 docker image 并在浏览器中查看
  2. logback日志pattern_Logback pattern transactionid 中如何自定义灵活的日志过滤规则
  3. gitlab-ee使用mysql_在 GitLab 我们是如何扩展数据库的
  4. oracle备份密码文件,[数据库]Oracle数据库备份dmp文件,使用cmd命令导入导出步骤,以及忘记Oracle密码_星空网...
  5. 迁徙图_虾米音乐上的原住民会迁徙去哪呢?
  6. c语言求树上节点的双亲,用非递归算法求二叉树叶子结点的c语言代码怎样写?...
  7. php getdefaultvalue,PHP ReflectionParameter getDefaultValueConstantName()用法及代码示例
  8. oracle 分页_80分页查询,不止写法
  9. 《深入理解java虚拟机》第2章 Java内存区域与内存溢出异常
  10. ElasticSearch fuzzy模糊查询(英文检索)