1

Example code:

Driver is being passed as an Argument so that Selenium is able to locate the element on the browser (driver).

Element is returned, so that an Action can be performed on it.

Method is declared as Public Static, so that it can be called in any other method without instantiate the class.

Follow the same rule for creating LogIn Page class.

So each and every single fragment, using the POM, always gets a WebDriver reference? Each and every fragment might then invoke PageFactory.initElements(driver, this)?

Just trying narrow down an overly broad, sprawling, question.

If each POM, each fragment, is as:

package pageObjects;

import org.openqa.selenium.*;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

public class LogIn_Page {
    private static WebElement element = null;

    public static WebElement txtbx_UserName(WebDriver driver){
         element = driver.findElement(By.id("log"));
         return element;
    }

     public static WebElement txtbx_Password(WebDriver driver){
         element = driver.findElement(By.id("pwd"));
         return element;
    }

     public static WebElement btn_LogIn(WebDriver driver){
         element = driver.findElement(By.id("login"));
         return element;
    }
}

then it's all static all the way down, is it not? How can this be refactored so that static isn't relied on so extensively, the POM is followed, and, as a bonus, PageFactory is employed?

Here's a sample using PageFactory:

public LoginPage(WebDriver driver) {
    PageFactory.initElements(driver, this);
}

@FindBy(how = How.ID, using = "username")
private WebElement userName;

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

@FindBy(how = How.ID, using = "login-btn")
private WebElement login;

public void logIn(String userName, String password) {
    this.userName.sendKeys(userName);
    this.password.sendKeys(password);
    this.login.click();
}

Let's say that this LoginPage wanted to create a page fragment, using the PageFactory which the POM utilized, how would it do so?

  • where is the "refactor my code to make it good" button? Meant in jest. I'm just trying to understand PageFactory usage and the POM. I'm not literally asking someone to come along and fix my code. Nor figuratively. – Thufir Dec 28 '18 at 16:55
2

I appreciate that author's contribution to the people's global knowledge sharing but I have doubt on how well he mastered his Java skills at least because of he doesn't adhere coding style convention that discourages snake_case style. Nobody also uses capitalized letters in package names. So I wouldn't rely on that or at least I would treat that with certain level of skepticism.

Moving to your question I'd like to spotlight the following:

  • Basically each of the fields in your example with PageFactory represent a fragment. So if you want your page to provide a page fragment you just introduce getter method to your page.
  • Using PageFactory approach lets you shortcut the way of fragmenting the page

However there are still some advantages in the first approach like:

  • you can parameterize locators which you cannot do with PageFactory approach since annotations cannot have dynamic values
  • It is easier to troubleshoot and analyze stacktrace since when you use reflection a lot of logic is built in runtime so you wouldn't have the "line where the issue happened".

Summing up, PageFactory approach seems to be enough since you can describe a fragment as annotated field and just provide it for outer world using getters.

  • It was just the first example I found, but, yeh. Second one in q is better source. When using PageFactory the instance must be initialized and so a driver reference must get passed in? – Thufir Dec 28 '18 at 19:04
  • @Thufir the instance of what? – Alexey R. Dec 29 '18 at 16:11
  • Good q. an instance of LoginPage would need a WebDriver reference to use PageFactory? So, any fragment employing PageFactory also needs a WebDriver reference? As a matter of practice, where does the reference originate? In the application driver classes main method? – Thufir Dec 29 '18 at 16:49
  • 1
    @Thufir This depends. If you utilize unit test frameworks, you don't have a main class. You rather have test classes which are controlled by a framework using reflection mechanism. In such the case you may have your driver as the field of your test class and instantiate it in @Before method. Then you instantiate your pages within a test and pass driver object there.Another way is to implement Singleton pattern-a special class that would expose static method that would return WebDriver.The specific is that when invoked the first time it creates an object and then just returns ready one. – Alexey R. Dec 29 '18 at 17:50
  • 1
    @Thufir this might be the topic for a separate question. – Alexey R. Dec 29 '18 at 17:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.