zoukankan      html  css  js  c++  java
  • 【转】Webdriver的PageObject改造By 张飞

    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 "";
    }


    Page类实例化时初始化@FindBy注解并赋值给FindElement类
    将@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;
    }
     
    }
    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(WebElementExt.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 WebElementExt element;
     
    public void clieckButton(){
    element.click();
    }
     
    }
  • 相关阅读:
    he canvas has been tainted by cross-origin data and tainted canvases may not be exported
    Uncaught SecurityError: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.
    HOW TO REPLACE ALL OCCURRENCES OF A CHARACTER IN A STD::STRING
    one or more multiply defined symbols found
    Std::map too few template arguments
    Always run a program in administrator mode in Windows 10
    JSON.parse 必须用双引号包起来
    jni4net使用小结
    Cannot generate C# proxy dll with JNI4NET tool, running batch file as trusted assembly?
    Java access to the Domino Objects, Part 1
  • 原文地址:https://www.cnblogs.com/Ronaldo-HD/p/10100750.html
Copyright © 2011-2022 走看看