All skills
bmad-labs avatar

/typescript-e2e-testing

@3bcc7a6
by bmad-labsbmad-labs/skills15 stars
4

E2E and integration testing for TypeScript/NestJS projects using Jest, supertest, and real infrastructure via Docker (Kafka, PostgreSQL, MongoDB, Redis) with the Given-When-Then pattern. Use whenever the user is working on `.e2e-spec.ts` files or anything under `test/e2e/`, or asks to set up, write, review, run, debug, or optimize E2E or integration tests — including flaky tests, docker-compose for tests, Kafka/Redpanda consumers, test isolation, or GWT compliance.

Use this Skill: https://skilld.dev/gh/bmad-labs/skills/typescript-e2e-testing

This session only. Nothing lands on disk.

referencescommonrules.md

≈1.6k tokens on demand. Your agent reads this file only when SKILL.md points to it.

E2E Testing Rules

Core Rules

Rule Requirement
Setup Replicate main.ts configuration exactly
Execution --runInBand (sequential) - NEVER parallel
Logger File logging via .env.e2e - DO NOT mock, DO NOT console.log
Log file logs/e2e-test.log - clean before each test run
Test structure MUST follow GWT pattern (Given-When-Then)
Output ALWAYS redirect to temp files - prevents context bloat

Context Efficiency Rule

CRITICAL: All test execution MUST output to temp files with unique session ID.

# Initialize session (once at start)
export E2E_SESSION=$(date +%s)-$$

# Standard pattern - redirect to temp file only (no console output)
npm run test:e2e > /tmp/e2e-${E2E_SESSION}-output.log 2>&1 && tail -50 /tmp/e2e-${E2E_SESSION}-output.log

# Get failures
grep -B 2 -A 15 "FAIL\|✕" /tmp/e2e-${E2E_SESSION}-output.log

# Cleanup when done
rm -f /tmp/e2e-${E2E_SESSION}-*.log /tmp/e2e-${E2E_SESSION}-*.md

Environment Configuration

E2E tests MUST use .env.e2e:

# Logger configuration
LOG_LEVEL=debug
LOG_FILE=./logs/e2e-test.log
LOG_SYNC_FILE=./logs/application.pid

# Database
DATABASE_URL=postgresql://test:test@localhost:5433/testdb
MONGODB_URI=mongodb://localhost:27018/testdb

# Kafka
KAFKA_BROKER=localhost:9094
KAFKA_CLIENT_ID=e2e-test-client
KAFKA_GROUP_ID=e2e-test-group

# Redis
REDIS_URL=redis://localhost:6380

# Application
NODE_ENV=test

Timeout Rules

Context Value Purpose
jest.setTimeout() 25000 Default per-test timeout
beforeAll 90000 Full app + infrastructure setup
afterAll 30000 Graceful cleanup
Kafka waits 8-10s Consumer group rebalancing
MongoDB cleanup wait 1000ms In-flight message completion

Test Isolation Rules

  1. Clean Before AND After: Clear data in both beforeEach and afterEach
  2. Wait Before Cleanup: Add 1s delay before cleanup for in-flight operations
  3. Unique Identifiers: Generate unique IDs per test (e.g., test-${Date.now()}-${uuid})
  4. Sequential Execution: Use --runInBand to prevent conflicts

Logging Rules

// ❌ BAD - NEVER DO
console.log('debug info');
mockLogger.log.mockImplementation(() => {});

// ✅ GOOD - ALWAYS
app.useLogger(app.get(CustomLoggerService));
// Configure LOG_FILE in .env.e2e

Viewing Logs:

# View test output (from temp file)
tail -50 /tmp/e2e-${E2E_SESSION}-output.log

# Get failure details
grep -B 2 -A 15 "FAIL\|✕" /tmp/e2e-${E2E_SESSION}-output.log

# View application logs (limited)
tail -100 logs/e2e-test.log
grep -i error logs/e2e-test.log | tail -20

Mock Rules

Mock ALL retry attempts:

// ❌ BAD - Retry succeeds on 2nd attempt
mockHttpService.post.mockReturnValueOnce(of({ status: 500 }));

// ✅ GOOD - All 3 retry attempts fail
mockHttpService.post.mockClear();
mockHttpService.post.mockReturnValueOnce(of({ status: 500 })); // attempt 1
mockHttpService.post.mockReturnValueOnce(of({ status: 500 })); // attempt 2
mockHttpService.post.mockReturnValueOnce(of({ status: 500 })); // attempt 3

Exception Type Rules

Exception HTTP Status Use Case
ValidateException 400 Input validation, malformed requests
InternalException 500 Infrastructure failures, external service errors
UnauthorizedException 401 Authentication failures
ForbiddenException 403 Authorization failures
NotFoundException 404 Resource not found

NestJS Setup Rules

CRITICAL: E2E tests MUST replicate production setup:

// ✅ REQUIRED in beforeAll
app.useLogger(app.get(CustomLoggerService));
app.useGlobalFilters(new UnknownExceptionsFilter(httpAdapter));
app.useGlobalFilters(new DefaultValidateExceptionFilter(httpAdapter));
app.useGlobalFilters(new DefaultInternalExceptionFilter(httpAdapter));
app.useGlobalFilters(new HttpExceptionFilter(httpAdapter));
app.useGlobalInterceptors(new HttpRequestLoggingInterceptor(cls, reflector));
app.useGlobalInterceptors(new KafkaRequestLoggingInterceptor(cls, reflector));
app.useGlobalPipes(new ValidationPipe(DefaultValidationOptions));

// ✅ REQUIRED for Kafka
app.connectMicroservice(kafkaConfig, { inheritAppConfig: true });

Failure Handling Rules

CRITICAL: Fix ONE test at a time. NEVER run full suite repeatedly while debugging.

❌ WRONG: Run full suite → See 5 failures → Run full suite again → Still failures → ...
✅ RIGHT: Run full suite → See 5 failures → Fix test 1 → Verify → Fix test 2 → ... → Full suite ONCE

Workflow:

  1. Create /tmp/e2e-${E2E_SESSION}-failures.md tracking file with ALL failing tests
  2. Select ONE failing test
  3. Run ONLY that test (never full suite, no console output):
    npm run test:e2e -- -t "test name" > /tmp/e2e-${E2E_SESSION}-debug.log 2>&1
    tail -50 /tmp/e2e-${E2E_SESSION}-debug.log
  4. Analyze failures: grep -B 2 -A 15 "FAIL\|Error:" /tmp/e2e-${E2E_SESSION}-debug.log
  5. Fix and verify with 3-5 runs of SAME test:
    for i in {1..5}; do npm run test:e2e -- -t "test name" > /tmp/e2e-${E2E_SESSION}-run$i.log 2>&1 && echo "Run $i: PASS" || echo "Run $i: FAIL"; done
  6. Mark as FIXED in tracking file
  7. Move to next failing test - repeat steps 2-6
  8. Run full suite ONLY ONCE after ALL individual tests pass:
    npm run test:e2e > /tmp/e2e-${E2E_SESSION}-output.log 2>&1 && tail -50 /tmp/e2e-${E2E_SESSION}-output.log
  9. Delete tracking file: rm /tmp/e2e-${E2E_SESSION}-failures.md

WHY: Full suite runs waste time and context. Each failing test pollutes output.

Checklist

Environment:

  • .env.e2e with file logging configuration
  • logs/ directory in .gitignore
  • Global setup deletes previous log file

Setup:

  • Use real logger via app.useLogger()
  • Global filters match main.ts
  • Global interceptors match main.ts
  • ValidationPipe BEFORE connectMicroservice
  • inheritAppConfig: true for Kafka
  • Unique consumer group ID
  • --runInBand in package.json

Test Structure:

  • ALL tests follow GWT pattern
  • GWT sections marked: // GIVEN:, // WHEN:, // THEN:
  • One test, one behavior
  • No conditional assertions

Assertions:

  • Assert specific values, not just existence
  • Tests fail when any field differs
  • Verify database state matches expected

Source: SKILL.md on GitHub

1 alert16d5 checks · Risk SAFE
  • Gen Agent Trust Hub16d

    This skill provides comprehensive workflows and reference materials for E2E testing in TypeScript/NestJS projects. It uses standard development tools like Jest, Docker, and shell commands. No malicious patterns or security risks were detected.

  • Socket16d

    No alerts

  • Snyk16d

    Risk: LOW · No issues

  • Runlayer7mo

    30/103 files flagged

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at 3bcc7a6. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 days ago.

Activeupdated 5 months ago
  • TypeScript
  • jest
  • nestjs
  • e2e-testing
  • supertest
  • docker
  • kafka
  • postgres
  • mongodb
  • redis
  • integration-testing
  • gwt-pattern

README badge

README badge for bmad-labs/skills

Writes E2E and integration tests for NestJS projects using Jest and supertest against real Docker infrastructure (Kafka, PostgreSQL, MongoDB, Redis) following the Given-When-Then pattern. Covers test setup, writing, review, debugging, and optimization workflows with technology-specific helpers and isolation strategies for each service.

Generated from the current SKILL.md.

Does this skill work with NestJS only?
The skill is built for NestJS projects using Jest and supertest, but the patterns and workflows apply to any TypeScript backend with HTTP endpoints. Technology-specific helpers exist for Kafka, PostgreSQL, MongoDB, and Redis.
Do I need Docker running to use this skill?
Yes. The skill assumes real infrastructure via Docker (Kafka, PostgreSQL, MongoDB, Redis). Tests execute against actual services, not mocks.
What if my E2E tests are flaky or failing?
The Debugging E2E Test workflow provides a systematic protocol: fix one test at a time using isolated test runs, verify with 3-5 consecutive runs before moving to the next failure, then run the full suite only once all tests pass individually.
Does this skill cover GraphQL or gRPC testing?
Yes. The API testing reference includes examples for REST, GraphQL, and gRPC, plus external API mocking with MSW and Nock.
What is the Given-When-Then pattern and is it mandatory?
GWT is the mandatory test structure: Given describes setup state, When describes the action under test, Then describes expected outcomes. All E2E tests in this skill must follow this pattern.

Generated from the current SKILL.md. These answers refresh after source changes.