日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發布時間:2025/3/15 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Selenium Web 自动化 - 项目实战(三) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

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”中的“動作名稱”列來賦值的:

  • 選擇“動作”列,如下圖所示,整列已經變灰色,表明整列已經被選中。
  • 點擊excel頂部的“數據”tab -> 數據驗證:在數據驗證-設置中選擇驗證條件為:序列并勾選“忽略空值”和“提供下拉箭頭”,點擊來源最右邊的帶箭頭的按鈕,點擊sheet 'Actions',選擇A2到A26(鼠標左鍵先點擊A2不放,然后拖拽至A26),此時注意數據驗證框的變化:=Actions!$A$2:$A$26,點擊回車鍵。
  • ?

    圖4 用例Login的執行步驟

    ?

    圖5 用例excel替換pagehelper類和data excel

    3.3 解析自動生成代碼

    自動生成代碼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 hasFile file = new File(dir+File.separator+functionName+".xlsx");// get the folder listpath = 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;}} 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代碼如下:

    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); //取得第一個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 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.我的單據,提取出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代碼如下:

    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>* 1、在統一的瀏覽器大小下運行用例,可以比較容易的跟一些基于圖像比對的工具進行結合* ,提升測試的靈活性及普遍適用性。比如可以跟sikuli結合,使用sikuli操作flash;<br>* 2、在不同的瀏覽器大小下訪問測試站點,對測試頁面截圖并保存,然后觀察或使用圖像比對工具對被測頁面的前端樣式進行評測。* 比如可以將瀏覽器設置成移動端大小(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>* 1、WebElement element - 要被操作的元素 <br>* 2、Keys key- 鍵盤上的功能鍵 比如ctrl ,alt等 <br>* 3、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;} elselogger.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 - newWindowwindow = 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);}} View Code

    ?

    轉載于:https://www.cnblogs.com/Ming8006/p/5757984.html

    總結

    以上是生活随笔為你收集整理的Selenium Web 自动化 - 项目实战(三)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    毛片久久久 | 久久久精品综合 | 91麻豆网站 | 免费成人在线观看视频 | 99久久婷婷国产一区二区三区 | 夜夜婷婷| 成年一级片 | 69av免费视频 | 美女亚洲精品 | 久久久久免费观看 | av在线电影免费观看 | 亚洲精品久久久久中文字幕二区 | 日本免费久久高清视频 | 婷婷在线网| 亚洲精品黄网站 | 久久高清国产 | 97在线影视 | 久草在线久 | 欧美久久久影院 | 国产精品专区h在线观看 | 久久人人爽爽人人爽人人片av | 黄色www| 九九亚洲视频 | 国产精品99蜜臀久久不卡二区 | 国产美腿白丝袜足在线av | 精品久久久久久综合日本 | 欧美性色黄 | 国产精品美女久久久久久久 | 日韩欧美精品在线 | 激情五月视频 | 色综合五月天 | 国产黄色av影视 | 四虎在线免费 | 国产在线色视频 | 国产在线观看高清视频 | 成人午夜网址 | 97人人澡人人添人人爽超碰 | 二区三区毛片 | 日韩视频免费观看高清 | 国产一区久久 | 久久精品女人毛片国产 | 美女网站视频免费都是黄 | 国产成人av一区二区三区在线观看 | 久久伊人精品天天 | 中文字幕免费在线 | 午夜精品99久久免费 | 国产免费av一区二区三区 | 中文字幕 二区 | 日本中出在线观看 | 综合久久网 | 天天操天天射天天舔 | 国产免码va在线观看免费 | 日本爽妇网 | 亚洲一二视频 | 这里只有精品视频在线 | 在线观看岛国 | 中文字幕一区2区3区 | 在线成人短视频 | 天天操操操操操 | 亚洲天堂在线观看完整版 | 久久久麻豆精品一区二区 | 国产中文字幕久久 | 国产精品久久久久久久久久三级 | 国产成人久久精品亚洲 | 在线免费视频一区 | 日韩欧美视频一区 | 日韩一区二区在线免费观看 | 天天色宗合 | 国产在线观看午夜 | 亚洲精品久久久久999中文字幕 | 国产精品久久久久久久久婷婷 | 久久久久久久久久久影院 | 在线视频91 | 久久99最新地址 | 中文字幕视频三区 | 国内揄拍国内精品 | 婷婷黄色片 | 香蕉网址| 亚洲精品美女免费 | 午夜国产福利在线观看 | 日韩精品一区不卡 | 国产免费成人 | 亚洲国产久 | 欧洲精品视频一区 | 天天曰天天爽 | 国产精品久久久久久av | 成人h动漫精品一区二 | 成人动漫一区二区三区 | www.xxxx变态.com| 亚洲一区日韩 | av综合av | 日日摸日日爽 | 美女网色 | 久久久噜噜噜久久久 | 不卡的av在线 | 国产一区在线观看免费 | 成年人黄色大片在线 | 国产精品毛片久久久久久 | 国产福利91精品一区二区三区 | 最新国产中文字幕 | 久久精品专区 | 这里只有精品视频在线 | 在线视频久 | 国产成人精品一区二区 | 国产精品99久久久久久人免费 | av中文天堂 | 国内精品久久影院 | 日韩精品网址 | 四虎国产永久在线精品 | 久久9精品 | 欧美综合国产 | 国产精品热| 97福利 | 中文字幕在线观看你懂的 | 日韩在线视频看看 | 99久久er热在这里只有精品66 | www.eeuss影院av撸| 精品一区二区日韩 | 亚洲影视九九影院在线观看 | 天天色欧美 | 最近最新最好看中文视频 | 国产精品久久一区二区无卡 | 日本黄色大片免费看 | 97在线看 | 97色噜噜 | 99精品国产99久久久久久福利 | 91私密保健 | 婷婷在线免费视频 | 日韩美女一级片 | 日本电影久久 | 99精彩视频在线观看免费 | 欧美少妇xxxxxx | 成人av电影免费在线观看 | 日韩精品久久久 | 在线观看一区 | 婷婷国产v亚洲v欧美久久 | 97精品国自产拍在线观看 | 日本福利视频在线 | 99免费看片 | 亚洲无吗天堂 | 国产美女永久免费 | 婷婷在线五月 | 亚洲综合爱 | 在线黄色国产 | 婷婷色综合网 | 中文字幕av最新 | 五月天亚洲婷婷 | 韩国av电影在线观看 | 亚洲精品观看 | 黄网站app在线观看免费视频 | 91精品国产99久久久久久久 | www一起操| 97av视频| a天堂在线看 | 久久这里只有精品久久 | 九九九九精品九九九九 | 97视频中文字幕 | 激情视频一区二区三区 | 久久激情视频网 | 久久黄色免费观看 | 精品一区二区在线免费观看 | 亚洲精品国产精品国 | 国际精品久久 | 91精品国产综合久久福利不卡 | 高清av中文在线字幕观看1 | 国产亚洲精品日韩在线tv黄 | 91色偷偷| 国产麻豆精品传媒av国产下载 | 日韩欧美在线免费观看 | 婷婷久久一区二区三区 | 久久99热久久99精品 | 国产色 在线 | 97看片吧| 欧美视频二区 | 在线看国产一区 | 国产尤物在线观看 | 特级黄色一级 | av一区在线播放 | 国产精品 日韩 | 亚洲国产日韩av | 亚洲激情在线观看 | 成人黄色在线电影 | 天天综合色网 | 97精品国产97久久久久久 | 婷婷在线播放 | a午夜电影 | 成人黄色影片在线 | 久久99精品国产 | 国产美女免费观看 | 超碰人人在线观看 | 久久久久久久久久久网 | 超碰人人av | 毛片网站免费在线观看 | 97国产精品一区二区 | 成人亚洲精品久久久久 | 色五丁香| 五月天色站 | 怡红院av | 久热久草 | 天天操天天操 | 黄色免费网 | 欧美天堂视频在线 | 国产亚洲婷婷免费 | 波多野结衣理论片 | 国产一级特黄毛片在线毛片 | 久草亚洲视频 | 成人免费ⅴa | 免费a网址 | 免费男女羞羞的视频网站中文字幕 | 国内三级在线观看 | 玖玖爱国产在线 | 久久久久久久久久久精 | 午夜丰满寂寞少妇精品 | 久久成年视频 | 欧美一区二区三区在线播放 | 中文在线字幕免费观 | 成人久久久久 | 97精品国产一二三产区 | h动漫中文字幕 | www.玖玖玖 | 五月婷婷六月丁香激情 | 国产经典 欧美精品 | 色视频网站免费观看 | 久久精品视频中文字幕 | 成年人黄色在线观看 | 成人av资源在线 | aaa日本高清在线播放免费观看 | 在线国产片 | .国产精品成人自产拍在线观看6 | 黄色aaa毛片 | 在线视频成人 | 免费99精品国产自在在线 | 黄色成人免费电影 | 狠狠狠色丁香婷婷综合久久五月 | 亚洲视频1 | 狠狠的操你 | 国产免费久久av | 日本bbbb摸bbbb | 国产精品网红福利 | 99热 精品在线 | 男女激情免费网站 | 国产精品9区 | 亚洲精品视频在线播放 | 日本一区二区三区免费看 | 国产亚洲精品久久久久久 | 免费在线观看av网站 | 爱爱av网站 | 国产视频资源在线观看 | 波多野结衣精品 | 免费观看完整版无人区 | 成片免费观看视频999 | 亚洲丁香久久久 | 热99在线 | 97视频精品 | 97人人人人 | 日韩免费一区二区三区 | 久福利| 久久久久久毛片 | 精品视频在线看 | 超碰免费公开 | 色婷婷在线播放 | 国产成免费视频 | 99久久精品久久久久久动态片 | 中文字幕日韩电影 | 91插插视频| 亚洲精品456在线播放乱码 | 麻豆综合网 | 亚洲成av片人久久久 | 欧美在线视频精品 | 久久久五月天 | 9在线观看免费高清完整版在线观看明 | 日本在线观看中文字幕无线观看 | 99精品免费网 | 日韩精品免费专区 | 婷婷丁香社区 | 久久美女高清视频 | 午夜91在线| 成人午夜电影在线播放 | 成年人在线免费看 | 91精品国产91p65 | 一区二区三区不卡在线 | 久久久国产精品亚洲一区 | 成人久久视频 | 国产精品美女视频 | 麻豆小视频在线观看 | 欧美日韩高清免费 | 日韩网站在线免费观看 | 久久亚洲精品国产亚洲老地址 | 综合色婷婷 | 国产在线观看污片 | 色婷婷激情综合 | 国产精品日韩在线播放 | 亚洲欧洲一区二区在线观看 | 十八岁免进欧美 | 999国内精品永久免费视频 | 久久9999久久免费精品国产 | 黄色av观看 | 亚洲精品91天天久久人人 | 日韩欧美精品在线 | 在线免费观看视频一区 | 曰本三级在线 | 91人人网| 激情欧美日韩一区二区 | 美女网站视频免费黄 | 黄色一级在线观看 | 亚洲天堂网站视频 | 蜜桃视频在线观看一区 | 国产精品一区在线观看你懂的 | 黄污视频网站大全 | 97超碰在线免费观看 | 日韩精品一区二区三区不卡 | 国产精品精品国产 | 青青河边草免费直播 | 亚洲一区二区三区四区精品 | 久久久久免费精品视频 | 免费观看的黄色 | 在线观看av网站 | 国产精彩视频一区二区 | 国产一区二区电影在线观看 | 欧美夫妻性生活电影 | 能在线看的av | 91视视频在线直接观看在线看网页在线看 | 成人黄色小说视频 | 国产原厂视频在线观看 | 国产精品手机在线 | 在线看日韩 | 久久无码精品一区二区三区 | 国产麻豆精品久久一二三 | 国产精品入口麻豆www | 欧美日韩国产在线 | 久久免费av电影 | 日本精品一区二区 | 国产精品丝袜久久久久久久不卡 | 黄网站app在线观看免费视频 | 国产在线专区 | 亚洲女人天堂成人av在线 | 亚洲我射av| 成人在线观看免费视频 | 精品国产一二三四区 | 日本中文字幕观看 | 久久99精品国产麻豆婷婷 | 青青河边草观看完整版高清 | 91热精品| 天天综合操 | 亚洲国产中文字幕在线观看 | 日韩欧美视频免费在线观看 | 欧美精品免费一区二区 | 国产亚洲精品久久久久久电影 | 国产精品免费久久久久久久久久中文 | 黄色av三级在线 | 国产精品久久久久久久久久久久久久 | 激情久久综合 | 91人人澡人人爽人人精品 | 久久九九国产精品 | 国产亚洲精品久久久久久网站 | 国产69久久精品成人看 | 四虎永久国产精品 | 亚洲黄色影院 | 蜜臀av性久久久久蜜臀aⅴ涩爱 | 国产精品久久久久久久久久 | 成年人在线观看视频免费 | 成人免费大片黄在线播放 | 2019中文字幕网站 | 日韩区欧美久久久无人区 | 久久国产剧场电影 | 色综合久久中文字幕综合网 | 亚洲成人黄色在线观看 | 91丨九色丨国产女 | 最新极品jizzhd欧美 | 91精品国产91久久久久福利 | 国产一级三级 | 99精品视频在线观看视频 | 在线观看你懂的网址 | 精品国产理论 | 日韩精品久久久免费观看夜色 | 92中文资源在线 | 国产一区二区精 | 婷婷色吧 | 久久手机免费视频 | 国产高清视频在线播放一区 | 亚洲男男gaygayxxxgv | www.五月天 | 久久精品亚洲国产 | 午夜电影一区 | 中文字幕亚洲精品日韩 | 蜜桃视频成人在线观看 | 久久精精品 | 久久色在线观看 | 欧美三级免费 | 午夜精品一区二区三区视频免费看 | 五月天av在线 | 日韩在线观看一区二区 | 91av看片 | 午夜精品婷婷 | 日韩午夜三级 | 国产综合精品一区二区三区 | 国产亚洲视频中文字幕视频 | 天天摸日日摸人人看 | 国产视频中文字幕在线观看 | 国产午夜精品一区二区三区嫩草 | 成人综合日日夜夜 | 国产天天爽 | 天天操天天干天天综合网 | 久久热亚洲 | 正在播放国产91 | 在线国产视频观看 | 一区二区激情 | 99在线视频精品 | 国偷自产中文字幕亚洲手机在线 | 欧美一级性生活视频 | 日韩在线中文字幕 | 亚洲干 | 日韩成人免费在线电影 | 国产精品一区二区吃奶在线观看 | 一区二区三区观看 | 亚洲欧美视频 | 日本一区二区三区免费看 | 色姑娘综合天天 | 免费观看一区二区 | 亚洲区另类春色综合小说校园片 | 久久99深爱久久99精品 | 欧美性做爰猛烈叫床潮 | 911久久香蕉国产线看观看 | 97精品一区二区三区 | 免费看黄的视频 | 综合久久五月天 | 蜜臀av性久久久久av蜜臀妖精 | www.伊人色.com| 欧美坐爱视频 | 精品一区91 | 在线观看电影av | 久草影视在线观看 | 麻花豆传媒mv在线观看网站 | 色伊人网 | 日韩在线播放欧美字幕 | 国产视频 亚洲视频 | 丁香九月婷婷综合 | 中文字幕久久亚洲 | 欧美在线视频免费 | 一区二区 不卡 | 国产一级二级在线播放 | 国产福利a | 久久夜色精品国产欧美乱极品 | 999成人网 | 男女激情片在线观看 | 日韩精品视频在线观看网址 | 蜜臀精品久久久久久蜜臀 | 中文在线免费视频 | 成人在线观看影院 | 夜夜夜精品| 中文字幕亚洲精品日韩 | 久久8精品 | 国产乱码精品一区二区蜜臀 | 国产一级片不卡 | 国产精品免费观看在线 | 激情伊人五月天久久综合 | 久草在线视频看看 | 天天草天天色 | 久久久久久久久久久高潮一区二区 | 96视频在线 | 天天干com | 欧美不卡在线 | 精品资源在线 | 一级黄色免费网站 | 亚洲欧美日本一区二区三区 | 国产成人一区二区三区在线观看 | av在线一 | 91香蕉亚洲精品 | av在线网站观看 | 免费在线观看av网站 | a天堂中文在线 | 国产精品九九九九九九 | 午夜精品久久久久久99热明星 | 久草在线手机视频 | 色综合天天色综合 | 中文av字幕在线观看 | 国产专区欧美专区 | 天天综合日 | 免费碰碰 | 国产丝袜一区二区三区 | 成人黄色免费在线观看 | 人人爱人人舔 | 亚洲国产网站 | 久久免费大片 | 青青啪| av中文在线影视 | 成人免费共享视频 | 天天干天天草 | 国产一区二区三区网站 | 97超级碰碰碰碰久久久久 | 深夜视频久久 | 久草在线资源网 | 久久狠狠干 | 久久影视网 | 国产精品精品国产婷婷这里av | 亚洲精品网站在线 | 国产精品亚洲视频 | 在线观看国产成人av片 | 久精品视频在线 | 日韩av在线资源 | 日本狠狠干| 日本深夜福利视频 | 亚洲精品系列 | 丁香花中文在线免费观看 | 一级成人网 | 在线观看国产成人av片 | 中文字幕日韩av | 特级xxxxx欧美 | 成人全视频免费观看在线看 | 国产理论在线 | 国产又粗又猛又色又黄网站 | 亚洲国产精品资源 | 成人免费视频网站 | 国产福利91精品张津瑜 | 久久99久久精品国产 | 日日夜夜狠狠操 | 在线亚洲播放 | 国产高清在线免费观看 | 亚洲人成免费 | 亚洲区另类春色综合小说校园片 | 国产精品白丝av | 91久久久久久国产精品 | 午夜精品久久久久久久久久久久久久 | 国产精品久久久久永久免费观看 | 日韩免费在线观看视频 | 另类老妇性bbwbbw高清 | 成人免费视频在线观看 | 久久九九网站 | 在线观看av大片 | 日韩在线观看免费 | 亚洲免费一级电影 | 亚洲国产美女精品久久久久∴ | 亚洲成人精品 | 97成人在线观看视频 | 久久中文字幕导航 | 成人avav | 少妇搡bbbb搡bbb搡aa | 久久国产免费看 | 亚洲综合视频在线播放 | 久久综合色综合88 | 五月天综合 | 欧美成人69av | 麻豆91在线观看 | 国产99精品 | 午夜视频在线观看一区二区三区 | www视频免费在线观看 | www好男人 | 在线观看蜜桃视频 | 久久精品一区二区国产 | 亚洲国产成人在线 | a爱爱视频 | 国产精品久久麻豆 | 日本aaaa级毛片在线看 | 久久久在线 | 国产成人久久精品一区二区三区 | 最新av网址在线观看 | 久久欧美在线电影 | 91精品久久久久久久99蜜桃 | 成人免费在线看片 | 欧美做受69 | 91九色蝌蚪国产 | 在线视频日韩精品 | 激情在线网址 | 99热官网| 成人久久国产 | 黄色网大全 | av在线超碰 | 国产日韩在线一区 | 国产日产精品一区二区三区四区的观看方式 | 手机在线欧美 | 97成人精品视频在线播放 | 精品毛片在线 | 狠狠干婷婷色 | 91完整版在线观看 | 亚洲精品乱码久久久久久高潮 | 97成人免费 | 亚洲v欧美v国产v在线观看 | 免费福利片 | 色综合国产 | 手机av看片 | 亚洲美女视频在线 | 亚洲欧美日韩一二三区 | 天天操天天舔天天爽 | 久草在线资源视频 | 99re久久精品国产 | 欧洲精品在线视频 | 高清精品在线 | 国产精在线 | 亚洲精品美女久久久 | 色视频网站免费观看 | 五月婷婷,六月丁香 | 婷婷综合网 | www免费| 成人资源网 | 国产成人一区二区啪在线观看 | 久草在线这里只有精品 | 欧美另类人妖 | 国产不卡在线播放 | 六月激情丁香 | 日韩免费一区 | 欧美午夜精品久久久久 | 国产高清成人在线 | 免费在线一区二区 | 亚洲九九爱 | 91成人在线观看高潮 | 日韩精品欧美专区 | 亚洲天堂精品视频在线观看 | 国产伦精品一区二区三区高清 | 91人人插 | 国产精品专区在线观看 | 国产精品淫片 | 免费不卡中文字幕视频 | 久久国产精品区 | 日韩电影久久 | 久久人人插 | 日韩激情视频 | 日本最新中文字幕 | 久久久久久蜜桃一区二区 | 国产一级淫片免费看 | 久久99亚洲精品久久 | 伊人天天狠天天添日日拍 | 天天操天天干天天爽 | 日韩丝袜 | 97影视| 日韩成人免费在线 | 99亚洲视频| 午夜电影中文字幕 | 国产午夜精品福利视频 | 成人毛片a| 久草精品网 | 欧美一区免费在线观看 | 欧洲精品在线视频 | 日韩中文字幕视频在线观看 | av黄色免费在线观看 | 最新免费中文字幕 | 日韩精品一区二区三区高清免费 | 欧美怡红院 | 久久国产高清 | 欧美精品免费在线 | 国产资源精品在线观看 | 97成人超碰| 一区二区三区中文字幕在线观看 | 日韩丝袜 | 亚州免费视频 | 国产精品久久99综合免费观看尤物 | 日韩视频一区二区在线观看 | 一区二区精品在线 | 久久视频中文字幕 | 免费在线黄 | 精品在线视频播放 | 欧美视频网址 | 久久久久人人 | 五月天婷婷狠狠 | 99视频国产在线 | 操操操com| 日韩成人黄色av | 91麻豆精品一区二区三区 | 碰超在线 | 人人澡超碰碰 | 高清av中文在线字幕观看1 | 欧美精品久久久久a | 日日日日 | 国产精品毛片久久 | 国产精品久久在线观看 | 午夜精品久久久久久99热明星 | av在线之家电影网站 | 久久96国产精品久久99漫画 | 国产成人亚洲在线观看 | 成人黄大片视频在线观看 | 夜夜躁日日躁狠狠久久88av | 免费精品在线视频 | 五月亚洲综合 | 日韩精品一区二区三区免费观看 | 色搞搞 | 91九色成人 | 91麻豆精品国产 | 亚洲一级电影在线观看 | 国产日本在线播放 | 9999毛片 | 日韩视频免费在线观看 | 99精品在线免费视频 | 男女精品久久 | 人人擦 | 五月丁香 | 91原创在线观看 | 国产精品一区二区三区视频免费 | 国产精品99久久久久久久久 | 亚洲国产精品激情在线观看 | 国产高清不卡在线 | 中文字幕av最新更新 | 久在线 | 欧美日韩中文在线视频 | 婷婷丁香花五月天 | 久久午夜电影网 | 久久ww| 日本三级久久久 | 国产自制av | 午夜少妇一区二区三区 | 欧美国产精品一区二区 | 久久国产精品免费观看 | 国产精品免费一区二区三区 | 国产区在线视频 | 中文字幕av专区 | 亚洲欧洲精品一区二区 | 久99久中文字幕在线 | 91在线91拍拍在线91 | av激情五月 | 国产又粗又硬又长又爽的视频 | 黄色www在线观看 | 免费看片网页 | 久久久久综合网 | 日本精品久久久久久 | 国产黄色大片免费看 | 日本xxxxav| 亚洲人成网站精品片在线观看 | 国内精品久久久久久久久久久 | 99人久久精品视频最新地址 | 中文字幕在线看视频国产中文版 | 在线播放一区二区三区 | 久久精品视 | 西西444www大胆高清图片 | 日韩精品一区二区在线观看视频 | 日韩乱码中文字幕 | 免费a网站 | 五月天色婷婷丁香 | 97超碰在线人人 | 亚洲 综合 激情 | 欧美在线a视频 | 久久久久综合网 | 69亚洲视频 | 久草视频免费在线播放 | 亚洲高清视频在线 | 黄色成人av在线 | 极品国产91在线网站 | 午夜电影一区 | 色国产精品一区在线观看 | 国产色资源 | 夜色资源站wwwcom | 视频在线观看亚洲 | 日韩三级一区 | 久草免费新视频 | 91毛片在线 | 日韩精品网址 | 99精品乱码国产在线观看 | 在线观看91精品视频 | av在线一二三区 | 欧美视频国产视频 | 亚洲精品免费在线观看 | 色香天天| 国产高清视频色在线www | 黄色软件网站在线观看 | 美女网站在线播放 | 精品播放 | 91福利视频一区 | 五月天中文字幕mv在线 | 日韩美在线 | 91在线观看视频网站 | 91成人免费| 国产老熟 | 欧美成人影音 | 丁香六月激情 | 亚洲视频高清 | 欧美成人性战久久 | 超碰免费成人 | av在线播放中文字幕 | 精品国产区 | 三级av黄色 | 最新av在线免费观看 | 超碰97中文 | 精品国产亚洲日本 | 亚洲国产一区二区精品专区 | 99在线观看视频网站 | 九九久久电影 | 中文字幕在线中文 | 国产va在线| 成人小视频在线免费观看 | 91丨九色丨国产女 | 欧美视频国产视频 | 日日干精品 | 97成人免费视频 | 免费在线黄色av | 欧美日韩在线观看一区二区三区 | 免费福利视频导航 | 在线观看国产区 | 东方av免费在线观看 | 国产免码va在线观看免费 | 亚洲婷婷免费 | 国产精品一区久久久久 | 日韩网站免费观看 | 色综合久久久久综合 | 久久综合免费 | 全久久久久久久久久久电影 | 欧美久草视频 | 久久久18| 在线91播放 | 中文在线√天堂 | 91免费看黄色 | 国产高清无线码2021 | 8090yy亚洲精品久久 | 国产免费影院 | 黄色精品网站 | 深爱激情av | 国产午夜三级一区二区三 | 欧美日韩国产一区二区三区在线观看 | 日韩 精品 一区 国产 麻豆 | 青青草在久久免费久久免费 | www.天天操.com| 国产一区视频在线观看免费 | 亚洲日日日 | 国产高清在线不卡 | 天天干夜夜擦 | 婷婷色九月| 一级一片免费看 | 免费男女羞羞的视频网站中文字幕 | 在线观看亚洲精品 | 99r在线视频 | 少妇精品久久久一区二区免费 | 国产乱码精品一区二区蜜臀 | 91探花国产综合在线精品 | 亚洲精品自在在线观看 | 久久久精品 一区二区三区 国产99视频在线观看 | 天天色天天射天天综合网 | 久久综合久久综合这里只有精品 | 992tv又爽又黄的免费视频 | 亚洲特级毛片 | 国产精品视频永久免费播放 | 在线播放一区二区三区 | 91av资源网 | 成年人在线免费看视频 | 91伊人| 天天天综合 | 不卡av免费在线观看 | 亚洲成人免费在线 | 在线免费观看国产视频 | 中文字幕在线第一页 | 国产精品午夜久久久久久99热 | 日韩在线高清免费视频 | 欧美日韩不卡一区二区 | 国产999视频在线观看 | 久久久久久国产精品亚洲78 | 国产r级在线观看 | 日韩激情片在线观看 | 91一区一区三区 | 国产成人一级 | 精品国产一区二区三区噜噜噜 | 久久五月激情 | 欧美日视频 | 亚洲精品国产精品99久久 | 91在线一区 | av在线日韩 | 日韩激情第一页 | 激情图片久久 | 六月婷婷网 | 国产精品一区在线观看你懂的 | 91精品色| 欧美日韩免费一区二区三区 | 日本久久久久久久久久 | 亚洲aⅴ久久精品 | 国内免费久久久久久久久久久 | 日韩在线视频播放 | 又长又大又黑又粗欧美 | 国产精品18videosex性欧美 | 超碰97人人干 | 中文字幕久久亚洲 | 在线亚洲天堂网 | 欧美影片 | 99热国产在线中文 | 五月婷综合 | 亚洲日韩中文字幕 | 日韩亚洲在线视频 | 在线看日韩av | 久久视频在线观看中文字幕 | 免费网站观看www在线观看 | 狠狠操导航 | 伊人久久一区 | 天天色官网| 黄色aaa级片 | 欧美一区二区三区在线看 | 91精品影视 | 久久欧洲视频 | 久视频在线播放 | 欧美日韩精品网站 | av综合在线观看 | 久久亚洲私人国产精品va | 成人午夜剧场在线观看 | 粉嫩av一区二区三区四区五区 | 国产一区二区三区四区大秀 | 亚洲一级片 | 三级av在线 | av免费电影网站 | 麻豆视频免费版 | 国产不卡在线视频 | 五月婷婷六月丁香在线观看 | 日韩三级精品 | 久久精品人人做人人综合老师 | 91豆花在线观看 | 久久久免费看视频 | 日韩在线视频免费看 | 国产精品18久久久久白浆 | 中文字幕免 | 久久久福利 | 中文字幕一区二区三区四区视频 | 亚洲精品免费播放 | 国产伦理一区二区 | 久久综合九色 | www欧美xxxx | 综合在线色 | 久久久激情视频 | 91福利在线观看 | 成人欧美在线 | 六月丁香婷婷久久 | 国内精品视频一区二区三区八戒 | 国产在线免费av | 日本精品二区 | 日韩欧美视频一区二区 | 91av电影在线 | 国产黄色看片 | 久久久久综合精品福利啪啪 | 五月天com| 丁香花中文字幕 | 91av在| 黄色片网站免费 | 成人黄色在线看 | 日韩av视屏在线观看 | 日韩在线观看一区 | 四虎永久免费在线观看 | 中文字幕国内精品 | 亚洲精品在线视频网站 | 日韩av电影中文字幕在线观看 | 天天操天天色天天射 | 欧美一进一出抽搐大尺度视频 | 免费日韩 | 国产亚洲小视频 | 精品国产伦一区二区三区观看体验 | 免费中文字幕视频 | 五月在线视频 | av在线专区 | 97在线精品 | 国产xxxx做受性欧美88 | 精品国产_亚洲人成在线 | 香蕉成人在线视频 | 国产免费观看久久黄 | 日韩r级在线 | 四虎在线永久免费观看 | 日本精品视频在线观看 | 欧女人精69xxxxxx | 午夜久久久久久久久久影院 | 深爱激情亚洲 | 91精品国产自产91精品 | 日韩在线视频网站 | 国产精品中文字幕在线 | 国产免费午夜 | 国产在线播放观看 | 中文资源在线官网 | 国产免费精彩视频 | 91视频com | 色吧久久 | 很黄很黄的网站免费的 | 免费观看www视频 | 久久精品一区二区三区国产主播 | 国产一区免费视频 | 麻豆国产在线播放 | 亚洲天堂网在线观看视频 | 国产日韩欧美自拍 | 天天草综合| 日韩欧美综合在线视频 | 欧美日本啪啪无遮挡网站 | 18久久久 | 欧美一级久久久久 | 日韩欧美在线播放 | 欧美精品久久人人躁人人爽 | 热re99久久精品国产66热 | 91香蕉视频污在线 | 黄色电影在线免费观看 | 人人插超碰 | 97狠狠干| 日本久久电影网 | 久久久久国产精品www | 欧美精品国产精品 | 国产精品欧美一区二区 | 色丁香久久 | 天天五月天色 | 在线观看视频日韩 | 一区二区三区高清 | 欧美日韩在线免费视频 | 91视频最新网址 | 国产亚洲成人精品 | 久久久久女人精品毛片 | 欧美激情视频在线观看免费 | 日韩网站一区 | 精品美女久久久久久免费 | 欧美日韩后 | 二区视频在线观看 | 成人资源在线播放 | 999久久久欧美日韩黑人 | 91福利影院在线观看 | 四虎视频| 天天艹天天爽 |