@sun-asterisk/sungen 2.4.0 → 2.4.2
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/dist/cli/index.js +1 -1
- package/dist/generators/gherkin-parser/index.d.ts +8 -0
- package/dist/generators/gherkin-parser/index.d.ts.map +1 -1
- package/dist/generators/gherkin-parser/index.js +12 -0
- package/dist/generators/gherkin-parser/index.js.map +1 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/table-match-data.hbs +15 -0
- package/dist/generators/test-generator/patterns/index.d.ts.map +1 -1
- package/dist/generators/test-generator/patterns/index.js +2 -1
- package/dist/generators/test-generator/patterns/index.js.map +1 -1
- package/dist/generators/test-generator/patterns/table-patterns.d.ts +4 -1
- package/dist/generators/test-generator/patterns/table-patterns.d.ts.map +1 -1
- package/dist/generators/test-generator/patterns/table-patterns.js +49 -1
- package/dist/generators/test-generator/patterns/table-patterns.js.map +1 -1
- package/dist/orchestrator/templates/ai-instructions/claude-cmd-run-test.md +19 -16
- package/dist/orchestrator/templates/ai-instructions/claude-skill-error-mapping.md +5 -5
- package/dist/orchestrator/templates/ai-instructions/claude-skill-gherkin-syntax.md +44 -1
- package/dist/orchestrator/templates/ai-instructions/claude-skill-selector-fix.md +46 -61
- package/dist/orchestrator/templates/ai-instructions/claude-skill-tc-generation.md +34 -1
- package/dist/orchestrator/templates/ai-instructions/claude-skill-viewpoint.md +3 -1
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-run-test.md +19 -16
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-error-mapping.md +5 -5
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-gherkin-syntax.md +45 -2
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-selector-fix.md +46 -61
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-tc-generation.md +34 -1
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint.md +3 -1
- package/dist/orchestrator/templates/readme.md +82 -19
- package/package.json +1 -1
- package/src/cli/index.ts +1 -1
- package/src/generators/gherkin-parser/index.ts +23 -0
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/table-match-data.hbs +15 -0
- package/src/generators/test-generator/patterns/index.ts +2 -1
- package/src/generators/test-generator/patterns/table-patterns.ts +58 -1
- package/src/orchestrator/templates/ai-instructions/claude-cmd-run-test.md +19 -16
- package/src/orchestrator/templates/ai-instructions/claude-skill-error-mapping.md +5 -5
- package/src/orchestrator/templates/ai-instructions/claude-skill-gherkin-syntax.md +44 -1
- package/src/orchestrator/templates/ai-instructions/claude-skill-selector-fix.md +46 -61
- package/src/orchestrator/templates/ai-instructions/claude-skill-tc-generation.md +34 -1
- package/src/orchestrator/templates/ai-instructions/claude-skill-viewpoint.md +3 -1
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-run-test.md +19 -16
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-error-mapping.md +5 -5
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-gherkin-syntax.md +45 -2
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-selector-fix.md +46 -61
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-tc-generation.md +34 -1
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint.md +3 -1
- package/src/orchestrator/templates/readme.md +82 -19
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: sungen-gherkin-syntax
|
|
3
|
-
description: 'Sungen Gherkin patterns, selector types, and YAML key rules.
|
|
3
|
+
description: 'Sungen Gherkin patterns, selector types, and YAML key rules. Auto-loaded when writing .feature, selectors.yaml, or test-data.yaml.'
|
|
4
4
|
user-invocable: false
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -50,7 +50,7 @@ User check [T] radio # select radio
|
|
|
50
50
|
User uncheck [T] checkbox # uncheck
|
|
51
51
|
User uncheck [T] toggle # toggle off
|
|
52
52
|
User select [T] dropdown with {{v}} # select option
|
|
53
|
-
User
|
|
53
|
+
User fill [T] uploader with {{f}} # file upload
|
|
54
54
|
```
|
|
55
55
|
|
|
56
56
|
### Interaction
|
|
@@ -161,10 +161,17 @@ User see [Table] table with {{count}} # row count
|
|
|
161
161
|
User see [Table] table is empty # empty table
|
|
162
162
|
User see [Col] column with {{v}} # cell value (row scoped)
|
|
163
163
|
User click [Act] button in [Table] table with {{v}} # action in row
|
|
164
|
+
User see [Table] table match data: # exact table match (inline DataTable)
|
|
165
|
+
| Header1 | Header2 |
|
|
166
|
+
| {{value1}} | {{value2}} |
|
|
164
167
|
```
|
|
165
168
|
|
|
169
|
+
**Priority**: Use row scope patterns for single-row verification + actions. Use `table match data` only when verifying multiple rows at once.
|
|
170
|
+
|
|
166
171
|
Row scope: `see [Ref] row in [Table] table with {{v}}` defines `tableRow`. Subsequent `see [Col] column with {{v}}` checks the cell in that row. With `columns` config → exact `nth(index)`, without → `filter({ hasText })`.
|
|
167
172
|
|
|
173
|
+
Table match data: `see [Table] table match data:` followed by a Cucumber DataTable. First row = headers, remaining rows = expected data. Uses **filter-based matching** — verifies rows containing expected values exist, resilient to data changes, extra rows, and row reordering. Use `{{variable}}` for cell values.
|
|
174
|
+
|
|
168
175
|
### States
|
|
169
176
|
|
|
170
177
|
`hidden` `visible` `disabled` `enabled` `checked` `unchecked` `focused` `empty` `loading` `selected` `sorted ascending` `sorted descending`
|
|
@@ -240,3 +247,39 @@ Options: `nth` `exact` `scope` `match` `variant` `frame` `contenteditable` `colu
|
|
|
240
247
|
| Missing `is` for state | `with {{text}} hidden` | `with {{text}} is hidden` |
|
|
241
248
|
| State as value | `with {{disabled}}` | `is disabled` |
|
|
242
249
|
| Missing target type | `fill [email] with {{v}}` | `fill [email] field with {{v}}` |
|
|
250
|
+
| Using Background | `Background: Given User is on...` | Use `@steps` + `@extend` instead |
|
|
251
|
+
| `is on` after When | `When ... And User is on [X] dialog` | `And User see [X] dialog` or separate Given |
|
|
252
|
+
|
|
253
|
+
## Background vs @steps/@extend
|
|
254
|
+
|
|
255
|
+
**Do NOT use `Background:` block.** Use `@steps` + `@extend` instead.
|
|
256
|
+
|
|
257
|
+
**Why:**
|
|
258
|
+
- `Background` runs before EVERY scenario but cannot set dialog/frame scope correctly
|
|
259
|
+
- `Background` with `When` + `And User is on [X] dialog` creates keyword mismatch (`is on` = Given, not When)
|
|
260
|
+
- `@steps` + `@extend` gives explicit control: base steps run Given→When, extending scenario starts with `Given User is on [X] dialog` (correct scope setup)
|
|
261
|
+
|
|
262
|
+
**Wrong:**
|
|
263
|
+
```gherkin
|
|
264
|
+
Background:
|
|
265
|
+
Given User is on [Kudos] page
|
|
266
|
+
When User click [Open] button
|
|
267
|
+
And User is on [Modal] dialog ← keyword mismatch
|
|
268
|
+
|
|
269
|
+
Scenario: VP-UI-001 Title visible
|
|
270
|
+
Then User see [Title] heading
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
**Correct:**
|
|
274
|
+
```gherkin
|
|
275
|
+
@steps:open_modal
|
|
276
|
+
Scenario: Open modal
|
|
277
|
+
Given User is on [Kudos] page
|
|
278
|
+
When User click [Open] button
|
|
279
|
+
Then User see [Modal] dialog
|
|
280
|
+
|
|
281
|
+
@extend:open_modal
|
|
282
|
+
Scenario: VP-UI-001 Title visible
|
|
283
|
+
Given User is on [Modal] dialog
|
|
284
|
+
Then User see [Title] heading
|
|
285
|
+
```
|
|
@@ -1,41 +1,51 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: sungen-selector-fix
|
|
3
|
-
description: 'Selector
|
|
3
|
+
description: 'Selector fixing strategy — diagnose failures, explore live page targeted, fix broken selectors. Auto-loaded by run-test command.'
|
|
4
4
|
user-invocable: false
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## Strategy: Fix Only What Breaks
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Most selectors auto-infer from Gherkin element types (see `sungen-selector-keys` skill). Only add YAML entries for selectors that fail during test execution.
|
|
10
|
+
|
|
11
|
+
**Minimal `selectors.yaml`**: page selectors (required), overrides for elements where auto-infer doesn't work. Never generate a full page catalog upfront.
|
|
10
12
|
|
|
11
13
|
---
|
|
12
14
|
|
|
13
|
-
## Step 1:
|
|
15
|
+
## Step 1: Diagnose Failures
|
|
14
16
|
|
|
15
|
-
|
|
16
|
-
2. `browser_navigate` to `baseURL`
|
|
17
|
-
3. If redirected to login → ask user to log in manually via MCP browser
|
|
18
|
-
4. Navigate to target page → `browser_snapshot`
|
|
17
|
+
Parse Playwright error output to categorize failures:
|
|
19
18
|
|
|
20
|
-
|
|
19
|
+
| Error pattern | Root cause | Fix target |
|
|
20
|
+
|---|---|---|
|
|
21
|
+
| `No element found` / `strict mode violation` | Selector mismatch | `selectors.yaml` |
|
|
22
|
+
| `toBeVisible` timeout | Wrong name or missing element | `selectors.yaml` |
|
|
23
|
+
| `toHaveText` / `toHaveValue` mismatch | Wrong expected data | `test-data.yaml` |
|
|
24
|
+
| `page.goto` error | Wrong URL | page selector in `selectors.yaml` |
|
|
25
|
+
| `frame` error | Element inside iframe | add `frame` field |
|
|
26
|
+
|
|
27
|
+
**Group by root cause** — if 5 tests fail because `[Submit]` button has a different name, that's 1 fix, not 5.
|
|
28
|
+
|
|
29
|
+
**Check `test-results/` first** — Playwright captures failure screenshots automatically. Use these to diagnose before any MCP exploration.
|
|
21
30
|
|
|
22
31
|
---
|
|
23
32
|
|
|
24
|
-
## Step 2:
|
|
33
|
+
## Step 2: Targeted MCP Exploration
|
|
25
34
|
|
|
26
|
-
|
|
35
|
+
Only when `test-results/` screenshots are insufficient:
|
|
27
36
|
|
|
28
|
-
|
|
37
|
+
1. Read `baseURL` from `playwright.config.ts`
|
|
38
|
+
2. `browser_navigate` to target page
|
|
39
|
+
3. If redirected to login → ask user to log in manually via MCP browser
|
|
40
|
+
4. Take **ONE** `browser_snapshot` — fix all broken selectors from this single snapshot
|
|
29
41
|
|
|
30
|
-
|
|
31
|
-
```js
|
|
32
|
-
Array.from(document.querySelectorAll('[data-testid]'))
|
|
33
|
-
.map(e => ({ testid: e.dataset.testid, tag: e.tagName, text: e.textContent.trim().slice(0, 60) }))
|
|
34
|
-
```
|
|
42
|
+
**Never use `sungen makeauth`.** Never use `browser_evaluate` to inject cookies.
|
|
35
43
|
|
|
36
44
|
---
|
|
37
45
|
|
|
38
|
-
## Step 3:
|
|
46
|
+
## Step 3: Fix Broken Selectors
|
|
47
|
+
|
|
48
|
+
For each failed selector, find the correct locator from the snapshot:
|
|
39
49
|
|
|
40
50
|
Selector priority (use first applicable):
|
|
41
51
|
|
|
@@ -50,24 +60,24 @@ Selector priority (use first applicable):
|
|
|
50
60
|
|
|
51
61
|
**Exact name rule**: copy name character-for-character from snapshot. Never infer from Gherkin label.
|
|
52
62
|
|
|
53
|
-
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
value: '[role="searchbox"]'
|
|
63
|
+
Check for `data-testid` attributes if role-based matching fails:
|
|
64
|
+
```js
|
|
65
|
+
Array.from(document.querySelectorAll('[data-testid]'))
|
|
66
|
+
.map(e => ({ testid: e.dataset.testid, tag: e.tagName, text: e.textContent.trim().slice(0, 60) }))
|
|
58
67
|
```
|
|
59
68
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
69
|
+
Common fixes:
|
|
70
|
+
- Name mismatch → copy exact name from snapshot
|
|
71
|
+
- Multiple matches → add `nth` or `exact: true`
|
|
72
|
+
- No accessible name → use `testid` or `locator` (CSS)
|
|
73
|
+
- Element in iframe → add `frame` field
|
|
74
|
+
- Dynamic content → use `testid` or structural `role` + `nth`
|
|
65
75
|
|
|
66
76
|
---
|
|
67
77
|
|
|
68
78
|
## Step 4: Table Selectors
|
|
69
79
|
|
|
70
|
-
For table patterns
|
|
80
|
+
For table patterns, add table selectors with `columns` config:
|
|
71
81
|
|
|
72
82
|
```yaml
|
|
73
83
|
users:
|
|
@@ -88,15 +98,6 @@ users:
|
|
|
88
98
|
|
|
89
99
|
**How to build `columns`**: count column headers in snapshot (left to right, 0-indexed). Map each `[Col] column` reference from feature file to its index.
|
|
90
100
|
|
|
91
|
-
**Why**: enables exact cell assertion via `cell.nth(index).toHaveText(value)` instead of approximate `cell.filter({ hasText })`.
|
|
92
|
-
|
|
93
|
-
**Row scope Gherkin** — these patterns use the table selector:
|
|
94
|
-
```gherkin
|
|
95
|
-
Then User see [Username] row in [Users] table with {{user_name}}
|
|
96
|
-
Then User see [Status] column with {{expected_status}}
|
|
97
|
-
When User click [Edit] button in [Users] table with {{user_name}}
|
|
98
|
-
```
|
|
99
|
-
|
|
100
101
|
---
|
|
101
102
|
|
|
102
103
|
## Step 5: Detail Screens with Dynamic IDs
|
|
@@ -113,28 +114,12 @@ user detail:
|
|
|
113
114
|
|
|
114
115
|
---
|
|
115
116
|
|
|
116
|
-
## Step 6:
|
|
117
|
-
|
|
118
|
-
**Fix 80%+ of selector issues before first test run.**
|
|
119
|
-
|
|
120
|
-
After generating `selectors.yaml`, verify each entry against the live snapshot:
|
|
121
|
-
- `role` + `name` → search snapshot for `role "name"`
|
|
122
|
-
- `testid` → `browser_evaluate`: `document.querySelector('[data-testid="xxx"]')`
|
|
123
|
-
- `placeholder` → search snapshot for textbox with placeholder
|
|
124
|
-
- `page` → verify URL path exists
|
|
125
|
-
|
|
126
|
-
Common fixes: name mismatch → copy from snapshot, element in iframe → add `frame`, multiple matches → add `nth` or `exact: true`.
|
|
127
|
-
|
|
128
|
-
---
|
|
129
|
-
|
|
130
|
-
## Step 7: Run & Fix Loop
|
|
131
|
-
|
|
132
|
-
Run tests in batches of 20. Group failures by root cause (same selector, same error type). Fix once, verify batch, move to next.
|
|
133
|
-
|
|
134
|
-
```
|
|
135
|
-
compile → batch run 20 → fix root cause → recompile → re-run failures → next batch
|
|
136
|
-
```
|
|
117
|
+
## Step 6: Fix Loop
|
|
137
118
|
|
|
138
|
-
After
|
|
119
|
+
After fixing selectors:
|
|
120
|
+
1. Recompile: `sungen generate --screen <screen>`
|
|
121
|
+
2. Re-run only failing tests: `npx playwright test --grep "VP-XXX-001|VP-XXX-002" --reporter=line`
|
|
122
|
+
3. If new failures → repeat (max 3 attempts)
|
|
123
|
+
4. After all fixes → run ALL tests once for regression check
|
|
139
124
|
|
|
140
|
-
If still failing after
|
|
125
|
+
If still failing after 3 attempts → ask user for guidance.
|
|
@@ -68,25 +68,38 @@ And User wait for [Page Title] heading is visible
|
|
|
68
68
|
|
|
69
69
|
**Feature file** — `qa/screens/<screen>/features/<screen>.feature`
|
|
70
70
|
|
|
71
|
+
**Never use `Background:`.** Use `@steps` + `@extend` for shared setup (see `sungen-gherkin-syntax` skill).
|
|
72
|
+
|
|
71
73
|
```gherkin
|
|
72
74
|
@auth:role
|
|
73
75
|
Feature: <Screen> Screen
|
|
74
76
|
|
|
77
|
+
# Shared setup — use @steps, not Background
|
|
78
|
+
@steps:open_form
|
|
79
|
+
Scenario: Open form
|
|
80
|
+
Given User is on [Screen] page
|
|
81
|
+
And User wait for [Screen Title] heading is visible
|
|
82
|
+
When User click [Create] button
|
|
83
|
+
Then User see [Form] dialog
|
|
84
|
+
|
|
75
85
|
# ============================================================
|
|
76
86
|
# Section: Create User Form
|
|
77
87
|
# ============================================================
|
|
78
88
|
|
|
79
89
|
# --- UI/UX ---
|
|
80
90
|
|
|
91
|
+
@extend:open_form
|
|
81
92
|
Scenario: VP-UI-001 Form displays all fields with correct defaults
|
|
82
|
-
Given User is on [
|
|
93
|
+
Given User is on [Form] dialog
|
|
83
94
|
Then User see [Name] field
|
|
84
95
|
And User see [Email] field
|
|
85
96
|
And User see [Submit] button is disabled
|
|
86
97
|
|
|
87
98
|
# --- Validation ---
|
|
88
99
|
|
|
100
|
+
@extend:open_form
|
|
89
101
|
Scenario: VP-VAL-001 Submit with all empty fields shows errors
|
|
102
|
+
Given User is on [Form] dialog
|
|
90
103
|
When User click [Submit] button
|
|
91
104
|
Then User see [Name error] message with {{name_required_error}}
|
|
92
105
|
|
|
@@ -100,8 +113,28 @@ Feature: <Screen> Screen
|
|
|
100
113
|
Then User see [Name] column in [Users] table
|
|
101
114
|
And User see [Email] column in [Users] table
|
|
102
115
|
And User see [Status] column in [Users] table
|
|
116
|
+
|
|
117
|
+
# --- Data & Validate ---
|
|
118
|
+
|
|
119
|
+
Scenario: VP-VAL-010 Table displays correct data
|
|
120
|
+
Then User see [Users] table match data:
|
|
121
|
+
| Name | Email | Status |
|
|
122
|
+
| {{name_1}} | {{email_1}} | {{status_1}} |
|
|
123
|
+
| {{name_2}} | {{email_2}} | {{status_2}} |
|
|
124
|
+
|
|
125
|
+
Scenario: VP-VAL-011 Edit button targets correct row
|
|
126
|
+
Given User see [Target] row in [Users] table with {{name_1}}
|
|
127
|
+
When User click [Edit] button in [Users] table with {{name_1}}
|
|
128
|
+
Then User see [Name] field with {{name_1}}
|
|
103
129
|
```
|
|
104
130
|
|
|
131
|
+
### When to use DataTable vs Row Scope
|
|
132
|
+
|
|
133
|
+
| Pattern | Use when |
|
|
134
|
+
|---|---|
|
|
135
|
+
| `table match data:` + DataTable | Verifying **multiple rows** exist with expected values |
|
|
136
|
+
| `row in [Table] table with {{v}}` + `column with {{v}}` | Checking **single row** details or **acting** on a row (click, edit) |
|
|
137
|
+
|
|
105
138
|
**Naming**: `VP-<CATEGORY>-<NNN>` prefix.
|
|
106
139
|
|
|
107
140
|
**Test data** — `qa/screens/<screen>/test-data/<screen>.yaml`, grouped by section.
|
|
@@ -52,6 +52,8 @@ user-invocable: false
|
|
|
52
52
|
- Consistency: total record count on UI matches server data
|
|
53
53
|
- Row Limit: displayed rows never exceed page size/limit
|
|
54
54
|
- Cell Integrity: cell data matches database, correct format (date, currency, status)
|
|
55
|
+
- **Use `table match data:` with inline DataTable** for multi-row content verification (filter-based, resilient to data changes)
|
|
56
|
+
- Use row scope (`row in [Table] table with {{v}}` + `column with {{v}}`) for single-row detail checks or when you need actions on a row
|
|
55
57
|
|
|
56
58
|
**Logic**
|
|
57
59
|
- Sorting: column sort refreshes data with correct order, updates header icon
|
|
@@ -82,7 +84,7 @@ user-invocable: false
|
|
|
82
84
|
|
|
83
85
|
**Security**
|
|
84
86
|
- Injection: XSS/SQL encoded as plain text, never executed
|
|
85
|
-
- Wildcards:
|
|
87
|
+
- Wildcards: `%, _, *` treated as normal text (escaped)
|
|
86
88
|
|
|
87
89
|
---
|
|
88
90
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Sungen Test Automation
|
|
2
2
|
|
|
3
|
-
This project uses [Sungen v2](https://github.com/sun-asterisk/sungen) — a deterministic E2E test compiler.
|
|
3
|
+
This project uses [Sungen v2.4.1](https://github.com/sun-asterisk/sungen) — a deterministic E2E test compiler.
|
|
4
4
|
|
|
5
5
|
## How it works
|
|
6
6
|
|
|
@@ -37,16 +37,16 @@ sungen generate → compiles Gherkin + selectors + data → Playwright .spec.ts
|
|
|
37
37
|
## Workflow
|
|
38
38
|
|
|
39
39
|
```
|
|
40
|
-
Step 1 Step 2 Step 3
|
|
41
|
-
┌──────────┐ ┌──────────┐ ┌──────────┐
|
|
42
|
-
│ /add- │────────▶│ /create-
|
|
43
|
-
│ screen │ │
|
|
44
|
-
└──────────┘ └──────────┘ └──────────┘
|
|
45
|
-
Scaffold Pick sections Generate
|
|
46
|
-
directories → design TCs selectors
|
|
47
|
-
→ generate → compile
|
|
48
|
-
.feature + → run tests
|
|
49
|
-
test-data → auto-fix
|
|
40
|
+
Step 1 Step 2 Step 3 Step 4
|
|
41
|
+
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
|
|
42
|
+
│ /add- │────────▶│ /create- │────────▶│ /run- │────────▶│ /review │
|
|
43
|
+
│ screen │ │ test │ │ test │ │ │
|
|
44
|
+
└──────────┘ └──────────┘ └──────────┘ └──────────┘
|
|
45
|
+
Scaffold Pick sections Generate Review
|
|
46
|
+
directories → design TCs selectors syntax &
|
|
47
|
+
→ generate → compile coverage
|
|
48
|
+
.feature + → run tests → score &
|
|
49
|
+
test-data → auto-fix auto-fix
|
|
50
50
|
```
|
|
51
51
|
|
|
52
52
|
Use AI commands (Claude Code or GitHub Copilot) to drive the workflow:
|
|
@@ -84,6 +84,17 @@ AI acts as a **Senior Developer**:
|
|
|
84
84
|
3. Compiles Gherkin → Playwright `.spec.ts`
|
|
85
85
|
4. Runs tests, auto-fixes selectors on failure (up to 5 attempts)
|
|
86
86
|
|
|
87
|
+
### Step 4: Review test cases
|
|
88
|
+
|
|
89
|
+
| Claude Code | GitHub Copilot (VS Code) |
|
|
90
|
+
|---|---|
|
|
91
|
+
| `/sungen:review login` | `/sungen-review login` |
|
|
92
|
+
|
|
93
|
+
AI acts as a **Senior QA Reviewer**:
|
|
94
|
+
1. Validates syntax against all Gherkin rules
|
|
95
|
+
2. Scores coverage across viewpoint categories
|
|
96
|
+
3. Can auto-fix issues when `--fix` flag is used
|
|
97
|
+
|
|
87
98
|
### Auth setup
|
|
88
99
|
|
|
89
100
|
If any page requires authentication, the AI will ask you to **log in manually via the MCP browser** during Step 2 or Step 3. No separate auth command needed.
|
|
@@ -123,38 +134,85 @@ Add to `.vscode/settings.json` to auto-load Gherkin syntax when editing `.featur
|
|
|
123
134
|
### Syntax
|
|
124
135
|
|
|
125
136
|
```
|
|
126
|
-
User <action> [
|
|
137
|
+
[Keyword] User <action> [Target] <type> <in [Parent] parentType> <with {{value}}> <is state>
|
|
127
138
|
```
|
|
128
139
|
|
|
129
140
|
- `[Target]` → selector reference → lookup in `selectors/*.yaml`
|
|
130
|
-
- `{{
|
|
131
|
-
- `<type>` → element type: button, link, field, heading, text, etc.
|
|
141
|
+
- `{{value}}` → test data reference → lookup in `test-data/*.yaml`
|
|
142
|
+
- `<type>` → element type: button, link, field, heading, text, table, etc.
|
|
143
|
+
- `in [Parent] parentType` → optional parent scope for disambiguation
|
|
132
144
|
|
|
133
145
|
### Key Patterns
|
|
134
146
|
|
|
135
147
|
| Pattern | Example |
|
|
136
148
|
|---|---|
|
|
137
149
|
| Navigate | `User is on [login] page` |
|
|
150
|
+
| Navigate with data | `User is on [user detail] page with {{user_id}}` |
|
|
138
151
|
| Click | `User click [Submit] button` |
|
|
139
152
|
| Fill | `User fill [Email] field with {{email}}` |
|
|
140
|
-
|
|
|
153
|
+
| Select | `User select [Country] dropdown with {{country}}` |
|
|
154
|
+
| Check | `User check [Remember me] checkbox` |
|
|
155
|
+
| Upload | `User fill [Avatar] uploader with {{file}}` |
|
|
156
|
+
| Clear | `User clear [Search] field` |
|
|
157
|
+
| Hover | `User hover [Info] icon` |
|
|
158
|
+
| Keyboard | `User press Enter on [Search] field` |
|
|
159
|
+
| Scroll | `User scroll to [Footer] section` |
|
|
160
|
+
| Assert visible | `User see [Welcome] heading` |
|
|
161
|
+
| Assert hidden | `User see [Error] message is hidden` |
|
|
141
162
|
| Assert text | `User see [Title] heading with {{title}}` |
|
|
163
|
+
| Assert value | `User see [Email] field with {{email}}` |
|
|
142
164
|
| Assert state | `User see [Submit] button is disabled` |
|
|
143
|
-
|
|
|
165
|
+
| Contains text | `User see [Message] text contains {{partial}}` |
|
|
166
|
+
| Wait for | `User wait for [Modal] dialog` |
|
|
144
167
|
| Table row | `User see [Username] row in [Users] table with {{name}}` |
|
|
168
|
+
| Table cell | `User see [Status] column with {{status}}` (row scoped) |
|
|
145
169
|
| Table column | `User see [Email] column in [Users] table` |
|
|
170
|
+
| Table count | `User see [Users] table with {{count}}` |
|
|
171
|
+
| Table empty | `User see [Users] table is empty` |
|
|
172
|
+
| Table action | `User click [Edit] button in [Users] table with {{name}}` |
|
|
173
|
+
| Table match | `User see [Users] table match data:` + inline DataTable |
|
|
174
|
+
| Alert | `User click [OK] alert` |
|
|
175
|
+
| Frame | `User switch to [Payment] frame` |
|
|
176
|
+
|
|
177
|
+
### Table Match Data
|
|
178
|
+
|
|
179
|
+
Verify multiple rows exist using filter-based matching (resilient to data changes and row reordering):
|
|
180
|
+
|
|
181
|
+
```gherkin
|
|
182
|
+
Then User see [Users] table match data:
|
|
183
|
+
| ID | Name | Status |
|
|
184
|
+
| {{id_1}} | {{name_1}} | {{status_1}} |
|
|
185
|
+
| {{id_2}} | {{name_2}} | {{status_2}} |
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
First row = headers, remaining rows = expected data. For single-row verification + actions, use row scope patterns instead.
|
|
146
189
|
|
|
147
|
-
States
|
|
190
|
+
### States
|
|
191
|
+
|
|
192
|
+
`hidden` `visible` `disabled` `enabled` `checked` `unchecked` `focused` `empty` `loading` `selected` `sorted ascending` `sorted descending`
|
|
193
|
+
|
|
194
|
+
### Element Types
|
|
195
|
+
|
|
196
|
+
| Group | Types |
|
|
197
|
+
|---|---|
|
|
198
|
+
| **Context** | `page` `dialog` `modal` `drawer` `tab` `alert` `overlay` `step` |
|
|
199
|
+
| **Input** | `field` `textarea` `search` `dropdown` `option` `checkbox` `radio` `toggle` `uploader` `slider` `date-picker` |
|
|
200
|
+
| **Trigger** | `button` `link` `icon` `menuitem` `tag` |
|
|
201
|
+
| **Data** | `table` `row` `column` `cell` `list` `item` `card` `section` |
|
|
202
|
+
| **Feedback** | `message` `header` `label` `text` `tooltip` `badge` `breadcrumb` `image` |
|
|
203
|
+
| **System** | `key` `frame` `spinner` `progressbar` |
|
|
148
204
|
|
|
149
205
|
### Tags
|
|
150
206
|
|
|
151
207
|
| Tag | Purpose |
|
|
152
208
|
|---|---|
|
|
209
|
+
| `@auto` | Standard scenario, ready for automation |
|
|
210
|
+
| `@manual` | Skip scenario in generation |
|
|
211
|
+
| `@smoke` / `@regression` | Test suite grouping |
|
|
153
212
|
| `@auth:role` | Use Playwright storage state for auth |
|
|
154
213
|
| `@no-auth` | Disable inherited auth for this scenario |
|
|
155
214
|
| `@steps:name` | Define reusable step group |
|
|
156
215
|
| `@extend:name` | Inherit steps from another scenario |
|
|
157
|
-
| `@manual` | Skip scenario in generation |
|
|
158
216
|
|
|
159
217
|
### YAML Selector Keys
|
|
160
218
|
|
|
@@ -167,10 +225,15 @@ Keys are **lowercase with spaces**, Unicode preserved:
|
|
|
167
225
|
|
|
168
226
|
```yaml
|
|
169
227
|
search:
|
|
170
|
-
type: 'placeholder' # testid, role, placeholder, label, text, locator, page
|
|
228
|
+
type: 'placeholder' # testid, role, placeholder, label, text, locator, page, upload, frame
|
|
171
229
|
value: 'Search users' # placeholder text, role name, CSS selector, etc.
|
|
172
230
|
name: 'Search' # accessible name (for role type)
|
|
173
231
|
nth: 0 # element index (for multiple matches)
|
|
232
|
+
exact: true # exact name matching
|
|
233
|
+
columns: # table column config (for table type)
|
|
234
|
+
status:
|
|
235
|
+
index: 2
|
|
236
|
+
header: Status
|
|
174
237
|
```
|
|
175
238
|
|
|
176
239
|
Priority: `data-testid` > `role+name` > `placeholder` > `label` > `text` > `CSS locator`
|