selenium测试框架使用xml作为对象库

之前已经写过一篇:

selenium测试框架篇,页面对象和元素对象的管理

上次使用的excel作为Locator对象管理,由于excel处理不够方便,有以下缺点:

  • 不能实现分page 加载Locator对象
  • 不能够实现Locator对象重名
  • 文件比较大,读写速度没有xml快

所以,重新写了使用dom4j操作xml,使用xml管理Locator对象,能够有效解决以上问题

首先,定义Locator文件

<?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对应一个真实的页面element

之前定义过的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;
    }

}
View Code

每一个Locator对象包含3属性 ByType 、timeOut时间和相应的xpath、id......的value

接下来需要写一个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起来,也算是一种关键字驱动.

传入的两个参数分别是library的路径和对应的page

那么怎么获取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());
    }
View Code

这样,这个框架能够实现一些基本操作,下一步还需要实现失败重试截图,配合虚拟机

下载地址:https://github.com/tobecrazy/Demo

 

posted @ 2015-09-10 23:58  to be crazy  阅读(5693)  评论(1编辑  收藏  举报