@sun-asterisk/sungen 3.2.33 → 3.2.34-beta.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.
- package/dist/cli/commands/audit.d.ts +4 -0
- package/dist/cli/commands/audit.d.ts.map +1 -1
- package/dist/cli/commands/audit.js +54 -10
- package/dist/cli/commands/audit.js.map +1 -1
- package/dist/cli/commands/capability.d.ts.map +1 -1
- package/dist/cli/commands/capability.js +5 -1
- package/dist/cli/commands/capability.js.map +1 -1
- package/dist/cli/commands/changed.d.ts.map +1 -1
- package/dist/cli/commands/changed.js +2 -3
- package/dist/cli/commands/changed.js.map +1 -1
- package/dist/cli/commands/dashboard.d.ts.map +1 -1
- package/dist/cli/commands/dashboard.js +2 -28
- package/dist/cli/commands/dashboard.js.map +1 -1
- package/dist/cli/commands/defect.d.ts +7 -0
- package/dist/cli/commands/defect.d.ts.map +1 -0
- package/dist/cli/commands/defect.js +68 -0
- package/dist/cli/commands/defect.js.map +1 -0
- package/dist/cli/commands/delivery.d.ts.map +1 -1
- package/dist/cli/commands/delivery.js +75 -42
- package/dist/cli/commands/delivery.js.map +1 -1
- package/dist/cli/commands/results-merge.d.ts +9 -0
- package/dist/cli/commands/results-merge.d.ts.map +1 -1
- package/dist/cli/commands/results-merge.js +7 -0
- package/dist/cli/commands/results-merge.js.map +1 -1
- package/dist/cli/commands/select.d.ts +12 -0
- package/dist/cli/commands/select.d.ts.map +1 -0
- package/dist/cli/commands/select.js +122 -0
- package/dist/cli/commands/select.js.map +1 -0
- package/dist/cli/commands/triage.d.ts +7 -0
- package/dist/cli/commands/triage.d.ts.map +1 -0
- package/dist/cli/commands/triage.js +98 -0
- package/dist/cli/commands/triage.js.map +1 -0
- package/dist/cli/commands/update.d.ts.map +1 -1
- package/dist/cli/commands/update.js +3 -0
- package/dist/cli/commands/update.js.map +1 -1
- package/dist/cli/commands/viewpoint.d.ts +7 -0
- package/dist/cli/commands/viewpoint.d.ts.map +1 -0
- package/dist/cli/commands/viewpoint.js +70 -0
- package/dist/cli/commands/viewpoint.js.map +1 -0
- package/dist/cli/index.js +13 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/dashboard/templates/index.html +1 -1
- package/dist/dashboard/types.d.ts +1 -0
- package/dist/dashboard/types.d.ts.map +1 -1
- package/dist/exporters/csv-exporter.d.ts +4 -0
- package/dist/exporters/csv-exporter.d.ts.map +1 -1
- package/dist/exporters/csv-exporter.js +12 -11
- package/dist/exporters/csv-exporter.js.map +1 -1
- package/dist/exporters/feature-parser.d.ts +8 -0
- package/dist/exporters/feature-parser.d.ts.map +1 -1
- package/dist/exporters/feature-parser.js +12 -0
- package/dist/exporters/feature-parser.js.map +1 -1
- package/dist/exporters/json-exporter.d.ts.map +1 -1
- package/dist/exporters/json-exporter.js +7 -0
- package/dist/exporters/json-exporter.js.map +1 -1
- package/dist/exporters/manual-hybrid-oracle.d.ts +54 -0
- package/dist/exporters/manual-hybrid-oracle.d.ts.map +1 -0
- package/dist/exporters/manual-hybrid-oracle.js +114 -0
- package/dist/exporters/manual-hybrid-oracle.js.map +1 -0
- package/dist/exporters/matrix/build.d.ts.map +1 -1
- package/dist/exporters/matrix/build.js +55 -12
- package/dist/exporters/matrix/build.js.map +1 -1
- package/dist/exporters/matrix/carry-manual-results.d.ts +19 -0
- package/dist/exporters/matrix/carry-manual-results.d.ts.map +1 -1
- package/dist/exporters/matrix/carry-manual-results.js +76 -6
- package/dist/exporters/matrix/carry-manual-results.js.map +1 -1
- package/dist/exporters/matrix/export.d.ts +8 -2
- package/dist/exporters/matrix/export.d.ts.map +1 -1
- package/dist/exporters/matrix/export.js +15 -3
- package/dist/exporters/matrix/export.js.map +1 -1
- package/dist/exporters/matrix/gates.js +6 -0
- package/dist/exporters/matrix/gates.js.map +1 -1
- package/dist/exporters/matrix/render-csv.js +1 -1
- package/dist/exporters/matrix/render-csv.js.map +1 -1
- package/dist/exporters/matrix/render-testcase-sheet.d.ts.map +1 -1
- package/dist/exporters/matrix/render-testcase-sheet.js +10 -4
- package/dist/exporters/matrix/render-testcase-sheet.js.map +1 -1
- package/dist/exporters/matrix/render-xlsx.d.ts.map +1 -1
- package/dist/exporters/matrix/render-xlsx.js +3 -0
- package/dist/exporters/matrix/render-xlsx.js.map +1 -1
- package/dist/exporters/matrix/types.d.ts +13 -1
- package/dist/exporters/matrix/types.d.ts.map +1 -1
- package/dist/exporters/matrix/types.js.map +1 -1
- package/dist/exporters/matrix/wording.d.ts +1 -1
- package/dist/exporters/matrix/wording.d.ts.map +1 -1
- package/dist/exporters/matrix/wording.js +10 -1
- package/dist/exporters/matrix/wording.js.map +1 -1
- package/dist/exporters/playwright-report-parser.d.ts.map +1 -1
- package/dist/exporters/playwright-report-parser.js +1 -0
- package/dist/exporters/playwright-report-parser.js.map +1 -1
- package/dist/exporters/run-environment.d.ts +32 -0
- package/dist/exporters/run-environment.d.ts.map +1 -0
- package/dist/exporters/run-environment.js +125 -0
- package/dist/exporters/run-environment.js.map +1 -0
- package/dist/exporters/scenario-merger.d.ts +18 -0
- package/dist/exporters/scenario-merger.d.ts.map +1 -1
- package/dist/exporters/scenario-merger.js +49 -3
- package/dist/exporters/scenario-merger.js.map +1 -1
- package/dist/exporters/test-data-resolver.d.ts +0 -4
- package/dist/exporters/test-data-resolver.d.ts.map +1 -1
- package/dist/exporters/test-data-resolver.js +0 -7
- package/dist/exporters/test-data-resolver.js.map +1 -1
- package/dist/exporters/types.d.ts +5 -0
- package/dist/exporters/types.d.ts.map +1 -1
- package/dist/generators/gherkin-parser/index.d.ts +11 -4
- package/dist/generators/gherkin-parser/index.d.ts.map +1 -1
- package/dist/generators/gherkin-parser/index.js +49 -19
- package/dist/generators/gherkin-parser/index.js.map +1 -1
- package/dist/generators/test-generator/adapters/adapter-interface.d.ts +4 -0
- package/dist/generators/test-generator/adapters/adapter-interface.d.ts.map +1 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/click-select-action.hbs +1 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/select-action.hbs +1 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/partials/pick-option.hbs +13 -0
- package/dist/generators/test-generator/adapters/playwright/templates/test-file.hbs +16 -0
- package/dist/generators/test-generator/code-generator.d.ts.map +1 -1
- package/dist/generators/test-generator/code-generator.js +23 -2
- package/dist/generators/test-generator/code-generator.js.map +1 -1
- package/dist/generators/test-generator/diagnostics.d.ts +3 -1
- package/dist/generators/test-generator/diagnostics.d.ts.map +1 -1
- package/dist/generators/test-generator/diagnostics.js +3 -1
- package/dist/generators/test-generator/diagnostics.js.map +1 -1
- package/dist/harness/audit.d.ts +3 -0
- package/dist/harness/audit.d.ts.map +1 -1
- package/dist/harness/audit.js +48 -15
- package/dist/harness/audit.js.map +1 -1
- package/dist/harness/counted-assertions.d.ts +2 -0
- package/dist/harness/counted-assertions.d.ts.map +1 -0
- package/dist/harness/counted-assertions.js +38 -0
- package/dist/harness/counted-assertions.js.map +1 -0
- package/dist/harness/data-driven-lint.d.ts.map +1 -1
- package/dist/harness/data-driven-lint.js +69 -27
- package/dist/harness/data-driven-lint.js.map +1 -1
- package/dist/harness/defect-draft.d.ts +14 -0
- package/dist/harness/defect-draft.d.ts.map +1 -0
- package/dist/harness/defect-draft.js +143 -0
- package/dist/harness/defect-draft.js.map +1 -0
- package/dist/harness/defects.d.ts +24 -0
- package/dist/harness/defects.d.ts.map +1 -0
- package/dist/harness/defects.js +118 -0
- package/dist/harness/defects.js.map +1 -0
- package/dist/harness/manifest.d.ts.map +1 -1
- package/dist/harness/manifest.js +2 -2
- package/dist/harness/manifest.js.map +1 -1
- package/dist/harness/next-step.d.ts +2 -4
- package/dist/harness/next-step.d.ts.map +1 -1
- package/dist/harness/next-step.js +50 -5
- package/dist/harness/next-step.js.map +1 -1
- package/dist/harness/parse.d.ts +45 -0
- package/dist/harness/parse.d.ts.map +1 -1
- package/dist/harness/parse.js +142 -24
- package/dist/harness/parse.js.map +1 -1
- package/dist/harness/quality-gates.d.ts.map +1 -1
- package/dist/harness/quality-gates.js +6 -4
- package/dist/harness/quality-gates.js.map +1 -1
- package/dist/harness/read-text.d.ts +15 -0
- package/dist/harness/read-text.d.ts.map +1 -1
- package/dist/harness/read-text.js +25 -0
- package/dist/harness/read-text.js.map +1 -1
- package/dist/harness/script-check.d.ts.map +1 -1
- package/dist/harness/script-check.js +7 -1
- package/dist/harness/script-check.js.map +1 -1
- package/dist/harness/select-by-ids.d.ts +31 -0
- package/dist/harness/select-by-ids.d.ts.map +1 -0
- package/dist/harness/select-by-ids.js +106 -0
- package/dist/harness/select-by-ids.js.map +1 -0
- package/dist/harness/sensors.d.ts +8 -1
- package/dist/harness/sensors.d.ts.map +1 -1
- package/dist/harness/sensors.js +92 -21
- package/dist/harness/sensors.js.map +1 -1
- package/dist/harness/spec-branches.js +1 -1
- package/dist/harness/spec-branches.js.map +1 -1
- package/dist/harness/triage-signals.d.ts +20 -0
- package/dist/harness/triage-signals.d.ts.map +1 -0
- package/dist/harness/triage-signals.js +30 -0
- package/dist/harness/triage-signals.js.map +1 -0
- package/dist/harness/triage-unit.d.ts +23 -0
- package/dist/harness/triage-unit.d.ts.map +1 -0
- package/dist/harness/triage-unit.js +142 -0
- package/dist/harness/triage-unit.js.map +1 -0
- package/dist/harness/triage.d.ts +28 -0
- package/dist/harness/triage.d.ts.map +1 -0
- package/dist/harness/triage.js +99 -0
- package/dist/harness/triage.js.map +1 -0
- package/dist/harness/ui-inventory.d.ts +40 -0
- package/dist/harness/ui-inventory.d.ts.map +1 -0
- package/dist/harness/ui-inventory.js +191 -0
- package/dist/harness/ui-inventory.js.map +1 -0
- package/dist/harness/viewpoint-baseline.d.ts.map +1 -1
- package/dist/harness/viewpoint-baseline.js +7 -1
- package/dist/harness/viewpoint-baseline.js.map +1 -1
- package/dist/harness/viewpoint-draft-header.d.ts +7 -0
- package/dist/harness/viewpoint-draft-header.d.ts.map +1 -0
- package/dist/harness/viewpoint-draft-header.js +100 -0
- package/dist/harness/viewpoint-draft-header.js.map +1 -0
- package/dist/harness/viewpoint-ledger.d.ts +13 -3
- package/dist/harness/viewpoint-ledger.d.ts.map +1 -1
- package/dist/harness/viewpoint-ledger.js +104 -18
- package/dist/harness/viewpoint-ledger.js.map +1 -1
- package/dist/harness/viewpoint-mode.d.ts +9 -0
- package/dist/harness/viewpoint-mode.d.ts.map +1 -0
- package/dist/harness/viewpoint-mode.js +52 -0
- package/dist/harness/viewpoint-mode.js.map +1 -0
- package/dist/harness/viewpoint-priority.d.ts +19 -0
- package/dist/harness/viewpoint-priority.d.ts.map +1 -0
- package/dist/harness/viewpoint-priority.js +36 -0
- package/dist/harness/viewpoint-priority.js.map +1 -0
- package/dist/harness/viewpoint-review-open.d.ts +6 -0
- package/dist/harness/viewpoint-review-open.d.ts.map +1 -0
- package/dist/harness/viewpoint-review-open.js +90 -0
- package/dist/harness/viewpoint-review-open.js.map +1 -0
- package/dist/harness/viewpoint-scan-refs.d.ts +50 -0
- package/dist/harness/viewpoint-scan-refs.d.ts.map +1 -0
- package/dist/harness/viewpoint-scan-refs.js +200 -0
- package/dist/harness/viewpoint-scan-refs.js.map +1 -0
- package/dist/harness/viewpoint-scan.d.ts +41 -0
- package/dist/harness/viewpoint-scan.d.ts.map +1 -0
- package/dist/harness/viewpoint-scan.js +118 -0
- package/dist/harness/viewpoint-scan.js.map +1 -0
- package/dist/orchestrator/flow-manager.d.ts +0 -1
- package/dist/orchestrator/flow-manager.d.ts.map +1 -1
- package/dist/orchestrator/flow-manager.js +3 -52
- package/dist/orchestrator/flow-manager.js.map +1 -1
- package/dist/orchestrator/screen-manager.d.ts.map +1 -1
- package/dist/orchestrator/screen-manager.js +8 -62
- package/dist/orchestrator/screen-manager.js.map +1 -1
- package/dist/orchestrator/templates/ai-src/agents/discovery.md +11 -3
- package/dist/orchestrator/templates/ai-src/agents/reviewer.md +8 -0
- package/dist/orchestrator/templates/ai-src/commands/create-test.md +32 -24
- package/dist/orchestrator/templates/ai-src/commands/review.md +2 -2
- package/dist/orchestrator/templates/ai-src/commands/run-test.md +78 -15
- package/dist/orchestrator/templates/ai-src/skills/sungen-capture/mode-local.md +2 -2
- package/dist/orchestrator/templates/ai-src/skills/sungen-error-mapping/SKILL.md +22 -0
- package/dist/orchestrator/templates/ai-src/skills/sungen-gherkin-syntax/SKILL.md +18 -9
- package/dist/orchestrator/templates/ai-src/skills/sungen-harness-audit/SKILL.md +5 -1
- package/dist/orchestrator/templates/ai-src/skills/sungen-selector-fix/SKILL.md +58 -14
- package/dist/orchestrator/templates/ai-src/skills/sungen-tc-generation/SKILL.md +42 -2
- package/dist/orchestrator/templates/ai-src/skills/sungen-tc-review/SKILL.md +7 -0
- package/dist/orchestrator/templates/ai-src/skills/sungen-viewpoint/SKILL.md +18 -0
- package/dist/orchestrator/templates/ai-src/skills/sungen-viewpoint/review-checklist.md +63 -0
- package/dist/orchestrator/templates/ai-src/skills/sungen-viewpoint/viewpoint-template.md +158 -0
- package/dist/orchestrator/templates/playwright.config.ts +4 -2
- package/dist/orchestrator/templates/specs-url-assert.d.ts.map +1 -1
- package/dist/orchestrator/templates/specs-url-assert.js +24 -2
- package/dist/orchestrator/templates/specs-url-assert.js.map +1 -1
- package/dist/orchestrator/templates/specs-url-assert.ts +23 -2
- package/dist/orchestrator/trace-mode-install.d.ts +14 -0
- package/dist/orchestrator/trace-mode-install.d.ts.map +1 -0
- package/dist/orchestrator/trace-mode-install.js +132 -0
- package/dist/orchestrator/trace-mode-install.js.map +1 -0
- package/dist/orchestrator/viewpoint-pattern-catalog.d.ts +23 -0
- package/dist/orchestrator/viewpoint-pattern-catalog.d.ts.map +1 -0
- package/dist/orchestrator/viewpoint-pattern-catalog.js +48 -0
- package/dist/orchestrator/viewpoint-pattern-catalog.js.map +1 -0
- package/dist/orchestrator/viewpoint-scaffold.d.ts +3 -0
- package/dist/orchestrator/viewpoint-scaffold.d.ts.map +1 -0
- package/dist/orchestrator/viewpoint-scaffold.js +70 -0
- package/dist/orchestrator/viewpoint-scaffold.js.map +1 -0
- package/package.json +3 -3
- package/src/cli/commands/audit.ts +49 -10
- package/src/cli/commands/capability.ts +3 -1
- package/src/cli/commands/changed.ts +2 -4
- package/src/cli/commands/dashboard.ts +1 -26
- package/src/cli/commands/defect.ts +49 -0
- package/src/cli/commands/delivery.ts +70 -42
- package/src/cli/commands/results-merge.ts +7 -1
- package/src/cli/commands/select.ts +88 -0
- package/src/cli/commands/triage.ts +57 -0
- package/src/cli/commands/update.ts +3 -0
- package/src/cli/commands/viewpoint.ts +58 -0
- package/src/cli/index.ts +13 -2
- package/src/dashboard/templates/index.html +1 -1
- package/src/dashboard/types.ts +1 -0
- package/src/exporters/csv-exporter.ts +12 -11
- package/src/exporters/feature-parser.ts +12 -0
- package/src/exporters/json-exporter.ts +6 -1
- package/src/exporters/manual-hybrid-oracle.ts +112 -0
- package/src/exporters/matrix/build.ts +57 -11
- package/src/exporters/matrix/carry-manual-results.ts +70 -7
- package/src/exporters/matrix/export.ts +16 -2
- package/src/exporters/matrix/gates.ts +6 -0
- package/src/exporters/matrix/render-csv.ts +1 -1
- package/src/exporters/matrix/render-testcase-sheet.ts +10 -4
- package/src/exporters/matrix/render-xlsx.ts +3 -0
- package/src/exporters/matrix/types.ts +13 -1
- package/src/exporters/matrix/wording.ts +10 -1
- package/src/exporters/playwright-report-parser.ts +1 -0
- package/src/exporters/run-environment.ts +89 -0
- package/src/exporters/scenario-merger.ts +51 -5
- package/src/exporters/test-data-resolver.ts +0 -6
- package/src/exporters/types.ts +5 -0
- package/src/generators/gherkin-parser/index.ts +50 -18
- package/src/generators/test-generator/adapters/adapter-interface.ts +4 -0
- package/src/generators/test-generator/adapters/playwright/templates/steps/actions/click-select-action.hbs +1 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/actions/select-action.hbs +1 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/partials/pick-option.hbs +13 -0
- package/src/generators/test-generator/adapters/playwright/templates/test-file.hbs +16 -0
- package/src/generators/test-generator/code-generator.ts +23 -2
- package/src/generators/test-generator/diagnostics.ts +3 -1
- package/src/harness/audit.ts +52 -17
- package/src/harness/counted-assertions.ts +33 -0
- package/src/harness/data-driven-lint.ts +82 -24
- package/src/harness/defect-draft.ts +115 -0
- package/src/harness/defects.ts +94 -0
- package/src/harness/manifest.ts +2 -2
- package/src/harness/next-step.ts +47 -5
- package/src/harness/parse.ts +151 -27
- package/src/harness/quality-gates.ts +6 -4
- package/src/harness/read-text.ts +25 -0
- package/src/harness/script-check.ts +7 -1
- package/src/harness/select-by-ids.ts +83 -0
- package/src/harness/sensors.ts +91 -21
- package/src/harness/spec-branches.ts +1 -1
- package/src/harness/triage-signals.ts +46 -0
- package/src/harness/triage-unit.ts +113 -0
- package/src/harness/triage.ts +127 -0
- package/src/harness/ui-inventory.ts +164 -0
- package/src/harness/viewpoint-baseline.ts +7 -1
- package/src/harness/viewpoint-draft-header.ts +55 -0
- package/src/harness/viewpoint-ledger.ts +111 -24
- package/src/harness/viewpoint-mode.ts +49 -0
- package/src/harness/viewpoint-priority.ts +38 -0
- package/src/harness/viewpoint-review-open.ts +51 -0
- package/src/harness/viewpoint-scan-refs.ts +154 -0
- package/src/harness/viewpoint-scan.ts +111 -0
- package/src/orchestrator/flow-manager.ts +3 -53
- package/src/orchestrator/screen-manager.ts +7 -61
- package/src/orchestrator/templates/ai-src/agents/discovery.md +11 -3
- package/src/orchestrator/templates/ai-src/agents/reviewer.md +8 -0
- package/src/orchestrator/templates/ai-src/commands/create-test.md +32 -24
- package/src/orchestrator/templates/ai-src/commands/review.md +2 -2
- package/src/orchestrator/templates/ai-src/commands/run-test.md +78 -15
- package/src/orchestrator/templates/ai-src/skills/sungen-capture/mode-local.md +2 -2
- package/src/orchestrator/templates/ai-src/skills/sungen-error-mapping/SKILL.md +22 -0
- package/src/orchestrator/templates/ai-src/skills/sungen-gherkin-syntax/SKILL.md +18 -9
- package/src/orchestrator/templates/ai-src/skills/sungen-harness-audit/SKILL.md +5 -1
- package/src/orchestrator/templates/ai-src/skills/sungen-selector-fix/SKILL.md +58 -14
- package/src/orchestrator/templates/ai-src/skills/sungen-tc-generation/SKILL.md +42 -2
- package/src/orchestrator/templates/ai-src/skills/sungen-tc-review/SKILL.md +7 -0
- package/src/orchestrator/templates/ai-src/skills/sungen-viewpoint/SKILL.md +18 -0
- package/src/orchestrator/templates/ai-src/skills/sungen-viewpoint/review-checklist.md +63 -0
- package/src/orchestrator/templates/ai-src/skills/sungen-viewpoint/viewpoint-template.md +158 -0
- package/src/orchestrator/templates/playwright.config.ts +4 -2
- package/src/orchestrator/templates/specs-url-assert.ts +23 -2
- package/src/orchestrator/trace-mode-install.ts +94 -0
- package/src/orchestrator/viewpoint-pattern-catalog.ts +61 -0
- package/src/orchestrator/viewpoint-scaffold.ts +36 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** The template's trace value: cheap on CI (retries exist there), a trace for every local failure. */
|
|
2
|
+
export declare const TRACE_MODE_EXPRESSION = "process.env.CI ? 'on-first-retry' : 'retain-on-failure'";
|
|
3
|
+
/**
|
|
4
|
+
* 'patched' — the old default was rewritten now
|
|
5
|
+
* 'present' — already the template expression (idempotent)
|
|
6
|
+
* 'custom' — another value, no trace line, more than one old-default line, or one inside
|
|
7
|
+
* `projects: [...]`; nothing written
|
|
8
|
+
* 'absent' — no playwright.config.ts (a mobile-only project, or not a sungen project)
|
|
9
|
+
*/
|
|
10
|
+
export type TraceModeOutcome = 'patched' | 'present' | 'custom' | 'absent';
|
|
11
|
+
export declare function patchTraceMode(cwd: string, dryRun?: boolean): TraceModeOutcome;
|
|
12
|
+
/** `sungen update` step: patch the trace mode and say so when it changed. */
|
|
13
|
+
export declare function installTraceMode(cwd: string, dryRun?: boolean): void;
|
|
14
|
+
//# sourceMappingURL=trace-mode-install.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trace-mode-install.d.ts","sourceRoot":"","sources":["../../src/orchestrator/trace-mode-install.ts"],"names":[],"mappings":"AAgBA,sGAAsG;AACtG,eAAO,MAAM,qBAAqB,4DAA4D,CAAC;AAE/F;;;;;;GAMG;AACH,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAC;AA6C3E,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,OAAe,GAAG,gBAAgB,CAgBrF;AAED,6EAA6E;AAC7E,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,OAAe,GAAG,IAAI,CAG3E"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.TRACE_MODE_EXPRESSION = void 0;
|
|
37
|
+
exports.patchTraceMode = patchTraceMode;
|
|
38
|
+
exports.installTraceMode = installTraceMode;
|
|
39
|
+
/**
|
|
40
|
+
* Move an existing project's `use.trace` off the old default so local runs keep a trace.
|
|
41
|
+
*
|
|
42
|
+
* The old template paired `trace: 'on-first-retry'` with `retries: process.env.CI ? 2 : 0`: off CI
|
|
43
|
+
* there is no retry, so there is never a "first retry" and a QA fixing a test on their machine never
|
|
44
|
+
* got a trace. The template now records `on-first-retry` on CI and `retain-on-failure` locally.
|
|
45
|
+
*
|
|
46
|
+
* `playwright.config.ts` is written once at `sungen init` and never re-synced (see
|
|
47
|
+
* report-sanitize-reporter-install.ts, the same problem for the sanitize reporter), so `sungen update`
|
|
48
|
+
* calls this. It rewrites the trace line ONLY while it is still the old default — any other value is
|
|
49
|
+
* a choice the user made, and a wrong edit to a user's config is worse than a missing trace. The same
|
|
50
|
+
* goes for a `trace` inside `projects: [...]`: that is a per-project override, not the template default.
|
|
51
|
+
*/
|
|
52
|
+
const fs = __importStar(require("fs"));
|
|
53
|
+
const path = __importStar(require("path"));
|
|
54
|
+
/** The template's trace value: cheap on CI (retries exist there), a trace for every local failure. */
|
|
55
|
+
exports.TRACE_MODE_EXPRESSION = "process.env.CI ? 'on-first-retry' : 'retain-on-failure'";
|
|
56
|
+
const escapeRegExp = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
57
|
+
// Both are anchored to the start of a line, so a commented-out copy (`// trace: …`) never counts.
|
|
58
|
+
// OLD_DEFAULT keeps the indentation in $1 and leaves the trailing comma, comment and EOL alone.
|
|
59
|
+
const OLD_DEFAULT = /^([ \t]*trace:[ \t]*)(['"])on-first-retry\2/gm;
|
|
60
|
+
const PRESENT = new RegExp(`^[ \\t]*trace:[ \\t]*${escapeRegExp(exports.TRACE_MODE_EXPRESSION)}`, 'm');
|
|
61
|
+
// The old template's one-line comment, only when it sits directly above the (patched) trace line.
|
|
62
|
+
// A comment the user wrote is theirs and stays.
|
|
63
|
+
const OLD_COMMENT = new RegExp(`^([ \\t]*)/\\* Collect trace when retrying the failed test\\. See https://playwright\\.dev/docs/trace-viewer \\*/(\\r?\\n)(?=[ \\t]*trace:[ \\t]*${escapeRegExp(exports.TRACE_MODE_EXPRESSION)})`, 'm');
|
|
64
|
+
const newComment = (indent, eol) => `${indent}/* Trace for a failed test. CI: recorded on the first retry (CI retries). Local: no retries, so${eol}` +
|
|
65
|
+
`${indent} 'on-first-retry' would never record one — keep the trace of every failed test instead.${eol}` +
|
|
66
|
+
`${indent} See https://playwright.dev/docs/trace-viewer */${eol}`;
|
|
67
|
+
/**
|
|
68
|
+
* [start, end] offsets of each live `projects: [...]` array, matched by bracket depth. Brackets inside
|
|
69
|
+
* a `//` or `/* *\/` comment or a quoted string are skipped: one stray `]` in a note would otherwise
|
|
70
|
+
* close the span early and expose a per-project override to the patch.
|
|
71
|
+
*/
|
|
72
|
+
function projectsSpans(src) {
|
|
73
|
+
const spans = [];
|
|
74
|
+
for (const m of src.matchAll(/^[ \t]*projects\s*:\s*\[/gm)) {
|
|
75
|
+
const open = m.index + m[0].length - 1;
|
|
76
|
+
let depth = 0;
|
|
77
|
+
for (let i = open; i < src.length; i++) {
|
|
78
|
+
const ch = src[i];
|
|
79
|
+
if (ch === '/' && src[i + 1] === '/') {
|
|
80
|
+
const nl = src.indexOf('\n', i);
|
|
81
|
+
i = nl < 0 ? src.length : nl;
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
if (ch === '/' && src[i + 1] === '*') {
|
|
85
|
+
const end = src.indexOf('*/', i + 2);
|
|
86
|
+
i = end < 0 ? src.length : end + 1;
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
if (ch === "'" || ch === '"' || ch === '`') {
|
|
90
|
+
for (i++; i < src.length && src[i] !== ch; i++)
|
|
91
|
+
if (src[i] === '\\')
|
|
92
|
+
i++;
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
if (ch === '[')
|
|
96
|
+
depth++;
|
|
97
|
+
else if (ch === ']' && --depth === 0) {
|
|
98
|
+
spans.push([open, i]);
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return spans;
|
|
104
|
+
}
|
|
105
|
+
function patchTraceMode(cwd, dryRun = false) {
|
|
106
|
+
const configPath = path.join(cwd, 'playwright.config.ts');
|
|
107
|
+
if (!fs.existsSync(configPath))
|
|
108
|
+
return 'absent';
|
|
109
|
+
const src = fs.readFileSync(configPath, 'utf8');
|
|
110
|
+
if (PRESENT.test(src))
|
|
111
|
+
return 'present';
|
|
112
|
+
const hits = [...src.matchAll(OLD_DEFAULT)];
|
|
113
|
+
if (hits.length !== 1)
|
|
114
|
+
return 'custom'; // none: the user's own value · several: ambiguous, don't guess
|
|
115
|
+
const at = hits[0].index;
|
|
116
|
+
if (projectsSpans(src).some(([s, e]) => at > s && at < e))
|
|
117
|
+
return 'custom'; // a per-project override
|
|
118
|
+
if (!dryRun) {
|
|
119
|
+
const patched = src
|
|
120
|
+
.replace(OLD_DEFAULT, `$1${exports.TRACE_MODE_EXPRESSION}`)
|
|
121
|
+
.replace(OLD_COMMENT, (_m, indent, eol) => newComment(indent, eol));
|
|
122
|
+
fs.writeFileSync(configPath, patched);
|
|
123
|
+
}
|
|
124
|
+
return 'patched';
|
|
125
|
+
}
|
|
126
|
+
/** `sungen update` step: patch the trace mode and say so when it changed. */
|
|
127
|
+
function installTraceMode(cwd, dryRun = false) {
|
|
128
|
+
if (patchTraceMode(cwd, dryRun) !== 'patched')
|
|
129
|
+
return;
|
|
130
|
+
console.log(`${dryRun ? '📋 would update' : '✓ updated'} playwright.config.ts: local runs now keep a trace for every failed test (trace: ${exports.TRACE_MODE_EXPRESSION})`);
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=trace-mode-install.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trace-mode-install.js","sourceRoot":"","sources":["../../src/orchestrator/trace-mode-install.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The sungen-viewpoint pattern catalog by number — the `## N. <Name>` headings of
|
|
3
|
+
* `templates/ai-src/skills/sungen-viewpoint/group-*.md` — for the "UI Patterns Identified" table
|
|
4
|
+
* `sungen add` scaffolds into `test-viewpoint.md` (#842).
|
|
5
|
+
*
|
|
6
|
+
* The scaffold used to hard-code its own ten rows: eight of them numbered differently from the
|
|
7
|
+
* catalog (Data Table 2 vs 7, Modal 9 vs 12…), plus a "Pagination" pattern the catalog does not
|
|
8
|
+
* have, so authors copied the wrong numbers next to a skill that cites the right ones.
|
|
9
|
+
* `tests/harness/viewpoint-comments-and-patterns.run.ts` pins this list to the catalog headings.
|
|
10
|
+
*/
|
|
11
|
+
export interface ViewpointPattern {
|
|
12
|
+
n: number;
|
|
13
|
+
name: string;
|
|
14
|
+
/** Group F — native-app patterns, read IN ADDITION to 1–17 for a mobile screen. */
|
|
15
|
+
mobile?: boolean;
|
|
16
|
+
}
|
|
17
|
+
export declare const VIEWPOINT_PATTERNS: readonly ViewpointPattern[];
|
|
18
|
+
/**
|
|
19
|
+
* The scaffold's pattern-table rows: 1–17 for every screen, plus Group F on a mobile project.
|
|
20
|
+
* `Áp dụng?` is left empty for the QA to mark ✅ / ❌, as the QA template does.
|
|
21
|
+
*/
|
|
22
|
+
export declare function uiPatternRows(isMobile: boolean): string[];
|
|
23
|
+
//# sourceMappingURL=viewpoint-pattern-catalog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"viewpoint-pattern-catalog.d.ts","sourceRoot":"","sources":["../../src/orchestrator/viewpoint-pattern-catalog.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,WAAW,gBAAgB;IAC/B,CAAC,EAAE,MAAM,CAAC;IACV,IAAI,EAAE,MAAM,CAAC;IACb,mFAAmF;IACnF,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,eAAO,MAAM,kBAAkB,EAAE,SAAS,gBAAgB,EAiCzD,CAAC;AAEF;;;GAGG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,OAAO,GAAG,MAAM,EAAE,CAIzD"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.VIEWPOINT_PATTERNS = void 0;
|
|
4
|
+
exports.uiPatternRows = uiPatternRows;
|
|
5
|
+
exports.VIEWPOINT_PATTERNS = [
|
|
6
|
+
{ n: 1, name: 'Form & Inputs' },
|
|
7
|
+
{ n: 2, name: 'File Upload' },
|
|
8
|
+
{ n: 3, name: 'Import / Export' },
|
|
9
|
+
{ n: 4, name: 'Create / Add' },
|
|
10
|
+
{ n: 5, name: 'Update / Edit' },
|
|
11
|
+
{ n: 6, name: 'Delete' },
|
|
12
|
+
{ n: 7, name: 'Data Table' },
|
|
13
|
+
{ n: 8, name: 'Search' },
|
|
14
|
+
{ n: 9, name: 'Filter' },
|
|
15
|
+
{ n: 10, name: 'List / Card View' },
|
|
16
|
+
{ n: 11, name: 'Chart / Analytics' },
|
|
17
|
+
{ n: 12, name: 'Modal / Dialog' },
|
|
18
|
+
{ n: 13, name: 'Navigation' },
|
|
19
|
+
{ n: 14, name: 'Notification / Toast / Alert' },
|
|
20
|
+
{ n: 15, name: 'Login / Logout' },
|
|
21
|
+
{ n: 16, name: 'Register' },
|
|
22
|
+
{ n: 17, name: 'Password Management' },
|
|
23
|
+
{ n: 18, name: 'Bottom Sheet', mobile: true },
|
|
24
|
+
{ n: 19, name: 'Tab Bar / Bottom Navigation', mobile: true },
|
|
25
|
+
{ n: 20, name: 'Swipe-to-Delete Row', mobile: true },
|
|
26
|
+
{ n: 21, name: 'Native Picker', mobile: true },
|
|
27
|
+
{ n: 22, name: 'Permission Dialog', mobile: true },
|
|
28
|
+
{ n: 23, name: 'Biometric Prompt', mobile: true },
|
|
29
|
+
{ n: 24, name: 'Camera / Gallery Picker', mobile: true },
|
|
30
|
+
{ n: 25, name: 'Push Notification', mobile: true },
|
|
31
|
+
{ n: 26, name: 'Deep-link Entry', mobile: true },
|
|
32
|
+
{ n: 27, name: 'Offline Banner', mobile: true },
|
|
33
|
+
{ n: 28, name: 'Onboarding Carousel', mobile: true },
|
|
34
|
+
{ n: 29, name: 'Pull-to-Refresh List', mobile: true },
|
|
35
|
+
{ n: 30, name: 'Soft-Keyboard Overlap', mobile: true },
|
|
36
|
+
{ n: 31, name: 'Settings Toggle List', mobile: true },
|
|
37
|
+
{ n: 32, name: 'App Lifecycle & Orientation', mobile: true },
|
|
38
|
+
];
|
|
39
|
+
/**
|
|
40
|
+
* The scaffold's pattern-table rows: 1–17 for every screen, plus Group F on a mobile project.
|
|
41
|
+
* `Áp dụng?` is left empty for the QA to mark ✅ / ❌, as the QA template does.
|
|
42
|
+
*/
|
|
43
|
+
function uiPatternRows(isMobile) {
|
|
44
|
+
return exports.VIEWPOINT_PATTERNS
|
|
45
|
+
.filter((p) => isMobile || !p.mobile)
|
|
46
|
+
.map((p) => `| ${p.n} | ${p.name} | | |`);
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=viewpoint-pattern-catalog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"viewpoint-pattern-catalog.js","sourceRoot":"","sources":["../../src/orchestrator/viewpoint-pattern-catalog.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"viewpoint-scaffold.d.ts","sourceRoot":"","sources":["../../src/orchestrator/viewpoint-scaffold.ts"],"names":[],"mappings":"AAeA,eAAO,MAAM,uBAAuB,QAEnC,CAAC;AAKF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,MAAM,CAa1E"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.VIEWPOINT_TEMPLATE_PATH = void 0;
|
|
37
|
+
exports.viewpointScaffold = viewpointScaffold;
|
|
38
|
+
/**
|
|
39
|
+
* The `requirements/test-viewpoint.md` that `sungen add` and `sungen add-flow` write.
|
|
40
|
+
*
|
|
41
|
+
* It IS the QA template the AI drafts from (`skills/sungen-viewpoint/viewpoint-template.md`), read
|
|
42
|
+
* at run time so QA and AI always start from the same file. Two substitutions only: the title, and
|
|
43
|
+
* the template's sample UI-pattern rows → the full catalog for the project's platform (#842).
|
|
44
|
+
*
|
|
45
|
+
* Every sample row sits inside `<!-- -->`, so an untouched scaffold declares no viewpoint and the
|
|
46
|
+
* audit reports VIEWPOINT-MISSING instead of measuring the suite against samples (#841). The
|
|
47
|
+
* scaffold never carries an active `drafted-by: ai` line: that marks an AI draft, and this is not one.
|
|
48
|
+
*/
|
|
49
|
+
const fs = __importStar(require("fs"));
|
|
50
|
+
const path = __importStar(require("path"));
|
|
51
|
+
const viewpoint_pattern_catalog_1 = require("./viewpoint-pattern-catalog");
|
|
52
|
+
exports.VIEWPOINT_TEMPLATE_PATH = path.join(__dirname, 'templates', 'ai-src', 'skills', 'sungen-viewpoint', 'viewpoint-template.md');
|
|
53
|
+
/** A UI-pattern row: `| 12 | Modal / Dialog | … |`. Only section 1 of the template has them. */
|
|
54
|
+
const PATTERN_ROW = /^\|\s*\d+\s*\|/;
|
|
55
|
+
function viewpointScaffold(title, isMobile) {
|
|
56
|
+
const lines = fs.readFileSync(exports.VIEWPOINT_TEMPLATE_PATH, 'utf-8').replace(/\r\n?/g, '\n').split('\n');
|
|
57
|
+
const titleAt = lines.findIndex((l) => l.startsWith('# '));
|
|
58
|
+
const rowsAt = lines.findIndex((l) => PATTERN_ROW.test(l));
|
|
59
|
+
// A template edit that drops either anchor must fail here, not ship a scaffold without them.
|
|
60
|
+
if (titleAt < 0 || rowsAt < 0) {
|
|
61
|
+
throw new Error(`viewpoint-template.md has no title or no UI-pattern sample rows: ${exports.VIEWPOINT_TEMPLATE_PATH}`);
|
|
62
|
+
}
|
|
63
|
+
let rowsEnd = rowsAt;
|
|
64
|
+
while (rowsEnd < lines.length && PATTERN_ROW.test(lines[rowsEnd]))
|
|
65
|
+
rowsEnd++;
|
|
66
|
+
lines[titleAt] = `# Test Viewpoint — ${title}`;
|
|
67
|
+
lines.splice(rowsAt, rowsEnd - rowsAt, ...(0, viewpoint_pattern_catalog_1.uiPatternRows)(isMobile));
|
|
68
|
+
return lines.join('\n');
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=viewpoint-scaffold.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"viewpoint-scaffold.js","sourceRoot":"","sources":["../../src/orchestrator/viewpoint-scaffold.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsBA,8CAaC;AAnCD;;;;;;;;;;GAUG;AACH,uCAAyB;AACzB,2CAA6B;AAC7B,2EAA4D;AAE/C,QAAA,uBAAuB,GAAG,IAAI,CAAC,IAAI,CAC9C,SAAS,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,kBAAkB,EAAE,uBAAuB,CACxF,CAAC;AAEF,gGAAgG;AAChG,MAAM,WAAW,GAAG,gBAAgB,CAAC;AAErC,SAAgB,iBAAiB,CAAC,KAAa,EAAE,QAAiB;IAChE,MAAM,KAAK,GAAG,EAAE,CAAC,YAAY,CAAC,+BAAuB,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACpG,MAAM,OAAO,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;IAC3D,MAAM,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3D,6FAA6F;IAC7F,IAAI,OAAO,GAAG,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,oEAAoE,+BAAuB,EAAE,CAAC,CAAC;IACjH,CAAC;IACD,IAAI,OAAO,GAAG,MAAM,CAAC;IACrB,OAAO,OAAO,GAAG,KAAK,CAAC,MAAM,IAAI,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAAE,OAAO,EAAE,CAAC;IAC7E,KAAK,CAAC,OAAO,CAAC,GAAG,sBAAsB,KAAK,EAAE,CAAC;IAC/C,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,EAAE,GAAG,IAAA,yCAAa,EAAC,QAAQ,CAAC,CAAC,CAAC;IACnE,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sun-asterisk/sungen",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.34-beta.1",
|
|
4
4
|
"description": "Deterministic E2E Test Compiler - Gherkin + Selectors → Playwright tests",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"types": "src/index.ts",
|
|
@@ -40,8 +40,8 @@
|
|
|
40
40
|
"@babel/types": "^7.28.5",
|
|
41
41
|
"@cucumber/gherkin": "^37.0.0",
|
|
42
42
|
"@cucumber/messages": "^31.0.0",
|
|
43
|
-
"@sungen/driver-data-factory": "3.2.
|
|
44
|
-
"@sungen/driver-ui": "3.2.
|
|
43
|
+
"@sungen/driver-data-factory": "3.2.34-beta.1",
|
|
44
|
+
"@sungen/driver-ui": "3.2.34-beta.1",
|
|
45
45
|
"chalk": "^5.6.2",
|
|
46
46
|
"commander": "^14.0.2",
|
|
47
47
|
"dotenv": "^17.2.3",
|
|
@@ -4,6 +4,7 @@ import * as fs from 'fs';
|
|
|
4
4
|
import { runAudit, AuditReport, catalogIdFromScreenDir } from '../../harness/audit';
|
|
5
5
|
import { reportSlug } from '../../harness/unit-paths';
|
|
6
6
|
import { acceptViewpointBaseline } from '../../harness/viewpoint-baseline';
|
|
7
|
+
import { removeDraftLineFromFile, viewpointFileIsAiDraft } from '../../harness/viewpoint-draft-header';
|
|
7
8
|
import { findUnitDir } from '../resolve-unit';
|
|
8
9
|
|
|
9
10
|
|
|
@@ -15,6 +16,14 @@ export function bar(ratio: number, width = 20): string {
|
|
|
15
16
|
return '█'.repeat(n) + '░'.repeat(width - n);
|
|
16
17
|
}
|
|
17
18
|
|
|
19
|
+
/** The ⑥ headline. No viewpoint ID read → nothing was matched, so `0%` would read as a measured
|
|
20
|
+
* failure; say `n/a` and why instead (#832). Same with no scenario yet (#852). */
|
|
21
|
+
export function traceabilityHeadline(trace: AuditReport['trace']): string {
|
|
22
|
+
if (trace.overviewIds === 0) return ' ⑥ Traceability — n/a (no viewpoint ID found in test-viewpoint.md)';
|
|
23
|
+
if (trace.total === 0) return ' ⑥ Traceability — n/a (no scenarios yet)';
|
|
24
|
+
return ` ⑥ Traceability — ${(trace.mappedRatio * 100).toFixed(0)}% scenarios linked to viewpoint-overview`;
|
|
25
|
+
}
|
|
26
|
+
|
|
18
27
|
function render(r: AuditReport): void {
|
|
19
28
|
const L = console.log;
|
|
20
29
|
L('');
|
|
@@ -82,7 +91,7 @@ function render(r: AuditReport): void {
|
|
|
82
91
|
if (r.depth.shallowBusinessCritical.length > 8) L(` … +${r.depth.shallowBusinessCritical.length - 8} more`);
|
|
83
92
|
L('');
|
|
84
93
|
L(` ③ Claim-Proof — ${r.claim.proven}/${r.claim.withClaims} titled claims proven by steps [${r.claim.verdict.toUpperCase()}]`);
|
|
85
|
-
if (r.claim.unproven.length === 0) L(' ✓ every claim (all/only/single/correct/changes/hidden) is backed by an assertion');
|
|
94
|
+
if (r.claim.unproven.length === 0) L(' ✓ every claim (all/only/single/correct/changes/hidden/order/limit) is backed by an assertion');
|
|
86
95
|
for (const u of r.claim.unproven.slice(0, 8)) L(` ${u.severity === 'fail' ? '✗' : '⚠'} [${u.claim}] ${u.name} → needs ${u.need}`);
|
|
87
96
|
if (r.claim.unproven.length > 8) L(` … +${r.claim.unproven.length - 8} more`);
|
|
88
97
|
L('');
|
|
@@ -110,7 +119,7 @@ function render(r: AuditReport): void {
|
|
|
110
119
|
}
|
|
111
120
|
}
|
|
112
121
|
L('');
|
|
113
|
-
L(
|
|
122
|
+
L(traceabilityHeadline(r.trace));
|
|
114
123
|
L(` ${r.trace.note}`);
|
|
115
124
|
L('');
|
|
116
125
|
if (r.spec.hasSpec && (r.spec.frTotal > 0 || r.spec.triggerGaps.length > 0 || r.spec.verdict !== 'pass')) {
|
|
@@ -135,7 +144,7 @@ function render(r: AuditReport): void {
|
|
|
135
144
|
const held = new Set(r.score.axes.filter((x) => x.withheld).map((x) => x.key));
|
|
136
145
|
const absent = na.filter((k) => !held.has(k));
|
|
137
146
|
if (absent.length) L(` not scored (no evidence in this unit): ${absent.join(', ')}`);
|
|
138
|
-
if (held.size) L(` measured but held (viewpoint
|
|
147
|
+
if (held.size) L(` measured but held (viewpoint not accepted yet — changed, adopted after the suite, or an AI draft; review, then --accept-viewpoint): ${[...held].join(', ')}`);
|
|
139
148
|
}
|
|
140
149
|
L(` weakest: ${r.calibration.weakest.axis} ${(r.calibration.weakest.value * 100).toFixed(0)}%${r.calibration.inflated ? ' ⚠ SCORE-INFLATED-BY-BREADTH' : ''}`);
|
|
141
150
|
if (r.calibration.cappedAt !== undefined) {
|
|
@@ -165,14 +174,18 @@ export function registerAuditCommand(program: Command): void {
|
|
|
165
174
|
.option('--area <name>', 'Alias of --api — an API-first area (qa/api/<name>)')
|
|
166
175
|
.option('--json', 'Output the raw JSON report')
|
|
167
176
|
.option('--accept-viewpoint', 'Accept the current test-viewpoint.md as the baseline the suite is measured against')
|
|
177
|
+
.option('--no-baseline', 'Measure without writing .sungen/viewpoint-baseline.json (audit a drafted viewpoint before generating)')
|
|
168
178
|
.action((options) => {
|
|
169
179
|
try {
|
|
170
180
|
const name = options.screen || options.api || options.area;
|
|
171
181
|
if (!name) throw new Error('Provide --screen <name> (or --api <area>)');
|
|
182
|
+
// Commander's `--no-*`: `baseline` is true unless the flag is passed.
|
|
183
|
+
const recordBaseline = options.baseline !== false;
|
|
184
|
+
if (!recordBaseline && options.acceptViewpoint) throw new Error('--no-baseline and --accept-viewpoint cannot be combined');
|
|
172
185
|
const dir = findUnitDir(name);
|
|
173
186
|
if (!dir) throw new Error(`Not found: qa/screens/${name}, qa/flows/${name}, or qa/api/${name}`);
|
|
174
187
|
|
|
175
|
-
|
|
188
|
+
let report = runAudit(dir, name);
|
|
176
189
|
|
|
177
190
|
// The baseline is only ever written HERE, never by the measurement itself:
|
|
178
191
|
// a first sighting has nothing to compare against, and any later change is
|
|
@@ -187,18 +200,43 @@ export function registerAuditCommand(program: Command): void {
|
|
|
187
200
|
const unitId = catalogIdFromScreenDir(dir);
|
|
188
201
|
const vb = report.viewpointBaseline;
|
|
189
202
|
const postHoc = vb.status === 'new' && report.scenarioCount > 0;
|
|
203
|
+
// `drafted-by: ai` — a viewpoint the AI wrote is never accepted by the audit that measures it,
|
|
204
|
+
// with scenarios or without: only `--accept-viewpoint` does, and that removes the line.
|
|
205
|
+
const vpPath = path.join(dir, 'requirements', 'test-viewpoint.md');
|
|
206
|
+
const hasDraftMarker = viewpointFileIsAiDraft(vpPath);
|
|
207
|
+
// A draft with no VP id has nothing to accept — only VIEWPOINT-MISSING speaks for it. Fail
|
|
208
|
+
// here, before any write, so the file stays as it is and the QA is told why.
|
|
209
|
+
if (options.acceptViewpoint && vb.status === 'absent' && hasDraftMarker) {
|
|
210
|
+
throw new Error('the draft declares no VP ids — nothing to accept. Add the viewpoint ids (VP-… in the Priority Viewpoints table or checks), then run --accept-viewpoint again.');
|
|
211
|
+
}
|
|
212
|
+
const aiDraft = vb.status !== 'absent' && hasDraftMarker;
|
|
190
213
|
// A re-parsed baseline is a CACHE migration, not an acceptance: the comparison already
|
|
191
214
|
// resolved to `unchanged`, and rewriting the record only lets the NEXT real edit be
|
|
192
215
|
// detected. Left unwritten it would re-migrate — and re-announce — on every run.
|
|
193
|
-
|
|
194
|
-
|
|
216
|
+
//
|
|
217
|
+
// `--no-baseline` skips every write here, the migration included: a draft audited before its
|
|
218
|
+
// scenarios exist is `new` and not post-hoc, and a plain audit would record it as the yardstick.
|
|
219
|
+
if (recordBaseline && !aiDraft && vb.reparsed) acceptViewpointBaseline(process.cwd(), unitId, { hash: vb.hash, ids: vb.ids, fileHash: vb.fileHash });
|
|
220
|
+
if (recordBaseline && ((vb.status === 'new' && !postHoc && !aiDraft) || (options.acceptViewpoint && (vb.status === 'changed' || postHoc || aiDraft)))) {
|
|
195
221
|
acceptViewpointBaseline(process.cwd(), unitId, { hash: vb.hash, ids: vb.ids, fileHash: vb.fileHash });
|
|
196
|
-
if (options.acceptViewpoint
|
|
197
|
-
|
|
198
|
-
|
|
222
|
+
if (options.acceptViewpoint) {
|
|
223
|
+
// The baseline is recorded first: if the line cannot be removed the draft stays flagged
|
|
224
|
+
// (held, finding, decide step) and the accept can simply be run again.
|
|
225
|
+
const lineRemoved = aiDraft && removeDraftLineFromFile(vpPath);
|
|
226
|
+
// Measure again against what was just accepted: the report printed and saved below (the
|
|
227
|
+
// one `sungen next` reads) must not be the pre-accept one, still holding the axes (#867).
|
|
228
|
+
report = runAudit(dir, name);
|
|
229
|
+
if (!options.json) {
|
|
230
|
+
console.log(`\n ✓ test-viewpoint.md accepted as the baseline for ${name} (${vb.ids.length} viewpoint id(s)).`);
|
|
231
|
+
if (lineRemoved) console.log(' Removed the `drafted-by: ai` line from test-viewpoint.md — it is QA-reviewed from here on.');
|
|
232
|
+
console.log(' The report below is measured against it.\n');
|
|
233
|
+
}
|
|
199
234
|
}
|
|
200
235
|
} else if (options.acceptViewpoint && !options.json) {
|
|
201
|
-
|
|
236
|
+
// `absent` covers a file with no readable viewpoint id too — say which (#832).
|
|
237
|
+
console.log(vb.status === 'absent'
|
|
238
|
+
? `\n ○ nothing to accept for ${name} — no viewpoint ID found in requirements/test-viewpoint.md (missing file, or no section declares one).\n`
|
|
239
|
+
: `\n ○ nothing to accept for ${name} — the viewpoint baseline is ${vb.status}.\n`);
|
|
202
240
|
}
|
|
203
241
|
|
|
204
242
|
// Persist report under .sungen/reports/ (flat slug: api flow `flows/x` → `flows-x-audit.json`).
|
|
@@ -212,6 +250,7 @@ export function registerAuditCommand(program: Command): void {
|
|
|
212
250
|
} else {
|
|
213
251
|
render(report);
|
|
214
252
|
console.log(` Report: ${path.relative(process.cwd(), outPath)}`);
|
|
253
|
+
if (!recordBaseline) console.log(' ○ baseline not recorded (--no-baseline)');
|
|
215
254
|
console.log('');
|
|
216
255
|
}
|
|
217
256
|
// Non-zero exit when the gate fails — usable in CI / repair loop. Set exitCode (not
|
|
@@ -265,7 +265,9 @@ export function registerCapabilityCommand(program: Command): void {
|
|
|
265
265
|
else console.log(' – skipped appium-environment/ (already exists)');
|
|
266
266
|
|
|
267
267
|
// Best-effort driver install — non-fatal so capability add still succeeds offline.
|
|
268
|
-
|
|
268
|
+
// --skip-install promises no npm install; the driver + wdio/appium runtime is ~290 MB.
|
|
269
|
+
if (o.skipInstall) console.log(' – skipped mobile driver install (--skip-install) — later: sungen capability add mobile');
|
|
270
|
+
else installMobileDriver(cwd);
|
|
269
271
|
|
|
270
272
|
// --skip-install means "record only" — then provisioning the machine is not wanted either.
|
|
271
273
|
runAppiumEnvironmentSetup(cwd, { skip: !!(o.skipEnvSetup || o.skipInstall) });
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
import { Command } from 'commander';
|
|
13
13
|
import { buildRunManifest, readRunManifest, writeRunManifest, selectChanged } from '../../harness/run-manifest';
|
|
14
14
|
import { findUnitDir } from '../resolve-unit';
|
|
15
|
+
import { titlesToGrep } from '../../harness/select-by-ids';
|
|
15
16
|
import { execFileSync } from 'child_process';
|
|
16
17
|
import * as path from 'path';
|
|
17
18
|
|
|
@@ -40,9 +41,6 @@ function gitChangedFiles(unitDir: string): string[] {
|
|
|
40
41
|
}
|
|
41
42
|
}
|
|
42
43
|
|
|
43
|
-
/** Escape a scenario title for a `-g` / `--mochaOpts.grep` regex. */
|
|
44
|
-
const toGrep = (titles: string[]): string =>
|
|
45
|
-
titles.map((t) => t.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join('|');
|
|
46
44
|
|
|
47
45
|
export function registerChangedCommand(program: Command): void {
|
|
48
46
|
program
|
|
@@ -75,7 +73,7 @@ export function registerChangedCommand(program: Command): void {
|
|
|
75
73
|
if (options.grep) {
|
|
76
74
|
// Empty output is meaningful: nothing to run. A caller must treat "" as "skip the run",
|
|
77
75
|
// never as "match everything" — an empty grep would run the whole suite.
|
|
78
|
-
console.log(
|
|
76
|
+
console.log(titlesToGrep(selection.scenarios));
|
|
79
77
|
return;
|
|
80
78
|
}
|
|
81
79
|
if (options.json) { console.log(JSON.stringify(selection, null, 2)); return; }
|
|
@@ -11,8 +11,7 @@ import { Command } from 'commander';
|
|
|
11
11
|
import * as path from 'path';
|
|
12
12
|
import * as fs from 'fs';
|
|
13
13
|
import { execSync } from 'child_process';
|
|
14
|
-
import {
|
|
15
|
-
import { resolveWebBaseUrl } from '../../exporters/env-qa';
|
|
14
|
+
import { getEnvironment } from '../../exporters/run-environment';
|
|
16
15
|
import {
|
|
17
16
|
buildDashboardSnapshot,
|
|
18
17
|
DashboardTarget,
|
|
@@ -37,30 +36,6 @@ const COLOR = {
|
|
|
37
36
|
|
|
38
37
|
function log(msg: string): void { console.log(msg); }
|
|
39
38
|
|
|
40
|
-
function getEnvironment(cwd: string): EnvironmentInfo {
|
|
41
|
-
let baseURL = '';
|
|
42
|
-
let projectName = 'chromium';
|
|
43
|
-
const configPath = path.join(cwd, 'playwright.config.ts');
|
|
44
|
-
if (fs.existsSync(configPath)) {
|
|
45
|
-
const c = fs.readFileSync(configPath, 'utf-8');
|
|
46
|
-
// Both config shapes: legacy literal and env-aware resolveBaseUrl('x') wrapper.
|
|
47
|
-
const baseMatch = c.match(/baseURL:\s*(?:resolveBaseUrl\(\s*)?['"]([^'"]+)['"]/);
|
|
48
|
-
if (baseMatch) baseURL = baseMatch[1];
|
|
49
|
-
const projMatch = c.match(/name:\s*['"]([^'"]+)['"]/);
|
|
50
|
-
if (projMatch) projectName = projMatch[1];
|
|
51
|
-
}
|
|
52
|
-
// Same SUNGEN_BASE_URL override as delivery — the two surfaces must agree.
|
|
53
|
-
baseURL = resolveWebBaseUrl(cwd, baseURL);
|
|
54
|
-
|
|
55
|
-
let executor = process.env.CI_USER || process.env.USER || '';
|
|
56
|
-
try {
|
|
57
|
-
const gitUser = execSync('git config user.name', { cwd, encoding: 'utf-8' }).trim();
|
|
58
|
-
if (gitUser) executor = gitUser;
|
|
59
|
-
} catch { /* ignore */ }
|
|
60
|
-
|
|
61
|
-
return { baseURL, projectName, executor };
|
|
62
|
-
}
|
|
63
|
-
|
|
64
39
|
interface DashboardOptions {
|
|
65
40
|
noHistory?: boolean;
|
|
66
41
|
open?: boolean;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { resolveUnit } from '../resolve-unit';
|
|
3
|
+
import { draftDefects } from '../../harness/defect-draft';
|
|
4
|
+
import { readDefects } from '../../harness/defects';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* `sungen defect draft|list` — defect records under qa/defects/ (see harness/defects.ts).
|
|
8
|
+
* `draft` writes one record per product-candidate row of the unit's last `sungen triage`.
|
|
9
|
+
*/
|
|
10
|
+
export function registerDefectCommand(program: Command): void {
|
|
11
|
+
const defect = program.command('defect').description('Draft and list defect records (qa/defects/DEF-NNN-*.md) from red scenarios');
|
|
12
|
+
|
|
13
|
+
defect
|
|
14
|
+
.command('draft')
|
|
15
|
+
.description('Draft a defect record for each product-candidate row of the last `sungen triage`')
|
|
16
|
+
.option('-s, --screen <name>', 'Screen or flow name')
|
|
17
|
+
.option('--api <name>', 'API-first area or api flow (qa/api/<name>)')
|
|
18
|
+
.option('--scenario <title|id>', 'Only the scenario whose title contains this text, or that carries this VP id')
|
|
19
|
+
.option('--json', 'Output raw JSON')
|
|
20
|
+
.action((o: { screen?: string; api?: string; scenario?: string; json?: boolean }) => {
|
|
21
|
+
try {
|
|
22
|
+
const name = o.screen || o.api;
|
|
23
|
+
if (!name) throw new Error('Provide --screen <name> (or --api <area>)');
|
|
24
|
+
const unit = resolveUnit(name, process.cwd());
|
|
25
|
+
if (!unit) throw new Error(`Not found: qa/screens/${name}, qa/flows/${name}, or qa/api/${name}`);
|
|
26
|
+
const r = draftDefects(process.cwd(), unit, { scenario: o.scenario });
|
|
27
|
+
if (o.json) { console.log(JSON.stringify(r, null, 2)); return; }
|
|
28
|
+
if (r.missingTriage) { console.log(`\n ${name}: no triage yet — run \`sungen triage --screen ${name}\` after the tests.\n`); return; }
|
|
29
|
+
for (const f of r.written) console.log(` ✎ ${f}`);
|
|
30
|
+
for (const s of r.skipped) console.log(` ○ already recorded as ${s.id}: ${s.scenario}`);
|
|
31
|
+
if (!r.written.length && !r.skipped.length) console.log(` ✓ ${name}: no product-candidate rows to draft.`);
|
|
32
|
+
} catch (error) {
|
|
33
|
+
console.error('Error:', error instanceof Error ? error.message : error);
|
|
34
|
+
process.exitCode = 1;
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
defect
|
|
39
|
+
.command('list')
|
|
40
|
+
.description('List defect records (id, severity, status, units, scenario count)')
|
|
41
|
+
.option('--status <status>', 'Only records with this status (open, fixed, verified, closed, wont-fix)')
|
|
42
|
+
.option('--json', 'Output raw JSON')
|
|
43
|
+
.action((o: { status?: string; json?: boolean }) => {
|
|
44
|
+
const rows = readDefects(process.cwd()).filter((r) => !o.status || r.status === o.status);
|
|
45
|
+
if (o.json) { console.log(JSON.stringify(rows, null, 2)); return; }
|
|
46
|
+
if (!rows.length) { console.log(' (no defect records)'); return; }
|
|
47
|
+
for (const r of rows) console.log(` ${r.id} ${r.severity.padEnd(8)} ${r.status.padEnd(9)} ${r.units.join(',')} ${r.scenarios.length} scenario(s) ${r.title}`);
|
|
48
|
+
});
|
|
49
|
+
}
|