# SkillPatch skill: gauge-skill

This skill generates Gauge test specifications in Markdown format alongside step implementations in Java, Python, JavaScript, Ruby, and C#. It covers core Gauge patterns including spec files, concepts (reusable step groups), data-driven tables, cloud execution via LambdaTest, and CLI commands for setup and execution. It is designed for use with ThoughtWorks' Gauge BDD test automation framework.

You (the agent) were given this URL and asked to use this skill. This is a **public** skill — no SkillPatch account, API key, or prior setup is required. Two ways to use it:

**1. Use it right now** — the skill's complete file tree (SKILL.md + all reference files) is inlined below; read `SKILL.md` first, then follow it, consulting the other files as it directs.

**2. Install the exact package onto disk** (recommended if you can run a shell — this reproduces the skill byte-for-byte, including any binary assets that can't be inlined):

```bash
mkdir -p .claude/skills/gauge-skill
curl -sSL https://skillpatch.dev/install_skill/gauge-skill | tar -xz -C .claude/skills/
```

(`.claude/skills/` is Claude Code's convention; use whatever directory your agent loads skills from.)


---

## Skill files (3)

- `SKILL.md`
- `reference/advanced-patterns.md`
- `reference/playbook.md`


### `SKILL.md`

````markdown
---
name: gauge-skill
description: >
  Generates Gauge test specifications in Markdown with step implementations
  in Java, Python, JS, or Ruby. ThoughtWorks' test automation framework.
  Use when user mentions "Gauge", "spec file", "## Scenario", "step
  implementation". Triggers on: "Gauge", "Gauge spec", "Gauge framework",
  "ThoughtWorks test".
languages:
  - Java
  - Python
  - JavaScript
  - Ruby
  - C#
category: bdd-testing
license: MIT
metadata:
  author: TestMu AI
  version: "1.0"
---

# Gauge Automation Skill

## Core Patterns

### Specification (specs/login.spec)

```markdown
# Login Feature

## Successful Login
* Navigate to login page
* Enter email "user@test.com"
* Enter password "password123"
* Click login button
* Verify dashboard is displayed
* Verify welcome message contains "Welcome"

## Invalid Credentials
* Navigate to login page
* Enter email "wrong@test.com"
* Enter password "wrong"
* Click login button
* Verify error message "Invalid credentials" is shown

## Login with multiple users
|email             |password |expected  |
|-----------------|---------|----------|
|admin@test.com   |admin123 |Dashboard |
|user@test.com    |pass123  |Dashboard |
|bad@test.com     |wrong    |Error     |

* Login as <email> with <password>
* Verify <expected> page is shown
```

### Step Implementation — Java

```java
import com.thoughtworks.gauge.Step;
import com.thoughtworks.gauge.Table;

public class LoginSteps {
    WebDriver driver;

    @Step("Navigate to login page")
    public void navigateToLogin() {
        driver.get("http://localhost:3000/login");
    }

    @Step("Enter email <email>")
    public void enterEmail(String email) {
        driver.findElement(By.id("email")).sendKeys(email);
    }

    @Step("Enter password <password>")
    public void enterPassword(String password) {
        driver.findElement(By.id("password")).sendKeys(password);
    }

    @Step("Click login button")
    public void clickLogin() {
        driver.findElement(By.cssSelector("button[type='submit']")).click();
    }

    @Step("Verify dashboard is displayed")
    public void verifyDashboard() {
        assertTrue(driver.getCurrentUrl().contains("/dashboard"));
    }
}
```

### Step Implementation — Python

```python
from getgauge.python import step
from selenium import webdriver

@step("Navigate to login page")
def navigate_to_login():
    driver.get("http://localhost:3000/login")

@step("Enter email <email>")
def enter_email(email):
    driver.find_element_by_id("email").send_keys(email)

@step("Click login button")
def click_login():
    driver.find_element_by_css_selector("button[type='submit']").click()
```

### Concepts (Reusable Step Groups — specs/concepts/login.cpt)

```markdown
# Login as <email> with <password>
* Navigate to login page
* Enter email <email>
* Enter password <password>
* Click login button
```

## Setup: `gauge install java` (or `python`, `js`, `ruby`)
## Init: `gauge init java`
## Run: `gauge run specs/` or `gauge run specs/login.spec`

### Cloud Execution on TestMu AI

Set environment variables: `LT_USERNAME`, `LT_ACCESS_KEY`

```java
// StepImplementation.java
ChromeOptions browserOptions = new ChromeOptions();
HashMap<String, Object> ltOptions = new HashMap<>();
ltOptions.put("user", System.getenv("LT_USERNAME"));
ltOptions.put("accessKey", System.getenv("LT_ACCESS_KEY"));
ltOptions.put("build", "Gauge Build");
ltOptions.put("platformName", "Windows 11");
ltOptions.put("video", true);
ltOptions.put("console", true);
browserOptions.setCapability("LT:Options", ltOptions);
Driver.setWebDriver(new RemoteWebDriver(
    new URL("https://hub.lambdatest.com/wd/hub"), browserOptions));
```
## Tags: `gauge run --tags "smoke"` (use `Tags: smoke` in spec)

## Deep Patterns

See `reference/playbook.md` for production-grade patterns:

| Section | What You Get |
|---------|-------------|
| §1 Project Setup | Installation, project structure, environment properties |
| §2 Spec Files | Markdown scenarios, data tables, concepts (.cpt) |
| §3 Step Implementations | Java steps, table-driven steps, assertions |
| §4 Hooks & Execution | BeforeSuite/Scenario/Step, screenshots, browser logs |
| §5 Page Objects | BasePage, concrete pages, usage in steps |
| §6 Data Management | ScenarioDataStore, SpecDataStore, CSV data |
| §7 LambdaTest Integration | Remote driver factory with LT:Options |
| §8 CI/CD Integration | GitHub Actions with parallel execution, XML reports |
| §9 Debugging Table | 12 common problems with causes and fixes |
| §10 Best Practices | 14-item Gauge testing checklist |

````


### `reference/advanced-patterns.md`

````markdown
# Gauge — Advanced Patterns & Playbook

## Data-Driven Specs

```markdown
# User Registration

|name   |email            |expected|
|-------|-----------------|--------|
|Alice  |alice@test.com   |success |
|       |invalid          |error   |
|Bob    |bob@existing.com |error   |

## Register user with <name> and <email>
* Navigate to registration page
* Enter name <name> and email <email>
* Submit registration
* Verify result is <expected>
```

## Step Implementation with Hooks

```java
public class RegistrationSteps {
    private WebDriver driver;

    @BeforeScenario
    public void setup() {
        driver = new ChromeDriver();
    }

    @AfterScenario
    public void teardown() {
        if (driver != null) driver.quit();
    }

    @Step("Navigate to registration page")
    public void navigateToRegistration() {
        driver.get(System.getenv("APP_URL") + "/register");
    }

    @Step("Enter name <name> and email <email>")
    public void enterDetails(String name, String email) {
        driver.findElement(By.id("name")).sendKeys(name);
        driver.findElement(By.id("email")).sendKeys(email);
    }

    @Step("Submit registration")
    public void submit() {
        driver.findElement(By.id("submit")).click();
    }

    @Step("Verify result is <expected>")
    public void verify(String expected) {
        if ("success".equals(expected)) {
            assertTrue(driver.findElement(By.css(".success")).isDisplayed());
        } else {
            assertTrue(driver.findElement(By.css(".error")).isDisplayed());
        }
    }
}
```

## Concepts (Reusable Step Groups)

```markdown
# Login as <role>
* Navigate to login page
* Enter credentials for <role>
* Click login button
* Verify dashboard is visible
```

## Custom Report Plugin

```java
// Implement GaugeListener
public class CustomReporter implements GaugeListener {
    @Override
    public void scenarioEnd(ScenarioInfo info) {
        logger.info("Scenario: {} - {}", info.getName(),
            info.isFailing() ? "FAIL" : "PASS");
    }
}
```

## Anti-Patterns

- ❌ Steps with UI details in spec files — specs should be business-readable
- ❌ Duplicate step implementations — use Concepts for reuse
- ❌ Hardcoded data in steps — use table-driven specs or env variables
- ❌ Missing `@AfterScenario` cleanup — browser/state leaks

````


### `reference/playbook.md`

````markdown
# Gauge — Advanced Playbook

## §1 — Project Setup

### Installation
```bash
# Install Gauge
curl -SsL https://downloads.gauge.org/stable | sh
# Or via npm
npm install -g @getgauge/cli

# Install language runners
gauge install java   # Java runner
gauge install js     # JavaScript runner
gauge install python # Python runner

# Install plugins
gauge install html-report
gauge install xml-report
gauge install screenshot

# Initialize project (Java)
gauge init java
```

### Project Structure
```
project/
├── specs/
│   ├── login.spec
│   ├── checkout.spec
│   └── concepts/
│       └── login_actions.cpt
├── src/test/java/
│   ├── steps/
│   │   ├── LoginSteps.java
│   │   ├── CheckoutSteps.java
│   │   └── CommonSteps.java
│   ├── pages/
│   │   ├── BasePage.java
│   │   ├── LoginPage.java
│   │   └── DashboardPage.java
│   └── utils/
│       ├── DriverFactory.java
│       └── TestDataManager.java
├── env/
│   ├── default/
│   │   └── default.properties
│   └── staging/
│       └── staging.properties
├── resources/
│   └── testdata/
│       └── users.csv
└── manifest.json
```

### Environment Configuration
```properties
# env/default/default.properties
base_url = http://localhost:3000
browser = chrome
headless = false
screenshot_on_failure = true
gauge_clear_state_level = scenario
# Parallel execution
gauge_parallel_streams = 4

# env/staging/staging.properties
base_url = https://staging.example.com
headless = true
```

---

## §2 — Spec Files (Markdown Scenarios)

### Basic Spec
```markdown
# User Authentication

Tags: auth, smoke

## Successful login with valid credentials
Tags: positive

* Navigate to "/login"
* Enter "user@test.com" in "email" field
* Enter "SecurePass123" in "password" field
* Click "Sign In" button
* Verify user is on "/dashboard"
* Verify page contains "Welcome back"

## Login fails with invalid password
Tags: negative

* Navigate to "/login"
* Enter "user@test.com" in "email" field
* Enter "wrongpassword" in "password" field
* Click "Sign In" button
* Verify error message "Invalid email or password"
```

### Data-Driven Specs (Table Parameters)
```markdown
# Product Search

## Search returns matching results

* Search for products with criteria

  |category |min_price |max_price |expected_count |
  |---------|----------|----------|---------------|
  |laptops  |500       |1500      |12             |
  |phones   |200       |800       |25             |
  |tablets  |150       |600       |8              |

## User registration with multiple roles

* Register user with role <role> and verify access to <section>

  |role    |section          |
  |--------|-----------------|
  |admin   |/admin/dashboard |
  |editor  |/content/manage  |
  |viewer  |/reports/view    |
```

### Concepts (Reusable Step Groups)
```markdown
# concepts/login_actions.cpt

# Log in as user <email> with password <password>
* Navigate to "/login"
* Enter <email> in "email" field
* Enter <password> in "password" field
* Click "Sign In" button
* Wait for page load

# Add product <n> to cart with quantity <qty>
* Search for product <n>
* Click first search result
* Set quantity to <qty>
* Click "Add to Cart" button
* Verify cart badge shows <qty>
```

### Using Concepts in Specs
```markdown
# Checkout Flow

## Complete purchase as registered user

* Log in as user "buyer@test.com" with password "pass123"
* Add product "Wireless Mouse" to cart with quantity "2"
* Navigate to "/cart"
* Click "Proceed to Checkout"
* Enter shipping address
* Select "Credit Card" payment method
* Confirm order
* Verify order confirmation displayed
```

---

## §3 — Step Implementations (Java)

### Basic Steps
```java
import com.thoughtworks.gauge.Step;
import com.thoughtworks.gauge.Table;
import com.thoughtworks.gauge.TableRow;
import org.openqa.selenium.*;
import org.openqa.selenium.support.ui.*;

public class CommonSteps {

    private WebDriver driver;
    private WebDriverWait wait;

    public CommonSteps() {
        driver = DriverFactory.getDriver();
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Step("Navigate to <url>")
    public void navigateTo(String url) {
        String baseUrl = System.getenv("base_url");
        driver.get(baseUrl + url);
    }

    @Step("Enter <value> in <field> field")
    public void enterText(String value, String field) {
        WebElement element = wait.until(
            ExpectedConditions.visibilityOfElementLocated(
                By.cssSelector("[data-testid='" + field + "']")
            )
        );
        element.clear();
        element.sendKeys(value);
    }

    @Step("Click <buttonText> button")
    public void clickButton(String buttonText) {
        wait.until(ExpectedConditions.elementToBeClickable(
            By.xpath("//button[normalize-space()='" + buttonText + "']")
        )).click();
    }

    @Step("Verify user is on <path>")
    public void verifyPath(String path) {
        wait.until(ExpectedConditions.urlContains(path));
        assertTrue(driver.getCurrentUrl().contains(path));
    }

    @Step("Verify page contains <text>")
    public void verifyText(String text) {
        wait.until(ExpectedConditions.textToBePresentInElementLocated(
            By.tagName("body"), text
        ));
    }

    @Step("Verify error message <message>")
    public void verifyError(String message) {
        WebElement alert = wait.until(
            ExpectedConditions.visibilityOfElementLocated(
                By.cssSelector("[role='alert'], .error-message")
            )
        );
        assertEquals(message, alert.getText());
    }
}
```

### Table-Driven Steps
```java
import com.thoughtworks.gauge.Step;
import com.thoughtworks.gauge.Table;
import com.thoughtworks.gauge.TableRow;

public class SearchSteps {

    @Step("Search for products with criteria <table>")
    public void searchWithCriteria(Table table) {
        for (TableRow row : table.getTableRows()) {
            String category = row.getCell("category");
            String minPrice = row.getCell("min_price");
            String maxPrice = row.getCell("max_price");
            int expectedCount = Integer.parseInt(row.getCell("expected_count"));

            navigateTo("/products?category=" + category);
            applyPriceFilter(minPrice, maxPrice);

            int actual = getResultCount();
            assertTrue(
                "Expected " + expectedCount + " for " + category + ", got " + actual,
                actual >= expectedCount
            );
        }
    }

    @Step("Register user with role <role> and verify access to <section>")
    public void registerWithRole(String role, String section) {
        String email = "test_" + role + "_" + System.currentTimeMillis() + "@test.com";
        registerUser(email, role);
        loginAs(email);
        navigateTo(section);
        verifyPageLoaded(section);
    }
}
```

---

## §4 — Hooks & Execution Control

### Execution Hooks
```java
import com.thoughtworks.gauge.*;

public class ExecutionHooks {

    @BeforeSuite
    public void setupSuite() {
        TestDataManager.seedDatabase();
        System.out.println("Suite started: " + java.time.LocalDateTime.now());
    }

    @AfterSuite
    public void teardownSuite() {
        TestDataManager.cleanDatabase();
        DriverFactory.quitAllDrivers();
    }

    @BeforeScenario
    public void setupScenario(ExecutionContext context) {
        DriverFactory.createDriver();
        System.out.println("Running: " + context.getCurrentScenario().getName());
    }

    @AfterScenario
    public void teardownScenario(ExecutionContext context) {
        if (context.getCurrentScenario().getIsFailing()) {
            captureScreenshot(context.getCurrentScenario().getName());
            capturePageSource(context.getCurrentScenario().getName());
            captureBrowserLogs();
        }
        DriverFactory.quitDriver();
    }

    @BeforeStep
    public void beforeStep(ExecutionContext context) {
        // Log step for debugging
    }

    @AfterStep
    public void afterStep(ExecutionContext context) {
        if (context.getCurrentStep().getIsFailing()) {
            Gauge.writeMessage("Step failed: " + context.getCurrentStep().getText());
        }
    }

    private void captureScreenshot(String scenarioName) {
        try {
            TakesScreenshot ts = (TakesScreenshot) DriverFactory.getDriver();
            byte[] screenshot = ts.getScreenshotAs(OutputType.BYTES);
            Gauge.captureScreenshot(); // Attaches to report
        } catch (Exception e) {
            Gauge.writeMessage("Screenshot capture failed: " + e.getMessage());
        }
    }

    private void captureBrowserLogs() {
        try {
            LogEntries logs = DriverFactory.getDriver()
                .manage().logs().get(LogType.BROWSER);
            for (LogEntry entry : logs) {
                Gauge.writeMessage("[BROWSER] " + entry.getMessage());
            }
        } catch (Exception e) {
            // Browser log capture not supported
        }
    }
}
```

---

## §5 — Page Object Pattern

### Base Page
```java
public abstract class BasePage {
    protected WebDriver driver;
    protected WebDriverWait wait;

    public BasePage() {
        this.driver = DriverFactory.getDriver();
        this.wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    protected WebElement find(By locator) {
        return wait.until(ExpectedConditions.visibilityOfElementLocated(locator));
    }

    protected void click(By locator) {
        wait.until(ExpectedConditions.elementToBeClickable(locator)).click();
    }

    protected void type(By locator, String text) {
        WebElement el = find(locator);
        el.clear();
        el.sendKeys(text);
    }

    protected void selectByText(By locator, String visibleText) {
        new Select(find(locator)).selectByVisibleText(visibleText);
    }

    protected boolean isVisible(By locator) {
        try {
            return find(locator).isDisplayed();
        } catch (TimeoutException e) {
            return false;
        }
    }

    protected void waitForUrl(String partialUrl) {
        wait.until(ExpectedConditions.urlContains(partialUrl));
    }
}
```

### Concrete Page Objects
```java
public class LoginPage extends BasePage {
    private final By emailInput = By.cssSelector("[data-testid='email']");
    private final By passwordInput = By.cssSelector("[data-testid='password']");
    private final By submitBtn = By.cssSelector("[data-testid='login-submit']");
    private final By errorMsg = By.cssSelector("[role='alert']");

    public LoginPage open() {
        driver.get(System.getenv("base_url") + "/login");
        return this;
    }

    public DashboardPage loginAs(String email, String password) {
        type(emailInput, email);
        type(passwordInput, password);
        click(submitBtn);
        return new DashboardPage();
    }

    public String getErrorMessage() {
        return find(errorMsg).getText();
    }
}

public class DashboardPage extends BasePage {
    private final By welcomeText = By.cssSelector("[data-testid='welcome']");
    private final By navMenu = By.cssSelector("[data-testid='nav-menu']");

    public DashboardPage verifyLoaded() {
        waitForUrl("/dashboard");
        find(welcomeText);
        return this;
    }

    public String getWelcomeMessage() {
        return find(welcomeText).getText();
    }

    public void navigateTo(String menuItem) {
        click(navMenu);
        click(By.linkText(menuItem));
    }
}
```

### Using Page Objects in Steps
```java
public class LoginSteps {
    private LoginPage loginPage = new LoginPage();
    private DashboardPage dashboardPage;

    @Step("Open login page")
    public void openLogin() {
        loginPage.open();
    }

    @Step("Log in as <email> with password <password>")
    public void login(String email, String password) {
        dashboardPage = loginPage.open().loginAs(email, password);
    }

    @Step("Verify dashboard welcome message contains <text>")
    public void verifyWelcome(String text) {
        dashboardPage.verifyLoaded();
        assertTrue(dashboardPage.getWelcomeMessage().contains(text));
    }
}
```

---

## §6 — Data Management & Custom Data Stores

### Data Store (Scenario/Spec/Suite Level)
```java
import com.thoughtworks.gauge.datastore.*;

public class DataStoreSteps {

    @Step("Create user and store details")
    public void createAndStoreUser() {
        String email = "user_" + System.currentTimeMillis() + "@test.com";
        String userId = UserApi.createUser(email, "Test User");

        // Available for current scenario only
        ScenarioDataStore.put("userEmail", email);
        ScenarioDataStore.put("userId", userId);
    }

    @Step("Verify created user is displayed")
    public void verifyUser() {
        String email = (String) ScenarioDataStore.get("userEmail");
        verifyText(email);
    }

    @Step("Set up shared test data for spec")
    public void specLevelData() {
        // Available across all scenarios in one spec
        SpecDataStore.put("apiToken", AuthHelper.getAdminToken());
    }

    @Step("Initialize suite-level config")
    public void suiteLevelData() {
        // Available for entire suite
        SuiteDataStore.put("environment", System.getenv("GAUGE_ENV"));
    }
}
```

### CSV Data Files
```java
@Step("Load users from CSV and verify accounts")
public void loadFromCsv() throws Exception {
    try (CSVReader reader = new CSVReader(
            new FileReader("resources/testdata/users.csv"))) {
        String[] headers = reader.readNext();
        String[] line;
        while ((line = reader.readNext()) != null) {
            String email = line[0];
            String role = line[1];
            verifyUserAccount(email, role);
        }
    }
}
```

---

## §7 — LambdaTest Integration

### Driver Factory with LambdaTest
```java
public class DriverFactory {
    private static ThreadLocal<WebDriver> drivers = new ThreadLocal<>();

    public static WebDriver createDriver() {
        String browser = System.getenv("browser");
        boolean isCloud = "true".equals(System.getenv("use_lambdatest"));

        WebDriver driver;
        if (isCloud) {
            driver = createLambdaTestDriver();
        } else {
            driver = createLocalDriver(browser);
        }
        drivers.set(driver);
        return driver;
    }

    private static WebDriver createLambdaTestDriver() {
        String username = System.getenv("LT_USERNAME");
        String accessKey = System.getenv("LT_ACCESS_KEY");

        ChromeOptions options = new ChromeOptions();
        options.setPlatformName("Windows 11");
        options.setBrowserVersion("latest");

        HashMap<String, Object> ltOptions = new HashMap<>();
        ltOptions.put("project", "Gauge Tests");
        ltOptions.put("build", "gauge-" + System.getenv("BUILD_NUMBER"));
        ltOptions.put("name", Thread.currentThread().getName());
        ltOptions.put("console", true);
        ltOptions.put("network", true);
        ltOptions.put("visual", true);
        ltOptions.put("w3c", true);
        options.setCapability("LT:Options", ltOptions);

        try {
            return new RemoteWebDriver(
                new URL("https://" + username + ":" + accessKey +
                    "@hub.lambdatest.com/wd/hub"),
                options
            );
        } catch (MalformedURLException e) {
            throw new RuntimeException("Invalid LambdaTest hub URL", e);
        }
    }

    private static WebDriver createLocalDriver(String browser) {
        return switch (browser != null ? browser : "chrome") {
            case "firefox" -> new FirefoxDriver();
            case "edge" -> new EdgeDriver();
            default -> {
                ChromeOptions opts = new ChromeOptions();
                if ("true".equals(System.getenv("headless"))) {
                    opts.addArguments("--headless=new");
                }
                yield new ChromeDriver(opts);
            }
        };
    }

    public static WebDriver getDriver() {
        return drivers.get();
    }

    public static void quitDriver() {
        WebDriver driver = drivers.get();
        if (driver != null) {
            driver.quit();
            drivers.remove();
        }
    }
}
```

### LambdaTest Environment Properties
```properties
# env/lambdatest/lambdatest.properties
use_lambdatest = true
browser = chrome
headless = false
LT_USERNAME = ${LT_USERNAME}
LT_ACCESS_KEY = ${LT_ACCESS_KEY}
```

---

## §8 — CI/CD Integration

### GitHub Actions
```yaml
name: Gauge Tests
on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

jobs:
  gauge-tests:
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:15
        env:
          POSTGRES_DB: testdb
          POSTGRES_PASSWORD: postgres
        ports: ['5432:5432']
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5

    steps:
      - uses: actions/checkout@v4

      - name: Set up JDK
        uses: actions/setup-java@v4
        with:
          distribution: temurin
          java-version: '17'

      - name: Install Gauge
        uses: getgauge/setup-gauge@master
        with:
          gauge-version: master
          gauge-plugins: java, html-report, xml-report

      - name: Run Gauge specs
        run: gauge run specs/ --env ci
        env:
          base_url: http://localhost:3000
          headless: true
          GAUGE_PARALLEL_STREAMS: 4

      - name: Upload reports
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: gauge-reports
          path: |
            reports/html-report/
            reports/xml-report/

      - name: Publish test results
        if: always()
        uses: dorny/test-reporter@v1
        with:
          name: Gauge Results
          path: reports/xml-report/*.xml
          reporter: java-junit
```

### Running with Tags
```bash
# Run smoke tests only
gauge run specs/ --tags "smoke"

# Run auth tests except negative
gauge run specs/ --tags "auth & !negative"

# Run in parallel
gauge run specs/ --parallel -n 4

# Run specific spec
gauge run specs/login.spec

# Run with specific environment
gauge run specs/ --env staging

# Run with verbose output
gauge run specs/ --verbose
```

---

## §9 — Debugging Table

| # | Problem | Cause | Fix |
|---|---------|-------|-----|
| 1 | `Step implementation not found` | Step text in spec doesn't match `@Step` annotation exactly | Compare spec step text character-by-character with annotation; check parameter placeholders `<param>` match |
| 2 | `Could not get a driver` | DriverFactory not returning ThreadLocal driver | Ensure `createDriver()` is called in `@BeforeScenario`; check `drivers.set(driver)` is called |
| 3 | `Scenario data store returns null` | Storing in one step, reading in different scenario | Use `ScenarioDataStore` only within same scenario; use `SpecDataStore` for cross-scenario sharing |
| 4 | Concept step not resolved | Concept file has wrong extension or location | Concepts must be `.cpt` files in `specs/` or `concepts/` directory; verify Markdown heading format |
| 5 | Parallel tests interfere with each other | Shared mutable state between threads | Use `ThreadLocal` for all driver/state references; isolate test data per thread with timestamps |
| 6 | Table parameters not passed to step | Step signature doesn't accept `Table` type | Add `com.thoughtworks.gauge.Table` as last parameter in step method |
| 7 | Tags filter not working | Wrong tag operator syntax | Use `&` for AND, `|` for OR; quote complex expressions: `--tags "smoke & !slow"` |
| 8 |
...<truncated>
````
