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

  • 相关阅读:
    remove white space from read
    optimize the access speed of django website
    dowload image from requests
    run jupyter from command
    crawl wechat page
    python version 2.7 required which was not found in the registry windows 7
    health
    alternate rows shading using conditional formatting
    word
    【JAVA基础】static 关键字
  • 原文地址:https://www.cnblogs.com/shengs/p/7967331.html
Copyright © 2011-2022 走看看