@sun-asterisk/sungen 2.4.5 → 2.5.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/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/generate.d.ts.map +1 -1
- package/dist/cli/commands/generate.js +2 -0
- package/dist/cli/commands/generate.js.map +1 -1
- 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/gherkin-parser/index.d.ts +1 -0
- package/dist/generators/gherkin-parser/index.d.ts.map +1 -1
- package/dist/generators/gherkin-parser/index.js +3 -0
- package/dist/generators/gherkin-parser/index.js.map +1 -1
- package/dist/generators/test-generator/adapters/adapter-interface.d.ts +29 -1
- package/dist/generators/test-generator/adapters/adapter-interface.d.ts.map +1 -1
- package/dist/generators/test-generator/adapters/playwright/playwright-adapter.d.ts +21 -1
- package/dist/generators/test-generator/adapters/playwright/playwright-adapter.d.ts.map +1 -1
- package/dist/generators/test-generator/adapters/playwright/playwright-adapter.js +11 -2
- package/dist/generators/test-generator/adapters/playwright/playwright-adapter.js.map +1 -1
- package/dist/generators/test-generator/adapters/playwright/templates/after-all.hbs +8 -0
- package/dist/generators/test-generator/adapters/playwright/templates/after-each.hbs +8 -0
- package/dist/generators/test-generator/adapters/playwright/templates/before-all.hbs +8 -0
- package/dist/generators/test-generator/adapters/playwright/templates/imports.hbs +3 -0
- package/dist/generators/test-generator/adapters/playwright/templates/test-file.hbs +24 -0
- package/dist/generators/test-generator/code-generator.d.ts +2 -0
- package/dist/generators/test-generator/code-generator.d.ts.map +1 -1
- package/dist/generators/test-generator/code-generator.js +109 -12
- package/dist/generators/test-generator/code-generator.js.map +1 -1
- package/dist/generators/test-generator/step-mapper.d.ts +1 -0
- package/dist/generators/test-generator/step-mapper.d.ts.map +1 -1
- package/dist/generators/test-generator/step-mapper.js +1 -1
- package/dist/generators/test-generator/step-mapper.js.map +1 -1
- package/dist/generators/test-generator/template-engine.d.ts +29 -1
- package/dist/generators/test-generator/template-engine.d.ts.map +1 -1
- package/dist/generators/test-generator/template-engine.js +11 -2
- package/dist/generators/test-generator/template-engine.js.map +1 -1
- package/dist/generators/test-generator/utils/data-resolver.d.ts +11 -2
- package/dist/generators/test-generator/utils/data-resolver.d.ts.map +1 -1
- package/dist/generators/test-generator/utils/data-resolver.js +36 -25
- package/dist/generators/test-generator/utils/data-resolver.js.map +1 -1
- package/dist/generators/test-generator/utils/runtime-data-transformer.d.ts +7 -0
- package/dist/generators/test-generator/utils/runtime-data-transformer.d.ts.map +1 -0
- package/dist/generators/test-generator/utils/runtime-data-transformer.js +42 -0
- package/dist/generators/test-generator/utils/runtime-data-transformer.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/generators/types.d.ts +1 -0
- package/dist/generators/types.d.ts.map +1 -1
- package/dist/generators/types.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 +21 -1
- package/dist/orchestrator/project-initializer.d.ts.map +1 -1
- package/dist/orchestrator/project-initializer.js +158 -74
- package/dist/orchestrator/project-initializer.js.map +1 -1
- package/dist/orchestrator/screen-manager.d.ts.map +1 -1
- package/dist/orchestrator/screen-manager.js +2 -0
- package/dist/orchestrator/screen-manager.js.map +1 -1
- package/dist/orchestrator/templates/ai-instructions/claude-cmd-add-screen.md +15 -17
- 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 +28 -1
- package/dist/orchestrator/templates/ai-instructions/claude-config.md +23 -4
- 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 +68 -13
- package/dist/orchestrator/templates/ai-instructions/claude-skill-selector-keys.md +22 -0
- package/dist/orchestrator/templates/ai-instructions/claude-skill-tc-generation.md +54 -3
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-add-screen.md +13 -15
- 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 +38 -14
- package/dist/orchestrator/templates/ai-instructions/copilot-config.md +23 -4
- 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 +88 -13
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-selector-keys.md +22 -0
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-tc-generation.md +54 -3
- 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/dist/orchestrator/templates/specs-base.d.ts +12 -1
- package/dist/orchestrator/templates/specs-base.d.ts.map +1 -1
- package/dist/orchestrator/templates/specs-base.js +47 -5
- package/dist/orchestrator/templates/specs-base.js.map +1 -1
- package/dist/orchestrator/templates/specs-base.ts +65 -7
- package/dist/orchestrator/templates/specs-test-data.d.ts +14 -0
- package/dist/orchestrator/templates/specs-test-data.d.ts.map +1 -0
- package/dist/orchestrator/templates/specs-test-data.js +100 -0
- package/dist/orchestrator/templates/specs-test-data.js.map +1 -0
- package/dist/orchestrator/templates/specs-test-data.ts +66 -0
- package/package.json +2 -1
- package/src/cli/commands/delivery.ts +348 -0
- package/src/cli/commands/generate.ts +2 -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/gherkin-parser/index.ts +4 -0
- package/src/generators/test-generator/adapters/adapter-interface.ts +12 -1
- package/src/generators/test-generator/adapters/playwright/playwright-adapter.ts +14 -2
- package/src/generators/test-generator/adapters/playwright/templates/after-all.hbs +8 -0
- package/src/generators/test-generator/adapters/playwright/templates/after-each.hbs +8 -0
- package/src/generators/test-generator/adapters/playwright/templates/before-all.hbs +8 -0
- package/src/generators/test-generator/adapters/playwright/templates/imports.hbs +3 -0
- package/src/generators/test-generator/adapters/playwright/templates/test-file.hbs +24 -0
- package/src/generators/test-generator/code-generator.ts +122 -13
- package/src/generators/test-generator/step-mapper.ts +2 -2
- package/src/generators/test-generator/template-engine.ts +28 -2
- package/src/generators/test-generator/utils/data-resolver.ts +45 -27
- package/src/generators/test-generator/utils/runtime-data-transformer.ts +51 -0
- package/src/generators/test-generator/utils/selector-resolver.ts +26 -0
- package/src/generators/types.ts +1 -0
- package/src/orchestrator/ai-rules-updater.ts +12 -0
- package/src/orchestrator/project-initializer.ts +187 -80
- package/src/orchestrator/screen-manager.ts +2 -0
- package/src/orchestrator/templates/ai-instructions/claude-cmd-add-screen.md +15 -17
- 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 +28 -1
- package/src/orchestrator/templates/ai-instructions/claude-config.md +23 -4
- 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 +68 -13
- package/src/orchestrator/templates/ai-instructions/claude-skill-selector-keys.md +22 -0
- package/src/orchestrator/templates/ai-instructions/claude-skill-tc-generation.md +54 -3
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-add-screen.md +13 -15
- 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 +38 -14
- package/src/orchestrator/templates/ai-instructions/copilot-config.md +23 -4
- 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 +88 -13
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-selector-keys.md +22 -0
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-tc-generation.md +54 -3
- package/src/orchestrator/templates/playwright.config.ts +6 -1
- package/src/orchestrator/templates/specs-base.ts +65 -7
- package/src/orchestrator/templates/specs-test-data.ts +66 -0
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
import * as fs from 'fs';
|
|
7
7
|
import * as path from 'path';
|
|
8
8
|
import { execSync } from 'child_process';
|
|
9
|
+
import { AI_RULES_FILE_MAPPING } from './ai-rules-updater';
|
|
9
10
|
|
|
10
11
|
export class ProjectInitializer {
|
|
11
12
|
private baseCwd: string;
|
|
@@ -47,8 +48,9 @@ export class ProjectInitializer {
|
|
|
47
48
|
// Create tsconfig.json if doesn't exist
|
|
48
49
|
this.createTsConfig();
|
|
49
50
|
|
|
50
|
-
// Create specs/base.ts for shared context
|
|
51
|
+
// Create specs/base.ts for shared context and specs/test-data.ts for runtime data
|
|
51
52
|
this.createSpecsBase();
|
|
53
|
+
this.createSpecsTestData();
|
|
52
54
|
|
|
53
55
|
// Create/update .gitignore
|
|
54
56
|
this.updateGitignore();
|
|
@@ -62,6 +64,9 @@ export class ProjectInitializer {
|
|
|
62
64
|
// Create VS Code settings for Copilot auto-attach
|
|
63
65
|
this.createVSCodeSettings();
|
|
64
66
|
|
|
67
|
+
// Create root .mcp.json for Claude Code
|
|
68
|
+
this.createClaudeMCPConfig();
|
|
69
|
+
|
|
65
70
|
// Display summary
|
|
66
71
|
this.displaySummary(normalizedProjectName);
|
|
67
72
|
}
|
|
@@ -190,46 +195,112 @@ export class ProjectInitializer {
|
|
|
190
195
|
private createVSCodeSettings(): void {
|
|
191
196
|
const settingsPath = path.join(this.cwd, '.vscode', 'settings.json');
|
|
192
197
|
|
|
193
|
-
if (fs.existsSync(settingsPath)) {
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
198
|
+
if (!fs.existsSync(settingsPath)) {
|
|
199
|
+
const settingsDir = path.dirname(settingsPath);
|
|
200
|
+
if (!fs.existsSync(settingsDir)) {
|
|
201
|
+
fs.mkdirSync(settingsDir, { recursive: true });
|
|
202
|
+
}
|
|
197
203
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
204
|
+
const settings = {
|
|
205
|
+
'github.copilot.chat.agent.runTasks': true,
|
|
206
|
+
'chat.tools.terminal.autoApprove': {
|
|
207
|
+
sungen: true,
|
|
208
|
+
'npx playwright': true,
|
|
209
|
+
},
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n', 'utf-8');
|
|
213
|
+
this.createdItems.push('.vscode/settings.json');
|
|
214
|
+
} else {
|
|
215
|
+
this.skippedItems.push('.vscode/settings.json');
|
|
201
216
|
}
|
|
202
217
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
218
|
+
// .vscode/mcp.json (Copilot format) — safe-merge Playwright + Figma entries
|
|
219
|
+
this.mergeMCPConfig(
|
|
220
|
+
path.join(this.cwd, '.vscode', 'mcp.json'),
|
|
221
|
+
'servers',
|
|
222
|
+
{
|
|
223
|
+
playwright: {
|
|
224
|
+
command: 'npx',
|
|
225
|
+
args: ['@playwright/mcp@latest'],
|
|
226
|
+
},
|
|
227
|
+
figma: {
|
|
228
|
+
type: 'http',
|
|
229
|
+
url: 'https://mcp.figma.com/mcp',
|
|
230
|
+
},
|
|
208
231
|
},
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
this.createdItems.push('.vscode/settings.json');
|
|
213
|
-
|
|
214
|
-
// Create MCP config for Playwright browser tools
|
|
215
|
-
const mcpPath = path.join(this.cwd, '.vscode', 'mcp.json');
|
|
216
|
-
|
|
217
|
-
if (fs.existsSync(mcpPath)) {
|
|
218
|
-
this.skippedItems.push('.vscode/mcp.json');
|
|
219
|
-
return;
|
|
220
|
-
}
|
|
232
|
+
'.vscode/mcp.json',
|
|
233
|
+
);
|
|
234
|
+
}
|
|
221
235
|
|
|
222
|
-
|
|
223
|
-
|
|
236
|
+
/**
|
|
237
|
+
* Create root .mcp.json for Claude Code — safe-merge Playwright + Figma entries
|
|
238
|
+
*/
|
|
239
|
+
private createClaudeMCPConfig(): void {
|
|
240
|
+
this.mergeMCPConfig(
|
|
241
|
+
path.join(this.cwd, '.mcp.json'),
|
|
242
|
+
'mcpServers',
|
|
243
|
+
{
|
|
224
244
|
playwright: {
|
|
245
|
+
type: 'stdio',
|
|
225
246
|
command: 'npx',
|
|
226
247
|
args: ['@playwright/mcp@latest'],
|
|
227
248
|
},
|
|
249
|
+
figma: {
|
|
250
|
+
type: 'http',
|
|
251
|
+
url: 'https://mcp.figma.com/mcp',
|
|
252
|
+
},
|
|
228
253
|
},
|
|
229
|
-
|
|
254
|
+
'.mcp.json',
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Add MCP server entries without overwriting user config.
|
|
260
|
+
* Preserves existing entries with the same key — user edits always win.
|
|
261
|
+
*/
|
|
262
|
+
private mergeMCPConfig(
|
|
263
|
+
filePath: string,
|
|
264
|
+
rootKey: string,
|
|
265
|
+
newServers: Record<string, unknown>,
|
|
266
|
+
displayName: string,
|
|
267
|
+
): void {
|
|
268
|
+
const dir = path.dirname(filePath);
|
|
269
|
+
if (!fs.existsSync(dir)) {
|
|
270
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
let config: Record<string, Record<string, unknown>> = {};
|
|
274
|
+
const existed = fs.existsSync(filePath);
|
|
230
275
|
|
|
231
|
-
|
|
232
|
-
|
|
276
|
+
if (existed) {
|
|
277
|
+
try {
|
|
278
|
+
config = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
|
|
279
|
+
} catch {
|
|
280
|
+
this.skippedItems.push(`${displayName} (invalid JSON, skipped)`);
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
if (!config[rootKey] || typeof config[rootKey] !== 'object') {
|
|
286
|
+
config[rootKey] = {};
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
let added = 0;
|
|
290
|
+
for (const [name, entry] of Object.entries(newServers)) {
|
|
291
|
+
if (!config[rootKey][name]) {
|
|
292
|
+
config[rootKey][name] = entry;
|
|
293
|
+
added++;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
if (added === 0) {
|
|
298
|
+
this.skippedItems.push(displayName);
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
fs.writeFileSync(filePath, JSON.stringify(config, null, 2) + '\n', 'utf-8');
|
|
303
|
+
this.createdItems.push(existed ? `${displayName} (updated)` : displayName);
|
|
233
304
|
}
|
|
234
305
|
|
|
235
306
|
/**
|
|
@@ -264,51 +335,14 @@ export class ProjectInitializer {
|
|
|
264
335
|
}
|
|
265
336
|
|
|
266
337
|
/**
|
|
267
|
-
* Create AI rules files for GitHub Copilot and Claude Code
|
|
338
|
+
* Create AI rules files for GitHub Copilot and Claude Code.
|
|
339
|
+
* Shares `AI_RULES_FILE_MAPPING` with `sungen update` so a newly added
|
|
340
|
+
* skill / command template only needs to be registered once.
|
|
268
341
|
*/
|
|
269
342
|
private createAIRules(): void {
|
|
270
343
|
const aiTemplateDir = path.join(__dirname, 'templates', 'ai-instructions');
|
|
271
344
|
|
|
272
|
-
|
|
273
|
-
const fileMapping: [string, string][] = [
|
|
274
|
-
// Config
|
|
275
|
-
['claude-config.md', 'CLAUDE.md'],
|
|
276
|
-
['copilot-config.md', '.github/copilot-instructions.md'],
|
|
277
|
-
|
|
278
|
-
// Commands — Claude Code
|
|
279
|
-
['claude-cmd-add-screen.md', '.claude/commands/sungen/add-screen.md'],
|
|
280
|
-
['claude-cmd-create-test.md', '.claude/commands/sungen/create-test.md'],
|
|
281
|
-
['claude-cmd-run-test.md', '.claude/commands/sungen/run-test.md'],
|
|
282
|
-
['claude-cmd-review.md', '.claude/commands/sungen/review.md'],
|
|
283
|
-
|
|
284
|
-
// Commands — GitHub Copilot
|
|
285
|
-
['copilot-cmd-add-screen.md', '.github/prompts/sungen-add-screen.prompt.md'],
|
|
286
|
-
['copilot-cmd-create-test.md', '.github/prompts/sungen-create-test.prompt.md'],
|
|
287
|
-
['copilot-cmd-run-test.md', '.github/prompts/sungen-run-test.prompt.md'],
|
|
288
|
-
['copilot-cmd-review.md', '.github/prompts/sungen-review.prompt.md'],
|
|
289
|
-
|
|
290
|
-
// Skills — Claude Code
|
|
291
|
-
['claude-skill-gherkin-syntax.md', '.claude/skills/sungen-gherkin-syntax/SKILL.md'],
|
|
292
|
-
['claude-skill-selector-keys.md', '.claude/skills/sungen-selector-keys/SKILL.md'],
|
|
293
|
-
['claude-skill-error-mapping.md', '.claude/skills/sungen-error-mapping/SKILL.md'],
|
|
294
|
-
['claude-skill-tc-generation.md', '.claude/skills/sungen-tc-generation/SKILL.md'],
|
|
295
|
-
['claude-skill-test-design-techniques.md', '.claude/skills/sungen-test-design-techniques/SKILL.md'],
|
|
296
|
-
['claude-skill-selector-fix.md', '.claude/skills/sungen-selector-fix/SKILL.md'],
|
|
297
|
-
['claude-skill-tc-review.md', '.claude/skills/sungen-tc-review/SKILL.md'],
|
|
298
|
-
['claude-skill-viewpoint.md', '.claude/skills/sungen-viewpoint/SKILL.md'],
|
|
299
|
-
|
|
300
|
-
// Skills — GitHub Copilot (separate copies with Copilot-friendly descriptions)
|
|
301
|
-
['github-skill-sungen-gherkin-syntax.md', '.github/skills/sungen-gherkin-syntax/SKILL.md'],
|
|
302
|
-
['github-skill-sungen-selector-keys.md', '.github/skills/sungen-selector-keys/SKILL.md'],
|
|
303
|
-
['github-skill-sungen-error-mapping.md', '.github/skills/sungen-error-mapping/SKILL.md'],
|
|
304
|
-
['github-skill-sungen-tc-generation.md', '.github/skills/sungen-tc-generation/SKILL.md'],
|
|
305
|
-
['github-skill-sungen-test-design-techniques.md', '.github/skills/sungen-test-design-techniques/SKILL.md'],
|
|
306
|
-
['github-skill-sungen-selector-fix.md', '.github/skills/sungen-selector-fix/SKILL.md'],
|
|
307
|
-
['github-skill-sungen-tc-review.md', '.github/skills/sungen-tc-review/SKILL.md'],
|
|
308
|
-
['github-skill-sungen-viewpoint.md', '.github/skills/sungen-viewpoint/SKILL.md'],
|
|
309
|
-
];
|
|
310
|
-
|
|
311
|
-
for (const [templateFile, outputRelPath] of fileMapping) {
|
|
345
|
+
for (const [templateFile, outputRelPath] of AI_RULES_FILE_MAPPING) {
|
|
312
346
|
const outputPath = path.join(this.cwd, outputRelPath);
|
|
313
347
|
|
|
314
348
|
if (fs.existsSync(outputPath)) {
|
|
@@ -350,6 +384,27 @@ export class ProjectInitializer {
|
|
|
350
384
|
this.createdItems.push('specs/generated/base.ts');
|
|
351
385
|
}
|
|
352
386
|
|
|
387
|
+
/**
|
|
388
|
+
* Create specs/test-data.ts for runtime YAML loading
|
|
389
|
+
*/
|
|
390
|
+
private createSpecsTestData(): void {
|
|
391
|
+
const testDataPath = path.join(this.cwd, 'specs', 'generated', 'test-data.ts');
|
|
392
|
+
|
|
393
|
+
if (fs.existsSync(testDataPath)) {
|
|
394
|
+
this.skippedItems.push('specs/generated/test-data.ts');
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
const baseDir = path.dirname(testDataPath);
|
|
399
|
+
if (!fs.existsSync(baseDir)) {
|
|
400
|
+
fs.mkdirSync(baseDir, { recursive: true });
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
const content = this.readTemplate('specs-test-data.ts');
|
|
404
|
+
fs.writeFileSync(testDataPath, content, 'utf-8');
|
|
405
|
+
this.createdItems.push('specs/generated/test-data.ts');
|
|
406
|
+
}
|
|
407
|
+
|
|
353
408
|
/**
|
|
354
409
|
* Read a template file from the templates directory
|
|
355
410
|
*/
|
|
@@ -372,26 +427,78 @@ export class ProjectInitializer {
|
|
|
372
427
|
this.createdItems.push('package.json');
|
|
373
428
|
}
|
|
374
429
|
|
|
375
|
-
//
|
|
430
|
+
// Ensure standard scripts exist in package.json
|
|
431
|
+
this.ensurePackageScripts(packageJsonPath);
|
|
432
|
+
|
|
433
|
+
// Check which dependencies are missing
|
|
434
|
+
const requiredDeps = ['@playwright/test', '@types/node', 'yaml'];
|
|
435
|
+
let missingDeps: string[] = requiredDeps;
|
|
376
436
|
try {
|
|
377
437
|
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
|
|
378
438
|
const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
|
|
379
|
-
|
|
380
|
-
console.log('✓ @playwright/test already installed\n');
|
|
381
|
-
return;
|
|
382
|
-
}
|
|
439
|
+
missingDeps = requiredDeps.filter(d => !deps[d]);
|
|
383
440
|
} catch {
|
|
384
|
-
// package.json just created,
|
|
441
|
+
// package.json just created, install all
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
if (missingDeps.length === 0) {
|
|
445
|
+
console.log('✓ All dependencies already installed\n');
|
|
446
|
+
return;
|
|
385
447
|
}
|
|
386
448
|
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
execSync('npm install -D @playwright/test @types/node', execOpts);
|
|
449
|
+
console.log(`📦 Installing ${missingDeps.join(', ')}...\n`);
|
|
450
|
+
execSync(`npm install -D ${missingDeps.join(' ')}`, execOpts);
|
|
390
451
|
|
|
391
452
|
console.log('\n🎭 Installing Playwright browsers...\n');
|
|
392
453
|
execSync('npx playwright install', execOpts);
|
|
393
454
|
}
|
|
394
455
|
|
|
456
|
+
/**
|
|
457
|
+
* Ensure package.json has standard Playwright + Sungen scripts.
|
|
458
|
+
* Only adds missing scripts — never overwrites user customizations.
|
|
459
|
+
*/
|
|
460
|
+
private ensurePackageScripts(packageJsonPath: string): void {
|
|
461
|
+
let packageJson: Record<string, any>;
|
|
462
|
+
try {
|
|
463
|
+
packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
|
|
464
|
+
} catch {
|
|
465
|
+
return;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
if (!packageJson.scripts || typeof packageJson.scripts !== 'object') {
|
|
469
|
+
packageJson.scripts = {};
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
const standardScripts: Record<string, string> = {
|
|
473
|
+
'test': 'playwright test specs/generated/',
|
|
474
|
+
'test:headed': 'playwright test specs/generated/ --headed',
|
|
475
|
+
'test:debug': 'playwright test specs/generated/ --debug',
|
|
476
|
+
'test:ui': 'playwright test specs/generated/ --ui',
|
|
477
|
+
'report': 'playwright show-report',
|
|
478
|
+
'generate': 'sungen generate --all',
|
|
479
|
+
'install:browsers': 'npx playwright install chromium',
|
|
480
|
+
};
|
|
481
|
+
|
|
482
|
+
let added = 0;
|
|
483
|
+
for (const [name, command] of Object.entries(standardScripts)) {
|
|
484
|
+
// Skip if user already has this script (don't overwrite)
|
|
485
|
+
// Exception: overwrite the npm init default test script
|
|
486
|
+
const existing = packageJson.scripts[name];
|
|
487
|
+
if (existing && existing !== 'echo "Error: no test specified" && exit 1') {
|
|
488
|
+
continue;
|
|
489
|
+
}
|
|
490
|
+
packageJson.scripts[name] = command;
|
|
491
|
+
added++;
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
if (added > 0) {
|
|
495
|
+
// Also mark as private (test projects should not be published)
|
|
496
|
+
packageJson.private = true;
|
|
497
|
+
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n', 'utf-8');
|
|
498
|
+
console.log(`📝 Added ${added} standard script(s) to package.json\n`);
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
|
|
395
502
|
/**
|
|
396
503
|
* Get Playwright configuration template
|
|
397
504
|
*/
|
|
@@ -296,6 +296,8 @@ export class ScreenManager {
|
|
|
296
296
|
|
|
297
297
|
## Overview
|
|
298
298
|
- **URL Path:** ${pagePath}
|
|
299
|
+
- **Live URL:** <!-- optional, full URL for live page capture (falls back to baseURL + URL Path) -->
|
|
300
|
+
- **Figma URL:** <!-- optional, Figma frame URL for design-driven capture (requires Figma MCP) -->
|
|
299
301
|
- **Auth Required:** no
|
|
300
302
|
- **Platform:** web
|
|
301
303
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: add-screen
|
|
3
|
-
description: 'Add a new Sungen screen — scaffolds directories, helps fill spec.md, and can
|
|
3
|
+
description: 'Add a new Sungen screen — scaffolds directories, helps fill spec.md, and can capture visuals from Figma (pre-launch) or live page via the capture skills'
|
|
4
4
|
argument-hint: [screen-name] [url-path]
|
|
5
|
-
allowed-tools: Read, Grep, Bash, Glob, Edit, Write, AskUserQuestion, mcp__playwright__browser_navigate, mcp__playwright__browser_take_screenshot, mcp__playwright__browser_snapshot
|
|
5
|
+
allowed-tools: Read, Grep, Bash, Glob, Edit, Write, AskUserQuestion, mcp__playwright__browser_navigate, mcp__playwright__browser_take_screenshot, mcp__playwright__browser_snapshot, mcp__figma__get_design_context, mcp__figma__get_variable_defs, mcp__figma__get_screenshot
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
You are adding a new Sungen screen for test generation.
|
|
@@ -25,27 +25,25 @@ Run:
|
|
|
25
25
|
sungen add --screen <screen> --path <path>
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
### 2.
|
|
28
|
+
### 2. Fill spec.md
|
|
29
29
|
|
|
30
|
-
Use `AskUserQuestion
|
|
30
|
+
Use `AskUserQuestion`: *"Fill `spec.md` now?"* — offer **Yes, fill now (Recommended)** / **Skip, fill later**.
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
- **Fill `spec.md` only** — app not live yet, or no need for visuals
|
|
34
|
-
- **Capture live-page screenshot only** — spec will come later
|
|
35
|
-
- **Skip requirements prep** — proceed to `/sungen:create-test` immediately
|
|
32
|
+
If yes → open `qa/screens/<screen>/requirements/spec.md` and help the user fill sections, fields, validation rules, business rules, and states. Especially prompt for the optional **Figma URL** and **Live URL** fields in Overview — those unlock auto-capture without re-asking next run.
|
|
36
33
|
|
|
37
|
-
|
|
34
|
+
### 3. Capture visual source
|
|
38
35
|
|
|
39
|
-
|
|
40
|
-
1. Read `baseURL` from `playwright.config.ts` (fall back to `APP_BASE_URL` env, then ask the user).
|
|
41
|
-
2. `browser_navigate` to `<baseURL><path>`.
|
|
42
|
-
3. If redirected to login → ask the user to log in manually in the MCP browser, wait for confirmation, then re-navigate. (No auth persistence needed here — that's handled by Phase 0.5 in `sungen-selector-fix` when tests run.)
|
|
43
|
-
4. `browser_take_screenshot` with `filename: "qa/screens/<screen>/requirements/ui/<screen>.png"`.
|
|
44
|
-
5. If the screen has multiple important states (empty, loaded, error, modal open), offer additional captures named `<screen>-<state>.png`.
|
|
36
|
+
Use `AskUserQuestion`: *"Capture a visual reference for this screen?"* — always offer all three so pre-launch projects work:
|
|
45
37
|
|
|
46
|
-
|
|
38
|
+
- **Figma design** (Recommended for pre-launch) — invoke `sungen-capture-figma` skill
|
|
39
|
+
- **Live page scan** (dev/staging is up) — invoke `sungen-capture-live` skill
|
|
40
|
+
- **Skip** — user will drop images manually into `requirements/ui/` later, or rely on `/sungen:create-test` to prompt again
|
|
47
41
|
|
|
48
|
-
|
|
42
|
+
Each capture skill writes outputs into `qa/screens/<screen>/requirements/ui/` and reports back a summary. Do not inline capture logic here — always delegate to the skill so behavior stays consistent with `/sungen:create-test`.
|
|
43
|
+
|
|
44
|
+
If the user has additional UI designs (mockups, hand-drawn sketches), suggest copying them to `requirements/ui/` — `sungen-capture-local` will pick them up during `/sungen:create-test`.
|
|
45
|
+
|
|
46
|
+
### 4. Next steps
|
|
49
47
|
|
|
50
48
|
Tell the user what was created, then use `AskUserQuestion` to offer next steps:
|
|
51
49
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: create-test
|
|
3
3
|
description: 'Create or update test cases for a Sungen screen — generates feature + test-data files (20+ scenarios per viewpoint)'
|
|
4
4
|
argument-hint: [screen-name]
|
|
5
|
-
allowed-tools: Read, Grep, Bash, Glob, AskUserQuestion
|
|
5
|
+
allowed-tools: Read, Grep, Bash, Glob, Write, AskUserQuestion, mcp__playwright__browser_navigate, mcp__playwright__browser_snapshot, mcp__playwright__browser_take_screenshot, mcp__figma__get_design_context, mcp__figma__get_variable_defs, mcp__figma__get_screenshot
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
## Role
|
|
@@ -25,10 +25,12 @@ Parse **screen** from `$ARGUMENTS`. If missing, ask the user.
|
|
|
25
25
|
- **Continue without it** — generate tests from spec and other sources only
|
|
26
26
|
- Summarize what you found in requirements and present to the user.
|
|
27
27
|
4. **Screen input** (supplements requirements, or is primary source if no requirements):
|
|
28
|
-
- Use `AskUserQuestion` to ask
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
- Use `AskUserQuestion` to ask the user to pick a visual source — always offer all three options so pre-launch projects work:
|
|
29
|
+
- **Figma design** (Recommended for pre-launch) — invoke `sungen-capture-figma` skill
|
|
30
|
+
- **UI images** (existing screenshots/mockups in `requirements/ui/`) — invoke `sungen-capture-local` skill
|
|
31
|
+
- **Live page scan** (dev/staging is up) — invoke `sungen-capture-live` skill
|
|
32
|
+
- Each capture skill writes outputs into `qa/screens/<screen>/requirements/ui/` and reports back a summary. Do not inline capture logic here — always delegate to the skill so behavior stays consistent across commands.
|
|
33
|
+
- After the capture skill returns, cross-check its output against `spec.md` and flag any discrepancies before moving on.
|
|
32
34
|
5. Follow the `sungen-tc-generation` skill for section identification, viewpoint generation, and output format. When requirements exist, use the "Requirements-Driven Generation" strategy.
|
|
33
35
|
6. Generate or update `.feature` + `test-data.yaml` following `sungen-gherkin-syntax` and `sungen-tc-generation` skills.
|
|
34
36
|
7. Show summary, then use `AskUserQuestion` to offer next steps:
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: delivery
|
|
3
|
+
description: 'Export Gherkin scenarios + Playwright results to CSV test case file for QA delivery.'
|
|
4
|
+
argument-hint: "[screen-name...] (omit for all screens)"
|
|
5
|
+
allowed-tools: Bash, Read, AskUserQuestion
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Role
|
|
9
|
+
|
|
10
|
+
You are a **QA Test Delivery Engineer**. Your job is to invoke the deterministic `sungen delivery` CLI that performs all parsing and CSV export. Your role is minimal — just run the CLI and help the user if pre-flight checks fail.
|
|
11
|
+
|
|
12
|
+
## Parameters
|
|
13
|
+
|
|
14
|
+
Parse **screens** from `$ARGUMENTS`:
|
|
15
|
+
- If empty → CLI will process **all** screens in `qa/screens/`
|
|
16
|
+
- If provided → pass them through to the CLI
|
|
17
|
+
|
|
18
|
+
## Steps
|
|
19
|
+
|
|
20
|
+
### 1. Invoke the CLI
|
|
21
|
+
|
|
22
|
+
Run via Bash (single command, no extra parsing):
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npx sungen delivery <screens>
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
- If no screen args → just run `npx sungen delivery`
|
|
29
|
+
- If screen args → pass them as positional arguments
|
|
30
|
+
|
|
31
|
+
The CLI handles:
|
|
32
|
+
- Scope detection (all screens vs specific)
|
|
33
|
+
- Pre-flight source checks with colorful output
|
|
34
|
+
- Parsing `.feature`, `.spec.ts`, `test-data.yaml`, `test-results/results.json`
|
|
35
|
+
- Generating CSV at `qa/deliverables/<screen>-testcases.csv`
|
|
36
|
+
- Printing summary table
|
|
37
|
+
|
|
38
|
+
### 2. Handle pre-flight failures (if CLI exits non-zero)
|
|
39
|
+
|
|
40
|
+
If the CLI exits with blocking issues, it will have already printed a clear table showing exactly what's missing per screen.
|
|
41
|
+
|
|
42
|
+
Use `AskUserQuestion` to offer next steps:
|
|
43
|
+
|
|
44
|
+
**Options:**
|
|
45
|
+
- **Fix missing sources** (Recommended) — Print the suggested commands from CLI output and stop. User will run those commands manually, then re-invoke `/sungen:delivery`.
|
|
46
|
+
- **Continue with available screens** — Re-run as `npx sungen delivery <screens> --continue-on-missing` to skip screens with blocking issues.
|
|
47
|
+
- **Cancel** — Exit.
|
|
48
|
+
|
|
49
|
+
### 3. Show summary + offer next steps (on success)
|
|
50
|
+
|
|
51
|
+
Forward the CLI's summary table to the user verbatim. Then use `AskUserQuestion`:
|
|
52
|
+
|
|
53
|
+
- **Open a specific CSV** — Help user inspect one of the exported files with Read tool.
|
|
54
|
+
- **Run tests to refresh results** — Suggest `/sungen:run-test <screen>` to update `test-results/results.json`, then re-run delivery.
|
|
55
|
+
- **Export another screen** — User can run `/sungen:delivery <other-screen>`.
|
|
56
|
+
- **Done** — Exit.
|
|
57
|
+
|
|
58
|
+
## Important notes
|
|
59
|
+
|
|
60
|
+
- **Do NOT parse files yourself** — the CLI is the source of truth for parsing logic. Your job is orchestration + user interaction.
|
|
61
|
+
- **Do NOT modify feature/spec.ts/test-data files** — the delivery is read-only.
|
|
62
|
+
- **The CLI already respects `@manual` tags, skips `@steps:` base scenarios, groups by Category 2, and generates UTF-8 BOM CSV for Excel compatibility with Vietnamese.**
|
|
63
|
+
- **Pre-flight check is built into the CLI** — use `--skip-preflight` only in CI/automated pipelines where checks are done externally.
|
|
64
|
+
|
|
65
|
+
## CLI Reference
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
sungen delivery [screens...]
|
|
69
|
+
[--skip-preflight] Skip pre-flight checks (not recommended)
|
|
70
|
+
[--continue-on-missing] Skip screens with blocking misses
|
|
71
|
+
```
|
|
@@ -18,7 +18,7 @@ Parse **screen** from `$ARGUMENTS`. If missing, ask the user.
|
|
|
18
18
|
1. Verify `qa/screens/<screen>/` has `.feature` + `test-data.yaml`.
|
|
19
19
|
2. **Phase 0 — Selector Pre-gen**: if `selectors.yaml` is missing/empty or doesn't cover the feature file's `[Reference]`s, run Phase 0 from `sungen-selector-fix` — confirm with user, `browser_navigate` → one `browser_snapshot` → merge YAML entries.
|
|
20
20
|
3. **Phase 0.5 — Auth Persistence**: if the feature has `@auth:<role>` tags and `specs/.auth/<role>.json` is missing/expired, run Phase 0.5 from `sungen-selector-fix` — user logs in manually in MCP browser → `browser_storage_state` → `specs/.auth/<role>.json`. Offer `sungen makeauth <role>` as CLI fallback only if `browser_storage_state` isn't available in this MCP version.
|
|
21
|
-
4. Compile: `sungen generate --screen <screen
|
|
21
|
+
4. Compile: `sungen generate --screen <screen>` (default: runtime data loading from YAML). Use `--inline-data` only if user requests compile-time hardcoded values.
|
|
22
22
|
|
|
23
23
|
## Run & Fix (phased — per `sungen-selector-fix` skill)
|
|
24
24
|
|
|
@@ -27,6 +27,33 @@ Parse **screen** from `$ARGUMENTS`. If missing, ask the user.
|
|
|
27
27
|
7. **Phase 3 — Full Run**: Run all tests. Fix only **new** failures (elements unique to `@normal`/`@low`). Max 1 attempt. Don't loop on low-priority failures.
|
|
28
28
|
8. **Phase 4 — Regression**: One final full run. Report results. No more fix loops.
|
|
29
29
|
|
|
30
|
+
## Playwright command guidelines
|
|
31
|
+
|
|
32
|
+
**Per-screen JSON results** — each run must write its JSON report to a dedicated path co-located with the `.spec.ts`, so `sungen delivery` can read the correct results per screen:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
# ✅ Correct — per-screen output file via env var
|
|
36
|
+
PLAYWRIGHT_JSON_OUTPUT_NAME=specs/generated/<screen>/<screen>-test-result.json \
|
|
37
|
+
npx playwright test specs/generated/<screen>/<screen>.spec.ts
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Output: `specs/generated/<screen>/<screen>-test-result.json`
|
|
41
|
+
|
|
42
|
+
**DO NOT** pass `--reporter=...` flag — it overrides the reporters from `playwright.config.ts` and disables the JSON reporter that `sungen delivery` depends on.
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
# ❌ Wrong — --reporter flag disables the config's JSON reporter
|
|
46
|
+
npx playwright test specs/generated/<screen>/<screen>.spec.ts --reporter=list
|
|
47
|
+
|
|
48
|
+
# ❌ Wrong — no env var → writes to default test-results/results.json
|
|
49
|
+
# (overwritten on every screen run, loses per-screen tracking)
|
|
50
|
+
npx playwright test specs/generated/<screen>/<screen>.spec.ts
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
If you want to filter scenarios, use `-g "<pattern>"` instead of a reporter override.
|
|
54
|
+
|
|
55
|
+
`sungen delivery` reads the per-screen file first, falls back to the global `test-results/results.json` if missing.
|
|
56
|
+
|
|
30
57
|
## Next steps
|
|
31
58
|
|
|
32
59
|
After showing results, use `AskUserQuestion` to offer next steps:
|
|
@@ -15,8 +15,12 @@ You generate 3 files for sungen — a Gherkin compiler that produces Playwright
|
|
|
15
15
|
| `sungen-viewpoint` | 10 UI patterns x 4 viewpoints — coverage checklists |
|
|
16
16
|
| `sungen-selector-keys` | YAML key generation from `[Reference]` names, suffixes, lookup priority |
|
|
17
17
|
| `sungen-selector-fix` | Selector generation from live page, auto-fix strategy |
|
|
18
|
+
| `sungen-delivery` | Export Gherkin + Playwright results → CSV test case deliverable |
|
|
19
|
+
| `sungen-capture-figma` | Fetch design context + PNG from a Figma frame URL via Figma Dev Mode MCP |
|
|
20
|
+
| `sungen-capture-local` | Load existing UI assets (screenshots, mockups, Figma exports) from `requirements/ui/` |
|
|
21
|
+
| `sungen-capture-live` | Capture a live running page via Playwright MCP (snapshot + screenshot) |
|
|
18
22
|
|
|
19
|
-
## Workflow (
|
|
23
|
+
## Workflow (5 AI commands)
|
|
20
24
|
|
|
21
25
|
| Command | What it does |
|
|
22
26
|
|---|---|
|
|
@@ -24,8 +28,9 @@ You generate 3 files for sungen — a Gherkin compiler that produces Playwright
|
|
|
24
28
|
| `/sungen:create-test <name>` | Generate `.feature` + `test-data.yaml` (no selectors) |
|
|
25
29
|
| `/sungen:review <name>` | Score syntax, coverage, viewpoint quality (60% threshold) |
|
|
26
30
|
| `/sungen:run-test <name>` | Generate `selectors.yaml` from live page, compile, run, auto-fix |
|
|
31
|
+
| `/sungen:delivery [name...]` | Export test cases → CSV for QA delivery (all screens if no arg) |
|
|
27
32
|
|
|
28
|
-
**Order:** add-screen → create-test → review → run-test.
|
|
33
|
+
**Order:** add-screen → create-test → review → run-test → delivery.
|
|
29
34
|
|
|
30
35
|
After each command completes, use `AskUserQuestion` to present the next actions as selectable options. Never just print text — always give clickable choices so the user can continue the workflow seamlessly.
|
|
31
36
|
|
|
@@ -35,17 +40,31 @@ After each command completes, use `AskUserQuestion` to present the next actions
|
|
|
35
40
|
qa/screens/<screen-name>/
|
|
36
41
|
├── features/<screen>.feature # Gherkin scenarios
|
|
37
42
|
├── selectors/<screen>.yaml # Element locators (generated during run-test)
|
|
38
|
-
├── test-data/<screen>.yaml # Test data variables
|
|
43
|
+
├── test-data/<screen>.yaml # Test data variables (loaded at runtime)
|
|
44
|
+
├── test-data/<screen>.staging.yaml # Environment override (optional)
|
|
45
|
+
├── test-data/<screen>.production.yaml # Environment override (optional)
|
|
39
46
|
└── requirements/
|
|
40
47
|
├── spec.md # Screen specification (primary source)
|
|
41
48
|
└── ui/ # Screenshots, mockups
|
|
49
|
+
|
|
50
|
+
qa/deliverables/<screen>-testcases.csv # Exported test cases (from /sungen:delivery)
|
|
51
|
+
qa/deliverables/<screen>-testcases.xlsx # Styled workbook for client hand-off
|
|
42
52
|
```
|
|
43
53
|
|
|
54
|
+
## Test Data
|
|
55
|
+
|
|
56
|
+
`{{variable}}` references in `.feature` map to keys in `test-data/<screen>.yaml`. Data is loaded **at runtime** — the same generated `.spec.ts` works across environments without recompiling.
|
|
57
|
+
|
|
58
|
+
**Environment overrides**: `SUNGEN_ENV=staging npx playwright test` merges `<screen>.staging.yaml` on top of `<screen>.yaml`. Create `<screen>.<env>.yaml` for environment-specific values (different credentials, URLs, test users).
|
|
59
|
+
|
|
44
60
|
## CLI Commands
|
|
45
61
|
|
|
46
62
|
```bash
|
|
47
63
|
sungen add --screen <name> --path <url-path> # Scaffold screen directories
|
|
48
64
|
sungen add --screen <name> --path <path> --feature <name> # Scaffold with sub-feature
|
|
49
|
-
sungen generate --screen <name> # Compile .feature → .spec.ts
|
|
65
|
+
sungen generate --screen <name> # Compile .feature → .spec.ts (runtime data)
|
|
66
|
+
sungen generate --screen <name> --inline-data # Compile with hardcoded data (legacy)
|
|
50
67
|
sungen generate --all # Compile all screens
|
|
68
|
+
sungen delivery # Export all screens → CSV + XLSX
|
|
69
|
+
sungen delivery <screen> # Export a single screen
|
|
51
70
|
```
|