package test_4_1.tools; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.NoSuchElementException; import java.util.Scanner; import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.function.Function; import net.sf.json.JSONArray; import net.sf.json.JSONObject; import org.junit.Assert; import org.openqa.selenium.By; import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.StaleElementReferenceException; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.ie.InternetExplorerDriver; import org.openqa.selenium.remote.DesiredCapabilities; import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.support.ui.FluentWait; import org.openqa.selenium.support.ui.Wait; import com.fasterxml.jackson.core.JsonParser.Feature; import com.fasterxml.jackson.databind.ObjectMapper; /** * @author Terry Date : 2016-02-29 23:17 工具类 */ public class Utils { /** * 项目设置对象 */ public static JSONObject settings = null; public static WebDriver driver; public static List barcodes; public static List resendout; public static List reBarcodes = new ArrayList(); /** * 根据项目名称,初始化项目的配置对象 * * @param projectName * 项目名称的字符串 * @return 项目配置对象 */ public static JSONObject initProjectSettings(String projectName) { settings = getProjectSettings(projectName); return settings; } /** * 打印当前页面的源代码,用于分析调试 * * @param driver */ public static void printCurrentWebpageSourcecode(WebDriver driver) { Object response = ((JavascriptExecutor) driver) .executeScript("return document.documentElement.innerHTML;"); String source = (String) response; System.out.println(source); } /** 打开浏览器 */ public static void webDriverInit() { // System.setProperty("webdriver.ie.driver", // "C:\\IEDriverServer_Win32_3.3.0\\IEDriverServer.exe"); // 解决ie兼容模式设置导致无法启动问题 DesiredCapabilities ieCapabilities = DesiredCapabilities .internetExplorer(); ieCapabilities .setCapability( InternetExplorerDriver.INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS, true); ieCapabilities.setCapability("applicationName", "cherry"); ieCapabilities.setCapability("version", "11.0"); // driver = new InternetExplorerDriver(ieCapabilities); try { driver = new RemoteWebDriver(new URL( "http://192.168.2.18:4444/wd/hub"), ieCapabilities); } catch (MalformedURLException e) { e.printStackTrace(); } driver.get(Utils.settings.get("服务器地址").toString()); } /** * 初始化设置,包括项目配置和webdriver的初始化 * */ public static void init() { // initProjectSettings("zd5y"); initProjectSettings("all"); // initProjectSettings("zsyy"); webDriverInit(); } /** 定位到弹出对话框的按钮 */ public static void LocaAndWait() { Wait wait = new FluentWait(Utils.driver) .withTimeout(30, TimeUnit.SECONDS) .pollingEvery(3, TimeUnit.SECONDS) .ignoring(NoSuchElementException.class); WebElement yesbutton = wait .until(new Function() { public WebElement apply(WebDriver driver) { return driver.findElement(By.linkText("是")); } }); yesbutton.click(); } /** 获取当前日期 */ public static void DateTime() { Date now = new Date(); SimpleDateFormat dateFormater = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss"); System.out.print(dateFormater.format(now) + " "); } /** * 获取装配时创建的器械包的条码,为集合对象 * */ public static List getToussesBarcodes() { JavascriptExecutor js = (JavascriptExecutor) driver; Object toussesStr = js .executeScript("return JSON.stringify(packingToussesArray)"); List barcodes = new ArrayList(); JSONArray array = JSONArray.fromObject(toussesStr); if (array != null) { for (int i = 0; i < array.size(); i++) { JSONObject tousse = array.getJSONObject(i); JSONArray b = tousse.getJSONArray("barcodes"); for (int j = 0; j < b.size(); j++) { barcodes.add((String) b.get(j)); } } } Utils.reBarcodes.addAll(barcodes); return barcodes; } /** * 重复查找和click,当出现引用的element过时后,重新查找该element * * @param by * @return */ public boolean retryingFindClick(By by) { boolean result = false; int attempts = 0; while (attempts < 2) { try { retryingFind(by).click(); result = true; break; } catch (StaleElementReferenceException e) { } attempts++; } return result; } /** * 重复查找,当出现引用的element过时后,重新查找该element * * @param by * @return */ public static WebElement retryingFind(By by) { WebElement element = null; int attempts = 0; while (attempts < 3) { try { Wait wait = new FluentWait(Utils.driver) .withTimeout(5000, TimeUnit.MILLISECONDS) .pollingEvery(100, TimeUnit.MILLISECONDS) .ignoring(NoSuchElementException.class); element = driver.findElement(by); Thread.sleep(1000); break; } catch (Exception e) { } attempts++; } return element; } /** * 重复查找和click,html表格的第一个单元格对象 * * @param by * html table的查找条件 * @return 单元格对象 */ public static boolean retryingFindClickFirstCellOfTable(By by) { boolean result = false; int attempts = 0; while (attempts < 2) { try { WebElement table = retryingFind(by); if (table != null) { WebElement cell = getFirstCellOfTable(table); cell.click(); result = true; break; } } catch (StaleElementReferenceException e) { System.out.println("发生了异常:StaleElementReferenceException"); e.printStackTrace(); } catch (NoSuchElementException e) { System.out.println("发生了异常:NoSuchElementException"); e.printStackTrace(); } attempts++; } return result; } /** * 重复查找,html表格的第四个单元格对象 * * @param by * html table的查找条件 * @return 单元格对象 */ public static WebElement retryingFindForthCellOfTable(By by) { WebElement result = null; int attempts = 0; while (attempts < 2) { try { WebElement table = retryingFind(by); if (table != null) { WebElement cell = getforthCellOfTable(table); if (cell != null) { String text = cell.getText(); if (text != null) { if (text.equals("自定义器械包申请单") || text.equals("消毒物品申请单")) { result = cell; break; } else { result = null; break; } } } else { result = null; break; } } } catch (StaleElementReferenceException e) { System.out.println("发生了异常:StaleElementReferenceException"); e.printStackTrace(); } catch (NoSuchElementException e) { System.out.println("发生了异常:NoSuchElementException"); e.printStackTrace(); } attempts++; } return result; } /** * 获取Html Table的第一个单元格,即第一行第一列的单元格 * * @param table * 表格对象 * @return 单元格对象 */ private static WebElement getFirstCellOfTable(WebElement table) { WebElement cell = null; // Now get all the TR elements from the table List allRows = table.findElements(By.tagName("tr")); System.out.println("rows size = " + allRows.size()); if (allRows != null && allRows.size() > 0) { WebElement row = allRows.get(0); // return row; List cells = row.findElements(By.tagName("td")); if (cells != null && cells.size() > 0) { cell = cells.get(0); } } return cell; } /** * 获取Html Table的第四个单元格,即第一行第四列的单元格 * * @param table * 表格对象 * @return 单元格对象 */ private static WebElement getforthCellOfTable(WebElement table) { WebElement cell = null; // Now get all the TR elements from the table List allRows = table.findElements(By.tagName("tr")); System.out.println("rows size = " + allRows.size()); if (allRows != null && allRows.size() > 0) { WebElement row = allRows.get(0); // return row; List cells = row.findElements(By.tagName("td")); if (cells != null && cells.size() > 0) { cell = cells.get(3); } } return cell; } /** * 等待直到新窗口被打开 * * @param noOfWindows * 期望的窗口数量 * @param timeOut * 超时时间,单位为毫秒 */ public static void waitForWindowToOpen(int noOfWindows, int timeOut) { int initCount = driver.getWindowHandles().size(); if (initCount == noOfWindows) { return; } else { boolean foundWindow = false; long duration; long startTime = System.currentTimeMillis(); duration = (System.currentTimeMillis() - startTime); while (timeOut > duration && !foundWindow) { try { Thread.sleep(500); } catch (InterruptedException e) { } foundWindow = driver.getWindowHandles().size() >= noOfWindows; duration = (System.currentTimeMillis() - startTime); } if (timeOut <= duration && !foundWindow) { // Throw Error } } } /** * 回收窗口的切换 */ public static void changeWindow() { try { // 主窗口 String mainWindow = Utils.driver.getWindowHandle(); Utils.retryingFind(By.id("recyclingRecordTouchScreen")).click(); Utils.waitForWindowToOpen(2, 5000); // 遍历所有窗口,切换至新窗口(回收清点窗口) Set handles = Utils.driver.getWindowHandles(); for (String windowHandle : handles) { if (!windowHandle.equalsIgnoreCase(mainWindow)) { Utils.driver.switchTo().window(windowHandle); System.out.println("切换到新窗口:" + windowHandle); } } Thread.sleep(2000); // 确认已经切换至回收清点窗口 String currentUrl = Utils.driver.getCurrentUrl(); System.out.println("currentUrl = " + currentUrl); boolean isLoginOk = currentUrl .indexOf("/disinfectsystem/touchScreen/recycle/awaitForRecycleList.jsp?resolution=1980") > 0; if (!isLoginOk) { } Assert.assertTrue(isLoginOk); Thread.sleep(2000); } catch (Exception e) { e.printStackTrace(); Assert.fail(e.getMessage()); } } /** * 尝试关闭警告对话框,如果弹出了警告对话框,则关闭该对话框 警告框可能有多个,如:器械包过期告警、满意度调查 */ public static void tryToCloseWarningWindow() { try { Wait wait = new FluentWait(Utils.driver) .withTimeout(5000, TimeUnit.MILLISECONDS) .pollingEvery(100, TimeUnit.MILLISECONDS) .ignoring(NoSuchElementException.class); // 等待对话框弹出 Thread.sleep(1000); // wait.until(ExpectedConditions // .visibilityOfElementLocated(By // .xpath("//div/span[contains(text(),'满意度调查表')]"))); // 获取警告信息对话框的集合 List closeBtns = wait .until(new Function>() { public List apply(WebDriver driver) { return driver.findElements(By .cssSelector("div[class='x-tool x-tool-close']")); } }); if (closeBtns.size() == 0) { return; } // List closeBtns = Utils.driver.findElements(By // .cssSelector("div[class='x-tool x-tool-close']")); System.out.println("closeBtns.size() = " + closeBtns.size()); // 逐个关闭对话框,先关闭最外层的。如果没关闭最外层的,里面的对话框无法关闭 for (int i = closeBtns.size() - 1; i >= 0; i--) { closeBtns.get(i).click(); } } catch (Exception e) { e.printStackTrace(); Assert.fail(e.getMessage()); } } /** * 回收自定义入筐窗口的切换 */ public static void changeCustomWindow() { try { // 回收窗口 String mainWindow = Utils.driver.getWindowHandle(); Utils.retryingFind(By.cssSelector("div[class='add2']")).click(); Utils.waitForWindowToOpen(3, 5000); // 遍历所有窗口,切换至新窗口(自定义入筐窗口) Set handles = Utils.driver.getWindowHandles(); for (String windowHandle : handles) { if (!windowHandle.equalsIgnoreCase(mainWindow)) { Utils.driver.switchTo().window(windowHandle); System.out.println("切换到新窗口:" + windowHandle); } } Thread.sleep(5000); // 确认已经切换至自定义入筐窗口 String currentUrl = Utils.driver.getCurrentUrl(); System.out.println("currentUrl = " + currentUrl); boolean isLoginOk = currentUrl .indexOf("disinfectsystem/touchScreen/recycle/customIntoBasket.jsp?data") > 0; if (!isLoginOk) { } Assert.assertTrue(isLoginOk); } catch (Exception e) { e.printStackTrace(); Assert.fail(e.getMessage()); } } /** * 等待一段时间,直到页面的URL地址变为期望值 * * @param newUrl * 期望的url * @param seconds * 等待的超时时间 */ public static void waitUntilUrlChange(final String newUrl, int seconds) { Wait wait = new FluentWait(Utils.driver) .withTimeout(5000, TimeUnit.MILLISECONDS) .pollingEvery(100, TimeUnit.MILLISECONDS) .ignoring(NoSuchElementException.class); wait.until(new Function() { public Boolean apply(WebDriver d) { return d.getCurrentUrl().startsWith(newUrl); } }); } /** * 获取项目的配置信息,该配置信息合并了web项目的config.js与seleniumTest的settings.json配置信息 * * @param projectName * 项目名称 * @return 项目配置的json对象 */ public static JSONObject getProjectSettings(String projectName) { JSONObject jsonObj = null; ObjectMapper mapper = new ObjectMapper().configure( Feature.ALLOW_COMMENTS, true); mapper.configure(Feature.ALLOW_UNQUOTED_FIELD_NAMES, true); mapper.configure(Feature.ALLOW_SINGLE_QUOTES, true); try { // 获取Selenium自动化测试的配置信息 InputStream instream1 = Utils.class.getClassLoader() .getResourceAsStream( "test_4_1/config/" + projectName + "/config.js"); Scanner scanner1 = new Scanner(instream1); String content = scanner1.useDelimiter("\\Z").next(); content = content.replaceAll("var sstsConfig = ", ""); jsonObj = mapper.readValue(content, JSONObject.class); // String testConfigFilename = seleniumTestConfigPath + "/" // + projectName + "/settings.json"; InputStream instream2 = Utils.class .getClassLoader() .getResourceAsStream( "test_4_1/config/" + projectName + "/settings.json"); Scanner scanner2 = new Scanner(instream2); String testConfigFileContent = scanner2.useDelimiter("\\Z").next(); JSONObject jsonObjTestSettings = mapper.readValue( testConfigFileContent, JSONObject.class); // 合并到jsonObj jsonObj.putAll(jsonObjTestSettings); instream1.close(); scanner1.close(); instream2.close(); scanner2.close(); } catch (IOException e) { e.printStackTrace(); } return jsonObj; } }