AI-Native E2E Test Generator - Generate Playwright tests from Gherkin features using AI
npm install @sun-asterisk/sungenVersion: 3.2.0 (Unreleased)
Priority-Based E2E Test Generation with Deterministic Selector Mapping
---
Sungen is a deterministic-first E2E test automation framework that generates Playwright tests from Gherkin features using a priority-based approach:
1. Strict UI Scanning - Filters only interactive elements (input, button, a, select, textarea)
2. Priority-Based Selector Mapping:
- 1οΈβ£ Direct ID Match - Exact data-testid matching (instant, free, deterministic)
- 2οΈβ£ Accessibility Match - Semantic role + aria-label matching
- 3οΈβ£ AI Fallback - Claude Sonnet as last resort (not primary solution)
3. Auto-Tagging Tool - Inject stable data-testid into source code proactively
4. Authentication Support - Built-in Playwright storage states via @auth:{role} tags
5. Test Generation - Create production-ready Playwright test code
Key Achievement: 90%+ Direct ID match rate with minimal AI dependency!
---
``bash`
npm install -g @sun-asterisk/sungen@latest
Or use locally in your project:
`bash`
npm install --save-dev @sun-asterisk/sungen
1. Initialize your Sungen project:
`bash`
sungen init
This creates:
- qa/screens/ - Screen definitions directory (use sungen add --screen to create)spec/generated/
- - Generated test code output directoryplaywright.config.ts
- - Playwright configuration.gitignore
- - Updated with Sungen patterns
Note: Use sungen add --screen to create screen definitions with proper structure.
2. Create your first screen definition:
`bash`
sungen add --screen login --path /auth/login
This creates a screen definition with:
- qa/screens/login/features/login.feature - Gherkin scenariosqa/screens/login/selectors/login.override.yaml
- - User override file (empty with guidelines)qa/screens/login/test-data/login.override.yaml
- - User override file (empty with guidelines)
Note: Override files will NEVER be modified by sungen map. Edit these to customize selectors and test data.
3. Run sungen map to generate base files:
`bash`
sungen map --screen login
This generates:
- qa/screens/login/selectors/login.yaml - Auto-generated base selectorsqa/screens/login/test-data/login.yaml
- - Auto-generated base test data
At runtime, values from .override.yaml take precedence over base files.
`bashCreate a new screen definition
sungen add --screen login --path /auth/login
---
π Project Structure
`
your-project/
βββ app/ # Your React source
β βββ auth/
β β βββ page.tsx
β βββ chat/
β βββ page.tsx
β
βββ qa/ # Input artifacts
β βββ screens/ # Screen definitions (NEW structure)
β βββ auth/
β βββ features/ # Gherkin scenarios
β β βββ login.feature
β β βββ logout.feature
β βββ selectors/ # Element mappings
β β βββ login.yaml
β β βββ logout.yaml
β βββ test-data/ # Test variables
β βββ login.yaml
β βββ logout.yaml
β
βββ specs/ # Output artifacts (sibling to qa/)
β βββ .auth/ # Authentication storage states (gitignored)
β β βββ .gitignore
β β βββ admin.json
β β βββ user.json
β βββ auth.setup.ts # Playwright auth setup (auto-generated)
β βββ generated/ # Generated Playwright tests
β βββ auth
β βββ login.spec.ts
β βββ logout.spec.ts
β
βββ sungen.config.yaml # Framework configuration
`
Key Changes in v3.2:
- Organized by screens: Each screen has its own directory
- Self-contained: Features, selectors, and test data grouped together
- Use
sungen add --screen to create new screen definitions---
π¨ Gherkin Syntax
Sungen uses a simple, natural language grammar for Gherkin:
Pattern:
User + action + [element] + with {{data}}$3
`gherkin
Feature: Login Screen As a user
I want to interact with the Login screen
So that I can access my account
Path: /auth/login
@high
Scenario: User logs in successfully
Given User open page
When User fill [Email] field with {{valid_email}}
And User fill [Password] field with {{valid_password}}
And User click [Login] button
Then User see [Welcome message !] text with {{success_message}}
`$3
| Component | Syntax | Example |
|-----------|--------|---------|
| Actor |
User | User open page |
| Action | click, fill, see | User click [button] |
| Element | [element name] | [Email] field, [submit] button |
| Data | {{variable}} | {{valid_email}}, {{success.message}} |
| Path | Path: /route | Path: /auth/login |$3
`gherkin
Navigation
Given User open pageInput
When User fill [element] field with {{data}}Click
When User click [element] buttonVerification
Then User see [element] text with {{expected_text}}
`$3
Define variables in
test-data/:`yaml
test-data/login.yaml
valid_email: "user@example.com"
valid_password: "SecurePassword123"
success:
message: "Welcome back!"
`$3
Sungen supports Playwright's authentication storage states via
@auth:{role} tags, allowing you to reuse authenticated browser contexts across tests.#### Basic Usage
Tag your features or scenarios:
`gherkin
@auth:admin
Feature: User Management
Scenario: Delete user
Given User navigate to "/users"
When User click [delete-button]
Then User see [success-message]@auth:user
Feature: Profile Settings
Scenario: Update email
Given User navigate to "/profile"
When User fill [email] field with {{new_email}}
`Generated Playwright code automatically includes storage state:
`typescript
// user-management.spec.ts
test.use({ storageState: 'specs/.auth/admin.json' });test('Delete user', async ({ page }) => {
// Already authenticated as admin!
await page.goto('/users');
// ...
});
`#### Tag Inheritance
Tags can be applied at feature level (inherited by all scenarios) or scenario level (overrides feature):
`gherkin
@auth:admin
Feature: Admin Dashboard
Scenario: View analytics
# Inherits @auth:admin from feature
@auth:moderator
Scenario: Review flagged content
# Overrides with @auth:moderator
@no-auth
Scenario: View public help page
# Explicitly disables authentication
`Precedence: Scenario > Feature > None
#### Setting Up Authentication
On first
sungen generate with @auth tags, an auth.setup.ts scaffold is auto-generated:`bash
sungen generate --screen adminOutput:
β Generated specs/auth.setup.ts - Update TODOs before running tests
β Created specs/.auth/ directory for storage states
Detected roles: admin, user, moderator
`Customize the generated setup file:
`typescript
// specs/auth.setup.ts
import { test as setup } from '@playwright/test';const authFile = (role: string) =>
specs/.auth/${role}.json;setup('authenticate as admin', async ({ page }) => {
// TODO: Navigate to your login page
await page.goto('/login');
// TODO: Fill in credentials for admin role
await page.getByLabel('Email').fill('admin@example.com');
await page.getByLabel('Password').fill('admin123');
// TODO: Click login button
await page.getByRole('button', { name: 'Sign in' }).click();
// TODO: Wait for authentication to complete
await page.waitForURL('/dashboard');
// Save authentication state
await page.context().storageState({ path: authFile('admin') });
});
// Additional setup functions for other roles...
`#### Features
- β
Feature-level tags - All scenarios inherit authentication
- β
Scenario-level tags - Override feature authentication
- β
@no-auth tag - Explicitly disable inherited authentication
- β
Auto-generation - Setup scaffold created on first use
- β
Multiple roles - Support unlimited authentication roles
- β
Storage reuse - Fast tests by reusing authenticated contexts
#### Notes
- Storage state files (
specs/.auth/*.json) are gitignored by default
- Setup runs before tests via Playwright's global setup
- New roles detected after initial setup trigger a warning with manual update instructions$3
Map elements in
selectors/:`yaml
selectors/login.yaml
email-input:
selector: ""
type: "testid"
submit-button:
selector: ""
type: "role"
value: "button"
`---
ποΈ Architecture
---
π CLI Commands
$3
Initialize Sungen project structure`bash
sungen init
`Creates:
-
qa/screens/ directory for screen definitions
- spec/generated/ directory for generated tests
- playwright.config.ts if it doesn't exist
- Updates .gitignore with Sungen patterns$3
Create a new screen definition with scaffolded files. Supports multiple test scenarios per screen.`bash
sungen add --screen [options]Options:
--screen Screen name (required)
-p, --path Screen route path - also controls filename
-d, --description Screen description
Examples:
# Create screen with default file
sungen add --screen login
# Create screen with custom path/filename
sungen add --screen login --path /login-valid --description "Valid login"
# Add additional test scenarios to existing screen
sungen add --screen login --path /login-invalid
sungen add --screen login --path /login-mfa
`What it does:
- First call: Creates
qa/screens/ directory structure
- Subsequent calls: Adds additional feature files to existing screen
- Generates features/ with Gherkin template
- Generates selectors/ with selector structure
- Generates test-data/ for test variables
- Path option: Controls both filename and Path metadata in feature fileMulti-file workflow (organizing test scenarios):
`bash
Create base screen
sungen add --screen loginAdd valid login scenario
sungen add --screen login --path /login-validAdd invalid credentials scenario
sungen add --screen login --path /login-invalidAdd 2FA scenario
sungen add --screen login --path /login-mfa
`Result:
`
qa/screens/login/
βββ features/
β βββ login.feature
β βββ login-valid.feature
β βββ login-invalid.feature
β βββ login-mfa.feature
βββ selectors/
β βββ login.yaml
β βββ login-valid.yaml
β βββ login-invalid.yaml
β βββ login-mfa.yaml
βββ test-data/
βββ login.yaml
βββ login-valid.yaml
βββ login-invalid.yaml
βββ login-mfa.yaml
`Backward compatible: Default behavior (no
--path) creates single file named after screen.
$3
Map Gherkin references to actual selectors using AI`bash
sungen map --screen [options]Options:
--screen Screen name to map (required)
--all Map all screens
--force Force regeneration, bypass cache, overwrite existing files
--verbose Detailed output
`Output: Processes each feature file individually, generating separate YAML files for each:
`
Mapping screen: loginβ Mapped login.feature
β selectors/login.yaml (5 elements)
β test-data/login.yaml (3 variables)
β Mapped login-valid.feature
β selectors/login-valid.yaml (3 elements)
β test-data/login-valid.yaml (2 variables)
Next step: sungen generate --screen login
`Multi-file support: Each
.feature file generates matching .yaml files, maintaining clean separation between test scenarios.$3
Generate Playwright test code from features`bash
sungen generate [options]Options:
--ai-mapper Enable AI fallback for unknown Gherkin patterns
--framework Test framework (playwright, appium, integration) - default: playwright
-s, --screen Filter generation to specific screen (recommended)
-f, --force Force regeneration, bypass cache
Examples:
sungen generate --screen login # Generate tests for login screen
sungen generate -s login --force # Force regenerate login screen tests
sungen generate # Generate all tests (legacy)
`Output: Shows per-file results with step counts:
`
Generating tests: loginβ Generated login.spec.ts
β spec/generated/login/login.spec.ts (8 steps)
β Generated login-valid.spec.ts
β spec/generated/login/login-valid.spec.ts (5 steps)
β Generated login-invalid.spec.ts
β spec/generated/login/login-invalid.spec.ts (3 steps)
Next step: npx playwright test
`Selector Merging: Supports optional base + feature-specific selector files:
- Base file:
selectors/ - Shared selectors for all scenarios
- Feature file: selectors/ - Scenario-specific selectors (required)
- Feature-specific selectors override base selectors when keys conflictValidation: Checks for missing selector files before generation and suggests running
map command if needed.$3
Run complete pipeline (discover + map + generate)`bash
sungen full [options]Options:
--screen Process specific screen (optional)
--depth Max component depth
--force Force regeneration
--verbose Detailed output
`$3
Clear all cached data`bash
sungen cache-clear
`$3
Generate authentication state for login sessions (supports SSO and manual login)`bash
sungen makeauth [options]Options:
-u, --url Base URL of the application (auto-detected from playwright.config.ts)
-p, --path Login page path (default: /login)
-o, --output Output directory (default: specs/.auth)
-t, --timeout Overall timeout in milliseconds (default: 180000)
--nav-timeout Navigation timeout in milliseconds (default: 180000)
--stability-wait URL stability wait in milliseconds (default: 5000)
--headless Run browser in headless mode
--verify Verify existing auth state is still valid
--list List all existing auth states
--export Export auth state as base64 for CI
Examples:
sungen makeauth user # Create auth state for 'user' role
sungen makeauth admin --url http://localhost:3000
sungen makeauth admin --path /auth/signin
sungen makeauth admin --list # List all auth states
sungen makeauth admin --verify # Check if auth is still valid
`What it does:
- Opens a browser window for manual login (including SSO providers like Google, GitHub, etc.)
- Saves authentication state (cookies, localStorage, sessionStorage) to
specs/.auth/
- Can be used in Playwright tests to skip login process and maintain sessions
- Supports multiple auth roles (admin, user, guest, etc.)Using auth state in tests:
`typescript
// playwright.config.ts
export default defineConfig({
projects: [
{
name: 'authenticated',
use: {
storageState: 'specs/.auth/user.json',
},
},
],
});
`See docs/makeauth.md for complete documentation.
$3
Auto-inject stable data-testid attributes into source code`bash
sungen auto-tag [options]Options:
--screen Tag specific screen (optional, defaults to all)
--dry-run Preview changes without modifying files
--force Overwrite existing data-testid (use with caution)
--verbose Show detailed changes
Examples:
sungen auto-tag --screen login --dry-run # Preview changes
sungen auto-tag --screen login # Apply changes
sungen auto-tag # Tag all screens
`What it does:
- Scans React/Vue/HTML source code for interactive elements
- Injects
data-testid="screen-element" attributes
- Idempotent (skips if data-testid already exists)
- Preserves code formatting (Prettier/ESLint compatible)Before:
`tsx
`After:
`tsx
`---
π Examples
See the
/examples` folder for complete working examples:- ai-chat - Chat application with authentication
- More examples coming soon!
---
---
Contributions are welcome! Please read our contributing guidelines and follow the Kim chα» nam (North Star Principles) in the Implementation Guide.
---
MIT License - see LICENSE file for details
---
- Built with Claude Sonnet 4.5
- Uses @anthropic-ai/sdk
- Powered by Playwright
- Gherkin parsing by @cucumber/gherkin
---
Made with β€οΈ by Bach Ngoc Hoai