SlideShare a Scribd company logo
End-to-end
testing
A “spocky” story
Blatant self-promotion
Jesús L. Domínguez Muriel
@jdmuriel
Freelance, working at DIGIBÍS
End to end testing
- Chapter I: Why
- Chapter II: A spooky story
- Chapter III: Doing it with geb
Chapter I- Why: Sometimes, software starts small...
... and then it grows
Then, any small change can awake the beast
Ways to handle a 15 year software beast
- Flee
- Rewrite
- Refactor
How to handle a 15 year software beast (I): Flee
(No quiero mirar a nadie :-P )
How to handle a 15 year software beast (II): Rewrite
(Usually not an option)
How to handle a 15 year software beast (III): Refactor
- Refactor need tests
- You usually have untestable code
- Start testing at the lowest level possible
- Unit
- Integration
- End-to-end
- Add new code with good testing practices
- References
- https://www.youtube.com/watch?v=6W-EyIfUTmI
End-to-end tests
- Aka functional tests
- Test the application as an end user would do it
- Backend + frontend + everything in between
- Good for
- Acceptance criteria in user stories
- Systems with many coordinated pieces
- Testing untestable code
End to end testing
wisdom (I)
“End to end tests are like
cats”
(they always do the
same until they don’t)
End to end testing
wisdom (II)
““As anyone who has tried
knows, maintaining a large
suite of functional web tests for
a changing application can
become an expensive and
frustrating process””
Chapter II: a spooky story
Our story starts
with a library
With the years, it somehow has grown in other thing
Digibib - later Digiarch, Digihub, Digimus
- 2003 - 2017
- 43 jars, 136 dependencies
- Several hundred thousands lines of code
- Our own framework -in 2003 there is not Spring
- XML based :-(
- Reimplementations
- Code who nobody knows if it is used or not
- Several generations of front-ends
- Some time around 2012 we start thinking we need some tests
First iteration: Selenium IDE for non technical users
- Firefox extension
- Records browser activity
- Generates an script
- Small IDE to edit the script
- Script can be replayed
- Can be automated with some
effort
- Usable by trained non
technical users…?
- Firefox extension
- Records browser activity
- Generates an script
- Small IDE to edit the script
- Script can be replayed
- Can be automated with some
effort
- Usable by trained non
technical users…?
First iteration: Selenium IDE for non technical users
Selenium IDE: not what we expected
- Selecting the element to check not easy for non technical users (even
if the tool allows selecting it in the browser)
- By CSS
- By XPath
- Changes in a page require recapture of whole, long scripts
- Firefox updates break the extension
- Automation too brittle
- Multi script test execution too slow
- We never get end users to really use the IDE
Selenium IDE: not what we expected
Second iteration: exporting scripts to Java
Advantages
- News scripts can be created faster
- Easier to integrate with jenkins
- Easier to use other browsers
- Improved speed using headless browser
PhantomJS
Second iteration: exporting scripts to Java
Disadvantages
“The key to not pulling your hair out when dealing with web tests” - @ldaley
Tests call domain methods, no HTML
becomes
Access to the specific HTML and CSS only within that Page Objects
If the HTML is changed, only the affected Page object must be changed
Even Martin Fowler said it!!! (https://martinfowler.com/bliki/PageObject.html)
Page object pattern
So, we have work to do
3 or 4 most tested pages are already converted to Page objects
Login
Search form
Many still to do:
Results
Configuration, Indexes, etc.
Chapter III: Enters geb
Developer focused tool
Uses Groovy's dynamism to remove boilerplate, achieve pseudo English code
Uses WebDriver (evolution of Selenium 2) - Cross browser
Inspired by jQuery, robust Page Object modelling support
Good documentation. The “Book of Geb” http://www.gebish.org/manual/current/
Luke Daley (Gradle, Ratpack), Marcin Erdmann (current)
Why geb
Concise
Team already using Groovy with Spock for tests
Standard, tested implementation of utilities we were implementing ad hoc:
- Driver configuration
- Timeout configuration
- Screenshots
- Integration
You can give a talk!!!
Why not geb
Dependency madness (specially with Maven and eclipse)
No autocomplete (on Eclipse)
Oriented to Groovy developers
Geb in 10 slides - Browser
Browser.drive {
go "http://gebish.org"
assert title == "Geb - Very Groovy Browser Automation"
$("div.menu a.manuals").click()
waitFor { !$("#manuals-menu").hasClass("animating") }
$("#manuals-menu a")[0].click()
assert title.startsWith("The Book Of Geb")
}
Browser always have a current page and delegates methods and properties to it.
Geb in 10 slides - Test adapter
class GebishOrgTest extends GebSpec {
@Test
void “clicking first manual goes to book of geb”() {
given:
go "http://gebish.org" //Delegate to browser
when:
$("div.menu a.manuals").click() //Delegate to page
waitFor { !$("#manuals-menu").hasClass("animating") }
$("#manuals-menu a")[0].click()
then:
title.startsWith("The Book Of Geb")
}
}
//Automatic screenshot reporting after every test
Geb in 10 slides - $(), Navigator
Inspired by jQuery:
//$("<css selector>", index_or_range, <attribute/text matcher>)
$("div>p", 0..2, class: "heading", text: iEndsWith("!")) == [“a!”, “b!”]
$("p", text: ~/This./).size() == 2
$(By.id("some-id"))
$(By.xpath('//p[@class="xpath"]'))
//Navigators are iterable
$("p").max { it.text() }.text() == "2"
$("p")*.text().max() == "2"
//Methods for filtering, element traversal
$("div").filter(".a").not(".c").has("p", text: "Found!").hasNot("br")
$("div").find("p").parent().next().children("a", href: contains("www"))
//nextAll(), previous(), siblings(), parents(), closest(),
//nextUntil(), prevUntil(), parentsUntil()
Geb in 10 slides - $(), Navigator
//Composition
$( $("p.a"), $("p.b") )
//Methods
$("a.login").click()
$("input") << "test" << Keys.chord(Keys.CONTROL, "c")
//Properties
displayed, focused //single element needed
height, width, x, y
text(), tag(), classes(), @attribute
//CSS Properties
css("<css property>")
Geb in 10 slides - Page objects
class GebHomePage extends Page {
static url = "http://gebish.org"
static at = { title.contains "Groovy" }
static content = {
toggle { $("div.menu a.manuals") }
linksContainer { $("#manuals-menu") }
links { linksContainer.find("a") }
//stacked content
}
}
class TheBookOfGebPage extends Page {
//url is optional
static at = {
title.startsWith("The Book Of Geb")
}
}
void “clicking first manual goes to book of geb”() {
given:
to GebHomePage //checks at
when:
toggle.click()
waitFor {
!linksContainer.hasClass("animating")
}
links[0].click()
then:
at TheBookOfGebPage
}
Geb in 10 slides - Module
class GebHomePage extends Page {
static url = "http://gebish.org"
static at = { title.contains "Groovy" }
static content = {
manualsMenu { module(ManualsMenuModule)}
}
}
class ManualsMenuModule extends Module {
static content = {
toggle { $("div.menu a.manuals") }
linksContainer { $("#manuals-menu") }
links { linksContainer.find("a") }
}
void open() {
toggle.click()
waitFor { !linksContainer.hasClass
("animating") }
}
}
void “clicking first manual goes to book of geb”() {
given:
to GebHomePage //checks at
when:
manualsMenu.open()
manualsMenu.links[0].click()
then:
at TheBookOfGebPage
}
Geb in 10 slides - Content DSL, moduleList()
static content = {
«name»(«options map») { «definition» }
theDiv(required: false) { $("div", id: "a") }
theDiv(min: 1, max: 2) { $("div", id: "a") }
theDiv(cache: false) { $("div", id: "a") }
helpLink(to: HelpPage) { $("a", text: "Help") } //helpLink.click() sets browser page
loginButton(to: [LoginSuccessfulPage, LoginFailedPage]) { $("input.loginButton") }
dynamicallyAdded(wait: true) { $("p.dynamic") }
someDiv { $("div#aliased") }
aliasedDiv(aliases: "someDiv")
firstCartItem { $("table tr", 0) module (CartRow)}
cartItems {
$("table tr").tail().moduleList(CartRow)
}
assert cartItems.every { it.price > 0.0 }
Geb in 10 slides - Interact API, javascript interface
interact {
clickAndHold($('#draggable'))
moveByOffset(150, 200)
release()
} //All WebDriver Actions
<html>
<head>
<script type="text/javascript">
var aVariable = 1;
</script>
</head>
</html>
assert Browser.js.aVariable == 1
$("div#a").jquery.mouseover()
Geb in 10 slides - Configuration
GebConfig.groovy or GebConfig class in classpath
driver = “firefox” //driver = { new FirefoxDriver() }
environments {
prod {
driver = chrome
}
}
waiting {
timeout = 10
retryInterval = 0.5
presets {
slow {
Timeout = 20
}
}
}
retorsDir = “target/geb-reports”
Geb in 10 slides - Download API
Browser.drive {
to LoginPage
login("me", "secret")
def pdfBytes = downloadBytes(pdfLink.@href)
}
//downloadStream, downloadText, downloadContent
Browser.drive {
go "/"
def jsonBytes = downloadBytes { HttpURLConnection connection ->
connection.setRequestProperty("Accept", "application/json")
}
}
Geb in 10 slides - windows & frames
<a href="http://www.gebish.org" target="myWindow">Geb</a>
Browser.drive {
go()
$("a").click()
withWindow("myWindow", close: true) {
assert title == "Geb - Very Groovy Browser Automation"
}
withWindow({ title == "Geb - Very Groovy Browser Automation" }) {
assert $(".slogan").text().startsWith("Very Groovy browser automation.")
}
}
//withNewWindow(), withFrame(), withNewFrame()
Closures everywhere!
Contents, modules,
waitFor, browser, interact
Rewritten AST “a la Spock”, so that every
expression is turned in an assert (in ats, waits)
Wrapped classes - all page, browser available in
test specs
MethodMissing,
PropertyMissing
Geb’s black magic
Summary
If you have a big application,
use end-to-end tests
If you use Groovy, use Geb
Don’t walk alone in a misty forest...
Thanks
Questions?
@jdmuriel

More Related Content

PDF
How to make Ajax work for you
PDF
jQuery Proven Performance Tips & Tricks
PPTX
Maintainable JavaScript 2012
PPT
WordPress and Ajax
PDF
JavaScript Library Overview
PDF
Ajax Security
PDF
Better Selenium Tests with Geb - Selenium Conf 2014
PPT
jQuery introduction
How to make Ajax work for you
jQuery Proven Performance Tips & Tricks
Maintainable JavaScript 2012
WordPress and Ajax
JavaScript Library Overview
Ajax Security
Better Selenium Tests with Geb - Selenium Conf 2014
jQuery introduction

What's hot (20)

PDF
DrupalCon Dublin 2016 - Automated browser testing with Nightwatch.js
PPTX
FuncUnit
KEY
jQuery Anti-Patterns for Performance & Compression
PDF
Web Projects: From Theory To Practice
PDF
tut0000021-hevery
PDF
Realize mais com HTML 5 e CSS 3 - 16 EDTED - RJ
PDF
Django Heresies
PDF
Front End Development: The Important Parts
PDF
Pragmatic Browser Automation with Geb - GIDS 2015
KEY
#NewMeetup Performance
PDF
Design patterns revisited with PHP 5.3
PDF
Meetup Performance
PPT
High Performance Ajax Applications
PPTX
JavaScript Advanced - Useful methods to power up your code
PDF
Introduction To Django (Strange Loop 2011)
PPTX
jQuery from the very beginning
PPTX
The Django Web Application Framework 2
PDF
Working with the django admin
PPTX
SharePoint and jQuery Essentials
PDF
Create responsive websites with Django, REST and AngularJS
DrupalCon Dublin 2016 - Automated browser testing with Nightwatch.js
FuncUnit
jQuery Anti-Patterns for Performance & Compression
Web Projects: From Theory To Practice
tut0000021-hevery
Realize mais com HTML 5 e CSS 3 - 16 EDTED - RJ
Django Heresies
Front End Development: The Important Parts
Pragmatic Browser Automation with Geb - GIDS 2015
#NewMeetup Performance
Design patterns revisited with PHP 5.3
Meetup Performance
High Performance Ajax Applications
JavaScript Advanced - Useful methods to power up your code
Introduction To Django (Strange Loop 2011)
jQuery from the very beginning
The Django Web Application Framework 2
Working with the django admin
SharePoint and jQuery Essentials
Create responsive websites with Django, REST and AngularJS
Ad

Similar to End-to-end testing with geb (20)

PPT
Comprehensive Browser Automation Solution using Groovy, WebDriver & Obect Model
PPTX
Agile NCR 2013 - Gaurav Bansal- web_automation
PDF
Stanislaw potoczny kra_qa_21.01.20
PDF
Taming Functional Web Testing with Spock and Geb
PDF
Geb presentation
PPTX
QA Fest 2017. Ярослав Святкин. Тестовый фреймворк GEB для тестирования WEB пр...
PPTX
A test framework out of the box - Geb for Web and mobile
PPTX
Geb qa fest2017
PDF
Acceptance testing with Geb
PDF
Web driver selenium simplified
PDF
BDD, ATDD, Page Objects: The Road to Sustainable Web Testing
PDF
Web UI test automation instruments
PDF
Geb Best Practices
PDF
Browser-level testing
PPTX
Geb: Save Time with Groovy Functional Testing
PDF
Selenium Tips & Tricks - StarWest 2015
PPTX
Web UI Tests: Introduce UI tests using Selenium
PDF
Selenium Design Patterns And Best Practices Dima Kovalenko
KEY
Graceful Failure with Selenium and Continuous Integration
PDF
Geb for testing your grails application
Comprehensive Browser Automation Solution using Groovy, WebDriver & Obect Model
Agile NCR 2013 - Gaurav Bansal- web_automation
Stanislaw potoczny kra_qa_21.01.20
Taming Functional Web Testing with Spock and Geb
Geb presentation
QA Fest 2017. Ярослав Святкин. Тестовый фреймворк GEB для тестирования WEB пр...
A test framework out of the box - Geb for Web and mobile
Geb qa fest2017
Acceptance testing with Geb
Web driver selenium simplified
BDD, ATDD, Page Objects: The Road to Sustainable Web Testing
Web UI test automation instruments
Geb Best Practices
Browser-level testing
Geb: Save Time with Groovy Functional Testing
Selenium Tips & Tricks - StarWest 2015
Web UI Tests: Introduce UI tests using Selenium
Selenium Design Patterns And Best Practices Dima Kovalenko
Graceful Failure with Selenium and Continuous Integration
Geb for testing your grails application
Ad

Recently uploaded (20)

PDF
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
PPTX
Essential Infomation Tech presentation.pptx
PPTX
history of c programming in notes for students .pptx
PPTX
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
PDF
System and Network Administration Chapter 2
PDF
Odoo Companies in India – Driving Business Transformation.pdf
PDF
How Creative Agencies Leverage Project Management Software.pdf
PDF
Design an Analysis of Algorithms I-SECS-1021-03
PPTX
Transform Your Business with a Software ERP System
PPTX
ai tools demonstartion for schools and inter college
PPTX
Odoo POS Development Services by CandidRoot Solutions
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
PDF
Wondershare Filmora 15 Crack With Activation Key [2025
PDF
Digital Strategies for Manufacturing Companies
PDF
Adobe Premiere Pro 2025 (v24.5.0.057) Crack free
PDF
Adobe Illustrator 28.6 Crack My Vision of Vector Design
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 41
PDF
How to Migrate SBCGlobal Email to Yahoo Easily
PDF
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
PDF
Upgrade and Innovation Strategies for SAP ERP Customers
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
Essential Infomation Tech presentation.pptx
history of c programming in notes for students .pptx
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
System and Network Administration Chapter 2
Odoo Companies in India – Driving Business Transformation.pdf
How Creative Agencies Leverage Project Management Software.pdf
Design an Analysis of Algorithms I-SECS-1021-03
Transform Your Business with a Software ERP System
ai tools demonstartion for schools and inter college
Odoo POS Development Services by CandidRoot Solutions
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
Wondershare Filmora 15 Crack With Activation Key [2025
Digital Strategies for Manufacturing Companies
Adobe Premiere Pro 2025 (v24.5.0.057) Crack free
Adobe Illustrator 28.6 Crack My Vision of Vector Design
Internet Downloader Manager (IDM) Crack 6.42 Build 41
How to Migrate SBCGlobal Email to Yahoo Easily
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
Upgrade and Innovation Strategies for SAP ERP Customers

End-to-end testing with geb

  • 2. Blatant self-promotion Jesús L. Domínguez Muriel @jdmuriel Freelance, working at DIGIBÍS
  • 3. End to end testing - Chapter I: Why - Chapter II: A spooky story - Chapter III: Doing it with geb
  • 4. Chapter I- Why: Sometimes, software starts small...
  • 5. ... and then it grows
  • 6. Then, any small change can awake the beast
  • 7. Ways to handle a 15 year software beast - Flee - Rewrite - Refactor
  • 8. How to handle a 15 year software beast (I): Flee (No quiero mirar a nadie :-P )
  • 9. How to handle a 15 year software beast (II): Rewrite (Usually not an option)
  • 10. How to handle a 15 year software beast (III): Refactor - Refactor need tests - You usually have untestable code - Start testing at the lowest level possible - Unit - Integration - End-to-end - Add new code with good testing practices - References - https://www.youtube.com/watch?v=6W-EyIfUTmI
  • 11. End-to-end tests - Aka functional tests - Test the application as an end user would do it - Backend + frontend + everything in between - Good for - Acceptance criteria in user stories - Systems with many coordinated pieces - Testing untestable code
  • 12. End to end testing wisdom (I) “End to end tests are like cats” (they always do the same until they don’t)
  • 13. End to end testing wisdom (II) ““As anyone who has tried knows, maintaining a large suite of functional web tests for a changing application can become an expensive and frustrating process””
  • 14. Chapter II: a spooky story Our story starts with a library
  • 15. With the years, it somehow has grown in other thing
  • 16. Digibib - later Digiarch, Digihub, Digimus - 2003 - 2017 - 43 jars, 136 dependencies - Several hundred thousands lines of code - Our own framework -in 2003 there is not Spring - XML based :-( - Reimplementations - Code who nobody knows if it is used or not - Several generations of front-ends - Some time around 2012 we start thinking we need some tests
  • 17. First iteration: Selenium IDE for non technical users - Firefox extension - Records browser activity - Generates an script - Small IDE to edit the script - Script can be replayed - Can be automated with some effort - Usable by trained non technical users…?
  • 18. - Firefox extension - Records browser activity - Generates an script - Small IDE to edit the script - Script can be replayed - Can be automated with some effort - Usable by trained non technical users…? First iteration: Selenium IDE for non technical users
  • 19. Selenium IDE: not what we expected
  • 20. - Selecting the element to check not easy for non technical users (even if the tool allows selecting it in the browser) - By CSS - By XPath - Changes in a page require recapture of whole, long scripts - Firefox updates break the extension - Automation too brittle - Multi script test execution too slow - We never get end users to really use the IDE Selenium IDE: not what we expected
  • 21. Second iteration: exporting scripts to Java Advantages - News scripts can be created faster - Easier to integrate with jenkins - Easier to use other browsers - Improved speed using headless browser PhantomJS
  • 22. Second iteration: exporting scripts to Java Disadvantages
  • 23. “The key to not pulling your hair out when dealing with web tests” - @ldaley Tests call domain methods, no HTML becomes Access to the specific HTML and CSS only within that Page Objects If the HTML is changed, only the affected Page object must be changed Even Martin Fowler said it!!! (https://martinfowler.com/bliki/PageObject.html) Page object pattern
  • 24. So, we have work to do 3 or 4 most tested pages are already converted to Page objects Login Search form Many still to do: Results Configuration, Indexes, etc.
  • 25. Chapter III: Enters geb Developer focused tool Uses Groovy's dynamism to remove boilerplate, achieve pseudo English code Uses WebDriver (evolution of Selenium 2) - Cross browser Inspired by jQuery, robust Page Object modelling support Good documentation. The “Book of Geb” http://www.gebish.org/manual/current/ Luke Daley (Gradle, Ratpack), Marcin Erdmann (current)
  • 26. Why geb Concise Team already using Groovy with Spock for tests Standard, tested implementation of utilities we were implementing ad hoc: - Driver configuration - Timeout configuration - Screenshots - Integration You can give a talk!!!
  • 27. Why not geb Dependency madness (specially with Maven and eclipse) No autocomplete (on Eclipse) Oriented to Groovy developers
  • 28. Geb in 10 slides - Browser Browser.drive { go "http://gebish.org" assert title == "Geb - Very Groovy Browser Automation" $("div.menu a.manuals").click() waitFor { !$("#manuals-menu").hasClass("animating") } $("#manuals-menu a")[0].click() assert title.startsWith("The Book Of Geb") } Browser always have a current page and delegates methods and properties to it.
  • 29. Geb in 10 slides - Test adapter class GebishOrgTest extends GebSpec { @Test void “clicking first manual goes to book of geb”() { given: go "http://gebish.org" //Delegate to browser when: $("div.menu a.manuals").click() //Delegate to page waitFor { !$("#manuals-menu").hasClass("animating") } $("#manuals-menu a")[0].click() then: title.startsWith("The Book Of Geb") } } //Automatic screenshot reporting after every test
  • 30. Geb in 10 slides - $(), Navigator Inspired by jQuery: //$("<css selector>", index_or_range, <attribute/text matcher>) $("div>p", 0..2, class: "heading", text: iEndsWith("!")) == [“a!”, “b!”] $("p", text: ~/This./).size() == 2 $(By.id("some-id")) $(By.xpath('//p[@class="xpath"]')) //Navigators are iterable $("p").max { it.text() }.text() == "2" $("p")*.text().max() == "2" //Methods for filtering, element traversal $("div").filter(".a").not(".c").has("p", text: "Found!").hasNot("br") $("div").find("p").parent().next().children("a", href: contains("www")) //nextAll(), previous(), siblings(), parents(), closest(), //nextUntil(), prevUntil(), parentsUntil()
  • 31. Geb in 10 slides - $(), Navigator //Composition $( $("p.a"), $("p.b") ) //Methods $("a.login").click() $("input") << "test" << Keys.chord(Keys.CONTROL, "c") //Properties displayed, focused //single element needed height, width, x, y text(), tag(), classes(), @attribute //CSS Properties css("<css property>")
  • 32. Geb in 10 slides - Page objects class GebHomePage extends Page { static url = "http://gebish.org" static at = { title.contains "Groovy" } static content = { toggle { $("div.menu a.manuals") } linksContainer { $("#manuals-menu") } links { linksContainer.find("a") } //stacked content } } class TheBookOfGebPage extends Page { //url is optional static at = { title.startsWith("The Book Of Geb") } } void “clicking first manual goes to book of geb”() { given: to GebHomePage //checks at when: toggle.click() waitFor { !linksContainer.hasClass("animating") } links[0].click() then: at TheBookOfGebPage }
  • 33. Geb in 10 slides - Module class GebHomePage extends Page { static url = "http://gebish.org" static at = { title.contains "Groovy" } static content = { manualsMenu { module(ManualsMenuModule)} } } class ManualsMenuModule extends Module { static content = { toggle { $("div.menu a.manuals") } linksContainer { $("#manuals-menu") } links { linksContainer.find("a") } } void open() { toggle.click() waitFor { !linksContainer.hasClass ("animating") } } } void “clicking first manual goes to book of geb”() { given: to GebHomePage //checks at when: manualsMenu.open() manualsMenu.links[0].click() then: at TheBookOfGebPage }
  • 34. Geb in 10 slides - Content DSL, moduleList() static content = { «name»(«options map») { «definition» } theDiv(required: false) { $("div", id: "a") } theDiv(min: 1, max: 2) { $("div", id: "a") } theDiv(cache: false) { $("div", id: "a") } helpLink(to: HelpPage) { $("a", text: "Help") } //helpLink.click() sets browser page loginButton(to: [LoginSuccessfulPage, LoginFailedPage]) { $("input.loginButton") } dynamicallyAdded(wait: true) { $("p.dynamic") } someDiv { $("div#aliased") } aliasedDiv(aliases: "someDiv") firstCartItem { $("table tr", 0) module (CartRow)} cartItems { $("table tr").tail().moduleList(CartRow) } assert cartItems.every { it.price > 0.0 }
  • 35. Geb in 10 slides - Interact API, javascript interface interact { clickAndHold($('#draggable')) moveByOffset(150, 200) release() } //All WebDriver Actions <html> <head> <script type="text/javascript"> var aVariable = 1; </script> </head> </html> assert Browser.js.aVariable == 1 $("div#a").jquery.mouseover()
  • 36. Geb in 10 slides - Configuration GebConfig.groovy or GebConfig class in classpath driver = “firefox” //driver = { new FirefoxDriver() } environments { prod { driver = chrome } } waiting { timeout = 10 retryInterval = 0.5 presets { slow { Timeout = 20 } } } retorsDir = “target/geb-reports”
  • 37. Geb in 10 slides - Download API Browser.drive { to LoginPage login("me", "secret") def pdfBytes = downloadBytes(pdfLink.@href) } //downloadStream, downloadText, downloadContent Browser.drive { go "/" def jsonBytes = downloadBytes { HttpURLConnection connection -> connection.setRequestProperty("Accept", "application/json") } }
  • 38. Geb in 10 slides - windows & frames <a href="http://www.gebish.org" target="myWindow">Geb</a> Browser.drive { go() $("a").click() withWindow("myWindow", close: true) { assert title == "Geb - Very Groovy Browser Automation" } withWindow({ title == "Geb - Very Groovy Browser Automation" }) { assert $(".slogan").text().startsWith("Very Groovy browser automation.") } } //withNewWindow(), withFrame(), withNewFrame()
  • 39. Closures everywhere! Contents, modules, waitFor, browser, interact Rewritten AST “a la Spock”, so that every expression is turned in an assert (in ats, waits) Wrapped classes - all page, browser available in test specs MethodMissing, PropertyMissing Geb’s black magic
  • 40. Summary If you have a big application, use end-to-end tests If you use Groovy, use Geb Don’t walk alone in a misty forest...