Blog

All articles

Practical Application of PageObjects pattern + Selenium (Java)

Practical Application of PageObjects pattern + Selenium (Java)

Let’s try to give here a practical example of how to implement an automated testing framework and start writing clear, easily supported and smoothly functioning tests, using PageObjects pattern and Selenium (Java).

Example:

The LoginPage includes a Login button and two entry fields, the User field and the Password field. If the login and the password you’ve sent are correct, a Home page containing the username and the Logout link is open. If the login and the password you’ve sent are INcorrect, an ErrorLogin page containing an error message and the Back To Login Page link is open.

Task:

Write test scripts:

  1. A correct login -> username verification -> Logout
  2. An incorrect Login -> error message verification -> Back To Login Page

Solution:

  1. Create a Selenium-based working context

Context.java:

public class Context {
    public static final String BROWSER_IE = "*iexplore";
    public static final String BROWSER_FF = "*firefox";
    public static final String BROWSER_CH = "*chrome";
    
    private static Context context;
    private static String siteUrl;
   
    private Selenium browser;
    private SeleniumServer seleniumServer;

    private Context() {
    }

    public static void initInstance(String browserType, String siteURL) {
        context = new Context();
        siteUrl = siteURL;
        context.setBrowser(new DefaultSelenium("localhost", 4444, browserType, siteURL));
        context.start();
    }

    public static Context getInstance() {
        if (context == null) {
            throw new IllegalStateException("Context is not initialized");
        }
        return context;
    }

    public Selenium getBrowser() {
        if (browser != null) {
            return browser;
        }
        throw new IllegalStateException("WebBrowser is not initialized");
    }
    
    public String getSiteUrl() {
       return siteUrl;
    }

    public void start() {
        try {
            seleniumServer = new SeleniumServer();
            seleniumServer.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
        browser.start();
    }
    
    public void close() {
        browser.close();
        browser.stop();
        seleniumServer.stop();
    }
        
    public void setBrowser(Selenium browser) {
        this.browser = browser;
    }
}
  1. Add to the abstract superclass Page the link for your working context as well as the service method you apply to obtain a Selenium getBrowser() object.

Page.java:

public abstract class Page {
    private Context context;
    private String currentPage; 
    
    protected Page(String pageUrl) {
        this.currentPage = pageUrl;
        setContext(Context.getInstance());
        init();
        parsePage();
    }

    private void setContext(Context instance) {
        this.context = instance;
    }

    protected abstract void init();
    protected abstract void parsePage();

    public String getCurrentPage() {
  return context.getSiteUrl() + this.currentPage;
    }
   
    protected Selenium getBrowser() {
        return context.getBrowser();
    }

    // ....
    // service methods...
    // ....
}
  1. Implement page classes necessary to write the test in question, namely: LoginPage, HomePage and ErrorLoginPage. Add to service methods the following elements: data-entry field, push button and click the link

LoginPage.java:

public class LoginPage extends Page {
   public static final String PAGE_URL = "/login.html";

   protected LoginPage() {
       super(PAGE_URL);
   }

   public static LoginPage openLoginPage() {
       LoginPage loginPage = new LoginPage();
       loginPage.getBrowser().open(PAGE_URL);
       return loginPage;
   }

   private void setUserName(String userName) {
       // Entry field code (Username)
       getBrowser().type("id=UserName", userName);
   }

   private void setPassword(String password) {
       // Entry field code (Password)
       getBrowser().type("id=Password", password);
   }

   private void pushLoginButton() {
       // Push Login Button code
       getBrowser().click("id=LoginButton");
   }

   protected void parsePage() {
       // Page elements parse
       //Enter relevant values using the data from the page   

}

   protected void init() {
       // Page initialization, for example, verification of the address of the page (URL):   
       if(!getBrowser().getLocation().equals(PAGE_URL)) {
           throw new IllegalStateException("Invalid page is opened");
       }
       // You can also check the availability of the object you need to continue writing your test     // 
   }

   private void loginAs(String userName, String password) {
       setUserName(userName);
       setPassword(password);
       pushLoginButton();
   }

   public HomePage login(String userName, String password) {
       loginAs(userName, password);
       return new HomePage();
   }

   public ErrorLoginPage loginInvalid(String userName, String password) {
       loginAs(userName, password);
       return new ErrorLoginPage();
   }
}

HomePage.java:

public class HomePage extends Page {
   public static final String PAGE_URL = "/home.html";
   private String loggedinUserName;

   protected HomePage() {
       super(PAGE_URL);
   }

   protected void init() {
       // Page initialization   }

   protected void parsePage() {
       // Page elements parse

       this.loggedinUserName = getBrowser().getText("id=userName");
   }

   public String getLoggedinUserName() {
       return loggedinUserName;
   }

   public LoginPage logout() {
       getBrowser().click("id=LogoutLink");
       return new LoginPage();
   }
}

ErrorLoginPage.java:

public class ErrorLoginPage extends Page {
   public static final String PAGE_URL = "/loginError.html";
   private String errorMessage;
 
   protected ErrorLoginPage() {
       super(PAGE_URL);
   }

   protected void init() {
       // Page initialization   }

   protected void parsePage() {
       // Page elements parse

       this.errorMessage = getBrowser().getText("id=ErrorMessage");
   }

   public String getErrorMessage() {
       return this.errorMessage;
   }

   public LoginPage backToLoginPage() {
       getBrowser().click("id=BackLink");
       return new LoginPage();
   }
}
  1. Write JUnit-based tests:
public class TestLogin extends TestCase {
   public void setUp() {
        // Context initialization 
        Context.initInstance(Context.BROWSER_IE, "http://www.testtesttestlogin.com");
    }

   public void testLoginLogout() {
        String userName = "tester";
        String password = "testPass";
        LoginPage loginPage = LoginPage.openLoginPage();
        HomePage homePage = loginPage.login(userName, password);
        assertEquals(userName, homePage.getLoggedinUserName());
        homePage.logout();
    }

    public void testInvalidLogin() {
        String userName = "$tester@#";
        String password = "********";
        String expectedMessage = "Invalid username or password"; 
        LoginPage loginPage = LoginPage.openLoginPage();
        ErrorLoginPage errorLoginPage = loginPage.loginInvalid(userName, password);
        assertEquals(expectedMessage, errorLoginPage.getErrorMessage());
        errorLoginPage.backToLoginPage();
    }

    protected void tearDown() throws Exception {
        // Close browser
       Context.getInstance().close(); 
    }
}

Here you have your first page objects, your first tests. Try it, perhaps the architecture will work. Hopefully these examples will help you to familiarize yourself with automated testing as soon as possible.