@sun-asterisk/sungen 2.2.3 → 2.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/README.md +6 -6
  2. package/dist/cli/commands/update.d.ts +3 -0
  3. package/dist/cli/commands/update.d.ts.map +1 -0
  4. package/dist/cli/commands/update.js +21 -0
  5. package/dist/cli/commands/update.js.map +1 -0
  6. package/dist/cli/index.js +3 -1
  7. package/dist/cli/index.js.map +1 -1
  8. package/dist/generators/gherkin-parser/index.d.ts +2 -0
  9. package/dist/generators/gherkin-parser/index.d.ts.map +1 -1
  10. package/dist/generators/gherkin-parser/index.js +16 -2
  11. package/dist/generators/gherkin-parser/index.js.map +1 -1
  12. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/attribute-assertion.hbs +3 -0
  13. package/dist/generators/test-generator/adapters/playwright/templates/steps/partials/locator-base.hbs +12 -1
  14. package/dist/generators/test-generator/adapters/playwright/templates/steps/partials/locator.hbs +12 -1
  15. package/dist/generators/test-generator/patterns/assertion-patterns.d.ts.map +1 -1
  16. package/dist/generators/test-generator/patterns/assertion-patterns.js +12 -0
  17. package/dist/generators/test-generator/patterns/assertion-patterns.js.map +1 -1
  18. package/dist/generators/test-generator/patterns/index.d.ts +9 -0
  19. package/dist/generators/test-generator/patterns/index.d.ts.map +1 -1
  20. package/dist/generators/test-generator/patterns/index.js +32 -0
  21. package/dist/generators/test-generator/patterns/index.js.map +1 -1
  22. package/dist/generators/test-generator/patterns/interaction-patterns.d.ts.map +1 -1
  23. package/dist/generators/test-generator/patterns/interaction-patterns.js +0 -13
  24. package/dist/generators/test-generator/patterns/interaction-patterns.js.map +1 -1
  25. package/dist/generators/test-generator/patterns/table-patterns.d.ts.map +1 -1
  26. package/dist/generators/test-generator/patterns/table-patterns.js +8 -5
  27. package/dist/generators/test-generator/patterns/table-patterns.js.map +1 -1
  28. package/dist/orchestrator/ai-rules-updater.d.ts +13 -0
  29. package/dist/orchestrator/ai-rules-updater.d.ts.map +1 -0
  30. package/dist/orchestrator/ai-rules-updater.js +159 -0
  31. package/dist/orchestrator/ai-rules-updater.js.map +1 -0
  32. package/dist/orchestrator/project-initializer.d.ts.map +1 -1
  33. package/dist/orchestrator/project-initializer.js +2 -27
  34. package/dist/orchestrator/project-initializer.js.map +1 -1
  35. package/dist/orchestrator/screen-manager.d.ts +1 -0
  36. package/dist/orchestrator/screen-manager.d.ts.map +1 -1
  37. package/dist/orchestrator/screen-manager.js +70 -3
  38. package/dist/orchestrator/screen-manager.js.map +1 -1
  39. package/dist/orchestrator/templates/ai-instructions/claude-cmd-add-screen.md +18 -9
  40. package/dist/orchestrator/templates/ai-instructions/claude-cmd-make-tc.md +12 -4
  41. package/dist/orchestrator/templates/ai-instructions/claude-cmd-make-test.md +9 -11
  42. package/dist/orchestrator/templates/ai-instructions/claude-skill-gherkin-review.md +228 -0
  43. package/dist/orchestrator/templates/ai-instructions/claude-skill-gherkin-syntax.md +30 -11
  44. package/dist/orchestrator/templates/ai-instructions/claude-skill-selector-fix.md +91 -25
  45. package/dist/orchestrator/templates/ai-instructions/claude-skill-tc-generation.md +92 -71
  46. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-add-screen.md +13 -5
  47. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-make-tc.md +13 -4
  48. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-make-test.md +9 -11
  49. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-gherkin-review.md +228 -0
  50. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-gherkin-syntax.md +30 -11
  51. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-selector-fix.md +72 -31
  52. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-tc-generation.md +92 -72
  53. package/dist/orchestrator/templates/readme.md +13 -8
  54. package/package.json +1 -1
  55. package/src/cli/commands/update.ts +18 -0
  56. package/src/cli/index.ts +3 -1
  57. package/src/generators/gherkin-parser/index.ts +19 -2
  58. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/attribute-assertion.hbs +3 -0
  59. package/src/generators/test-generator/adapters/playwright/templates/steps/partials/locator-base.hbs +12 -1
  60. package/src/generators/test-generator/adapters/playwright/templates/steps/partials/locator.hbs +12 -1
  61. package/src/generators/test-generator/patterns/assertion-patterns.ts +13 -0
  62. package/src/generators/test-generator/patterns/index.ts +41 -0
  63. package/src/generators/test-generator/patterns/interaction-patterns.ts +0 -14
  64. package/src/generators/test-generator/patterns/table-patterns.ts +8 -5
  65. package/src/orchestrator/ai-rules-updater.ts +141 -0
  66. package/src/orchestrator/project-initializer.ts +2 -32
  67. package/src/orchestrator/screen-manager.ts +72 -3
  68. package/src/orchestrator/templates/ai-instructions/claude-cmd-add-screen.md +18 -9
  69. package/src/orchestrator/templates/ai-instructions/claude-cmd-make-tc.md +12 -4
  70. package/src/orchestrator/templates/ai-instructions/claude-cmd-make-test.md +9 -11
  71. package/src/orchestrator/templates/ai-instructions/claude-skill-gherkin-review.md +228 -0
  72. package/src/orchestrator/templates/ai-instructions/claude-skill-gherkin-syntax.md +30 -11
  73. package/src/orchestrator/templates/ai-instructions/claude-skill-selector-fix.md +91 -25
  74. package/src/orchestrator/templates/ai-instructions/claude-skill-tc-generation.md +92 -71
  75. package/src/orchestrator/templates/ai-instructions/copilot-cmd-add-screen.md +13 -5
  76. package/src/orchestrator/templates/ai-instructions/copilot-cmd-make-tc.md +13 -4
  77. package/src/orchestrator/templates/ai-instructions/copilot-cmd-make-test.md +9 -11
  78. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-gherkin-review.md +228 -0
  79. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-gherkin-syntax.md +30 -11
  80. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-selector-fix.md +72 -31
  81. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-tc-generation.md +92 -72
  82. package/src/orchestrator/templates/readme.md +13 -8
  83. package/docs/gherkin standards/gherkin-core-standard.md +0 -431
  84. package/docs/gherkin standards/gherkin-core-standard.vi.md +0 -399
  85. package/docs/gherkin-dictionary.md +0 -1126
  86. package/docs/makeauth.md +0 -225
@@ -203,20 +203,6 @@ export const interactionPatterns: StepPattern[] = [
203
203
  },
204
204
  priority: 8,
205
205
  },
206
- {
207
- name: 'press-enter',
208
- matcher: (step: ParsedStep) =>
209
- step.text.includes('presses') && step.text.includes('Enter') && !!step.selectorRef,
210
- resolver: (step, context) => {
211
- const resolved = context.selectorResolver.resolveSelector(step.selectorRef!, undefined, step.elementType, step.nth);
212
- return {
213
- templateName: 'press-action',
214
- data: { ...resolved, key: 'Enter' },
215
- comment: `Press Enter in ${step.selectorRef}`,
216
- };
217
- },
218
- priority: 9,
219
- },
220
206
  {
221
207
  name: 'click-by-data-text',
222
208
  matcher: (step: ParsedStep) =>
@@ -6,11 +6,12 @@
6
6
  import { StepPattern } from './types';
7
7
 
8
8
  export const tablePatterns: StepPattern[] = [
9
- // "User see [Users] table has {{count}} rows" — must have "rows" AFTER {{data}}
9
+ // "User see [Users] table with {{count}} rows" (preferred)
10
+ // Also accepts: "User see [Users] table has {{count}} rows" (backward compat)
10
11
  {
11
12
  name: 'table-row-count',
12
13
  matcher: (step) => {
13
- return /\btable\s+has\b/i.test(step.text) &&
14
+ return /\btable\s+(?:has|with)\b/i.test(step.text) &&
14
15
  /\}\}\s*rows?\b/i.test(step.text) &&
15
16
  !!step.dataRef;
16
17
  },
@@ -29,7 +30,8 @@ export const tablePatterns: StepPattern[] = [
29
30
  priority: 16,
30
31
  },
31
32
 
32
- // "User see [Users] table has [Email] column"
33
+ // "User see [Users] table has [Email] column" (backward compat)
34
+ // Preferred: "User see [Email] column in [Users] table" (parent scoping)
33
35
  {
34
36
  name: 'table-column-exists',
35
37
  matcher: (step) => {
@@ -152,11 +154,12 @@ export const tablePatterns: StepPattern[] = [
152
154
  priority: 17,
153
155
  },
154
156
 
155
- // "User see [Users] table has row with {{name}}"
157
+ // "User see [Users] table row with {{name}}" (preferred)
158
+ // Also accepts: "User see [Users] table has row with {{name}}" (backward compat)
156
159
  {
157
160
  name: 'table-row-exists',
158
161
  matcher: (step) => {
159
- return /\btable\s+has\s+row\s+with\b/i.test(step.text) && !!step.dataRef;
162
+ return /\btable\s+(?:has\s+)?row\s+with\b/i.test(step.text) && !!step.dataRef;
160
163
  },
161
164
  resolver: (step, context) => {
162
165
  const resolved = context.selectorResolver.resolveSelector(
@@ -0,0 +1,141 @@
1
+ /**
2
+ * AI Rules Updater
3
+ * Updates AI rules, commands, and skills from bundled templates.
4
+ * Used by `sungen update` command.
5
+ */
6
+
7
+ import * as fs from 'fs';
8
+ import * as path from 'path';
9
+
10
+ // File mapping: [templateFile, outputPath]
11
+ // Shared with project-initializer.ts
12
+ export const AI_RULES_FILE_MAPPING: [string, string][] = [
13
+ // Config
14
+ ['claude-config.md', 'CLAUDE.md'],
15
+ ['copilot-config.md', '.github/copilot-instructions.md'],
16
+
17
+ // Commands — Claude Code
18
+ ['claude-cmd-add-screen.md', '.claude/commands/sungen/add-screen.md'],
19
+ ['claude-cmd-make-tc.md', '.claude/commands/sungen/make-tc.md'],
20
+ ['claude-cmd-make-test.md', '.claude/commands/sungen/make-test.md'],
21
+
22
+ // Commands — GitHub Copilot
23
+ ['copilot-cmd-add-screen.md', '.github/prompts/sungen-add-screen.prompt.md'],
24
+ ['copilot-cmd-make-tc.md', '.github/prompts/sungen-make-tc.prompt.md'],
25
+ ['copilot-cmd-make-test.md', '.github/prompts/sungen-make-test.prompt.md'],
26
+
27
+ // Skills — Claude Code
28
+ ['claude-skill-gherkin-syntax.md', '.claude/skills/sungen-gherkin-syntax/SKILL.md'],
29
+ ['claude-skill-selector-keys.md', '.claude/skills/sungen-selector-keys/SKILL.md'],
30
+ ['claude-skill-error-mapping.md', '.claude/skills/sungen-error-mapping/SKILL.md'],
31
+ ['claude-skill-tc-generation.md', '.claude/skills/sungen-tc-generation/SKILL.md'],
32
+ ['claude-skill-selector-fix.md', '.claude/skills/sungen-selector-fix/SKILL.md'],
33
+ ['claude-skill-gherkin-review.md', '.claude/skills/sungen-gherkin-review/SKILL.md'],
34
+
35
+ // Skills — GitHub Copilot
36
+ ['github-skill-sungen-gherkin-syntax.md', '.github/skills/sungen-gherkin-syntax/SKILL.md'],
37
+ ['github-skill-sungen-selector-keys.md', '.github/skills/sungen-selector-keys/SKILL.md'],
38
+ ['github-skill-sungen-error-mapping.md', '.github/skills/sungen-error-mapping/SKILL.md'],
39
+ ['github-skill-sungen-tc-generation.md', '.github/skills/sungen-tc-generation/SKILL.md'],
40
+ ['github-skill-sungen-selector-fix.md', '.github/skills/sungen-selector-fix/SKILL.md'],
41
+ ['github-skill-sungen-gherkin-review.md', '.github/skills/sungen-gherkin-review/SKILL.md'],
42
+ ];
43
+
44
+ export class AIRulesUpdater {
45
+ private cwd: string;
46
+ private aiTemplateDir: string;
47
+
48
+ constructor(cwd: string) {
49
+ this.cwd = cwd;
50
+ this.aiTemplateDir = path.join(__dirname, 'templates', 'ai-instructions');
51
+ }
52
+
53
+ async update(dryRun: boolean): Promise<void> {
54
+ console.log('🔄 Updating AI rules, commands, and skills...\n');
55
+
56
+ const updated: string[] = [];
57
+ const created: string[] = [];
58
+ const unchanged: string[] = [];
59
+ const missing: string[] = [];
60
+
61
+ for (const [templateFile, outputRelPath] of AI_RULES_FILE_MAPPING) {
62
+ const templatePath = path.join(this.aiTemplateDir, templateFile);
63
+ const outputPath = path.join(this.cwd, outputRelPath);
64
+
65
+ if (!fs.existsSync(templatePath)) {
66
+ missing.push(templateFile);
67
+ continue;
68
+ }
69
+
70
+ const newContent = fs.readFileSync(templatePath, 'utf-8');
71
+
72
+ if (fs.existsSync(outputPath)) {
73
+ const currentContent = fs.readFileSync(outputPath, 'utf-8');
74
+ if (currentContent === newContent) {
75
+ unchanged.push(outputRelPath);
76
+ continue;
77
+ }
78
+
79
+ if (!dryRun) {
80
+ fs.writeFileSync(outputPath, newContent, 'utf-8');
81
+ }
82
+ updated.push(outputRelPath);
83
+ } else {
84
+ if (!dryRun) {
85
+ const outputDir = path.dirname(outputPath);
86
+ if (!fs.existsSync(outputDir)) {
87
+ fs.mkdirSync(outputDir, { recursive: true });
88
+ }
89
+ fs.writeFileSync(outputPath, newContent, 'utf-8');
90
+ }
91
+ created.push(outputRelPath);
92
+ }
93
+ }
94
+
95
+ // Print results
96
+ if (dryRun) {
97
+ console.log('📋 Dry run — no files changed\n');
98
+ }
99
+
100
+ if (updated.length > 0) {
101
+ console.log(`✏️ Updated (${updated.length}):`);
102
+ for (const f of updated) {
103
+ console.log(` ${f}`);
104
+ }
105
+ console.log();
106
+ }
107
+
108
+ if (created.length > 0) {
109
+ console.log(`✨ Created (${created.length}):`);
110
+ for (const f of created) {
111
+ console.log(` ${f}`);
112
+ }
113
+ console.log();
114
+ }
115
+
116
+ if (unchanged.length > 0) {
117
+ console.log(`✅ Already up to date (${unchanged.length}):`);
118
+ for (const f of unchanged) {
119
+ console.log(` ${f}`);
120
+ }
121
+ console.log();
122
+ }
123
+
124
+ if (missing.length > 0) {
125
+ console.log(`⚠️ Template not found (${missing.length}):`);
126
+ for (const f of missing) {
127
+ console.log(` ${f}`);
128
+ }
129
+ console.log();
130
+ }
131
+
132
+ const totalChanges = updated.length + created.length;
133
+ if (totalChanges === 0) {
134
+ console.log('All AI rules are up to date. No changes needed.');
135
+ } else if (dryRun) {
136
+ console.log(`${totalChanges} file(s) would be changed. Run without --dry-run to apply.`);
137
+ } else {
138
+ console.log(`${totalChanges} file(s) updated successfully.`);
139
+ }
140
+ }
141
+ }
@@ -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;
@@ -250,38 +251,7 @@ export class ProjectInitializer {
250
251
  private createAIRules(): void {
251
252
  const aiTemplateDir = path.join(__dirname, 'templates', 'ai-instructions');
252
253
 
253
- // File mapping: [templateFile, outputPath]
254
- const fileMapping: [string, string][] = [
255
- // Config
256
- ['claude-config.md', 'CLAUDE.md'],
257
- ['copilot-config.md', '.github/copilot-instructions.md'],
258
-
259
- // Commands — Claude Code
260
- ['claude-cmd-add-screen.md', '.claude/commands/sungen/add-screen.md'],
261
- ['claude-cmd-make-tc.md', '.claude/commands/sungen/make-tc.md'],
262
- ['claude-cmd-make-test.md', '.claude/commands/sungen/make-test.md'],
263
-
264
- // Commands — GitHub Copilot
265
- ['copilot-cmd-add-screen.md', '.github/prompts/sungen-add-screen.prompt.md'],
266
- ['copilot-cmd-make-tc.md', '.github/prompts/sungen-make-tc.prompt.md'],
267
- ['copilot-cmd-make-test.md', '.github/prompts/sungen-make-test.prompt.md'],
268
-
269
- // Skills — Claude Code
270
- ['claude-skill-gherkin-syntax.md', '.claude/skills/sungen-gherkin-syntax/SKILL.md'],
271
- ['claude-skill-selector-keys.md', '.claude/skills/sungen-selector-keys/SKILL.md'],
272
- ['claude-skill-error-mapping.md', '.claude/skills/sungen-error-mapping/SKILL.md'],
273
- ['claude-skill-tc-generation.md', '.claude/skills/sungen-tc-generation/SKILL.md'],
274
- ['claude-skill-selector-fix.md', '.claude/skills/sungen-selector-fix/SKILL.md'],
275
-
276
- // Skills — GitHub Copilot (separate copies with Copilot-friendly descriptions)
277
- ['github-skill-sungen-gherkin-syntax.md', '.github/skills/sungen-gherkin-syntax/SKILL.md'],
278
- ['github-skill-sungen-selector-keys.md', '.github/skills/sungen-selector-keys/SKILL.md'],
279
- ['github-skill-sungen-error-mapping.md', '.github/skills/sungen-error-mapping/SKILL.md'],
280
- ['github-skill-sungen-tc-generation.md', '.github/skills/sungen-tc-generation/SKILL.md'],
281
- ['github-skill-sungen-selector-fix.md', '.github/skills/sungen-selector-fix/SKILL.md'],
282
- ];
283
-
284
- for (const [templateFile, outputRelPath] of fileMapping) {
254
+ for (const [templateFile, outputRelPath] of AI_RULES_FILE_MAPPING) {
285
255
  const outputPath = path.join(this.cwd, outputRelPath);
286
256
 
287
257
  if (fs.existsSync(outputPath)) {
@@ -47,6 +47,8 @@ export class ScreenManager {
47
47
  const featuresDir = path.join(screenDir, 'features');
48
48
  const selectorsDir = path.join(screenDir, 'selectors');
49
49
  const testDataDir = path.join(screenDir, 'test-data');
50
+ const requirementsDir = path.join(screenDir, 'requirements');
51
+ const requirementsUiDir = path.join(requirementsDir, 'ui');
50
52
 
51
53
  // File paths
52
54
  const featurePath = path.join(featuresDir, `${filename}.feature`);
@@ -66,6 +68,7 @@ export class ScreenManager {
66
68
  fs.mkdirSync(featuresDir, { recursive: true });
67
69
  fs.mkdirSync(selectorsDir, { recursive: true });
68
70
  fs.mkdirSync(testDataDir, { recursive: true });
71
+ fs.mkdirSync(requirementsUiDir, { recursive: true });
69
72
  } catch (error) {
70
73
  console.error(`Error: Failed to create directories`);
71
74
  console.error(` ${error instanceof Error ? error.message : String(error)}`);
@@ -111,15 +114,27 @@ export class ScreenManager {
111
114
  ].join('\n'), 'utf-8');
112
115
  }
113
116
 
117
+ // Generate requirements spec.md (only on first screen creation)
118
+ const specPath = path.join(requirementsDir, 'spec.md');
119
+ if (!fs.existsSync(specPath)) {
120
+ fs.writeFileSync(specPath, this.generateSpecTemplate(options, screenName), 'utf-8');
121
+ }
122
+
114
123
  // Display success
115
124
  console.log(`Created files:`);
116
125
  console.log(` ${path.relative(this.cwd, featurePath)}`);
117
126
  console.log(` ${path.relative(this.cwd, selectorPath)}`);
118
- console.log(` ${path.relative(this.cwd, testDataPath)}\n`);
127
+ console.log(` ${path.relative(this.cwd, testDataPath)}`);
128
+ if (isFirstFile) {
129
+ console.log(` ${path.relative(this.cwd, specPath)}`);
130
+ console.log(` ${path.relative(this.cwd, requirementsUiDir)}/`);
131
+ }
132
+ console.log('');
119
133
 
120
134
  console.log('Next steps:');
121
- console.log(` 1. Use AI (Copilot/Claude) to generate Gherkin + selectors from the live page`);
122
- console.log(` 2. Fill in test-data values`);
135
+ console.log(` 1. Fill requirements/spec.md with screen spec (fields, validation, business rules)`);
136
+ console.log(` Optionally add UI designs to requirements/ui/ (screenshots, mockups)`);
137
+ console.log(` 2. Generate test cases: /sungen:make-tc ${screenName} (or /sungen-make-tc)`);
123
138
  console.log(` 3. Compile: sungen generate --screen ${screenName}`);
124
139
  console.log(` 4. Run: npx playwright test\n`);
125
140
  }
@@ -150,6 +165,60 @@ export class ScreenManager {
150
165
  return this.normalizeScreenName(lastSegment);
151
166
  }
152
167
 
168
+ private generateSpecTemplate(options: ScreenOptions, screenName: string): string {
169
+ const pagePath = options.path || `/${screenName}`;
170
+ return `# ${options.name} Screen Specification
171
+
172
+ ## Overview
173
+ - **URL Path:** ${pagePath}
174
+ - **Auth Required:** no
175
+ - **Platform:** web
176
+
177
+ ## Sections
178
+
179
+ ### Section: [Section Name]
180
+ - **Type:** form | table | list | card | tabs | modal | search | navigation
181
+ - **Description:** [Brief description of this section]
182
+
183
+ #### Fields
184
+ <!-- Remove this table if section has no input fields -->
185
+ | Field | Type | Required | Constraints | Default |
186
+ |-------|------|----------|-------------|---------|
187
+ | [Field Name] | input (text) | yes | max 255 | — |
188
+
189
+ #### Actions
190
+ | Action | Element | Behavior |
191
+ |--------|---------|----------|
192
+ | [Action Name] | button | [What happens on click] |
193
+
194
+ #### Validation Rules
195
+ <!-- Exact error messages help AI generate accurate assertions -->
196
+ | Condition | Error Message |
197
+ |-----------|---------------|
198
+ | Empty required field | "[Exact error message from UI]" |
199
+
200
+ #### States
201
+ | State | Condition | Visual |
202
+ |-------|-----------|--------|
203
+ | Default | Page load | [Default appearance] |
204
+ | Loading | After submit | [Loading indicator] |
205
+ | Error | Validation fail | [Error appearance] |
206
+ | Success | Action complete | [Success behavior] |
207
+
208
+ ## Business Rules
209
+ <!-- Rules that affect test logic: limits, permissions, conditions -->
210
+ - [Rule 1]
211
+
212
+ ## Accessibility
213
+ <!-- Tab order, aria-labels, screen reader behavior -->
214
+ - Tab order: [field1] → [field2] → [submit]
215
+
216
+ ## Notes
217
+ <!-- Edge cases, known issues, environment-specific behavior -->
218
+ - [Note 1]
219
+ `;
220
+ }
221
+
153
222
  private generateFeatureTemplate(options: ScreenOptions, filename: string): string {
154
223
  const screenName = this.normalizeScreenName(options.name);
155
224
  const featurePath = options.path || `/${screenName}`;
@@ -25,19 +25,28 @@ Run:
25
25
  sungen add --screen <screen> --path <path>
26
26
  ```
27
27
 
28
- ### 2. Create test cases
28
+ ### 2. Fill requirements (recommended)
29
+
30
+ Ask the user: "Would you like to fill in `requirements/spec.md` now? This helps generate higher quality test cases."
31
+
32
+ - If yes → open `qa/screens/<screen>/requirements/spec.md` and help the user fill sections, fields, validation rules, business rules, and states.
33
+ - If they have UI designs (screenshots, Figma exports, mockups) → suggest copying them to `requirements/ui/`.
34
+ - If no → proceed to step 3.
35
+
36
+ ### 3. Create test cases
29
37
 
30
38
  Ask the user: "Would you like to create test cases now?"
31
39
 
32
- If yes, delegate to `/sungen:make-tc <screen>` to handle:
33
- - Exploring the live page or analyzing static designs
34
- - Gathering test viewpoints (UI/UX, Validation, Logic, Security)
35
- - Generating the 3 files (feature, selectors, test-data)
40
+ If yes **you MUST use the Skill tool** to invoke `/sungen:make-tc <screen>`. This is critical because `make-tc` auto-loads the `sungen-gherkin-syntax` and `sungen-tc-generation` skills which contain the full Gherkin syntax rules, pattern shapes, viewpoint checklists, and output format. **Do NOT attempt to generate test cases yourself** — always invoke the Skill tool so these skills are properly loaded.
41
+
42
+ ```
43
+ Skill: make-tc
44
+ Args: <screen>
45
+ ```
36
46
 
37
- ### 3. Confirm
47
+ ### 4. Confirm
38
48
 
39
- Tell the user what was created and next steps:
40
- - If the page requires authentication, the user will be asked to log in via the MCP browser during `/sungen:make-tc`
41
- - Edit the generated files as needed
49
+ If the user declined test case creation, tell them next steps:
50
+ - Fill `requirements/spec.md` with screen specs (if not done)
42
51
  - Run `/sungen:make-tc <screen>` to create test cases
43
52
  - Run `/sungen:make-test <screen>` to generate selectors, compile, and run tests
@@ -17,9 +17,17 @@ Parse **screen** from `$ARGUMENTS`. If missing, ask the user.
17
17
 
18
18
  1. Verify `qa/screens/<screen>/` exists. If not → `/sungen:add-screen` first.
19
19
  2. Check if `.feature` file already has scenarios. If yes → use `AskUserQuestion` to ask the update mode (see `sungen-tc-generation` skill for details). If no → fresh creation.
20
- 3. Use `AskUserQuestion` to ask: **Live page** (explore via Playwright MCP) or **Static designs** (screenshots, Figma)? Explore accordingly (see CLAUDE.md for MCP rules).
21
- 4. Follow the `sungen-tc-generation` skill for section identification, viewpoint generation, and output format.
22
- 5. Generate or update `.feature` + `test-data.yaml` following `sungen-gherkin-syntax` and `sungen-tc-generation` skills.
23
- 6. Show summary next: `/sungen:make-test <screen>`
20
+ 3. **Read requirements** check `qa/screens/<screen>/requirements/`:
21
+ - If `spec.md` exists read it as PRIMARY source (sections, fields, validation rules, business rules, states).
22
+ - If `ui/` has images read them for visual context (layout, element positions, states).
23
+ - If `notes.md` existsread for edge cases and additional context.
24
+ - Summarize what you found in requirements and present to the user.
25
+ 4. **Explore page** (supplements requirements, or is primary source if no requirements):
26
+ - Use `AskUserQuestion` to ask: **Live page** (explore via Playwright MCP) or **Static designs** (screenshots, Figma)? Or **Skip** (if requirements are sufficient)?
27
+ - If exploring, verify and supplement requirements — flag any discrepancies found.
28
+ 5. Follow the `sungen-tc-generation` skill for section identification, viewpoint generation, and output format. When requirements exist, use the "Requirements-Driven Generation" strategy.
29
+ 6. Generate or update `.feature` + `test-data.yaml` following `sungen-gherkin-syntax` and `sungen-tc-generation` skills.
30
+ 7. **Self-review** — re-read the `.feature` file and apply the full **`sungen-gherkin-review` skill**: assertion quality rules (4 rules), action-result coherence (5 rules), and the 9-point quality checklist. **Auto-fix any issues found**, then re-read to verify.
31
+ 8. Show summary → next: `/sungen:make-test <screen>`
24
32
 
25
33
  **No selectors.yaml** — selectors are generated during `/sungen:make-test`.
@@ -16,16 +16,14 @@ Parse **screen** from `$ARGUMENTS`. If missing, ask the user.
16
16
  ## Steps
17
17
 
18
18
  1. Verify `qa/screens/<screen>/` has `.feature` + `test-data.yaml`. If not → `/sungen:make-tc` first.
19
- 2. Generate `selectors.yaml` from live page using `sungen-selector-fix` and `sungen-selector-keys` skills.
20
- 3. Compile: `sungen generate --screen <screen>`
21
- 4. **Initial run** run ALL tests to get the full failure picture:
22
- `npx playwright test specs/generated/<screen>/<screen>.spec.ts --reporter=line`
23
- 5. **Batched fix loop** (max 5 attempts) — see `sungen-selector-fix` skill for details:
24
- - Group failures by root cause (same selector, same error type)
25
- - Fix selectors/test-data for the current batch
26
- - Recompile, then re-run ONLY the previously-failing tests (max 20 at a time via `--grep`)
27
- - If the batch passes, pick the next batch of remaining failures
28
- - Repeat until no failures remain or max attempts reached
29
- 6. **Final confirmation** — run ALL tests once to ensure no regressions.
19
+ 2. **Generate selectors** explore live page via MCP, build `selectors.yaml` using `sungen-selector-fix` and `sungen-selector-keys` skills.
20
+ 3. **Proactive validation** — verify EVERY selector against the live page using `browser_snapshot` + `browser_evaluate` BEFORE running any test. Fix mismatches immediately. See `sungen-selector-fix` skill "Proactive Selector Validation" section. Target: 80%+ issues fixed before first run.
21
+ 4. **Compile**: `sungen generate --screen <screen>`
22
+ 5. **Batched test run** — run tests in batches of 20 via `--grep`:
23
+ `npx playwright test specs/generated/<screen>/*.spec.ts --grep "VP-UI-001|...|VP-UI-020" --reporter=line`
24
+ - If failures in batch → group by root cause, fix, recompile, re-run only failing tests
25
+ - If batch passes move to next 20 tests
26
+ - Max 5 fix attempts per batch
27
+ 6. **Final confirmation** run ALL tests once to catch regressions.
30
28
  7. After 5 fix attempts still failing → ask user about direct `.spec.ts` fix.
31
29
  8. Show: pass/fail, attempt count, files changed.