/geb-demo

Demo of the Geb Web-Testing Framework

Primary LanguageGroovy

Geb

Another web testing framework?

  • Geb uses CSS / Jquery like syntax for selecting HTML elements
  • Full Power of Groovy
  • Page-Object Pattern

Installation

  • Recommended Groovy Version 1.7.5
  • I’ve tested on Ubuntu Linux, Windows XP, Cygwin
  • For this demo, you need Firefox installed
    • Latest Selenium driver has some bugs
    • For this pres, I use org.seleniumhq.selenium:selenium-firefox-driver:2.0a
  • To test other browsers (Chrome, Internet Explorer), I think you need to have that browser installed on your system.

Quick Start

Run this from the Groovy Console

<<header>>  
      assert title == "Help - About"
      // Un-comment driver.close() to close the browser window
      // driver.close()  
      assert $("a", text:"Loooogin").size() == 0
      assert $("a", text:"Login").size() == 1
<<footer>>
  • Grapes pulls down dependency goodies. How it works is beyond me.
  • Selenium runs under the hood, and creates an instance of the specified browser.
  • Test results are some kind of instance of selenium’s FirefoxWebElement

http://webdriver.googlecode.com/svn/javadoc/org/openqa/selenium/firefox/FirefoxWebElement.html

Attribute Selectors

Given the following HTML:
<h3 class="reallynow">Thanks</h3>

Here’s the Geb code we need to match the HTML. (Both expressions match)

assert $("h3", class: "reallynow", text: "Thanks").size() == 1
assert $("h3.reallynow", text: "Thanks").size() == 1

Testing Relationships

Here we have a <p> element that’s right next to an h3 which has the version of our software. We can make sure the website shows the correct version.
<h3 class="reallynow">Version</h3>
<p>Version 0.2 "Dangle"</p>
assert $("h3.reallynow").siblings("p").find { it.text() =~/Dangle/ }
assert $("h3.reallynow").siblings("p").find { it.text() =~/0\.2/ }

Failed Login

$("a", text:"Login").click()
$("#loginForm").username = "badguy"
$("#loginForm").password = "badguypassword"
$("#login").click()
assert title == "Login"
assert $("*", text: ~/.*Invalid.*username.*password/).size() > 0

Successful Login

$("a", text:"Login").click()
$("#loginForm").username = "gug"
$("#loginForm").password = "groovy18"
$("#login").click()
assert $("*", text: ~/.*Welcome to Enrollio, gug!.*/).size() > 0

One more powerful example

  • On our students page, we have a Students table
  • Students table contains links to different “Woodstock Jacksons”. One’s a parent, the other is a student.
  • In the first test, we want to click on the parent
  • Second test, click on the student
<!-- Link to Woodstock Jackson (parent is in the FIRST td) -->
<tr><td><a href="/parents/2">Woodstock Jackson</a></td>
<!-- Link to Woodstock Jackson (student is in the SECOND td) -->
<tr><td><a href="/parents/2">Schizoid Jackson></td><td><a href="/students/2">Woodstock Jackson</a>
$("a", text:"Students").click()

def linkToWoodstockParent = $("tr td:first-child a", text:contains("Woodstock Jackson"))
assert parentLink.size() != 0
parentLink.click()
assert title == "Contact:Woodstock Jackson"
driver.navigate().back()

def linkToWoodstockStudent = $("tr td:nth-child(2) a", text:contains("Woodstock Jackson"))
assert studentLink.size() != 0
studentLink.click()
assert title == "Student: Woodstock Jackson"

Moving Along

We need a test harness

  • Improvements to the above setup
  • Need to find out how to get more descriptive test results when running simple tests.
  • Would need to replicate a lot of code when running similar tests

We have a lot of code that’s duplicated within each script

  • Login code
  • Click here, click there
  • What if “Students” link changes or moves?

Page Object Pattern

http://geb.codehaus.org/manual/latest/intro.html#the_page_object_pattern

Example

class LoginPage extends Page {
    static url = "http://enrollio.org/login"
    static at = { title == "Login" }
    static content = {
        usernameField { $("input[name='username']") }
        passwordField { $("input[name='password']") }
        loginButton{ $("#login") }
        errorsMessage { $("div.errors").text() }
    }
}
 
Browser.drive(LoginPage) {
        usernameField.value("badguy")
        passwordField.value("badguypassword")
        loginButton.click()
        assert at(LoginPage)
        assert errorsMessage =~ /(?i)invALID uSERNAME.*password/
        assert errorsMessage =~ /Invalid username.*password/
}

Compare this to Failed Login

Easy to Get Started

  • Demo of Peter’s SpringOnePresentation

http://github.com/geb/geb-springone2gx-2010-example.git

See Also