@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.
Files changed (45) hide show
  1. package/dist/cli/index.js +1 -1
  2. package/dist/generators/gherkin-parser/index.d.ts +8 -0
  3. package/dist/generators/gherkin-parser/index.d.ts.map +1 -1
  4. package/dist/generators/gherkin-parser/index.js +12 -0
  5. package/dist/generators/gherkin-parser/index.js.map +1 -1
  6. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/table-match-data.hbs +15 -0
  7. package/dist/generators/test-generator/patterns/index.d.ts.map +1 -1
  8. package/dist/generators/test-generator/patterns/index.js +2 -1
  9. package/dist/generators/test-generator/patterns/index.js.map +1 -1
  10. package/dist/generators/test-generator/patterns/table-patterns.d.ts +4 -1
  11. package/dist/generators/test-generator/patterns/table-patterns.d.ts.map +1 -1
  12. package/dist/generators/test-generator/patterns/table-patterns.js +49 -1
  13. package/dist/generators/test-generator/patterns/table-patterns.js.map +1 -1
  14. package/dist/orchestrator/templates/ai-instructions/claude-cmd-run-test.md +19 -16
  15. package/dist/orchestrator/templates/ai-instructions/claude-skill-error-mapping.md +5 -5
  16. package/dist/orchestrator/templates/ai-instructions/claude-skill-gherkin-syntax.md +44 -1
  17. package/dist/orchestrator/templates/ai-instructions/claude-skill-selector-fix.md +46 -61
  18. package/dist/orchestrator/templates/ai-instructions/claude-skill-tc-generation.md +34 -1
  19. package/dist/orchestrator/templates/ai-instructions/claude-skill-viewpoint.md +3 -1
  20. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-run-test.md +19 -16
  21. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-error-mapping.md +5 -5
  22. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-gherkin-syntax.md +45 -2
  23. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-selector-fix.md +46 -61
  24. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-tc-generation.md +34 -1
  25. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint.md +3 -1
  26. package/dist/orchestrator/templates/readme.md +82 -19
  27. package/package.json +1 -1
  28. package/src/cli/index.ts +1 -1
  29. package/src/generators/gherkin-parser/index.ts +23 -0
  30. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/table-match-data.hbs +15 -0
  31. package/src/generators/test-generator/patterns/index.ts +2 -1
  32. package/src/generators/test-generator/patterns/table-patterns.ts +58 -1
  33. package/src/orchestrator/templates/ai-instructions/claude-cmd-run-test.md +19 -16
  34. package/src/orchestrator/templates/ai-instructions/claude-skill-error-mapping.md +5 -5
  35. package/src/orchestrator/templates/ai-instructions/claude-skill-gherkin-syntax.md +44 -1
  36. package/src/orchestrator/templates/ai-instructions/claude-skill-selector-fix.md +46 -61
  37. package/src/orchestrator/templates/ai-instructions/claude-skill-tc-generation.md +34 -1
  38. package/src/orchestrator/templates/ai-instructions/claude-skill-viewpoint.md +3 -1
  39. package/src/orchestrator/templates/ai-instructions/copilot-cmd-run-test.md +19 -16
  40. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-error-mapping.md +5 -5
  41. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-gherkin-syntax.md +45 -2
  42. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-selector-fix.md +46 -61
  43. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-tc-generation.md +34 -1
  44. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint.md +3 -1
  45. 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. Use this when writing or editing .feature, selectors.yaml, or test-data.yaml files.'
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 upload [T] uploader with {{f}} # file upload
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 generation and fixing strategy — explore live page, generate selectors.yaml, validate, auto-fix. Auto-loaded by run-test command.'
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
- ## When to Generate
7
+ ## Strategy: Fix Only What Breaks
8
8
 
9
- Selectors are generated during `/sungen:run-test`, NOT during `/sungen:create-test`.
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: Authenticate & Snapshot
15
+ ## Step 1: Diagnose Failures
14
16
 
15
- 1. Read `baseURL` from `playwright.config.ts`
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
- **Never use `sungen makeauth`.** Never use `browser_evaluate` to inject cookies.
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: Build Element Catalog
33
+ ## Step 2: Targeted MCP Exploration
25
34
 
26
- **Never guess names from Gherkin labels. Copy exact values from snapshot.**
35
+ Only when `test-results/` screenshots are insufficient:
27
36
 
28
- Catalog all accessible elements from snapshot: buttons, links, headings, inputs, regions, images.
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
- Then check for `data-testid` attributes:
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: Map Gherkin Labels → Selectors
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
- **No accessible name**: use `locator` with CSS/ARIA attribute:
54
- ```yaml
55
- search field:
56
- type: 'locator'
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
- **Dynamic content**: never use `type: text` with specific value. Use `testid` or structural `role` + `nth`.
61
-
62
- **Multiple matches**: add `nth: 0` for first occurrence.
63
-
64
- Auto-infer rules and lookup priority see `sungen-selector-keys` skill.
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 iframeadd `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 using the v2.3 syntax, generate table selectors with `columns` config:
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: Validate Before Running
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 all batches pass → run ALL tests once for regression check.
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 5 attempts per batch → ask user about direct `.spec.ts` fix.
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 [Create User] page
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: %, _, * treated as normal text (escaped)
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-test │────────▶│ /make-
43
- │ screen │ │ │ │ test │
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> [<Target>] <type> with {{<Value>}}
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
- - `{{Value}}` → test data reference → lookup in `test-data/*.yaml`
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
- | Assert visible | `User see [Welcome] heading is visible` |
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
- | Wait for | `User wait for [Modal] dialog is visible` |
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: `hidden` `visible` `disabled` `enabled` `checked` `unchecked` `focused` `empty` `loading` `selected`
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`