zoukankan      html  css  js  c++  java
  • Selenium Webdriver 的 PageObject 改造

    PageObject中提供了一个@FindBy注解,也非常好用,但由于其是一次性全部初始化所有的WebElement,对于当前还不存在于页面上的Element在初始化时就会报错,为了解决这个问题,自然就不能用这个@FindBy注解了,而我们可以自已去写一个类似的注解来解决这个问题,下面是思路的实现:

    自定义一个@FindBy注解

    @Retention(RetentionPolicy.RUNTIME)
    @Target({ ElementType.FIELD })
    public @interface FindBy {
    
        String name();
    
        int age();
    
        int lazy() default 0;
    }
    

    定义一个TestInfo类来模拟WebElement类

    public class TestInfo {
    
        private String name;
    
        private int age;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "TestInfo [name=" + name + ", age=" + age + "]";
        }
    
    }
    

    解析@FindBy注解

    public class PageUtil {
    
        private static void initialLazyInfo(Object obj, int lazy) {
            try{
                Field[] fields = obj.getClass().getDeclaredFields();
                for (Field field : fields) {
                    if(field.isAnnotationPresent(FindBy.class) && field.getType().equals(TestInfo.class)){
                        FindBy findBy = field.getAnnotation(FindBy.class);
                        if(findBy.lazy()==lazy){
                            TestInfo temp = new TestInfo();
                            temp.setName(findBy.name());
                            temp.setAge(findBy.age());
                            field.setAccessible(true);
                            field.set(obj, temp);
                        }
                    }
                }
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    
        public static void initialLazy(Object obj){
            PageUtil.initialLazyInfo(obj, 0);
        }
    
        public static void initialLazy(Object obj, int lazy){
            PageUtil.initialLazyInfo(obj, lazy);
        }
    
    }
    

    使用方式

    public class DemoPage {
    
        public DemoPage() {
            PageUtil.initialLazy(this);
        }
    
        @FindBy(name="zf1", age=1)
        private TestInfo info1;
    
        @FindBy(name="zf2", age=2, lazy=1)
        private TestInfo info2;
    
        public void test(){
            System.out.println("info1 is: " + info1);
            System.out.println("info2 is: " + info2);
            PageUtil.initialLazy(this, 1);
            System.out.println("info2 is: " + info2);
        }
    
        public static void main(String[] args) {
            DemoPage dp = new DemoPage();
            dp.test();
        }
    
    }
    

    运行结果

    info1 is: TestInfo [name=zf1, age=1]
    info2 is: null
    info2 is: TestInfo [name=zf2, age=2]
    

    说明

    • 将TestInfo初始化进行了分层次的初始化
    • 在需要用到的地方用PageUtil.initialLazy(this, int);进行初始化

    以上虽然实现了分层次的初始化,但是在要用到的地方都需要调用PageUtil.initialLazy(this, int);,还是显得有点麻烦,要解决这个问题,还得从改造WebElement类开始,然后自定义一个@FindBy注解,并且在需要用到元素的地方再去判断并初始化。

    定义@FindBy注解

    @Retention(RetentionPolicy.RUNTIME)
    @Target({ ElementType.FIELD })
    public @interface FindBy {
    
        String id() default "";
    
        String name() default "";
    
        String className() default "";
    
        String css() default "";
    
        String tagName() default "";
    
        String linkText() default "";
    
        String partialLinkText() default "";
    
        String xpath() default "";
    }
    

    @FindBy注解中的值结赋到一个中间类中去,在Page类进行初始化的时候进行赋值

    public class FindElement {
    
        private String id;
    
        private String name;
    
        private String className;
    
        private String css;
    
        private String tagName;
    
        private String linkText;
    
        private String partialLinkText;
    
        private String xpath;
    
        public String getId() {
            return id;
        }
    
        public void setId(String id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getClassName() {
            return className;
        }
    
        public void setClassName(String className) {
            this.className = className;
        }
    
        public String getCss() {
            return css;
        }
    
        public void setCss(String css) {
            this.css = css;
        }
    
        public String getTagName() {
            return tagName;
        }
    
        public void setTagName(String tagName) {
            this.tagName = tagName;
        }
    
        public String getLinkText() {
            return linkText;
        }
    
        public void setLinkText(String linkText) {
            this.linkText = linkText;
        }
    
        public String getPartialLinkText() {
            return partialLinkText;
        }
    
        public void setPartialLinkText(String partialLinkText) {
            this.partialLinkText = partialLinkText;
        }
    
        public String getXpath() {
            return xpath;
        }
    
        public void setXpath(String xpath) {
            this.xpath = xpath;
        }
    
    }
    

    Page类实例化时初始化@FindBy注解并赋值给FindElement类

    public class PageUtil {
    
        public static void initialWebElement(Object obj) {
            try{
                Field[] fields = obj.getClass().getDeclaredFields();
                for (Field field : fields) {
                    if(field.isAnnotationPresent(FindBy.class) && field.getType().equals(WebElement.class)){
                        FindBy findBy = field.getAnnotation(FindBy.class);
                        FindElement findElement = new FindElement();
                        if(!"".equals(findBy.id())){
                            findElement.setId(findBy.id());
                        }else if(!"".equals(findBy.name())){
                            findElement.setName(findBy.name());
                        }else if(!"".equals(findBy.className())){
                            findElement.setClassName(findBy.className());
                        }else if(!"".equals(findBy.css())){
                            findElement.setCss(findBy.css());
                        }else if(!"".equals(findBy.tagName())){
                            findElement.setTagName(findBy.tagName());
                        }else if(!"".equals(findBy.linkText())){
                            findElement.setLinkText(findBy.linkText());
                        }else if(!"".equals(findBy.partialLinkText())){
                            findElement.setPartialLinkText(findBy.partialLinkText());
                        }else if(!"".equals(findBy.xpath())){
                            findElement.setXpath(findBy.xpath());
                        }
                        WebElementExt ext = new WebElementExt(findElement);
                        field.setAccessible(true);
                        field.set(obj, ext);
                    }
                }
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    
    }
    

    改造WebElement类,利用的是装饰器模式

    public class WebElementExt implements WebElement {
    
        private static WebDriver driver = new FirefoxDriver();
    
        private FindElement findElement;
    
        public WebElementExt(FindElement findElement) {
            this.findElement = findElement;
        }
    
        private WebElement element;
    
        private WebElement getWebElement(){
            if(element != null){
                return element;
            }
            if(findElement.getId() != null){
                element = this.waitForElement(By.id(findElement.getId()));
            }else if(findElement.getName() != null){
                element = this.waitForElement(By.name(findElement.getName()));
            }else if(findElement.getClassName() != null){
                element = this.waitForElement(By.className(findElement.getClassName()));
            }else if(findElement.getCss() != null){
                element = this.waitForElement(By.cssSelector(findElement.getCss()));
            }else if(findElement.getTagName() != null){
                element = this.waitForElement(By.tagName(findElement.getTagName()));
            }else if(findElement.getLinkText() != null){
                element = this.waitForElement(By.linkText(findElement.getLinkText()));
            }else if(findElement.getPartialLinkText() != null){
                element = this.waitForElement(By.partialLinkText(findElement.getPartialLinkText()));
            }else if(findElement.getXpath() != null){
                element = this.waitForElement(By.xpath(findElement.getXpath()));
            }
            if(this.waitElementToBeDisplayed(element)){
                return element;
            }
            return null;
        }
    
        private WebElement waitForElement(final By by) {
            WebElement element = null;
            try {
                element = new WebDriverWait(driver, 20).until(new ExpectedCondition<WebElement>() {
                    public WebElement apply(WebDriver d) {
                        return d.findElement(by);
                    }
                });
            } catch (Exception e) {
                e.printStackTrace();
            }
            return element;
        } 
    
        private boolean waitElementToBeDisplayed(final WebElement element) {
            boolean wait = false;
            if (element == null)
                return wait;
            try {           
                wait = new WebDriverWait(driver, 20).until(new ExpectedCondition<Boolean>() {
                    public Boolean apply(WebDriver d) {
                        return element.isDisplayed();
                    }
                });
            } catch (Exception e) {         
               e.printStackTrace();
            }
            return wait;
        }
    
        @Override
        public void click() {
            this.getWebElement();
            element.click();
        }
    
        @Override
        public void submit() {
            this.getWebElement();
            element.submit();
        }
    
        @Override
        public void sendKeys(CharSequence... charSequences) {
            this.getWebElement();
            element.sendKeys(charSequences);
        }
    
        @Override
        public void clear() {
            this.getWebElement();
            element.clear();
        }
    
        @Override
        public String getTagName() {
            this.getWebElement();
            return element.getTagName();
        }
    
        @Override
        public String getAttribute(String s) {
            this.getWebElement();
            return element.getAttribute(s);
        }
    
        @Override
        public boolean isSelected() {
            this.getWebElement();
            return element.isSelected();
        }
    
        @Override
        public boolean isEnabled() {
            this.getWebElement();
            return element.isEnabled();
        }
    
        @Override
        public String getText() {
            this.getWebElement();
            return element.getText();
        }
    
        @Override
        public List<WebElement> findElements(By by) {
            this.getWebElement();
            return element.findElements(by);
        }
    
        @Override
        public WebElement findElement(By by) {
            this.getWebElement();
            return element.findElement(by);
        }
    
        @Override
        public boolean isDisplayed() {
            this.getWebElement();
            return element.isDisplayed();
        }
    
        @Override
        public Point getLocation() {
            this.getWebElement();
            return element.getLocation();
        }
    
        @Override
        public Dimension getSize() {
            this.getWebElement();
            return element.getSize();
        }
    
        @Override
        public String getCssValue(String s) {
            this.getWebElement();
            return element.getCssValue(s);
        }
    }
    

    使用方法

    public class DemoPage {
    
        public DemoPage() {
            PageUtil.initialWebElement(this);
        }
    
        @FindBy(xpath="//abc")
        private WebElement element;
    
        public void clieckButton(){
            element.click();
        }
    
    }
    

    经过上面这样改造后,即便是页面中动态加载的元素,也不用担心会报错了,也不用多次初始化了!

    https://testerhome.com/topics/10803

  • 相关阅读:
    裴蜀定理
    欧几里得算法
    最大公约数
    质数和合数
    整除
    CSP斗地主
    skkyk:点分治
    题解:P2130 狂奔的Wzf
    题解:最大子树和
    博客大换主题祭
  • 原文地址:https://www.cnblogs.com/shengs/p/7967331.html
Copyright © 2011-2022 走看看