@sun-asterisk/sungen 2.4.3 → 2.4.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/commands/add.d.ts.map +1 -1
- package/dist/cli/commands/add.js +8 -2
- package/dist/cli/commands/add.js.map +1 -1
- package/dist/cli/commands/delivery.d.ts +7 -0
- package/dist/cli/commands/delivery.d.ts.map +1 -0
- package/dist/cli/commands/delivery.js +348 -0
- package/dist/cli/commands/delivery.js.map +1 -0
- package/dist/cli/commands/update.d.ts.map +1 -1
- package/dist/cli/commands/update.js +64 -1
- package/dist/cli/commands/update.js.map +1 -1
- package/dist/cli/index.js +4 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/exporters/csv-exporter.d.ts +32 -0
- package/dist/exporters/csv-exporter.d.ts.map +1 -0
- package/dist/exporters/csv-exporter.js +311 -0
- package/dist/exporters/csv-exporter.js.map +1 -0
- package/dist/exporters/feature-parser.d.ts +48 -0
- package/dist/exporters/feature-parser.d.ts.map +1 -0
- package/dist/exporters/feature-parser.js +178 -0
- package/dist/exporters/feature-parser.js.map +1 -0
- package/dist/exporters/package-info.d.ts +9 -0
- package/dist/exporters/package-info.d.ts.map +1 -0
- package/dist/exporters/package-info.js +73 -0
- package/dist/exporters/package-info.js.map +1 -0
- package/dist/exporters/playwright-report-parser.d.ts +21 -0
- package/dist/exporters/playwright-report-parser.d.ts.map +1 -0
- package/dist/exporters/playwright-report-parser.js +184 -0
- package/dist/exporters/playwright-report-parser.js.map +1 -0
- package/dist/exporters/scenario-merger.d.ts +21 -0
- package/dist/exporters/scenario-merger.d.ts.map +1 -0
- package/dist/exporters/scenario-merger.js +51 -0
- package/dist/exporters/scenario-merger.js.map +1 -0
- package/dist/exporters/spec-parser.d.ts +20 -0
- package/dist/exporters/spec-parser.d.ts.map +1 -0
- package/dist/exporters/spec-parser.js +259 -0
- package/dist/exporters/spec-parser.js.map +1 -0
- package/dist/exporters/step-formatter.d.ts +32 -0
- package/dist/exporters/step-formatter.d.ts.map +1 -0
- package/dist/exporters/step-formatter.js +76 -0
- package/dist/exporters/step-formatter.js.map +1 -0
- package/dist/exporters/test-data-resolver.d.ts +20 -0
- package/dist/exporters/test-data-resolver.d.ts.map +1 -0
- package/dist/exporters/test-data-resolver.js +96 -0
- package/dist/exporters/test-data-resolver.js.map +1 -0
- package/dist/exporters/types.d.ts +104 -0
- package/dist/exporters/types.d.ts.map +1 -0
- package/dist/exporters/types.js +6 -0
- package/dist/exporters/types.js.map +1 -0
- package/dist/exporters/xlsx-exporter.d.ts +19 -0
- package/dist/exporters/xlsx-exporter.d.ts.map +1 -0
- package/dist/exporters/xlsx-exporter.js +309 -0
- package/dist/exporters/xlsx-exporter.js.map +1 -0
- package/dist/generators/test-generator/utils/selector-resolver.d.ts.map +1 -1
- package/dist/generators/test-generator/utils/selector-resolver.js +26 -0
- package/dist/generators/test-generator/utils/selector-resolver.js.map +1 -1
- package/dist/orchestrator/ai-rules-updater.d.ts.map +1 -1
- package/dist/orchestrator/ai-rules-updater.js +12 -0
- package/dist/orchestrator/ai-rules-updater.js.map +1 -1
- package/dist/orchestrator/project-initializer.d.ts +12 -1
- package/dist/orchestrator/project-initializer.d.ts.map +1 -1
- package/dist/orchestrator/project-initializer.js +84 -64
- package/dist/orchestrator/project-initializer.js.map +1 -1
- package/dist/orchestrator/screen-manager.d.ts +1 -0
- package/dist/orchestrator/screen-manager.d.ts.map +1 -1
- package/dist/orchestrator/screen-manager.js +4 -2
- package/dist/orchestrator/screen-manager.js.map +1 -1
- package/dist/orchestrator/templates/ai-instructions/claude-cmd-add-screen.md +18 -9
- package/dist/orchestrator/templates/ai-instructions/claude-cmd-create-test.md +7 -5
- package/dist/orchestrator/templates/ai-instructions/claude-cmd-delivery.md +71 -0
- package/dist/orchestrator/templates/ai-instructions/claude-cmd-run-test.md +38 -10
- package/dist/orchestrator/templates/ai-instructions/claude-config.md +12 -2
- package/dist/orchestrator/templates/ai-instructions/claude-skill-capture-figma.md +142 -0
- package/dist/orchestrator/templates/ai-instructions/claude-skill-capture-live.md +100 -0
- package/dist/orchestrator/templates/ai-instructions/claude-skill-capture-local.md +73 -0
- package/dist/orchestrator/templates/ai-instructions/claude-skill-delivery.md +103 -0
- package/dist/orchestrator/templates/ai-instructions/claude-skill-gherkin-syntax.md +2 -0
- package/dist/orchestrator/templates/ai-instructions/claude-skill-selector-fix.md +87 -4
- package/dist/orchestrator/templates/ai-instructions/claude-skill-selector-keys.md +22 -0
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-add-screen.md +18 -9
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-create-test.md +6 -4
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-delivery.md +71 -0
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-run-test.md +45 -20
- package/dist/orchestrator/templates/ai-instructions/copilot-config.md +12 -2
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-capture-figma.md +142 -0
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-capture-live.md +100 -0
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-capture-local.md +73 -0
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-delivery.md +103 -0
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-gherkin-syntax.md +2 -0
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-selector-fix.md +87 -4
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-selector-keys.md +22 -0
- package/dist/orchestrator/templates/playwright.config.d.ts.map +1 -1
- package/dist/orchestrator/templates/playwright.config.js +6 -1
- package/dist/orchestrator/templates/playwright.config.js.map +1 -1
- package/dist/orchestrator/templates/playwright.config.ts +6 -1
- package/package.json +2 -1
- package/src/cli/commands/add.ts +9 -2
- package/src/cli/commands/delivery.ts +348 -0
- package/src/cli/commands/update.ts +84 -2
- package/src/cli/index.ts +4 -2
- package/src/exporters/csv-exporter.ts +304 -0
- package/src/exporters/feature-parser.ts +168 -0
- package/src/exporters/package-info.ts +35 -0
- package/src/exporters/playwright-report-parser.ts +168 -0
- package/src/exporters/scenario-merger.ts +63 -0
- package/src/exporters/spec-parser.ts +247 -0
- package/src/exporters/step-formatter.ts +80 -0
- package/src/exporters/test-data-resolver.ts +59 -0
- package/src/exporters/types.ts +112 -0
- package/src/exporters/xlsx-exporter.ts +301 -0
- package/src/generators/test-generator/utils/selector-resolver.ts +26 -0
- package/src/orchestrator/ai-rules-updater.ts +12 -0
- package/src/orchestrator/project-initializer.ts +103 -70
- package/src/orchestrator/screen-manager.ts +5 -2
- package/src/orchestrator/templates/ai-instructions/claude-cmd-add-screen.md +18 -9
- package/src/orchestrator/templates/ai-instructions/claude-cmd-create-test.md +7 -5
- package/src/orchestrator/templates/ai-instructions/claude-cmd-delivery.md +71 -0
- package/src/orchestrator/templates/ai-instructions/claude-cmd-run-test.md +38 -10
- package/src/orchestrator/templates/ai-instructions/claude-config.md +12 -2
- package/src/orchestrator/templates/ai-instructions/claude-skill-capture-figma.md +142 -0
- package/src/orchestrator/templates/ai-instructions/claude-skill-capture-live.md +100 -0
- package/src/orchestrator/templates/ai-instructions/claude-skill-capture-local.md +73 -0
- package/src/orchestrator/templates/ai-instructions/claude-skill-delivery.md +103 -0
- package/src/orchestrator/templates/ai-instructions/claude-skill-gherkin-syntax.md +2 -0
- package/src/orchestrator/templates/ai-instructions/claude-skill-selector-fix.md +87 -4
- package/src/orchestrator/templates/ai-instructions/claude-skill-selector-keys.md +22 -0
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-add-screen.md +18 -9
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-create-test.md +6 -4
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-delivery.md +71 -0
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-run-test.md +45 -20
- package/src/orchestrator/templates/ai-instructions/copilot-config.md +12 -2
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-capture-figma.md +142 -0
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-capture-live.md +100 -0
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-capture-local.md +73 -0
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-delivery.md +103 -0
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-gherkin-syntax.md +2 -0
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-selector-fix.md +87 -4
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-selector-keys.md +22 -0
- package/src/orchestrator/templates/playwright.config.ts +6 -1
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sungen-capture-figma
|
|
3
|
+
description: 'Fetch design context + PNG from a Figma frame URL via Figma Dev Mode MCP. Auto-loaded by create-test when user picks Figma as the visual source.'
|
|
4
|
+
user-invocable: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Purpose
|
|
8
|
+
|
|
9
|
+
Pull **structured design data** (layout, typography, colors, component tree, design tokens) and a **PNG screenshot** from a Figma frame URL, so `sungen-tc-generation` can author Gherkin + test-data before a live domain exists.
|
|
10
|
+
|
|
11
|
+
Use this when the project is pre-launch, or when Figma is the source of truth and the live build lags the design.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Prerequisites
|
|
16
|
+
|
|
17
|
+
- **Figma MCP server** (`https://mcp.figma.com/mcp`, HTTP transport) connected in `.vscode/mcp.json` — `sungen init` scaffolds this automatically. On first use, VS Code / Copilot opens a browser for Figma OAuth. Official tools: `get_design_context`, `get_variable_defs`, `get_screenshot`.
|
|
18
|
+
- Figma account signed in with access to the file. **Dev/Full seats** get per-minute rate limits; **Starter/View seats** get monthly tool-call limits.
|
|
19
|
+
- A Figma URL with both **fileKey** and **nodeId** in it.
|
|
20
|
+
|
|
21
|
+
If the MCP is not connected, **do not fail silently** — tell the user:
|
|
22
|
+
> "Figma MCP not detected. Run `sungen init` to scaffold the config, or manually add `figma` with `url: https://mcp.figma.com/mcp` to `.vscode/mcp.json`. Then sign in when VS Code prompts."
|
|
23
|
+
|
|
24
|
+
Then stop.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Steps
|
|
29
|
+
|
|
30
|
+
### 1. Resolve Figma URL
|
|
31
|
+
|
|
32
|
+
Prefer in this order:
|
|
33
|
+
|
|
34
|
+
1. `Figma URL` field in `qa/screens/<screen>/requirements/spec.md` (Overview section)
|
|
35
|
+
2. If empty or missing → ask the user: *"Paste the Figma frame URL"*
|
|
36
|
+
|
|
37
|
+
Accept any of these URL shapes:
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
https://www.figma.com/file/<fileKey>/<title>?node-id=<nodeId>
|
|
41
|
+
https://www.figma.com/design/<fileKey>/<title>?node-id=<nodeId>
|
|
42
|
+
https://www.figma.com/proto/<fileKey>/<title>?node-id=<nodeId>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Parse:
|
|
46
|
+
- `fileKey` = the segment after `/file/`, `/design/`, or `/proto/`
|
|
47
|
+
- `nodeId` = the `node-id` query param (may use `-` or `:` — pass through as-is; MCP accepts both)
|
|
48
|
+
|
|
49
|
+
If `node-id` is missing, ask the user to select a frame in Figma and copy the **frame URL** specifically (not the file root URL).
|
|
50
|
+
|
|
51
|
+
### 2. Fetch design context
|
|
52
|
+
|
|
53
|
+
Call **both** in parallel:
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
get_design_context({ fileKey, nodeId })
|
|
57
|
+
get_variable_defs({ fileKey, nodeId })
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
`get_design_context` returns layout, typography, color values, component structure, spacing.
|
|
61
|
+
`get_variable_defs` returns named design tokens (color/spacing/typography variables).
|
|
62
|
+
|
|
63
|
+
### 3. Fetch screenshot
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
get_screenshot({ fileKey, nodeId })
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Save the returned PNG to:
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
qa/screens/<screen>/requirements/ui/figma-<sanitized-nodeId>.png
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Sanitize `nodeId` for filesystem: replace `:` and `-` with `_`. Example: `42-15` → `figma-42_15.png`.
|
|
76
|
+
|
|
77
|
+
### 4. Write metadata dump
|
|
78
|
+
|
|
79
|
+
Combine the design context + variables into a Markdown summary at:
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
qa/screens/<screen>/requirements/ui/figma-meta.md
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Format:
|
|
86
|
+
|
|
87
|
+
```markdown
|
|
88
|
+
# Figma Capture — <nodeId>
|
|
89
|
+
|
|
90
|
+
**Source:** <full Figma URL>
|
|
91
|
+
**Captured:** <ISO date>
|
|
92
|
+
|
|
93
|
+
## Components
|
|
94
|
+
<hierarchical list of component names + variants from get_design_context>
|
|
95
|
+
|
|
96
|
+
## Typography
|
|
97
|
+
<font families, sizes, weights, line heights>
|
|
98
|
+
|
|
99
|
+
## Colors
|
|
100
|
+
<color tokens + raw hex values>
|
|
101
|
+
|
|
102
|
+
## Spacing & Layout
|
|
103
|
+
<spacing tokens, auto-layout specs>
|
|
104
|
+
|
|
105
|
+
## Text Content
|
|
106
|
+
<visible text strings from the frame — used by tc-generation to populate test-data>
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
This file is consumed by `sungen-tc-generation` as a secondary source alongside `spec.md`.
|
|
110
|
+
|
|
111
|
+
### 5. Report back
|
|
112
|
+
|
|
113
|
+
Output a short summary to the user:
|
|
114
|
+
|
|
115
|
+
> Captured Figma frame `<nodeId>`:
|
|
116
|
+
> - Components: N
|
|
117
|
+
> - Text strings: M
|
|
118
|
+
> - Design tokens: K
|
|
119
|
+
> - Screenshot: `qa/screens/<screen>/requirements/ui/figma-<nodeId>.png`
|
|
120
|
+
> - Metadata: `requirements/ui/figma-meta.md`
|
|
121
|
+
|
|
122
|
+
Then hand back to the calling command.
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## Error handling
|
|
127
|
+
|
|
128
|
+
| Error | Action |
|
|
129
|
+
|---|---|
|
|
130
|
+
| MCP tool not available | Print setup instructions, stop, do not fall back silently |
|
|
131
|
+
| `fileKey` missing from URL | Ask user to paste a valid frame URL |
|
|
132
|
+
| `nodeId` missing from URL | Ask user to right-click a frame in Figma → *Copy link to selection* |
|
|
133
|
+
| `get_design_context` 403 | Ask user to check Dev Mode seat on that file |
|
|
134
|
+
| `get_screenshot` returns no image | Continue with metadata only; warn user no PNG was captured |
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## What this skill does NOT do
|
|
139
|
+
|
|
140
|
+
- Does not generate Gherkin (that's `sungen-tc-generation`)
|
|
141
|
+
- Does not write `selectors.yaml` (that's `/sungen-run-test`)
|
|
142
|
+
- Does not validate the design against live UI (future skill: `sungen-capture-live` can be run afterwards for cross-check)
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sungen-capture-live
|
|
3
|
+
description: 'Capture a live running page via Playwright MCP — snapshot + screenshot for visual context. Auto-loaded by create-test when user picks Live page scan.'
|
|
4
|
+
user-invocable: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Purpose
|
|
8
|
+
|
|
9
|
+
Navigate a running application, take **one accessibility snapshot** and **one screenshot**, and save them as visual context for test generation. Use when the app is live (dev, staging, or production with read-only access) and you want the tests grounded in the actual rendered UI.
|
|
10
|
+
|
|
11
|
+
This skill handles auth gracefully: if the page redirects to login, it asks the user to sign in manually rather than injecting cookies.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Prerequisites
|
|
16
|
+
|
|
17
|
+
- Playwright MCP connected.
|
|
18
|
+
- Dev/staging server reachable (or a public URL).
|
|
19
|
+
- `playwright.config.ts` exists at the project root (for `baseURL` fallback).
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Steps
|
|
24
|
+
|
|
25
|
+
### 1. Resolve target URL
|
|
26
|
+
|
|
27
|
+
Resolve in this order:
|
|
28
|
+
|
|
29
|
+
1. `Live URL` field in `qa/screens/<screen>/requirements/spec.md` (Overview section)
|
|
30
|
+
2. `baseURL` from `playwright.config.ts` + `URL Path` from `spec.md`
|
|
31
|
+
3. If neither works → ask the user: *"Paste the full URL for the page to scan"*
|
|
32
|
+
|
|
33
|
+
### 2. Navigate
|
|
34
|
+
|
|
35
|
+
`browser_navigate` to the resolved URL.
|
|
36
|
+
|
|
37
|
+
### 3. Handle auth redirect
|
|
38
|
+
|
|
39
|
+
If the page redirects to a login route (URL contains `/login`, `/signin`, `/auth`, or the page title/content indicates a login screen):
|
|
40
|
+
|
|
41
|
+
1. Tell the user which login URL they landed on.
|
|
42
|
+
2. Ask the user:
|
|
43
|
+
- **1) I'll log in manually** — wait for user confirmation, then re-navigate to the target URL
|
|
44
|
+
- **2) Skip live scan** — tell caller to invoke `sungen-capture-local` instead
|
|
45
|
+
- **3) Cancel**
|
|
46
|
+
3. **Never** inject cookies or localStorage via `browser_evaluate` or `browser_run_code`. Auth belongs to the user.
|
|
47
|
+
|
|
48
|
+
### 4. Snapshot
|
|
49
|
+
|
|
50
|
+
Take **ONE** `browser_snapshot`. This accessibility tree is the primary AI context — it contains roles, names, text, and structure that the tc-generation skill uses to identify sections and fields.
|
|
51
|
+
|
|
52
|
+
### 5. Screenshot (optional but recommended)
|
|
53
|
+
|
|
54
|
+
Take **ONE** `browser_take_screenshot` with `fullPage: true`. Save to:
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
qa/screens/<screen>/requirements/ui/live-<timestamp>.png
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Where `<timestamp>` is `YYYYMMDD-HHMM` in local time (e.g. `live-20260421-1430.png`).
|
|
61
|
+
|
|
62
|
+
This gives users a visual record they can reference later without re-scanning.
|
|
63
|
+
|
|
64
|
+
### 6. Detect discrepancies vs spec
|
|
65
|
+
|
|
66
|
+
If `spec.md` exists, briefly cross-check the snapshot against spec sections:
|
|
67
|
+
|
|
68
|
+
- Fields listed in spec but not in snapshot → flag as *missing in UI*
|
|
69
|
+
- Elements visible in snapshot but not in spec → flag as *missing in spec*
|
|
70
|
+
|
|
71
|
+
Report findings but **do not** auto-edit `spec.md` — let the user decide.
|
|
72
|
+
|
|
73
|
+
### 7. Report back
|
|
74
|
+
|
|
75
|
+
> Captured live page `<URL>`:
|
|
76
|
+
> - Snapshot: <N> interactive elements detected
|
|
77
|
+
> - Screenshot: `requirements/ui/live-<timestamp>.png`
|
|
78
|
+
> - Discrepancies vs spec: <count, or "none">
|
|
79
|
+
|
|
80
|
+
Hand back to the calling command.
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## What this skill does NOT do
|
|
85
|
+
|
|
86
|
+
- Does not run tests
|
|
87
|
+
- Does not generate `selectors.yaml` (that's `/sungen-run-test`)
|
|
88
|
+
- Does not inject auth state (user logs in manually)
|
|
89
|
+
- Does not crawl — scans **exactly one** page per invocation
|
|
90
|
+
- Does not generate Gherkin — that's `sungen-tc-generation`
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Relationship to other capture skills
|
|
95
|
+
|
|
96
|
+
- `sungen-capture-figma` — design source of truth (pre-launch)
|
|
97
|
+
- `sungen-capture-local` — any image the user dropped in `requirements/ui/`
|
|
98
|
+
- `sungen-capture-live` — this skill, verifies/supplements against the running app
|
|
99
|
+
|
|
100
|
+
All three write to `requirements/ui/` and report back to the caller. They are mutually exclusive per create-test run, but a user can run create-test multiple times with different sources to layer context.
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sungen-capture-local
|
|
3
|
+
description: 'Load existing UI assets (screenshots, Figma exports, hand-drawn mockups) from requirements/ui/. Auto-loaded by create-test when user picks UI images as the visual source.'
|
|
4
|
+
user-invocable: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Purpose
|
|
8
|
+
|
|
9
|
+
Use **pre-existing images** in `qa/screens/<screen>/requirements/ui/` as visual context for test generation. No network, no MCP, no live site required — works for any design tool (Figma export, Sketch, Penpot, Zeplin, hand-drawn, screenshots of a staging env).
|
|
10
|
+
|
|
11
|
+
This is the **baseline fallback**: if live domain is down and Figma MCP isn't configured, this always works as long as the user drops images in the folder.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Steps
|
|
16
|
+
|
|
17
|
+
### 1. List available images
|
|
18
|
+
|
|
19
|
+
Glob `qa/screens/<screen>/requirements/ui/*.{png,jpg,jpeg,webp,gif}` and report count + filenames.
|
|
20
|
+
|
|
21
|
+
Filter out metadata files (e.g. `figma-meta.md` written by `sungen-capture-figma`) — those are read by `tc-generation` separately, not treated as images here.
|
|
22
|
+
|
|
23
|
+
### 2. Handle empty folder
|
|
24
|
+
|
|
25
|
+
If no images found:
|
|
26
|
+
|
|
27
|
+
1. Tell the user the folder is empty, with the full path so they can navigate there in their file manager.
|
|
28
|
+
2. Ask the user to pick:
|
|
29
|
+
- **1) I'll drop images now** — wait for user to confirm, then re-glob
|
|
30
|
+
- **2) Switch to Figma URL** — tell caller to invoke `sungen-capture-figma` instead
|
|
31
|
+
- **3) Switch to live page scan** — tell caller to invoke `sungen-capture-live` instead
|
|
32
|
+
- **4) Cancel** — abort create-test
|
|
33
|
+
3. If user picks "drop images now", wait for their confirmation message (e.g. "done") then re-run step 1.
|
|
34
|
+
|
|
35
|
+
### 3. Read images for context
|
|
36
|
+
|
|
37
|
+
Use the `read` tool on each image file — the assistant can read PNG/JPG/WebP directly as visual context.
|
|
38
|
+
|
|
39
|
+
For large sets (>10 images), ask the user which are primary and which are states/variants, to avoid loading too much visual context at once.
|
|
40
|
+
|
|
41
|
+
### 4. Summarize
|
|
42
|
+
|
|
43
|
+
Output a short summary:
|
|
44
|
+
|
|
45
|
+
> Loaded N image(s) from `qa/screens/<screen>/requirements/ui/`:
|
|
46
|
+
> - `<filename-1>` — <one-line description of what's visible>
|
|
47
|
+
> - `<filename-2>` — <one-line description>
|
|
48
|
+
> ...
|
|
49
|
+
|
|
50
|
+
Hand back to the calling command.
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## File naming hints for users
|
|
55
|
+
|
|
56
|
+
When this skill reports back, nudge users toward consistent filenames so future runs are self-documenting:
|
|
57
|
+
|
|
58
|
+
- `<section>-default.png` — baseline state of a section
|
|
59
|
+
- `<section>-error.png` — error state
|
|
60
|
+
- `<section>-loading.png` — loading state
|
|
61
|
+
- `<section>-empty.png` — empty state
|
|
62
|
+
- `full-page.png` / `viewport.png` — whole screen (auto-generated by `sungen add --capture`)
|
|
63
|
+
|
|
64
|
+
Don't enforce — just suggest if filenames are ambiguous.
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## What this skill does NOT do
|
|
69
|
+
|
|
70
|
+
- Does not download images from external URLs
|
|
71
|
+
- Does not generate images (no AI image generation)
|
|
72
|
+
- Does not modify existing images (no crop/resize)
|
|
73
|
+
- Does not generate Gherkin — that's `sungen-tc-generation`
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sungen-delivery
|
|
3
|
+
description: 'Export Gherkin scenarios + Playwright results → CSV test case deliverable. Auto-loaded by delivery command.'
|
|
4
|
+
user-invocable: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Purpose
|
|
8
|
+
|
|
9
|
+
Export test cases from Sungen screens to a standardized CSV file (format BM-2-901-13) for QA delivery.
|
|
10
|
+
|
|
11
|
+
**This skill delegates all heavy work to the `sungen delivery` CLI.** The CLI is the single source of truth for parsing logic — do NOT re-parse files in AI. Your role is only to:
|
|
12
|
+
|
|
13
|
+
1. Invoke the CLI
|
|
14
|
+
2. Show its output verbatim
|
|
15
|
+
3. Help the user react to pre-flight failures
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Architecture
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
User → /sungen:delivery [screen...]
|
|
23
|
+
│
|
|
24
|
+
▼
|
|
25
|
+
sungen delivery CLI (deterministic — no AI tokens)
|
|
26
|
+
├─ Scope detection (no-arg = all screens)
|
|
27
|
+
├─ Pre-flight source checks per screen
|
|
28
|
+
├─ Parse .feature (metadata)
|
|
29
|
+
├─ Parse .spec.ts (resolved Playwright code — source of truth)
|
|
30
|
+
├─ Parse test-data.yaml (resolve {{vars}})
|
|
31
|
+
├─ Parse test-results/results.json (match test titles)
|
|
32
|
+
├─ Merge sources + generate CSV rows
|
|
33
|
+
└─ Write qa/deliverables/<screen>-testcases.csv
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Source modules: `src/exporters/*.ts`
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Required sources (CLI pre-flight checks these)
|
|
41
|
+
|
|
42
|
+
| # | Source | Path | Created by |
|
|
43
|
+
|---|--------|------|------------|
|
|
44
|
+
| 1 | Feature file | `qa/screens/<screen>/features/<screen>.feature` | `/sungen:add-screen` + `/sungen:create-test` |
|
|
45
|
+
| 2 | Test data | `qa/screens/<screen>/test-data/<screen>.yaml` | `/sungen:create-test` |
|
|
46
|
+
| 3 | Selectors | `qa/screens/<screen>/selectors/<screen>.yaml` | `/sungen:run-test` |
|
|
47
|
+
| 4 | Compiled spec | `specs/generated/<screen>/<screen>.spec.ts` | `sungen generate` (during `/sungen:run-test`) |
|
|
48
|
+
| 5 | Test results | `specs/generated/<screen>/<screen>-test-result.json` (per-screen) or `test-results/results.json` (global fallback) | `/sungen:run-test` |
|
|
49
|
+
|
|
50
|
+
**Sources 1-4 are blocking** — CLI aborts if any is missing.
|
|
51
|
+
**Source 5 is optional** — CSV is still generated but Test Result/Date/Executor/Env columns are empty (all tests show as Pending).
|
|
52
|
+
|
|
53
|
+
The CLI reads the **per-screen result file first** (co-located with `.spec.ts`), then falls back to the global `test-results/results.json`. Per-screen is preferred because the global file gets OVERWRITTEN each time Playwright runs, losing results from earlier screens.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Column mapping (handled by CLI)
|
|
58
|
+
|
|
59
|
+
| CSV Column | Source |
|
|
60
|
+
|------------|--------|
|
|
61
|
+
| TC ID | Generated: `<SCREEN_UPPER>-<VP>-<NNN>` |
|
|
62
|
+
| Category 1 | Scenario name with VP prefix stripped |
|
|
63
|
+
| Category 2 | VP group: `VP-SEC`→Accessing, `VP-UI`→GUI, `VP-VAL`/`VP-LOGIC`→Function |
|
|
64
|
+
| Category 3 | Feature name (first line of `.feature`) |
|
|
65
|
+
| Category 4 | Screen name |
|
|
66
|
+
| Pre-condition | Auth tag → "Logged in as X" / "Not authenticated" + Given steps (natural language) |
|
|
67
|
+
| Test Data | `{{vars}}` from scenario resolved via test-data.yaml → `key: value; key2: value2` |
|
|
68
|
+
| Steps | `.spec.ts` code comments for interactions (numbered) |
|
|
69
|
+
| Expected results | `.spec.ts` `expect(...)` comments (numbered) |
|
|
70
|
+
| Priority | Tag: `@critical`/`@high`/`@normal`/`@low` (default: Normal) |
|
|
71
|
+
| Testcase type | `@manual` → Manual, else Auto. Not compiled → "Not compiled" |
|
|
72
|
+
| Test Result | results.json status: passed→Passed, failed/timedOut→Failed, skipped→N/A, else Pending |
|
|
73
|
+
| Executed Date | results.json startTime formatted as `dd/mm/yyyy` |
|
|
74
|
+
| Test Executor | `git config user.name` |
|
|
75
|
+
| Test Environment | `playwright.config.ts` baseURL + project name |
|
|
76
|
+
| Note | Error message + trace path (for failed tests) |
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Excluded from CSV
|
|
81
|
+
|
|
82
|
+
- `@steps:<name>` **base** scenarios — these are setup-only, inlined into `@extend:...` scenarios at compile time
|
|
83
|
+
- Default scaffold `Sample scenario for <screen>` — not a real test
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## CLI command reference
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
# Export all screens
|
|
91
|
+
sungen delivery
|
|
92
|
+
|
|
93
|
+
# Export specific screens
|
|
94
|
+
sungen delivery kudos awards
|
|
95
|
+
|
|
96
|
+
# Skip pre-flight (CI only)
|
|
97
|
+
sungen delivery --skip-preflight
|
|
98
|
+
|
|
99
|
+
# Skip screens with blocking misses
|
|
100
|
+
sungen delivery --continue-on-missing
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Output: `qa/deliverables/<screen>-testcases.csv` (UTF-8 with BOM)
|
|
@@ -109,6 +109,8 @@ Row scope: `see [Ref] row in [Table] table with {{v}}` enters scope. Subsequent
|
|
|
109
109
|
|
|
110
110
|
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.
|
|
111
111
|
|
|
112
|
+
**Types requiring YAML entry:** `date-picker`, `uploader`, `overlay`, `frame`, `step` - these have no standard ARIA role and need explicit selectors.
|
|
113
|
+
|
|
112
114
|
## YAML Keys
|
|
113
115
|
|
|
114
116
|
`[Reference]` → **lowercase, keep Unicode**: `[Search Content]` → `search content:`, `[Thời gian]` → `thời gian:`
|
|
@@ -8,7 +8,88 @@ user-invocable: false
|
|
|
8
8
|
|
|
9
9
|
Run tests in priority waves — catch fundamental issues early, fix critical paths first, let shared fixes cascade to lower-priority tests.
|
|
10
10
|
|
|
11
|
-
**Never run all tests blindly.** Always start with a smoke check.
|
|
11
|
+
**Never run all tests blindly.** Always start with selector pre-generation, then a smoke check.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Phase 0: Pre-run Selector Generation (Playwright MCP)
|
|
16
|
+
|
|
17
|
+
**Before any `sungen generate` or test run**, populate `selectors.yaml` from the live page so tests don't fail on missing keys in Phase 1.
|
|
18
|
+
|
|
19
|
+
### When to run Phase 0
|
|
20
|
+
|
|
21
|
+
- `selectors.yaml` missing, empty, or contains only the page selector
|
|
22
|
+
- The `.feature` file has `[Reference]` keys without corresponding YAML entries and the referenced element can't be auto-inferred (see `sungen-selector-keys` § Auto-Infer)
|
|
23
|
+
- User explicitly re-scans after UI changes
|
|
24
|
+
|
|
25
|
+
If existing selectors already cover the feature file, **skip Phase 0** and go straight to compile + Phase 1.
|
|
26
|
+
|
|
27
|
+
### Steps
|
|
28
|
+
|
|
29
|
+
1. **Confirm with the user**: *"Generate selectors from the live page via Playwright MCP now?"* — offer **Yes, scan live page** / **Skip (use existing selectors.yaml)** / **Cancel**.
|
|
30
|
+
2. **Collect references**: parse the `.feature` file for every `[Reference]` element + its type (e.g. `[Submit] button`, `[Email] field`). Deduplicate.
|
|
31
|
+
3. **Ensure page selector**: if missing, ask user for URL path and write it first.
|
|
32
|
+
4. **Navigate**:
|
|
33
|
+
- Read `baseURL` from `playwright.config.ts`.
|
|
34
|
+
- `browser_navigate` to the page URL.
|
|
35
|
+
- If redirected to login → **ask the user to log in manually in the MCP browser**, wait for confirmation, then continue. Never use `sungen makeauth`. Never inject cookies via `browser_evaluate`.
|
|
36
|
+
5. **Snapshot**: take **ONE** `browser_snapshot`. All Phase 0 selectors come from this single snapshot.
|
|
37
|
+
6. **Generate YAML entries**:
|
|
38
|
+
- Keys: follow `sungen-selector-keys` (lowercase, Unicode preserved, `--type` / `--N` suffixes).
|
|
39
|
+
- Selector priority: follow the table in **Diagnosis & Fix § Step 3** (`testid` > `role`+name > `placeholder` > `label` > `locator` > `text`).
|
|
40
|
+
- Copy names **character-for-character** from the snapshot. Never infer from the Gherkin label.
|
|
41
|
+
- If an element is auto-inferable per `sungen-selector-keys` § Auto-Infer, **omit it** from YAML — keep the file minimal.
|
|
42
|
+
7. **Merge, don't overwrite**: preserve the page selector and any user-authored entries in `selectors.yaml`. Only add missing keys.
|
|
43
|
+
8. **Show summary + confirm**: list the keys that will be added, ask the user to approve, then write the file.
|
|
44
|
+
9. **Compile**: `sungen generate --screen <screen>` — then proceed to Phase 1.
|
|
45
|
+
|
|
46
|
+
### Common Phase 0 pitfalls
|
|
47
|
+
|
|
48
|
+
- Writing keys inferred from the Gherkin label instead of the snapshot name → Phase 1 will fail with "no element found".
|
|
49
|
+
- Skipping Phase 0.5 when an auth redirect happened → snapshot captures the login page, all selectors wrong.
|
|
50
|
+
- Using `browser_evaluate` alone to scrape cookies → misses httpOnly session cookies. Always use `browser_storage_state` (or the `browser_run_code` fallback).
|
|
51
|
+
- Overwriting user-authored selectors → always merge.
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Phase 0.5: Auth Persistence (MCP alternative to `sungen makeauth`)
|
|
56
|
+
|
|
57
|
+
Capture an authenticated session from the MCP browser into `specs/.auth/<role>.json` — the same path `sungen makeauth` writes to, which compiled tests already reference via `test.use({ storageState })` based on `@auth:<role>` tags. No `playwright.config.ts` edits needed. Run once per auth lifetime, not on every selector fix.
|
|
58
|
+
|
|
59
|
+
### When to run Phase 0.5
|
|
60
|
+
|
|
61
|
+
- Phase 0 navigation hit a login redirect and `specs/.auth/<role>.json` is missing or expired
|
|
62
|
+
- A scenario tagged `@auth:<role>` is about to run and its auth file is absent
|
|
63
|
+
- User asks to refresh auth
|
|
64
|
+
|
|
65
|
+
Skip if `specs/.auth/<role>.json` already exists and a probe navigation reaches an authenticated page without redirecting to login.
|
|
66
|
+
|
|
67
|
+
### Steps
|
|
68
|
+
|
|
69
|
+
1. **Resolve the role**:
|
|
70
|
+
- Look at the `.feature` file for `@auth:<role>` tags (feature-level or scenario-level). Pick the role for the scenario being run. If no tag exists, default to `user`.
|
|
71
|
+
- Target file: `specs/.auth/<role>.json`. Create `specs/.auth/` if missing.
|
|
72
|
+
- If the file already exists → confirm overwrite with the user (mirrors the `(y/N)` prompt in `sungen makeauth`).
|
|
73
|
+
2. **Navigate to login**:
|
|
74
|
+
- Read `baseURL` from `playwright.config.ts` (fall back to `APP_BASE_URL` env, then `http://localhost:3000` — same resolution order as `sungen makeauth`).
|
|
75
|
+
- `browser_navigate` to `<baseURL>/login`. If the app uses a different login path, ask the user.
|
|
76
|
+
- If the URL doesn't stay on `/login` after load → user is already signed in. Skip step 3.
|
|
77
|
+
3. **Ask the user to log in manually** in the MCP browser (username, password, MFA, SSO — whatever the app needs). Never type credentials via `browser_type` or script the login. Wait for the user to confirm in chat that they're signed in.
|
|
78
|
+
4. **Verify login** — check the current URL or take a `browser_snapshot`; confirm the page is no longer on `/login`.
|
|
79
|
+
5. **Export storage state** (preferred → fallback):
|
|
80
|
+
- **Preferred** — `browser_storage_state` with `filename: "specs/.auth/<role>.json"` (native Playwright MCP tool; captures cookies including httpOnly + localStorage + sessionStorage via the Playwright context — same output format as `context.storageState({ path })` used by `sungen makeauth`).
|
|
81
|
+
- **Fallback** — if `browser_storage_state` isn't available in this MCP version, use `browser_run_code` to execute `await context.storageState({ path: 'specs/.auth/<role>.json' })`.
|
|
82
|
+
- **Do NOT** use `browser_evaluate` for auth export — it misses httpOnly cookies and session auth will fail silently.
|
|
83
|
+
6. **Gitignore** — ensure `specs/.auth/` (or `specs/.auth/*.json`) is in `.gitignore`. Add it if missing.
|
|
84
|
+
7. **Return to Phase 0 step 4** — re-`browser_navigate` to the target page; the session is now active.
|
|
85
|
+
|
|
86
|
+
### Phase 0.5 pitfalls
|
|
87
|
+
|
|
88
|
+
- Writing to a path other than `specs/.auth/<role>.json` → compiled tests won't find the file. Always match `sungen makeauth`'s convention.
|
|
89
|
+
- Committing `specs/.auth/*.json` → leaks a live session. Always gitignore.
|
|
90
|
+
- Scripting the login with `browser_type` → bypasses MFA/CAPTCHA and risks account lockout. Always manual.
|
|
91
|
+
- Running Phase 0.5 on every `run-test` invocation → unnecessary; reuse the file until tests start redirecting to login.
|
|
92
|
+
- Mismatch between `<role>` in the auth file and `@auth:<role>` tag → compiled tests reference a nonexistent file.
|
|
12
93
|
|
|
13
94
|
---
|
|
14
95
|
|
|
@@ -94,10 +175,10 @@ Only when `test-results/` screenshots are insufficient:
|
|
|
94
175
|
|
|
95
176
|
1. Read `baseURL` from `playwright.config.ts`
|
|
96
177
|
2. `browser_navigate` to target page
|
|
97
|
-
3. If redirected to login →
|
|
178
|
+
3. If redirected to login → run **Phase 0.5: Auth Persistence**, then re-navigate
|
|
98
179
|
4. Take **ONE** `browser_snapshot` — fix all broken selectors from this single snapshot
|
|
99
180
|
|
|
100
|
-
|
|
181
|
+
Never use `browser_evaluate` to inject or read cookies (misses httpOnly). For auth, use Phase 0.5 or `sungen makeauth`.
|
|
101
182
|
|
|
102
183
|
### Step 3: Fix Broken Selectors
|
|
103
184
|
|
|
@@ -181,9 +262,11 @@ user detail:
|
|
|
181
262
|
|
|
182
263
|
| Phase | What runs | Max fix attempts | On failure after max |
|
|
183
264
|
|---|---|---|---|
|
|
265
|
+
| 0. Pre-gen | Playwright MCP snapshot → write selectors.yaml | 1 snapshot | Ask user — skip or retry navigation |
|
|
266
|
+
| 0.5. Auth | Manual login in MCP browser → `browser_storage_state` → `specs/.auth/<role>.json` | 1 login | Ask user — retry login or fall back to `sungen makeauth` |
|
|
184
267
|
| 1. Smoke | First 5 @critical/@high | 2 | Ask user — fundamentals broken |
|
|
185
268
|
| 2. Priority | All @critical + @high | 2 | Report failures, continue to Phase 3 |
|
|
186
269
|
| 3. Full | All tests | 1 | Report @low/@normal failures, continue |
|
|
187
270
|
| 4. Regression | All tests | 0 | Report final results |
|
|
188
271
|
|
|
189
|
-
**Total worst case: 5 fix attempts** (2+2+1), not unbounded loops.
|
|
272
|
+
**Total worst case: 5 fix attempts** (2+2+1), not unbounded loops. Phases 0 and 0.5 don't count toward fix budget.
|
|
@@ -102,5 +102,27 @@ If no YAML key exists, the resolver infers from the Gherkin element type:
|
|
|
102
102
|
| `[X] list` | `getByRole('list', { name: 'X' })` |
|
|
103
103
|
| `[X] column` | `getByRole('columnheader', { name: 'X' })` |
|
|
104
104
|
| `[X] dialog` / `modal` / `drawer` | `getByRole('dialog', { name: 'X' })` |
|
|
105
|
+
| `[X] dropdown` / `select` | `getByRole('combobox', { name: 'X' })` |
|
|
106
|
+
| `[X] menuitem` | `getByRole('menuitem', { name: 'X' })` |
|
|
107
|
+
| `[X] progressbar` | `getByRole('progressbar', { name: 'X' })` |
|
|
108
|
+
| `[X] section` | `getByRole('region', { name: 'X' })` |
|
|
109
|
+
| `[X] card` | `getByRole('article', { name: 'X' })` |
|
|
110
|
+
| `[X] item` | `getByRole('listitem', { name: 'X' })` |
|
|
111
|
+
| `[X] cell` | `getByRole('cell', { name: 'X' })` |
|
|
112
|
+
| `[X] spinner` | `getByRole('status', { name: 'X' })` |
|
|
113
|
+
| `[X] breadcrumb` | `getByRole('navigation', { name: 'X' })` |
|
|
114
|
+
| `[X] badge` / `tooltip` / `tag` | `getByText('X')` |
|
|
105
115
|
|
|
106
116
|
**Only add a YAML entry when** the auto-inferred locator won't work (wrong name, need testid, need nth, etc.).
|
|
117
|
+
|
|
118
|
+
### Types requiring YAML entry (no auto-infer)
|
|
119
|
+
|
|
120
|
+
These types need explicit `selectors.yaml` entries:
|
|
121
|
+
|
|
122
|
+
| Type | Reason |
|
|
123
|
+
|------|--------|
|
|
124
|
+
| `date-picker` | Custom component, needs testid or CSS |
|
|
125
|
+
| `uploader` | File input, needs upload type selector |
|
|
126
|
+
| `overlay` | No standard ARIA role, needs CSS/testid |
|
|
127
|
+
| `frame` | Needs iframe selector |
|
|
128
|
+
| `step` | Custom stepper component, needs testid |
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"playwright.config.d.ts","sourceRoot":"","sources":["../../../src/orchestrator/templates/playwright.config.ts"],"names":[],"mappings":"AAEA;;;GAGG;AAKH;;GAEG;;AACH,
|
|
1
|
+
{"version":3,"file":"playwright.config.d.ts","sourceRoot":"","sources":["../../../src/orchestrator/templates/playwright.config.ts"],"names":[],"mappings":"AAEA;;;GAGG;AAKH;;GAEG;;AACH,wBAyEG"}
|
|
@@ -24,7 +24,12 @@ exports.default = (0, test_1.defineConfig)({
|
|
|
24
24
|
/* Global timeout per test */
|
|
25
25
|
timeout: 10000,
|
|
26
26
|
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
|
|
27
|
-
reporter
|
|
27
|
+
/* JSON reporter is required by `sungen delivery` to populate test result columns in the exported CSV. */
|
|
28
|
+
/* Output file path is controlled by PLAYWRIGHT_JSON_OUTPUT_NAME env var for per-screen isolation. */
|
|
29
|
+
reporter: [
|
|
30
|
+
['html'],
|
|
31
|
+
['json', { outputFile: process.env.PLAYWRIGHT_JSON_OUTPUT_NAME || 'test-results/results.json' }],
|
|
32
|
+
],
|
|
28
33
|
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
|
|
29
34
|
use: {
|
|
30
35
|
/* Base URL to use in actions like `await page.goto('')`. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"playwright.config.js","sourceRoot":"","sources":["../../../src/orchestrator/templates/playwright.config.ts"],"names":[],"mappings":";;AAAA,2CAAyD;AAEzD;;;GAGG;AACH,+BAA+B;AAC/B,2BAA2B;AAC3B,4DAA4D;AAE5D;;GAEG;AACH,kBAAe,IAAA,mBAAY,EAAC;IAC1B,OAAO,EAAE,mBAAmB;IAC5B,oCAAoC;IACpC,aAAa,EAAE,IAAI;IACnB,iFAAiF;IACjF,UAAU,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;IAC5B,sBAAsB;IACtB,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/B,sCAAsC;IACtC,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/B,6BAA6B;IAC7B,OAAO,EAAE,KAAM;IACf,qEAAqE;IACrE,QAAQ,EAAE,MAAM;
|
|
1
|
+
{"version":3,"file":"playwright.config.js","sourceRoot":"","sources":["../../../src/orchestrator/templates/playwright.config.ts"],"names":[],"mappings":";;AAAA,2CAAyD;AAEzD;;;GAGG;AACH,+BAA+B;AAC/B,2BAA2B;AAC3B,4DAA4D;AAE5D;;GAEG;AACH,kBAAe,IAAA,mBAAY,EAAC;IAC1B,OAAO,EAAE,mBAAmB;IAC5B,oCAAoC;IACpC,aAAa,EAAE,IAAI;IACnB,iFAAiF;IACjF,UAAU,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;IAC5B,sBAAsB;IACtB,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/B,sCAAsC;IACtC,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/B,6BAA6B;IAC7B,OAAO,EAAE,KAAM;IACf,qEAAqE;IACrE,yGAAyG;IACzG,qGAAqG;IACrG,QAAQ,EAAE;QACR,CAAC,MAAM,CAAC;QACR,CAAC,MAAM,EAAE,EAAE,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,2BAA2B,IAAI,2BAA2B,EAAE,CAAC;KACjG;IACD,wGAAwG;IACxG,GAAG,EAAE;QACH,4DAA4D;QAC5D,OAAO,EAAE,qBAAqB;QAE9B,+FAA+F;QAC/F,KAAK,EAAE,gBAAgB;KACxB;IAED,2CAA2C;IAC3C,QAAQ,EAAE;QACR;YACE,IAAI,EAAE,UAAU;YAChB,GAAG,EAAE,EAAE,GAAG,cAAO,CAAC,gBAAgB,CAAC,EAAE;SACtC;QAED;;;;;;;;;;;;;;;;;;;;;4CAqBoC;QACpC,IAAI;QACJ,4BAA4B;QAC5B,4DAA4D;QAC5D,KAAK;QACL,IAAI;QACJ,2BAA2B;QAC3B,8DAA8D;QAC9D,KAAK;KACN;IAED,yDAAyD;IACzD,eAAe;IACf,8BAA8B;IAC9B,kCAAkC;IAClC,0CAA0C;IAC1C,KAAK;CACN,CAAC,CAAC"}
|
|
@@ -24,7 +24,12 @@ export default defineConfig({
|
|
|
24
24
|
/* Global timeout per test */
|
|
25
25
|
timeout: 10_000,
|
|
26
26
|
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
|
|
27
|
-
reporter
|
|
27
|
+
/* JSON reporter is required by `sungen delivery` to populate test result columns in the exported CSV. */
|
|
28
|
+
/* Output file path is controlled by PLAYWRIGHT_JSON_OUTPUT_NAME env var for per-screen isolation. */
|
|
29
|
+
reporter: [
|
|
30
|
+
['html'],
|
|
31
|
+
['json', { outputFile: process.env.PLAYWRIGHT_JSON_OUTPUT_NAME || 'test-results/results.json' }],
|
|
32
|
+
],
|
|
28
33
|
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
|
|
29
34
|
use: {
|
|
30
35
|
/* Base URL to use in actions like `await page.goto('')`. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sun-asterisk/sungen",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.6",
|
|
4
4
|
"description": "Deterministic E2E Test Compiler - Gherkin + Selectors → Playwright tests",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
"chalk": "^5.6.2",
|
|
41
41
|
"commander": "^14.0.2",
|
|
42
42
|
"dotenv": "^17.2.3",
|
|
43
|
+
"exceljs": "^4.4.0",
|
|
43
44
|
"fast-glob": "^3.3.3",
|
|
44
45
|
"glob": "^13.0.0",
|
|
45
46
|
"handlebars": "^4.7.8",
|
package/src/cli/commands/add.ts
CHANGED
|
@@ -3,19 +3,26 @@ import { Command } from 'commander';
|
|
|
3
3
|
export function registerAddCommand(program: Command): void {
|
|
4
4
|
program
|
|
5
5
|
.command('add')
|
|
6
|
-
.description('Add screen or feature definition with scaffolded files.
|
|
6
|
+
.description('Add screen or feature definition with scaffolded files. Use --capture to auto-capture a live-page screenshot.')
|
|
7
7
|
.requiredOption('--screen <name>', 'Screen name')
|
|
8
|
-
.option('-p, --path <path>', 'Screen route path (e.g. /awards)
|
|
8
|
+
.option('-p, --path <path>', 'Screen route path (e.g. /awards)')
|
|
9
|
+
.option('-c, --capture', 'Auto-capture a live-page screenshot to requirements/ui/ (requires --path)')
|
|
9
10
|
.option('-f, --feature <name>', 'Add additional feature file to existing screen')
|
|
10
11
|
.option('-d, --description <text>', 'Screen description')
|
|
11
12
|
.action(async (options) => {
|
|
12
13
|
try {
|
|
14
|
+
if (options.capture && !options.path) {
|
|
15
|
+
console.error('Error: --capture requires --path to be set');
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
|
|
13
19
|
const { ScreenManager } = require('../../orchestrator/screen-manager');
|
|
14
20
|
const manager = new ScreenManager();
|
|
15
21
|
|
|
16
22
|
await manager.addScreen({
|
|
17
23
|
name: options.screen,
|
|
18
24
|
path: options.path,
|
|
25
|
+
capture: options.capture,
|
|
19
26
|
feature: options.feature,
|
|
20
27
|
description: options.description,
|
|
21
28
|
});
|