Reputation: 334
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
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
Reputation: 51473
The PageFactory
injects WebElement
s 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 WebElement
s 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
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