tags:

views:

63

answers:

1

In the example below (Taken from the Book of Geb), we're clicking on a button that takes us to another page.

class GoogleHomePage extends Page {
    static url = "http://google.com"
    static at = { 
        title == "Google" 
    }
    static content = {
        searchField { $("input[name=q]") }
        searchButton(to: GoogleResultsPage) { $("input[value='Google Search']") }
    }
}

Browser.drive(GoogleHomePage) {
    searchField.value("Chuck Norris")
    searchButton.click()
    assert at(GoogleResultsPage)
    assert resultLink(0).text() ==~ /Chuck/
}

How can we pass state when going to another page? eg The user has selected this language, in the next page, I expect the page to be in that language. A more generic example:

import geb.*
import grails.plugin.geb.GebSpec

class GoogleHomePage extends Page {
   static url = "http://google.com"
   static at = { title == "Google" }
   static content = {
       searchField { $("input[name=q]") }
       searchButton(to: GoogleResultsPage, searchTerm:searchField.value()) { $("input[value='Google Search']") }
   }
}

class GoogleResultsPage extends Page {

  def searchTerm

  static at = {
    title == "${searchTerm} - Google Search"
  }
}

class MainFunctionalSpec extends GebSpec {

 def "Google search"() {
   when:
   to GoogleHomePage

   then:
   searchField.value("Chuck Norris")
   searchButton.click()
   assert at(GoogleResultsPage)
 }
}

This code has 2 problems, I get a "No such property: searchField for class: GoogleHomePage" on searchButton.click() when trying to populate searchTerm. Even if I hardcode what gets passed, GoogleResultsPage.searchTerm is null and the at assert fails. Any ideas?

+1  A: 

This is not really possible with 0.4. The map options to template definitions become the options to that template. What is more, content templates are defined in a static context, but their closure definitions are evaluated in an instance context. The end result being that it's impossible to access instance state from that point.

The solution is to use the new lifecycle hooks in 0.5:

http://bamboo.ci.codehaus.org/browse/GEB-MASTERDEFAULTS/latest/artifact/Manual/pages.html#lifecycle_hooks

class GoogleHomePage extends Page {
    static url = "http://google.com"
    static at = { title == "Google" }
    static content = {
        searchField { $("input[name=q]") }
        searchButton(to: GoogleResultsPage, searchTerm:searchField.value()) { $("input[value='Google Search']") }
    }

    def onUnload(GoogleResultsPage nextPage) {
        nextPage.searchTerm = searchField.value()
    }
}

class GoogleResultsPage extends Page {
    def searchTerm
    static at = {
        title == "${searchTerm} - Google Search"
    }
}

This is available in that latest downloadable 0.5-SNAPSHOT versions from the codehaus snapshot repository.

Luke Daley
Perfect - Thank you!
Peter