@sun-asterisk/sungen 3.2.4 → 3.2.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.
Files changed (102) hide show
  1. package/dist/cli/commands/dashboard.js +2 -2
  2. package/dist/cli/commands/dashboard.js.map +1 -1
  3. package/dist/cli/commands/delivery.d.ts.map +1 -1
  4. package/dist/cli/commands/delivery.js +22 -5
  5. package/dist/cli/commands/delivery.js.map +1 -1
  6. package/dist/dashboard/snapshot-builder.d.ts +3 -0
  7. package/dist/dashboard/snapshot-builder.d.ts.map +1 -1
  8. package/dist/dashboard/snapshot-builder.js +47 -19
  9. package/dist/dashboard/snapshot-builder.js.map +1 -1
  10. package/dist/dashboard/templates/index.html +4 -4
  11. package/dist/dashboard/types.d.ts +4 -0
  12. package/dist/dashboard/types.d.ts.map +1 -1
  13. package/dist/exporters/api-testcase-formatter.d.ts +55 -0
  14. package/dist/exporters/api-testcase-formatter.d.ts.map +1 -0
  15. package/dist/exporters/api-testcase-formatter.js +304 -0
  16. package/dist/exporters/api-testcase-formatter.js.map +1 -0
  17. package/dist/exporters/csv-exporter.d.ts +13 -1
  18. package/dist/exporters/csv-exporter.d.ts.map +1 -1
  19. package/dist/exporters/csv-exporter.js +44 -28
  20. package/dist/exporters/csv-exporter.js.map +1 -1
  21. package/dist/exporters/feature-parser.d.ts +6 -0
  22. package/dist/exporters/feature-parser.d.ts.map +1 -1
  23. package/dist/exporters/feature-parser.js +9 -3
  24. package/dist/exporters/feature-parser.js.map +1 -1
  25. package/dist/exporters/json-exporter.d.ts.map +1 -1
  26. package/dist/exporters/json-exporter.js +58 -48
  27. package/dist/exporters/json-exporter.js.map +1 -1
  28. package/dist/exporters/result-variants.d.ts +29 -0
  29. package/dist/exporters/result-variants.d.ts.map +1 -0
  30. package/dist/exporters/result-variants.js +33 -0
  31. package/dist/exporters/result-variants.js.map +1 -0
  32. package/dist/exporters/types.d.ts +7 -0
  33. package/dist/exporters/types.d.ts.map +1 -1
  34. package/dist/exporters/xlsx-exporter.d.ts.map +1 -1
  35. package/dist/exporters/xlsx-exporter.js +45 -13
  36. package/dist/exporters/xlsx-exporter.js.map +1 -1
  37. package/dist/generators/test-generator/adapters/appium/templates/scenario.hbs +1 -1
  38. package/dist/generators/test-generator/adapters/playwright/templates/scenario.hbs +6 -6
  39. package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/expand-action.hbs +30 -8
  40. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/selected-assertion.hbs +16 -1
  41. package/dist/generators/test-generator/patterns/expect-patterns.d.ts.map +1 -1
  42. package/dist/generators/test-generator/patterns/expect-patterns.js +23 -0
  43. package/dist/generators/test-generator/patterns/expect-patterns.js.map +1 -1
  44. package/dist/generators/test-generator/patterns/index.d.ts +12 -0
  45. package/dist/generators/test-generator/patterns/index.d.ts.map +1 -1
  46. package/dist/generators/test-generator/patterns/index.js +21 -1
  47. package/dist/generators/test-generator/patterns/index.js.map +1 -1
  48. package/dist/generators/test-generator/utils/selector-resolver.d.ts +7 -0
  49. package/dist/generators/test-generator/utils/selector-resolver.d.ts.map +1 -1
  50. package/dist/generators/test-generator/utils/selector-resolver.js +13 -2
  51. package/dist/generators/test-generator/utils/selector-resolver.js.map +1 -1
  52. package/dist/orchestrator/project-initializer.d.ts +23 -0
  53. package/dist/orchestrator/project-initializer.d.ts.map +1 -1
  54. package/dist/orchestrator/project-initializer.js +118 -3
  55. package/dist/orchestrator/project-initializer.js.map +1 -1
  56. package/dist/orchestrator/templates/ai-src/commands/add-api.md +76 -0
  57. package/dist/orchestrator/templates/ai-src/commands/create-test.md +2 -2
  58. package/dist/orchestrator/templates/ai-src/config/codex.md +3 -2
  59. package/dist/orchestrator/templates/ai-src/skills/sungen-api-coverage-model/SKILL.md +73 -0
  60. package/dist/orchestrator/templates/ai-src/skills/sungen-api-design/SKILL.md +42 -8
  61. package/dist/orchestrator/templates/ai-src/skills/sungen-gherkin-syntax/SKILL.md +21 -0
  62. package/dist/orchestrator/templates/ai-src/skills/sungen-selector-fix/SKILL.md +2 -0
  63. package/dist/orchestrator/templates/ai-src/skills/sungen-selector-keys/SKILL.md +33 -0
  64. package/dist/orchestrator/templates/ai-src/skills/sungen-tc-review/SKILL.md +6 -0
  65. package/dist/orchestrator/templates/specs-api.d.ts +26 -0
  66. package/dist/orchestrator/templates/specs-api.d.ts.map +1 -1
  67. package/dist/orchestrator/templates/specs-api.js +131 -3
  68. package/dist/orchestrator/templates/specs-api.js.map +1 -1
  69. package/dist/orchestrator/templates/specs-api.ts +118 -5
  70. package/dist/orchestrator/templates/specs-test-data.ts +20 -1
  71. package/package.json +4 -3
  72. package/src/cli/commands/dashboard.ts +2 -2
  73. package/src/cli/commands/delivery.ts +24 -6
  74. package/src/dashboard/snapshot-builder.ts +46 -19
  75. package/src/dashboard/templates/index.html +4 -4
  76. package/src/dashboard/types.ts +5 -1
  77. package/src/exporters/api-testcase-formatter.ts +325 -0
  78. package/src/exporters/csv-exporter.ts +55 -27
  79. package/src/exporters/feature-parser.ts +8 -2
  80. package/src/exporters/json-exporter.ts +56 -47
  81. package/src/exporters/result-variants.ts +47 -0
  82. package/src/exporters/types.ts +7 -0
  83. package/src/exporters/xlsx-exporter.ts +48 -13
  84. package/src/generators/test-generator/adapters/appium/templates/scenario.hbs +1 -1
  85. package/src/generators/test-generator/adapters/playwright/templates/scenario.hbs +6 -6
  86. package/src/generators/test-generator/adapters/playwright/templates/steps/actions/expand-action.hbs +30 -8
  87. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/selected-assertion.hbs +16 -1
  88. package/src/generators/test-generator/patterns/expect-patterns.ts +23 -0
  89. package/src/generators/test-generator/patterns/index.ts +21 -1
  90. package/src/generators/test-generator/utils/selector-resolver.ts +30 -2
  91. package/src/orchestrator/project-initializer.ts +120 -3
  92. package/src/orchestrator/templates/ai-src/commands/add-api.md +76 -0
  93. package/src/orchestrator/templates/ai-src/commands/create-test.md +2 -2
  94. package/src/orchestrator/templates/ai-src/config/codex.md +3 -2
  95. package/src/orchestrator/templates/ai-src/skills/sungen-api-coverage-model/SKILL.md +73 -0
  96. package/src/orchestrator/templates/ai-src/skills/sungen-api-design/SKILL.md +42 -8
  97. package/src/orchestrator/templates/ai-src/skills/sungen-gherkin-syntax/SKILL.md +21 -0
  98. package/src/orchestrator/templates/ai-src/skills/sungen-selector-fix/SKILL.md +2 -0
  99. package/src/orchestrator/templates/ai-src/skills/sungen-selector-keys/SKILL.md +33 -0
  100. package/src/orchestrator/templates/ai-src/skills/sungen-tc-review/SKILL.md +6 -0
  101. package/src/orchestrator/templates/specs-api.ts +118 -5
  102. package/src/orchestrator/templates/specs-test-data.ts +20 -1
@@ -44,6 +44,9 @@ const DEFAULT_BASE_LOCALE = 'vi';
44
44
 
45
45
  export interface DashboardTarget {
46
46
  name: string;
47
+ kind: 'screen' | 'flow' | 'api';
48
+ /** Derived convenience (`kind === 'flow'`) — kept for the flow-specific
49
+ * branches that predate the api tier. */
47
50
  isFlow: boolean;
48
51
  }
49
52
 
@@ -134,7 +137,9 @@ function buildOneScreen(
134
137
  // For mobile, per-OS features flatten here so the Compare view can key each
135
138
  // scenario by (tcId, platform) via its OS-precise testEnvironment.
136
139
  const scenarios = features.flatMap((f) => f.scenarios);
137
- const label = target.isFlow ? `flow/${target.name}` : target.name;
140
+ const label = target.kind === 'flow' ? `flow/${target.name}`
141
+ : target.kind === 'api' ? `api/${target.name}`
142
+ : target.name;
138
143
 
139
144
  // Screen-level platform axis: 'mobile' when any feature is OS-tagged; the
140
145
  // union of OSes that actually produced a result file this run.
@@ -154,6 +159,7 @@ function buildOneScreen(
154
159
  return {
155
160
  name: label,
156
161
  isFlow: target.isFlow,
162
+ kind: target.kind,
157
163
  platform: anyPlatform ? 'mobile' : undefined,
158
164
  featureName: primary.featureName,
159
165
  featurePath: primary.featurePath,
@@ -434,14 +440,24 @@ function bumpKey(record: Record<string, number>, key: string): void {
434
440
  // Path helpers (mirror delivery.ts to stay consistent)
435
441
  // ----------------------------------------------------------------------------
436
442
 
443
+ /** qa/ subfolder for a unit kind (mirrors delivery.ts's qaParent). */
444
+ function qaParent(kind: DashboardTarget['kind']): string {
445
+ return kind === 'flow' ? 'flows' : kind === 'api' ? 'api' : 'screens';
446
+ }
447
+
437
448
  function qaDir(cwd: string, target: DashboardTarget): string {
438
- return path.join(cwd, 'qa', target.isFlow ? 'flows' : 'screens', target.name);
449
+ return path.join(cwd, 'qa', qaParent(target.kind), target.name);
439
450
  }
440
451
 
441
452
  function generatedDir(cwd: string, target: DashboardTarget): string {
442
- return target.isFlow
443
- ? path.join(cwd, 'specs', 'generated', 'flows', target.name)
444
- : path.join(cwd, 'specs', 'generated', target.name);
453
+ // Mirrors delivery.ts: screen → specs/generated/<name>, flow → …/flows/<name>,
454
+ // api → …/api/<name> (api flows carry name 'flows/<flow>', composing correctly).
455
+ const sub = target.kind === 'flow'
456
+ ? path.join('flows', target.name)
457
+ : target.kind === 'api'
458
+ ? path.join('api', target.name)
459
+ : target.name;
460
+ return path.join(cwd, 'specs', 'generated', sub);
445
461
  }
446
462
 
447
463
  // ----------------------------------------------------------------------------
@@ -451,17 +467,23 @@ function generatedDir(cwd: string, target: DashboardTarget): string {
451
467
  export function listDashboardTargets(cwd: string): DashboardTarget[] {
452
468
  const targets: DashboardTarget[] = [];
453
469
 
454
- const screensDir = path.join(cwd, 'qa', 'screens');
455
- if (fs.existsSync(screensDir)) {
456
- for (const d of fs.readdirSync(screensDir, { withFileTypes: true })) {
457
- if (d.isDirectory()) targets.push({ name: d.name, isFlow: false });
470
+ const scan = (kind: DashboardTarget['kind'], skip: (n: string) => boolean = () => false): void => {
471
+ const dir = path.join(cwd, 'qa', qaParent(kind));
472
+ if (!fs.existsSync(dir)) return;
473
+ for (const d of fs.readdirSync(dir, { withFileTypes: true })) {
474
+ if (d.isDirectory() && !skip(d.name)) targets.push({ name: d.name, kind, isFlow: kind === 'flow' });
458
475
  }
459
- }
460
-
461
- const flowsDir = path.join(cwd, 'qa', 'flows');
462
- if (fs.existsSync(flowsDir)) {
463
- for (const d of fs.readdirSync(flowsDir, { withFileTypes: true })) {
464
- if (d.isDirectory()) targets.push({ name: d.name, isFlow: true });
476
+ };
477
+ scan('screen');
478
+ scan('flow');
479
+ scan('api', (n) => n === 'flows'); // api areas: qa/api/<area> (the flows/ container is a nested tier)
480
+
481
+ // api flows: qa/api/flows/<flow> → name 'flows/<flow>', kind 'api'
482
+ // (paths compose to qa/api/flows/… + specs/generated/api/flows/…), mirroring delivery.ts.
483
+ const apiFlowsRoot = path.join(cwd, 'qa', 'api', 'flows');
484
+ if (fs.existsSync(apiFlowsRoot)) {
485
+ for (const d of fs.readdirSync(apiFlowsRoot, { withFileTypes: true })) {
486
+ if (d.isDirectory()) targets.push({ name: path.posix.join('flows', d.name), kind: 'api', isFlow: false });
465
487
  }
466
488
  }
467
489
 
@@ -469,10 +491,15 @@ export function listDashboardTargets(cwd: string): DashboardTarget[] {
469
491
  }
470
492
 
471
493
  export function resolveTargetType(cwd: string, name: string): DashboardTarget {
472
- if (fs.existsSync(path.join(cwd, 'qa', 'flows', name))) {
473
- return { name, isFlow: true };
474
- }
475
- return { name, isFlow: false };
494
+ if (fs.existsSync(path.join(cwd, 'qa', 'flows', name))) return { name, kind: 'flow', isFlow: true };
495
+ // Screen before api so `dashboard <name>` resolves the same unit as `delivery <name>`
496
+ // when a repo has both qa/screens/<name> and qa/api/<name> (delivery.ts precedence).
497
+ if (fs.existsSync(path.join(cwd, 'qa', 'screens', name))) return { name, kind: 'screen', isFlow: false };
498
+ if (fs.existsSync(path.join(cwd, 'qa', 'api', name))) return { name, kind: 'api', isFlow: false };
499
+ // `flows/<flow>` or a bare api-flow name → qa/api/flows/<flow>
500
+ const apiFlow = name.startsWith('flows/') ? name : path.posix.join('flows', name);
501
+ if (fs.existsSync(path.join(cwd, 'qa', 'api', apiFlow))) return { name: apiFlow, kind: 'api', isFlow: false };
502
+ return { name, kind: 'screen', isFlow: false };
476
503
  }
477
504
 
478
505
  // ----------------------------------------------------------------------------