@sun-asterisk/sungen 1.0.16 → 1.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +100 -601
- package/dist/cli/index.js +5 -5
- package/dist/cli/index.js.map +1 -1
- package/dist/generators/cli.js +1 -1
- package/dist/generators/scaffold-generator/index.d.ts +8 -1
- package/dist/generators/scaffold-generator/index.d.ts.map +1 -1
- package/dist/generators/scaffold-generator/index.js +52 -8
- package/dist/generators/scaffold-generator/index.js.map +1 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/partials/dialog-root.hbs +1 -0
- package/dist/generators/test-generator/patterns/navigation-patterns.js +1 -1
- package/dist/generators/test-generator/patterns/navigation-patterns.js.map +1 -1
- package/dist/generators/test-generator/step-mapper.d.ts.map +1 -1
- package/dist/generators/test-generator/step-mapper.js +31 -0
- package/dist/generators/test-generator/step-mapper.js.map +1 -1
- package/dist/generators/test-generator/template-engine.d.ts.map +1 -1
- package/dist/generators/test-generator/template-engine.js +14 -1
- package/dist/generators/test-generator/template-engine.js.map +1 -1
- package/dist/input/cli-adapter.js +3 -3
- package/dist/input/cli-adapter.js.map +1 -1
- package/dist/orchestrator/project-initializer.d.ts +6 -1
- package/dist/orchestrator/project-initializer.d.ts.map +1 -1
- package/dist/orchestrator/project-initializer.js +34 -8
- package/dist/orchestrator/project-initializer.js.map +1 -1
- package/package.json +1 -1
- package/src/cli/index.ts +5 -5
- package/src/generators/cli.ts +1 -1
- package/src/generators/scaffold-generator/index.ts +54 -10
- package/src/generators/test-generator/adapters/playwright/templates/steps/partials/dialog-root.hbs +1 -0
- package/src/generators/test-generator/patterns/navigation-patterns.ts +1 -1
- package/src/generators/test-generator/step-mapper.ts +30 -0
- package/src/generators/test-generator/template-engine.ts +14 -1
- package/src/input/cli-adapter.ts +3 -3
- package/src/orchestrator/project-initializer.ts +37 -8
package/README.md
CHANGED
|
@@ -1,671 +1,170 @@
|
|
|
1
1
|
# Sungen - AI-Native E2E Test Generator
|
|
2
2
|
|
|
3
|
-
**Version**:
|
|
4
|
-
**
|
|
3
|
+
**Version**: 1.0.17
|
|
4
|
+
**Deterministic-first E2E test generation**: Gherkin → Playwright tests
|
|
5
5
|
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
##
|
|
8
|
+
## What is Sungen?
|
|
9
9
|
|
|
10
|
-
Sungen
|
|
10
|
+
Sungen generates Playwright tests from Gherkin features using **priority-based selector mapping**:
|
|
11
11
|
|
|
12
|
-
1. **
|
|
13
|
-
2. **
|
|
14
|
-
|
|
15
|
-
- **2️⃣ Accessibility Match** - Semantic `role` + `aria-label` matching
|
|
16
|
-
- **3️⃣ AI Fallback** - Claude Sonnet as last resort (not primary solution)
|
|
17
|
-
3. **Auto-Tagging Tool** - Inject stable `data-testid` into source code proactively
|
|
18
|
-
4. **Authentication Support** - Built-in Playwright storage states via `@auth:{role}` tags
|
|
19
|
-
5. **Test Generation** - Create production-ready Playwright test code
|
|
12
|
+
1. **Direct ID** (`data-testid`) - instant, free, deterministic
|
|
13
|
+
2. **Accessibility** (`role` + `aria-label`) - semantic fallback
|
|
14
|
+
3. **AI Fallback** (Claude) - last resort only
|
|
20
15
|
|
|
21
|
-
|
|
16
|
+
Goal: **90%+ Direct ID match** with minimal AI dependency.
|
|
22
17
|
|
|
23
18
|
---
|
|
24
19
|
|
|
25
|
-
##
|
|
26
|
-
|
|
27
|
-
### Installation
|
|
20
|
+
## Quick Start
|
|
28
21
|
|
|
29
22
|
```bash
|
|
23
|
+
# Install
|
|
30
24
|
npm install -g @sun-asterisk/sungen@latest
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
Or use locally in your project:
|
|
34
|
-
|
|
35
|
-
```bash
|
|
36
|
-
npm install --save-dev @sun-asterisk/sungen
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
### Setup
|
|
40
|
-
|
|
41
|
-
1. Initialize your Sungen project:
|
|
42
25
|
|
|
43
|
-
|
|
26
|
+
# Initialize project
|
|
44
27
|
sungen init
|
|
45
|
-
```
|
|
46
28
|
|
|
47
|
-
|
|
48
|
-
- `qa/screens/` - Screen definitions directory (use `sungen add --screen` to create)
|
|
49
|
-
- `spec/generated/` - Generated test code output directory
|
|
50
|
-
- `playwright.config.ts` - Playwright configuration
|
|
51
|
-
- `.gitignore` - Updated with Sungen patterns
|
|
52
|
-
|
|
53
|
-
**Note:** Use `sungen add --screen <name>` to create screen definitions with proper structure.
|
|
54
|
-
|
|
55
|
-
2. Create your first screen definition:
|
|
56
|
-
|
|
57
|
-
```bash
|
|
29
|
+
# Create a screen, map selectors, generate tests
|
|
58
30
|
sungen add --screen login --path /auth/login
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
This creates a screen definition with:
|
|
62
|
-
- `qa/screens/login/features/login.feature` - Gherkin scenarios
|
|
63
|
-
- `qa/screens/login/selectors/login.override.yaml` - User override file (empty with guidelines)
|
|
64
|
-
- `qa/screens/login/test-data/login.override.yaml` - User override file (empty with guidelines)
|
|
65
|
-
|
|
66
|
-
**Note**: Override files will **NEVER** be modified by `sungen map`. Edit these to customize selectors and test data.
|
|
67
|
-
|
|
68
|
-
3. Run `sungen map` to generate base files:
|
|
69
|
-
|
|
70
|
-
```bash
|
|
71
31
|
sungen map --screen login
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
This generates:
|
|
75
|
-
- `qa/screens/login/selectors/login.yaml` - Auto-generated base selectors
|
|
76
|
-
- `qa/screens/login/test-data/login.yaml` - Auto-generated base test data
|
|
77
|
-
|
|
78
|
-
At runtime, values from `.override.yaml` take precedence over base files.
|
|
79
|
-
|
|
80
|
-
### Usage
|
|
81
|
-
|
|
82
|
-
```bash
|
|
83
|
-
# Create a new screen definition
|
|
84
|
-
sungen add --screen login --path /auth/login
|
|
85
|
-
|
|
86
|
-
# Step by step:
|
|
87
|
-
sungen map --screen login # 2. Map selectors with AI
|
|
88
|
-
sungen generate --screen login # 3. Generate Playwright tests
|
|
32
|
+
sungen generate --screen login
|
|
89
33
|
|
|
90
|
-
#
|
|
91
|
-
|
|
34
|
+
# Run tests
|
|
35
|
+
npx playwright test
|
|
92
36
|
```
|
|
93
37
|
|
|
94
38
|
---
|
|
95
39
|
|
|
96
|
-
##
|
|
40
|
+
## Gherkin Syntax
|
|
97
41
|
|
|
98
|
-
|
|
99
|
-
your-project/
|
|
100
|
-
├── app/ # Your React source
|
|
101
|
-
│ ├── auth/
|
|
102
|
-
│ │ └── page.tsx
|
|
103
|
-
│ └── chat/
|
|
104
|
-
│ └── page.tsx
|
|
105
|
-
│
|
|
106
|
-
├── qa/ # Input artifacts
|
|
107
|
-
│ └── screens/ # Screen definitions (NEW structure)
|
|
108
|
-
│ └── auth/
|
|
109
|
-
│ ├── features/ # Gherkin scenarios
|
|
110
|
-
│ │ └── login.feature
|
|
111
|
-
│ │ └── logout.feature
|
|
112
|
-
│ ├── selectors/ # Element mappings
|
|
113
|
-
│ │ └── login.yaml
|
|
114
|
-
│ │ └── logout.yaml
|
|
115
|
-
│ └── test-data/ # Test variables
|
|
116
|
-
│ └── login.yaml
|
|
117
|
-
│ └── logout.yaml
|
|
118
|
-
│
|
|
119
|
-
├── specs/ # Output artifacts (sibling to qa/)
|
|
120
|
-
│ ├── .auth/ # Authentication storage states (gitignored)
|
|
121
|
-
│ │ ├── .gitignore
|
|
122
|
-
│ │ ├── admin.json
|
|
123
|
-
│ │ └── user.json
|
|
124
|
-
│ ├── auth.setup.ts # Playwright auth setup (auto-generated)
|
|
125
|
-
│ └── generated/ # Generated Playwright tests
|
|
126
|
-
│ └── auth
|
|
127
|
-
│ ├── login.spec.ts
|
|
128
|
-
│ └── logout.spec.ts
|
|
129
|
-
│
|
|
130
|
-
└── sungen.config.yaml # Framework configuration
|
|
131
|
-
```
|
|
42
|
+
**Pattern**: `User + action + [element] type + with {{data}}`
|
|
132
43
|
|
|
44
|
+
**[Complete Gherkin Standard (English)](docs/gherkin%20standards/gherkin-core-standard.md)** | **[Tiếng Việt](docs/gherkin%20standards/gherkin-core-standard.vi.md)**
|
|
133
45
|
|
|
134
|
-
|
|
135
|
-
- Organized by screens: Each screen has its own directory
|
|
136
|
-
- Self-contained: Features, selectors, and test data grouped together
|
|
137
|
-
- Use `sungen add --screen <name>` to create new screen definitions
|
|
138
|
-
|
|
139
|
-
---
|
|
140
|
-
|
|
141
|
-
## 🎨 Gherkin Syntax
|
|
142
|
-
|
|
143
|
-
Sungen uses a **simple, natural language grammar** for Gherkin:
|
|
144
|
-
|
|
145
|
-
**Pattern**: `User + action + [element] + with {{data}}`
|
|
146
|
-
|
|
147
|
-
📘 **[Complete Gherkin Standard (English)](docs//gherkin%20standards/gherkin-core-standard.md)** | **[Tiếng Việt](docs/gherkin%20standards/gherkin-core-standard.vi.md)**
|
|
148
|
-
|
|
149
|
-
### Example Feature File
|
|
46
|
+
### Example
|
|
150
47
|
|
|
151
48
|
```gherkin
|
|
152
49
|
Feature: Login Screen
|
|
153
|
-
|
|
154
|
-
As a user
|
|
155
|
-
I want to interact with the Login screen
|
|
156
|
-
So that I can access my account
|
|
157
50
|
Path: /auth/login
|
|
158
51
|
|
|
159
|
-
@high
|
|
160
52
|
Scenario: User logs in successfully
|
|
161
|
-
Given User
|
|
53
|
+
Given User is on [Login] page
|
|
162
54
|
When User fill [Email] field with {{valid_email}}
|
|
163
55
|
And User fill [Password] field with {{valid_password}}
|
|
164
56
|
And User click [Login] button
|
|
165
|
-
Then User see [Welcome
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
### Grammar Rules
|
|
169
|
-
|
|
170
|
-
| Component | Syntax | Example |
|
|
171
|
-
|-----------|--------|---------|
|
|
172
|
-
| **Actor** | `User` | `User open page` |
|
|
173
|
-
| **Action** | `click`, `fill`, `see` | `User click [button]` |
|
|
174
|
-
| **Element** | `[element name]` | `[Email] field`, `[submit] button` |
|
|
175
|
-
| **Data** | `{{variable}}` | `{{valid_email}}`, `{{success.message}}` |
|
|
176
|
-
| **Path** | `Path: /route` | `Path: /auth/login` |
|
|
177
|
-
|
|
178
|
-
### Common Actions
|
|
179
|
-
|
|
180
|
-
```gherkin
|
|
181
|
-
# Navigation
|
|
182
|
-
Given User open page
|
|
183
|
-
|
|
184
|
-
# Input
|
|
185
|
-
When User fill [element] field with {{data}}
|
|
186
|
-
|
|
187
|
-
# Click
|
|
188
|
-
When User click [element] button
|
|
189
|
-
|
|
190
|
-
# Verification
|
|
191
|
-
Then User see [element] text with {{expected_text}}
|
|
192
|
-
```
|
|
193
|
-
|
|
194
|
-
### Test Data
|
|
195
|
-
|
|
196
|
-
Define variables in `test-data/<screen>.yaml`:
|
|
197
|
-
|
|
198
|
-
```yaml
|
|
199
|
-
# test-data/login.yaml
|
|
200
|
-
valid_email: "user@example.com"
|
|
201
|
-
valid_password: "SecurePassword123"
|
|
202
|
-
success:
|
|
203
|
-
message: "Welcome back!"
|
|
57
|
+
Then User see [Welcome] text with {{success_message}}
|
|
204
58
|
```
|
|
205
59
|
|
|
206
|
-
###
|
|
207
|
-
|
|
208
|
-
Sungen supports Playwright's authentication storage states via `@auth:{role}` tags, allowing you to reuse authenticated browser contexts across tests.
|
|
60
|
+
### Actions
|
|
209
61
|
|
|
210
|
-
|
|
62
|
+
| Action | Example |
|
|
63
|
+
|--------|---------|
|
|
64
|
+
| Navigate | `Given User is on [Login] page` |
|
|
65
|
+
| Open | `Given User open [Login] page` |
|
|
66
|
+
| Fill | `When User fill [Email] field with {{email}}` |
|
|
67
|
+
| Click | `When User click [Submit] button` |
|
|
68
|
+
| Select | `When User select [Country] dropdown with {{country}}` |
|
|
69
|
+
| See (visible) | `Then User see [Welcome] text` |
|
|
70
|
+
| See (with value) | `Then User see [Welcome] text with {{message}}` |
|
|
71
|
+
| See (hidden) | `Then User see [panel] dialog with {{title}} is hidden` |
|
|
72
|
+
| Wait for hidden | `And User wait for dialog with {{title}} is hidden` |
|
|
211
73
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
```gherkin
|
|
215
|
-
@auth:admin
|
|
216
|
-
Feature: User Management
|
|
217
|
-
|
|
218
|
-
Scenario: Delete user
|
|
219
|
-
Given User navigate to "/users"
|
|
220
|
-
When User click [delete-button]
|
|
221
|
-
Then User see [success-message]
|
|
222
|
-
|
|
223
|
-
@auth:user
|
|
224
|
-
Feature: Profile Settings
|
|
225
|
-
|
|
226
|
-
Scenario: Update email
|
|
227
|
-
Given User navigate to "/profile"
|
|
228
|
-
When User fill [email] field with {{new_email}}
|
|
229
|
-
```
|
|
74
|
+
### Annotations
|
|
230
75
|
|
|
231
|
-
|
|
76
|
+
| Syntax | Description |
|
|
77
|
+
|--------|-------------|
|
|
78
|
+
| `[Element]` | Selector reference (mapped via selectors YAML) |
|
|
79
|
+
| `{{variable}}` | Test data reference (mapped via test-data YAML) |
|
|
80
|
+
| `Path: /route` | Page route in feature description |
|
|
232
81
|
|
|
233
|
-
|
|
234
|
-
// user-management.spec.ts
|
|
235
|
-
test.use({ storageState: 'specs/.auth/admin.json' });
|
|
82
|
+
### Tags
|
|
236
83
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
84
|
+
| Tag | Level | Description |
|
|
85
|
+
|-----|-------|-------------|
|
|
86
|
+
| `@auth:<role>` | Feature/Scenario | Use Playwright auth storage state |
|
|
87
|
+
| `@no-auth` | Feature/Scenario | Disable inherited auth |
|
|
88
|
+
| `@steps:<name>` | Scenario | Mark as reusable step block |
|
|
89
|
+
| `@extend:<name>` | Scenario | Prepend steps from a `@steps` block |
|
|
90
|
+
| `@ignore` | Step (comment) | Skip step in generation |
|
|
91
|
+
| `@ignore-testcase` | Step (comment) | Skip entire scenario |
|
|
243
92
|
|
|
244
|
-
|
|
93
|
+
**Auth precedence**: Scenario > Feature > None
|
|
94
|
+
**@extend precedence**: Extending scenario `@auth` > Base scenario `@auth` > Feature `@auth`
|
|
245
95
|
|
|
246
|
-
|
|
96
|
+
### Reusable Steps with @steps / @extend
|
|
247
97
|
|
|
248
98
|
```gherkin
|
|
249
|
-
@auth:
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
On first `sungen generate` with `@auth` tags, an `auth.setup.ts` scaffold is auto-generated:
|
|
269
|
-
|
|
270
|
-
```bash
|
|
271
|
-
sungen generate --screen admin
|
|
272
|
-
|
|
273
|
-
# Output:
|
|
274
|
-
✓ Generated specs/auth.setup.ts - Update TODOs before running tests
|
|
275
|
-
✓ Created specs/.auth/ directory for storage states
|
|
276
|
-
Detected roles: admin, user, moderator
|
|
277
|
-
```
|
|
278
|
-
|
|
279
|
-
**Customize the generated setup file:**
|
|
280
|
-
|
|
281
|
-
```typescript
|
|
282
|
-
// specs/auth.setup.ts
|
|
283
|
-
import { test as setup } from '@playwright/test';
|
|
284
|
-
|
|
285
|
-
const authFile = (role: string) => `specs/.auth/${role}.json`;
|
|
286
|
-
|
|
287
|
-
setup('authenticate as admin', async ({ page }) => {
|
|
288
|
-
// TODO: Navigate to your login page
|
|
289
|
-
await page.goto('/login');
|
|
290
|
-
|
|
291
|
-
// TODO: Fill in credentials for admin role
|
|
292
|
-
await page.getByLabel('Email').fill('admin@example.com');
|
|
293
|
-
await page.getByLabel('Password').fill('admin123');
|
|
294
|
-
|
|
295
|
-
// TODO: Click login button
|
|
296
|
-
await page.getByRole('button', { name: 'Sign in' }).click();
|
|
297
|
-
|
|
298
|
-
// TODO: Wait for authentication to complete
|
|
299
|
-
await page.waitForURL('/dashboard');
|
|
300
|
-
|
|
301
|
-
// Save authentication state
|
|
302
|
-
await page.context().storageState({ path: authFile('admin') });
|
|
303
|
-
});
|
|
304
|
-
|
|
305
|
-
// Additional setup functions for other roles...
|
|
306
|
-
```
|
|
307
|
-
|
|
308
|
-
#### Features
|
|
309
|
-
|
|
310
|
-
- ✅ **Feature-level tags** - All scenarios inherit authentication
|
|
311
|
-
- ✅ **Scenario-level tags** - Override feature authentication
|
|
312
|
-
- ✅ **@no-auth tag** - Explicitly disable inherited authentication
|
|
313
|
-
- ✅ **Auto-generation** - Setup scaffold created on first use
|
|
314
|
-
- ✅ **Multiple roles** - Support unlimited authentication roles
|
|
315
|
-
- ✅ **Storage reuse** - Fast tests by reusing authenticated contexts
|
|
316
|
-
|
|
317
|
-
#### Notes
|
|
318
|
-
|
|
319
|
-
- Storage state files (`specs/.auth/*.json`) are gitignored by default
|
|
320
|
-
- Setup runs before tests via Playwright's global setup
|
|
321
|
-
- New roles detected after initial setup trigger a warning with manual update instructions
|
|
322
|
-
|
|
323
|
-
### Element Selectors
|
|
324
|
-
|
|
325
|
-
Map elements in `selectors/<screen>.yaml`:
|
|
326
|
-
|
|
327
|
-
```yaml
|
|
328
|
-
# selectors/login.yaml
|
|
329
|
-
email-input:
|
|
330
|
-
selector: ""
|
|
331
|
-
type: "testid"
|
|
332
|
-
|
|
333
|
-
submit-button:
|
|
334
|
-
selector: ""
|
|
335
|
-
type: "role"
|
|
336
|
-
value: "button"
|
|
337
|
-
```
|
|
338
|
-
|
|
339
|
-
---
|
|
340
|
-
|
|
341
|
-
## 🏗️ Architecture
|
|
342
|
-
|
|
99
|
+
@auth:user @steps:open-dialog
|
|
100
|
+
Scenario: Open kudos dialog
|
|
101
|
+
Given User is on [kudo] page
|
|
102
|
+
When User click [Notifications] button
|
|
103
|
+
And User click [Write Kudos] menuitem
|
|
104
|
+
Then User see [panel] dialog with {{kudo_title}}
|
|
105
|
+
|
|
106
|
+
@auth:user @extend:open-dialog
|
|
107
|
+
Scenario: User sends a thank you message
|
|
108
|
+
Given User is on [panel] dialog with {{kudo_title}}
|
|
109
|
+
When User fill [Search] field with {{teammate_name}}
|
|
110
|
+
And User click [teammate] row with {{teammate_name}}
|
|
111
|
+
And User fill [Message] textarea with {{message}}
|
|
112
|
+
And User click [Send] button
|
|
113
|
+
And User wait for dialog with {{kudo_title}} is hidden
|
|
114
|
+
Then User see [panel] modal with {{kudo_title}} is hidden
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
The `@extend:open-dialog` scenario automatically inherits all steps from `@steps:open-dialog` before its own steps.
|
|
343
118
|
|
|
344
119
|
---
|
|
345
120
|
|
|
346
|
-
##
|
|
121
|
+
## Project Structure
|
|
347
122
|
|
|
348
|
-
### `sungen init`
|
|
349
|
-
Initialize Sungen project structure
|
|
350
|
-
|
|
351
|
-
```bash
|
|
352
|
-
sungen init
|
|
353
|
-
```
|
|
354
|
-
|
|
355
|
-
Creates:
|
|
356
|
-
- `qa/screens/` directory for screen definitions
|
|
357
|
-
- `spec/generated/` directory for generated tests
|
|
358
|
-
- `playwright.config.ts` if it doesn't exist
|
|
359
|
-
- Updates `.gitignore` with Sungen patterns
|
|
360
|
-
|
|
361
|
-
### `sungen add --screen` ⭐ NEW
|
|
362
|
-
Create a new screen definition with scaffolded files. Supports multiple test scenarios per screen.
|
|
363
|
-
|
|
364
|
-
```bash
|
|
365
|
-
sungen add --screen <name> [options]
|
|
366
|
-
|
|
367
|
-
Options:
|
|
368
|
-
--screen <name> Screen name (required)
|
|
369
|
-
-p, --path <path> Screen route path - also controls filename
|
|
370
|
-
-d, --description Screen description
|
|
371
|
-
|
|
372
|
-
Examples:
|
|
373
|
-
# Create screen with default file
|
|
374
|
-
sungen add --screen login
|
|
375
|
-
|
|
376
|
-
# Create screen with custom path/filename
|
|
377
|
-
sungen add --screen login --path /login-valid --description "Valid login"
|
|
378
|
-
|
|
379
|
-
# Add additional test scenarios to existing screen
|
|
380
|
-
sungen add --screen login --path /login-invalid
|
|
381
|
-
sungen add --screen login --path /login-mfa
|
|
382
|
-
```
|
|
383
|
-
|
|
384
|
-
**What it does:**
|
|
385
|
-
- **First call**: Creates `qa/screens/<name>/` directory structure
|
|
386
|
-
- **Subsequent calls**: Adds additional feature files to existing screen
|
|
387
|
-
- Generates `features/<filename>.feature` with Gherkin template
|
|
388
|
-
- Generates `selectors/<filename>.yaml` with selector structure
|
|
389
|
-
- Generates `test-data/<filename>.yaml` for test variables
|
|
390
|
-
- **Path option**: Controls both filename and Path metadata in feature file
|
|
391
|
-
|
|
392
|
-
**Multi-file workflow** (organizing test scenarios):
|
|
393
|
-
```bash
|
|
394
|
-
# Create base screen
|
|
395
|
-
sungen add --screen login
|
|
396
|
-
|
|
397
|
-
# Add valid login scenario
|
|
398
|
-
sungen add --screen login --path /login-valid
|
|
399
|
-
|
|
400
|
-
# Add invalid credentials scenario
|
|
401
|
-
sungen add --screen login --path /login-invalid
|
|
402
|
-
|
|
403
|
-
# Add 2FA scenario
|
|
404
|
-
sungen add --screen login --path /login-mfa
|
|
405
123
|
```
|
|
124
|
+
qa/screens/<name>/
|
|
125
|
+
├── features/ # Gherkin .feature files
|
|
126
|
+
├── selectors/ # Element mappings (.yaml + .override.yaml)
|
|
127
|
+
└── test-data/ # Test variables (.yaml + .override.yaml)
|
|
406
128
|
|
|
407
|
-
|
|
129
|
+
specs/generated/<name>/
|
|
130
|
+
└── <feature>.spec.ts # Generated Playwright tests
|
|
408
131
|
```
|
|
409
|
-
qa/screens/login/
|
|
410
|
-
├── features/
|
|
411
|
-
│ ├── login.feature
|
|
412
|
-
│ ├── login-valid.feature
|
|
413
|
-
│ ├── login-invalid.feature
|
|
414
|
-
│ └── login-mfa.feature
|
|
415
|
-
├── selectors/
|
|
416
|
-
│ ├── login.yaml
|
|
417
|
-
│ ├── login-valid.yaml
|
|
418
|
-
│ ├── login-invalid.yaml
|
|
419
|
-
│ └── login-mfa.yaml
|
|
420
|
-
└── test-data/
|
|
421
|
-
├── login.yaml
|
|
422
|
-
├── login-valid.yaml
|
|
423
|
-
├── login-invalid.yaml
|
|
424
|
-
└── login-mfa.yaml
|
|
425
|
-
```
|
|
426
|
-
|
|
427
|
-
**Backward compatible**: Default behavior (no `--path`) creates single file named after screen.
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
### `sungen map`
|
|
431
|
-
Map Gherkin references to actual selectors using AI
|
|
432
|
-
|
|
433
|
-
```bash
|
|
434
|
-
sungen map --screen <screen-name> [options]
|
|
435
|
-
|
|
436
|
-
Options:
|
|
437
|
-
--screen <name> Screen name to map (required)
|
|
438
|
-
--all Map all screens
|
|
439
|
-
--force Force regeneration, bypass cache, overwrite existing files
|
|
440
|
-
--verbose Detailed output
|
|
441
|
-
```
|
|
442
|
-
|
|
443
|
-
**Output:** Processes each feature file individually, generating separate YAML files for each:
|
|
444
|
-
|
|
445
|
-
```
|
|
446
|
-
Mapping screen: login
|
|
447
|
-
|
|
448
|
-
✓ Mapped login.feature
|
|
449
|
-
→ selectors/login.yaml (5 elements)
|
|
450
|
-
→ test-data/login.yaml (3 variables)
|
|
451
|
-
|
|
452
|
-
✓ Mapped login-valid.feature
|
|
453
|
-
→ selectors/login-valid.yaml (3 elements)
|
|
454
|
-
→ test-data/login-valid.yaml (2 variables)
|
|
455
|
-
|
|
456
|
-
Next step: sungen generate --screen login
|
|
457
|
-
```
|
|
458
|
-
|
|
459
|
-
**Multi-file support:** Each `.feature` file generates matching `.yaml` files, maintaining clean separation between test scenarios.
|
|
460
|
-
|
|
461
|
-
### `sungen generate`
|
|
462
|
-
Generate Playwright test code from features
|
|
463
|
-
|
|
464
|
-
```bash
|
|
465
|
-
sungen generate [options]
|
|
466
|
-
|
|
467
|
-
Options:
|
|
468
|
-
--ai-mapper Enable AI fallback for unknown Gherkin patterns
|
|
469
|
-
--framework <name> Test framework (playwright, appium, integration) - default: playwright
|
|
470
|
-
-s, --screen <name> Filter generation to specific screen (recommended)
|
|
471
|
-
-f, --force Force regeneration, bypass cache
|
|
472
|
-
|
|
473
|
-
Examples:
|
|
474
|
-
sungen generate --screen login # Generate tests for login screen
|
|
475
|
-
sungen generate -s login --force # Force regenerate login screen tests
|
|
476
|
-
sungen generate # Generate all tests (legacy)
|
|
477
|
-
```
|
|
478
|
-
|
|
479
|
-
**Output:** Shows per-file results with step counts:
|
|
480
|
-
|
|
481
|
-
```
|
|
482
|
-
Generating tests: login
|
|
483
|
-
|
|
484
|
-
✓ Generated login.spec.ts
|
|
485
|
-
→ spec/generated/login/login.spec.ts (8 steps)
|
|
486
|
-
|
|
487
|
-
✓ Generated login-valid.spec.ts
|
|
488
|
-
→ spec/generated/login/login-valid.spec.ts (5 steps)
|
|
489
132
|
|
|
490
|
-
|
|
491
|
-
→ spec/generated/login/login-invalid.spec.ts (3 steps)
|
|
492
|
-
|
|
493
|
-
Next step: npx playwright test
|
|
494
|
-
```
|
|
495
|
-
|
|
496
|
-
**Selector Merging:** Supports optional base + feature-specific selector files:
|
|
497
|
-
- **Base file**: `selectors/<screen>.yaml` - Shared selectors for all scenarios
|
|
498
|
-
- **Feature file**: `selectors/<feature-name>.yaml` - Scenario-specific selectors (required)
|
|
499
|
-
- Feature-specific selectors override base selectors when keys conflict
|
|
500
|
-
|
|
501
|
-
**Validation:** Checks for missing selector files before generation and suggests running `map` command if needed.
|
|
502
|
-
|
|
503
|
-
### `sungen full`
|
|
504
|
-
Run complete pipeline (discover + map + generate)
|
|
505
|
-
|
|
506
|
-
```bash
|
|
507
|
-
sungen full [options]
|
|
508
|
-
|
|
509
|
-
Options:
|
|
510
|
-
--screen <name> Process specific screen (optional)
|
|
511
|
-
--depth <num> Max component depth
|
|
512
|
-
--force Force regeneration
|
|
513
|
-
--verbose Detailed output
|
|
514
|
-
```
|
|
515
|
-
|
|
516
|
-
### `sungen cache-clear`
|
|
517
|
-
Clear all cached data
|
|
518
|
-
|
|
519
|
-
```bash
|
|
520
|
-
sungen cache-clear
|
|
521
|
-
```
|
|
522
|
-
|
|
523
|
-
### `sungen makeauth` ⭐ NEW
|
|
524
|
-
Generate authentication state for login sessions (supports SSO and manual login)
|
|
525
|
-
|
|
526
|
-
```bash
|
|
527
|
-
sungen makeauth <name> [options]
|
|
528
|
-
|
|
529
|
-
Options:
|
|
530
|
-
-u, --url <url> Base URL of the application (auto-detected from playwright.config.ts)
|
|
531
|
-
-p, --path <path> Login page path (default: /login)
|
|
532
|
-
-o, --output <dir> Output directory (default: specs/.auth)
|
|
533
|
-
-t, --timeout <ms> Overall timeout in milliseconds (default: 180000)
|
|
534
|
-
--nav-timeout <ms> Navigation timeout in milliseconds (default: 180000)
|
|
535
|
-
--stability-wait <ms> URL stability wait in milliseconds (default: 5000)
|
|
536
|
-
--headless Run browser in headless mode
|
|
537
|
-
--verify Verify existing auth state is still valid
|
|
538
|
-
--list List all existing auth states
|
|
539
|
-
--export Export auth state as base64 for CI
|
|
540
|
-
|
|
541
|
-
Examples:
|
|
542
|
-
sungen makeauth user # Create auth state for 'user' role
|
|
543
|
-
sungen makeauth admin --url http://localhost:3000
|
|
544
|
-
sungen makeauth admin --path /auth/signin
|
|
545
|
-
sungen makeauth admin --list # List all auth states
|
|
546
|
-
sungen makeauth admin --verify # Check if auth is still valid
|
|
547
|
-
```
|
|
548
|
-
|
|
549
|
-
**What it does:**
|
|
550
|
-
- Opens a browser window for manual login (including SSO providers like Google, GitHub, etc.)
|
|
551
|
-
- Saves authentication state (cookies, localStorage, sessionStorage) to `specs/.auth/<name>.json`
|
|
552
|
-
- Can be used in Playwright tests to skip login process and maintain sessions
|
|
553
|
-
- Supports multiple auth roles (admin, user, guest, etc.)
|
|
554
|
-
|
|
555
|
-
**Using auth state in tests:**
|
|
556
|
-
```typescript
|
|
557
|
-
// playwright.config.ts
|
|
558
|
-
export default defineConfig({
|
|
559
|
-
projects: [
|
|
560
|
-
{
|
|
561
|
-
name: 'authenticated',
|
|
562
|
-
use: {
|
|
563
|
-
storageState: 'specs/.auth/user.json',
|
|
564
|
-
},
|
|
565
|
-
},
|
|
566
|
-
],
|
|
567
|
-
});
|
|
568
|
-
```
|
|
569
|
-
|
|
570
|
-
See [docs/makeauth.md](docs/makeauth.md) for complete documentation.
|
|
571
|
-
|
|
572
|
-
### `sungen auto-tag` ⭐ NEW
|
|
573
|
-
Auto-inject stable `data-testid` attributes into source code
|
|
574
|
-
|
|
575
|
-
```bash
|
|
576
|
-
sungen auto-tag [options]
|
|
577
|
-
|
|
578
|
-
Options:
|
|
579
|
-
--screen <name> Tag specific screen (optional, defaults to all)
|
|
580
|
-
--dry-run Preview changes without modifying files
|
|
581
|
-
--force Overwrite existing data-testid (use with caution)
|
|
582
|
-
--verbose Show detailed changes
|
|
583
|
-
|
|
584
|
-
Examples:
|
|
585
|
-
sungen auto-tag --screen login --dry-run # Preview changes
|
|
586
|
-
sungen auto-tag --screen login # Apply changes
|
|
587
|
-
sungen auto-tag # Tag all screens
|
|
588
|
-
```
|
|
589
|
-
|
|
590
|
-
**What it does:**
|
|
591
|
-
- Scans React/Vue/HTML source code for interactive elements
|
|
592
|
-
- Injects `data-testid="screen-element"` attributes
|
|
593
|
-
- Idempotent (skips if `data-testid` already exists)
|
|
594
|
-
- Preserves code formatting (Prettier/ESLint compatible)
|
|
595
|
-
|
|
596
|
-
**Before:**
|
|
597
|
-
```tsx
|
|
598
|
-
<input type="email" name="email" />
|
|
599
|
-
<button onClick={handleSubmit}>Login</button>
|
|
600
|
-
```
|
|
601
|
-
|
|
602
|
-
**After:**
|
|
603
|
-
```tsx
|
|
604
|
-
<input type="email" name="email" data-testid="login-email-input" />
|
|
605
|
-
<button onClick={handleSubmit} data-testid="login-submit-btn">Login</button>
|
|
606
|
-
```
|
|
133
|
+
Override files (`.override.yaml`) are never overwritten by `sungen map` and take precedence at runtime.
|
|
607
134
|
|
|
608
135
|
---
|
|
609
136
|
|
|
610
|
-
##
|
|
137
|
+
## CLI Commands
|
|
611
138
|
|
|
612
|
-
|
|
139
|
+
| Command | Description |
|
|
140
|
+
|---------|-------------|
|
|
141
|
+
| `sungen init` | Initialize project structure |
|
|
142
|
+
| `sungen add --screen <name> [--path <path>]` | Create screen definition |
|
|
143
|
+
| `sungen map --screen <name> [--force]` | Generate selector/test-data YAML from Gherkin |
|
|
144
|
+
| `sungen generate --screen <name> [--force]` | Generate Playwright .spec.ts |
|
|
145
|
+
| `sungen full --screen <name>` | Run all: discover → map → generate |
|
|
146
|
+
| `sungen auto-tag --screen <name> [--dry-run]` | Inject `data-testid` into source code |
|
|
147
|
+
| `sungen makeauth <role>` | Save browser auth state (supports SSO) |
|
|
148
|
+
| `sungen validate --screen <name>` | Validate features and mappings |
|
|
149
|
+
| `sungen cache-clear` | Clear cached data |
|
|
613
150
|
|
|
614
|
-
|
|
615
|
-
- More examples coming soon!
|
|
151
|
+
Use `sungen <command> -h` for detailed options.
|
|
616
152
|
|
|
617
153
|
---
|
|
618
154
|
|
|
619
|
-
##
|
|
620
|
-
|
|
621
|
-
### Getting Started
|
|
622
|
-
- **[Documentation Index](docs/README.md)** - Start here for all documentation
|
|
623
|
-
- **[Implementation Guide](docs/IMPLEMENTATION_GUIDE.md)** ⭐ **Core reference**
|
|
624
|
-
- Kim chỉ nam (North Star Principles)
|
|
625
|
-
- Architecture overview
|
|
626
|
-
- Implementation roadmap
|
|
627
|
-
- Best practices
|
|
628
|
-
|
|
629
|
-
### Core Guides
|
|
630
|
-
- **[System Overview](docs/SYSTEM_OVERVIEW.md)** - High-level architecture
|
|
631
|
-
- **[Gherkin Core Standard](docs/gherkin-core-standard.md)** ⭐ **Must Read** - Complete Gherkin syntax rules ([Tiếng Việt](docs/gherkin-core-standard.vi.md))
|
|
632
|
-
- **[Gherkin Standards](docs/GHERKIN_STANDARDS.md)** - Extended conventions and examples
|
|
633
|
-
- **[Selector Override Guide](docs/SELECTOR_OVERRIDE_GUIDE.md)** - How to fix AI mapping errors
|
|
634
|
-
- **[Debugging Guide](docs/DEBUGGING_GUIDE.md)** - Troubleshooting common issues
|
|
635
|
-
|
|
636
|
-
### Recent Updates
|
|
637
|
-
- **[Improvement Summary](docs/IMPROVEMENT_SUMMARY.md)** - Latest fixes and improvements (Dec 2025)
|
|
638
|
-
- Test results: 1 → 6 passed (+500%)
|
|
639
|
-
- Selector override mechanism
|
|
640
|
-
- Heuristic mapper implementation
|
|
641
|
-
- Complete test-data structure
|
|
642
|
-
|
|
643
|
-
### Quick Links
|
|
644
|
-
- **For QA**: Start with [Gherkin Core Standard](docs/gherkin-core-standard.md) ([Vietnamese](docs/gherkin-core-standard.vi.md))
|
|
645
|
-
- **For Developers**: Read [Implementation Guide](docs/IMPLEMENTATION_GUIDE.md)
|
|
646
|
-
- **Fix AI Errors**: Use [Selector Override](docs/SELECTOR_OVERRIDE_GUIDE.md)
|
|
155
|
+
## Documentation
|
|
647
156
|
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
157
|
+
- **[Gherkin Core Standard](docs/gherkin%20standards/gherkin-core-standard.md)** - Complete syntax rules ([Tiếng Việt](docs/gherkin%20standards/gherkin-core-standard.vi.md))
|
|
158
|
+
- **[Pattern Reference](docs/pattern-reference.md)** - All 31 supported step patterns
|
|
159
|
+
- **[Selector Override Guide](docs/selector-override.md)** - Fix AI mapping errors
|
|
160
|
+
- **[Auth Setup Guide](docs/makeauth.md)** - Configure authentication states
|
|
161
|
+
- **[Validation Guide](docs/validate.md)** - Validate Gherkin files
|
|
162
|
+
- **[Windows Setup Guide](WINDOWS-SETUP-GUIDE.md)** - Step-by-step for Windows users
|
|
653
163
|
|
|
654
164
|
---
|
|
655
165
|
|
|
656
|
-
##
|
|
166
|
+
## License
|
|
657
167
|
|
|
658
|
-
MIT License - see LICENSE file for details
|
|
659
|
-
|
|
660
|
-
---
|
|
661
|
-
|
|
662
|
-
## 🙏 Credits
|
|
663
|
-
|
|
664
|
-
- Built with [Claude Sonnet 4.5](https://www.anthropic.com/claude)
|
|
665
|
-
- Uses [@anthropic-ai/sdk](https://github.com/anthropics/anthropic-sdk-typescript)
|
|
666
|
-
- Powered by [Playwright](https://playwright.dev/)
|
|
667
|
-
- Gherkin parsing by [@cucumber/gherkin](https://github.com/cucumber/gherkin)
|
|
668
|
-
|
|
669
|
-
---
|
|
168
|
+
MIT License - see LICENSE file for details.
|
|
670
169
|
|
|
671
170
|
**Made with ❤️ by Bach Ngoc Hoai**
|