Skip to main content
Glama
felipeassis10

bdd-regression-test-generator

README.md
# bdd-regression-test-generator

An autonomous agent that analyzes REST API endpoints and OpenAPI/Swagger service contracts to generate:

- **BDD Gherkin specifications** (`.feature` files) describing all happy-path and edge-case scenarios.
- **TypeScript regression test scripts** (Jest + Playwright-ready) ready to run against real services.

It exposes two interfaces:

| Interface | Description |
|-----------|-------------|
| **CLI** | `bdd-gen generate --input <spec> --output <dir>` |
| **MCP Server** | Model Context Protocol server exposable to any MCP-aware host (e.g. IBM Bob, Claude Desktop) |

---

## Features

- Parses OpenAPI 3.x and Swagger 2.0 contracts (JSON or YAML).
- Extracts all paths, HTTP methods, parameters, request bodies, and response schemas.
- Generates one `.feature` file per endpoint tag group.
- Generates one `*.spec.ts` file per endpoint tag group with fully typed Jest test cases.
- Supports custom base-URL injection at generation time.
- MCP server exposes `analyze_contract`, `generate_gherkin`, and `generate_tests` tools.

---

## Installation

```bash
npm install
npm run build
```

To use as a global CLI after building:

```bash
npm link
```

---

## CLI Usage

```bash
# Generate both Gherkin and Jest tests from an OpenAPI YAML spec
bdd-gen generate --input ./petstore.yaml --output ./generated --baseUrl https://api.example.com

# Generate only Gherkin feature files
bdd-gen generate --input ./petstore.json --output ./generated --only gherkin

# Generate only Jest test scripts
bdd-gen generate --input ./petstore.json --output ./generated --only jest

# Analyze a contract and print a summary (no file generation)
bdd-gen analyze --input ./petstore.yaml
```

### CLI Options

| Option | Alias | Description | Default |
|--------|-------|-------------|---------|
| `--input <path>` | `-i` | Path to the OpenAPI/Swagger contract file | **required** |
| `--output <dir>` | `-o` | Directory where generated files will be written | `./generated` |
| `--baseUrl <url>` | `-b` | Base URL to embed in the generated test files | `http://localhost:3000` |
| `--only <type>` | | Generate only `gherkin` or `jest` (omit for both) | both |
| `--verbose` | `-v` | Enable verbose logging | `false` |

---

## MCP Server

Start the MCP server with:

```bash
npm run mcp
```

The server registers the following tools:

### `analyze_contract`

Parses an OpenAPI/Swagger contract from a file path or raw JSON/YAML string.

**Input:**
```json
{ "source": "./petstore.yaml" }
```

**Output:** A structured `ContractSummary` JSON object with paths, methods, parameters, and schemas.

---

### `generate_gherkin`

Generates Gherkin `.feature` content from a parsed contract.

**Input:**
```json
{
  "source": "./petstore.yaml",
  "outputDir": "./generated"
}
```

**Output:** List of written `.feature` file paths.

---

### `generate_tests`

Generates TypeScript Jest test scripts from a parsed contract.

**Input:**
```json
{
  "source": "./petstore.yaml",
  "outputDir": "./generated",
  "baseUrl": "https://api.example.com"
}
```

**Output:** List of written `.spec.ts` file paths.

---

## Project Structure

```
bdd-regression-test-generator/
├── src/
│   ├── parser/
│   │   └── contract-analyzer.ts   # OpenAPI/Swagger parser and extractor
│   ├── generator/
│   │   ├── gherkin-builder.ts     # Gherkin .feature file builder
│   │   └── jest-builder.ts        # TypeScript Jest spec builder
│   ├── mcp/
│   │   └── server.ts              # MCP server exposing generation tools
│   └── cli.ts                     # Commander-based CLI entry point
├── tests/
│   └── generator.test.ts          # Unit tests for parser and generators
├── dist/                          # Compiled output (after build)
├── package.json
├── tsconfig.json
└── README.md
```

---

## Running Tests

```bash
npm test
```

With coverage:

```bash
npm run test:coverage
```

---

## Example: Generated Gherkin

```gherkin
Feature: Pets

  Background:
    Given the API base URL is "https://api.example.com"

  Scenario: GET /pets - list all pets - success
    Given I have valid authentication credentials
    When I send a GET request to "/pets"
    Then the response status code should be 200
    And the response body should match the "PetList" schema

  Scenario: GET /pets - list all pets - unauthorized
    Given I have invalid or missing authentication credentials
    When I send a GET request to "/pets"
    Then the response status code should be 401
```

---

## Example: Generated Jest Test

```typescript
import axios from 'axios';

const BASE_URL = 'https://api.example.com';

describe('Pets', () => {
  describe('GET /pets', () => {
    it('should return 200 for a valid request', async () => {
      const response = await axios.get(`${BASE_URL}/pets`);
      expect(response.status).toBe(200);
    });
  });
});
```

---

## License

MIT