Fork me on GitHub

30 Nov 2010

Encapsulating page state and actions in Geb

Geb Page and Module classes are just regular Groovy classes. In addition to the content DSL you can declare methods just as you would in any other class. Those methods can use content properties directly. This is really useful for encapsulating state and actions in a reusable way.

In this post I want to run through a couple of simple examples of re-usable Module classes that are enhanced with methods. Although the examples deal with Module classes everything here is equally applicable to Page classes.

Page object methods tend to fall into two categories:

report on some aspect of page state (e.g. whether a user is logged in or not).
have non-void return types (I prefer explicit return types on methods but def would work too).
can be used for making assertions.
perform an action such as clicking a link or button.
will typically be void (note that it's not necessary to return a Page instance or class from a navigation method in Geb).
throw IllegalStateException if the action is invalid in the current page state.

First let's consider an authentication module that can be used across every page in a site. The markup of the module can be completely different depending on whether a user is logged in or not. When not logged in a username/password form is shown:

<aside id="auth"> 
        <legend>Log In</legend> 
        <form action="/auth/login" method="post" > 
            <label>Username: <input name="username"/></label> 
            <label>Password: <input type="password" name="password"></label> 
            <button name="login" type="submit">Log In</button> 

When logged in, a welcome message is shown:

<aside id="auth"> 
    Welcome back <span class="username">blackbeard</span> 
    <a href="/auth/logout" name="logout">Log Out</a> 

To model this I'll create a Geb Module like this:

class AuthModule extends Module {
    static base = { $("aside#auth") }

    static content = {
        username(required: false) { $(".username").text() }
        logoutButton(required: false, to: HomePage) { $("a[name=logout]") }
        form(required: false) { $("form") }
        loginButton(required: false, to: HomePage) { $("button[name=login]") }

The required: false declaration is used to declare content properties that may or may not be on the page. The username and logoutButton properties are only present in the logged-in state and the form and loginButton properties are only present in the logged-out state.

I can use the module in some tests like this:

def "user can log in"() {
    authModule.form.username = "blackbeard"
    authModule.form.password = "yohoho!"

    at HomePage
    authModule.username == "blackbeard"

def "user can log out"() {

    at HomePage
    authModule.username == null

This is a good start but there are several assumptions and bits of page detail creeping into the test. The test is using the presence or absence of the username to determine if someone is logged in or not. That doesn't lead to a very meaningful assertion in the test and is assuming things about the page detail. Likewise the login step is quite long-winded and likely to be repeated in a lot of tests. Not only that but it won't work if a user is already logged in as the form fields won't be present on the page.

To encapsulate the module's state and actions better I'll add the following methods:

boolean isLoggedIn() { username }

void login(String username, String password = "password") {
    if (loggedIn) throw new IllegalStateException("already logged in")
    form.username = username
    form.password = password

void logout() {
    if (!loggedIn) throw new IllegalStateException("already logged out")

The methods declared by the module abstract some detail away very effectively. The isLoggedIn method means I can change the login detection mechanism later and just change the module's method rather than a bunch of tests. The login and logout methods abstract away the how of logging in and out so the test can just deal with the what. I've used IllegalStateException for cases where a method is called when the module is not in the correct state. The tests now look much clearer:

def "user can log in"() {
    authModule.login "blackbeard"

    at HomePage
    authModule.username == "blackbeard"

def "user can log out"() {

    at HomePage

Another good example of encapsulating state and behaviour like this is a typical pagination module that would appear on a list or search results page. The markup would look something like this (I've omitted the link href attributes for clarity):

<nav class="pagination">
    <a class="prevLink">Previous</a>
    <a class="step">1</a>
    <span class="currentStep">2</span>
    <a class="step">3</a>
    <a class="nextLink">Next</a>

The previous and next links will only appear when there is a previous or next page and no links will be present at all if there is only a single page. The following Module class models the state and actions of this component:

class Pagination extends Module {
    static content = {
        links(required: false) { $("a") }
        currentPage(required: false) { $(".currentStep")?.text()?.toInteger() ?: 1 }
        nextLink(required: false) { links.filter(".nextLink") }
        previousLink(required: false) { links.filter(".prevLink") }

    boolean isFirstPage() {

    boolean isLastPage() {

    void toPage(int pageNumber) {
        def link = links.filter(text: "$pageNumber")
        if (!link) throw new IllegalArgumentException("Page number $pageNumber not present in pagination")

    void nextPage() {
        if (lastPage) throw new IllegalStateException("Already on the last page")

    void previousPage() {
        if (firstPage) throw new IllegalStateException("Already on the first page")

Breaking the Module down in detail:

  • The currentPage property returns the current page number as an int and defaults to 1 if there is no pagination present in the page.
  • The isFirstPage and isLastPage observer methods use the absence of the previous and next links respectively to determine if the current page is the first or last one.
  • The toPage method finds a numbered link and clicks it, throwing IllegalArgumentException if no such link is present.
  • The nextPage and previousPage action methods throw IllegalStateException if the relevant link is not on the page.

The Pagination class now neatly encapsulates the detail of the pagination elements and presents a higher-level façade to the tests.

Fuller versions of the examples in this post can be found on GitHub.


Unknown said...

Hi Rob,

Just referenced this post on Stack Overflow. You might be able to add some more clarity to the solution



Unknown said...

Have gathered plentiful knowledge related to the long run trade encapsulation services through this share. Present buyers need the most premium features in their each service, so the firm should all the time prepared for this.

buyket said...

تتعدد الحاجه الي شركة خدمات توفر للعميل اكثر من خدمة لتوفر له الوقت والجهد في ان واحد
فمثلا يحتاج بعض العملاء الي شركة مكافحة حشرات بجدة
للتخلص اولا من الحشرات المنزليه
قبل النقل الي المنزل الجديد عن طريق شركة نقل اثاث بجدة وتكون متخصصه في تلك الخدمات وعلي اعلي مستوي
كما يتوافر لديها ايضا قسم بالرياض الرش قبل الانشاء عن طريق شركة تنظيف خزانات بجدة
شركة تنظيف مساجد بالرياض
شركة تنظيف بجدة
شركة رش دفان بالرياض شركة مكافحة الفئران بالرياض
لتكمل بها مجموعت الخدمات التي تهدف لها

Unknown said...

Welcomes to google underwater keep sharing such ideas in the future as well. google mirror this was actually what i was looking for,and i am glad to came here!
elgoog Hi! I’ve been reading your blog for a while google gravity I want you to thank for your time of this wonderful read!!! google terminal now and finally got the courage to go ahead and give youu a shout out from Austin Texas!
google pacman Just wanted to tell you keep up the fantastic work!my weblog: google guitar I definately enjoy every little bit of it and I have you bookmarked to check out new stuff of your blog a must read blog! google snake
Amazing insight you have on this, Happy wheels it's nice to find a website that details so much information about different artists... Age of war 2 This article always blew me... Earn to die For how many times I have read this.
slither io
big farm

Linda Rose said...

Thanks for sharing the information. It is very useful for my future. keep sharing
Run 3 | Stick Run 2 | Return Man 2
Run 2 | Stick Run | Return Man | run 3 game | run 3 unblocked | Tank Trouble | Tank Trouble 2
Papa's Bakeria | Papa Bakeria | Five nights at Freddy's | Five nights at Freddy's 4

Unknown said...

Article really helpful and wonderful. Thanks for sharing. You can visit my website
square quick, square quick, square quick, square quick, square quick, square quick, square quick, square quick, square quick, square quick

Unknown said...

شركة تنظيف بالرياض
شركة نظافة بالرياض
شركات تنظيف بالرياض
شركات نظافة بالرياض
شركة تنظيف منازل بالرياض
شركة نظافة منازل بالرياض
شركات تنظيف منازل بالرياض
شركة تنظيف شقق بالرياض
شركة نظافة شقق بالرياض
شركات تنظيف شقق بالرياض
شركة تنظيف خزانات بالرياض
شركات تنظيف خزانات بالرياض
شركة نظافة خزانات بالرياض
شركات نظافة خزانات بالرياض
شركة رش مبيدات بالرياض
شركة مكافحة حشرات بالرياض
شركة كشف تسربات المياه بالرياض

ngocanh said...

Your blog posts are more interesting and impressive. I think there are many people like and visit it regularly, including me.I actually appreciate your own position and I will be sure to come back here.
b612 l b612 app l baixar b612 l download b612 l b612 apk

Unknown said...

شركة قمة الدقة للخدمات المنزلية
شركة مكافحة النمل الابيض بالظهران
شركة رش مبيدات بالدمام
شركة رش مبيدات بالخبر
شركة رش مبيدات بالظهران
شركة رش دفان بالدمام
شركة رش دفان بالخبر
شركة رش دفان بالظهران
رش مبيدات
شركة مكافحة الحشرات
مكافحة حشرات
شركة مكافحة حشرات
شركة مكافحة حشرات بالاحساء
شركة مكافحة النمل الابيض بالاحساء

agario games said...

Thanks for your post! I believe there are many who feel the same satisfaction as I read this article! I hope you will continue to have such articles to share with everyone!

aliamay said...

Watch champion trophy 2017 live streaming CT 2017 of all the matches live scorecard Ball by ball commentary of all the matches.
Match prediction CT 2017.
Astrology prdiction CT 2017
TV channels broadcast CT 2017

Bloons tower defense 5 said...

Thanks for the informations you shared!! I hope you will continue to have similar posts to share with everyone! I believe a lot of people will be surprised to read this article!
happy wheels

Unknown said...

Thanks for your post! Through your pen I found the problem up interesting! I believe there are many other people who are interested in them just like me! Thanks your shared!... I hope you will continue to have similar posts to share with everyone! I believe a lot of people will be surprised to read this article!
slither io

Unknown said...

I was very impressed by this post, this site has always been pleasant news. Thank you very much for such an interesting post. Keep working, great job! In my free time, I like play game: What about you?

Quba Khan said...

Here we go with the Latest Govt jobs 2017 -2018 ( 3,18,200 Sarkari Naukri jobs openings. Government Jobs 2017-18: Get notification of all Government Jobs, Sarkari Naukri recruitment, bank jobs, State Govt jobs including SSSB, SSC, PSC, UPSC etc. Latest 10th 12th Pass Govt Jobs 2017 – 2018(62000 Sarkari) records.
Lest talk the latest 10th 12th Pass Govt Jobs 2017 – 2018(62000 Sarkari Vacancies Opening .... Latest Govt jobs 2017 -2018 ( 3,18,200 Sarkari Naukri jobs openings ). Sarkari Naukri 2017, सरकारी नौकरी, Government Jobs. Sarkari Naukri provide employment news of sarkari naukri 2017 for government jobs. Sarkari Naukri update latest job news for govt sector companies - 2017. Sarkari Naukri: Latest Govt Jobs, Sarkari Job, सरकारी ... - Amar Ujala Translate this pageबुधवार, 22 नवंबर 2017; +. सतीश धवन स्पेस सेंटर में टेक्नीशियन/ ड्राफ्ट्समैन के पद पर वैकेंसी • पॉलीटेक्निक के 89 स्टूडेंट्स. Sarkari Naukri in India 2017 | सरकारी नौकरी भारत में
Looking to get Sarkari Naukri? Check सरकारी नौकरी in India. Latest updates on 10000+ vacancies opportunity. You can apply online or offline. Upcoming Government Jobs 2018 ( 2,77000 Sarkari Naukri Opening). Jump to Jharkhand Staff Selection Commission recruitment 2017 - HP Police Recruitment 2017 – 1073 ... Govt Jobs (Sarkari Naukri 2018). Sarkari Naukri in Rajasthan Govt Jobs in Rajasthan Vacancy 2017. Latest Government Jobs in Rajasthan 2017 For Sarkari Naukri in Rajasthan and Current Vacancy in Jaipur, Udaipur, Jodhpur, Bikaner. Sarkari Naukri 2018 सरकारी नौकरी Sarkari Jobs Naukari. Sarkari Naukri Daily is Top Sarkari Job Portal and sarkari naukri 2017 for Banking, Railway Naukari, Public Sector, Research Sarkari Naukri 2018 in India. ... Top Current Affairs For Sarkari Naukri Preparation 22 November 2017 • Latest Government Jobs 2018-2019 | THE SARKARI NAUKRI. Oct 18, 2016 - We have listed here the latest Sarkari Naukri / Government Jobs with Number ... BPSC, Assistant Engineer, 1345 posts, 06.12.2017, Click Here. Police Jobs 2018 | THE SARKARI NAUKRI. Chhattisgarh Police Recruitment 2017 – 2976 posts of Constable (GD) and ... Here we have listed Jobs / Sarkari Naukri in Police Department of various Indian

Unknown said...

Best Android Apps for PC

sound cloud for pc

spotify premium apk

mobdro APK latest version

mobdro app for pc

vidmate app for pc

kakaotalk for pc

mobdro App for PC

mobdro apk latest version

pandora premium apk

شركه تنظيف said...

تنظيف المنازل بالرياض
فحص تسربات المياه بالرياض 
شركة تنظيف منازل بالرياض
عزل الأسطح بالرياض
شركة كشف تسربات بالرياض 
نقل عفش بالمدينة
تنظيف منازل بالرياض

Unknown said...




jacklinemelda said...

The writers at our company have sufficient experience in creating high-quality Affordable Custom Essay Writing Service and we always ensure that we provide quality Writing Services Online to all.

Unknown said...

Great info latina movies

The Digi Experts said...

ayush shukla
ayush shukla
ayush shukla
ayush shukla
ayush shukla
ayush shukla
ayush shukla

seo company said...

Fast Social Follower will help you increase your visiliblty on social media platform such as Buy Facebook Followers

steve said...

شركة تنظيف بالامارات
شركة تنظيف دبي
شركة تنظيف كنب بدبي بالبخار
شركة تنظيف سجاد بدبي
شركة تنظيف في ابوظبي
شركة تنظيف منازل فى العين
شركة تنظيف كنب في ابوظبي
شركة تنظيف كنب العين

Ideal Assignment Help said...

Our specialists in engineering subjects at Ideal Assignment Help are capable of giving world category, however affordable assignment facilitate service for engineering students from Australia as well as everywhere the world in completing their engineering assignments, numerical, essays, projects. IdealAssignmentHelp specialists of Engineering Assignment Help team are committed to deliver assignments even when a student is faced with the tight of point in time.

رواد الحرمين said...

عزل اسطح بالدمام لحماية وزيادة عمر الخزان الافتراضي.

شركه عزل فوم بالدمام عزل فوم