Babulu
Babulu

Reputation: 334

Need of page factory in page object model

Can anyone please explain what is the need of pagefactory in page object model.

Eg. We use below code for initializing the page object class.

LoginPage loginPage = PageFactory.initElements(driver, LoginPage.class);

Why can't we use

LoginPage loginPage = new LoginPage(driver);

Similarly while returning new page in each page object method we use

return new PageFactory.initElements(driver, HomePage.class);

why should it not be

return new HomePage(driver);

Please help me in understanding PageFactory, as I am new to page object pattern. I am thinking we can still manage without using PageFactory.

Upvotes: 1

Views: 5493

Answers (3)

vins
vins

Reputation: 15400

I see that you use java for selenium. You should take a look at the Arquillian-Graphene framework. It is an extesnion. So it will not mess up with your existing framework.

Main aim of using Arquillian framework is - you do not need Page Factory. It has nice set of annotations to inject the page object model at run time.

For ex: I create a page object for Google as shown here.

public class Google {

    @Drone
    private WebDriver driver;

    public void goTo(){
        driver.get("https://www.google.com");
    }

    public boolean isAt(){
        return driver.getTitle().equals("Google");
    }
}

In my testng/junit,

@RunAsClient
public class GoogleSearchTest extends Arquillian{

    @Page
    Google google;


    @Test(priority = 1)
    public void launchGoogle(){

        google.goTo();
        Assert.assertTrue(google.isAt());

    }

}

Did you notice? @Drone - automatically injects the browser instance. @Page automatically creates a Google page object instance.

Check here for more info:

http://www.testautomationguru.com/arquillian-graphene-page-fragments/

Upvotes: 0

René Link
René Link

Reputation: 51473

The PageFactory injects WebElements defined in your page object using the WebDriver you provide.

The documentation of PageFactory says:

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.

So you can just define a field of type WebElement with the id or name of an WebElement and the PageFactory takes care that it will be available.

I am thinking we can still manage without using PageFactory.

Yes you can. If you don't use the PageFactory you must lookup the WebElements using the WebDriver api, e.g.

WebElement searchBox = driver.findElement(By.id("q"));

But you can also annotate a field with @FindBy, @FindBys or @FindAll , e.g.

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

I am new to page object pattern

A page object is an encapsulation of some web page. It's api provides a user-like access to the web page and hides the implementation details of a page (web elements, ids, etc.). Thus you can write your tests in a way a user would describe the tests.

For example

 @Test
 public void googleSearch(){
     WebDriver driver = ....;

     GooglePage google = GooglePage.open(driver);
     SearchResultPage searchResult = google.search("stackoverflow");
     SearchResult firstResult = searchResult.getResult(0); // first result

     Assert.assertEquals("Stack Overflow", firstResult.getTitle());
     ...
 }

Upvotes: 2

JimEvans
JimEvans

Reputation: 27496

You can, in fact, use the page object pattern without using the PageFactory class. The page object pattern simply abstracts your business logic away from the physical structure of your pages. What the PageFactory class gives you is the ability to use annotations to automatically find the elements on the page without resorting to explicit findElement calls. It lets you write code like this:

public class LoginPage {
  @FindBy(how = How.ID, using = "user")
  private WebElement userNameTextBox;

  @FindBy(how = How.ID, using = "password")
  private WebElement passwordTextBox;

  public void fillLoginDetails(String userName, String password) {
    userNameTextBox.sendKeys(userName);
    passwordTextBox.sendKeys(password);
  }
}

Note that there are no explicit findElement calls here. Using the PageFactory allows you to write this code more cleanly and eliminates some boilerplate code. The same thing could be accomplished by using findElement in your page objects to locate the appropriate elements. It's a stylistic choice.

Upvotes: 4

Related Questions