The PageObject pattern

PageObject is an approach widely used in testing to reduce code duplication and increase the reusability of code. It is a design pattern that defines a page using objects. Moreover, the page object provides easy maintenance of code, and the scripts can be read easily anytime by any user. It is a pattern representing an entire page or a portion of the page in an object-oriented behavior.

Let's discuss the PageObject design pattern with an example on the Google web page. To start with the example, let's create a class that emphasizes how to write PageObject methods for a page in detail (GoogleSearchPage.java). The search() and assertTitle()methods let you perform Google searches and to assert the page title on the results page. Here's how we create the aforementioned class for this example:

public class GoogleSearchPage {
  public WebDriver driver;
  private final Wait<WebDriver> wait;

  public GoogleSearchPage(WebDriver driver) {
    this.driver = driver;
    wait = new WebDriverWait(driver, 10);
    //driver.get("https://seleniumworks.com");
  }

  public void search() throws Exception{
    //  search google
    wait.until.(ExpectedConditions.presenceOfElementLocated(By.name("q")));
    driver.findElement(By.name("q")).sendKeys("Prashanth Sams");
    driver.findElement(By.name("q")).submit();
    System.out.println("Google Search - SUCCESS!!");
    Thread.sleep(4000);
  }

  public void assertTitle() throws Exception{
    //  assert google search
    Boolean b = driver.getTitle().contains("Prashanth Sams");
    System.out.println(b);
  }
}

Now, create a test class using the TestNG unit test framework (for example, TC.java). The following test methods perform three different tasks, namely, opening the Google URL, searching for a keyword, and finally asserting the page title on the Google results page:

public class TC {
  private WebDriver driver;
  public GoogleSearchPage Task;

  @BeforeTest
  public void setUp() throws Exception {
    System.out.println("Instantiating Chrome Driver...");
    driver = new ChromeDriver();
  }

  @Test
  public void Test01() throws Exception {
    URL url = new URL(driver);
    url.geturl();
  }

  @Test
  public void Test02() throws Exception {
    Task = new GoogleSearchPage(driver);
    Task.search();
  }

  @Test
  public void Test03() throws Exception {
    Task = new GoogleSearchPage(driver);
    Task.assertTitle();
}

  @AfterTest
  public void tearDown() throws Exception {
    driver.quit();
  }
}

Here, Selenium WebDriver is initiated at the start, followed by a series of test methods; the page objects are initialized inside the test class as well. The constructor avoids unusual errors by defining a driver as shown in the following Java class (URL.java). However, this class is significantly used to load the Google web page in this example. Once done with the task, it returns control to another class that contains PageObject methods for the tests to continue further. The following code exemplifies the discussion in this paragraph:

public class URL{
  public WebDriver driver;
  private String baseUrl;
  private boolean acceptNextAlert = true;
  private StringBuffer verificationErrors = new StringBuffer();

  public URL(WebDriver driver) {
    this.driver = driver;
    driver.get("http://www.google.co.in");
  }

  public GoogleSearchPage geturl() {
    System.out.println("Opened URL successfully");
    return new GoogleSearchPage(driver);
  }
}

The following is the final test report for all the preceding test cases:

The PageObject pattern

The PageFactory class

The PageFactory class is a class file under WebDriver's support library that maintains the PageObject pattern. It has the ability to find and locate elements quickly. The PageFactory class uses the initElements method to instantiate the WebDriver instance of PageObject. The following is the syntax for the the PageFactory class:

PageFactory.initElements(WebDriver driver, classname.class)

NullPointerException will be thrown when a user fails to implement PageFactory. By default, the name and id locator types can be accessed directly without labeling locators. For example, refer to the following code snippet:

private WebElement lst-ib; // Here, 'lst-ib' is an id
private WebElement q; // Here, 'q' is a name

lst-ib.sendKeys("selenium essentials");
q.sendKeys("Prashanth Sams");

Let's discuss PageFactory in detail with an example on the Google web page. This example is similar to the previous one. However, we will get to know how to make use of the PageFactory class efficiently in order to maintain the PageObject pattern. Let's create a test class using the TestNG unit-test framework (for example, GoogleTest.java). Initialize WebDriver and create an object using the PageFactory class as shown in the following snippet:

public class GoogleTest {
  private WebDriver driver;

 @BeforeTest
  public void setUp() throws Exception {
    driver = new FirefoxDriver();
  }

  @Test
  public void Test01() throws Exception{
    GoogleSearchPage page = PageFactory.initElements(driver, GoogleSearchPage.class);
    page.searchFor("Prashanth Sams");
  }

  @AfterTest
  public void Teardown() throws Exception{
    driver.quit();
  }
}

Now, create a class file (for example, GoogleSearchPage.java) containing methods where the locator values are declared without any attribute names:

public class GoogleSearchPage {

  private WebElement q; // Here's the Element
  public WebDriver driver;

  public GoogleSearchPage(WebDriver driver) {
    this.driver = driver;
    driver.get("http://www.google.com/");
  }

  public void searchFor(String text) {
    q.sendKeys(text);
    q.submit();
  }
}

Here, the element q is declared without stating any locator type. However, it automatically identifies whether it is id or name. The PageFactory class finds an element with the id attribute matching; if not, it searches for the name attribute.

The @FindBy annotation

There are several methods to locate an element and one among them is the @FindBy annotation from PageFactory, which supports PageObject. The annotations @FindBy and @FindBys let you find elements using locators easily. The following snippets are an alternative approach to define the Google search text field. Here's the first of these snippets:

@FindBy(how = How.NAME, using = "q")
private WebElement searchBox;

@FindBy(name "q")
private WebElement searchBox;

Let's discuss this with an example using the @FindBy annotation on the Google web page. Here, the @CacheLookup annotation is used to keep the elements in cache and utilize them from the next time for rapid test execution:

import org.openqa.selenium.support.CacheLookup;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.How;

public class GoogleSearchPage {

  @FindBy(how = How.NAME, using = "q") // or use @FindBy(name = "q")
  @CacheLookup
  private WebElement searchme;

  @FindBy(id = "lst-ib") // Less Verbose
  private WebElement submitme;
  //Here, both searchme & submitme refers to the same element

  public WebDriver driver;

  public GoogleSearchPage(WebDriver driver) {
    this.driver = driver;
    driver.get("http://www.google.com/");
  }

  public void searchFor(String text) {
    searchme.sendKeys(text);
    submitme.submit();
  }
}

The @FindBys annotation

The @FindBys annotation can have any numbers of tags in a series to define an element. In the following example, the @FindBys annotation handles three tags in a series to locate the Google search field. The tag series can be in top-to-bottom order, as shown in the following screenshot:

The @FindBys annotation

The following is the code for the @FindBys annotation:

import org.openqa.selenium.support.CacheLookup;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindBys;

public class GoogleSearchPage {

@FindBys({ @FindBy(id = "sb_ifc0"), @FindBy(id = "gs_lc0"), @FindBy(name = "q") })
  @CacheLookup // keeps the element in cache for rapid execution    
  private WebElement searchme;

  public WebDriver driver;

  public GoogleSearchPage(WebDriver driver) {
    this.driver = driver;
    driver.get("http://www.google.com/");
  }

  public void searchFor(String text) {
    searchme.sendKeys(text);
    searchme.submit();
  }
}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.222.32.67