Javascript Page Object Pattern for Sahi

May 26, 2012

I've been reading about the virtues of the Page Object design pattern and am intrigued by the benefits it could offer. I found examples of it's use in many of the popular automation tools like Selenium, Watir and WatiN, but very little information about a Javascript implementation, or it being used in Sahi (my current automation tool of choice). Thus I was forced to have a go at it myself.

First off, a Page Object is a design pattern intended to create a model of a web page in code via a object or class. If you've written even a bit of automation code, you'll recognize the amount of chaff created to accommodate your ultimate test goal; clicking through ui elements, repetitive steps, etc.... a Page Object attempts to abstract those clicks and steps and allow for more elegant and maintainable test code. Therefore, for each page in your web application, you'd have a corresponding object that would provide the services offered by that page to your test.

An example

Here is my take at a Page Object pattern for Sahi, written in Javascript (though Sahi does use a "$" in front of it's vars to differentiate them from page Javascript vars). In my example, I've created three objects; a home page, a search results page and a shared, common object page (that might exist on multiple pages). You can copy this code and run it as is in Sahi Pro (the open source version currently has a bug that will make this fail. Email me and I'll explain a workaround).

// page object via object literal...
var GoogleHome = {
    // you need the $ if passing to Sahi methods...
    $url : "",
    $textbox : "q",
    $submitButton : "Google Search",
    $title : "Google",

    isPage : function() {
        \_assertEqual(this.$title, \_title());
    visit : function() {
        this.isPage(); // verify we're on the right page...
    searchFor : function($searchText) {
        \_setValue(\_textbox(this.$textbox), $searchText);

// results page object...
var GoogleResults = {
    $title : new RegExp(".\*Google"),
    SearchFilter : new SearchFilter, // include common page element...

    getFirstResult : function() {
        \_alert(\_getText(\_link(0, \_in(\_div("ires")))));

// share a common page element between page objects via constructor...
function SearchFilter() {
    // this. makes the method public...
    this.filterBy = function($filterName) {
        \_click(\_link($filterName, \_in(\_div("leftnav"))));
// test...
GoogleHome.searchFor("javascript page object pattern");


As you can see, in addition to the cleaner testing code, Page Objects also offer a bit of encapsulation, not to mention the ability to define a domain language for your tests.

I decided to go with object literals for the page objects as they take care of instantiation (no need to use new to create an object) and they are easy to use and read. One downside is they can't currently take advantage of inheritance but they seem to do the trick nonetheless.

Any items shared across multiple pages (nav bar, sidebar, etc...) should be broken out into their own objects and instantiated in the various page objects that make use of them (like SeachFilter in my example).

As I'm new to this concept, please do feel free to email me and let me know how this code might be improved. I'd be happy to have the input.

UPDATE: I've since added an updated and expanded example with working code: