Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Taming your browser with Geb

Taming your browser with Geb

Talk at ApacheCon 2020

Sergio del Amo

September 30, 2020
Tweet

More Decks by Sergio del Amo

Other Decks in Programming

Transcript

  1. Taming your browser
    with Geb introduction

    View Slide

  2. Sergio del Amo


    OCI Grails Team


    https://sergiodelamo.com

    View Slide

  3. Geb Introduction

    View Slide

  4. 䡦 A Groovy layer on top of WebDriver


    䡦 WebDriver instance management


    䡦 Built-in configuration mechanism


    䡦 Page Object Pattern as first class citizen


    䡦 jQuery-like Navigator API


    䡦 Integrates with various test frameworks
    What is Geb?

    View Slide

  5. Geb is a Browser automation solution


    You can use it for:


    䡦 Acceptance Testing Web Applications


    䡦 Automating Web Sites


    䡦 Screen Scraping
    Totally Groovy Browser
    Automation

    View Slide

  6. 䡦 Cross browser automation capabilities of
    WebDriver


    䡦 Elegance of jQuery content selection


    䡦 Expressiveness of the Groovy language


    䡦 Robustness of Page Object modelling
    It brings together the…

    View Slide

  7. 䡦 Free Open Source, Apache License, v2.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
    About the Project

    View Slide

  8. Marcin Erdmann


    Geb project Lead


    http://blog.proxerd.pl

    View Slide

  9. The heart is the geb-core component which is all
    you really need (plus Web Driver).


    For testing, you probably also want one of these
    as well:


    䡦 geb-spock


    䡦 geb-junit3


    䡦 geb-junit4


    䡦 geb-testng


    䡦 geb-easyb
    Project Components

    View Slide

  10. 䡦 http://seleniumhq.org/projects/webdriver/


    䡦 Successor to the Selenium project


    䡦 Also known as “Selenium 2”.


    䡦 Sponsored and driven by Google.


    䡦 Becoming a standard.


    䡦 https://www.w3.org/TR/webdriver/
    WebDriver

    View Slide

  11. Java based, with many language bindings.
    Cross-browser automation

    View Slide

  12. 䡦 Geb sits on top of WebDriver so you rarely deal
    with its API, though it’s accessible if you need
    it.


    䡦 Geb never talks to the actual browser.


    䡦 That’s what WebDriver does.
    WebDriver API

    View Slide

  13. You need to pull in a specific driver
    implementation for each browser you want to
    work with.
    Driver dependency

    View Slide

  14. http://jquery.com jQuery - write more do less


    jQuery provides an incredibly powerful ApI for
    navigating and selecting content.


    CSS based, a whole lot better than XPath.
    jQuery

    View Slide

  15. Geb features a Navigator API that it is inspired by
    jQuery.


    API is not identical
    Geb’s inspiration

    View Slide

  16. 䡦 Compiled, never interpreted


    䡦 Dynamically, optionally typed


    䡦 99% Java syntax compatible


    䡦 Concise, clear and pragmattic


    䡦 Great for DSLs


    䡦 A comfortable Java alternative for most
    Groovy

    View Slide

  17. 䡦 http://groovy-lang.org


    䡦 You don’t need to be a Groovy ninja to use
    Geb.


    䡦 Groovy knowledge can defenitely help when
    things go wrong though.
    Required Apache Groovy
    Knowledge

    View Slide

  18. Geb uses Groovy’s dynamism to remove
    boilerplate.
    Geb & Groovy

    View Slide

  19. 䡦 The key to not pulling your hair out when
    dealing with web tests.


    䡦 In a phrase: Domain Modelling


    䡦 By modelling and creating abstractions, we
    can isolate implementation detail.
    Page Objects

    View Slide

  20. is more fragile than this…
    Page Objects

    View Slide

  21. 䡦 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.



    Just Good Programming

    View Slide

  22. The to() and click() methods are changing the
    underlying page.


    You can refer to the current page’s content and
    methods just by name.
    Browser has-a Page

    View Slide

  23. The Page Object Pattern allows us to apply the same principles of
    modularity, reuse and encapsulation that we use in other aspects of
    programming to avoid such issues in browser automation code
    Geb Pages

    View Slide

  24. View Slide

  25. View Slide

  26. View Slide

  27. View Slide

  28. Geb Pages

    View Slide

  29. Geb Modules

    View Slide

  30. View Slide

  31. View Slide

  32. Modules can be used for repeating content

    View Slide

  33. Modules
    Modules have a base, from which all content
    lookups are relative.

    View Slide

  34. We now have a model for a row in our table.


    Can be used for any reused/repeating content.


    Note: talking about domain objects, not HTML
    tables and rows.
    Modules

    View Slide

  35. Example - Pagination Module
    .PAGINATION
    .NAV-NEXT

    View Slide

  36. Example - Pagination Module

    View Slide

  37. Example - Pagination Module

    View Slide

  38. Example - Pagination Module

    View Slide

  39. Inheritance
    Pages (and modules) can be arranged in
    inheritance hierarchies.

    View Slide

  40. Geb's testing adapters. Geb can be used with…


    䡦 Spock


    䡦 Junit ( 3 & 4)


    䡦 TestNG


    䡦 EasyB


    䡦 Cucumber (Cuke4Duke)
    Testing

    View Slide

  41. Geb can dump HTML and screenshots for each
    “test” to help in debugging.


    Reports

    View Slide

  42. 䡦 jQuery inspired content selection/navigation


    䡦 The $() method


    䡦 Returns a Navigator Object


    䡦 General Format
    Navigator API

    View Slide

  43. 䡦 Returned from invocations of $() function


    䡦 Wrapper around DOM elements


    䡦 jQuery-like API


    䡦 Used for finding, filtering and interacting with
    DOM elements
    Navigator

    View Slide

  44. Examples

    View Slide

  45. Full CSS3 if the target browser supports it.


    CSS Lookups are fast
    CSS Selector

    View Slide

  46. Can match on attribute values:
    Attribute/Text matching

    View Slide

  47. The “text” attribute is special
    Attribute/Text matching

    View Slide

  48. Can use Regular Expressions:
    Attribute/Text matching

    View Slide

  49. Geb supplies some handy predicates:


    There are more of these.


    Predicates

    View Slide

  50. $() returns a Navigator that allows you to find
    relative content.


    Relative content

    View Slide

  51. Most of these methods take selectors, indexes
    and attribute text/matchers too.
    Relative Content
    $("p").nextAll(".listing")


    View Slide

  52. Content definitions can build upon each other.


    Content definitions are actually templates.


    Content DSL
    class GoogleResultsPage extends Page {


    static content = {


    results { $("li.g") }


    result { i -> results[i] }


    resultLink { i -> result(i).find("a.l", 0) }


    firstResultLink { resultLink(0) }


    }


    }

    View Slide

  53. By default, Geb will error if the content you select
    doesn't exist.


    The “`required`” option disables this check.


    Content definitions are actually templates.


    Optional Content
    class OptionalPage extends Page {


    static content = {


    errorMsg(required: false) { $("p.errorMsg") }


    }


    }

    View Slide

  54. Geb will wait for some time for this content to
    appear.


    Same semantics as the waitFor {} method that
    can be used anywhere.


    Content definitions are actually templates.


    Dynamic Content
    class DynamicPage extends Page {


    static content = {


    errorMsg(wait: true) { $("p.errorMsg") }


    }


    }

    View Slide

  55. Getting around. The to() method


    Pages can define a url that defines the page
    location.


    Navigation
    class MicronautHomePage extends Page {


    static url = “http://micronaut.io/index.html”


    }

    View Slide

  56. The to() method sends the browser there and sets
    that as the current page object.


    to MicronautHomePage


    The page url can be relative (will be resolved
    against a config driven base).


    There are advanced parameterisation options too.
    Navigation

    View Slide

  57. When this content is clicked, the underlying page
    will be changed implicitly.
    Content based navigation
    class FrontPage {


    static content = {


    aboutUsLink(to: AboutUsPage) {


    $("div#nav ul li a", text:
    iStartsWith("About Us"))


    }


    }


    }


    to FrontPage


    aboutUsLink.click()


    page instanceof AboutUsPage

    View Slide

  58. url = baseUrl + url + covertToPath
    Dynamic Url
    browser.baseUrl = 'http://localhost:8080'


    browser.to EditRoomPage, 1
    class EditRoomPage extends Page {


    static at = { title == 'Edit Room' }


    static url = '/room/edit'


    String convertToPath(Object[] args) {


    args ? "/${args[0]}" : ""


    }


    View Slide

  59. UI Interaction - Keyboard

    View Slide

  60. UI Interaction - Sliders

    View Slide

  61. 䡦 JavaScript interface


    䡦 jQuery interface


    䡦 Direct Downloading


    䡦 Multi Window support


    䡦 Frame support


    䡦 Page Change Listening


    䡦 Actions (e.g. Drag & Drop)


    䡦 alert()/confirm() handling
    䡦 Caching expensive
    content lookups


    䡦 Scripting style (sans
    Page Objects)


    䡦 Configuration &
    Environments
    WebDriver instance
    management
    More

    View Slide

  62. Example


    Hidden Content
    and Mouse over
    events

    View Slide

  63. View Slide

  64. View Slide

  65. Fails: Hidden Content

    View Slide

  66. Call a JS Method

    View Slide

  67. Move to Element

    View Slide

  68. Include Library

    View Slide

  69. geb-spock
    GebSpec
    Contains Specification subclasses which
    setup a Browser instance that all method
    calls and property accesses/references
    resolve against via Groovy’s methodMissing
    and propertyMissing mechanism.
    GebReportingSpec

    View Slide

  70. 䡦 BrowserStack


    䡦 Sauce Labs


    䡦 Xvfb
    Headless browser alternatives

    View Slide

  71. Sample App
    https://github.com/grails-samples/geb-example-grails

    View Slide

  72. Website testing
    https://github.com/micronaut-projects/static-website-test

    View Slide

  73. Q & A

    View Slide