8.2. Opening the page

A page object is usually designed to work with a particular web page. When the open() method is invoked, the browser will be opened to the default URL for the page.

The @DefaultUrl annotation indicates the URL that this test should use when run in isolation (e.g. from within your IDE). Generally, however, the host part of the default URL will be overridden by the webdriver.base.url property, as this allows you to set the base URL across the board for all of your tests, and so makes it easier to run your tests on different environments by simply changing this property value. For example, in the test class above, setting the webdriver.base.url to https://staging.mycompany.com would result in the page being opened at the URL of https://staging.mycompany.com/somepage.

You can also define named URLs that can be used to open the web page, optionally with parameters. For example, in the following code, we define a URL called open.issue, that accepts a single parameter:

@DefaultUrl("http://jira.mycompany.org")
@NamedUrls(
  {
    @NamedUrl(name = "open.issue", url = "http://jira.mycompany.org/issues/{1}")
  }
)
public class JiraIssuePage extends PageObject {
    ...
}

You could then open this page to the http://jira.mycompany.org/issues/ISSUE-1 URL as shown here:

page.open("open.issue", withParameters("ISSUE-1"));

You could also dispense entirely with the base URL in the named URL definition, and rely on the default values:

@DefaultUrl("http://jira.mycompany.org")
@NamedUrls(
  {
    @NamedUrl(name = "open.issue", url = "/issues/{1}")
  }
)
public class JiraIssuePage extends PageObject {
    ...
}

And naturally you can define more than one definition:

@NamedUrls(
  {
          @NamedUrl(name = "open.issue", url = "/issues/{1}"),
          @NamedUrl(name = "close.issue", url = "/issues/close/{1}")
  }
)

You should never try to implement the open() method yourself. In fact, it is final. If you need your page to do something upon loading, such as waiting for a dynamic element to appear, you can use the @WhenPageOpens annotation. Methods in the PageObject with this annotation will be invoked (in an unspecified order) after the URL has been opened. In this example, the open() method will not return until the dataSection web element is visible:

@DefaultUrl("http://localhost:8080/client/list")
    public class ClientList extends PageObject {

     @FindBy(id="data-section");
     WebElement dataSection;
     ...

     @WhenPageOpens
     public void waitUntilTitleAppears() {
         element(dataSection).waitUntilVisible();
     }
}