Agent skill

Geb and Spock Browser Tests

by apache in apache/groovy-geb

Writes and reviews Geb browser automation specs with Spock, using Page Objects, at checkers, Modules and explicit waits, for Groovy and Gradle projects.

Apache-2.0Auto-check passedTesting & QA

Install Geb and Spock Browser Tests

skills CLI
$ npx skills add apache/groovy-geb --skill geb-spock -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install apache/groovy-geb geb-spock --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/apache/groovy-geb.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/geb-spock .claude/skills/geb-spock && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
geb-spock
GitHub stars
1.2k
Token cost
~2.4k tokens
SKILL.md length
712 words
Files
1
Skills in repo
1
Repo updated
First seen
Licence
Apache-2.0

At a glance

Writes and reviews Geb browser automation specs with Spock, using Page Objects, at checkers, Modules and explicit waits, for Groovy and Gradle projects.

  • Works in 8 steps: Always use Page Objects — never inline… → Use at checkers — every Page Object must… → Prefer CSS selectors over XPath; avoid… → …
  • Writing a new Geb spec for a web page
  • SKILL.md covers Core Principles, Spec File Structure, Page Object Structure and Module Structure, plus 4 more sections
  • Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md

What it does

Geb plus Spock specs are generated and reviewed against a fixed set of principles: always use Page Objects and never inline selectors, give every page a static at checker, prefer CSS selectors over XPath, and use waitFor explicitly instead of Thread.sleep, ideally inside methods on the page or module classes so the waiting knowledge is reusable.

Specs extend GebReportingSpec rather than GebSpec so screenshots are captured on failure, stay in given, when and then blocks with one behavior per feature method, and use Modules for repeated components such as navigation bars, modals and form rows. To avoid flaky tests, the skill suggests stress-testing a spec by adding network latency and re-running it many times locally. Templates show the spec, Page Object and Module structure, and the Geb manual is the reference for details.

When your agent uses it

  • Writing a new Geb spec for a web page
  • Reviewing Geb tests for brittle selectors or sleeps
  • Creating Page Objects and Modules in a Groovy project
  • Fixing a flaky Geb test

Example prompts

  • “Write a Geb spec for the login page using a Page Object.”
  • “Review this Geb test for brittle selectors and Thread.sleep calls.”
  • “Create a Module for the navigation bar and use it in the dashboard spec.”

Requirements

  • A Groovy project with Geb and Spock set up, such as through Gradle

Workflow steps

8 steps, taken from the first numbered list in SKILL.md.

  1. Always use Page Objects — never inline selectors in specs.
  2. Use at checkers — every Page Object must declare static at.
  3. Prefer CSS selectors over XPath; avoid brittle nth-child selectors.
  4. Use waitFor explicitly for dynamic content; never Thread.sleep.
  5. Use GebReportingSpec (not GebSpec) so screenshots are captured on failure.
  6. Keep specs in given/when/then blocks — one behaviour per feature method.
  7. Use Modules for repeated UI components (nav bars, modals, form rows).
  8. Avoid writing flaky tests by stress-testing your Geb spec before committing

What it can do on your machine

Read from SKILL.md and the folder at commit e433962. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md (its code samples are groovy).

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Links to these hosts (documentation or services it may open):

    • groovy.apache.org
    • spockframework.org

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Geb and Spock Browser Tests loads about 2.4k tokens when it runs. Until then it costs about 124 tokens; SKILL.md has 712 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~124
When it runs · the whole SKILL.md, loaded when a task matches
~2.4k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from apache/groovy-geb at commit e433962, republished under its Apache-2.0 licence (© apache). 712 words, ~2,363 tokens.

Download SKILL.mdSave it as .claude/skills/geb-spock/SKILL.md (or your agent's skills folder).
name
geb-spock
description
Write Geb browser automation tests using the Spock framework with best practices. Use this skill whenever the user asks to write, generate, fix, or review Geb test specs, mentions Geb, GebSpec, GebReportingSpec, or asks about browser automation with Groovy/Spock. Also trigger for requests involving Page Objects in a Groovy/Gradle project, `at` checkers, Geb content DSL, or `waitFor` usage. Even if the user just says "write me a Geb test" or "help me test this page", use this skill.
license
Apache-2.0
<!--
SPDX-License-Identifier: Apache-2.0

Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements; and to You under the Apache License, Version 2.0.
-->

Geb Testing Skill

Generates and reviews Geb + Spock browser automation specs following intermediate-level best practices.

Geb documentation is at https://groovy.apache.org/geb/manual/current/.

Core Principles

  1. Always use Page Objects — never inline selectors in specs.
  2. Use at checkers — every Page Object must declare static at.
  3. Prefer CSS selectors over XPath; avoid brittle nth-child selectors.
  4. Use waitFor explicitly for dynamic content; never Thread.sleep.
    1. Strongly prefer to put waitFor method calls into methods inside classes that extend geb.Page, geb.Module, or other shared test fixtures. If clicking or interacting with some object on a page requires waiting for some response, it's best to encapsulate that knowledge into a method on the pageObject (e.g. deleteTableRow or submitForm) that then waits for the signal that the operation is complete. That will make the knowledge of your page more reusable and avoid repeated waitFor.
  5. Use GebReportingSpec (not GebSpec) so screenshots are captured on failure.
  6. Keep specs in given/when/then blocks — one behaviour per feature method.
    1. Caveat: if a behaviour requires multiple steps, it's okay to have multiple when/then block pairs within one test method, so long as each intermediary step is integral to the journey under test.
  7. Use Modules for repeated UI components (nav bars, modals, form rows).
  8. Avoid writing flaky tests by stress-testing your Geb spec before committing:
    1. Try introducing network latency to verify that a test will pass on a slow network.
    2. Try re-running tests many times in succession locally to ensure they aren't flaky

Spec File Structure

groovy
package com.example.specs

import geb.spock.GebReportingSpec
import com.example.pages.LoginPage
import com.example.pages.DashboardPage
import spock.lang.Stepwise   // only when steps truly depend on each other

@Stepwise                    // omit if steps are independent
class LoginSpec extends GebReportingSpec {

    def "successful login redirects to dashboard"() {
        given: "user is on the login page"
        to LoginPage

        when: "valid credentials are submitted"
        loginForm.username = "user@example.com"
        loginForm.password = "secret"
        loginForm.submit()

        then: "the dashboard is displayed"
        at DashboardPage
        welcomeMessage.text() == "Welcome, user@example.com"
    }

    def "login fails with invalid credentials"() {
        given:
        to LoginPage

        when:
        loginForm.username = "bad@example.com"
        loginForm.password = "wrong"
        loginForm.submit()

        then:
        at LoginPage
        errorMessage.displayed
        errorMessage.text().contains("Invalid credentials")
    }
}

Page Object Structure

groovy
package com.example.pages

import geb.Page
import com.example.modules.LoginFormModule

class LoginPage extends Page {

    // `at` checker — verified when `to` or `at` is called
    static at = { title == "Login | MyApp" }

    // URL for `to LoginPage`
    static url = "/login"

    static content = {
        // Lazy by default; set required: false for optional elements
        loginForm    { module(LoginFormModule) }
        errorMessage(required: false) { $(".alert-error") }
    }
}
groovy
class DashboardPage extends Page {
    static at = { $("h1.dashboard-title").displayed }
    static url = "/dashboard"

    static content = {
        welcomeMessage { $(".welcome-msg") }
        navBar         { module(NavBarModule) }
    }
}

Module Structure

Use modules for components that repeat across pages (nav, modal, form row, table row).

groovy
package com.example.modules

import geb.Module

class LoginFormModule extends Module {

    static content = {
        username { $("input[name='username']") }
        password { $("input[name='password']") }
        submitBtn { $("button[type='submit']") }
    }

    void submit() {
        submitBtn.click()
    }
}

waitFor Patterns

groovy
// Wait for element to appear (default timeout from GebConfig)
waitFor { $(".spinner").not(".active") }

// Wait with custom timeout (seconds)
waitFor(10) { successBanner.displayed }

// Wait and return the element
def result = waitFor { $(".result-row") }

// Use in content DSL for elements that load dynamically
static content = {
    // Wait for this element every time it's accessed
    asyncTable(wait: true) { $("table.results") }
}

Never use Thread.sleep. If waitFor keeps timing out, make sure your assertion is actually eventually true (you may be relying on an unreliable side effect), ensure that your page is completing its work as quickly as it can, or increase the timeout in GebConfig.groovy rather than sleeping.


Selector Best Practices

✅ Prefer❌ Avoid
$("input[name='email']")$("div > div:nth-child(2) > input")
$(".submit-btn")$("button", text: "Submit") (fragile for i18n)
$("table.results tbody tr")XPath selectors
data-testid attributesPosition-based selectors

If the app doesn't have data-testid attrs, use stable semantic selectors: name, id, aria-label, role.


Common Patterns

Checking a list of items
groovy
def rows = 
rows.size() == 3
rows[0].find("td.name").text() == "Alice"
Filling a form
groovy
$("input[name='firstName']").value("Jane")
$("select[name='country']").value("US")
$("input[type='checkbox'][name='agree']").value(true)
Interacting with dropdowns (non-native)
groovy
// For custom JS dropdowns (not <select>)
$(".dropdown-trigger").click()
waitFor { $(".dropdown-menu").displayed }
$(".dropdown-menu li", text: "Option B").click()
Asserting navigation
groovy
// Checks URL and `at` checker
at ConfirmationPage
currentUrl.contains("/confirmation")

Show full SKILL.md (337 more words)Show less

Anti-Patterns to Avoid

  • @Stepwise overuse — only use when steps share state (e.g., a multi-step wizard). Independent scenarios should be separate specs or use setup()/cleanup().
  • Assertions inside when: blocks — lines after then: or expect: are automatically asserted - no need to even supply the assert keyword!
  • sleep() anywhere in test code.
  • Hard-coded absolute URLs — use relative paths; base URL lives in GebConfig.groovy.
  • Accessing the DOM directly in specs — all $() calls belong in Page Objects or Modules.
  • Overusing required: false on optional content - the only time you really want to mark a page element as required: false is when your spec needs to try to interact with it when it's absent (for example, to assert that it isn't present, !page.buttons.sometimesThereButton). If the button may or may not be there, but you never test the case where it isn't there, you should just leave it as required. Remember, throwing an exception when something exceptional happens is okay, especially in tests!
Avoiding creating flaky tests

Browser testing frameworks like Geb sometimes get a bad reputation for being flaky, but with some diligence you can keep your Geb tests more reliable!

Introduce Network latency

Adding even a small amount of network latency to your test can expose places where you probably want to add a waitFor statement to your page object. Drop some code like this in your test's setup() method and run it a few times to make sure it consistently works:

groovy
def networkLatency = java.time.Duration.ofMillis(500)
browser.networkLatency = networkLatency
Introduce reruns

While developing your tests, try doing a pass of re-running the test locally to make sure it consistently passes. If each of your tests only fails 1 time out of a hundred, but you have ten tests, your build pipelines are going to be flakier than your team can tolerate.

If you're using geb-spock, use the RepeatUntilFailure annotation with a maxAttempts value to run the test locally. You probably won't want to commit that annotation in most cases, but it's a good tool to verify your test is consistent before making it a blocker for someone else's PR.

© apache, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .agents/skills/geb-spock of apache/groovy-geb.

Open the folder on GitHubat commit e433962

Compare with similar skills

Geb and Spock Browser Tests next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Geb and Spock Browser Tests compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Geb and Spock Browser Tests this skillapache/groovy-geb1.2k—~2.4kAutomated safety check: PassApache-2.0
Web Application Testinganthropics/skills180k51 repos~966Automated safety check: PassApache-2.0
playwright-cli Browser Automationgithub/gh-aw5.4k24 repos~2.8kAutomated safety check: PassMIT
Write and Verify Playwright Testsappsmithorg/appsmith41k—~2.9kAutomated safety check: NotesApache-2.0
Cucumber and Playwright E2E Testslanggenius/dify158k—~682Automated safety check: PassCustom licence
E2E Testinglangflow-ai/langflow156k—~3.3kAutomated safety check: PassMIT

Similar skills

  • Web Application Testing

    anthropics/skills

    Official

    Tests local web applications with Python Playwright scripts, checking frontend behavior, capturing screenshots and reading browser console logs.

    180k GitHub starsUsed in 51 repos~966 tokens
    Testing & QAAuto-check passed
  • Official

    Drives a real browser from the command line with playwright-cli to open pages, interact, mock requests, save state and work with Playwright tests.

    5.4k GitHub starsUsed in 24 repos~2.8k tokens
    Testing & QAAuto-check passed
  • Writes a Playwright end-to-end test from a prompt, runs it against a live Appsmith deployment and retries with fixes up to three times until it passes.

    41k GitHub stars~2.9k tokensUpdated today
    Testing & QAAuto-check: notes
  • Guides changes and reviews of the Cucumber and Playwright end-to-end suite under `e2e/`: feature files, step definitions, support code, tags, locators and assertions.

    158k GitHub stars~682 tokensUpdated today
    Testing & QAAuto-check passed
  • E2E Testing

    langflow-ai/langflow

    Write and review Playwright E2E tests for Langflow. An agent skill from langflow-ai/langflow.

    156k GitHub stars~3.3k tokensUpdated today
    Testing & QAAuto-check passed
  • Handsontable Playwright E2E Tests

    handsontable/handsontable

    Guides writing and changing Playwright end-to-end tests for Handsontable using page objects, data-testid hooks and deterministic waits.

    22k GitHub stars~1.8k tokensUpdated today
    Testing & QAAuto-check passed

Works with

Categories

Questions about Geb and Spock Browser Tests

What does Geb and Spock Browser Tests do?

Writes and reviews Geb browser automation specs with Spock, using Page Objects, at checkers, Modules and explicit waits, for Groovy and Gradle projects. sleep, ideally inside methods on the page or module classes so the waiting knowledge is reusable.

When should I use Geb and Spock Browser Tests?

Geb and Spock Browser Tests fits situations like: writing a new Geb spec for a web page; reviewing Geb tests for brittle selectors or sleeps; creating Page Objects and Modules in a Groovy project; fixing a flaky Geb test.

How do I install Geb and Spock Browser Tests in Claude Code?

Run `npx skills add apache/groovy-geb --skill geb-spock -a claude-code`. Or copy the skill folder (.agents/skills/geb-spock in apache/groovy-geb) into .claude/skills/geb-spock in your project. Claude Code loads it when a task matches its description.

How do I install Geb and Spock Browser Tests in Codex?

Run `npx skills add apache/groovy-geb --skill geb-spock -a codex`. Or copy the skill folder (.agents/skills/geb-spock in apache/groovy-geb) into .agents/skills/geb-spock in your project. Codex loads it when a task matches its description.

Can I use Geb and Spock Browser Tests in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add apache/groovy-geb --skill geb-spock -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/geb-spock, .gemini/skills/geb-spock, .github/skills/geb-spock and .opencode/skills/geb-spock in your project.

What does Geb and Spock Browser Tests need to run?

SKILL.md names no scripts, command-line tools or credentials: Geb and Spock Browser Tests is instructions for the agent only. Our summary lists: A Groovy project with Geb and Spock set up, such as through Gradle.

Does Geb and Spock Browser Tests access the network?

SKILL.md names 2 domains. As links in the text: groovy.apache.org and spockframework.org. This is read from the text; nothing was executed.

Is Geb and Spock Browser Tests safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Geb and Spock Browser Tests use?

Geb and Spock Browser Tests is published under the Apache-2.0 licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Geb and Spock Browser Tests use?

About 2.4k tokens (SKILL.md is roughly 9.5k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Geb and Spock Browser Tests?

Skills that share tags, products or a category with Geb and Spock Browser Tests: Web Application Testing (anthropics/skills, 180k stars), playwright-cli Browser Automation (github/gh-aw, 5.4k stars), Write and Verify Playwright Tests (appsmithorg/appsmith, 41k stars) and Cucumber and Playwright E2E Tests (langgenius/dify, 158k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Geb and Spock Browser Tests?

apache (a GitHub organization) maintains it in apache/groovy-geb, which has 1,174 GitHub stars. The repository was last updated on October 7, 2026.

Source: apache/groovy-geb on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.