Writing E2E Scenarios
This guide walks through adding a new end-to-end test scenario using Gherkin syntax and godog step definitions.
Where Feature Files Live
Feature files are in category folders under:
crawbl-backend/test-features/
├── auth/ (auth.feature, logout.feature, cleanup.feature, error_cases.feature)
├── chat/ (chat.feature, conversations_crud.feature, mentions.feature, agent_*.feature, error_cases.feature)
├── core/ (health.feature, legal.feature, models.feature, edge_cases.feature, uploads_contract.feature)
├── integrations/ (integrations.feature)
├── multi_user/ (multi_user.feature, error_cases.feature)
├── profile/ (profile.feature, error_cases.feature)
├── tools/ (memory.feature, web_search.feature)
└── workspaces/ (workspaces.feature, mobile_first_launch.feature, error_cases.feature)
Add new scenarios to the existing file that matches your domain, or create a new feature file inside the matching category folder.
Gherkin Syntax Basics
Feature: Integrations
Scenarios for creating and managing integrations.
Scenario: Create an integration
Given the user "primary" is authenticated
When I send a POST request to "/v1/integrations" with body:
"""
{
"workspace_id": "{primary_workspace_id}",
"provider": "slack"
}
"""
Then the response status should be 201
And the response body should contain "slack"
Use {key} for value interpolation (e.g. {primary_workspace_id}, {last_response_id}).
Step Definition Files
Step definitions live in internal/testsuite/e2e/ and are registered per file:
| File | Purpose |
|---|---|
steps_http.go | HTTP request steps |
steps_auth.go | Authentication and session steps |
steps_assert.go | Response assertion steps |
steps_db.go | Database assertion steps |
steps_state.go | Value interpolation and stored state |
steps_chat.go | Chat and conversation steps |
steps_agent.go | Agent interaction steps |
steps_health.go | Health check steps |
steps_workspace.go | Workspace lifecycle steps |
steps_user.go | User lifecycle steps |
steps_isolation.go | Test isolation helpers |
steps_integrations.go | Integration-specific steps |
steps_redis.go | Redis state assertions |
steps_spaces.go | Spaces steps |
Registration follows this pattern in each file:
func registerXxxSteps(sc *godog.ScenarioContext, tc *testContext) {
sc.Step(`^step pattern$`, tc.stepHandler)
}
Adding a New Scenario
Choose the feature file
Add the scenario to the existing category file that matches your domain:
test-features/integrations/integrations.feature
Write the Gherkin
Start with the scenario in plain Gherkin. Use {key} for interpolated values.
Scenario: Create a Slack integration
Given the user "primary" is authenticated
And the user "primary" has a workspace
When I send a POST request to "/v1/workspaces/{primary_workspace_id}/integrations" with body:
"""
{
"provider": "slack"
}
"""
Then the response status should be 201
And the response JSON at "provider" should equal "slack"
Reuse existing step definitions
Most scenarios fit the existing Given, When, and Then helpers across the 14 step files.
Given the user "primary" is authenticated
When I send a GET request to "/v1/users/profile"
Then the response status should be 200
And I store the response JSON at "id" as "integration_id"
Add new steps only if needed
If a step does not exist, add it to the matching steps_*.go file and register it.
func registerIntegrationSteps(sc *godog.ScenarioContext, tc *testContext) {
sc.Step(`^the response JSON array should be empty$`, tc.theResponseJSONArrayShouldBeEmpty)
}
Run the scenario
Target a single category to iterate quickly, then widen once it passes.
crawbl test e2e --port-forward --category integrations -v
Tips
- Use the 3 fixed test users (
primary,frank,grace) — do not create new users per scenario. - Use
{key}interpolation to reference IDs from previous steps. - Keep scenarios independent — each scenario should work regardless of execution order within the same user context.
- Test error cases — include 400, 401, 403, and 404 scenarios alongside happy paths; each category has an
error_cases.featurefor this.
What's next: Test Architecture