以前已經寫過一篇:css
上次使用的excel做爲Locator對象管理,因爲excel處理不夠方便,有如下缺點:html
因此,從新寫了使用dom4j操做xml,使用xml管理Locator對象,可以有效解決以上問題java
首先,定義Locator文件git
<?xml version="1.0" encoding="UTF-8"?> <map> <!--locator of page map info --> <page pageName="com.dbyl.libarary.pageAction.HomePage"> <!--Locator lists --> <locator type="ByXpath" timeOut="3" value="//div[@class='top-nav-profile']//img[@class='avatar']">profile</locator> </page> <!--locator of page map info --> <page pageName="com.dbyl.libarary.pageAction.LoginPage"> <!--Locator lists --> <locator type="" timeOut="3" value="//input[@name='account' and not(@autocomplete)]">loginEmailInputBox</locator> <locator type="ByXpath" timeOut="3" value="//button[@class='sign-button submit' and text()='登陸']">loginButton</locator> <locator type="ByXpath" timeOut="3" value="//div[@class='top-nav-profile']//img[@class='avatar']">profile</locator> <locator type="ByXpath" timeOut="3" value="//input[@name='password' and @placeholder='密碼']">loginPasswordInputBox</locator> </page> </map>
每個Page對應一個真實的頁面,而每個page下的Locator對應一個真實的頁面elementgithub
以前定義過的Locator類以下:數組
package com.dbyl.libarary.utils; /** * This is for element library * * @author Young * */ public class Locator { private String element; private int waitSec; /** * create a enum variable for By * * @author Young * */ public enum ByType { xpath, id, linkText, name, className, cssSelector, partialLinkText, tagName } private ByType byType; public Locator() { } /** * defaut Locator ,use Xpath * * @author Young * @param element */ public Locator(String element) { this.element = element; this.waitSec = 3; this.byType = ByType.xpath; } public Locator(String element, int waitSec) { this.waitSec = waitSec; this.element = element; this.byType = ByType.xpath; } public Locator(String element, int waitSec, ByType byType) { this.waitSec = waitSec; this.element = element; this.byType = byType; } public String getElement() { return element; } public int getWaitSec() { return waitSec; } public ByType getBy() { return byType; } public void setBy(ByType byType) { this.byType = byType; } }
每個Locator對象包含3屬性 ByType 、timeOut時間和相應的xpath、id......的valueapp
接下來須要寫一個wrapper框架
package com.dbyl.libarary.utils; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.HashMap; import java.util.Iterator; import org.dom4j.Attribute; import org.dom4j.Document; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.dom4j.io.OutputFormat; import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; import com.dbyl.libarary.utils.Locator.ByType; public class xmlUtils { /** * @author Young * @param path * @param pageName * @return * @throws Exception */ public static HashMap<String, Locator> readXMLDocument(String path, String pageName) throws Exception { System.out.print(pageName); HashMap<String, Locator> locatorMap = new HashMap<String, Locator>(); locatorMap.clear(); File file = new File(path); if (!file.exists()) { throw new IOException("Can't find " + path); } SAXReader reader = new SAXReader(); Document document = reader.read(file); Element root = document.getRootElement(); for (Iterator<?> i = root.elementIterator(); i.hasNext();) { Element page = (Element) i.next(); if (page.attribute(0).getValue().equalsIgnoreCase(pageName)) { System.out.println("page Info is:" + pageName); for (Iterator<?> l = page.elementIterator(); l.hasNext();) { String type = null; String timeOut = "3"; String value = null; String locatorName = null; Element locator = (Element) l.next(); for (Iterator<?> j = locator.attributeIterator(); j .hasNext();) { Attribute attribute = (Attribute) j.next(); if (attribute.getName().equals("type")) { type = attribute.getValue(); System.out.println(">>>>type " + type); } else if (attribute.getName().equals("timeOut")) { timeOut = attribute.getValue(); System.out.println(">>>>timeOut " + timeOut); } else { value = attribute.getValue(); System.out.println(">>>>value " + value); } } Locator temp = new Locator(value, Integer.parseInt(timeOut), getByType(type)); locatorName = locator.getText(); System.out.println("locator Name is " + locatorName); locatorMap.put(locatorName, temp); } continue; } } return locatorMap; } /** * @param type */ public static ByType getByType(String type) { ByType byType = ByType.xpath; if (type == null || type.equalsIgnoreCase("xpath")) { byType = ByType.xpath; } else if (type.equalsIgnoreCase("id")) { byType = ByType.id; } else if (type.equalsIgnoreCase("linkText")) { byType = ByType.linkText; } else if (type.equalsIgnoreCase("name")) { byType = ByType.name; } else if (type.equalsIgnoreCase("className")) { byType = ByType.className; } else if (type.equalsIgnoreCase("cssSelector")) { byType = ByType.cssSelector; } else if (type.equalsIgnoreCase("partialLinkText")) { byType = ByType.partialLinkText; } else if (type.equalsIgnoreCase("tagName")) { byType = ByType.tagName; } return byType; } /** * @author Young * @throws IOException */ public static void writeXMLDocument() throws IOException { OutputFormat format = OutputFormat.createPrettyPrint(); XMLWriter writer = new XMLWriter(new FileWriter("output.xml"), format); Document document = DocumentHelper.createDocument(); Element root = document.addElement("map"); root.addComment("locator of page map info"); Element page = root.addElement("page").addAttribute("pageName", "com.dbyl.libarary.pageAction.HomePage"); page.addComment("Locator lists"); page.addElement("locator").addAttribute("type", "ByName") .addAttribute("timeOut", "3") .addAttribute("value", "\\\\div[@name]").addText("loginButton"); page.addElement("locator").addAttribute("type", "ById") .addAttribute("timeOut", "3") .addAttribute("value", "\\\\div[@id]").addText("InputButton"); writer.write(document); writer.close(); } }
定義一個readXMLDocument 方法,返回一個hashMap用來和頁面元素名字和Locator對象match起來,也算是一種關鍵字驅動.dom
傳入的兩個參數分別是library的路徑和對應的pageide
那麼怎麼獲取page的class路徑?
能夠經過反射機制獲取:
locatorMap = xmlUtils.readXMLDocument(path, this.getClass().getCanonicalName());
這樣每次只按照page對象去加載其頁面的Locator對象,而不是一次性所有加載到內存
hashMap能夠經過key去獲取Locator,這樣也是極好的,比以前二維數組所有遍歷好多了
封裝一個basePage去處理Locator對象
package com.dbyl.libarary.utils; import java.io.IOException; import java.util.HashMap; import org.openqa.selenium.Alert; import org.openqa.selenium.By; 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; public class BasePage { protected WebDriver driver; // protected String[][] locatorMap; HashMap<String, Locator> locatorMap; String path = "C:/Users/Young/workspace/Demo/src/com/dbyl/libarary/pageAction/UILibrary.xml"; protected Log log = new Log(this.getClass()); protected BasePage(WebDriver driver) throws Exception { this.driver = driver; log.debug(this.getClass().getCanonicalName()); // locatorMap = ReadExcelUtil.getLocatorMap(); locatorMap = xmlUtils.readXMLDocument(path, this.getClass().getCanonicalName()); } protected void type(Locator locator, String values) throws Exception { WebElement e = findElement(driver, locator); log.info("type value is: " + values); e.sendKeys(values); } protected void click(Locator locator) throws Exception { WebElement e = findElement(driver, locator); log.info("click button"); e.click(); } protected void select(Locator locator, String value) throws Exception { WebElement e = findElement(driver, locator); Select select = new Select(e); try { log.info("select by Value " + value); select.selectByValue(value); } catch (Exception notByValue) { log.info("select by VisibleText " + value); select.selectByVisibleText(value); } } protected void alertConfirm() { Alert alert = driver.switchTo().alert(); try { alert.accept(); } catch (Exception notFindAlert) { throw notFindAlert; } } protected void alertDismiss() { Alert alert = driver.switchTo().alert(); try { alert.dismiss(); } catch (Exception notFindAlert) { throw notFindAlert; } } protected String getAlertText() { Alert alert = driver.switchTo().alert(); try { return alert.getText(); } catch (Exception notFindAlert) { throw notFindAlert; } } protected void clickAndHold(Locator locator) throws IOException { WebElement e = findElement(driver, locator); Actions actions = new Actions(driver); actions.clickAndHold(e).perform(); } public WebDriver getDriver() { return driver; } public void setDriver(WebDriver driver) { this.driver = driver; } public WebElement getElement(Locator locator) throws IOException { return getElement(this.getDriver(), locator); } /** * get by parameter * * @author Young * @param driver * @param locator * @return * @throws IOException */ public WebElement getElement(WebDriver driver, Locator locator) throws IOException { locator = getLocator(locator.getElement()); WebElement e; switch (locator.getBy()) { case xpath: log.debug("find element By xpath"); e = driver.findElement(By.xpath(locator.getElement())); break; case id: log.debug("find element By id"); e = driver.findElement(By.id(locator.getElement())); break; case name: log.debug("find element By name"); e = driver.findElement(By.name(locator.getElement())); break; case cssSelector: log.debug("find element By cssSelector"); e = driver.findElement(By.cssSelector(locator.getElement())); break; case className: log.debug("find element By className"); e = driver.findElement(By.className(locator.getElement())); break; case tagName: log.debug("find element By tagName"); e = driver.findElement(By.tagName(locator.getElement())); break; case linkText: log.debug("find element By linkText"); e = driver.findElement(By.linkText(locator.getElement())); break; case partialLinkText: log.debug("find element By partialLinkText"); e = driver.findElement(By.partialLinkText(locator.getElement())); break; default: e = driver.findElement(By.id(locator.getElement())); } return e; } public boolean isElementPresent(WebDriver driver, Locator myLocator, int timeOut) throws IOException { final Locator locator = getLocator(myLocator.getElement()); boolean isPresent = false; WebDriverWait wait = new WebDriverWait(driver, 60); isPresent = wait.until(new ExpectedCondition<WebElement>() { @Override public WebElement apply(WebDriver d) { return findElement(d, locator); } }).isDisplayed(); return isPresent; } /** * This Method for check isPresent Locator * * @param locator * @param timeOut * @return * @throws IOException */ public boolean isElementPresent(Locator locator, int timeOut) throws IOException { return isElementPresent(driver, locator, timeOut); } /** * * @param driver * @param locator * @return */ public WebElement findElement(WebDriver driver, final Locator locator) { WebElement element = (new WebDriverWait(driver, locator.getWaitSec())) .until(new ExpectedCondition<WebElement>() { @Override public WebElement apply(WebDriver driver) { try { return getElement(driver, locator); } catch (IOException e) { // TODO Auto-generated catch block log.error("can't find element " + locator.getElement()); return null; } } }); return element; } /** * @author Young * * @param locatorName * @return * @throws IOException */ public Locator getLocator(String locatorName) throws IOException { Locator locator; // for (int i = 0; i < locatorMap.length; i++) { // if (locatorMap[i][0].endsWith(locatorName)) { // return locator = new Locator(locatorMap[i][1]); // } // } // return locator = new Locator(locatorName); locator = locatorMap.get(locatorName); if (locator == null) { locator = new Locator(locatorName); } return locator; } }
接下來就能夠在pageAction使用,若是使用頁面跳轉,能夠使用反射機制,封裝一個PageFactory,根據傳入的Page類class建立對象
PageFactory以下:
package com.dbyl.libarary.utils; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import org.openqa.selenium.WebDriver; public class PageFactory { public synchronized static Object getPage(Class<?> key,WebDriver d) throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException { String test = key.getCanonicalName(); System.out.println(test); Class<?> clazz = Class.forName(test); Object obj = null; try { Constructor<?> constructor = clazz.getConstructor(WebDriver.class); obj = constructor.newInstance(d); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } return obj; } }
使用方法:
public static HomePage login(String email, String password) throws Exception { loginPage = new LoginPage(getDriver()); loginPage.waitForPageLoad(); loginPage.typeEmailInputBox(email); loginPage.typePasswordInputBox(password); loginPage.clickOnLoginButton(); Assert.assertTrue(loginPage.isPrestentProfile(), "login failed"); return (HomePage) PageFactory.getPage(HomePage.class, getDriver()); }
這樣,這個框架可以實現一些基本操做,下一步還須要實現失敗重試截圖,配合虛擬機