Learn how to design, create, maintain, and re-factor an automation framework using the power of WebDriver, the elegance of jQuery content selection, the robustness of Page Object modeling, and the expressiveness of the Groovy language. Gaurav introduces an open-source testing solution that provides all this, and can be integrated with testing frameworks such as Spock, JUnit & TestNG.
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Comprehensive Browser Automation Solution using Groovy, WebDriver & Obect Model
1. Web Automation using Groovy, WebDriver,
JQuery and Page Object Model
By: Gaurav Bansal
2. Need…
• We need a solution that is based on technology
that is native to WebBrowsers.
• We need a solution that requires no boilerplate
code.
• We need a solution that offers a powerful set of
tools for matching a set of elements in a
document.
• We need a solution that offers in-built
mechanism to incorporate Page-object model
4. What is Geb?
• Geb is a browser automation solution.
• You can use it for…
– Acceptance Testing Web Applications
– Automating Web Sites
– Screen Scraping
• It brings together the…
– Cross browser automation capabilities of WebDriver
– Elegance of jQuery content selection
– Expressiveness of the Groovy language
– Robustness of Page Object modelling
5. About the Project
• Free Open Source, Apache License, Version
2.0.
• Currently at version 0.7.0.
– Home Page — http://www.gebish.org
– The Book of Geb — http://www.gebish.org
/manual/current
– Source Code — https://github.com/geb/geb
– User Mailing List — http://
xircles.codehaus.org/projects/geb/lists
– In Maven Central — http://
mvnrepository.com/artifact/org.codehaus.geb
6. Project Components
• The heart is the geb-core component which is
all you really need (plus WebDriver).
• For testing, you probably also want one of these
as well:
– geb-spock
– geb-junit3
– geb-junit4
– geb-testng
– geb-easyb
• (Has been used from Cucumber as well).
• There is also a Grails plugin.
8. WebDriver
• Successor to the Selenium project.
• Also known as “Selenium 2”.
• Sponsored and driven by Google.
• Becoming a W3C standard.
– http://dvcs.w3.org/hg/webdriver/raw-
file/515b648d58ff/webdriver-spec.html
9. Cross-browser
Automation
Java based, with many language bindings.
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.By;
import org.openqa.selenium.firefox.FirefoxDriver;
WebDriver driver = new FirefoxDriver();
driver.get("http://google.com");
WebElement heading = driver.findElement(By.tagName("h1"));
10. Mobile Browsers
• Rapidly improving.
– iPad
– iPhone
– Android
– Blackberry
• Can use real devices or emulators in most
cases.
• A headless webkit based driver
(PhantomJS) is in progress.
11. WebDriver API
• Geb sits on top of WebDriver so you very
rarely deal with its API, though it's
accessible if you need it.
• Geb never talks to the actual browser
because that's what WebDriver does.
12. Driver dependency
• You need to pull in a specific driver
implementation for each browser you want
to work with.
– <dependency>
– <groupId>org.seleniumhq.selenium</groupId>
– <artifactId>selenium-firefox-driver</artifactId>
– <version>2.24.1</version>
– </dependency>
14. JQuery
• jQuery provides an incredibly powerful API
for navigating and selecting content.
– $("div#footer").prev().children();
– CSS based, a whole lot better than XPath.
15. Geb's inspiration
• Geb features a “Navigator API” that is
inspired by jQuery.
– // This is Geb code, not jQuery JavaScript… $
("h1").previous().children();
• API is not identical.
17. Dynamic JVM Lang.
• Groovy is…
– Compiled, never interpreted
– Dynamic, optionally typed
– 99% Java syntax compatible
– Concise, clear and pragmatic
– Great for DSLs
– A comfortable Java alternative for most
18. Geb & Groovy
• Geb uses Groovy's dynamism to
remove boilerplate.
import geb.*
Browser.drive {
to GoogleHomePage
at GoogleHomePage
search.forTerm "wikipedia“
at GoogleResultsPage
assert firstResultLink.text() == "Wikipedia"
firstResultLink.click()
waitFor { at WikipediaPage }
}
19. Page Objects
The key to not pulling your hair
out when dealing with web tests.
20. What are they?
• In a phrase: Domain Modelling.
• By modelling and creating abstractions, we can isolate implementation
detail.
$("input[name=username]").value("user")
$("input[name=pwd]").value("password")
$("input[type=submit]").click()
• Is far more fragile than this…
void login(String username, String password) {
$("input[name=username]").value(username)
$("input[name=pwd]").value(password)
$("input[type=submit]").click()
}
login("user", "password")
21. Just good programming
• It's the application of trusted principles;
encapsulation and reuse.
• Not new at all, but new to the world of web
testing/automation.
• Not just about modelling “pages”. It's
about modelling all kinds of things in the
domain of a user's actions online.
• Just giving symbolic names to page
content is a great start.
22. Browser has-a Page
Browser.drive {
to GoogleHomePage
at GoogleHomePage
search.forTerm "wikipedia"
at GoogleResultsPage
assert firstResultLink.text() == "Wikipedia"
firstResultLink.click()
waitFor { at WikipediaPage }
}
• The to() and click() methods are changing the
underlying page.
• You can refer to the current page's content and
methods just by name.
23. Geb's Page Objects
• Geb builds the Page Object pattern
directly into the framework (though it is
optional).
import geb.*
class GoogleHomePage extends Page {
static url = "http://google.com/ncr"
static at = { title == "Google" }
static content = {
search { module GoogleSearchModule }
}
}
24. Geb's Page Objects
• Features the “Content DSL” for naming
content in a dynamic and powerful way.
import geb.*
class GoogleResultsPage extends Page {
static at = { waitFor { title.endsWith("Google Search") } }
static content = {
search { module GoogleSearchModule }
results { $("li.g") }
result { i -> results[i] }
resultLink { i -> result(i).find("a.l", 0) }
firstResultLink { resultLink(0) } } }
27. Geb for Testing
• Geb can be used with…
– Spock
– JUnit (3 & 4)
– TestNG
– EasyB
– Cucumber (Cuke4Duke)
• The majority of Geb users use Spock.
• Geb can dump HTML and screenshots for each
“test” to help in debugging.
29. The $() method
• Returns a Navigator object.
• General format:
–$
(«css selector», «index/range», «attribute/text
matchers»)
• Examples:
– $("div") // all divs
– $("div", 0) // first div $("div", 0..2) // first three divs
– // The third section heading with text “Geb” $("h2", 2, id: "section", text: "Geb")
30. CSS Selectors
• Full CSS3 if the target browser supports it.
$("div.some-class p:first[title='something']")
$("ul li a") $("table tr:nth-child(2n+1) td")
$("div#content p:first-child::first-line")
• CSS lookups are fast.
31. Attribute/Text match
• Can match on attribute values:
– //<div foo="bar">
– $("div", foo: "bar")
• The “text” attribute is special:
– //<div>foo</div>
– $("div", text: "foo")
• Can use Regular Expressions:
– //<div>foo</div>
– $("div", text: ~/f.+/)
33. Relative Content
• $() returns a Navigator that allows you to find
relative content.
$("p").previous()
$("p").prevAll()
$("p").next()
$("p").nextAll()
$("p").parent()
$("p").siblings()
$("div").children()
• Most of these methods take selectors, indexes
and attribute text/matchers too.
$("p").nextAll(".listing")
42. At Checking
• The “at checking” mechanism enables fail
fast and less debugging.
class LoginPage extends Page {
static at = { $("h1").text() == "Please log in" }
}
browser.at LoginPage
• Will throw an exception if every statement
of the at check is not true.
43. Driver Management
• Geb caches the WebDriver instance (per
thread) and shares it across test cases.
• Manages clearing cookies and is
configurable.
• This can be disabled and tuned.
44. Config. Management
• Looks for GebConfig class or GebConfig.groovy
file (or class) on classpath.
driver = {
new FirefoxDriver()
}
waiting {
timeout = 2
slow { timeout = 100 }
}
reportsDir = "geb-reports“
environments {
chrome { driver = "chrome" }
}
45. What we didn't see
• JavaScript interface
• jQuery interface
• Direct Downloading
• Multi Window support
• Frame support
• Page Change Listening
• Actions (e.g. Drag & Drop)
• alert()/confirm() handling