$npx -y skills add LambdaTest/agent-skills --skill geb-skillGenerates Geb browser automation tests in Groovy with Spock integration. jQuery-like content DSL and page object pattern. Use when user mentions "Geb", "Groovy test", "GebSpec", "Browser.drive". Triggers on: "Geb", "GebSpec", "Groovy browser test", "Browser.drive".
| 1 | # Geb Automation Skill |
| 2 | |
| 3 | For TestMu AI cloud execution, see [reference/cloud-integration.md](reference/cloud-integration.md) and [shared/testmu-cloud-reference.md](../shared/testmu-cloud-reference.md). |
| 4 | |
| 5 | ## Core Patterns |
| 6 | |
| 7 | ### Basic Test (Spock) |
| 8 | |
| 9 | ```groovy |
| 10 | import geb.spock.GebSpec |
| 11 | |
| 12 | class LoginSpec extends GebSpec { |
| 13 | def "login with valid credentials"() { |
| 14 | when: |
| 15 | to LoginPage |
| 16 | emailInput.value("user@test.com") |
| 17 | passwordInput.value("password123") |
| 18 | loginButton.click() |
| 19 | |
| 20 | then: |
| 21 | at DashboardPage |
| 22 | welcomeMessage.text().contains("Welcome") |
| 23 | } |
| 24 | |
| 25 | def "login shows error for invalid credentials"() { |
| 26 | when: |
| 27 | to LoginPage |
| 28 | emailInput.value("wrong@test.com") |
| 29 | passwordInput.value("wrong") |
| 30 | loginButton.click() |
| 31 | |
| 32 | then: |
| 33 | at LoginPage |
| 34 | errorMessage.displayed |
| 35 | errorMessage.text().contains("Invalid") |
| 36 | } |
| 37 | } |
| 38 | ``` |
| 39 | |
| 40 | ### Page Objects |
| 41 | |
| 42 | ```groovy |
| 43 | class LoginPage extends geb.Page { |
| 44 | static url = "/login" |
| 45 | static at = { title == "Login" } |
| 46 | static content = { |
| 47 | emailInput { $("#email") } |
| 48 | passwordInput { $("#password") } |
| 49 | loginButton { $("button[type='submit']") } |
| 50 | errorMessage(required: false) { $(".error") } |
| 51 | } |
| 52 | } |
| 53 | |
| 54 | class DashboardPage extends geb.Page { |
| 55 | static url = "/dashboard" |
| 56 | static at = { $(".dashboard").displayed } |
| 57 | static content = { |
| 58 | welcomeMessage { $(".welcome") } |
| 59 | userName { $(".user-name") } |
| 60 | } |
| 61 | } |
| 62 | ``` |
| 63 | |
| 64 | ### Navigator API |
| 65 | |
| 66 | ```groovy |
| 67 | $("css-selector") |
| 68 | $("div", class: "active") |
| 69 | $("input", name: "email") |
| 70 | $("div.items li", 0) // First match |
| 71 | $("div.items li").size() // Count |
| 72 | |
| 73 | // Actions |
| 74 | element.click() |
| 75 | element.value("text") |
| 76 | element << "text" // Append text |
| 77 | element.text() |
| 78 | element.displayed |
| 79 | element.@href // Attribute |
| 80 | ``` |
| 81 | |
| 82 | ### Cloud: `driver = new RemoteWebDriver(new URL(gridUrl), caps)` |
| 83 | |
| 84 | ## Setup: Gradle with `geb-spock` and `selenium-support` dependencies |
| 85 | |
| 86 | ### Cloud Execution on TestMu AI |
| 87 | |
| 88 | Set environment variables: `LT_USERNAME`, `LT_ACCESS_KEY` |
| 89 | |
| 90 | ```groovy |
| 91 | // GebConfig.groovy |
| 92 | environments { |
| 93 | lambdatest { |
| 94 | driver = { |
| 95 | def ltOptions = [ |
| 96 | user: System.getenv("LT_USERNAME"), |
| 97 | accessKey: System.getenv("LT_ACCESS_KEY"), |
| 98 | build: "Geb Build", |
| 99 | name: "Geb Test", |
| 100 | platformName: "Windows 11", |
| 101 | video: true, |
| 102 | console: true, |
| 103 | network: true, |
| 104 | ] |
| 105 | def caps = new ChromeOptions() |
| 106 | caps.setCapability("LT:Options", ltOptions) |
| 107 | new RemoteWebDriver( |
| 108 | new URL("https://hub.lambdatest.com/wd/hub"), caps) |
| 109 | } |
| 110 | } |
| 111 | } |
| 112 | ``` |
| 113 | |
| 114 | Run: `./gradlew test -Dgeb.env=lambdatest` |
| 115 | ## Run: `./gradlew test` |
| 116 | |
| 117 | ## Deep Patterns |
| 118 | |
| 119 | See `reference/playbook.md` for production-grade patterns: |
| 120 | |
| 121 | | Section | What You Get | |
| 122 | |---------|-------------| |
| 123 | | §1 Project Setup | build.gradle, GebConfig.groovy, environments, waiting config | |
| 124 | | §2 Page Objects | Content DSL, at checks, modules for reusable components | |
| 125 | | §3 Spec Tests | Spock integration, data-driven with @Unroll, @Stepwise flows | |
| 126 | | §4 Waiting & Async | Waiting presets, JavaScript interaction, alerts/confirms | |
| 127 | | §5 Advanced Patterns | File upload/download, windows, frames, custom extensions | |
| 128 | | §6 API Testing | REST API specs with Groovy JsonSlurper | |
| 129 | | §7 CI/CD Integration | GitHub Actions with headless Chrome, Gradle caching | |
| 130 | | §8 Debugging Table | 12 common problems with causes and fixes | |
| 131 | | §9 Best Practices | 14-item Geb testing checklist | |