At this sections there are some very experimental concepts described which need to be proofed and may change or be completly removed.
As we have seen in [Basics] a page is opened by declaring a method with the annotation @PageAccessor.
Lets say you want to define a set of pages which can be accessed directly by entering an url. That PageObjects implement an interface Openable. To add the information which url to enter you have to redefine your methods in every PageObject:
:::java
public interface Openable {
void open();
void open(Map<String, String> parameters);
}
@Page(name="Search")
public interface Search extends Openable {
@PageAccessor(uri="/search.jsp")
void open();
@PageAccess(uri="/search.jsp")
void open(Map<String, String> parameters);
}
By adding the PageAccessor at page-level you can define your methods this way
:::java
public interface Openable {
@PageAccessor
void open();
@PageAccessor
void open(Map<String, String> parameters);
}
@Page(name="Search")
@PageAccessor(uri="/search.jsp")
public interface Search extends Openable {
}
Say you have a function you want to support all (or maybe a subset) of your PageObjects. That function cannot be declared but needs to be implemented. Then you would have something like that:
:::java
public abstract class ReloadableSite {
private WebDriver driver;
public ReloadableSite(WebDriver driver) {
this.driver = driver;
}
public void reload() {
driver.navigate().reload();
}
}
@Page(name="Search")
@PageAccessor(uri="/search.jsp")
public abstract class Search extends ReloadableSite implements Openable {
public Search(WebDriver driver) {
super(driver);
}
@Locator(name="...", id="...")
public abstract IButton someButton();
}
Thats ugly. Now all of your PageObjects need to define a constructor. You have to write "public abstract" to all of your Locator-methods and you loose the flexibility of interfaces. Just because you want to define one method at superclass-level.
PopperFramwork lets you implement methods on interfaces:
:::java
public interface ReloadableSite {
@MethodImplementedBy(ReloadRunner.class)
void reload();
public static class ReloadRunner implements IMethodRunner<ReloadableSite, Void> {
private WebDriver driver;
public ReloadRunner(WebDriver driver) {
this.driver = driver;
}
@Override
public Void runMethod(ISite arg0, Object[] arg1) {
driver.navigate().refresh();
return null;
}
}
}
@Page(name="Search")
@PageAccessor(uri="/search.jsp")
public interface Search extends ReloadableSite, Openable {
@Locator(name="...", id="...")
IButton someButton();
}