@sun-asterisk/sungen 2.0.3 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +3 -2
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/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 +123 -0
- package/dist/orchestrator/templates/ai-instructions/claude-skill-selector-keys.md +94 -0
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-add-screen.md +41 -0
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-make-tc.md +59 -0
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-make-test.md +58 -0
- package/dist/orchestrator/templates/ai-instructions/copilot-config.md +90 -0
- package/dist/orchestrator/templates/ai-instructions/copilot-skill-error-mapping.md +27 -0
- package/dist/orchestrator/templates/ai-instructions/copilot-skill-gherkin-syntax.md +123 -0
- package/dist/orchestrator/templates/ai-instructions/copilot-skill-selector-keys.md +94 -0
- package/dist/orchestrator/templates/readme.md +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/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 +123 -0
- package/src/orchestrator/templates/ai-instructions/claude-skill-selector-keys.md +94 -0
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-add-screen.md +41 -0
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-make-tc.md +59 -0
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-make-test.md +58 -0
- package/src/orchestrator/templates/ai-instructions/copilot-config.md +90 -0
- package/src/orchestrator/templates/ai-instructions/copilot-skill-error-mapping.md +27 -0
- package/src/orchestrator/templates/ai-instructions/copilot-skill-gherkin-syntax.md +123 -0
- package/src/orchestrator/templates/ai-instructions/copilot-skill-selector-keys.md +94 -0
- package/src/orchestrator/templates/readme.md +42 -38
- package/dist/orchestrator/templates/ai-rules.md +0 -189
- package/src/orchestrator/templates/ai-rules.md +0 -189
|
@@ -19,8 +19,6 @@ sungen generate → compiles Gherkin + selectors + data → Playwright .spec.ts
|
|
|
19
19
|
├── specs/
|
|
20
20
|
│ ├── generated/ # Auto-generated Playwright tests
|
|
21
21
|
│ └── .auth/ # Auth storage states
|
|
22
|
-
├── docs/
|
|
23
|
-
│ └── gherkin-dictionary.md # Full grammar & compiler rules
|
|
24
22
|
├── .github/
|
|
25
23
|
│ └── copilot-instructions.md # AI rules for GitHub Copilot
|
|
26
24
|
└── CLAUDE.md # AI rules for Claude Code
|
|
@@ -28,55 +26,62 @@ sungen generate → compiles Gherkin + selectors + data → Playwright .spec.ts
|
|
|
28
26
|
|
|
29
27
|
## Workflow
|
|
30
28
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
29
|
+
```
|
|
30
|
+
Step 1 Step 2 Step 3
|
|
31
|
+
┌──────────┐ ┌──────────┐ ┌──────────┐
|
|
32
|
+
│ /add- │────────▶│ /make-tc │────────▶│ /make- │
|
|
33
|
+
│ screen │ │ │ │ test │
|
|
34
|
+
└──────────┘ └──────────┘ └──────────┘
|
|
35
|
+
Scaffold Design TCs Compile &
|
|
36
|
+
directories & generate run tests
|
|
37
|
+
3 files
|
|
37
38
|
```
|
|
38
39
|
|
|
39
|
-
|
|
40
|
+
Use AI commands (Claude Code or GitHub Copilot) to drive the workflow:
|
|
40
41
|
|
|
41
|
-
|
|
42
|
-
sungen makeauth admin
|
|
43
|
-
# Opens browser → login manually → saves specs/.auth/admin.json
|
|
44
|
-
```
|
|
42
|
+
### Step 1: Add a screen
|
|
45
43
|
|
|
46
|
-
|
|
44
|
+
| Claude Code | GitHub Copilot |
|
|
45
|
+
|---|---|
|
|
46
|
+
| `/sungen:add-screen login /login` | `@workspace /sungen-add-screen login /login` |
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
1. Navigate to the page URL via MCP Playwright
|
|
50
|
-
2. Take an accessibility snapshot
|
|
51
|
-
3. Generate `.feature` + `selectors.yaml` + `test-data.yaml`
|
|
48
|
+
Scaffolds `qa/screens/<name>/` with empty feature, selectors, and test-data files, then asks if you want to create test cases.
|
|
52
49
|
|
|
53
|
-
|
|
54
|
-
how to write correct Gherkin syntax and selector YAML for sungen.
|
|
50
|
+
### Step 2: Create test cases
|
|
55
51
|
|
|
56
|
-
|
|
52
|
+
| Claude Code | GitHub Copilot |
|
|
53
|
+
|---|---|
|
|
54
|
+
| `/sungen:make-tc login` | `@workspace /sungen-make-tc login` |
|
|
57
55
|
|
|
58
|
-
|
|
59
|
-
sungen generate --screen login
|
|
60
|
-
# or for all screens:
|
|
61
|
-
sungen generate --all
|
|
62
|
-
```
|
|
56
|
+
AI acts as a **Senior QA Engineer**: explores the live page (via Playwright MCP) or analyzes static designs, gathers test viewpoints (UI/UX, Validation, Logic, Security), and generates the 3 files.
|
|
63
57
|
|
|
64
|
-
###
|
|
58
|
+
### Step 3: Compile & run tests
|
|
59
|
+
|
|
60
|
+
| Claude Code | GitHub Copilot |
|
|
61
|
+
|---|---|
|
|
62
|
+
| `/sungen:make-test login` | `@workspace /sungen-make-test login` |
|
|
63
|
+
|
|
64
|
+
AI acts as a **Senior Developer**: compiles Gherkin → Playwright `.spec.ts`, runs tests, and auto-fixes selectors/test-data on failure (up to 5 attempts).
|
|
65
|
+
|
|
66
|
+
### Auth setup (if needed)
|
|
67
|
+
|
|
68
|
+
If any page requires authentication, run manually before Step 2:
|
|
65
69
|
|
|
66
70
|
```bash
|
|
67
|
-
|
|
68
|
-
|
|
71
|
+
sungen makeauth admin --url <baseURL>
|
|
72
|
+
# Opens browser → login manually → saves specs/.auth/admin.json
|
|
69
73
|
```
|
|
70
74
|
|
|
71
|
-
###
|
|
72
|
-
|
|
73
|
-
When tests fail, use AI to read the error → fix `selectors.yaml` → recompile → re-run.
|
|
75
|
+
### Manual CLI commands
|
|
74
76
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
77
|
+
```bash
|
|
78
|
+
sungen add --screen <name> --path <path> # Scaffold screen
|
|
79
|
+
sungen add --screen <name> --feature <name> # Add feature to screen
|
|
80
|
+
sungen generate --screen <name> # Compile to .spec.ts
|
|
81
|
+
sungen generate --all # Compile all screens
|
|
82
|
+
npx playwright test # Run all tests
|
|
83
|
+
npx playwright test --ui # Interactive mode
|
|
84
|
+
```
|
|
80
85
|
|
|
81
86
|
---
|
|
82
87
|
|
|
@@ -192,6 +197,5 @@ Locator priority: `data-testid` > `role+name` > `label` > `text` > `CSS`
|
|
|
192
197
|
|
|
193
198
|
## Documentation
|
|
194
199
|
|
|
195
|
-
- [Gherkin Dictionary](docs/gherkin-dictionary.md) — full grammar, all 17 patterns, compiler rules
|
|
196
200
|
- [Sungen GitHub](https://github.com/sun-asterisk/sungen)
|
|
197
201
|
- [Playwright Documentation](https://playwright.dev)
|
|
@@ -1,189 +0,0 @@
|
|
|
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
|
-
## Complete Example
|
|
7
|
-
|
|
8
|
-
Given a login page, here are the 3 files you generate:
|
|
9
|
-
|
|
10
|
-
**qa/screens/login/features/login.feature**
|
|
11
|
-
```gherkin
|
|
12
|
-
@auth:admin
|
|
13
|
-
Feature: Login Screen
|
|
14
|
-
|
|
15
|
-
Scenario: Successful login
|
|
16
|
-
Given User is on [login] page
|
|
17
|
-
When User fill [Email] field with {{email}}
|
|
18
|
-
And User fill [Password] field with {{password}}
|
|
19
|
-
And User click [Submit] button
|
|
20
|
-
Then User see [Welcome] heading with {{welcome_text}}
|
|
21
|
-
And User see [Dashboard] link is visible
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
**qa/screens/login/selectors/login.yaml**
|
|
25
|
-
```yaml
|
|
26
|
-
login:
|
|
27
|
-
type: 'page'
|
|
28
|
-
value: '/login'
|
|
29
|
-
|
|
30
|
-
email:
|
|
31
|
-
type: 'placeholder'
|
|
32
|
-
value: 'Enter your email'
|
|
33
|
-
|
|
34
|
-
password:
|
|
35
|
-
type: 'placeholder'
|
|
36
|
-
value: 'Enter your password'
|
|
37
|
-
|
|
38
|
-
submit:
|
|
39
|
-
type: 'role'
|
|
40
|
-
value: 'button'
|
|
41
|
-
name: 'Submit'
|
|
42
|
-
|
|
43
|
-
welcome:
|
|
44
|
-
type: 'role'
|
|
45
|
-
value: 'heading'
|
|
46
|
-
name: 'Welcome'
|
|
47
|
-
|
|
48
|
-
dashboard:
|
|
49
|
-
type: 'role'
|
|
50
|
-
value: 'link'
|
|
51
|
-
name: 'Dashboard'
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
**qa/screens/login/test-data/login.yaml**
|
|
55
|
-
```yaml
|
|
56
|
-
email: 'admin@example.com'
|
|
57
|
-
password: 'password123'
|
|
58
|
-
welcome_text: 'Welcome back'
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
## Key Rules
|
|
62
|
-
|
|
63
|
-
### YAML key format (CRITICAL)
|
|
64
|
-
|
|
65
|
-
YAML keys = Gherkin `[Reference]` converted to: **lowercase, spaces→dots, no special chars**.
|
|
66
|
-
|
|
67
|
-
| Gherkin | YAML Key |
|
|
68
|
-
|---|---|
|
|
69
|
-
| `[Submit]` | `submit:` |
|
|
70
|
-
| `[Search Content]` | `search.content:` |
|
|
71
|
-
| `[Kudos Detail Modal]` | `kudos.detail.modal:` |
|
|
72
|
-
| `[Page 2]` | `page.2:` |
|
|
73
|
-
|
|
74
|
-
**NEVER use spaces in YAML keys.**
|
|
75
|
-
|
|
76
|
-
### Gherkin patterns (all 17)
|
|
77
|
-
|
|
78
|
-
```
|
|
79
|
-
User click [Target] button # click
|
|
80
|
-
User fill [Target] field with {{value}} # fill
|
|
81
|
-
User check [Target] checkbox # check/uncheck
|
|
82
|
-
User select [Target] dropdown with {{value}} # select
|
|
83
|
-
User upload [Target] file with {{filename}} # upload
|
|
84
|
-
User double click [Target] element # double click
|
|
85
|
-
User hover [Target] icon # hover
|
|
86
|
-
User clear [Target] field # clear
|
|
87
|
-
User press Escape key # global key
|
|
88
|
-
User press Enter on [Target] field # key on element
|
|
89
|
-
User is on [target] page # navigate (Given)
|
|
90
|
-
User see [target] page # URL assertion (Then)
|
|
91
|
-
User wait for 3 seconds # wait timeout
|
|
92
|
-
User wait for [Target] dialog is hidden # wait state
|
|
93
|
-
User scroll to [Target] section # scroll
|
|
94
|
-
User switch to [Target] frame # iframe
|
|
95
|
-
User see [Target] heading with {{value}} # visible assertion
|
|
96
|
-
User see [Target] button is disabled # state assertion
|
|
97
|
-
User see [Target] text contains {{partial}} # text contains
|
|
98
|
-
User see [Table] table has row with {{filter}} # table row
|
|
99
|
-
User see [Table] table row with {{f}} has [Col] with {{v}} # table cell
|
|
100
|
-
User click [Edit] in [Table] table row with {{name}} # action in row
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
States: `hidden`, `visible`, `disabled`, `enabled`, `checked`, `unchecked`, `focused`, `empty`
|
|
104
|
-
|
|
105
|
-
### Selector types
|
|
106
|
-
|
|
107
|
-
| type | value | name | when to use |
|
|
108
|
-
|---|---|---|---|
|
|
109
|
-
| `role` | `button`, `heading`, `link`, etc. | accessible name | **preferred** for interactive elements |
|
|
110
|
-
| `testid` | `data-testid` value | — | when `data-testid` exists |
|
|
111
|
-
| `placeholder` | placeholder text | — | input fields |
|
|
112
|
-
| `label` | label text | — | labeled inputs |
|
|
113
|
-
| `text` | — | — | static text content |
|
|
114
|
-
| `locator` | CSS selector | — | **last resort** |
|
|
115
|
-
| `page` | relative URL path | — | navigation targets |
|
|
116
|
-
| `upload` | — | — | file upload inputs |
|
|
117
|
-
| `frame` | iframe selector | — | iframe targets |
|
|
118
|
-
|
|
119
|
-
Priority: `testid` > `role+name` > `placeholder` > `label` > `text` > `locator`
|
|
120
|
-
|
|
121
|
-
### Tags
|
|
122
|
-
|
|
123
|
-
| Tag | Effect |
|
|
124
|
-
|---|---|
|
|
125
|
-
| `@auth:role` | Adds `test.use({ storageState: 'specs/.auth/role.json' })` |
|
|
126
|
-
| `@steps:name` | Define reusable step group |
|
|
127
|
-
| `@extend:name` | Inherit steps from another scenario |
|
|
128
|
-
| `@manual` | Skip in generation |
|
|
129
|
-
|
|
130
|
-
### Selector options
|
|
131
|
-
|
|
132
|
-
```yaml
|
|
133
|
-
element.key:
|
|
134
|
-
type: 'role'
|
|
135
|
-
value: 'button'
|
|
136
|
-
name: 'Submit' # accessible name
|
|
137
|
-
nth: 0 # element index (0=first)
|
|
138
|
-
exact: true # exact name match (avoid substring collisions)
|
|
139
|
-
scope: 'navigation' # parent landmark scope
|
|
140
|
-
match: 'exact' # exact text match for getByText
|
|
141
|
-
variant: 'native' # dropdown: 'native' (<select>) or 'custom' (div-based)
|
|
142
|
-
frame: '#iframe-id' # iframe scope
|
|
143
|
-
contenteditable: true # rich text editor
|
|
144
|
-
columns: # table columns
|
|
145
|
-
name: { index: 0, header: 'Name' }
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
### Navigation and baseURL
|
|
149
|
-
|
|
150
|
-
Page selectors use **relative paths only**. Playwright prepends `baseURL` from `playwright.config.ts`.
|
|
151
|
-
|
|
152
|
-
```yaml
|
|
153
|
-
login:
|
|
154
|
-
type: 'page'
|
|
155
|
-
value: '/login' # NOT https://example.com/login
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
### Auth
|
|
159
|
-
|
|
160
|
-
- `@auth:admin` on Feature or Scenario → compiler adds `test.use({ storageState: 'specs/.auth/admin.json' })`
|
|
161
|
-
- Auth JSON created by: `sungen makeauth admin` (opens browser for manual login)
|
|
162
|
-
- **Login pages**: no `@auth` tag needed
|
|
163
|
-
- **Authenticated pages**: always add `@auth:role`
|
|
164
|
-
|
|
165
|
-
## Using Playwright MCP to explore pages
|
|
166
|
-
|
|
167
|
-
When exploring a page to generate test files:
|
|
168
|
-
1. Read `playwright.config.ts` for `baseURL`
|
|
169
|
-
2. Use `browser_navigate` to open `baseURL + /path`
|
|
170
|
-
3. Use `browser_snapshot` to see all elements
|
|
171
|
-
4. Generate the 3 files from the snapshot
|
|
172
|
-
|
|
173
|
-
**NEVER use `browser_run_code`.** It fails with `require is not defined`.
|
|
174
|
-
Only use: `browser_navigate`, `browser_snapshot`, `browser_click`, `browser_fill_form`, `browser_evaluate`.
|
|
175
|
-
|
|
176
|
-
To browse authenticated pages via MCP:
|
|
177
|
-
1. Read `specs/.auth/role.json` with your file read tool
|
|
178
|
-
2. `browser_navigate` to the page
|
|
179
|
-
3. `browser_evaluate` to inject localStorage and cookies from the JSON
|
|
180
|
-
4. `browser_navigate` again to reload with auth
|
|
181
|
-
|
|
182
|
-
## Commands
|
|
183
|
-
|
|
184
|
-
```bash
|
|
185
|
-
sungen add --screen <name> --path <url-path> # Create screen
|
|
186
|
-
sungen generate --screen <name> # Compile to .spec.ts
|
|
187
|
-
sungen generate --all # Compile all
|
|
188
|
-
sungen makeauth <role> # Capture auth state
|
|
189
|
-
```
|
|
@@ -1,189 +0,0 @@
|
|
|
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
|
-
## Complete Example
|
|
7
|
-
|
|
8
|
-
Given a login page, here are the 3 files you generate:
|
|
9
|
-
|
|
10
|
-
**qa/screens/login/features/login.feature**
|
|
11
|
-
```gherkin
|
|
12
|
-
@auth:admin
|
|
13
|
-
Feature: Login Screen
|
|
14
|
-
|
|
15
|
-
Scenario: Successful login
|
|
16
|
-
Given User is on [login] page
|
|
17
|
-
When User fill [Email] field with {{email}}
|
|
18
|
-
And User fill [Password] field with {{password}}
|
|
19
|
-
And User click [Submit] button
|
|
20
|
-
Then User see [Welcome] heading with {{welcome_text}}
|
|
21
|
-
And User see [Dashboard] link is visible
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
**qa/screens/login/selectors/login.yaml**
|
|
25
|
-
```yaml
|
|
26
|
-
login:
|
|
27
|
-
type: 'page'
|
|
28
|
-
value: '/login'
|
|
29
|
-
|
|
30
|
-
email:
|
|
31
|
-
type: 'placeholder'
|
|
32
|
-
value: 'Enter your email'
|
|
33
|
-
|
|
34
|
-
password:
|
|
35
|
-
type: 'placeholder'
|
|
36
|
-
value: 'Enter your password'
|
|
37
|
-
|
|
38
|
-
submit:
|
|
39
|
-
type: 'role'
|
|
40
|
-
value: 'button'
|
|
41
|
-
name: 'Submit'
|
|
42
|
-
|
|
43
|
-
welcome:
|
|
44
|
-
type: 'role'
|
|
45
|
-
value: 'heading'
|
|
46
|
-
name: 'Welcome'
|
|
47
|
-
|
|
48
|
-
dashboard:
|
|
49
|
-
type: 'role'
|
|
50
|
-
value: 'link'
|
|
51
|
-
name: 'Dashboard'
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
**qa/screens/login/test-data/login.yaml**
|
|
55
|
-
```yaml
|
|
56
|
-
email: 'admin@example.com'
|
|
57
|
-
password: 'password123'
|
|
58
|
-
welcome_text: 'Welcome back'
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
## Key Rules
|
|
62
|
-
|
|
63
|
-
### YAML key format (CRITICAL)
|
|
64
|
-
|
|
65
|
-
YAML keys = Gherkin `[Reference]` converted to: **lowercase, spaces→dots, no special chars**.
|
|
66
|
-
|
|
67
|
-
| Gherkin | YAML Key |
|
|
68
|
-
|---|---|
|
|
69
|
-
| `[Submit]` | `submit:` |
|
|
70
|
-
| `[Search Content]` | `search.content:` |
|
|
71
|
-
| `[Kudos Detail Modal]` | `kudos.detail.modal:` |
|
|
72
|
-
| `[Page 2]` | `page.2:` |
|
|
73
|
-
|
|
74
|
-
**NEVER use spaces in YAML keys.**
|
|
75
|
-
|
|
76
|
-
### Gherkin patterns (all 17)
|
|
77
|
-
|
|
78
|
-
```
|
|
79
|
-
User click [Target] button # click
|
|
80
|
-
User fill [Target] field with {{value}} # fill
|
|
81
|
-
User check [Target] checkbox # check/uncheck
|
|
82
|
-
User select [Target] dropdown with {{value}} # select
|
|
83
|
-
User upload [Target] file with {{filename}} # upload
|
|
84
|
-
User double click [Target] element # double click
|
|
85
|
-
User hover [Target] icon # hover
|
|
86
|
-
User clear [Target] field # clear
|
|
87
|
-
User press Escape key # global key
|
|
88
|
-
User press Enter on [Target] field # key on element
|
|
89
|
-
User is on [target] page # navigate (Given)
|
|
90
|
-
User see [target] page # URL assertion (Then)
|
|
91
|
-
User wait for 3 seconds # wait timeout
|
|
92
|
-
User wait for [Target] dialog is hidden # wait state
|
|
93
|
-
User scroll to [Target] section # scroll
|
|
94
|
-
User switch to [Target] frame # iframe
|
|
95
|
-
User see [Target] heading with {{value}} # visible assertion
|
|
96
|
-
User see [Target] button is disabled # state assertion
|
|
97
|
-
User see [Target] text contains {{partial}} # text contains
|
|
98
|
-
User see [Table] table has row with {{filter}} # table row
|
|
99
|
-
User see [Table] table row with {{f}} has [Col] with {{v}} # table cell
|
|
100
|
-
User click [Edit] in [Table] table row with {{name}} # action in row
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
States: `hidden`, `visible`, `disabled`, `enabled`, `checked`, `unchecked`, `focused`, `empty`
|
|
104
|
-
|
|
105
|
-
### Selector types
|
|
106
|
-
|
|
107
|
-
| type | value | name | when to use |
|
|
108
|
-
|---|---|---|---|
|
|
109
|
-
| `role` | `button`, `heading`, `link`, etc. | accessible name | **preferred** for interactive elements |
|
|
110
|
-
| `testid` | `data-testid` value | — | when `data-testid` exists |
|
|
111
|
-
| `placeholder` | placeholder text | — | input fields |
|
|
112
|
-
| `label` | label text | — | labeled inputs |
|
|
113
|
-
| `text` | — | — | static text content |
|
|
114
|
-
| `locator` | CSS selector | — | **last resort** |
|
|
115
|
-
| `page` | relative URL path | — | navigation targets |
|
|
116
|
-
| `upload` | — | — | file upload inputs |
|
|
117
|
-
| `frame` | iframe selector | — | iframe targets |
|
|
118
|
-
|
|
119
|
-
Priority: `testid` > `role+name` > `placeholder` > `label` > `text` > `locator`
|
|
120
|
-
|
|
121
|
-
### Tags
|
|
122
|
-
|
|
123
|
-
| Tag | Effect |
|
|
124
|
-
|---|---|
|
|
125
|
-
| `@auth:role` | Adds `test.use({ storageState: 'specs/.auth/role.json' })` |
|
|
126
|
-
| `@steps:name` | Define reusable step group |
|
|
127
|
-
| `@extend:name` | Inherit steps from another scenario |
|
|
128
|
-
| `@manual` | Skip in generation |
|
|
129
|
-
|
|
130
|
-
### Selector options
|
|
131
|
-
|
|
132
|
-
```yaml
|
|
133
|
-
element.key:
|
|
134
|
-
type: 'role'
|
|
135
|
-
value: 'button'
|
|
136
|
-
name: 'Submit' # accessible name
|
|
137
|
-
nth: 0 # element index (0=first)
|
|
138
|
-
exact: true # exact name match (avoid substring collisions)
|
|
139
|
-
scope: 'navigation' # parent landmark scope
|
|
140
|
-
match: 'exact' # exact text match for getByText
|
|
141
|
-
variant: 'native' # dropdown: 'native' (<select>) or 'custom' (div-based)
|
|
142
|
-
frame: '#iframe-id' # iframe scope
|
|
143
|
-
contenteditable: true # rich text editor
|
|
144
|
-
columns: # table columns
|
|
145
|
-
name: { index: 0, header: 'Name' }
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
### Navigation and baseURL
|
|
149
|
-
|
|
150
|
-
Page selectors use **relative paths only**. Playwright prepends `baseURL` from `playwright.config.ts`.
|
|
151
|
-
|
|
152
|
-
```yaml
|
|
153
|
-
login:
|
|
154
|
-
type: 'page'
|
|
155
|
-
value: '/login' # NOT https://example.com/login
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
### Auth
|
|
159
|
-
|
|
160
|
-
- `@auth:admin` on Feature or Scenario → compiler adds `test.use({ storageState: 'specs/.auth/admin.json' })`
|
|
161
|
-
- Auth JSON created by: `sungen makeauth admin` (opens browser for manual login)
|
|
162
|
-
- **Login pages**: no `@auth` tag needed
|
|
163
|
-
- **Authenticated pages**: always add `@auth:role`
|
|
164
|
-
|
|
165
|
-
## Using Playwright MCP to explore pages
|
|
166
|
-
|
|
167
|
-
When exploring a page to generate test files:
|
|
168
|
-
1. Read `playwright.config.ts` for `baseURL`
|
|
169
|
-
2. Use `browser_navigate` to open `baseURL + /path`
|
|
170
|
-
3. Use `browser_snapshot` to see all elements
|
|
171
|
-
4. Generate the 3 files from the snapshot
|
|
172
|
-
|
|
173
|
-
**NEVER use `browser_run_code`.** It fails with `require is not defined`.
|
|
174
|
-
Only use: `browser_navigate`, `browser_snapshot`, `browser_click`, `browser_fill_form`, `browser_evaluate`.
|
|
175
|
-
|
|
176
|
-
To browse authenticated pages via MCP:
|
|
177
|
-
1. Read `specs/.auth/role.json` with your file read tool
|
|
178
|
-
2. `browser_navigate` to the page
|
|
179
|
-
3. `browser_evaluate` to inject localStorage and cookies from the JSON
|
|
180
|
-
4. `browser_navigate` again to reload with auth
|
|
181
|
-
|
|
182
|
-
## Commands
|
|
183
|
-
|
|
184
|
-
```bash
|
|
185
|
-
sungen add --screen <name> --path <url-path> # Create screen
|
|
186
|
-
sungen generate --screen <name> # Compile to .spec.ts
|
|
187
|
-
sungen generate --all # Compile all
|
|
188
|
-
sungen makeauth <role> # Capture auth state
|
|
189
|
-
```
|