The Blog Single

  • 01
    Jan

    POM, PageFactory Automation framework in selenium

    WebDriver supports POM (Page Object Model) via PageFactory class.  In order to use PageFactory, all the elements needs to be declared on a PageObject as “WebElement” or “List<WebElement>” as follow:

    import org.openqa.selenium.WebElement;

    public class GoogleSearchPage {
    // Here’s the element

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

    public void searchFor(String text) {
    // And here we use WebElement as defined above.
    searchBox.sendKeys(text);
    searchBox.submit();
    }
    }

    In order to execute above code, we need to Initialize PageObjects as follow:

    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.WebElement;
    import org.openqa.selenium.htmlunit.HtmlUnitDriver;
    import org.openqa.selenium.support.PageFactory;

    public class UsingGoogleSearchPage {
    public static void main(String[] args) {
    // Create a new instance of a driver
    WebDriver driver = new HtmlUnitDriver();

    // Navigate to the right place
    driver.get(“http://www.google.com/”);

    // Create a new instance of the search page class
    // and initialise any WebElement fields in it.
    GoogleSearchPage page = PageFactory.initElements(driver, GoogleSearchPage.class);

    // And now do the search.
    page.searchFor(“Cheese”);
    }
    }

    Explanation

    The PageFactory relies on using sensible defaults: the name of the field in the Java class is assumed to be the “id” or “name” of the element on the HTML page. That is, in the example above, the line:

    q.sendKeys(text);

    is equivalent to:

    driver.findElement(By.id("q")).sendKeys(text);

    Note

    • If you use the PageFactory, you can assume that the fields are initialised. If you don’t use the PageFactory, then NullPointerExceptions will be thrown if you make the assumption that the fields are already initialised.
    • List<WebElement> fields are decorated if and only if they have @FindBy or @FindBys annotation. Default search strategy “by id or name” that works for WebElement fields is hardly suitable for lists because it is rare to have several elements with the same id or name on a page.
    • WebElements are evaluated lazily. That is, if you never use a WebElement field in a PageObject, there will never be a call to “findElement” for it.
    • The functionality works using dynamic proxies. This means that you shouldn’t expect a WebElement to be a particular subclass, even if you know the type of the driver. For example, if you are using the HtmlUnitDriver, you shouldn’t expect the WebElement field to be initialised with an instance of HtmlUnitWebElement.

0 comments

Leave a reply