How to Run Automate with TEA
How to Run Automate with TEA
Section titled âHow to Run Automate with TEAâUse TEAâs automate workflow to generate comprehensive tests for existing features. Unlike *atdd, these tests pass immediately because the feature already exists.
When to Use This
Section titled âWhen to Use Thisâ- Feature already exists and works
- Want to add test coverage to existing code
- Need tests that pass immediately
- Expanding existing test suite
- Adding tests to legacy code
Donât use this if:
- Feature doesnât exist yet (use
atddinstead) - Want failing tests to guide development (use
atddfor TDD)
Prerequisites
Section titled âPrerequisitesâ- BMad Method installed
- TEA agent available
- Test framework setup complete (run
frameworkif needed) - Feature implemented and working
Note: This guide uses Playwright examples. If using Cypress, commands and syntax will differ.
1. Load TEA Agent
Section titled â1. Load TEA AgentâStart a fresh chat and load TEA:
tea2. Run the Automate Workflow
Section titled â2. Run the Automate Workflowâautomate3. Provide Context
Section titled â3. Provide ContextâTEA will ask for context about what youâre testing.
Option A: BMad-Integrated Mode (Recommended)
Section titled âOption A: BMad-Integrated Mode (Recommended)âIf you have BMad artifacts (stories, test designs, PRDs):
What are you testing?
I'm testing the user profile feature we just implemented.Story: story-profile-management.mdTest Design: test-design-epic-1.mdReference documents:
- Story file with acceptance criteria
- Test design document (if available)
- PRD sections relevant to this feature
- Tech spec (if available)
Existing tests:
We have basic tests in tests/e2e/profile-view.spec.tsAvoid duplicating that coverageTEA will analyze your artifacts and generate comprehensive tests that:
- Cover acceptance criteria from the story
- Follow priorities from test design (P0 â P1 â P2)
- Avoid duplicating existing tests
- Include edge cases and error scenarios
Option B: Standalone Mode
Section titled âOption B: Standalone ModeâIf youâre using TEA Solo or donât have BMad artifacts:
What are you testing?
TodoMVC React application at https://todomvc.com/examples/react/dist/Features: Create todos, mark as complete, filter by status, delete todosSpecific scenarios to cover:
- Creating todos (happy path)- Marking todos as complete/incomplete- Filtering (All, Active, Completed)- Deleting todos- Edge cases (empty input, long text)TEA will analyze the application and generate tests based on your description.
4. Specify Test Levels
Section titled â4. Specify Test LevelsâTEA will ask which test levels to generate:
Options:
- E2E tests - Full browser-based user workflows
- API tests - Backend endpoint testing (faster, more reliable)
- Component tests - UI component testing in isolation (framework-dependent)
- Mix - Combination of levels (recommended)
Example response:
Generate:- API tests for all CRUD operations- E2E tests for critical user workflows (P0)- Focus on P0 and P1 scenarios- Skip P3 (low priority edge cases)5. Review Generated Tests
Section titled â5. Review Generated TestsâTEA generates a comprehensive test suite with multiple test levels.
API Tests (tests/api/profile.spec.ts):
Section titled âAPI Tests (tests/api/profile.spec.ts):âVanilla Playwright:
import { test, expect } from '@playwright/test';
test.describe('Profile API', () => { let authToken: string;
test.beforeAll(async ({ request }) => { // Manual auth token fetch const response = await request.post('/api/auth/login', { data: { email: 'test@example.com', password: 'password123' } }); const { token } = await response.json(); authToken = token; });
test('should fetch user profile', async ({ request }) => { const response = await request.get('/api/profile', { headers: { Authorization: `Bearer ${authToken}` } });
expect(response.ok()).toBeTruthy(); const profile = await response.json(); expect(profile).toMatchObject({ id: expect.any(String), name: expect.any(String), email: expect.any(String) }); });
test('should update profile successfully', async ({ request }) => { const response = await request.patch('/api/profile', { headers: { Authorization: `Bearer ${authToken}` }, data: { name: 'Updated Name', bio: 'Test bio' } });
expect(response.ok()).toBeTruthy(); const updated = await response.json(); expect(updated.name).toBe('Updated Name'); expect(updated.bio).toBe('Test bio'); });
test('should validate email format', async ({ request }) => { const response = await request.patch('/api/profile', { headers: { Authorization: `Bearer ${authToken}` }, data: { email: 'invalid-email' } });
expect(response.status()).toBe(400); const error = await response.json(); expect(error.message).toContain('Invalid email'); });
test('should require authentication', async ({ request }) => { const response = await request.get('/api/profile'); expect(response.status()).toBe(401); });});With Playwright Utils:
import { test as base, expect } from '@playwright/test';import { test as apiRequestFixture } from '@seontechnologies/playwright-utils/api-request/fixtures';import { createAuthFixtures } from '@seontechnologies/playwright-utils/auth-session';import { mergeTests } from '@playwright/test';import { z } from 'zod';
const ProfileSchema = z.object({ id: z.string(), name: z.string(), email: z.string().email()});
// Merge API and auth fixturesconst authFixtureTest = base.extend(createAuthFixtures());export const testWithAuth = mergeTests(apiRequestFixture, authFixtureTest);
testWithAuth.describe('Profile API', () => { testWithAuth('should fetch user profile', async ({ apiRequest, authToken }) => { const { status, body } = await apiRequest({ method: 'GET', path: '/api/profile', headers: { Authorization: `Bearer ${authToken}` } }).validateSchema(ProfileSchema); // Chained validation
expect(status).toBe(200); // Schema already validated, type-safe access expect(body.name).toBeDefined(); });
testWithAuth('should update profile successfully', async ({ apiRequest, authToken }) => { const { status, body } = await apiRequest({ method: 'PATCH', path: '/api/profile', body: { name: 'Updated Name', bio: 'Test bio' }, headers: { Authorization: `Bearer ${authToken}` } }).validateSchema(ProfileSchema); // Chained validation
expect(status).toBe(200); expect(body.name).toBe('Updated Name'); });
testWithAuth('should validate email format', async ({ apiRequest, authToken }) => { const { status, body } = await apiRequest({ method: 'PATCH', path: '/api/profile', body: { email: 'invalid-email' }, headers: { Authorization: `Bearer ${authToken}` } });
expect(status).toBe(400); expect(body.message).toContain('Invalid email'); });});Key Differences:
authTokenfixture (persisted, reused across tests)apiRequestreturns{ status, body }(cleaner)- Schema validation with Zod (type-safe)
- Automatic retry for 5xx errors
- Less boilerplate (no manual
await response.json()everywhere)
E2E Tests (tests/e2e/profile.spec.ts):
Section titled âE2E Tests (tests/e2e/profile.spec.ts):âimport { test, expect } from '@playwright/test';
test('should edit profile', async ({ page }) => { // Login await page.goto('/login'); await page.getByLabel('Email').fill('test@example.com'); await page.getByLabel('Password').fill('password123'); await page.getByRole('button', { name: 'Sign in' }).click();
// Edit profile await page.goto('/profile'); await page.getByRole('button', { name: 'Edit Profile' }).click(); await page.getByLabel('Name').fill('New Name'); await page.getByRole('button', { name: 'Save' }).click();
// Verify success await expect(page.getByText('Profile updated')).toBeVisible();});TEA generates additional tests for validation, edge cases, etc. based on priorities.
Fixtures (tests/support/fixtures/profile.ts):
Section titled âFixtures (tests/support/fixtures/profile.ts):âVanilla Playwright:
import { test as base, Page } from '@playwright/test';
type ProfileFixtures = { authenticatedPage: Page; testProfile: { name: string; email: string; bio: string; };};
export const test = base.extend<ProfileFixtures>({ authenticatedPage: async ({ page }, use) => { // Manual login flow await page.goto('/login'); await page.getByLabel('Email').fill('test@example.com'); await page.getByLabel('Password').fill('password123'); await page.getByRole('button', { name: 'Sign in' }).click(); await page.waitForURL(/\/dashboard/);
await use(page); },
testProfile: async ({ request }, use) => { // Static test data const profile = { name: 'Test User', email: 'test@example.com', bio: 'Test bio' };
await use(profile); }});With Playwright Utils:
import { test as base } from '@playwright/test';import { createAuthFixtures } from '@seontechnologies/playwright-utils/auth-session';import { mergeTests } from '@playwright/test';import { faker } from '@faker-js/faker';
type ProfileFixtures = { testProfile: { name: string; email: string; bio: string; };};
// Merge auth fixtures with custom fixturesconst authTest = base.extend(createAuthFixtures());const profileTest = base.extend<ProfileFixtures>({ testProfile: async ({}, use) => { // Dynamic test data with faker const profile = { name: faker.person.fullName(), email: faker.internet.email(), bio: faker.person.bio() };
await use(profile); }});
export const test = mergeTests(authTest, profileTest);export { expect } from '@playwright/test';Usage:
import { test, expect } from '../support/fixtures/profile';
test('should update profile', async ({ page, authToken, testProfile }) => { // authToken from auth-session (automatic, persisted) // testProfile from custom fixture (dynamic data)
await page.goto('/profile'); // Test with dynamic, unique data});Key Benefits:
authTokenfixture (persisted token, no manual login)- Dynamic test data with faker (no conflicts)
- Fixture composition with mergeTests
- Reusable across test files
6. Review Additional Artifacts
Section titled â6. Review Additional ArtifactsâTEA also generates:
Updated README (tests/README.md):
Section titled âUpdated README (tests/README.md):â# Test Suite
## Running Tests
### All Testsnpm test
### Specific Levelsnpm run test:api # API tests onlynpm run test:e2e # E2E tests onlynpm run test:smoke # Smoke tests (@smoke tag)
### Single Filenpx playwright test tests/api/profile.spec.ts
## Test Structure
tests/âââ api/ # API tests (fast, reliable)âââ e2e/ # E2E tests (full workflows)âââ fixtures/ # Shared test utilitiesâââ README.md
## Writing Tests
Follow the patterns in existing tests:- Use fixtures for authentication- Network-first patterns (no hard waits)- Explicit assertions- Self-cleaning testsDefinition of Done Summary:
Section titled âDefinition of Done Summary:â## Test Quality Checklist
â
All tests pass on first runâ
No hard waits (waitForTimeout)â
No conditionals for flow controlâ
Assertions are explicitâ
Tests clean up after themselvesâ
Tests can run in parallelâ
Execution time < 1.5 minutes per testâ
Test files < 300 lines7. Run the Tests
Section titled â7. Run the TestsâAll tests should pass immediately since the feature exists:
For Playwright:
npx playwright testFor Cypress:
npx cypress runExpected output:
Running 15 tests using 4 workers
â tests/api/profile.spec.ts (4 tests) - 2.1s â tests/e2e/profile-workflow.spec.ts (2 tests) - 5.3s
15 passed (7.4s)All green! Tests pass because feature already exists.
8. Review Test Coverage
Section titled â8. Review Test CoverageâCheck which scenarios are covered:
# View test reportnpx playwright show-report
# Check coverage (if configured)npm run test:coverageCompare against:
- Acceptance criteria from story
- Test priorities from test design
- Edge cases and error scenarios
What You Get
Section titled âWhat You GetâComprehensive Test Suite
Section titled âComprehensive Test Suiteâ- API tests - Fast, reliable backend testing
- E2E tests - Critical user workflows
- Component tests - UI component testing (if requested)
- Fixtures - Shared utilities and setup
Component Testing by Framework
Section titled âComponent Testing by FrameworkâTEA supports component testing using framework-appropriate tools:
| Your Framework | Component Testing Tool | Tests Location |
|---|---|---|
| Cypress | Cypress Component Testing | tests/component/ |
| Playwright | Vitest + React Testing Library | tests/component/ or src/**/*.test.tsx |
Note: Component tests use separate tooling from E2E tests:
- Cypress users: TEA generates Cypress Component Tests
- Playwright users: TEA generates Vitest + React Testing Library tests
Quality Features
Section titled âQuality Featuresâ- Network-first patterns - Wait for actual responses, not timeouts
- Deterministic tests - No flakiness, no conditionals
- Self-cleaning - Tests donât leave test data behind
- Parallel-safe - Can run all tests concurrently
Documentation
Section titled âDocumentationâ- Updated README - How to run tests
- Test structure explanation - Where tests live
- Definition of Done - Quality standards
Start with Test Design
Section titled âStart with Test DesignâRun test-design before automate for better results:
test-design # Risk assessment, prioritiesautomate # Generate tests based on prioritiesTEA will focus on P0/P1 scenarios and skip low-value tests.
Prioritize Test Levels
Section titled âPrioritize Test LevelsâNot everything needs E2E tests:
Good strategy:
- P0 scenarios: API + E2E tests- P1 scenarios: API tests only- P2 scenarios: API tests (happy path)- P3 scenarios: Skip or add laterWhy?
- API tests are 10x faster than E2E
- API tests are more reliable (no browser flakiness)
- E2E tests reserved for critical user journeys
Avoid Duplicate Coverage
Section titled âAvoid Duplicate CoverageâTell TEA about existing tests:
We already have tests in:- tests/e2e/profile-view.spec.ts (viewing profile)- tests/api/auth.spec.ts (authentication)
Don't duplicate that coverageTEA will analyze existing tests and only generate new scenarios.
MCP Enhancements (Optional)
Section titled âMCP Enhancements (Optional)âIf you have MCP servers configured (tea_use_mcp_enhancements: true), TEA can use them during automate for:
- Healing mode: Fix broken selectors, update assertions, enhance with trace analysis
- Recording mode: Verify selectors with live browser, capture network requests
No prompts - TEA uses MCPs automatically when available. See Enable MCP Enhancements for setup.
Generate Tests Incrementally
Section titled âGenerate Tests IncrementallyâDonât generate all tests at once:
Iteration 1:
Generate P0 tests only (critical path)Run: automateIteration 2:
Generate P1 tests (high value scenarios)Run: automateTell TEA to avoid P0 coverageIteration 3:
Generate P2 tests (if time permits)Run: automateThis iterative approach:
- Provides fast feedback
- Allows validation before proceeding
- Keeps test generation focused
Common Issues
Section titled âCommon IssuesâTests Pass But Coverage Is Incomplete
Section titled âTests Pass But Coverage Is IncompleteâProblem: Tests pass but donât cover all scenarios.
Cause: TEA wasnât given complete context.
Solution: Provide more details:
Generate tests for:- All acceptance criteria in story-profile.md- Error scenarios (validation, authorization)- Edge cases (empty fields, long inputs)Too Many Tests Generated
Section titled âToo Many Tests GeneratedâProblem: TEA generated 50 tests for a simple feature.
Cause: Didnât specify priorities or scope.
Solution: Be specific:
Generate ONLY:- P0 and P1 scenarios- API tests for all scenarios- E2E tests only for critical workflows- Skip P2/P3 for nowTests Duplicate Existing Coverage
Section titled âTests Duplicate Existing CoverageâProblem: New tests cover the same scenarios as existing tests.
Cause: Didnât tell TEA about existing tests.
Solution: Specify existing coverage:
We already have these tests:- tests/api/profile.spec.ts (GET /api/profile)- tests/e2e/profile-view.spec.ts (viewing profile)
Generate tests for scenarios NOT covered by those filesMCP Enhancements for Better Selectors
Section titled âMCP Enhancements for Better SelectorsâIf you have MCP servers configured, TEA verifies selectors against live browser. Otherwise, TEA generates accessible selectors (getByRole, getByLabel) by default.
Setup: Answer âYesâ to MCPs in BMad installer + configure MCP servers in your IDE. See Enable MCP Enhancements.
Related Guides
Section titled âRelated Guidesâ- How to Run Test Design - Plan before generating
- How to Run ATDD - Failing tests before implementation
- How to Run Test Review - Audit generated quality
Understanding the Concepts
Section titled âUnderstanding the Conceptsâ- Testing as Engineering - Why TEA generates quality tests (foundational)
- Risk-Based Testing - Why prioritize P0 over P3
- Test Quality Standards - What makes tests good
- Fixture Architecture - Reusable test patterns
Reference
Section titled âReferenceâ- Command: *automate - Full command reference
- TEA Configuration - MCP and Playwright Utils options
Generated with BMad Method - TEA (Test Architect)