@sun-asterisk/sungen 2.3.0 → 2.4.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.
Files changed (90) hide show
  1. package/README.md +12 -13
  2. package/dist/cli/index.js +1 -1
  3. package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/table-action-in-row.hbs +1 -1
  4. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/table-column-exists.hbs +5 -1
  5. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/table-row-exists.hbs +7 -1
  6. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/table-row-not-exists.hbs +5 -1
  7. package/dist/generators/test-generator/patterns/interaction-patterns.d.ts.map +1 -1
  8. package/dist/generators/test-generator/patterns/interaction-patterns.js +0 -13
  9. package/dist/generators/test-generator/patterns/interaction-patterns.js.map +1 -1
  10. package/dist/generators/test-generator/patterns/table-patterns.d.ts +9 -0
  11. package/dist/generators/test-generator/patterns/table-patterns.d.ts.map +1 -1
  12. package/dist/generators/test-generator/patterns/table-patterns.js +94 -98
  13. package/dist/generators/test-generator/patterns/table-patterns.js.map +1 -1
  14. package/dist/generators/test-generator/patterns/types.d.ts +2 -0
  15. package/dist/generators/test-generator/patterns/types.d.ts.map +1 -1
  16. package/dist/generators/test-generator/step-mapper.d.ts +13 -0
  17. package/dist/generators/test-generator/step-mapper.d.ts.map +1 -1
  18. package/dist/generators/test-generator/step-mapper.js +80 -0
  19. package/dist/generators/test-generator/step-mapper.js.map +1 -1
  20. package/dist/orchestrator/ai-rules-updater.d.ts.map +1 -1
  21. package/dist/orchestrator/ai-rules-updater.js +8 -4
  22. package/dist/orchestrator/ai-rules-updater.js.map +1 -1
  23. package/dist/orchestrator/project-initializer.d.ts.map +1 -1
  24. package/dist/orchestrator/project-initializer.js +33 -2
  25. package/dist/orchestrator/project-initializer.js.map +1 -1
  26. package/dist/orchestrator/screen-manager.js +1 -1
  27. package/dist/orchestrator/screen-manager.js.map +1 -1
  28. package/dist/orchestrator/templates/ai-instructions/claude-cmd-add-screen.md +5 -5
  29. package/{src/orchestrator/templates/ai-instructions/claude-cmd-make-tc.md → dist/orchestrator/templates/ai-instructions/claude-cmd-create-test.md} +7 -6
  30. package/dist/orchestrator/templates/ai-instructions/claude-cmd-review.md +21 -0
  31. package/{src/orchestrator/templates/ai-instructions/claude-cmd-make-test.md → dist/orchestrator/templates/ai-instructions/claude-cmd-run-test.md} +2 -2
  32. package/dist/orchestrator/templates/ai-instructions/claude-config.md +65 -12
  33. package/dist/orchestrator/templates/ai-instructions/claude-skill-error-mapping.md +128 -52
  34. package/dist/orchestrator/templates/ai-instructions/claude-skill-gherkin-syntax.md +12 -43
  35. package/dist/orchestrator/templates/ai-instructions/claude-skill-selector-fix.md +67 -239
  36. package/dist/orchestrator/templates/ai-instructions/claude-skill-tc-generation.md +40 -240
  37. package/dist/orchestrator/templates/ai-instructions/claude-skill-tc-review.md +104 -0
  38. package/dist/orchestrator/templates/ai-instructions/claude-skill-viewpoint.md +186 -0
  39. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-add-screen.md +4 -4
  40. package/dist/orchestrator/templates/ai-instructions/{copilot-cmd-make-tc.md → copilot-cmd-create-test.md} +8 -7
  41. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-review.md +24 -0
  42. package/{src/orchestrator/templates/ai-instructions/copilot-cmd-make-test.md → dist/orchestrator/templates/ai-instructions/copilot-cmd-run-test.md} +3 -3
  43. package/dist/orchestrator/templates/ai-instructions/copilot-config.md +66 -13
  44. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-error-mapping.md +128 -52
  45. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-gherkin-syntax.md +12 -43
  46. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-selector-fix.md +67 -214
  47. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-tc-generation.md +40 -240
  48. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-tc-review.md +104 -0
  49. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint.md +186 -0
  50. package/dist/orchestrator/templates/readme.md +4 -4
  51. package/package.json +1 -1
  52. package/src/cli/index.ts +1 -1
  53. package/src/generators/test-generator/adapters/playwright/templates/steps/actions/table-action-in-row.hbs +1 -1
  54. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/table-column-exists.hbs +5 -1
  55. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/table-row-exists.hbs +7 -1
  56. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/table-row-not-exists.hbs +5 -1
  57. package/src/generators/test-generator/patterns/interaction-patterns.ts +0 -14
  58. package/src/generators/test-generator/patterns/table-patterns.ts +98 -111
  59. package/src/generators/test-generator/patterns/types.ts +2 -0
  60. package/src/generators/test-generator/step-mapper.ts +87 -1
  61. package/src/orchestrator/ai-rules-updater.ts +8 -4
  62. package/src/orchestrator/project-initializer.ts +38 -2
  63. package/src/orchestrator/screen-manager.ts +1 -1
  64. package/src/orchestrator/templates/ai-instructions/claude-cmd-add-screen.md +5 -5
  65. package/{dist/orchestrator/templates/ai-instructions/claude-cmd-make-tc.md → src/orchestrator/templates/ai-instructions/claude-cmd-create-test.md} +7 -6
  66. package/src/orchestrator/templates/ai-instructions/claude-cmd-review.md +21 -0
  67. package/{dist/orchestrator/templates/ai-instructions/claude-cmd-make-test.md → src/orchestrator/templates/ai-instructions/claude-cmd-run-test.md} +2 -2
  68. package/src/orchestrator/templates/ai-instructions/claude-config.md +65 -12
  69. package/src/orchestrator/templates/ai-instructions/claude-skill-error-mapping.md +128 -52
  70. package/src/orchestrator/templates/ai-instructions/claude-skill-gherkin-syntax.md +12 -43
  71. package/src/orchestrator/templates/ai-instructions/claude-skill-selector-fix.md +67 -239
  72. package/src/orchestrator/templates/ai-instructions/claude-skill-tc-generation.md +40 -240
  73. package/src/orchestrator/templates/ai-instructions/claude-skill-tc-review.md +104 -0
  74. package/src/orchestrator/templates/ai-instructions/claude-skill-viewpoint.md +186 -0
  75. package/src/orchestrator/templates/ai-instructions/copilot-cmd-add-screen.md +4 -4
  76. package/src/orchestrator/templates/ai-instructions/{copilot-cmd-make-tc.md → copilot-cmd-create-test.md} +8 -7
  77. package/src/orchestrator/templates/ai-instructions/copilot-cmd-review.md +24 -0
  78. package/{dist/orchestrator/templates/ai-instructions/copilot-cmd-make-test.md → src/orchestrator/templates/ai-instructions/copilot-cmd-run-test.md} +3 -3
  79. package/src/orchestrator/templates/ai-instructions/copilot-config.md +66 -13
  80. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-error-mapping.md +128 -52
  81. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-gherkin-syntax.md +12 -43
  82. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-selector-fix.md +67 -214
  83. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-tc-generation.md +40 -240
  84. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-tc-review.md +104 -0
  85. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint.md +186 -0
  86. package/src/orchestrator/templates/readme.md +4 -4
  87. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/table-cell-by-filter.hbs +0 -2
  88. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/table-cell-by-index.hbs +0 -2
  89. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/table-cell-by-filter.hbs +0 -2
  90. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/table-cell-by-index.hbs +0 -2
@@ -1,69 +1,145 @@
1
1
  ---
2
2
  name: sungen-error-mapping
3
- description: 'Playwright and Sungen error to fix mapping. Auto-loaded when running or debugging tests.'
3
+ description: 'Error diagnosis and fix strategy — systematic debugging flow, error patterns, fix priorities. Auto-loaded during run-test.'
4
4
  user-invocable: false
5
5
  ---
6
6
 
7
- ## Playwright Errors Fix
7
+ ## Diagnosis Flow (before fixing anything)
8
8
 
9
- | Error | Fix |
10
- |---|---|
11
- | strict mode violation | add `nth`, `exact: true`, or specific `name` in selectors.yaml |
12
- | Element is not an input | change `type` or `value` in selectors.yaml |
13
- | Timeout waiting for selector | fix `type`/`value`/`name` to match element in selectors.yaml |
14
- | toBeVisible Timeout | verify accessible name or use `testid` in selectors.yaml |
15
- | toHaveText mismatch | fix expected text in `test-data.yaml` — OR if element is an input (field/textarea/search/dropdown), change Gherkin type so compiler uses `toHaveValue` instead |
16
- | toHaveValue mismatch | fix expected value in `test-data.yaml` — this is for input elements (field, textarea, search, dropdown, slider, date-picker) |
17
- | toContainText mismatch | fix expected partial text in `test-data.yaml` |
18
- | Navigation failed | fix page `value` path in selectors.yaml |
19
- | not a select | set `variant: 'custom'` in selectors.yaml |
20
- | Frame not found | fix `frame` value in selectors.yaml |
21
- | dialog was dismissed | alert step is AFTER the trigger — move `click [OK] alert` BEFORE the button click that opens the dialog |
22
- | page.once('dialog') never fired | no browser dialog appeared — check if the action actually triggers a `window.alert/confirm/prompt`, not a CSS modal |
23
-
24
- ### Assertion type mismatch (toHaveText vs toHaveValue)
25
-
26
- Sungen picks the assertion based on element type:
27
- - **Input types** (`field`, `textarea`, `search`, `dropdown`, `slider`, `date-picker`) → `toHaveValue()`
28
- - **Text types** (everything else: `message`, `header`, `label`, `row`, etc.) → `toHaveText()`
29
- - **Partial match** (uses `contains` keyword) → `toContainText()`
30
-
31
- If you see `toHaveText` failing on an input element, the Gherkin step has the wrong target type. Fix: change the target type in the `.feature` file (e.g., `see [Email] message with {{v}}` → `see [Email] field with {{v}}`).
32
-
33
- ## Auth Errors → Fix
9
+ **Step 1: Read the error** — extract: error type, element name, expected vs actual, file:line.
34
10
 
35
- | Symptom | Fix |
36
- |---|---|
37
- | Tests redirect to login page | `specs/.auth/<role>.json` missing or expired. Tell user: `sungen makeauth <role> --url <baseURL>` |
38
- | `storageState` file not found | Run `sungen makeauth <role> --url <baseURL>` to create auth state |
39
- | Most tests timeout on first step | Auth expired — re-run `sungen makeauth <role> --url <baseURL>` |
40
- | Page shows home/login instead of target | SPA routing + expired auth. Re-run `sungen makeauth`, add `wait for` step after navigation |
11
+ **Step 2: Read error context** — check `test-results/` for the snapshot at failure time. This shows the exact page state when the test failed — more reliable than re-navigating with MCP.
12
+
13
+ **Step 3: Compare** match the failing selector against the snapshot. Ask:
14
+ - Does the element exist on the page?
15
+ - Does the accessible name match exactly?
16
+ - Are there multiple matches (strict mode)?
17
+ - Is the element inside an iframe or dialog?
18
+ - Is the page in the expected state (correct URL, loaded)?
19
+
20
+ Then choose the fix from the patterns below.
21
+
22
+ ---
23
+
24
+ ## Fix Priority (try in order)
25
+
26
+ 1. **Auth issue** — page redirected to login? Fix auth first, everything else is noise
27
+ 2. **Element not found** — wrong name/type/value in selectors.yaml. Re-snapshot, copy exact name
28
+ 3. **Multiple matches** — add `nth`, `exact: true`, or `scope` to narrow down
29
+ 4. **Wrong assertion** — `toHaveText` vs `toHaveValue` mismatch, wrong expected data
30
+ 5. **Timing** — SPA not loaded, async content. Add `wait for` step in .feature
31
+
32
+ ---
33
+
34
+ ## Playwright Errors
35
+
36
+ ### Selector errors → fix in `selectors.yaml`
37
+
38
+ | Error | Diagnosis | Fix |
39
+ |---|---|---|
40
+ | strict mode violation | Multiple elements match | Add `nth: 0`, `exact: true`, or more specific `name` |
41
+ | Timeout / not found | Element doesn't exist or name wrong | Re-snapshot → copy exact accessible name. Check iframe/dialog scope |
42
+ | Element is not an input | Wrong element type targeted | Change `type` or `value` to match actual element |
43
+ | not a select | Custom dropdown, not native `<select>` | Set `variant: 'custom'` |
44
+ | Frame not found | iframe selector wrong or doesn't exist | Fix `frame` value, verify iframe in snapshot |
45
+
46
+ ### Assertion errors → fix in `test-data.yaml` or `.feature`
47
+
48
+ | Error | Diagnosis | Fix |
49
+ |---|---|---|
50
+ | toHaveText mismatch | Expected text differs from actual | Fix value in test-data. If element is input type → change Gherkin type to `field`/`textarea` (triggers `toHaveValue` instead) |
51
+ | toHaveValue mismatch | Expected value differs from actual | Fix value in test-data |
52
+ | toContainText mismatch | Partial text not found | Fix expected partial text in test-data |
53
+ | toBeVisible timeout | Element exists but hidden, or name wrong | Check: is element conditionally visible? Wrong name? Inside dialog? |
54
+ | toHaveCount mismatch | Row count differs | Fix expected count in test-data. Verify: is table loaded? Filtered? |
41
55
 
42
- **Never run `sungen makeauth` yourself.** Always tell the user to run it manually.
56
+ ### Assertion type rule
43
57
 
44
- ## Performance Errors Fix (specs/base.ts)
58
+ Sungen picks assertion based on element type:
59
+ - **Input** (`field`, `textarea`, `search`, `dropdown`, `slider`) → `toHaveValue()`
60
+ - **Text** (everything else: `message`, `heading`, `label`, `row`) → `toHaveText()`
61
+ - **Partial** (`contains` keyword) → `toContainText()`
45
62
 
46
- All generated `.spec.ts` files import from `specs/base.ts`. This shared file handles context caching, navigation skip, and overlay cleanup.
63
+ If `toHaveText` fails on an input the Gherkin step has wrong target type. Fix: change type in `.feature`.
47
64
 
48
- | Symptom | Fix in `specs/base.ts` |
65
+ ---
66
+
67
+ ## Table-Specific Errors
68
+
69
+ | Error | Diagnosis | Fix |
70
+ |---|---|---|
71
+ | `tableRow is not defined` | Column assertion without preceding row scope step | Add `User see [Ref] row in [Table] table with {{v}}` before `User see [Col] column with {{v}}` |
72
+ | `toHaveText` on cell fails (with columns) | Wrong column index in `columns` config | Re-count columns in snapshot (0-indexed). Fix `index` in selectors.yaml |
73
+ | `toBeVisible` on cell fails (no columns) | `filter({ hasText })` didn't match | Check exact cell text in snapshot. Fix value in test-data |
74
+ | Row filter matches 0 rows | Filter text doesn't match any row content | Re-snapshot → find actual row text. Fix filter value in test-data |
75
+ | Row filter matches multiple rows | Filter text is too generic (matches multiple rows) | Use more specific filter text (unique identifier like email, ID) |
76
+ | Table not found | Wrong table name or table not rendered | Re-snapshot → copy exact table accessible name |
77
+
78
+ ---
79
+
80
+ ## Auth Errors
81
+
82
+ | Symptom | Fix |
49
83
  |---|---|
50
- | Server returns 429 (rate limited) | Context caching broken check `contextCache` Map reuses sessions per `storageState` |
51
- | Tests slow even with `--workers=1` | Navigation skip not working check `goto` patch compares `currentPath === url` |
52
- | Previous test's modal blocks next test | Overlay cleanup insufficient improve Escape/click dismiss logic |
53
- | All tests fail on first navigation | `page.url()` is `about:blank` check try/catch in goto patch |
54
- | Multiple session invalidation errors | Too many contexts created — ensure `contextCache.get(cacheKey)` returns existing context |
84
+ | Redirect to login page | Auth expired. Tell user: `sungen makeauth <role> --url <baseURL>` |
85
+ | `storageState` file not found | Run `sungen makeauth <role> --url <baseURL>` |
86
+ | Most tests timeout on first step | Auth expiredre-run makeauth |
87
+ | Page shows home instead of target | SPA + expired auth. Re-run makeauth + add `wait for` step |
55
88
 
56
- **Rules:**
57
- - `base.ts` changes affect ALL tests — edit carefully
58
- - Small project-specific tweaks are OK (e.g., custom overlay dismiss, timeout tuning, extra wait logic)
59
- - Do NOT move individual selector/data fixes into `base.ts` — those belong in `selectors.yaml` / `test-data.yaml`
60
- - If unsure whether a fix belongs in `base.ts` or selectors, ask the user
89
+ **Never run `sungen makeauth` yourself.** Tell the user.
61
90
 
62
- ## Sungen Errors → Fix
91
+ ---
92
+
93
+ ## Sungen Compile Errors
63
94
 
64
95
  | Error | Fix |
65
96
  |---|---|
66
- | Unknown step pattern | rewrite `.feature` step to match supported pattern |
67
- | Missing selector | add key to `selectors.yaml` |
68
- | Missing variable | add key to `test-data.yaml` |
69
- | Invalid selector type | use: role/testid/placeholder/label/text/locator/page/upload/frame |
97
+ | Unknown step pattern | Rewrite step to match `sungen-gherkin-syntax` patterns |
98
+ | Missing selector | Add key to `selectors.yaml` |
99
+ | Missing variable | Add key to `test-data.yaml` |
100
+ | Invalid selector type | Use: role/testid/placeholder/label/text/locator/page/upload/frame |
101
+
102
+ ---
103
+
104
+ ## Performance & Infrastructure Errors → Fix in `specs/base.ts`
105
+
106
+ All generated `.spec.ts` import from `specs/base.ts` — shared context caching, navigation, overlay cleanup. AI **can and should** tune `base.ts` to match the project.
107
+
108
+ | Symptom | Root cause | Fix |
109
+ |---|---|---|
110
+ | Server 429 (rate limited) | Too many browser contexts | Fix `contextCache` to reuse sessions per `storageState` |
111
+ | Tests slow with `--workers=1` | Redundant navigation | Fix goto patch: skip if `currentPath === url` |
112
+ | Previous test's modal blocks next | Overlay not cleaned up | Add/improve Escape + backdrop click in cleanup hook |
113
+ | All tests fail on first navigation | `page.url()` is `about:blank` | Add try/catch in goto patch |
114
+ | Flaky timeouts on SPA pages | Default timeout too short for app | Increase `actionTimeout` / `navigationTimeout` |
115
+ | Tests pass individually but fail in batch | Shared state leaking between tests | Isolate context per test or reset state in `beforeEach` |
116
+
117
+ ### What AI CAN fix in `base.ts`
118
+
119
+ - Timeout tuning (increase for slow APIs, decrease for fast apps)
120
+ - Custom overlay/modal dismiss logic (project has unique close patterns)
121
+ - Navigation wait strategy (`networkidle` vs `domcontentloaded` vs custom)
122
+ - Context caching strategy (per-role, per-session)
123
+ - Cookie/localStorage cleanup between tests
124
+
125
+ ### What AI should NOT move into `base.ts`
126
+
127
+ - Individual selector fixes → belong in `selectors.yaml`
128
+ - Test data values → belong in `test-data.yaml`
129
+ - Single-test workarounds → belong in the `.spec.ts` directly
130
+
131
+ ---
132
+
133
+ ## Smart Fix Strategy
134
+
135
+ ### When multiple tests fail on the same element
136
+ Fix the **root cause once** — don't fix each test individually. Group by selector key, fix selectors.yaml, recompile, re-run batch.
137
+
138
+ ### When you're unsure about the fix
139
+ **Re-snapshot** — `browser_navigate` to the failing page, take `browser_snapshot`, compare the live state against what the test expects. This is faster than guessing.
140
+
141
+ ### When the fix might break other tests
142
+ After fixing selectors.yaml, run ALL tests (not just the failing one) to catch regressions from renamed/changed selectors.
143
+
144
+ ### When nothing works after 3 attempts
145
+ Ask the user. The issue might be: dynamic content, race condition, environment-specific state, or a real application bug.
@@ -33,7 +33,6 @@ AND → inherits from preceding keyword
33
33
  User is on [T] page # navigate to page
34
34
  User is on [T] page with {{v}} # navigate with data (e.g., detail page with ID)
35
35
  User is on [T] dialog # enter dialog scope
36
- User is logged in | is not logged in # auth state
37
36
  ```
38
37
 
39
38
  ### Form
@@ -89,8 +88,8 @@ User see [message text] alert # assert dialog message
89
88
  ### Keyboard
90
89
 
91
90
  ```
92
- User press [Escape] key # global key press
93
- User press [Enter] on [T] field # key on element
91
+ User press Escape key # global key press
92
+ User press Enter on [T] field # key on element
94
93
  ```
95
94
 
96
95
  ### Wait
@@ -155,29 +154,16 @@ User see [T] page # URL assertion
155
154
  ### Table
156
155
 
157
156
  ```
158
- User see [Col] column in [Table] table # column exists (parent scoping)
159
- User see [Table] table row with {{f}} # row exists
160
- User see [Table] table has no row with {{f}} # row not exists
161
- User see [Table] table with {{count}} rows # row count
162
- User see [Table] table is empty # empty table
163
- User see [Table] table row with {{f}} has [Col] with {{v}} # cell by filter
164
- User see [Table] table row 1 [Col] cell with {{v}} # cell by index
165
- User click [Act] in [Table] table row with {{f}} # action in row
157
+ User see [Col] column in [Table] table # column exists
158
+ User see [Ref] row in [Table] table with {{v}} # row exists (enters row scope)
159
+ User see [Ref] row in [Table] table with {{v}} is hidden # row hidden
160
+ User see [Table] table with {{count}} # row count
161
+ User see [Table] table is empty # empty table
162
+ User see [Col] column with {{v}} # cell value (row scoped)
163
+ User click [Act] button in [Table] table with {{v}} # action in row
166
164
  ```
167
165
 
168
- ### Parent Scoping (disambiguation)
169
-
170
- ```
171
- User click [Submit] button in [User Info] form # button inside specific form
172
- User fill [Email] field in [Registration] form with {{v}} # field inside specific form
173
- User see [Total] text in [Summary] section with {{v}} # text inside specific section
174
- User click [Delete] button in [Active Users] table # button inside specific table
175
- ```
176
-
177
- - **Optional** — only use when page has 2+ similar UI blocks
178
- - **Valid parent types**: `table`, `list`, `section`, `dialog`, `form`
179
- - **Max 2 levels**: `[Target] in [Parent]`. **NEVER** nest 3 levels: `[A] in [B] in [C]`
180
- - Parent resolves from selectors YAML first, falls back to auto-infer `getByRole(parentType, { name })`
166
+ 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 })`.
181
167
 
182
168
  ### States
183
169
 
@@ -196,24 +182,7 @@ User click [Delete] button in [Active Users] table # button inside specifi
196
182
 
197
183
  ### Auto-infer (no YAML entry needed)
198
184
 
199
- | Gherkin | Playwright locator |
200
- |---|---|
201
- | `[Submit] button` | `getByRole('button', { name: 'Submit' })` |
202
- | `[Home] link` | `getByRole('link', { name: 'Home' })` |
203
- | `[Welcome] heading` / `header` | `getByRole('heading', { name: 'Welcome' })` |
204
- | `[Email] field` | `getByPlaceholder('Email')` |
205
- | `[Success] text` / `message` / `label` | `getByText('Success')` |
206
- | `[Terms] checkbox` | `getByRole('checkbox', { name: 'Terms' })` |
207
- | `[Male] radio` | `getByRole('radio', { name: 'Male' })` |
208
- | `[Global] search` | `getByRole('searchbox', { name: 'Global' })` |
209
- | `[Vietnam] option` | `getByRole('option', { name: 'Vietnam' })` |
210
- | `[Price] slider` | `getByRole('slider', { name: 'Price' })` |
211
- | `[Notification] toggle` | `getByRole('switch', { name: 'Notification' })` |
212
- | `[Profile] tab` | `getByRole('tab', { name: 'Profile' })` |
213
- | `[Orders] table` | `getByRole('table', { name: 'Orders' })` |
214
- | `[Products] list` | `getByRole('list', { name: 'Products' })` |
215
- | `[Name] column` | `getByRole('columnheader', { name: 'Name' })` |
216
- | `[Confirm] dialog` / `modal` / `drawer` | `getByRole('dialog', { name: 'Confirm' })` |
185
+ Most elements auto-infer from `[Label] type` → `getByRole(type, { name: 'Label' })`. Only add YAML when the accessible name differs, needs `nth`, or needs `testid`. Full auto-infer table → see `sungen-selector-keys` skill.
217
186
 
218
187
  ## YAML Keys
219
188
 
@@ -265,7 +234,7 @@ Options: `nth` `exact` `scope` `match` `variant` `frame` `contenteditable` `colu
265
234
  |---|---|---|
266
235
  | Wrong keyword | `Given User click [T] button` | `When User click [T] button` |
267
236
  | Wrong action for type | `When User click [T] checkbox` | `When User check [T] checkbox` |
268
- | press wrong target | `When User press [Submit] button` | `When User press [Enter] key` |
237
+ | press wrong target | `When User press [Submit] button` | `When User press Enter key` |
269
238
  | uncheck radio | `When User uncheck [Male] radio` | `When User check [Female] radio` |
270
239
  | Hardcode data | `with {{admin@mail.com}}` | `with {{invalid_email}}` |
271
240
  | Missing `is` for state | `with {{text}} hidden` | `with {{text}} is hidden` |