@sun-asterisk/sungen 2.0.3 → 2.1.1
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/adapter-interface.d.ts +6 -1
- package/dist/generators/test-generator/adapters/adapter-interface.d.ts.map +1 -1
- package/dist/generators/test-generator/adapters/playwright/templates/scenario.hbs +0 -4
- package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/drag-action.hbs +1 -0
- package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/expand-action.hbs +11 -0
- package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/toggle-action.hbs +1 -0
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/loading-assertion.hbs +2 -0
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/selected-assertion.hbs +2 -0
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/sorted-assertion.hbs +2 -0
- package/dist/generators/test-generator/adapters/playwright/templates/test-file.hbs +25 -0
- package/dist/generators/test-generator/code-generator.d.ts.map +1 -1
- package/dist/generators/test-generator/code-generator.js +41 -3
- package/dist/generators/test-generator/code-generator.js.map +1 -1
- package/dist/generators/test-generator/patterns/assertion-patterns.d.ts.map +1 -1
- package/dist/generators/test-generator/patterns/assertion-patterns.js +58 -6
- package/dist/generators/test-generator/patterns/assertion-patterns.js.map +1 -1
- package/dist/generators/test-generator/patterns/form-patterns.js +3 -3
- package/dist/generators/test-generator/patterns/form-patterns.js.map +1 -1
- package/dist/generators/test-generator/patterns/interaction-patterns.d.ts.map +1 -1
- package/dist/generators/test-generator/patterns/interaction-patterns.js +86 -1
- package/dist/generators/test-generator/patterns/interaction-patterns.js.map +1 -1
- package/dist/generators/test-generator/template-engine.d.ts +6 -0
- package/dist/generators/test-generator/template-engine.d.ts.map +1 -1
- package/dist/generators/test-generator/template-engine.js +1 -0
- package/dist/generators/test-generator/template-engine.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/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 +127 -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 +127 -0
- package/dist/orchestrator/templates/ai-instructions/copilot-skill-selector-keys.md +94 -0
- package/dist/orchestrator/templates/readme.md +42 -38
- 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/adapter-interface.ts +7 -1
- package/src/generators/test-generator/adapters/playwright/templates/scenario.hbs +0 -4
- package/src/generators/test-generator/adapters/playwright/templates/steps/actions/drag-action.hbs +1 -0
- package/src/generators/test-generator/adapters/playwright/templates/steps/actions/expand-action.hbs +11 -0
- package/src/generators/test-generator/adapters/playwright/templates/steps/actions/toggle-action.hbs +1 -0
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/loading-assertion.hbs +2 -0
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/selected-assertion.hbs +2 -0
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/sorted-assertion.hbs +2 -0
- package/src/generators/test-generator/adapters/playwright/templates/test-file.hbs +25 -0
- package/src/generators/test-generator/code-generator.ts +50 -8
- package/src/generators/test-generator/patterns/assertion-patterns.ts +62 -6
- package/src/generators/test-generator/patterns/form-patterns.ts +3 -3
- package/src/generators/test-generator/patterns/interaction-patterns.ts +93 -1
- package/src/generators/test-generator/template-engine.ts +4 -0
- package/src/orchestrator/project-initializer.ts +74 -58
- 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 +127 -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 +127 -0
- package/src/orchestrator/templates/ai-instructions/copilot-skill-selector-keys.md +94 -0
- package/src/orchestrator/templates/readme.md +42 -38
- package/dist/orchestrator/templates/ai-rules.md +0 -189
- package/src/orchestrator/templates/ai-rules.md +0 -189
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: make-test
|
|
3
|
+
description: 'Compile and run Playwright tests for a Sungen screen — auto-fixes selectors on failure, falls back to AI .spec.ts fix after 5 attempts'
|
|
4
|
+
argument-hint: [screen-name]
|
|
5
|
+
allowed-tools: Read, Grep, Bash, Glob, Edit
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Role
|
|
9
|
+
|
|
10
|
+
You are a **Senior Developer** specialized in Playwright test debugging. You diagnose test failures, fix selectors/test-data, and patch `.spec.ts` when needed. Use the `sungen-error-mapping` and `sungen-selector-keys` skills for error diagnosis and key fixes.
|
|
11
|
+
|
|
12
|
+
## Parameters
|
|
13
|
+
|
|
14
|
+
Parse from `$ARGUMENTS`:
|
|
15
|
+
- **screen** — screen name (e.g., `login`, `dashboard`)
|
|
16
|
+
|
|
17
|
+
If missing, ask the user.
|
|
18
|
+
|
|
19
|
+
## Steps
|
|
20
|
+
|
|
21
|
+
### 1. Verify screen exists
|
|
22
|
+
|
|
23
|
+
Check `qa/screens/<screen>/` has all 3 source files. If not, tell user to run `/sungen:add-screen` and `/sungen:make-tc` first.
|
|
24
|
+
|
|
25
|
+
### 2. Compile
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
sungen generate --screen <screen>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
If fails, fix source files per `sungen-error-mapping` skill and retry.
|
|
32
|
+
|
|
33
|
+
### 3. Run tests
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npx playwright test specs/screens/<screen>/<screen>.spec.ts
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
If pass → Step 5. If fail → Step 4.
|
|
40
|
+
|
|
41
|
+
### 4. Fix and retry (max 5 attempts)
|
|
42
|
+
|
|
43
|
+
Per attempt:
|
|
44
|
+
1. Read Playwright error output
|
|
45
|
+
2. Map error to fix using `sungen-error-mapping` skill
|
|
46
|
+
3. Fix `selectors.yaml` or `test-data.yaml`
|
|
47
|
+
4. Recompile: `sungen generate --screen <screen>`
|
|
48
|
+
5. Retest
|
|
49
|
+
|
|
50
|
+
### 5. Fallback — AI fix .spec.ts
|
|
51
|
+
|
|
52
|
+
After 5 failed attempts, ask user:
|
|
53
|
+
> Tests still failing. Would you like me to directly fix the `.spec.ts` file?
|
|
54
|
+
|
|
55
|
+
If yes: read `.spec.ts`, fix locators/assertions, mark with `// AI-fixed: <reason>`
|
|
56
|
+
|
|
57
|
+
### 6. Confirm
|
|
58
|
+
|
|
59
|
+
Show: pass/fail, attempt count, files changed.
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Sungen AI Rules
|
|
2
|
+
|
|
3
|
+
You generate 3 files for sungen — a Gherkin compiler that produces Playwright tests.
|
|
4
|
+
**You do NOT write Playwright code.** You only write `.feature`, `selectors.yaml`, and `test-data.yaml`.
|
|
5
|
+
|
|
6
|
+
For Gherkin syntax, selector types, and YAML rules, the `sungen-gherkin-syntax` skill is auto-loaded when needed.
|
|
7
|
+
For error diagnosis, the `sungen-error-mapping` skill is auto-loaded when needed.
|
|
8
|
+
|
|
9
|
+
## Complete Example
|
|
10
|
+
|
|
11
|
+
Given a login page, here are the 3 files you generate:
|
|
12
|
+
|
|
13
|
+
**qa/screens/login/features/login.feature**
|
|
14
|
+
```gherkin
|
|
15
|
+
@auth:admin
|
|
16
|
+
Feature: Login Screen
|
|
17
|
+
|
|
18
|
+
Scenario: Successful login
|
|
19
|
+
Given User is on [login] page
|
|
20
|
+
When User fill [Email] field with {{email}}
|
|
21
|
+
And User fill [Password] field with {{password}}
|
|
22
|
+
And User click [Submit] button
|
|
23
|
+
Then User see [Welcome] heading with {{welcome_text}}
|
|
24
|
+
And User see [Dashboard] link is visible
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**qa/screens/login/selectors/login.yaml**
|
|
28
|
+
```yaml
|
|
29
|
+
login:
|
|
30
|
+
type: 'page'
|
|
31
|
+
value: '/login'
|
|
32
|
+
|
|
33
|
+
email:
|
|
34
|
+
type: 'placeholder'
|
|
35
|
+
value: 'Enter your email'
|
|
36
|
+
|
|
37
|
+
password:
|
|
38
|
+
type: 'placeholder'
|
|
39
|
+
value: 'Enter your password'
|
|
40
|
+
|
|
41
|
+
submit:
|
|
42
|
+
type: 'role'
|
|
43
|
+
value: 'button'
|
|
44
|
+
name: 'Submit'
|
|
45
|
+
|
|
46
|
+
welcome:
|
|
47
|
+
type: 'role'
|
|
48
|
+
value: 'heading'
|
|
49
|
+
name: 'Welcome'
|
|
50
|
+
|
|
51
|
+
dashboard:
|
|
52
|
+
type: 'role'
|
|
53
|
+
value: 'link'
|
|
54
|
+
name: 'Dashboard'
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**qa/screens/login/test-data/login.yaml**
|
|
58
|
+
```yaml
|
|
59
|
+
email: 'admin@example.com'
|
|
60
|
+
password: 'password123'
|
|
61
|
+
welcome_text: 'Welcome back'
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Using Playwright MCP to explore pages
|
|
65
|
+
|
|
66
|
+
When exploring a page to generate test files:
|
|
67
|
+
1. Read `playwright.config.ts` for `baseURL`
|
|
68
|
+
2. Use `browser_navigate` to open `baseURL + /path`
|
|
69
|
+
3. Use `browser_snapshot` to see all elements
|
|
70
|
+
4. Generate the 3 files from the snapshot
|
|
71
|
+
|
|
72
|
+
**NEVER use `browser_run_code`.** It fails with `require is not defined`.
|
|
73
|
+
Only use: `browser_navigate`, `browser_snapshot`, `browser_click`, `browser_fill_form`, `browser_evaluate`.
|
|
74
|
+
|
|
75
|
+
To browse authenticated pages via MCP:
|
|
76
|
+
1. Check if `specs/.auth/<role>.json` exists
|
|
77
|
+
2. If not, read `baseURL` from `playwright.config.ts` and tell the user to manually run: `sungen makeauth <role> --url <baseURL>`. **Do NOT execute `sungen makeauth` yourself.** Wait for user confirmation.
|
|
78
|
+
3. Read `specs/.auth/<role>.json`
|
|
79
|
+
4. `browser_navigate` to the page
|
|
80
|
+
5. `browser_evaluate` to inject localStorage and cookies from the JSON
|
|
81
|
+
6. `browser_navigate` again to reload with auth
|
|
82
|
+
|
|
83
|
+
## Commands
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
sungen add --screen <name> --path <url-path> # Create screen
|
|
87
|
+
sungen generate --screen <name> # Compile to .spec.ts
|
|
88
|
+
sungen generate --all # Compile all
|
|
89
|
+
sungen makeauth <role> # Capture auth state
|
|
90
|
+
```
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sungen-error-mapping
|
|
3
|
+
description: 'Playwright and Sungen error to fix mapping. Auto-loaded when running or debugging tests.'
|
|
4
|
+
user-invocable: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Playwright Errors → Fix
|
|
8
|
+
|
|
9
|
+
| Error | Fix in `selectors.yaml` |
|
|
10
|
+
|---|---|
|
|
11
|
+
| strict mode violation | add `nth`, `exact: true`, or specific `name` |
|
|
12
|
+
| Element is not an input | change `type` or `value` |
|
|
13
|
+
| Timeout waiting for selector | fix `type`/`value`/`name` to match element |
|
|
14
|
+
| toBeVisible Timeout | verify accessible name or use `testid` |
|
|
15
|
+
| toHaveText mismatch | fix in `test-data.yaml` |
|
|
16
|
+
| Navigation failed | fix page `value` path |
|
|
17
|
+
| not a select | set `variant: 'custom'` |
|
|
18
|
+
| Frame not found | fix `frame` value |
|
|
19
|
+
|
|
20
|
+
## Sungen Errors → Fix
|
|
21
|
+
|
|
22
|
+
| Error | Fix |
|
|
23
|
+
|---|---|
|
|
24
|
+
| Unknown step pattern | rewrite `.feature` step to match supported pattern |
|
|
25
|
+
| Missing selector | add key to `selectors.yaml` |
|
|
26
|
+
| Missing variable | add key to `test-data.yaml` |
|
|
27
|
+
| Invalid selector type | use: role/testid/placeholder/label/text/locator/page/upload/frame |
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sungen-gherkin-syntax
|
|
3
|
+
description: 'Sungen Gherkin patterns, selector types, and YAML key rules. Auto-loaded when writing .feature, selectors.yaml, or test-data.yaml.'
|
|
4
|
+
user-invocable: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Step Patterns (65 patterns)
|
|
8
|
+
|
|
9
|
+
### Setup
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
User is on [T] page # navigate to page
|
|
13
|
+
User navigate to [T] page with {{v}} # navigate with data
|
|
14
|
+
User is logged in | is not logged in # auth state
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### Form
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
User fill [T] field with {{v}} # text input
|
|
21
|
+
User clear [T] field # clear input
|
|
22
|
+
User check [T] checkbox # check
|
|
23
|
+
User uncheck [T] checkbox # uncheck
|
|
24
|
+
User select [T] dropdown with {{v}} # select option
|
|
25
|
+
User toggle [T] switch # toggle switch/checkbox
|
|
26
|
+
User upload [T] file with {{f}} # file upload
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Interaction
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
User click [T] button # click
|
|
33
|
+
User click [T] button with {{v}} # click with text match
|
|
34
|
+
User double click [T] element # double click
|
|
35
|
+
User hover [T] icon # hover
|
|
36
|
+
User drag [T] to [T2] # drag and drop
|
|
37
|
+
User expand [T] row # expand (aria-expanded)
|
|
38
|
+
User collapse [T] row # collapse (aria-expanded)
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Keyboard
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
User press Escape key # global key press
|
|
45
|
+
User press Enter on [T] field # key on element
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Wait
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
User wait for N seconds # wait timeout
|
|
52
|
+
User wait for [T] dialog # wait for element
|
|
53
|
+
User wait for [T] dialog is STATE # wait for state
|
|
54
|
+
User wait for [T] dialog with {{v}} # wait for element with text
|
|
55
|
+
User wait for [T] page # wait for navigation
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Scroll & Frame
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
User scroll to [T] section # scroll into view
|
|
62
|
+
User switch to [T] frame # enter/exit iframe
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Assertions
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
User see [T] page # URL assertion
|
|
69
|
+
User see [T] heading # visibility
|
|
70
|
+
User see [T] heading with {{v}} # visibility + text
|
|
71
|
+
User see [T] text contains {{v}} # partial text match
|
|
72
|
+
User see [T] text has text {{v}} # exact text match
|
|
73
|
+
User see [T] button is STATE # state assertion
|
|
74
|
+
User see [T] dialog with {{v}} is STATE # text + state
|
|
75
|
+
User see {{v}} # see data text
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Table
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
User see [Table] table has row with {{f}} # row exists
|
|
82
|
+
User see [Table] table has no row with {{f}} # row not exists
|
|
83
|
+
User see [Table] table has {{count}} rows # row count
|
|
84
|
+
User see [Table] table has [Col] column # column exists
|
|
85
|
+
User see [Table] table is empty # empty table
|
|
86
|
+
User see [Table] table row with {{f}} has [Col] with {{v}} # cell by filter
|
|
87
|
+
User see [Table] table row 1 [Col] cell with {{v}} # cell by index
|
|
88
|
+
User click [Act] in [Table] table row with {{f}} # action in row
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### States
|
|
92
|
+
|
|
93
|
+
`hidden` `visible` `disabled` `enabled` `checked` `unchecked` `focused` `empty` `loading` `selected` `sorted ascending` `sorted descending`
|
|
94
|
+
|
|
95
|
+
### Element Types
|
|
96
|
+
|
|
97
|
+
`page` `button` `link` `field` `textarea` `heading` `text` `checkbox` `radio` `switch` `dropdown` `dialog` `modal` `menu` `menuitem` `tab` `tabpanel` `table` `row` `cell` `list` `listitem` `icon` `image` `alert` `spinner` `progressbar` `section` `region` `nav` `frame` `uploader` `file` `columnheader` `tooltip` `slider` `treeitem`
|
|
98
|
+
|
|
99
|
+
## YAML Keys
|
|
100
|
+
|
|
101
|
+
`[Reference]` → **lowercase, spaces→dots**: `[Search Content]` → `search.content:`
|
|
102
|
+
|
|
103
|
+
## Selectors (priority order)
|
|
104
|
+
|
|
105
|
+
| type | value | name | use |
|
|
106
|
+
|---|---|---|---|
|
|
107
|
+
| `testid` | data-testid | — | when exists |
|
|
108
|
+
| `role` | button/heading/link… | accessible name | interactive elements |
|
|
109
|
+
| `placeholder` | placeholder text | — | inputs |
|
|
110
|
+
| `label` | label text | — | labeled inputs |
|
|
111
|
+
| `text` | — | — | static text |
|
|
112
|
+
| `locator` | CSS selector | — | last resort |
|
|
113
|
+
| `page` | relative URL | — | navigation |
|
|
114
|
+
| `upload` | — | — | file inputs |
|
|
115
|
+
| `frame` | iframe selector | — | iframes |
|
|
116
|
+
|
|
117
|
+
Options: `nth` `exact` `scope` `match` `variant` `frame` `contenteditable` `columns`
|
|
118
|
+
|
|
119
|
+
## Tags
|
|
120
|
+
|
|
121
|
+
| Tag | Effect |
|
|
122
|
+
|---|---|
|
|
123
|
+
| `@auth:role` | Use auth storage state for role |
|
|
124
|
+
| `@no-auth` | Disable inherited auth |
|
|
125
|
+
| `@steps:name` | Define reusable step block |
|
|
126
|
+
| `@extend:name` | Prepend steps from @steps block |
|
|
127
|
+
| `@manual` | Skip in generation |
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sungen-selector-keys
|
|
3
|
+
description: 'Rules for generating correct YAML selector keys from Gherkin [Reference] names. Auto-loaded when creating or fixing selectors.yaml files.'
|
|
4
|
+
user-invocable: false
|
|
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.).
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: 'Add a new Sungen screen — scaffolds directories and delegates to make-tc for test case creation'
|
|
3
|
+
mode: 'agent'
|
|
4
|
+
tools: ['terminal']
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
You are adding a new Sungen screen for test generation.
|
|
8
|
+
|
|
9
|
+
## Parameters
|
|
10
|
+
|
|
11
|
+
Parse from user input:
|
|
12
|
+
- **screen** — screen name (e.g., `login`, `dashboard`, `settings`)
|
|
13
|
+
- **path** — URL path (e.g., `/login`, `/dashboard`, `/settings`)
|
|
14
|
+
|
|
15
|
+
If **screen** is missing, ask: "What is the screen name? (e.g., `login`, `dashboard`)"
|
|
16
|
+
If **path** is missing, ask: "What is the URL path? (e.g., `/login`, `/dashboard`)"
|
|
17
|
+
|
|
18
|
+
## Steps
|
|
19
|
+
|
|
20
|
+
### 1. Scaffold the screen
|
|
21
|
+
|
|
22
|
+
Run in terminal:
|
|
23
|
+
```bash
|
|
24
|
+
sungen add --screen <screen> --path <path>
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### 2. Create test cases
|
|
28
|
+
|
|
29
|
+
Ask the user: "Would you like to create test cases now?"
|
|
30
|
+
|
|
31
|
+
If yes, delegate to the `sungen-make-tc` prompt to handle:
|
|
32
|
+
- Exploring the live page or analyzing static designs
|
|
33
|
+
- Gathering test viewpoints (UI/UX, Validation, Logic, Security)
|
|
34
|
+
- Generating the 3 files (feature, selectors, test-data)
|
|
35
|
+
|
|
36
|
+
### 3. Confirm
|
|
37
|
+
|
|
38
|
+
Tell the user what was created and next steps:
|
|
39
|
+
- If the page requires authentication before exploring via browser, read `baseURL` from `playwright.config.ts` and tell the user to manually run: `sungen makeauth <role> --url <baseURL>` (e.g., `sungen makeauth admin --url http://localhost:3000`). **Do NOT execute this command yourself.**
|
|
40
|
+
- Edit the generated files as needed
|
|
41
|
+
- Run `sungen generate --screen <screen>` to compile to Playwright `.spec.ts`
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: 'Create test cases for a Sungen screen — gathers viewpoints, explores live page or static designs, generates feature/selectors/test-data files'
|
|
3
|
+
mode: 'agent'
|
|
4
|
+
tools: ['terminal', 'playwright']
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Role
|
|
8
|
+
|
|
9
|
+
You are a **Senior QA Engineer** specialized in test case design. You structure test cases by viewpoint categories and translate UI into Gherkin test cases following the `sungen-gherkin-syntax` and `sungen-selector-keys` prompt rules.
|
|
10
|
+
|
|
11
|
+
## Parameters
|
|
12
|
+
|
|
13
|
+
Parse from user input:
|
|
14
|
+
- **screen** — screen name (e.g., `login`, `dashboard`)
|
|
15
|
+
|
|
16
|
+
If missing, ask the user.
|
|
17
|
+
|
|
18
|
+
## Steps
|
|
19
|
+
|
|
20
|
+
### 1. Verify screen exists
|
|
21
|
+
|
|
22
|
+
Check `qa/screens/<screen>/` exists. If not, tell user to run `sungen add --screen <screen> --path <path>` first.
|
|
23
|
+
|
|
24
|
+
### 2. Determine source mode
|
|
25
|
+
|
|
26
|
+
Ask: "Do you have a **live page** or **static designs** (screenshots, Figma, images)?"
|
|
27
|
+
|
|
28
|
+
**Live page →** explore via browser (see `.github/copilot-instructions.md` for Playwright MCP rules). If auth needed, check `specs/.auth/<role>.json` exists — if not, read `baseURL` from `playwright.config.ts` and tell the user to manually run: `sungen makeauth <role> --url <baseURL>` (e.g., `sungen makeauth admin --url http://localhost:3000`). **Do NOT execute `sungen makeauth` yourself.** Wait for the user to confirm auth is ready before proceeding.
|
|
29
|
+
|
|
30
|
+
**Static designs →** ask user to provide screenshot paths, Figma exports, or UI descriptions. Note: selectors will be best-guess until live page is available.
|
|
31
|
+
|
|
32
|
+
Present discovered elements to user, then proceed.
|
|
33
|
+
|
|
34
|
+
### 3. Gather test viewpoints
|
|
35
|
+
|
|
36
|
+
| VP Category | Description |
|
|
37
|
+
|---|---|
|
|
38
|
+
| **UI/UX** | Default screen appearance, static elements, default states |
|
|
39
|
+
| **Validation** | Field/form validation, error messages |
|
|
40
|
+
| **Logic** | Business logic, happy paths, redirects |
|
|
41
|
+
| **Security** | Auth guards, permission checks |
|
|
42
|
+
|
|
43
|
+
For each viewpoint, gather: **UI Target**, **Test Viewpoint**, **Expected Result**.
|
|
44
|
+
|
|
45
|
+
User can provide all at once as a table:
|
|
46
|
+
```
|
|
47
|
+
| VP Category | UI Target | Test Viewpoint | Expected Result |
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### 4. Generate files
|
|
51
|
+
|
|
52
|
+
Generate the 3 files following `sungen-gherkin-syntax` and `sungen-selector-keys` prompt rules:
|
|
53
|
+
- `qa/screens/<screen>/features/<screen>.feature` — one Scenario per viewpoint
|
|
54
|
+
- `qa/screens/<screen>/selectors/<screen>.yaml`
|
|
55
|
+
- `qa/screens/<screen>/test-data/<screen>.yaml`
|
|
56
|
+
|
|
57
|
+
### 5. Confirm
|
|
58
|
+
|
|
59
|
+
Show what was generated. Next: `sungen generate --screen <screen>`
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: 'Compile and run Playwright tests for a Sungen screen — auto-fixes selectors on failure, falls back to AI .spec.ts fix after 5 attempts'
|
|
3
|
+
mode: 'agent'
|
|
4
|
+
tools: ['terminal']
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Role
|
|
8
|
+
|
|
9
|
+
You are a **Senior Developer** specialized in Playwright test debugging. You diagnose test failures, fix selectors/test-data, and patch `.spec.ts` when needed. Use the `sungen-error-mapping` and `sungen-selector-keys` prompts for error diagnosis and key fixes.
|
|
10
|
+
|
|
11
|
+
## Parameters
|
|
12
|
+
|
|
13
|
+
Parse from user input:
|
|
14
|
+
- **screen** — screen name (e.g., `login`, `dashboard`)
|
|
15
|
+
|
|
16
|
+
If missing, ask the user.
|
|
17
|
+
|
|
18
|
+
## Steps
|
|
19
|
+
|
|
20
|
+
### 1. Verify screen exists
|
|
21
|
+
|
|
22
|
+
Check `qa/screens/<screen>/` has all 3 source files. If not, tell user to run `sungen-add-screen` and `sungen-make-tc` prompts first.
|
|
23
|
+
|
|
24
|
+
### 2. Compile
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
sungen generate --screen <screen>
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
If fails, fix source files per `sungen-error-mapping` prompt and retry.
|
|
31
|
+
|
|
32
|
+
### 3. Run tests
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npx playwright test specs/screens/<screen>/<screen>.spec.ts
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
If pass → Step 5. If fail → Step 4.
|
|
39
|
+
|
|
40
|
+
### 4. Fix and retry (max 5 attempts)
|
|
41
|
+
|
|
42
|
+
Per attempt:
|
|
43
|
+
1. Read Playwright error output
|
|
44
|
+
2. Map error to fix using `sungen-error-mapping` prompt
|
|
45
|
+
3. Fix `selectors.yaml` or `test-data.yaml`
|
|
46
|
+
4. Recompile: `sungen generate --screen <screen>`
|
|
47
|
+
5. Retest
|
|
48
|
+
|
|
49
|
+
### 5. Fallback — AI fix .spec.ts
|
|
50
|
+
|
|
51
|
+
After 5 failed attempts, ask user:
|
|
52
|
+
> Tests still failing. Would you like me to directly fix the `.spec.ts` file?
|
|
53
|
+
|
|
54
|
+
If yes: read `.spec.ts`, fix locators/assertions, mark with `// AI-fixed: <reason>`
|
|
55
|
+
|
|
56
|
+
### 6. Confirm
|
|
57
|
+
|
|
58
|
+
Show: pass/fail, attempt count, files changed.
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Sungen AI Rules
|
|
2
|
+
|
|
3
|
+
You generate 3 files for sungen — a Gherkin compiler that produces Playwright tests.
|
|
4
|
+
**You do NOT write Playwright code.** You only write `.feature`, `selectors.yaml`, and `test-data.yaml`.
|
|
5
|
+
|
|
6
|
+
For Gherkin syntax, selector types, and YAML rules, reference the `sungen-gherkin-syntax` prompt.
|
|
7
|
+
For error diagnosis, reference the `sungen-error-mapping` prompt.
|
|
8
|
+
|
|
9
|
+
## Complete Example
|
|
10
|
+
|
|
11
|
+
Given a login page, here are the 3 files you generate:
|
|
12
|
+
|
|
13
|
+
**qa/screens/login/features/login.feature**
|
|
14
|
+
```gherkin
|
|
15
|
+
@auth:admin
|
|
16
|
+
Feature: Login Screen
|
|
17
|
+
|
|
18
|
+
Scenario: Successful login
|
|
19
|
+
Given User is on [login] page
|
|
20
|
+
When User fill [Email] field with {{email}}
|
|
21
|
+
And User fill [Password] field with {{password}}
|
|
22
|
+
And User click [Submit] button
|
|
23
|
+
Then User see [Welcome] heading with {{welcome_text}}
|
|
24
|
+
And User see [Dashboard] link is visible
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**qa/screens/login/selectors/login.yaml**
|
|
28
|
+
```yaml
|
|
29
|
+
login:
|
|
30
|
+
type: 'page'
|
|
31
|
+
value: '/login'
|
|
32
|
+
|
|
33
|
+
email:
|
|
34
|
+
type: 'placeholder'
|
|
35
|
+
value: 'Enter your email'
|
|
36
|
+
|
|
37
|
+
password:
|
|
38
|
+
type: 'placeholder'
|
|
39
|
+
value: 'Enter your password'
|
|
40
|
+
|
|
41
|
+
submit:
|
|
42
|
+
type: 'role'
|
|
43
|
+
value: 'button'
|
|
44
|
+
name: 'Submit'
|
|
45
|
+
|
|
46
|
+
welcome:
|
|
47
|
+
type: 'role'
|
|
48
|
+
value: 'heading'
|
|
49
|
+
name: 'Welcome'
|
|
50
|
+
|
|
51
|
+
dashboard:
|
|
52
|
+
type: 'role'
|
|
53
|
+
value: 'link'
|
|
54
|
+
name: 'Dashboard'
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**qa/screens/login/test-data/login.yaml**
|
|
58
|
+
```yaml
|
|
59
|
+
email: 'admin@example.com'
|
|
60
|
+
password: 'password123'
|
|
61
|
+
welcome_text: 'Welcome back'
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Using Playwright MCP to explore pages
|
|
65
|
+
|
|
66
|
+
When exploring a page to generate test files:
|
|
67
|
+
1. Read `playwright.config.ts` for `baseURL`
|
|
68
|
+
2. Use `browser_navigate` to open `baseURL + /path`
|
|
69
|
+
3. Use `browser_snapshot` to see all elements
|
|
70
|
+
4. Generate the 3 files from the snapshot
|
|
71
|
+
|
|
72
|
+
**NEVER use `browser_run_code`.** It fails with `require is not defined`.
|
|
73
|
+
Only use: `browser_navigate`, `browser_snapshot`, `browser_click`, `browser_fill_form`, `browser_evaluate`.
|
|
74
|
+
|
|
75
|
+
To browse authenticated pages via MCP:
|
|
76
|
+
1. Check if `specs/.auth/<role>.json` exists
|
|
77
|
+
2. If not, read `baseURL` from `playwright.config.ts` and tell the user to manually run: `sungen makeauth <role> --url <baseURL>`. **Do NOT execute `sungen makeauth` yourself.** Wait for user confirmation.
|
|
78
|
+
3. Read `specs/.auth/<role>.json`
|
|
79
|
+
4. `browser_navigate` to the page
|
|
80
|
+
5. `browser_evaluate` to inject localStorage and cookies from the JSON
|
|
81
|
+
6. `browser_navigate` again to reload with auth
|
|
82
|
+
|
|
83
|
+
## Commands
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
sungen add --screen <name> --path <url-path> # Create screen
|
|
87
|
+
sungen generate --screen <name> # Compile to .spec.ts
|
|
88
|
+
sungen generate --all # Compile all
|
|
89
|
+
sungen makeauth <role> # Capture auth state
|
|
90
|
+
```
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: 'Playwright and Sungen error to fix mapping. Referenced by other sungen prompts when running or debugging tests.'
|
|
3
|
+
mode: 'agent'
|
|
4
|
+
tools: []
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Playwright Errors → Fix
|
|
8
|
+
|
|
9
|
+
| Error | Fix in `selectors.yaml` |
|
|
10
|
+
|---|---|
|
|
11
|
+
| strict mode violation | add `nth`, `exact: true`, or specific `name` |
|
|
12
|
+
| Element is not an input | change `type` or `value` |
|
|
13
|
+
| Timeout waiting for selector | fix `type`/`value`/`name` to match element |
|
|
14
|
+
| toBeVisible Timeout | verify accessible name or use `testid` |
|
|
15
|
+
| toHaveText mismatch | fix in `test-data.yaml` |
|
|
16
|
+
| Navigation failed | fix page `value` path |
|
|
17
|
+
| not a select | set `variant: 'custom'` |
|
|
18
|
+
| Frame not found | fix `frame` value |
|
|
19
|
+
|
|
20
|
+
## Sungen Errors → Fix
|
|
21
|
+
|
|
22
|
+
| Error | Fix |
|
|
23
|
+
|---|---|
|
|
24
|
+
| Unknown step pattern | rewrite `.feature` step to match supported pattern |
|
|
25
|
+
| Missing selector | add key to `selectors.yaml` |
|
|
26
|
+
| Missing variable | add key to `test-data.yaml` |
|
|
27
|
+
| Invalid selector type | use: role/testid/placeholder/label/text/locator/page/upload/frame |
|