如何使用页面对象模型处理页面导航

R.L*_*R.L 7 java junit selenium automated-tests

我正在尝试使用页面对象模型进行测试,并试图构建页面类以能够执行类似“生成器模式”的结构(我很少见过,所以我不知道它是否有名称或什至是一件东西),例如以下示例:

public class Page1 implements Page  {
   public static Page1 goOn(){
       return new Page1();
   }

   public Page1 action1() {
       return this;
   }

   public Page2 gotoPage2() {
       return new Page2();
   }
}

public class Page2 implements Page  {
    public Page2 action2() {
        return this;
    }

    public Page2 gotoPage1() {
        return new Page2();
    }
 }
Run Code Online (Sandbox Code Playgroud)

然后像这样使用它:

Page1.goOn()
     .action1()
     .gotoPage2() //it return a Page2 object which mean you cant use Page1 methods anymore
     .action2()   // avoiding using the Page1 object which wouldnt be usable anymore if we stored it
     .goToPage1() //and poof we can only use Page1 methods again
     .action1()
     //etc...
Run Code Online (Sandbox Code Playgroud)

因此,这就是我处理“线性”页面更改的方式,它允许自动补全功能,并迫使您仅在编译之前执行有效操作(我认为这很不错,因为我讨厌运行时错误> :()

然后我尝试处理登录页面(它主要是下一步要做的一个简单示例),根据登录是否失败,可能会有2种不同的输出。对于具体情况我可以做2个功能,public Page1 LogIn(){...}并且public Page2 "LogInButFail(){...}但是对于原因,我想这样做:

public Page logIn(User user) {
    //do the login in the page
    //IF login worked:
    //return new Page2();
    //ELSE
    //return this; // or new Page1(), 
}
Run Code Online (Sandbox Code Playgroud)

问题是,要继续使用方法链,我在必须进行不安全的强制转换之前就已经有了它,这...我可以相当安全地很好地处理它们,但这意味着要打破Java关于键入的神圣规则...而且,我的静态打字迷的小脑子一直在努力决定该怎么做。

所以:-有没有做不安全转换的方法-如果不是,我应该:-使用不安全转换进行有效的代码(这是可以的,因为如果这些转换失败意味着测试之前就失败了)-做效率较低的代码但让Java开心:)

感谢您对本主题的任何帮助,如果您需要更多解释,请问我,我将尽我所能更准确地解释它(也请您知道这种做法对我是否感兴趣):)

编辑:使用动态logIn()之后,我使用以下函数来声明页面的类型(这是我必须避免尝试的不安全类型转换的地方)

public <T extends Page> T assertPage(Class<T> type){
  boolean isgood = (this.getClass.equals(type));
  assertTrue(isgood);
  if(isgood){
    return (T)this; //this is the unsafe cast im trying to avoid
  }else{
    //throw an exception as this is not suposed to happen
  }
}
Run Code Online (Sandbox Code Playgroud)

Gen*_*sev 1

因此,您需要页面对象方法,该方法将有条件地返回 Page1 或 Page2 的实例。为此,您创建了 Page 类型的方法。并且您想要执行此方法并继续使用 Page1 或 Page2 的实例,具体取决于条件而不进行强制转换。正确的?您可以通过泛型来做到这一点。这是简化的示例:

class Page{
    <T extends Page> T conditionalAction( T pageObject ){
        return pageObject;
    }
}
class Page1 extends Page{
    Page1 action1(){ return this; }
}
class Page2 extends Page{
    Page2 action2(){ return this; }
}
Run Code Online (Sandbox Code Playgroud)

现在,您可以执行以下操作:

Page1 page1 = new Page1();
Page2 page2 = new Page2();
page1.action1()
     .conditionalAction( page1 )
     .action1()
     .conditionalAction( page2 )
     .action2();
Run Code Online (Sandbox Code Playgroud)

您可以在父类/子类中的任何位置自由使用此类通用返回类型的方法。

如果您只想断言从方法中获得的类,则可以进行检查:

public Page conditionalAction( boolean condition ) {
    if ( condition ) {
        return new Page1();
    } else {
        return new Page2();
    }
}
Run Code Online (Sandbox Code Playgroud)

// 测试中

Page result = new Page1().conditionalAction( true );
if ( result instanceof Page1 ){
    Page1 page1 = (Page1) result;
} else if ( result instanceof Page2 ){
    Page2 page2 = (Page2) result;
}
Run Code Online (Sandbox Code Playgroud)