Regular Selenium tests (in Java) might look like:
selenium.open("/login"); selenium.type("id=username", "bob"); selenium.type("id=password", "password"); selenium.click("Login"); selenium.waitForPageToLoad(); selenium.click("My Account"); selenium.waitForPageToLoad(); assertEquals("bob", selenium.getText("//table/tr/td/");
After a few tests, this kind of thing becomes painful to manage. The typical solution is to create a bunch of constants for IDs and Xpaths, but that doesn’t help too much.
Fellow Pivot Mike Grafton came up with a cool pattern for improving on this. The idea is to create a class representing each page of your web app. Each class contains two types of methods: a bunch of action methods (
typeUsername()), and a bunch of inspection commands (
When an action takes you to a new page, the corresponding action method returns a new class representing that page. When it stays on the same page, the method just returns “this”. This allows methods to be chained to make the tests more readable.
Here’s how that test would look using this new pattern:
MyAccountPage myAccountPage = new LoginPage(selenium) .typeUsername("bob") .typePassword("password") .clickLoginButton() .clickMyAccountLink(); assertEquals("bob", myAccountPage.getLoggedInUsername());
The constructor of each page class should validate that it’s on the correct page (waiting if necessary, and perhaps asserting on the page title).