Testing Web Applications with GEB provides concise summaries in 3 sentences or less:
GEB allows testing of web applications by driving browsers like Firefox using the Selenium WebDriver API. It integrates with jQuery-like content selection and supports features like page objects, modules, and JavaScript execution to simplify testing of Ajax applications. GEB uses Groovy for a more expressive and dynamic testing approach compared to other frameworks like Selenium.
9. Power of Selenium WebDriver 2.15.0
Elegance of jQuery content selection
Robustness of Page Object modelling
Expressiveness of Groovy
First Class Documentation
17. $(css selector, index, attribute / text matchers)
$("p") ➠ all <p>
CS
$("p", 3) ➠ 4th <p> S3
$("p")[3] ➠ 4th <p>
$("p")[0..2] ➠ 1st through 3rd <p>
18. Attribute Matchers
$("a", text:"Blade Runner")
➠ All <a> tags whose text is "Blade Runner"
$("a", href: contains("/name/")
➠ All <a> tags whose href attribute contains "/name/"
$("a", href: ~/nm[0-9]+/)
➠ All <a> tags whose href attribute matches the
pattern
19. Attribute Predicates
Case Sensitive Case Insensitive Description
startsWith iStartsWith start with value
contains iContains contains the value anywhere
endsWith iEndsWith end with value
contains value surrounded by whitespace (or at
constainsWord iContainsWord
begin or end)
notStartsWith iNotStartsWith DOES NOT start with value
notContains iNotContains DOES NOT contain value anywhere
notEndsWith iNotEndsWith DOES NOT end with value
DOES NOT contain value (surrounded by
notContainsWord iNotContainsWord
whitespace, or at begin or end)
21. Navigators are Groovy Collections
each() is a Groovy Collection method
groovy:000> castList = [:]
===> {}
groovy:000> b.$("table.cast_list tr").tail().each
{ castList[it.find("td.name").text()] = it.find("td.character").text() }
===> […]
groovy:000> castList
===> {Harrison Ford=Rick Deckard, Rutger Hauer=Roy Batty, Sean Young=Rachael,
Edward James Olmos=Gaff, M. Emmet Walsh=Bryant, Daryl Hannah=Pris, William
Sanderson=J.F. Sebastian, Brion James=Leon Kowalski, Joe Turkel=Dr. Eldon
Tyrell, Joanna Cassidy=Zhora, James Hong=Hannibal Chew, Morgan Paull=Holden,
Kevin Thompson=Bear, John Edward Allen=Kaiser, Hy Pyke=Taffey Lewis}
http://groovy.codehaus.org/groovy-jdk/java/util/Collection.html
29. Content Options
Option Type Default Description
Evaluate content once, or
cache boolean false
on each access
Error on page load if
content does not exist (use
required boolean true
false for optional or Ajax-
loaded)
Page or Class, On a link, identify the page
to null
list of Page or Class the link submits to
Wait for content to become
wait varies null
available (via Ajax/DHTML)
30. Page Methods
class Home extends Page {
static at = { title == "The Internet Movie Database (IMDb)" }
static url = ""
static content = {
boxOffice { $("h3", text:"Box Office").parent() }
boxOfficeLinks { boxOffice.find("a", text: iNotStartsWith("see more")) }
}
def clickBoxOffice(index) {
def link = boxOfficeLinks[index]
def label = link.text()
link.click()
waitFor { title.startsWith(label) }
}
}
groovy:000> b.to Home
===> null
groovy:000> b.clickBoxOffice 0
===> true
groovy:000>
31. Problem: Re-used web pages
class Movie extends Page {
static at = {
assert title.startsWith("Blade Runner")
true GEB 0.7 will magically
} convert to asserts
static content = {
rating { $(".star-box-gig-start").text() }
castList { $("table.cast_list tr").tail() }
}
}
groovy:000> b.$("#main table", 2).find("a",7).click(Movie)
===> null
groovy:000> b.page
===> Movie
groovy:000> b.verifyAt()
ERROR org.codehaus.groovy.runtime.powerassert.PowerAssertionError:
assert title.startsWith("Blade Runner")
| |
| false
The Bugs Bunny/Road-Runner Movie (1979) - IMDb
38. Solution: Module Lists
class CastRow extends Module {
static content = {
actorName { $("td.name").text() }
characterName { $("td.character").text() }
}
} Scope limited to each <tr>
class Movie extends Page {
String expectedTitle
static at = { title.startsWith expectedTitle }
static content = {
rating { $(".star-box-gig-start").text() }
castList { moduleList CastRow, $("table.cast_list tr").tail() }
}
}
39. groovy:000> b.at(new Movie(expectedTitle: "Blade Runner"))
===> true
groovy:000> b.castList[0].actorName
===> Harrison Ford
groovy:000> b.castList[0].characterName
===> Rick Deckard
groovy:000> b.castList*.actorName
===> [Harrison Ford, Rutger Hauer, Sean Young, Edward James Olmos, ⏎
M. Emmet Walsh, Daryl Hannah, William Sanderson, Brion James, Joe Turkel, ⏎
Joanna Cassidy, James Hong, Morgan Paull, Kevin Thompson, John Edward Allen, ⏎
Hy Pyke]
46. Reporting
package myapp.tests
Base class that reports at end of each test
import geb.spock.*
class Login extends GebReportingSpec {
def "successful login"() {
when:
go "login"
username = "user1"
report "login screen" Capture HTML and screenshot
login().click()
then:
title == "Welcome, User1"
}
}
reports/myapp/tests/Login/1-1-login-login screen.html
reports/myapp/tests/Login/1-1-login-login screen.png
reports/myapp/tests/Login/1-2-login-end.html
reports/myapp/tests/Login/1-2-login-end.png
47. Base Classes
Report end of each test
Framework Artifact Base Class Reporting Base Class
Spock geb-spock geb.spock.GebSpec geb.spock.GebReportingSpec
Junit 4 geb-juni4 geb.junit4.GebTest geb.junit4.GebReportingTest
Junit 3 geb-junit3 geb.junit3.GebTest geb.junit3.GebReportingTest
TestNG geb-testng geb.testng.GebTest geb.testng.GebReportingTest
Report failures only