SlideShare a Scribd company logo

Better Selenium Tests with Geb - Selenium Conf 2014

Naresha K
Naresha K

This document discusses using Geb to write more concise and maintainable Selenium tests. It introduces Geb's browser abstraction and navigator API for selecting page elements, as well as its support for page object modeling through modules. Integration with Spock is demonstrated for writing stepwise, specification-style tests that leverage Geb's power and Groovy syntax. In summary, Geb combines the capabilities of WebDriver, jQuery-like selection, page object modeling, and an expressive Groovy API to enable robust yet elegant Selenium tests.

1 of 42
Download to read offline
Better Selenium Tests with 
Geb 
Naresha K 
Enteleki Solutions 
naresha.k@gmail.com 
@naresha_k
http://martinfowler.com/bliki/PageObject.html 
WebDriver 
ChromeDriver FirefoxDriver InternetExplorerDriver
WebDriver 
WebDriverJS 
Selenium server 
ChromeDriver FirefoxDriver InternetExplorerDriver
Level of Abstraction 
https://www.flickr.com/photos/pagedooley/3028798210
WebDriver 
WebDriverJS 
Selenium server 
ChromeDriver FirefoxDriver InternetExplorerDriver
Any problem in 
computer science can 
be solved with another 
layer of indirection 
David Wheeler 
https://www.flickr.com/photos/pc_plod/14187378533
Better Selenium Tests with Geb - Selenium Conf 2014
Web Driver
Geb
Browser 
import geb.Browser! 
import org.openqa.selenium.firefox.FirefoxDriver! 
! 
Browser browser = new Browser(driver: new FirefoxDriver())!
Browser 
import geb.Browser! 
import org.openqa.selenium.firefox.FirefoxDriver! 
! 
Browser browser = new Browser(driver: new FirefoxDriver())! 
// driver.get("http://seleniumconf.org/")! 
browser.go 'http://seleniumconf.org/'!
External Config 
// GebConfig.groovy! 
import org.openqa.selenium.firefox.FirefoxDriver! 
! 
driver = { ! 
! def driverInstance = new FirefoxDriver() ! 
! driverInstance.manage().window().maximize() ! 
! driverInstance ! 
} ! 
Browser browser = new Browser()! 
! 
// driver.get("http://seleniumconf.org/")! 
browser.go 'http://seleniumconf.org/'! 
browser.quit()!
Accessing Elements 
// driver.findElement(By.name("j_username")) ! 
def username = browser.$(name: 'j_username')! 
// username.sendKeys("user1")! 
username << 'user1'! 
println username.value()!
Geb Browser
Hello Geb 
Browser browser = new Browser()! 
browser.go “http://localhost:8000/app/login.html"! 
browser.$(name: 'j_username') << 'user1'! 
browser.$(name: 'j_password') << 'secret'! 
browser.$('#submit').click()! 
browser.quit()!
Hello Geb - Improved 
Browser.drive{! 
! go “http://localhost:8000/app/login.html"! 
! $(name: 'j_username') << 'user1'! 
! $(name: 'j_password') << 'secret'! 
! $('#submit').click()! 
}.quit()!
Configurable URL 
// GebConfig.groovy! 
baseUrl = "http://localhost:8000/app/" ! 
Browser.drive{! 
! go “login.html”! 
! $(name: 'j_username') << 'user1'! 
! $(name: 'j_password') << 'secret'! 
! $('#submit').click()! 
}.quit()!
Assertion 
assert $('h1').text() == 'Dashboard'!
Navigator API
Navigator Syntax 
$(<css selector>, <index or range>, <attribute / text matchers>)
<h2>Introduction</h2>! 
<h2>Navigator</h2>! 
<h2>Page Objects</h2>! 
<h2>Summary</h2>! 
$('h2').text() == 'Introduction'! 
$('h2', 1).text() == 'Navigator'! 
$('h2').size() == 4!
<h2>Introduction</h2>! 
<h2>Navigator</h2>! 
<h2>Page Objects</h2>! 
<h2>Summary</h2>! 
$('h2', 0..2)*.text() == ! 
! ! ['Introduction', 'Navigator', 'Page Objects']!
<h2 duration="5">Introduction</h2>! 
<h2 duration="15">Navigator</h2>! 
<h2>Page Objects</h2>! 
<h2 duration="5">Summary</h2>! 
$('h2', duration: '5').size() == 2! 
$('h2', text: 'Summary').size() == 1!
<h2 duration="5">Introduction</h2>! 
<h2 duration="15">Navigator</h2>! 
<h2>Page Objects</h2>! 
<h2 duration="5">Summary</h2>! 
$('h2', text: contains('o')).size() == 2! 
$('h2', text: iContains('o')).size() == 3! 
$('h2', duration: contains('5')).size() == 3!
<div class="languages">! 
! ! <div class="language jvm">Java</div>! 
! ! <div class="language clr">C#</div>! 
! ! <div class="language jvm">Groovy</div>! 
! ! <div class="language clr">F#</div>! 
! ! <div class="language erlang">Elixir</div>! 
</div> 
$('div.languages').find('.jvm').each{ element ->! 
! ! println element.text()! 
} 
Java 
Groovy
<div class="languages">! 
! ! <div class="language jvm">Java</div>! 
! ! <div class="language clr">C#</div>! 
! ! <div class="language jvm">Groovy</div>! 
! ! <div class="language clr">F#</div>! 
! ! <div class="language erlang">Elixir</div>! 
</div> 
$('.language').filter('.jvm').each{ element ->! 
! ! println element.text()! 
} 
Java 
Groovy 
$('.language').not('.clr').each{ element ->! 
! ! println element.text()! 
} 
Java 
Groovy 
Elixir
Page Objects
Page Objects
Modules
Modules
Better Selenium Tests with Geb - Selenium Conf 2014
Modules 
class Record extends Module{! 
! static content = {! 
! ! column {index -> $('td', index)}! 
! ! productCode {column(1).text()}! 
! ! price { column(2).text().toInteger()}! 
! }! 
} 
class ProductPage extends Page{! 
! static url = 'table.html'! 
! static content = {! 
! ! products {moduleList Record, $('table tbody tr')}! 
! }! 
}
Modules 
Browser.drive() {! 
! to ProductPage! 
! products.each{ product ->! 
! ! println "${product.productCode} -> ${product.price}"! 
! }! 
}.quit()
Modules List
Waiting
Wait 
<div id="dynamic"></div> 
waitFor { $('#dynamic').text()}! 
waitFor(8) { $('#dynamic').text()}! 
waitFor(8, 0.5) { $('#dynamic').text()}! 
waitFor('slow') { $('#dynamic').text()} 
// GebConfig.groovy! 
waiting {! 
presets {! 
slow {! 
timeout = 12! 
retryInterval = 1! 
}! 
}! 
}
Integration 
https://www.flickr.com/photos/lumaxart/2137737248
Supported Frameworks
@Stepwise! 
class SampleGebSpec extends GebReportingSpec{! 
! 
def "User can login"(){! 
!! when:! 
!! ! to LoginPage! 
! ! ! login('user1', 'secret')! 
! 
! then:! 
! ! ! at DashboardPage! 
! ! ! and:! 
! ! ! header.pageTitle == 'Dashboard'! 
}! 
! 
}! 
Spock Example
Integration
Summary 
• Power of WebDriver 
• Elegance of jQuery selection 
• Robustness of Page Object 
modeling 
• Expressiveness of Groovy 
Welcome Geb
References 
Official Geb Page - http://www.gebish.org/ 
! 
Example - https://github.com/geb/geb-example-gradle 
! 
Spock Documentation - http://spock-framework. 
readthedocs.org/en/latest/ 
! 
Code samples - https://github.com/naresha/seconf2014

Recommended

Pragmatic Browser Automation with Geb - GIDS 2015
Pragmatic Browser Automation with Geb - GIDS 2015Pragmatic Browser Automation with Geb - GIDS 2015
Pragmatic Browser Automation with Geb - GIDS 2015Naresha K
 
Introduction to jQuery
Introduction to jQueryIntroduction to jQuery
Introduction to jQuerymanugoel2003
 
Introduction to jQuery
Introduction to jQueryIntroduction to jQuery
Introduction to jQueryGunjan Kumar
 
Drupal Best Practices
Drupal Best PracticesDrupal Best Practices
Drupal Best Practicesmanugoel2003
 
jQuery from the very beginning
jQuery from the very beginningjQuery from the very beginning
jQuery from the very beginningAnis Ahmad
 
jQuery Loves Developers - Oredev 2009
jQuery Loves Developers - Oredev 2009jQuery Loves Developers - Oredev 2009
jQuery Loves Developers - Oredev 2009Remy Sharp
 

More Related Content

What's hot

What's hot (20)

Learning jQuery in 30 minutes
Learning jQuery in 30 minutesLearning jQuery in 30 minutes
Learning jQuery in 30 minutes
 
jQuery
jQueryjQuery
jQuery
 
Prototype & jQuery
Prototype & jQueryPrototype & jQuery
Prototype & jQuery
 
jQuery Essentials
jQuery EssentialsjQuery Essentials
jQuery Essentials
 
Javascript first-class citizenery
Javascript first-class citizeneryJavascript first-class citizenery
Javascript first-class citizenery
 
jQuery Essentials
jQuery EssentialsjQuery Essentials
jQuery Essentials
 
Jquery
JqueryJquery
Jquery
 
jQuery
jQueryjQuery
jQuery
 
Sprout core and performance
Sprout core and performanceSprout core and performance
Sprout core and performance
 
jQuery PPT
jQuery PPTjQuery PPT
jQuery PPT
 
jQuery Fundamentals
jQuery FundamentalsjQuery Fundamentals
jQuery Fundamentals
 
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2KZepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
 
jQuery Presentation
jQuery PresentationjQuery Presentation
jQuery Presentation
 
A Short Introduction To jQuery
A Short Introduction To jQueryA Short Introduction To jQuery
A Short Introduction To jQuery
 
End-to-end testing with geb
End-to-end testing with gebEnd-to-end testing with geb
End-to-end testing with geb
 
Html5 For Jjugccc2009fall
Html5 For Jjugccc2009fallHtml5 For Jjugccc2009fall
Html5 For Jjugccc2009fall
 
jQuery
jQueryjQuery
jQuery
 
jQuery for beginners
jQuery for beginnersjQuery for beginners
jQuery for beginners
 
JavaScript and jQuery Basics
JavaScript and jQuery BasicsJavaScript and jQuery Basics
JavaScript and jQuery Basics
 
前端概述
前端概述前端概述
前端概述
 

Viewers also liked

Cloud browser testing with Gradle and Geb
Cloud browser testing with Gradle and GebCloud browser testing with Gradle and Geb
Cloud browser testing with Gradle and GebDavid Carr
 
Design Patterns from 10K feet
Design Patterns from 10K feetDesign Patterns from 10K feet
Design Patterns from 10K feetNaresha K
 
Java beyond Java - from the language to platform
Java beyond Java - from the language to platformJava beyond Java - from the language to platform
Java beyond Java - from the language to platformNaresha K
 

Viewers also liked (6)

Cloud browser testing with Gradle and Geb
Cloud browser testing with Gradle and GebCloud browser testing with Gradle and Geb
Cloud browser testing with Gradle and Geb
 
Design Patterns from 10K feet
Design Patterns from 10K feetDesign Patterns from 10K feet
Design Patterns from 10K feet
 
Java beyond Java - from the language to platform
Java beyond Java - from the language to platformJava beyond Java - from the language to platform
Java beyond Java - from the language to platform
 
Geb presentation
Geb presentationGeb presentation
Geb presentation
 
What makes Geb groovy?
What makes Geb groovy?What makes Geb groovy?
What makes Geb groovy?
 
Geb with spock
Geb with spockGeb with spock
Geb with spock
 

Similar to Better Selenium Tests with Geb - Selenium Conf 2014

What you need to know bout html5
What you need to know bout html5What you need to know bout html5
What you need to know bout html5Kevin DeRudder
 
Creating GUI container components in Angular and Web Components
Creating GUI container components in Angular and Web ComponentsCreating GUI container components in Angular and Web Components
Creating GUI container components in Angular and Web ComponentsRachael L Moore
 
J query b_dotnet_ug_meet_12_may_2012
J query b_dotnet_ug_meet_12_may_2012J query b_dotnet_ug_meet_12_may_2012
J query b_dotnet_ug_meet_12_may_2012ghnash
 
HTML5 New and Improved
HTML5   New and ImprovedHTML5   New and Improved
HTML5 New and ImprovedTimothy Fisher
 
Building iPhone Web Apps using "classic" Domino
Building iPhone Web Apps using "classic" DominoBuilding iPhone Web Apps using "classic" Domino
Building iPhone Web Apps using "classic" DominoRob Bontekoe
 
Resource Registries: Plone Conference 2014
Resource Registries: Plone Conference 2014Resource Registries: Plone Conference 2014
Resource Registries: Plone Conference 2014Rob Gietema
 
Practical HTML5: Using It Today
Practical HTML5: Using It TodayPractical HTML5: Using It Today
Practical HTML5: Using It TodayDoris Chen
 
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)Doris Chen
 
Oracle Application Express & jQuery Mobile - OGh Apex Dag 2012
Oracle Application Express & jQuery Mobile - OGh Apex Dag 2012Oracle Application Express & jQuery Mobile - OGh Apex Dag 2012
Oracle Application Express & jQuery Mobile - OGh Apex Dag 2012crokitta
 
Enjoy the vue.js
Enjoy the vue.jsEnjoy the vue.js
Enjoy the vue.jsTechExeter
 

Similar to Better Selenium Tests with Geb - Selenium Conf 2014 (20)

jQuery basics
jQuery basicsjQuery basics
jQuery basics
 
What you need to know bout html5
What you need to know bout html5What you need to know bout html5
What you need to know bout html5
 
Creating GUI container components in Angular and Web Components
Creating GUI container components in Angular and Web ComponentsCreating GUI container components in Angular and Web Components
Creating GUI container components in Angular and Web Components
 
J query b_dotnet_ug_meet_12_may_2012
J query b_dotnet_ug_meet_12_may_2012J query b_dotnet_ug_meet_12_may_2012
J query b_dotnet_ug_meet_12_may_2012
 
HTML5 New and Improved
HTML5   New and ImprovedHTML5   New and Improved
HTML5 New and Improved
 
HTML5 Essentials
HTML5 EssentialsHTML5 Essentials
HTML5 Essentials
 
Html5 intro
Html5 introHtml5 intro
Html5 intro
 
Play!ng with scala
Play!ng with scalaPlay!ng with scala
Play!ng with scala
 
Building iPhone Web Apps using "classic" Domino
Building iPhone Web Apps using "classic" DominoBuilding iPhone Web Apps using "classic" Domino
Building iPhone Web Apps using "classic" Domino
 
Html5
Html5Html5
Html5
 
HTML5
HTML5HTML5
HTML5
 
jQuery Basic API
jQuery Basic APIjQuery Basic API
jQuery Basic API
 
Resource Registries: Plone Conference 2014
Resource Registries: Plone Conference 2014Resource Registries: Plone Conference 2014
Resource Registries: Plone Conference 2014
 
J query training
J query trainingJ query training
J query training
 
Practical HTML5: Using It Today
Practical HTML5: Using It TodayPractical HTML5: Using It Today
Practical HTML5: Using It Today
 
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
 
HTML5, the new buzzword
HTML5, the new buzzwordHTML5, the new buzzword
HTML5, the new buzzword
 
Oracle Application Express & jQuery Mobile - OGh Apex Dag 2012
Oracle Application Express & jQuery Mobile - OGh Apex Dag 2012Oracle Application Express & jQuery Mobile - OGh Apex Dag 2012
Oracle Application Express & jQuery Mobile - OGh Apex Dag 2012
 
jQuery, CSS3 and ColdFusion
jQuery, CSS3 and ColdFusionjQuery, CSS3 and ColdFusion
jQuery, CSS3 and ColdFusion
 
Enjoy the vue.js
Enjoy the vue.jsEnjoy the vue.js
Enjoy the vue.js
 

More from Naresha K

The Groovy Way of Testing with Spock
The Groovy Way of Testing with SpockThe Groovy Way of Testing with Spock
The Groovy Way of Testing with SpockNaresha K
 
Evolving with Java - How to Remain Effective
Evolving with Java - How to Remain EffectiveEvolving with Java - How to Remain Effective
Evolving with Java - How to Remain EffectiveNaresha K
 
Take Control of your Integration Testing with TestContainers
Take Control of your Integration Testing with TestContainersTake Control of your Integration Testing with TestContainers
Take Control of your Integration Testing with TestContainersNaresha K
 
Implementing Resilience with Micronaut
Implementing Resilience with MicronautImplementing Resilience with Micronaut
Implementing Resilience with MicronautNaresha K
 
Take Control of your Integration Testing with TestContainers
Take Control of your Integration Testing with TestContainersTake Control of your Integration Testing with TestContainers
Take Control of your Integration Testing with TestContainersNaresha K
 
Favouring Composition - The Groovy Way
Favouring Composition - The Groovy WayFavouring Composition - The Groovy Way
Favouring Composition - The Groovy WayNaresha K
 
Effective Java with Groovy - How Language Influences Adoption of Good Practices
Effective Java with Groovy - How Language Influences Adoption of Good PracticesEffective Java with Groovy - How Language Influences Adoption of Good Practices
Effective Java with Groovy - How Language Influences Adoption of Good PracticesNaresha K
 
What's in Groovy for Functional Programming
What's in Groovy for Functional ProgrammingWhat's in Groovy for Functional Programming
What's in Groovy for Functional ProgrammingNaresha K
 
Effective Java with Groovy & Kotlin - How Languages Influence Adoption of Goo...
Effective Java with Groovy & Kotlin - How Languages Influence Adoption of Goo...Effective Java with Groovy & Kotlin - How Languages Influence Adoption of Goo...
Effective Java with Groovy & Kotlin - How Languages Influence Adoption of Goo...Naresha K
 
Effective Java with Groovy & Kotlin How Languages Influence Adoption of Good ...
Effective Java with Groovy & Kotlin How Languages Influence Adoption of Good ...Effective Java with Groovy & Kotlin How Languages Influence Adoption of Good ...
Effective Java with Groovy & Kotlin How Languages Influence Adoption of Good ...Naresha K
 
Eclipse Collections, Java Streams & Vavr - What's in them for Functional Pro...
Eclipse Collections, Java Streams & Vavr - What's in them for  Functional Pro...Eclipse Collections, Java Streams & Vavr - What's in them for  Functional Pro...
Eclipse Collections, Java Streams & Vavr - What's in them for Functional Pro...Naresha K
 
Implementing Cloud-Native Architectural Patterns with Micronaut
Implementing Cloud-Native Architectural Patterns with MicronautImplementing Cloud-Native Architectural Patterns with Micronaut
Implementing Cloud-Native Architectural Patterns with MicronautNaresha K
 
Groovy - Why and Where?
Groovy  - Why and Where?Groovy  - Why and Where?
Groovy - Why and Where?Naresha K
 
Leveraging Micronaut on AWS Lambda
Leveraging Micronaut on AWS LambdaLeveraging Micronaut on AWS Lambda
Leveraging Micronaut on AWS LambdaNaresha K
 
Groovy Refactoring Patterns
Groovy Refactoring PatternsGroovy Refactoring Patterns
Groovy Refactoring PatternsNaresha K
 
Implementing Cloud-native Architectural Patterns with Micronaut
Implementing Cloud-native Architectural Patterns with MicronautImplementing Cloud-native Architectural Patterns with Micronaut
Implementing Cloud-native Architectural Patterns with MicronautNaresha K
 
Effective Java with Groovy
Effective Java with GroovyEffective Java with Groovy
Effective Java with GroovyNaresha K
 
Evolving with Java - How to remain Relevant and Effective
Evolving with Java - How to remain Relevant and EffectiveEvolving with Java - How to remain Relevant and Effective
Evolving with Java - How to remain Relevant and EffectiveNaresha K
 
Effective Java with Groovy - How Language can Influence Good Practices
Effective Java with Groovy - How Language can Influence Good PracticesEffective Java with Groovy - How Language can Influence Good Practices
Effective Java with Groovy - How Language can Influence Good PracticesNaresha K
 
Beyond Lambdas & Streams - Functional Fluency in Java
Beyond Lambdas & Streams - Functional Fluency in JavaBeyond Lambdas & Streams - Functional Fluency in Java
Beyond Lambdas & Streams - Functional Fluency in JavaNaresha K
 

More from Naresha K (20)

The Groovy Way of Testing with Spock
The Groovy Way of Testing with SpockThe Groovy Way of Testing with Spock
The Groovy Way of Testing with Spock
 
Evolving with Java - How to Remain Effective
Evolving with Java - How to Remain EffectiveEvolving with Java - How to Remain Effective
Evolving with Java - How to Remain Effective
 
Take Control of your Integration Testing with TestContainers
Take Control of your Integration Testing with TestContainersTake Control of your Integration Testing with TestContainers
Take Control of your Integration Testing with TestContainers
 
Implementing Resilience with Micronaut
Implementing Resilience with MicronautImplementing Resilience with Micronaut
Implementing Resilience with Micronaut
 
Take Control of your Integration Testing with TestContainers
Take Control of your Integration Testing with TestContainersTake Control of your Integration Testing with TestContainers
Take Control of your Integration Testing with TestContainers
 
Favouring Composition - The Groovy Way
Favouring Composition - The Groovy WayFavouring Composition - The Groovy Way
Favouring Composition - The Groovy Way
 
Effective Java with Groovy - How Language Influences Adoption of Good Practices
Effective Java with Groovy - How Language Influences Adoption of Good PracticesEffective Java with Groovy - How Language Influences Adoption of Good Practices
Effective Java with Groovy - How Language Influences Adoption of Good Practices
 
What's in Groovy for Functional Programming
What's in Groovy for Functional ProgrammingWhat's in Groovy for Functional Programming
What's in Groovy for Functional Programming
 
Effective Java with Groovy & Kotlin - How Languages Influence Adoption of Goo...
Effective Java with Groovy & Kotlin - How Languages Influence Adoption of Goo...Effective Java with Groovy & Kotlin - How Languages Influence Adoption of Goo...
Effective Java with Groovy & Kotlin - How Languages Influence Adoption of Goo...
 
Effective Java with Groovy & Kotlin How Languages Influence Adoption of Good ...
Effective Java with Groovy & Kotlin How Languages Influence Adoption of Good ...Effective Java with Groovy & Kotlin How Languages Influence Adoption of Good ...
Effective Java with Groovy & Kotlin How Languages Influence Adoption of Good ...
 
Eclipse Collections, Java Streams & Vavr - What's in them for Functional Pro...
Eclipse Collections, Java Streams & Vavr - What's in them for  Functional Pro...Eclipse Collections, Java Streams & Vavr - What's in them for  Functional Pro...
Eclipse Collections, Java Streams & Vavr - What's in them for Functional Pro...
 
Implementing Cloud-Native Architectural Patterns with Micronaut
Implementing Cloud-Native Architectural Patterns with MicronautImplementing Cloud-Native Architectural Patterns with Micronaut
Implementing Cloud-Native Architectural Patterns with Micronaut
 
Groovy - Why and Where?
Groovy  - Why and Where?Groovy  - Why and Where?
Groovy - Why and Where?
 
Leveraging Micronaut on AWS Lambda
Leveraging Micronaut on AWS LambdaLeveraging Micronaut on AWS Lambda
Leveraging Micronaut on AWS Lambda
 
Groovy Refactoring Patterns
Groovy Refactoring PatternsGroovy Refactoring Patterns
Groovy Refactoring Patterns
 
Implementing Cloud-native Architectural Patterns with Micronaut
Implementing Cloud-native Architectural Patterns with MicronautImplementing Cloud-native Architectural Patterns with Micronaut
Implementing Cloud-native Architectural Patterns with Micronaut
 
Effective Java with Groovy
Effective Java with GroovyEffective Java with Groovy
Effective Java with Groovy
 
Evolving with Java - How to remain Relevant and Effective
Evolving with Java - How to remain Relevant and EffectiveEvolving with Java - How to remain Relevant and Effective
Evolving with Java - How to remain Relevant and Effective
 
Effective Java with Groovy - How Language can Influence Good Practices
Effective Java with Groovy - How Language can Influence Good PracticesEffective Java with Groovy - How Language can Influence Good Practices
Effective Java with Groovy - How Language can Influence Good Practices
 
Beyond Lambdas & Streams - Functional Fluency in Java
Beyond Lambdas & Streams - Functional Fluency in JavaBeyond Lambdas & Streams - Functional Fluency in Java
Beyond Lambdas & Streams - Functional Fluency in Java
 

Recently uploaded

Reliable, Remote Computation at All Scales
Reliable, Remote Computation at All ScalesReliable, Remote Computation at All Scales
Reliable, Remote Computation at All ScalesGlobus
 
From Software Development To Branding through Digital Marketing, IT Services
From Software Development To Branding through Digital Marketing, IT ServicesFrom Software Development To Branding through Digital Marketing, IT Services
From Software Development To Branding through Digital Marketing, IT ServicesAnisha Agarwal
 
Agile & Scrum, Certified Scrum Master! Crash Course
Agile & Scrum,  Certified Scrum Master! Crash CourseAgile & Scrum,  Certified Scrum Master! Crash Course
Agile & Scrum, Certified Scrum Master! Crash CourseRohan Chandane
 
Cybersecurity Measures For Remote Workers.pdf
Cybersecurity Measures For Remote Workers.pdfCybersecurity Measures For Remote Workers.pdf
Cybersecurity Measures For Remote Workers.pdfCIOWomenMagazine
 
Orion Context Broker introduction 20240227
Orion Context Broker introduction 20240227Orion Context Broker introduction 20240227
Orion Context Broker introduction 20240227Fermin Galan
 
How AI is preventing account fraud at web scale
How AI is preventing account fraud at web scaleHow AI is preventing account fraud at web scale
How AI is preventing account fraud at web scaleAmir Moghimi
 
An Introduction to Globus for Researchers
An Introduction to Globus for ResearchersAn Introduction to Globus for Researchers
An Introduction to Globus for ResearchersGlobus
 
Managing multicast/igmp stream on Docker
Managing multicast/igmp stream on DockerManaging multicast/igmp stream on Docker
Managing multicast/igmp stream on DockerThierry Gayet
 
Role of DevOps in SaaS product Development.pdf.pptx
Role of DevOps in SaaS product Development.pdf.pptxRole of DevOps in SaaS product Development.pdf.pptx
Role of DevOps in SaaS product Development.pdf.pptxMindInventory
 
Globus for System Administrators
Globus for System AdministratorsGlobus for System Administrators
Globus for System AdministratorsGlobus
 
CSS Notes in PDF, Easy to understand. For beginner to advanced. ...
CSS Notes in PDF, Easy to understand. For beginner to advanced.              ...CSS Notes in PDF, Easy to understand. For beginner to advanced.              ...
CSS Notes in PDF, Easy to understand. For beginner to advanced. ...syedfaisal759877
 
Instrument Data Automation: The Life of a Flow
Instrument Data Automation: The Life of a FlowInstrument Data Automation: The Life of a Flow
Instrument Data Automation: The Life of a FlowGlobus
 
Passbolt Introduction and Usage for secret managment
Passbolt Introduction and Usage for secret managmentPassbolt Introduction and Usage for secret managment
Passbolt Introduction and Usage for secret managmentThierry Gayet
 
انتزاع و هزینه - انتزاع و تاثیرات آن در توسعه و نگهداری نرم‌افزار
انتزاع و هزینه - انتزاع و تاثیرات آن در توسعه و نگهداری نرم‌افزارانتزاع و هزینه - انتزاع و تاثیرات آن در توسعه و نگهداری نرم‌افزار
انتزاع و هزینه - انتزاع و تاثیرات آن در توسعه و نگهداری نرم‌افزارsohilww
 
Workshop híbrido: Stream Processing con Flink
Workshop híbrido: Stream Processing con FlinkWorkshop híbrido: Stream Processing con Flink
Workshop híbrido: Stream Processing con Flinkconfluent
 
Alluxio Monthly Webinar | Why a Multi-Cloud Strategy Matters for Your AI Plat...
Alluxio Monthly Webinar | Why a Multi-Cloud Strategy Matters for Your AI Plat...Alluxio Monthly Webinar | Why a Multi-Cloud Strategy Matters for Your AI Plat...
Alluxio Monthly Webinar | Why a Multi-Cloud Strategy Matters for Your AI Plat...Alluxio, Inc.
 
LLMOps with Azure Machine Learning prompt flow
LLMOps with Azure Machine Learning prompt flowLLMOps with Azure Machine Learning prompt flow
LLMOps with Azure Machine Learning prompt flowNaoki (Neo) SATO
 
Open Source vs Closed Source LLMs. Pros and Cons
Open Source vs Closed Source LLMs. Pros and ConsOpen Source vs Closed Source LLMs. Pros and Cons
Open Source vs Closed Source LLMs. Pros and ConsSprings
 
killing camp 주차장 나누기-2 topology sort.pdf
killing camp 주차장 나누기-2 topology sort.pdfkilling camp 주차장 나누기-2 topology sort.pdf
killing camp 주차장 나누기-2 topology sort.pdfssuser82c38d
 

Recently uploaded (20)

Reliable, Remote Computation at All Scales
Reliable, Remote Computation at All ScalesReliable, Remote Computation at All Scales
Reliable, Remote Computation at All Scales
 
From Software Development To Branding through Digital Marketing, IT Services
From Software Development To Branding through Digital Marketing, IT ServicesFrom Software Development To Branding through Digital Marketing, IT Services
From Software Development To Branding through Digital Marketing, IT Services
 
Agile & Scrum, Certified Scrum Master! Crash Course
Agile & Scrum,  Certified Scrum Master! Crash CourseAgile & Scrum,  Certified Scrum Master! Crash Course
Agile & Scrum, Certified Scrum Master! Crash Course
 
Cybersecurity Measures For Remote Workers.pdf
Cybersecurity Measures For Remote Workers.pdfCybersecurity Measures For Remote Workers.pdf
Cybersecurity Measures For Remote Workers.pdf
 
Orion Context Broker introduction 20240227
Orion Context Broker introduction 20240227Orion Context Broker introduction 20240227
Orion Context Broker introduction 20240227
 
How AI is preventing account fraud at web scale
How AI is preventing account fraud at web scaleHow AI is preventing account fraud at web scale
How AI is preventing account fraud at web scale
 
An Introduction to Globus for Researchers
An Introduction to Globus for ResearchersAn Introduction to Globus for Researchers
An Introduction to Globus for Researchers
 
Managing multicast/igmp stream on Docker
Managing multicast/igmp stream on DockerManaging multicast/igmp stream on Docker
Managing multicast/igmp stream on Docker
 
Role of DevOps in SaaS product Development.pdf.pptx
Role of DevOps in SaaS product Development.pdf.pptxRole of DevOps in SaaS product Development.pdf.pptx
Role of DevOps in SaaS product Development.pdf.pptx
 
Globus for System Administrators
Globus for System AdministratorsGlobus for System Administrators
Globus for System Administrators
 
CSS Notes in PDF, Easy to understand. For beginner to advanced. ...
CSS Notes in PDF, Easy to understand. For beginner to advanced.              ...CSS Notes in PDF, Easy to understand. For beginner to advanced.              ...
CSS Notes in PDF, Easy to understand. For beginner to advanced. ...
 
Instrument Data Automation: The Life of a Flow
Instrument Data Automation: The Life of a FlowInstrument Data Automation: The Life of a Flow
Instrument Data Automation: The Life of a Flow
 
Passbolt Introduction and Usage for secret managment
Passbolt Introduction and Usage for secret managmentPassbolt Introduction and Usage for secret managment
Passbolt Introduction and Usage for secret managment
 
انتزاع و هزینه - انتزاع و تاثیرات آن در توسعه و نگهداری نرم‌افزار
انتزاع و هزینه - انتزاع و تاثیرات آن در توسعه و نگهداری نرم‌افزارانتزاع و هزینه - انتزاع و تاثیرات آن در توسعه و نگهداری نرم‌افزار
انتزاع و هزینه - انتزاع و تاثیرات آن در توسعه و نگهداری نرم‌افزار
 
Workshop híbrido: Stream Processing con Flink
Workshop híbrido: Stream Processing con FlinkWorkshop híbrido: Stream Processing con Flink
Workshop híbrido: Stream Processing con Flink
 
Alluxio Monthly Webinar | Why a Multi-Cloud Strategy Matters for Your AI Plat...
Alluxio Monthly Webinar | Why a Multi-Cloud Strategy Matters for Your AI Plat...Alluxio Monthly Webinar | Why a Multi-Cloud Strategy Matters for Your AI Plat...
Alluxio Monthly Webinar | Why a Multi-Cloud Strategy Matters for Your AI Plat...
 
LLMOps with Azure Machine Learning prompt flow
LLMOps with Azure Machine Learning prompt flowLLMOps with Azure Machine Learning prompt flow
LLMOps with Azure Machine Learning prompt flow
 
Open Source vs Closed Source LLMs. Pros and Cons
Open Source vs Closed Source LLMs. Pros and ConsOpen Source vs Closed Source LLMs. Pros and Cons
Open Source vs Closed Source LLMs. Pros and Cons
 
2024 Trends Transforming Enterprise Resource Planning
2024 Trends Transforming Enterprise Resource Planning2024 Trends Transforming Enterprise Resource Planning
2024 Trends Transforming Enterprise Resource Planning
 
killing camp 주차장 나누기-2 topology sort.pdf
killing camp 주차장 나누기-2 topology sort.pdfkilling camp 주차장 나누기-2 topology sort.pdf
killing camp 주차장 나누기-2 topology sort.pdf
 

Better Selenium Tests with Geb - Selenium Conf 2014

  • 1. Better Selenium Tests with Geb Naresha K Enteleki Solutions naresha.k@gmail.com @naresha_k
  • 3. WebDriver WebDriverJS Selenium server ChromeDriver FirefoxDriver InternetExplorerDriver
  • 4. Level of Abstraction https://www.flickr.com/photos/pagedooley/3028798210
  • 5. WebDriver WebDriverJS Selenium server ChromeDriver FirefoxDriver InternetExplorerDriver
  • 6. Any problem in computer science can be solved with another layer of indirection David Wheeler https://www.flickr.com/photos/pc_plod/14187378533
  • 9. Geb
  • 10. Browser import geb.Browser! import org.openqa.selenium.firefox.FirefoxDriver! ! Browser browser = new Browser(driver: new FirefoxDriver())!
  • 11. Browser import geb.Browser! import org.openqa.selenium.firefox.FirefoxDriver! ! Browser browser = new Browser(driver: new FirefoxDriver())! // driver.get("http://seleniumconf.org/")! browser.go 'http://seleniumconf.org/'!
  • 12. External Config // GebConfig.groovy! import org.openqa.selenium.firefox.FirefoxDriver! ! driver = { ! ! def driverInstance = new FirefoxDriver() ! ! driverInstance.manage().window().maximize() ! ! driverInstance ! } ! Browser browser = new Browser()! ! // driver.get("http://seleniumconf.org/")! browser.go 'http://seleniumconf.org/'! browser.quit()!
  • 13. Accessing Elements // driver.findElement(By.name("j_username")) ! def username = browser.$(name: 'j_username')! // username.sendKeys("user1")! username << 'user1'! println username.value()!
  • 15. Hello Geb Browser browser = new Browser()! browser.go “http://localhost:8000/app/login.html"! browser.$(name: 'j_username') << 'user1'! browser.$(name: 'j_password') << 'secret'! browser.$('#submit').click()! browser.quit()!
  • 16. Hello Geb - Improved Browser.drive{! ! go “http://localhost:8000/app/login.html"! ! $(name: 'j_username') << 'user1'! ! $(name: 'j_password') << 'secret'! ! $('#submit').click()! }.quit()!
  • 17. Configurable URL // GebConfig.groovy! baseUrl = "http://localhost:8000/app/" ! Browser.drive{! ! go “login.html”! ! $(name: 'j_username') << 'user1'! ! $(name: 'j_password') << 'secret'! ! $('#submit').click()! }.quit()!
  • 20. Navigator Syntax $(<css selector>, <index or range>, <attribute / text matchers>)
  • 21. <h2>Introduction</h2>! <h2>Navigator</h2>! <h2>Page Objects</h2>! <h2>Summary</h2>! $('h2').text() == 'Introduction'! $('h2', 1).text() == 'Navigator'! $('h2').size() == 4!
  • 22. <h2>Introduction</h2>! <h2>Navigator</h2>! <h2>Page Objects</h2>! <h2>Summary</h2>! $('h2', 0..2)*.text() == ! ! ! ['Introduction', 'Navigator', 'Page Objects']!
  • 23. <h2 duration="5">Introduction</h2>! <h2 duration="15">Navigator</h2>! <h2>Page Objects</h2>! <h2 duration="5">Summary</h2>! $('h2', duration: '5').size() == 2! $('h2', text: 'Summary').size() == 1!
  • 24. <h2 duration="5">Introduction</h2>! <h2 duration="15">Navigator</h2>! <h2>Page Objects</h2>! <h2 duration="5">Summary</h2>! $('h2', text: contains('o')).size() == 2! $('h2', text: iContains('o')).size() == 3! $('h2', duration: contains('5')).size() == 3!
  • 25. <div class="languages">! ! ! <div class="language jvm">Java</div>! ! ! <div class="language clr">C#</div>! ! ! <div class="language jvm">Groovy</div>! ! ! <div class="language clr">F#</div>! ! ! <div class="language erlang">Elixir</div>! </div> $('div.languages').find('.jvm').each{ element ->! ! ! println element.text()! } Java Groovy
  • 26. <div class="languages">! ! ! <div class="language jvm">Java</div>! ! ! <div class="language clr">C#</div>! ! ! <div class="language jvm">Groovy</div>! ! ! <div class="language clr">F#</div>! ! ! <div class="language erlang">Elixir</div>! </div> $('.language').filter('.jvm').each{ element ->! ! ! println element.text()! } Java Groovy $('.language').not('.clr').each{ element ->! ! ! println element.text()! } Java Groovy Elixir
  • 32. Modules class Record extends Module{! ! static content = {! ! ! column {index -> $('td', index)}! ! ! productCode {column(1).text()}! ! ! price { column(2).text().toInteger()}! ! }! } class ProductPage extends Page{! ! static url = 'table.html'! ! static content = {! ! ! products {moduleList Record, $('table tbody tr')}! ! }! }
  • 33. Modules Browser.drive() {! ! to ProductPage! ! products.each{ product ->! ! ! println "${product.productCode} -> ${product.price}"! ! }! }.quit()
  • 36. Wait <div id="dynamic"></div> waitFor { $('#dynamic').text()}! waitFor(8) { $('#dynamic').text()}! waitFor(8, 0.5) { $('#dynamic').text()}! waitFor('slow') { $('#dynamic').text()} // GebConfig.groovy! waiting {! presets {! slow {! timeout = 12! retryInterval = 1! }! }! }
  • 39. @Stepwise! class SampleGebSpec extends GebReportingSpec{! ! def "User can login"(){! !! when:! !! ! to LoginPage! ! ! ! login('user1', 'secret')! ! ! then:! ! ! ! at DashboardPage! ! ! ! and:! ! ! ! header.pageTitle == 'Dashboard'! }! ! }! Spock Example
  • 41. Summary • Power of WebDriver • Elegance of jQuery selection • Robustness of Page Object modeling • Expressiveness of Groovy Welcome Geb
  • 42. References Official Geb Page - http://www.gebish.org/ ! Example - https://github.com/geb/geb-example-gradle ! Spock Documentation - http://spock-framework. readthedocs.org/en/latest/ ! Code samples - https://github.com/naresha/seconf2014