@sun-asterisk/sungen 2.0.2 → 2.1.0
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 +2 -2
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +3 -2
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/unknown-element-action.hbs +1 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/disabled-with-role-variable-assertion.hbs +2 -2
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/disabled-with-variable-assertion.hbs +1 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/hidden-with-role-variable-assertion.hbs +2 -2
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/hidden-with-variable-assertion.hbs +1 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-with-role-variable-assertion.hbs +3 -3
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-with-value-assertion.hbs +1 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-with-variable-assertion.hbs +1 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/partials/locator-nth.hbs +1 -1
- package/dist/generators/test-generator/patterns/assertion-patterns.d.ts.map +1 -1
- package/dist/generators/test-generator/patterns/assertion-patterns.js +12 -13
- package/dist/generators/test-generator/patterns/assertion-patterns.js.map +1 -1
- package/dist/generators/test-generator/patterns/interaction-patterns.js +4 -4
- package/dist/generators/test-generator/patterns/interaction-patterns.js.map +1 -1
- package/dist/generators/test-generator/utils/selector-resolver.js +14 -14
- package/dist/generators/test-generator/utils/selector-resolver.js.map +1 -1
- package/dist/orchestrator/project-initializer.d.ts +3 -6
- package/dist/orchestrator/project-initializer.d.ts.map +1 -1
- package/dist/orchestrator/project-initializer.js +62 -58
- package/dist/orchestrator/project-initializer.js.map +1 -1
- package/dist/orchestrator/screen-manager.d.ts.map +1 -1
- package/dist/orchestrator/screen-manager.js +0 -1
- package/dist/orchestrator/screen-manager.js.map +1 -1
- package/dist/orchestrator/templates/ai-instructions/claude-cmd-add-screen.md +42 -0
- package/dist/orchestrator/templates/ai-instructions/claude-cmd-make-tc.md +60 -0
- package/dist/orchestrator/templates/ai-instructions/claude-cmd-make-test.md +59 -0
- package/dist/orchestrator/templates/ai-instructions/claude-config.md +90 -0
- package/dist/orchestrator/templates/ai-instructions/claude-skill-error-mapping.md +27 -0
- package/dist/orchestrator/templates/ai-instructions/claude-skill-gherkin-syntax.md +123 -0
- package/dist/orchestrator/templates/ai-instructions/claude-skill-selector-keys.md +94 -0
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-add-screen.md +41 -0
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-make-tc.md +59 -0
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-make-test.md +58 -0
- package/dist/orchestrator/templates/ai-instructions/copilot-config.md +90 -0
- package/dist/orchestrator/templates/ai-instructions/copilot-skill-error-mapping.md +27 -0
- package/dist/orchestrator/templates/ai-instructions/copilot-skill-gherkin-syntax.md +123 -0
- package/dist/orchestrator/templates/ai-instructions/copilot-skill-selector-keys.md +94 -0
- package/dist/orchestrator/templates/readme.md +43 -39
- package/docs/gherkin standards/gherkin-core-standard.md +141 -90
- package/docs/gherkin standards/gherkin-core-standard.vi.md +264 -54
- package/package.json +2 -2
- package/src/cli/commands/init.ts +3 -2
- package/src/cli/index.ts +1 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/actions/unknown-element-action.hbs +1 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/disabled-with-role-variable-assertion.hbs +2 -2
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/disabled-with-variable-assertion.hbs +1 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/hidden-with-role-variable-assertion.hbs +2 -2
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/hidden-with-variable-assertion.hbs +1 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-with-role-variable-assertion.hbs +3 -3
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-with-value-assertion.hbs +1 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-with-variable-assertion.hbs +1 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/partials/locator-nth.hbs +1 -1
- package/src/generators/test-generator/patterns/assertion-patterns.ts +12 -13
- package/src/generators/test-generator/patterns/interaction-patterns.ts +4 -4
- package/src/generators/test-generator/utils/selector-resolver.ts +15 -15
- package/src/orchestrator/project-initializer.ts +74 -58
- package/src/orchestrator/screen-manager.ts +0 -1
- package/src/orchestrator/templates/ai-instructions/claude-cmd-add-screen.md +42 -0
- package/src/orchestrator/templates/ai-instructions/claude-cmd-make-tc.md +60 -0
- package/src/orchestrator/templates/ai-instructions/claude-cmd-make-test.md +59 -0
- package/src/orchestrator/templates/ai-instructions/claude-config.md +90 -0
- package/src/orchestrator/templates/ai-instructions/claude-skill-error-mapping.md +27 -0
- package/src/orchestrator/templates/ai-instructions/claude-skill-gherkin-syntax.md +123 -0
- package/src/orchestrator/templates/ai-instructions/claude-skill-selector-keys.md +94 -0
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-add-screen.md +41 -0
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-make-tc.md +59 -0
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-make-test.md +58 -0
- package/src/orchestrator/templates/ai-instructions/copilot-config.md +90 -0
- package/src/orchestrator/templates/ai-instructions/copilot-skill-error-mapping.md +27 -0
- package/src/orchestrator/templates/ai-instructions/copilot-skill-gherkin-syntax.md +123 -0
- package/src/orchestrator/templates/ai-instructions/copilot-skill-selector-keys.md +94 -0
- package/src/orchestrator/templates/readme.md +43 -39
- package/dist/orchestrator/templates/ai-rules.md +0 -189
- package/src/orchestrator/templates/ai-rules.md +0 -189
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: 'Rules for generating correct YAML selector keys from Gherkin [Reference] names. Referenced by other sungen prompts when creating or fixing selectors.yaml files.'
|
|
3
|
+
mode: 'agent'
|
|
4
|
+
tools: []
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Key Generation: `[Reference]` → YAML key
|
|
8
|
+
|
|
9
|
+
Transform: Vietnamese/Japanese → ASCII → lowercase → remove special chars → spaces to dots.
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
[Submit] → submit
|
|
13
|
+
[Search Content] → search.content
|
|
14
|
+
[User's Profile] → users.profile
|
|
15
|
+
[Thời gian] → thoi.gian
|
|
16
|
+
[Địa điểm] → dia.diem
|
|
17
|
+
[ログイン] → roguin
|
|
18
|
+
[パスワード] → pasuwaado
|
|
19
|
+
[Page 2] → page.2
|
|
20
|
+
[Kudos Detail Modal] → kudos.detail.modal
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
**Rules:**
|
|
24
|
+
1. Remove Vietnamese diacritics: `ằắẳẵặ` → `a`, `đ` → `d`, etc.
|
|
25
|
+
2. Convert Japanese Hiragana/Katakana to Romaji
|
|
26
|
+
3. Lowercase everything
|
|
27
|
+
4. `'s` → `s` (apostrophe-s becomes just s)
|
|
28
|
+
5. Remove all special chars except spaces
|
|
29
|
+
6. Trim, then spaces → dots
|
|
30
|
+
7. **NEVER use spaces, underscores, or uppercase in YAML keys**
|
|
31
|
+
|
|
32
|
+
## Type-Suffixed Keys
|
|
33
|
+
|
|
34
|
+
When the same label is used for different element types, add `--type` suffix:
|
|
35
|
+
|
|
36
|
+
```yaml
|
|
37
|
+
# [Add Campaign] button AND [Add Campaign] text
|
|
38
|
+
add.campaign--button:
|
|
39
|
+
type: 'role'
|
|
40
|
+
value: 'button'
|
|
41
|
+
name: 'Add Campaign'
|
|
42
|
+
|
|
43
|
+
add.campaign--text:
|
|
44
|
+
type: 'text'
|
|
45
|
+
value: 'Add Campaign'
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Type aliases (normalized automatically):
|
|
49
|
+
| Gherkin type | Normalized suffix |
|
|
50
|
+
|---|---|
|
|
51
|
+
| title, label, caption, message | `text` |
|
|
52
|
+
| heading, header | `heading` |
|
|
53
|
+
| logo, image, icon | `img` |
|
|
54
|
+
| btn | `button` |
|
|
55
|
+
| input, textbox, textarea, editor | `field` |
|
|
56
|
+
| column | `columnheader` |
|
|
57
|
+
| list-item | `listitem` |
|
|
58
|
+
|
|
59
|
+
## Nth-Suffixed Keys
|
|
60
|
+
|
|
61
|
+
When targeting a specific occurrence by index, add `--N` suffix:
|
|
62
|
+
|
|
63
|
+
```yaml
|
|
64
|
+
# [Send Thank You] button 3
|
|
65
|
+
hay.gui.loi.cam.on--3:
|
|
66
|
+
type: 'role'
|
|
67
|
+
value: 'button'
|
|
68
|
+
name: 'Send Thank You'
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Lookup Priority
|
|
72
|
+
|
|
73
|
+
Resolver searches in this order:
|
|
74
|
+
1. `key--N` (nth-suffixed)
|
|
75
|
+
2. `key--type` (type-suffixed, normalized)
|
|
76
|
+
3. `key` (base key)
|
|
77
|
+
4. Auto-infer from element type if no YAML entry
|
|
78
|
+
5. Any `key--*` (first suffixed match)
|
|
79
|
+
|
|
80
|
+
## Auto-Infer (no YAML entry needed)
|
|
81
|
+
|
|
82
|
+
If no YAML key exists, the resolver infers from the Gherkin element type:
|
|
83
|
+
|
|
84
|
+
| Gherkin | Inferred locator |
|
|
85
|
+
|---|---|
|
|
86
|
+
| `[X] button` | `getByRole('button', { name: 'X' })` |
|
|
87
|
+
| `[X] link` | `getByRole('link', { name: 'X' })` |
|
|
88
|
+
| `[X] heading` | `getByRole('heading', { name: 'X' })` |
|
|
89
|
+
| `[X] checkbox` | `getByRole('checkbox', { name: 'X' })` |
|
|
90
|
+
| `[X] field` | `getByPlaceholder('X')` |
|
|
91
|
+
| `[X] text` | `getByText('X')` |
|
|
92
|
+
| `[X] logo/image/icon` | `getByRole('img', { name: 'X' })` |
|
|
93
|
+
|
|
94
|
+
**Only add a YAML entry when** the auto-inferred locator won't work (wrong name, need testid, need nth, etc.).
|
|
@@ -19,8 +19,6 @@ sungen generate → compiles Gherkin + selectors + data → Playwright .spec.ts
|
|
|
19
19
|
├── specs/
|
|
20
20
|
│ ├── generated/ # Auto-generated Playwright tests
|
|
21
21
|
│ └── .auth/ # Auth storage states
|
|
22
|
-
├── docs/
|
|
23
|
-
│ └── gherkin-dictionary.md # Full grammar & compiler rules
|
|
24
22
|
├── .github/
|
|
25
23
|
│ └── copilot-instructions.md # AI rules for GitHub Copilot
|
|
26
24
|
└── CLAUDE.md # AI rules for Claude Code
|
|
@@ -28,55 +26,62 @@ sungen generate → compiles Gherkin + selectors + data → Playwright .spec.ts
|
|
|
28
26
|
|
|
29
27
|
## Workflow
|
|
30
28
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
29
|
+
```
|
|
30
|
+
Step 1 Step 2 Step 3
|
|
31
|
+
┌──────────┐ ┌──────────┐ ┌──────────┐
|
|
32
|
+
│ /add- │────────▶│ /make-tc │────────▶│ /make- │
|
|
33
|
+
│ screen │ │ │ │ test │
|
|
34
|
+
└──────────┘ └──────────┘ └──────────┘
|
|
35
|
+
Scaffold Design TCs Compile &
|
|
36
|
+
directories & generate run tests
|
|
37
|
+
3 files
|
|
37
38
|
```
|
|
38
39
|
|
|
39
|
-
|
|
40
|
+
Use AI commands (Claude Code or GitHub Copilot) to drive the workflow:
|
|
40
41
|
|
|
41
|
-
|
|
42
|
-
sungen makeauth admin
|
|
43
|
-
# Opens browser → login manually → saves specs/.auth/admin.json
|
|
44
|
-
```
|
|
42
|
+
### Step 1: Add a screen
|
|
45
43
|
|
|
46
|
-
|
|
44
|
+
| Claude Code | GitHub Copilot |
|
|
45
|
+
|---|---|
|
|
46
|
+
| `/sungen:add-screen login /login` | `@workspace /sungen-add-screen login /login` |
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
1. Navigate to the page URL via MCP Playwright
|
|
50
|
-
2. Take an accessibility snapshot
|
|
51
|
-
3. Generate `.feature` + `selectors.yaml` + `test-data.yaml`
|
|
48
|
+
Scaffolds `qa/screens/<name>/` with empty feature, selectors, and test-data files, then asks if you want to create test cases.
|
|
52
49
|
|
|
53
|
-
|
|
54
|
-
how to write correct Gherkin syntax and selector YAML for sungen.
|
|
50
|
+
### Step 2: Create test cases
|
|
55
51
|
|
|
56
|
-
|
|
52
|
+
| Claude Code | GitHub Copilot |
|
|
53
|
+
|---|---|
|
|
54
|
+
| `/sungen:make-tc login` | `@workspace /sungen-make-tc login` |
|
|
57
55
|
|
|
58
|
-
|
|
59
|
-
sungen generate --screen login
|
|
60
|
-
# or for all screens:
|
|
61
|
-
sungen generate --all
|
|
62
|
-
```
|
|
56
|
+
AI acts as a **Senior QA Engineer**: explores the live page (via Playwright MCP) or analyzes static designs, gathers test viewpoints (UI/UX, Validation, Logic, Security), and generates the 3 files.
|
|
63
57
|
|
|
64
|
-
###
|
|
58
|
+
### Step 3: Compile & run tests
|
|
59
|
+
|
|
60
|
+
| Claude Code | GitHub Copilot |
|
|
61
|
+
|---|---|
|
|
62
|
+
| `/sungen:make-test login` | `@workspace /sungen-make-test login` |
|
|
63
|
+
|
|
64
|
+
AI acts as a **Senior Developer**: compiles Gherkin → Playwright `.spec.ts`, runs tests, and auto-fixes selectors/test-data on failure (up to 5 attempts).
|
|
65
|
+
|
|
66
|
+
### Auth setup (if needed)
|
|
67
|
+
|
|
68
|
+
If any page requires authentication, run manually before Step 2:
|
|
65
69
|
|
|
66
70
|
```bash
|
|
67
|
-
|
|
68
|
-
|
|
71
|
+
sungen makeauth admin --url <baseURL>
|
|
72
|
+
# Opens browser → login manually → saves specs/.auth/admin.json
|
|
69
73
|
```
|
|
70
74
|
|
|
71
|
-
###
|
|
72
|
-
|
|
73
|
-
When tests fail, use AI to read the error → fix `selectors.yaml` → recompile → re-run.
|
|
75
|
+
### Manual CLI commands
|
|
74
76
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
77
|
+
```bash
|
|
78
|
+
sungen add --screen <name> --path <path> # Scaffold screen
|
|
79
|
+
sungen add --screen <name> --feature <name> # Add feature to screen
|
|
80
|
+
sungen generate --screen <name> # Compile to .spec.ts
|
|
81
|
+
sungen generate --all # Compile all screens
|
|
82
|
+
npx playwright test # Run all tests
|
|
83
|
+
npx playwright test --ui # Interactive mode
|
|
84
|
+
```
|
|
80
85
|
|
|
81
86
|
---
|
|
82
87
|
|
|
@@ -180,7 +185,7 @@ submit.button:
|
|
|
180
185
|
type: 'role' # testid, role, text, label, placeholder, locator, page
|
|
181
186
|
value: 'button' # role name, testid value, CSS selector, etc.
|
|
182
187
|
name: 'Submit' # accessible name
|
|
183
|
-
nth: 0 # element index
|
|
188
|
+
nth: 0 # element index, 0-indexed (omit for strict mode)
|
|
184
189
|
exact: true # exact name match (avoid "Submit" matching "Submit Form")
|
|
185
190
|
scope: 'desktop navigation' # scope to parent landmark
|
|
186
191
|
match: 'exact' # exact text match for getByText
|
|
@@ -192,6 +197,5 @@ Locator priority: `data-testid` > `role+name` > `label` > `text` > `CSS`
|
|
|
192
197
|
|
|
193
198
|
## Documentation
|
|
194
199
|
|
|
195
|
-
- [Gherkin Dictionary](docs/gherkin-dictionary.md) — full grammar, all 17 patterns, compiler rules
|
|
196
200
|
- [Sungen GitHub](https://github.com/sun-asterisk/sungen)
|
|
197
201
|
- [Playwright Documentation](https://playwright.dev)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Gherkin Standard - Core (
|
|
1
|
+
# Gherkin Standard - Core (v2)
|
|
2
2
|
|
|
3
3
|
**Applies to: Manual Testing & Automation Testing**
|
|
4
4
|
|
|
@@ -36,13 +36,14 @@ Scenario: User logs in successfully with valid credentials
|
|
|
36
36
|
|
|
37
37
|
### Format
|
|
38
38
|
```
|
|
39
|
-
|
|
39
|
+
[Keyword] User <Action> [<Target>] <Target Type> <with {{Value}}> <is State>
|
|
40
40
|
```
|
|
41
41
|
|
|
42
42
|
### Rules
|
|
43
43
|
- ✅ `Actor` + `Action` are **mandatory**
|
|
44
|
-
- ✅ `Target` is **required** for most actions (except `
|
|
44
|
+
- ✅ `Target` is **required** for most actions (except `wait for N seconds`)
|
|
45
45
|
- ✅ `with {{Value}}` only used when action requires data
|
|
46
|
+
- ✅ `is State` only used for assertions and wait conditions
|
|
46
47
|
- ❌ No free-text variations
|
|
47
48
|
- ❌ No synonyms
|
|
48
49
|
|
|
@@ -54,6 +55,7 @@ Scenario: User logs in successfully with valid credentials
|
|
|
54
55
|
| Action | ✅ Always | `click`, `fill`, `see` |
|
|
55
56
|
| Target | ✅ Most cases | `[Login] button` |
|
|
56
57
|
| Value | ⚠️ When needed | `{{valid_email}}` |
|
|
58
|
+
| State | ⚠️ Assertions only | `is disabled` |
|
|
57
59
|
|
|
58
60
|
---
|
|
59
61
|
|
|
@@ -82,31 +84,41 @@ Scenario: User logs in successfully with valid credentials
|
|
|
82
84
|
|
|
83
85
|
## 4️⃣ Action
|
|
84
86
|
|
|
85
|
-
### Allowed Actions
|
|
86
|
-
|
|
87
|
-
| Action | Use Case | Example |
|
|
88
|
-
|
|
89
|
-
| `is on` | Navigate to page
|
|
90
|
-
| `
|
|
91
|
-
| `click` | Click button/link/element | `User click [Submit] button` |
|
|
92
|
-
| `
|
|
93
|
-
| `
|
|
94
|
-
|
|
|
95
|
-
| `
|
|
96
|
-
|
|
97
|
-
|
|
87
|
+
### Allowed Actions
|
|
88
|
+
|
|
89
|
+
| Group | Action | Use Case | Example |
|
|
90
|
+
|-------|--------|----------|---------|
|
|
91
|
+
| **Setup** | `is on` | Navigate to page/dialog | `User is on [Login] page` |
|
|
92
|
+
| **Setup** | `navigate to` | Navigate with data | `User navigate to [Profile] page with {{user_id}}` |
|
|
93
|
+
| **Interaction** | `click` | Click button/link/element | `User click [Submit] button` |
|
|
94
|
+
| **Interaction** | `double click` | Double click element | `User double click [Cell] element` |
|
|
95
|
+
| **Interaction** | `hover` | Hover over element | `User hover [Info] icon` |
|
|
96
|
+
| **Interaction** | `drag` | Drag to destination | `User drag [Card] to [Column]` |
|
|
97
|
+
| **Form** | `fill` | Enter text in field | `User fill [Email] field with {{email}}` |
|
|
98
|
+
| **Form** | `clear` | Clear field content | `User clear [Search] field` |
|
|
99
|
+
| **Form** | `select` | Choose from dropdown | `User select [Country] dropdown with {{country}}` |
|
|
100
|
+
| **Form** | `check` | Check checkbox | `User check [Remember me] checkbox` |
|
|
101
|
+
| **Form** | `uncheck` | Uncheck checkbox | `User uncheck [Newsletter] checkbox` |
|
|
102
|
+
| **Form** | `toggle` | Toggle switch | `User toggle [Dark mode] switch` |
|
|
103
|
+
| **Form** | `upload` | Upload file | `User upload [Avatar] file with {{path}}` |
|
|
104
|
+
| **Keyboard** | `press` | Press key (global or on element) | `User press Enter on [Search] field` |
|
|
105
|
+
| **Scroll** | `scroll to` | Scroll element into view | `User scroll to [Footer] section` |
|
|
106
|
+
| **Frame** | `switch to` | Enter/exit iframe | `User switch to [Payment] frame` |
|
|
107
|
+
| **Expand** | `expand` / `collapse` | Expand/collapse row | `User expand [Row 1] row` |
|
|
108
|
+
| **Wait** | `wait for` | Wait for element/timeout | `User wait for [Loading] spinner is hidden` |
|
|
109
|
+
| **Assertion** | `see` | Verify visibility/state/text | `User see [Error] message` |
|
|
98
110
|
|
|
99
111
|
### Rules
|
|
100
112
|
- ✅ Use **exact verbs** from the list above
|
|
101
|
-
- ❌ No synonyms: `type`, `enter`, `input`, `
|
|
113
|
+
- ❌ No synonyms: `type`, `enter`, `input`, `verify`, `expect`, `open`, etc.
|
|
102
114
|
- ❌ No compound actions: `click and wait`, `fill and submit`
|
|
103
115
|
|
|
104
116
|
### Anti-patterns
|
|
105
117
|
```gherkin
|
|
106
|
-
❌ User types {{password}} into [Password] field
|
|
107
|
-
❌ User
|
|
108
|
-
❌ User checks [Terms] checkbox
|
|
109
|
-
❌ User verifies [Success] message appears
|
|
118
|
+
❌ User types {{password}} into [Password] field → use "fill"
|
|
119
|
+
❌ User opens [Home] page → use "is on"
|
|
120
|
+
❌ User checks [Terms] checkbox → use "check" (no "s")
|
|
121
|
+
❌ User verifies [Success] message appears → use "see"
|
|
110
122
|
```
|
|
111
123
|
|
|
112
124
|
---
|
|
@@ -122,16 +134,32 @@ Scenario: User logs in successfully with valid credentials
|
|
|
122
134
|
|
|
123
135
|
| Element Type | When to Use | Example |
|
|
124
136
|
|--------------|-------------|---------|
|
|
125
|
-
| `
|
|
126
|
-
| `button` | Clickable button | `[Submit] button
|
|
137
|
+
| `page` | Entire screen/page | `[Login] page` |
|
|
138
|
+
| `button` | Clickable button | `[Submit] button` |
|
|
139
|
+
| `link` | Hyperlink | `[Forgot password] link` |
|
|
140
|
+
| `field` | Text input | `[Email] field` |
|
|
141
|
+
| `textarea` | Text area / rich editor | `[Message] textarea` |
|
|
142
|
+
| `heading` | Heading element | `[Welcome] heading` |
|
|
143
|
+
| `text` | Text content | `[Price] text` |
|
|
127
144
|
| `checkbox` | Checkbox input | `[Remember me] checkbox` |
|
|
128
|
-
| `dropdown` | Select element | `[Country] dropdown` |
|
|
129
145
|
| `radio` | Radio button | `[Payment method] radio` |
|
|
130
|
-
| `
|
|
131
|
-
| `
|
|
132
|
-
| `
|
|
133
|
-
| `
|
|
134
|
-
| `
|
|
146
|
+
| `switch` | Toggle switch | `[Dark mode] switch` |
|
|
147
|
+
| `dropdown` | Select / combobox | `[Country] dropdown` |
|
|
148
|
+
| `dialog` / `modal` | Modal / dialog overlay | `[Confirm] dialog` |
|
|
149
|
+
| `menu` / `menuitem` | Menu elements | `[Write Kudos] menuitem` |
|
|
150
|
+
| `tab` / `tabpanel` | Tab elements | `[Settings] tab` |
|
|
151
|
+
| `table` / `row` / `cell` | Table elements | `[Users] table` |
|
|
152
|
+
| `list` / `listitem` | List elements | `[Results] list` |
|
|
153
|
+
| `icon` / `image` | Visual icon/image | `[Close] icon` |
|
|
154
|
+
| `alert` | Alert/notification | `[Error] alert` |
|
|
155
|
+
| `spinner` / `progressbar` | Loading indicators | `[Loading] spinner` |
|
|
156
|
+
| `section` / `region` / `nav` | Layout landmarks | `[Footer] section` |
|
|
157
|
+
| `frame` / `iframe` | Iframe elements | `[Payment] frame` |
|
|
158
|
+
| `uploader` / `file` | File upload | `[Avatar] uploader` |
|
|
159
|
+
| `columnheader` | Table column header | `[Name] columnheader` |
|
|
160
|
+
| `tooltip` | Tooltip | `[Help] tooltip` |
|
|
161
|
+
| `slider` | Slider/range | `[Volume] slider` |
|
|
162
|
+
| `tree` / `treeitem` | Tree elements | `[Folder] treeitem` |
|
|
135
163
|
|
|
136
164
|
### Rules
|
|
137
165
|
- ✅ Use **business/UI meaningful names**, not technical selectors
|
|
@@ -144,8 +172,8 @@ Scenario: User logs in successfully with valid credentials
|
|
|
144
172
|
```gherkin
|
|
145
173
|
✅ User click [Login] button
|
|
146
174
|
✅ User fill [Email address] field with {{email}}
|
|
147
|
-
✅ User select [
|
|
148
|
-
✅ User see [Welcome back]
|
|
175
|
+
✅ User select [Country] dropdown with {{country}}
|
|
176
|
+
✅ User see [Welcome back] heading
|
|
149
177
|
|
|
150
178
|
❌ User click [#submit-btn] button
|
|
151
179
|
❌ User fill [input.email-field] field
|
|
@@ -209,8 +237,8 @@ expired_otp: "000000"
|
|
|
209
237
|
```gherkin
|
|
210
238
|
✅ Then User see [Error] message
|
|
211
239
|
✅ And User see [Dashboard] page
|
|
212
|
-
✅ And User see [Welcome]
|
|
213
|
-
✅ And User see [
|
|
240
|
+
✅ And User see [Welcome] heading with {{username}}
|
|
241
|
+
✅ And User see [Submit] button is disabled
|
|
214
242
|
|
|
215
243
|
❌ Then User verifies [Error] message
|
|
216
244
|
❌ Then System displays [Dashboard] page
|
|
@@ -222,55 +250,41 @@ expired_otp: "000000"
|
|
|
222
250
|
| Pattern | Use Case | Example |
|
|
223
251
|
|---------|----------|---------|
|
|
224
252
|
| Simple visibility | Element is visible | `User see [Login] button` |
|
|
225
|
-
| Visibility with value | Element
|
|
226
|
-
|
|
|
227
|
-
|
|
|
228
|
-
|
|
|
229
|
-
|
|
|
230
|
-
|
|
|
253
|
+
| Visibility with value | Element has specific text | `User see [Welcome] heading with {{username}}` |
|
|
254
|
+
| State assertion | Element state | `User see [Submit] button is disabled` |
|
|
255
|
+
| State with value | Element with text + state | `User see [Panel] dialog with {{title}} is hidden` |
|
|
256
|
+
| Text contains | Partial text match | `User see [Message] text contains {{partial}}` |
|
|
257
|
+
| Text has text | Exact text match | `User see [Counter] text has text {{count}}` |
|
|
258
|
+
| Has attribute | Attribute check | `User see [Avatar] image has {{avatar_url}}` |
|
|
231
259
|
|
|
232
260
|
### State Modifiers
|
|
233
261
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
When User fill [Email] field with {{invalid_email}}
|
|
261
|
-
And User fill [Password] field with {{invalid_password}}
|
|
262
|
-
And User click [Submit] button
|
|
263
|
-
Then User see [Error] message
|
|
264
|
-
And User see [Login] page
|
|
265
|
-
|
|
266
|
-
Scenario: User selects preferred language during registration
|
|
267
|
-
Given User is on [Registration] page
|
|
268
|
-
When User fill [Email] field with {{new_email}}
|
|
269
|
-
And User fill [Password] field with {{new_password}}
|
|
270
|
-
And User select [Language] dropdown with {{preferred_language}}
|
|
271
|
-
And User click [Sign up] button
|
|
272
|
-
Then User see [Verification] page
|
|
273
|
-
```
|
|
262
|
+
| State | Assertion |
|
|
263
|
+
|-------|-----------|
|
|
264
|
+
| `hidden` | Element is not visible |
|
|
265
|
+
| `visible` | Element is visible |
|
|
266
|
+
| `disabled` | Element is disabled |
|
|
267
|
+
| `enabled` | Element is enabled |
|
|
268
|
+
| `checked` | Checkbox/radio is checked |
|
|
269
|
+
| `unchecked` | Checkbox/radio is unchecked |
|
|
270
|
+
| `focused` | Element has focus |
|
|
271
|
+
| `empty` | Element has no text |
|
|
272
|
+
| `loading` | Loading indicator is visible |
|
|
273
|
+
| `selected` | Element is selected |
|
|
274
|
+
| `sorted ascending` | Column sorted ascending |
|
|
275
|
+
| `sorted descending` | Column sorted descending |
|
|
276
|
+
|
|
277
|
+
### Table Assertions
|
|
278
|
+
|
|
279
|
+
| Pattern | Example |
|
|
280
|
+
|---------|---------|
|
|
281
|
+
| Row exists | `User see [Users] table row with {{name}} has [Status] with {{status}}` |
|
|
282
|
+
| No row | `User see [Users] table has no row with {{name}}` |
|
|
283
|
+
| Row count | `User see [Users] table has {{count}} rows` |
|
|
284
|
+
| Column exists | `User see [Users] table has [Email] column` |
|
|
285
|
+
| Cell by index | `User see [Users] table row 1 [Name] cell with {{name}}` |
|
|
286
|
+
| Empty table | `User see [Users] table is empty` |
|
|
287
|
+
| Action in row | `User click [Edit] in [Users] table row with {{name}}` |
|
|
274
288
|
|
|
275
289
|
---
|
|
276
290
|
|
|
@@ -309,10 +323,8 @@ Scenario: User sends a thank you message
|
|
|
309
323
|
And User fill [Search] field with {{teammate_name}}
|
|
310
324
|
And User click [teammate] row with {{teammate_name}}
|
|
311
325
|
And User fill [Title] field with {{teammate_title}}
|
|
312
|
-
And User fill [Message] textarea 2 with {{teammate_message}}
|
|
313
|
-
And User click [Hashtag] tag with {{hashtag_1}}
|
|
314
326
|
And User click [Send] button
|
|
315
|
-
And User wait for dialog with {{kudo_title}} is hidden
|
|
327
|
+
And User wait for [panel] dialog with {{kudo_title}} is hidden
|
|
316
328
|
Then User see [panel] modal with {{kudo_title}} is hidden
|
|
317
329
|
```
|
|
318
330
|
|
|
@@ -332,13 +344,51 @@ Scenario: User sends a thank you message
|
|
|
332
344
|
|
|
333
345
|
---
|
|
334
346
|
|
|
347
|
+
## 📋 Complete Example
|
|
348
|
+
|
|
349
|
+
```gherkin
|
|
350
|
+
@auth:user
|
|
351
|
+
Feature: User Authentication
|
|
352
|
+
Path: /auth/login
|
|
353
|
+
|
|
354
|
+
Scenario: User logs in successfully with valid credentials
|
|
355
|
+
Given User is on [Login] page
|
|
356
|
+
When User fill [Email] field with {{valid_email}}
|
|
357
|
+
And User fill [Password] field with {{valid_password}}
|
|
358
|
+
And User check [Remember me] checkbox
|
|
359
|
+
And User click [Submit] button
|
|
360
|
+
Then User see [Dashboard] page
|
|
361
|
+
And User see [Welcome] heading with {{username}}
|
|
362
|
+
|
|
363
|
+
Scenario: User fails to login with invalid credentials
|
|
364
|
+
Given User is on [Login] page
|
|
365
|
+
When User fill [Email] field with {{invalid_email}}
|
|
366
|
+
And User fill [Password] field with {{invalid_password}}
|
|
367
|
+
And User click [Submit] button
|
|
368
|
+
Then User see [Error] alert
|
|
369
|
+
And User see [Login] page
|
|
370
|
+
And User see [Submit] button is enabled
|
|
371
|
+
|
|
372
|
+
Scenario: User selects preferred language during registration
|
|
373
|
+
Given User is on [Registration] page
|
|
374
|
+
When User fill [Email] field with {{new_email}}
|
|
375
|
+
And User fill [Password] field with {{new_password}}
|
|
376
|
+
And User select [Language] dropdown with {{preferred_language}}
|
|
377
|
+
And User check [Terms] checkbox
|
|
378
|
+
And User click [Sign up] button
|
|
379
|
+
Then User see [Verification] page
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
---
|
|
383
|
+
|
|
335
384
|
## ✅ Quick Reference
|
|
336
385
|
|
|
337
386
|
### Do's ✅
|
|
338
|
-
- Use **standard
|
|
387
|
+
- Use **standard actions** from section 4
|
|
339
388
|
- Use **`User`** as the only actor
|
|
340
389
|
- Use **`[Target] <element type>`** format
|
|
341
390
|
- Use **`{{snake_case}}`** for values
|
|
391
|
+
- Use **`is <state>`** for state assertions
|
|
342
392
|
- **1 Scenario = 1 business flow**
|
|
343
393
|
- **1 Step = 1 action or assertion**
|
|
344
394
|
|
|
@@ -349,6 +399,7 @@ Scenario: User sends a thank you message
|
|
|
349
399
|
- No hard-coded data in steps
|
|
350
400
|
- No compound actions
|
|
351
401
|
- No `verify`/`check`/`expect` (use `see`)
|
|
402
|
+
- No `open` (use `is on`)
|
|
352
403
|
|
|
353
404
|
---
|
|
354
405
|
|
|
@@ -359,19 +410,19 @@ Scenario: User sends a thank you message
|
|
|
359
410
|
| **Consistency** | Same patterns across all test cases |
|
|
360
411
|
| **Readability** | Non-technical stakeholders can understand |
|
|
361
412
|
| **Maintainability** | Easy to update when UI changes |
|
|
362
|
-
| **Automation-Ready** | Direct mapping to code
|
|
413
|
+
| **Automation-Ready** | Direct mapping to Playwright code via 17 pattern shapes |
|
|
363
414
|
| **No Ambiguity** | Single interpretation per step |
|
|
364
|
-
| **Tool Support** | Compatible with Sungen
|
|
415
|
+
| **Tool Support** | Compatible with Sungen v2 compiler |
|
|
365
416
|
|
|
366
417
|
---
|
|
367
418
|
|
|
368
419
|
## 📚 Related Documentation
|
|
369
|
-
- [
|
|
370
|
-
- [
|
|
371
|
-
- [
|
|
420
|
+
- [Gherkin Dictionary](../gherkin-dictionary.md) — Full grammar, all 17 patterns, compiler rules
|
|
421
|
+
- [Sungen GitHub](https://github.com/sun-asterisk/sungen)
|
|
422
|
+
- [Playwright Documentation](https://playwright.dev)
|
|
372
423
|
|
|
373
424
|
---
|
|
374
425
|
|
|
375
|
-
**Version**:
|
|
426
|
+
**Version**: 2.0
|
|
376
427
|
**Status**: Final
|
|
377
|
-
**Last Updated**: March
|
|
428
|
+
**Last Updated**: March 19, 2026
|