SlideShare uma empresa Scribd logo
1 de 54
Baixar para ler offline
Geb Best Practices
Marcin Erdmann
@marcinerdmann
•  Groovy enthusiast since 2010
•  Geb user since 2011
•  Geb lead since 2014
•  Open source contributor
•  Testing junkie
1.0!!!
08.10.2016
50 Geb contributors
•  Robert Fletcher
•  Peter Niederwieser
•  Alexander Zolotov
•  Christoph Neuroth
•  Antony Jones
•  Jan-Hendrik Peters
•  Tomás Lin
•  Jason Cahoon
•  Tomasz Kalkosiński
•  Rich Douglas Evans
•  Ian Durkan
•  Colin Harrington
•  Bob Herrmann
•  George T Walters II
•  Craig Atkinson
•  Andy Duncan
•  John Engelman
•  Michael Legart
•  Graeme Rocher
•  Craig Atkinson
•  Ken Geis
•  Chris Prior
•  Kelly Robinson
•  Todd Gerspacher
•  David M. Carr
•  Tom Dunstan
•  Brian Kotek
•  David W Millar
•  Ai-Lin Liou
•  Varun Menon
•  Anders D. Johnson
•  Hiroyuki Ohnaka
•  Erik Pragt
•  Vijay Bolleypally
•  Pierre Hilt
•  Yotaro Takahashi
•  Jochen Berger
•  Matan Katz
•  Victor Parmar
•  Berardino la Torre
•  Markus Schlichting
•  Andrey Hitrin
•  Leo Fedorov
•  Chris Byrneham
•  Aseem Bansal
•  Tomasz Przybysz
•  Brian Stewart
•  Jacob Aae Mikkelsen
•  Patrick Radtke
•  Leonard Brünings
Breaking changes in 1.0
•  Methods like isDisplayed() and
text() throw an exception when called
on multi element navigators
•  Weakly typed module() and
moduleList() removed
•  isDisabled() and isReadOnly()
removed from Navigator
Heresy warning...
Advanced usage
a.k.a. Tips & Tricks
Module is-a Navigator
•  Modules wrap around their base
Navigator
•  All Navigator methods can be called on
Module instances
•  Navigator methods can be used in
module implementations
Module is-a Navigator
<html>
<form method="post" action="login">
...
</from>
</html>
class LoginFormModule extends Module {
static base = { $("form") }
}

class LoginPage extends Page {
static content = {
form { module LoginFormModule }
}
}
Module is-a Navigator
to LoginPage
assert form.@method == "post”
assert form.displayed
Overriding value() on module
Class DatepickerModule extends Module {
LocalDate value() {
...
}

Navigator value(LocalDate date) {
...
}
}

class DatepickerPage extends Page {
static content = {
date { module DatepickerModule }
}
}
Overriding value() on module
to DatepickerPage
date.value(LocalDate.of(2017, 4, 1))
assert date.value() == LocalDate.of(2017, 4, 1)
to DatepickerPage
date = LocalDate.of(2017, 4, 1) 
assert date == LocalDate.of(2017, 4, 1)
Advanced navigation and types
•  Page.convertToPath(Object[]) is
used to translate arguments passed to
Browser.to() into a path
•  Consider overloading convertToPath()
for more expressive navigation
Advanced navigation and types
class PostPage extends Page {
static url = “posts”

String convertToPath(Post post) {
“${post.id}/${post.title.toLowerCase().replaceAll(“ ”, “-”)}”
}
}

def post = new Post(id: 1, title: “My first post”)

to PostPage, post
assert title == post.title
Parameterised pages
•  Pages can be instantiated and passed to
via(), to() and at()
•  Useful when you need to differ
implementation based on the object
represented by the page
Parameterised pages navigation
class PostPage extends Page {
Post post

String getPageUrl() {
“posts/${post.id}/${post.title.toLowerCase().replaceAll(“ ”, “-”)}”
}
}

def post = new Post(id: 1, title: “My first post”)

to(new PostPage(post: post))
assert title == post.title
Navigators are iterable
•  Navigators are backed by a collection of
WebElements
•  Navigators implement
Iterable<Navigator>
Navigators are iterable
<html>
<p>First paragraph</p>
<p>Second paragraph</p>
</html>
$(“p”).text() // throws exception
$(“p”)[0].text() // returns “First paragraph”
$(“p”)*.text() // returns [“First paragraph”, “Second paragraph”]

//returns [0: “First paragraph”, 1: “Second paragraph”]
$(“p”).withIndex().collectEntries { [(it.second): it.first.text()] }
What’s onLoad() for?
class CookieBarPage extends Page {
boolean autoCloseCookieBar = true
static content = {
cookieBar { module(CookieBarModule) }
}
void onLoad(Page previousPage) {
if (autoCloseCookieBar && cookieBar) {
cookieBar.close()
}
}

}
Injecting javascript into page
js.exec '''
var url = 'https://code.jquery.com/jquery-3.2.1.min.js';

var scriptElement = document.createElement('script');
scriptElement.setAttribute('src', url);
document.head.appendChild(scriptElement);
'''
Navigator’s elements in js
void waitForCssTransition(Navigator navigator, WaitingSupport waiting, JavascriptInterface js,
Closure trigger) {
js.exec(navigator.singleElement(), '''
var o = jQuery(arguments[0]);
window.setTransitionFinishedClass = function() {
$(this).addClass('transitionFinished');
}
o.bind('transitionend', window.setTransitionFinishedClass);
''')
try {
trigger.call()
waiting.waitFor { hasClass('transitionFinished') }
} finally {
js.exec(navigator.singleElement, '''
var o = jQuery(arguments[0]);
o.unbind('transitionend', window.setTransitionFinishedClass);
o.removeClass('transitionFinished')
window.setTransitionFinishedClass = undefined;
''')
}
}
Alternatives to inheritance
•  Using inheritance for code sharing leads to
complex inheritance structures
•  @Delegate can be used for code sharing
via delegation
•  Traits can be used for code sharing
Alternatives to inheritance
class TransitionSupport {
private final Navigator navigator
private final WaitingSupport waiting
private final JavascriptInterface js

TransitionSupport(Navigator navigator, WaitingSupport waiting, JavascriptInterface js) {
...
}
void waitForCssTransition(Closure trigger) {
...
}
}

class TransitioningModule extends Module {
@Delegate
TransitionSupport transitionSupport = new TransitionSupport(this, this, js)
}
Alternatives to inheritance
trait TransitionSupport implements Navigator, WaitingSupport {
abstract JavascriptInterface getJs()

void waitForCssTransition(Closure trigger) {
...
}
}

class TransitioningModule extends Module implements TransitionSupport {
}
Dynamic base url
class RatpackApplicationGebSpec extends GebSpec {

def application = new GroovyRatpackMainApplicationUnderTest()
def setup() {
browser.baseUrl = application.address.toString()
}

}
Testing responsive apps
class TestsMobileViewExtension extends 
AbstractAnnotationDrivenExtension<TestsMobileView> {
void visitFeatureAnnotation(TestsMobileView annotation, FeatureInfo feature) {
feature.addInterceptor { invocation ->
def window = new ConfigurationLoader().conf.driver.manage().window()
def originalSize = window.size
try {
window.size = new Dimension(320, 568)
invocation.proceed()
} finally {
window.size = originalSize
}
}
}
}
Best practices
a.k.a. Marcin’s musings
Strongly typed Geb code
•  Better authoring, i.e. autocompletion
•  Better navigation, i.e. going to method
definition, finding usages
•  Refactoring support
What IntelliJ understands?
•  Delegation to Browser methods in specs
•  Delegation to Page methods in specs
•  Content definitions
Tracking current page type
•  Capture current page in a variable
•  Use return values of via(), to() and
at()
•  Return new page instance from methods
triggering page transitions
Tracking current page
def homePage = to HomePage

homePage.loginPageLink.click()
def loginPage = at LoginPage

def securePage = loginPage.login("user", "password")
Tracking current page
to(HomePage).loginPageLink.click()

def securePage = at(LoginPage).login("user", "password")
At checks
•  Keep them quick and simple
•  Check if you are at the right page
•  Don’t test any page logic
What’s missing here?
class CookieBarPage extends Page {
boolean autoCloseCookieBar = true
static content = {
cookieBar { $('.cookie-message’) }
cookieBarText { $('.cookie-message-text').text() }
cookieBarCloseButton { $('.cookie-message-button > input') }
}

}
What are modules good for?
•  More than reuse
•  Modeling logical components
•  Hiding component structure from tests
•  Hiding complex interactions from tests
Invest time in fixture builders
•  Aim for easy, expressive and flexible data
setup
•  Keep data setup close to tests
•  Setup only the data necessary for the test
•  Groovy Remote Control can be very helpful
•  Fixtures are not not only about data
Geb’s test harness html fixture
def “can access element classes”() {
given:
html {
div(id: "a", 'class': "a1 a2 a3")
div(id: "b", 'class': "b1”)
}

expect:
$("#a").classes() == ["a1", "a2", "a3"]
$("#b").classes() == ["b1”]
}
Example data fixture DSL
bootstrapper.post {
id = “69f10bb6-118e-11e7-93ae-92361f002671”
title = “My first post”
tags = [“Groovy”, “Geb”]
author {
firstName = “Marcin”
lastName = “Erdmann”
}
}
Use real browser in CI
•  Available headless drivers are either
limited, not developed anymore or not
properly tested
•  Use a real browser with a virtual frame
buffer, i.e. Xvfb
•  Use a cloud browser provider
reportOnTestFailuresOnly
To waitFor() or
not?
To waitFor() or not?
•  Ask yourself if action is asynchronous
•  Watch out for quick asynchronous events
waitFor() considered harmful
•  Best not used directly in tests
•  Hide asynchronous behaviour in action
methods on modules and pages
Increasing the
timeout is
(usually) not the
answer
Use wait presets
Browser test are costly!
•  Slow, hard to maintain and flakey
•  Mind what you test at such high level
•  ...but they provide a lot of confidence
Cross browser
tests are costlier
Cloud browser providers
•  Gradle plugins for driving browsers with
Geb in BrowserStack and Suace Labs
•  Can test applications via a tunnel which are
not available on the Internet
Using attributes map selectors
•  Map selectors are now translated to CSS
attribute selectors
•  As quick as using css selectors but reads
better especially when using dynamic
values
Using attributes map selectors
$(‘button’, type: ‘select’)
$(‘button[type=“select”]’)

$(itemtype: ‘http://schema.org/Person’)
$(‘[itemtype=“http://schema.org/Person”]’)
Selecting by text is slow!
•  Selecting by text is a Geb extension not
something that CSS supports
•  Narrow down selected elements as much
as possible when selecting by text
Questions?
Thank you!

Mais conteúdo relacionado

Mais procurados

Red Hat OpenShift V3 Overview and Deep Dive
Red Hat OpenShift V3 Overview and Deep DiveRed Hat OpenShift V3 Overview and Deep Dive
Red Hat OpenShift V3 Overview and Deep DiveGreg Hoelzer
 
Kubernetes and Prometheus
Kubernetes and PrometheusKubernetes and Prometheus
Kubernetes and PrometheusWeaveworks
 
Flusso Continuous Integration & Continuous Delivery
Flusso Continuous Integration & Continuous DeliveryFlusso Continuous Integration & Continuous Delivery
Flusso Continuous Integration & Continuous DeliveryJoost van der Griendt
 
Finally, easy integration testing with Testcontainers
Finally, easy integration testing with TestcontainersFinally, easy integration testing with Testcontainers
Finally, easy integration testing with TestcontainersRudy De Busscher
 
Intro to vue.js
Intro to vue.jsIntro to vue.js
Intro to vue.jsTechMagic
 
KubeCon + CloudNative Con NA 2021 | A New Generation of NATS
KubeCon + CloudNative Con NA 2021 | A New Generation of NATSKubeCon + CloudNative Con NA 2021 | A New Generation of NATS
KubeCon + CloudNative Con NA 2021 | A New Generation of NATSNATS
 
Migrating from Struts 1 to Struts 2
Migrating from Struts 1 to Struts 2Migrating from Struts 1 to Struts 2
Migrating from Struts 1 to Struts 2Matt Raible
 
Docker introduction
Docker introductionDocker introduction
Docker introductiondotCloud
 
DevOps avec Ansible et Docker
DevOps avec Ansible et DockerDevOps avec Ansible et Docker
DevOps avec Ansible et DockerStephane Manciot
 
Realtime vs Cloud Firestore
Realtime vs Cloud Firestore Realtime vs Cloud Firestore
Realtime vs Cloud Firestore Appinventiv
 
Protecting Apps from Hacks in Kubernetes with NGINX
Protecting Apps from Hacks in Kubernetes with NGINXProtecting Apps from Hacks in Kubernetes with NGINX
Protecting Apps from Hacks in Kubernetes with NGINXNGINX, Inc.
 
MySQL operator for_kubernetes
MySQL operator for_kubernetesMySQL operator for_kubernetes
MySQL operator for_kubernetesrockplace
 
Gradle - the Enterprise Automation Tool
Gradle  - the Enterprise Automation ToolGradle  - the Enterprise Automation Tool
Gradle - the Enterprise Automation ToolIzzet Mustafaiev
 
Small, Simple, and Secure: Alpine Linux under the Microscope
Small, Simple, and Secure: Alpine Linux under the MicroscopeSmall, Simple, and Secure: Alpine Linux under the Microscope
Small, Simple, and Secure: Alpine Linux under the MicroscopeDocker, Inc.
 
Karate, the black belt of HTTP API testing?
Karate, the black belt of HTTP API testing?Karate, the black belt of HTTP API testing?
Karate, the black belt of HTTP API testing?Bertrand Delacretaz
 
Kubernetes networking in AWS
Kubernetes networking in AWSKubernetes networking in AWS
Kubernetes networking in AWSZvika Gazit
 
Redhat training &certification
Redhat training &certificationRedhat training &certification
Redhat training &certificationAhmed Abbas Ahmed
 
Cloud Native Networking & Security with Cilium & eBPF
Cloud Native Networking & Security with Cilium & eBPFCloud Native Networking & Security with Cilium & eBPF
Cloud Native Networking & Security with Cilium & eBPFRaphaël PINSON
 

Mais procurados (20)

Red Hat OpenShift V3 Overview and Deep Dive
Red Hat OpenShift V3 Overview and Deep DiveRed Hat OpenShift V3 Overview and Deep Dive
Red Hat OpenShift V3 Overview and Deep Dive
 
Kubernetes and Prometheus
Kubernetes and PrometheusKubernetes and Prometheus
Kubernetes and Prometheus
 
Flusso Continuous Integration & Continuous Delivery
Flusso Continuous Integration & Continuous DeliveryFlusso Continuous Integration & Continuous Delivery
Flusso Continuous Integration & Continuous Delivery
 
Finally, easy integration testing with Testcontainers
Finally, easy integration testing with TestcontainersFinally, easy integration testing with Testcontainers
Finally, easy integration testing with Testcontainers
 
Intro to vue.js
Intro to vue.jsIntro to vue.js
Intro to vue.js
 
KubeCon + CloudNative Con NA 2021 | A New Generation of NATS
KubeCon + CloudNative Con NA 2021 | A New Generation of NATSKubeCon + CloudNative Con NA 2021 | A New Generation of NATS
KubeCon + CloudNative Con NA 2021 | A New Generation of NATS
 
Migrating from Struts 1 to Struts 2
Migrating from Struts 1 to Struts 2Migrating from Struts 1 to Struts 2
Migrating from Struts 1 to Struts 2
 
Docker introduction
Docker introductionDocker introduction
Docker introduction
 
DevOps avec Ansible et Docker
DevOps avec Ansible et DockerDevOps avec Ansible et Docker
DevOps avec Ansible et Docker
 
Realtime vs Cloud Firestore
Realtime vs Cloud Firestore Realtime vs Cloud Firestore
Realtime vs Cloud Firestore
 
Protecting Apps from Hacks in Kubernetes with NGINX
Protecting Apps from Hacks in Kubernetes with NGINXProtecting Apps from Hacks in Kubernetes with NGINX
Protecting Apps from Hacks in Kubernetes with NGINX
 
Introduction to docker
Introduction to dockerIntroduction to docker
Introduction to docker
 
NServiceBus
NServiceBusNServiceBus
NServiceBus
 
MySQL operator for_kubernetes
MySQL operator for_kubernetesMySQL operator for_kubernetes
MySQL operator for_kubernetes
 
Gradle - the Enterprise Automation Tool
Gradle  - the Enterprise Automation ToolGradle  - the Enterprise Automation Tool
Gradle - the Enterprise Automation Tool
 
Small, Simple, and Secure: Alpine Linux under the Microscope
Small, Simple, and Secure: Alpine Linux under the MicroscopeSmall, Simple, and Secure: Alpine Linux under the Microscope
Small, Simple, and Secure: Alpine Linux under the Microscope
 
Karate, the black belt of HTTP API testing?
Karate, the black belt of HTTP API testing?Karate, the black belt of HTTP API testing?
Karate, the black belt of HTTP API testing?
 
Kubernetes networking in AWS
Kubernetes networking in AWSKubernetes networking in AWS
Kubernetes networking in AWS
 
Redhat training &certification
Redhat training &certificationRedhat training &certification
Redhat training &certification
 
Cloud Native Networking & Security with Cilium & eBPF
Cloud Native Networking & Security with Cilium & eBPFCloud Native Networking & Security with Cilium & eBPF
Cloud Native Networking & Security with Cilium & eBPF
 

Semelhante a Geb Best Practices

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
 
Building Single-Page Web Appplications in dart - Devoxx France 2013
Building Single-Page Web Appplications in dart - Devoxx France 2013Building Single-Page Web Appplications in dart - Devoxx France 2013
Building Single-Page Web Appplications in dart - Devoxx France 2013yohanbeschi
 
Whats new in MongoDB 24
Whats new in MongoDB 24Whats new in MongoDB 24
Whats new in MongoDB 24MongoDB
 
Architecture Components In Real Life Season 2
Architecture Components In Real Life Season 2Architecture Components In Real Life Season 2
Architecture Components In Real Life Season 2Somkiat Khitwongwattana
 
Modularity and Domain Driven Design - A killer combination - T De Wolf & S va...
Modularity and Domain Driven Design - A killer combination - T De Wolf & S va...Modularity and Domain Driven Design - A killer combination - T De Wolf & S va...
Modularity and Domain Driven Design - A killer combination - T De Wolf & S va...mfrancis
 
MicroProfile: A Quest for a Lightweight and Modern Enterprise Java Platform
MicroProfile: A Quest for a Lightweight and Modern Enterprise Java PlatformMicroProfile: A Quest for a Lightweight and Modern Enterprise Java Platform
MicroProfile: A Quest for a Lightweight and Modern Enterprise Java PlatformMike Croft
 
Examiness hints and tips from the trenches
Examiness hints and tips from the trenchesExaminess hints and tips from the trenches
Examiness hints and tips from the trenchesIsmail Mayat
 
Red Hat JBoss BRMS and BPMS Workbench and Rich Client Technology
Red Hat JBoss BRMS and BPMS Workbench and Rich Client TechnologyRed Hat JBoss BRMS and BPMS Workbench and Rich Client Technology
Red Hat JBoss BRMS and BPMS Workbench and Rich Client TechnologyMark Proctor
 
Modularity and Domain Driven Design; a killer combination?
Modularity and Domain Driven Design; a killer combination?Modularity and Domain Driven Design; a killer combination?
Modularity and Domain Driven Design; a killer combination?ACA IT-Solutions
 
5 x HTML5 worth using in APEX (5)
5 x HTML5 worth using in APEX (5)5 x HTML5 worth using in APEX (5)
5 x HTML5 worth using in APEX (5)Christian Rokitta
 
Annotation processing and code gen
Annotation processing and code genAnnotation processing and code gen
Annotation processing and code genkoji lin
 
LA Ember.js Meetup, Jan 2017
LA Ember.js Meetup, Jan 2017LA Ember.js Meetup, Jan 2017
LA Ember.js Meetup, Jan 2017Matthew Beale
 
node-crate: node.js and big data
 node-crate: node.js and big data node-crate: node.js and big data
node-crate: node.js and big dataStefan Thies
 
CouchDB for Web Applications - Erlang Factory London 2009
CouchDB for Web Applications - Erlang Factory London 2009CouchDB for Web Applications - Erlang Factory London 2009
CouchDB for Web Applications - Erlang Factory London 2009Jason Davies
 
DSL's with Groovy
DSL's with GroovyDSL's with Groovy
DSL's with Groovypaulbowler
 
Advanced guide to develop ajax applications using dojo
Advanced guide to develop ajax applications using dojoAdvanced guide to develop ajax applications using dojo
Advanced guide to develop ajax applications using dojoFu Cheng
 
Digital Publishing for Scale: The Economist and Go
Digital Publishing for Scale: The Economist and GoDigital Publishing for Scale: The Economist and Go
Digital Publishing for Scale: The Economist and GoC4Media
 
Web automation with #d8rules (European Drupal Days 2015)
Web automation with #d8rules (European Drupal Days 2015)Web automation with #d8rules (European Drupal Days 2015)
Web automation with #d8rules (European Drupal Days 2015)Eugenio Minardi
 

Semelhante a Geb Best Practices (20)

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)
 
Building Single-Page Web Appplications in dart - Devoxx France 2013
Building Single-Page Web Appplications in dart - Devoxx France 2013Building Single-Page Web Appplications in dart - Devoxx France 2013
Building Single-Page Web Appplications in dart - Devoxx France 2013
 
Whats new in MongoDB 24
Whats new in MongoDB 24Whats new in MongoDB 24
Whats new in MongoDB 24
 
Architecture Components In Real Life Season 2
Architecture Components In Real Life Season 2Architecture Components In Real Life Season 2
Architecture Components In Real Life Season 2
 
Modularity and Domain Driven Design - A killer combination - T De Wolf & S va...
Modularity and Domain Driven Design - A killer combination - T De Wolf & S va...Modularity and Domain Driven Design - A killer combination - T De Wolf & S va...
Modularity and Domain Driven Design - A killer combination - T De Wolf & S va...
 
MicroProfile: A Quest for a Lightweight and Modern Enterprise Java Platform
MicroProfile: A Quest for a Lightweight and Modern Enterprise Java PlatformMicroProfile: A Quest for a Lightweight and Modern Enterprise Java Platform
MicroProfile: A Quest for a Lightweight and Modern Enterprise Java Platform
 
Examiness hints and tips from the trenches
Examiness hints and tips from the trenchesExaminess hints and tips from the trenches
Examiness hints and tips from the trenches
 
Red Hat JBoss BRMS and BPMS Workbench and Rich Client Technology
Red Hat JBoss BRMS and BPMS Workbench and Rich Client TechnologyRed Hat JBoss BRMS and BPMS Workbench and Rich Client Technology
Red Hat JBoss BRMS and BPMS Workbench and Rich Client Technology
 
Modularity and Domain Driven Design; a killer combination?
Modularity and Domain Driven Design; a killer combination?Modularity and Domain Driven Design; a killer combination?
Modularity and Domain Driven Design; a killer combination?
 
5 x HTML5 worth using in APEX (5)
5 x HTML5 worth using in APEX (5)5 x HTML5 worth using in APEX (5)
5 x HTML5 worth using in APEX (5)
 
Annotation processing and code gen
Annotation processing and code genAnnotation processing and code gen
Annotation processing and code gen
 
jQuery for beginners
jQuery for beginnersjQuery for beginners
jQuery for beginners
 
LA Ember.js Meetup, Jan 2017
LA Ember.js Meetup, Jan 2017LA Ember.js Meetup, Jan 2017
LA Ember.js Meetup, Jan 2017
 
node-crate: node.js and big data
 node-crate: node.js and big data node-crate: node.js and big data
node-crate: node.js and big data
 
CouchDB for Web Applications - Erlang Factory London 2009
CouchDB for Web Applications - Erlang Factory London 2009CouchDB for Web Applications - Erlang Factory London 2009
CouchDB for Web Applications - Erlang Factory London 2009
 
DSL's with Groovy
DSL's with GroovyDSL's with Groovy
DSL's with Groovy
 
Life outside WO
Life outside WOLife outside WO
Life outside WO
 
Advanced guide to develop ajax applications using dojo
Advanced guide to develop ajax applications using dojoAdvanced guide to develop ajax applications using dojo
Advanced guide to develop ajax applications using dojo
 
Digital Publishing for Scale: The Economist and Go
Digital Publishing for Scale: The Economist and GoDigital Publishing for Scale: The Economist and Go
Digital Publishing for Scale: The Economist and Go
 
Web automation with #d8rules (European Drupal Days 2015)
Web automation with #d8rules (European Drupal Days 2015)Web automation with #d8rules (European Drupal Days 2015)
Web automation with #d8rules (European Drupal Days 2015)
 

Último

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXssuser89054b
 
Rums floating Omkareshwar FSPV IM_16112021.pdf
Rums floating Omkareshwar FSPV IM_16112021.pdfRums floating Omkareshwar FSPV IM_16112021.pdf
Rums floating Omkareshwar FSPV IM_16112021.pdfsmsksolar
 
Thermal Engineering-R & A / C - unit - V
Thermal Engineering-R & A / C - unit - VThermal Engineering-R & A / C - unit - V
Thermal Engineering-R & A / C - unit - VDineshKumar4165
 
Design For Accessibility: Getting it right from the start
Design For Accessibility: Getting it right from the startDesign For Accessibility: Getting it right from the start
Design For Accessibility: Getting it right from the startQuintin Balsdon
 
Bhubaneswar🌹Call Girls Bhubaneswar ❤Komal 9777949614 💟 Full Trusted CALL GIRL...
Bhubaneswar🌹Call Girls Bhubaneswar ❤Komal 9777949614 💟 Full Trusted CALL GIRL...Bhubaneswar🌹Call Girls Bhubaneswar ❤Komal 9777949614 💟 Full Trusted CALL GIRL...
Bhubaneswar🌹Call Girls Bhubaneswar ❤Komal 9777949614 💟 Full Trusted CALL GIRL...Call Girls Mumbai
 
Navigating Complexity: The Role of Trusted Partners and VIAS3D in Dassault Sy...
Navigating Complexity: The Role of Trusted Partners and VIAS3D in Dassault Sy...Navigating Complexity: The Role of Trusted Partners and VIAS3D in Dassault Sy...
Navigating Complexity: The Role of Trusted Partners and VIAS3D in Dassault Sy...Arindam Chakraborty, Ph.D., P.E. (CA, TX)
 
kiln thermal load.pptx kiln tgermal load
kiln thermal load.pptx kiln tgermal loadkiln thermal load.pptx kiln tgermal load
kiln thermal load.pptx kiln tgermal loadhamedmustafa094
 
Tamil Call Girls Bhayandar WhatsApp +91-9930687706, Best Service
Tamil Call Girls Bhayandar WhatsApp +91-9930687706, Best ServiceTamil Call Girls Bhayandar WhatsApp +91-9930687706, Best Service
Tamil Call Girls Bhayandar WhatsApp +91-9930687706, Best Servicemeghakumariji156
 
COST-EFFETIVE and Energy Efficient BUILDINGS ptx
COST-EFFETIVE  and Energy Efficient BUILDINGS ptxCOST-EFFETIVE  and Energy Efficient BUILDINGS ptx
COST-EFFETIVE and Energy Efficient BUILDINGS ptxJIT KUMAR GUPTA
 
Introduction to Serverless with AWS Lambda
Introduction to Serverless with AWS LambdaIntroduction to Serverless with AWS Lambda
Introduction to Serverless with AWS LambdaOmar Fathy
 
data_management_and _data_science_cheat_sheet.pdf
data_management_and _data_science_cheat_sheet.pdfdata_management_and _data_science_cheat_sheet.pdf
data_management_and _data_science_cheat_sheet.pdfJiananWang21
 
Engineering Drawing focus on projection of planes
Engineering Drawing focus on projection of planesEngineering Drawing focus on projection of planes
Engineering Drawing focus on projection of planesRAJNEESHKUMAR341697
 
Air Compressor reciprocating single stage
Air Compressor reciprocating single stageAir Compressor reciprocating single stage
Air Compressor reciprocating single stageAbc194748
 
HAND TOOLS USED AT ELECTRONICS WORK PRESENTED BY KOUSTAV SARKAR
HAND TOOLS USED AT ELECTRONICS WORK PRESENTED BY KOUSTAV SARKARHAND TOOLS USED AT ELECTRONICS WORK PRESENTED BY KOUSTAV SARKAR
HAND TOOLS USED AT ELECTRONICS WORK PRESENTED BY KOUSTAV SARKARKOUSTAV SARKAR
 
DC MACHINE-Motoring and generation, Armature circuit equation
DC MACHINE-Motoring and generation, Armature circuit equationDC MACHINE-Motoring and generation, Armature circuit equation
DC MACHINE-Motoring and generation, Armature circuit equationBhangaleSonal
 
School management system project Report.pdf
School management system project Report.pdfSchool management system project Report.pdf
School management system project Report.pdfKamal Acharya
 
Hostel management system project report..pdf
Hostel management system project report..pdfHostel management system project report..pdf
Hostel management system project report..pdfKamal Acharya
 

Último (20)

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 
Rums floating Omkareshwar FSPV IM_16112021.pdf
Rums floating Omkareshwar FSPV IM_16112021.pdfRums floating Omkareshwar FSPV IM_16112021.pdf
Rums floating Omkareshwar FSPV IM_16112021.pdf
 
Thermal Engineering-R & A / C - unit - V
Thermal Engineering-R & A / C - unit - VThermal Engineering-R & A / C - unit - V
Thermal Engineering-R & A / C - unit - V
 
Design For Accessibility: Getting it right from the start
Design For Accessibility: Getting it right from the startDesign For Accessibility: Getting it right from the start
Design For Accessibility: Getting it right from the start
 
Bhubaneswar🌹Call Girls Bhubaneswar ❤Komal 9777949614 💟 Full Trusted CALL GIRL...
Bhubaneswar🌹Call Girls Bhubaneswar ❤Komal 9777949614 💟 Full Trusted CALL GIRL...Bhubaneswar🌹Call Girls Bhubaneswar ❤Komal 9777949614 💟 Full Trusted CALL GIRL...
Bhubaneswar🌹Call Girls Bhubaneswar ❤Komal 9777949614 💟 Full Trusted CALL GIRL...
 
Navigating Complexity: The Role of Trusted Partners and VIAS3D in Dassault Sy...
Navigating Complexity: The Role of Trusted Partners and VIAS3D in Dassault Sy...Navigating Complexity: The Role of Trusted Partners and VIAS3D in Dassault Sy...
Navigating Complexity: The Role of Trusted Partners and VIAS3D in Dassault Sy...
 
kiln thermal load.pptx kiln tgermal load
kiln thermal load.pptx kiln tgermal loadkiln thermal load.pptx kiln tgermal load
kiln thermal load.pptx kiln tgermal load
 
Call Girls in South Ex (delhi) call me [🔝9953056974🔝] escort service 24X7
Call Girls in South Ex (delhi) call me [🔝9953056974🔝] escort service 24X7Call Girls in South Ex (delhi) call me [🔝9953056974🔝] escort service 24X7
Call Girls in South Ex (delhi) call me [🔝9953056974🔝] escort service 24X7
 
Tamil Call Girls Bhayandar WhatsApp +91-9930687706, Best Service
Tamil Call Girls Bhayandar WhatsApp +91-9930687706, Best ServiceTamil Call Girls Bhayandar WhatsApp +91-9930687706, Best Service
Tamil Call Girls Bhayandar WhatsApp +91-9930687706, Best Service
 
COST-EFFETIVE and Energy Efficient BUILDINGS ptx
COST-EFFETIVE  and Energy Efficient BUILDINGS ptxCOST-EFFETIVE  and Energy Efficient BUILDINGS ptx
COST-EFFETIVE and Energy Efficient BUILDINGS ptx
 
Introduction to Serverless with AWS Lambda
Introduction to Serverless with AWS LambdaIntroduction to Serverless with AWS Lambda
Introduction to Serverless with AWS Lambda
 
data_management_and _data_science_cheat_sheet.pdf
data_management_and _data_science_cheat_sheet.pdfdata_management_and _data_science_cheat_sheet.pdf
data_management_and _data_science_cheat_sheet.pdf
 
Engineering Drawing focus on projection of planes
Engineering Drawing focus on projection of planesEngineering Drawing focus on projection of planes
Engineering Drawing focus on projection of planes
 
Air Compressor reciprocating single stage
Air Compressor reciprocating single stageAir Compressor reciprocating single stage
Air Compressor reciprocating single stage
 
HAND TOOLS USED AT ELECTRONICS WORK PRESENTED BY KOUSTAV SARKAR
HAND TOOLS USED AT ELECTRONICS WORK PRESENTED BY KOUSTAV SARKARHAND TOOLS USED AT ELECTRONICS WORK PRESENTED BY KOUSTAV SARKAR
HAND TOOLS USED AT ELECTRONICS WORK PRESENTED BY KOUSTAV SARKAR
 
DC MACHINE-Motoring and generation, Armature circuit equation
DC MACHINE-Motoring and generation, Armature circuit equationDC MACHINE-Motoring and generation, Armature circuit equation
DC MACHINE-Motoring and generation, Armature circuit equation
 
School management system project Report.pdf
School management system project Report.pdfSchool management system project Report.pdf
School management system project Report.pdf
 
Hostel management system project report..pdf
Hostel management system project report..pdfHostel management system project report..pdf
Hostel management system project report..pdf
 
Integrated Test Rig For HTFE-25 - Neometrix
Integrated Test Rig For HTFE-25 - NeometrixIntegrated Test Rig For HTFE-25 - Neometrix
Integrated Test Rig For HTFE-25 - Neometrix
 
FEA Based Level 3 Assessment of Deformed Tanks with Fluid Induced Loads
FEA Based Level 3 Assessment of Deformed Tanks with Fluid Induced LoadsFEA Based Level 3 Assessment of Deformed Tanks with Fluid Induced Loads
FEA Based Level 3 Assessment of Deformed Tanks with Fluid Induced Loads
 

Geb Best Practices

  • 2. @marcinerdmann •  Groovy enthusiast since 2010 •  Geb user since 2011 •  Geb lead since 2014 •  Open source contributor •  Testing junkie
  • 3.
  • 5. 50 Geb contributors •  Robert Fletcher •  Peter Niederwieser •  Alexander Zolotov •  Christoph Neuroth •  Antony Jones •  Jan-Hendrik Peters •  Tomás Lin •  Jason Cahoon •  Tomasz Kalkosiński •  Rich Douglas Evans •  Ian Durkan •  Colin Harrington •  Bob Herrmann •  George T Walters II •  Craig Atkinson •  Andy Duncan •  John Engelman •  Michael Legart •  Graeme Rocher •  Craig Atkinson •  Ken Geis •  Chris Prior •  Kelly Robinson •  Todd Gerspacher •  David M. Carr •  Tom Dunstan •  Brian Kotek •  David W Millar •  Ai-Lin Liou •  Varun Menon •  Anders D. Johnson •  Hiroyuki Ohnaka •  Erik Pragt •  Vijay Bolleypally •  Pierre Hilt •  Yotaro Takahashi •  Jochen Berger •  Matan Katz •  Victor Parmar •  Berardino la Torre •  Markus Schlichting •  Andrey Hitrin •  Leo Fedorov •  Chris Byrneham •  Aseem Bansal •  Tomasz Przybysz •  Brian Stewart •  Jacob Aae Mikkelsen •  Patrick Radtke •  Leonard Brünings
  • 6. Breaking changes in 1.0 •  Methods like isDisplayed() and text() throw an exception when called on multi element navigators •  Weakly typed module() and moduleList() removed •  isDisabled() and isReadOnly() removed from Navigator
  • 9. Module is-a Navigator •  Modules wrap around their base Navigator •  All Navigator methods can be called on Module instances •  Navigator methods can be used in module implementations
  • 10. Module is-a Navigator <html> <form method="post" action="login"> ... </from> </html> class LoginFormModule extends Module { static base = { $("form") } } class LoginPage extends Page { static content = { form { module LoginFormModule } } }
  • 11. Module is-a Navigator to LoginPage assert form.@method == "post” assert form.displayed
  • 12. Overriding value() on module Class DatepickerModule extends Module { LocalDate value() { ... } Navigator value(LocalDate date) { ... } } class DatepickerPage extends Page { static content = { date { module DatepickerModule } } }
  • 13. Overriding value() on module to DatepickerPage date.value(LocalDate.of(2017, 4, 1)) assert date.value() == LocalDate.of(2017, 4, 1) to DatepickerPage date = LocalDate.of(2017, 4, 1) assert date == LocalDate.of(2017, 4, 1)
  • 14. Advanced navigation and types •  Page.convertToPath(Object[]) is used to translate arguments passed to Browser.to() into a path •  Consider overloading convertToPath() for more expressive navigation
  • 15. Advanced navigation and types class PostPage extends Page { static url = “posts” String convertToPath(Post post) { “${post.id}/${post.title.toLowerCase().replaceAll(“ ”, “-”)}” } } def post = new Post(id: 1, title: “My first post”) to PostPage, post assert title == post.title
  • 16. Parameterised pages •  Pages can be instantiated and passed to via(), to() and at() •  Useful when you need to differ implementation based on the object represented by the page
  • 17. Parameterised pages navigation class PostPage extends Page { Post post String getPageUrl() { “posts/${post.id}/${post.title.toLowerCase().replaceAll(“ ”, “-”)}” } } def post = new Post(id: 1, title: “My first post”) to(new PostPage(post: post)) assert title == post.title
  • 18. Navigators are iterable •  Navigators are backed by a collection of WebElements •  Navigators implement Iterable<Navigator>
  • 19. Navigators are iterable <html> <p>First paragraph</p> <p>Second paragraph</p> </html> $(“p”).text() // throws exception $(“p”)[0].text() // returns “First paragraph” $(“p”)*.text() // returns [“First paragraph”, “Second paragraph”] //returns [0: “First paragraph”, 1: “Second paragraph”] $(“p”).withIndex().collectEntries { [(it.second): it.first.text()] }
  • 20. What’s onLoad() for? class CookieBarPage extends Page { boolean autoCloseCookieBar = true static content = { cookieBar { module(CookieBarModule) } } void onLoad(Page previousPage) { if (autoCloseCookieBar && cookieBar) { cookieBar.close() } } }
  • 21. Injecting javascript into page js.exec ''' var url = 'https://code.jquery.com/jquery-3.2.1.min.js'; var scriptElement = document.createElement('script'); scriptElement.setAttribute('src', url); document.head.appendChild(scriptElement); '''
  • 22. Navigator’s elements in js void waitForCssTransition(Navigator navigator, WaitingSupport waiting, JavascriptInterface js, Closure trigger) { js.exec(navigator.singleElement(), ''' var o = jQuery(arguments[0]); window.setTransitionFinishedClass = function() { $(this).addClass('transitionFinished'); } o.bind('transitionend', window.setTransitionFinishedClass); ''') try { trigger.call() waiting.waitFor { hasClass('transitionFinished') } } finally { js.exec(navigator.singleElement, ''' var o = jQuery(arguments[0]); o.unbind('transitionend', window.setTransitionFinishedClass); o.removeClass('transitionFinished') window.setTransitionFinishedClass = undefined; ''') } }
  • 23. Alternatives to inheritance •  Using inheritance for code sharing leads to complex inheritance structures •  @Delegate can be used for code sharing via delegation •  Traits can be used for code sharing
  • 24. Alternatives to inheritance class TransitionSupport { private final Navigator navigator private final WaitingSupport waiting private final JavascriptInterface js TransitionSupport(Navigator navigator, WaitingSupport waiting, JavascriptInterface js) { ... } void waitForCssTransition(Closure trigger) { ... } } class TransitioningModule extends Module { @Delegate TransitionSupport transitionSupport = new TransitionSupport(this, this, js) }
  • 25. Alternatives to inheritance trait TransitionSupport implements Navigator, WaitingSupport { abstract JavascriptInterface getJs() void waitForCssTransition(Closure trigger) { ... } } class TransitioningModule extends Module implements TransitionSupport { }
  • 26. Dynamic base url class RatpackApplicationGebSpec extends GebSpec { def application = new GroovyRatpackMainApplicationUnderTest() def setup() { browser.baseUrl = application.address.toString() } }
  • 27. Testing responsive apps class TestsMobileViewExtension extends AbstractAnnotationDrivenExtension<TestsMobileView> { void visitFeatureAnnotation(TestsMobileView annotation, FeatureInfo feature) { feature.addInterceptor { invocation -> def window = new ConfigurationLoader().conf.driver.manage().window() def originalSize = window.size try { window.size = new Dimension(320, 568) invocation.proceed() } finally { window.size = originalSize } } } }
  • 29. Strongly typed Geb code •  Better authoring, i.e. autocompletion •  Better navigation, i.e. going to method definition, finding usages •  Refactoring support
  • 30. What IntelliJ understands? •  Delegation to Browser methods in specs •  Delegation to Page methods in specs •  Content definitions
  • 31. Tracking current page type •  Capture current page in a variable •  Use return values of via(), to() and at() •  Return new page instance from methods triggering page transitions
  • 32. Tracking current page def homePage = to HomePage homePage.loginPageLink.click() def loginPage = at LoginPage def securePage = loginPage.login("user", "password")
  • 33. Tracking current page to(HomePage).loginPageLink.click() def securePage = at(LoginPage).login("user", "password")
  • 34. At checks •  Keep them quick and simple •  Check if you are at the right page •  Don’t test any page logic
  • 35. What’s missing here? class CookieBarPage extends Page { boolean autoCloseCookieBar = true static content = { cookieBar { $('.cookie-message’) } cookieBarText { $('.cookie-message-text').text() } cookieBarCloseButton { $('.cookie-message-button > input') } } }
  • 36. What are modules good for? •  More than reuse •  Modeling logical components •  Hiding component structure from tests •  Hiding complex interactions from tests
  • 37. Invest time in fixture builders •  Aim for easy, expressive and flexible data setup •  Keep data setup close to tests •  Setup only the data necessary for the test •  Groovy Remote Control can be very helpful •  Fixtures are not not only about data
  • 38. Geb’s test harness html fixture def “can access element classes”() { given: html { div(id: "a", 'class': "a1 a2 a3") div(id: "b", 'class': "b1”) } expect: $("#a").classes() == ["a1", "a2", "a3"] $("#b").classes() == ["b1”] }
  • 39. Example data fixture DSL bootstrapper.post { id = “69f10bb6-118e-11e7-93ae-92361f002671” title = “My first post” tags = [“Groovy”, “Geb”] author { firstName = “Marcin” lastName = “Erdmann” } }
  • 40. Use real browser in CI •  Available headless drivers are either limited, not developed anymore or not properly tested •  Use a real browser with a virtual frame buffer, i.e. Xvfb •  Use a cloud browser provider
  • 43. To waitFor() or not? •  Ask yourself if action is asynchronous •  Watch out for quick asynchronous events
  • 44. waitFor() considered harmful •  Best not used directly in tests •  Hide asynchronous behaviour in action methods on modules and pages
  • 47. Browser test are costly! •  Slow, hard to maintain and flakey •  Mind what you test at such high level •  ...but they provide a lot of confidence
  • 49. Cloud browser providers •  Gradle plugins for driving browsers with Geb in BrowserStack and Suace Labs •  Can test applications via a tunnel which are not available on the Internet
  • 50. Using attributes map selectors •  Map selectors are now translated to CSS attribute selectors •  As quick as using css selectors but reads better especially when using dynamic values
  • 51. Using attributes map selectors $(‘button’, type: ‘select’) $(‘button[type=“select”]’) $(itemtype: ‘http://schema.org/Person’) $(‘[itemtype=“http://schema.org/Person”]’)
  • 52. Selecting by text is slow! •  Selecting by text is a Geb extension not something that CSS supports •  Narrow down selected elements as much as possible when selecting by text