@sun-asterisk/sungen 3.2.2-beta.9 → 3.2.3-beta.3
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/capabilities/discover.d.ts.map +1 -1
- package/dist/capabilities/discover.js +26 -3
- package/dist/capabilities/discover.js.map +1 -1
- package/dist/cli/commands/add-flow.d.ts.map +1 -1
- package/dist/cli/commands/add-flow.js +2 -0
- package/dist/cli/commands/add-flow.js.map +1 -1
- package/dist/cli/commands/add.d.ts.map +1 -1
- package/dist/cli/commands/add.js +4 -0
- package/dist/cli/commands/add.js.map +1 -1
- package/dist/cli/commands/capability.d.ts.map +1 -1
- package/dist/cli/commands/capability.js +61 -0
- package/dist/cli/commands/capability.js.map +1 -1
- package/dist/cli/commands/delivery.d.ts.map +1 -1
- package/dist/cli/commands/delivery.js +89 -2
- package/dist/cli/commands/delivery.js.map +1 -1
- package/dist/cli/commands/eval.js +3 -3
- package/dist/cli/commands/eval.js.map +1 -1
- package/dist/cli/commands/generate.d.ts.map +1 -1
- package/dist/cli/commands/generate.js +2 -1
- package/dist/cli/commands/generate.js.map +1 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +32 -2
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/journey.d.ts.map +1 -1
- package/dist/cli/commands/journey.js +24 -2
- package/dist/cli/commands/journey.js.map +1 -1
- package/dist/cli/commands/update.d.ts.map +1 -1
- package/dist/cli/commands/update.js +10 -3
- package/dist/cli/commands/update.js.map +1 -1
- package/dist/dashboard/snapshot-builder.d.ts.map +1 -1
- package/dist/dashboard/snapshot-builder.js +10 -1
- package/dist/dashboard/snapshot-builder.js.map +1 -1
- package/dist/exporters/csv-exporter.d.ts.map +1 -1
- package/dist/exporters/csv-exporter.js +3 -1
- package/dist/exporters/csv-exporter.js.map +1 -1
- package/dist/exporters/json-exporter.js +3 -1
- package/dist/exporters/json-exporter.js.map +1 -1
- package/dist/exporters/mobile-app-id.d.ts +22 -0
- package/dist/exporters/mobile-app-id.d.ts.map +1 -0
- package/dist/exporters/mobile-app-id.js +37 -0
- package/dist/exporters/mobile-app-id.js.map +1 -0
- package/dist/exporters/spec-parser.d.ts.map +1 -1
- package/dist/exporters/spec-parser.js +6 -2
- package/dist/exporters/spec-parser.js.map +1 -1
- package/dist/generators/test-generator/adapters/adapter-interface.d.ts +3 -0
- package/dist/generators/test-generator/adapters/adapter-interface.d.ts.map +1 -1
- package/dist/generators/test-generator/adapters/appium/templates/steps/actions/scroll-action.hbs +7 -4
- package/dist/generators/test-generator/adapters/appium/templates/steps/actions/toggle-action.hbs +20 -3
- package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/checked-assertion.hbs +4 -1
- package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/not-checked-assertion.hbs +4 -1
- package/dist/generators/test-generator/adapters/appium/templates/test-file.hbs +3 -0
- package/dist/generators/test-generator/code-generator.d.ts.map +1 -1
- package/dist/generators/test-generator/code-generator.js +48 -9
- package/dist/generators/test-generator/code-generator.js.map +1 -1
- package/dist/generators/test-generator/template-engine.d.ts +3 -0
- package/dist/generators/test-generator/template-engine.d.ts.map +1 -1
- package/dist/generators/test-generator/template-engine.js +11 -1
- package/dist/generators/test-generator/template-engine.js.map +1 -1
- package/dist/generators/test-generator/utils/selector-resolver.d.ts +11 -1
- package/dist/generators/test-generator/utils/selector-resolver.d.ts.map +1 -1
- package/dist/generators/test-generator/utils/selector-resolver.js +33 -0
- package/dist/generators/test-generator/utils/selector-resolver.js.map +1 -1
- package/dist/harness/audit.d.ts.map +1 -1
- package/dist/harness/audit.js +8 -1
- package/dist/harness/audit.js.map +1 -1
- package/dist/harness/catalog/universal-viewpoints.yaml +15 -0
- package/dist/harness/eval/skill-lint.d.ts +3 -3
- package/dist/harness/eval/skill-lint.d.ts.map +1 -1
- package/dist/harness/eval/skill-lint.js +88 -68
- package/dist/harness/eval/skill-lint.js.map +1 -1
- package/dist/harness/journey.d.ts +37 -1
- package/dist/harness/journey.d.ts.map +1 -1
- package/dist/harness/journey.js +146 -19
- package/dist/harness/journey.js.map +1 -1
- package/dist/harness/quality-gates.d.ts +13 -0
- package/dist/harness/quality-gates.d.ts.map +1 -1
- package/dist/harness/quality-gates.js +23 -0
- package/dist/harness/quality-gates.js.map +1 -1
- package/dist/harness/sensors.d.ts +1 -1
- package/dist/harness/sensors.d.ts.map +1 -1
- package/dist/harness/sensors.js +32 -9
- package/dist/harness/sensors.js.map +1 -1
- package/dist/orchestrator/ai-rules-updater.d.ts +11 -3
- package/dist/orchestrator/ai-rules-updater.d.ts.map +1 -1
- package/dist/orchestrator/ai-rules-updater.js +44 -180
- package/dist/orchestrator/ai-rules-updater.js.map +1 -1
- package/dist/orchestrator/ai-skills/adapters.d.ts +28 -0
- package/dist/orchestrator/ai-skills/adapters.d.ts.map +1 -0
- package/dist/orchestrator/ai-skills/adapters.js +34 -0
- package/dist/orchestrator/ai-skills/adapters.js.map +1 -0
- package/dist/orchestrator/ai-skills/build.d.ts +10 -0
- package/dist/orchestrator/ai-skills/build.d.ts.map +1 -0
- package/dist/orchestrator/ai-skills/build.js +128 -0
- package/dist/orchestrator/ai-skills/build.js.map +1 -0
- package/dist/orchestrator/ai-skills/cap-stripper.d.ts +27 -0
- package/dist/orchestrator/ai-skills/cap-stripper.d.ts.map +1 -0
- package/dist/orchestrator/ai-skills/cap-stripper.js +78 -0
- package/dist/orchestrator/ai-skills/cap-stripper.js.map +1 -0
- package/dist/orchestrator/ai-skills/commands.d.ts +22 -0
- package/dist/orchestrator/ai-skills/commands.d.ts.map +1 -0
- package/dist/orchestrator/ai-skills/commands.js +109 -0
- package/dist/orchestrator/ai-skills/commands.js.map +1 -0
- package/dist/orchestrator/ai-skills/generator.d.ts +23 -0
- package/dist/orchestrator/ai-skills/generator.d.ts.map +1 -0
- package/dist/orchestrator/ai-skills/generator.js +79 -0
- package/dist/orchestrator/ai-skills/generator.js.map +1 -0
- package/dist/orchestrator/ai-skills/golden-skills.test.d.ts +2 -0
- package/dist/orchestrator/ai-skills/golden-skills.test.d.ts.map +1 -0
- package/dist/orchestrator/ai-skills/golden-skills.test.js +183 -0
- package/dist/orchestrator/ai-skills/golden-skills.test.js.map +1 -0
- package/dist/orchestrator/ai-skills/resolve-assistants.d.ts +8 -0
- package/dist/orchestrator/ai-skills/resolve-assistants.d.ts.map +1 -0
- package/dist/orchestrator/ai-skills/resolve-assistants.js +28 -0
- package/dist/orchestrator/ai-skills/resolve-assistants.js.map +1 -0
- package/dist/orchestrator/ai-skills/writer.d.ts +15 -0
- package/dist/orchestrator/ai-skills/writer.d.ts.map +1 -0
- package/dist/orchestrator/ai-skills/writer.js +129 -0
- package/dist/orchestrator/ai-skills/writer.js.map +1 -0
- package/dist/orchestrator/flow-manager.d.ts +11 -0
- package/dist/orchestrator/flow-manager.d.ts.map +1 -1
- package/dist/orchestrator/flow-manager.js +147 -29
- package/dist/orchestrator/flow-manager.js.map +1 -1
- package/dist/orchestrator/mobile-runtime-scaffolder.d.ts +59 -0
- package/dist/orchestrator/mobile-runtime-scaffolder.d.ts.map +1 -0
- package/dist/orchestrator/mobile-runtime-scaffolder.js +298 -0
- package/dist/orchestrator/mobile-runtime-scaffolder.js.map +1 -0
- package/dist/orchestrator/project-initializer.d.ts +44 -7
- package/dist/orchestrator/project-initializer.d.ts.map +1 -1
- package/dist/orchestrator/project-initializer.js +147 -79
- package/dist/orchestrator/project-initializer.js.map +1 -1
- package/dist/orchestrator/screen-manager.d.ts +30 -0
- package/dist/orchestrator/screen-manager.d.ts.map +1 -1
- package/dist/orchestrator/screen-manager.js +205 -22
- package/dist/orchestrator/screen-manager.js.map +1 -1
- package/dist/orchestrator/templates/ai-src/README.md +58 -0
- package/dist/orchestrator/templates/{ai-instructions/claude-cmd-add-flow.md → ai-src/commands/add-flow.md} +63 -2
- package/dist/orchestrator/templates/{ai-instructions/claude-cmd-add-screen.md → ai-src/commands/add-screen.md} +171 -6
- package/dist/orchestrator/templates/{ai-instructions/claude-cmd-create-test.md → ai-src/commands/create-test.md} +118 -5
- package/{src/orchestrator/templates/ai-instructions/claude-cmd-dashboard.md → dist/orchestrator/templates/ai-src/commands/dashboard.md} +25 -3
- package/{src/orchestrator/templates/ai-instructions/claude-cmd-delivery.md → dist/orchestrator/templates/ai-src/commands/delivery.md} +67 -3
- package/dist/orchestrator/templates/ai-src/commands/design.md +29 -0
- package/{src/orchestrator/templates/ai-instructions/claude-cmd-feedback.md → dist/orchestrator/templates/ai-src/commands/feedback.md} +34 -3
- package/dist/orchestrator/templates/{ai-instructions/claude-cmd-locale.md → ai-src/commands/locale.md} +56 -4
- package/{src/orchestrator/templates/ai-instructions/claude-cmd-review.md → dist/orchestrator/templates/ai-src/commands/review.md} +57 -2
- package/dist/orchestrator/templates/{ai-instructions/claude-cmd-run-test.md → ai-src/commands/run-test.md} +116 -8
- package/dist/orchestrator/templates/ai-src/config/codex.md +8 -0
- package/{src/orchestrator/templates/ai-instructions/claude-skill-capture-mobile.md → dist/orchestrator/templates/ai-src/skills/sungen-capture-mobile/SKILL.md} +11 -0
- package/dist/orchestrator/templates/{ai-instructions/github-skill-sungen-error-mapping.md → ai-src/skills/sungen-error-mapping/SKILL.md} +31 -10
- package/{src/orchestrator/templates/ai-instructions/claude-skill-harness-audit.md → dist/orchestrator/templates/ai-src/skills/sungen-harness-audit/SKILL.md} +5 -5
- package/{src/orchestrator/templates/ai-instructions/claude-skill-locale.md → dist/orchestrator/templates/ai-src/skills/sungen-locale/SKILL.md} +275 -3
- package/{src/orchestrator/templates/ai-instructions/github-skill-sungen-selector-fix.md → dist/orchestrator/templates/ai-src/skills/sungen-selector-fix/SKILL.md} +17 -0
- package/{src/orchestrator/templates/ai-instructions/claude-skill-selector-fix-mobile.md → dist/orchestrator/templates/ai-src/skills/sungen-selector-fix-mobile/SKILL.md} +5 -0
- package/dist/orchestrator/templates/{ai-instructions/claude-skill-tc-generation.md → ai-src/skills/sungen-tc-generation/SKILL.md} +5 -0
- package/dist/orchestrator/templates/playwright.config.ts +7 -4
- package/package.json +3 -3
- package/src/capabilities/discover.ts +29 -3
- package/src/cli/commands/add-flow.ts +2 -0
- package/src/cli/commands/add.ts +4 -0
- package/src/cli/commands/capability.ts +64 -1
- package/src/cli/commands/delivery.ts +89 -2
- package/src/cli/commands/eval.ts +3 -3
- package/src/cli/commands/generate.ts +2 -1
- package/src/cli/commands/init.ts +50 -3
- package/src/cli/commands/journey.ts +20 -3
- package/src/cli/commands/update.ts +14 -4
- package/src/dashboard/snapshot-builder.ts +10 -1
- package/src/exporters/csv-exporter.ts +3 -1
- package/src/exporters/json-exporter.ts +3 -1
- package/src/exporters/mobile-app-id.ts +34 -0
- package/src/exporters/spec-parser.ts +6 -2
- package/src/generators/test-generator/adapters/adapter-interface.ts +3 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/actions/scroll-action.hbs +7 -4
- package/src/generators/test-generator/adapters/appium/templates/steps/actions/toggle-action.hbs +20 -3
- package/src/generators/test-generator/adapters/appium/templates/steps/assertions/checked-assertion.hbs +4 -1
- package/src/generators/test-generator/adapters/appium/templates/steps/assertions/not-checked-assertion.hbs +4 -1
- package/src/generators/test-generator/adapters/appium/templates/test-file.hbs +3 -0
- package/src/generators/test-generator/code-generator.ts +49 -9
- package/src/generators/test-generator/template-engine.ts +14 -1
- package/src/generators/test-generator/utils/selector-resolver.ts +51 -1
- package/src/harness/audit.ts +9 -2
- package/src/harness/catalog/universal-viewpoints.yaml +15 -0
- package/src/harness/eval/skill-lint.ts +71 -60
- package/src/harness/journey.ts +167 -19
- package/src/harness/quality-gates.ts +20 -0
- package/src/harness/sensors.ts +25 -8
- package/src/orchestrator/ai-rules-updater.ts +35 -197
- package/src/orchestrator/ai-skills/adapters.ts +52 -0
- package/src/orchestrator/ai-skills/build.ts +103 -0
- package/src/orchestrator/ai-skills/cap-stripper.ts +85 -0
- package/src/orchestrator/ai-skills/commands.ts +112 -0
- package/src/orchestrator/ai-skills/generator.ts +47 -0
- package/src/orchestrator/ai-skills/golden-skills.test.ts +124 -0
- package/src/orchestrator/ai-skills/resolve-assistants.ts +18 -0
- package/src/orchestrator/ai-skills/writer.ts +92 -0
- package/src/orchestrator/flow-manager.ts +165 -29
- package/src/orchestrator/mobile-runtime-scaffolder.ts +277 -0
- package/src/orchestrator/project-initializer.ts +159 -86
- package/src/orchestrator/screen-manager.ts +237 -22
- package/src/orchestrator/templates/ai-src/README.md +58 -0
- package/src/orchestrator/templates/{ai-instructions/claude-cmd-add-flow.md → ai-src/commands/add-flow.md} +63 -2
- package/src/orchestrator/templates/{ai-instructions/claude-cmd-add-screen.md → ai-src/commands/add-screen.md} +171 -6
- package/src/orchestrator/templates/{ai-instructions/claude-cmd-create-test.md → ai-src/commands/create-test.md} +118 -5
- package/{dist/orchestrator/templates/ai-instructions/claude-cmd-dashboard.md → src/orchestrator/templates/ai-src/commands/dashboard.md} +25 -3
- package/{dist/orchestrator/templates/ai-instructions/claude-cmd-delivery.md → src/orchestrator/templates/ai-src/commands/delivery.md} +67 -3
- package/src/orchestrator/templates/ai-src/commands/design.md +29 -0
- package/{dist/orchestrator/templates/ai-instructions/claude-cmd-feedback.md → src/orchestrator/templates/ai-src/commands/feedback.md} +34 -3
- package/src/orchestrator/templates/{ai-instructions/claude-cmd-locale.md → ai-src/commands/locale.md} +56 -4
- package/{dist/orchestrator/templates/ai-instructions/claude-cmd-review.md → src/orchestrator/templates/ai-src/commands/review.md} +57 -2
- package/src/orchestrator/templates/{ai-instructions/claude-cmd-run-test.md → ai-src/commands/run-test.md} +116 -8
- package/src/orchestrator/templates/ai-src/config/codex.md +8 -0
- package/{dist/orchestrator/templates/ai-instructions/claude-skill-capture-mobile.md → src/orchestrator/templates/ai-src/skills/sungen-capture-mobile/SKILL.md} +11 -0
- package/{dist/orchestrator/templates/ai-instructions/claude-skill-error-mapping.md → src/orchestrator/templates/ai-src/skills/sungen-error-mapping/SKILL.md} +31 -10
- package/{dist/orchestrator/templates/ai-instructions/claude-skill-harness-audit.md → src/orchestrator/templates/ai-src/skills/sungen-harness-audit/SKILL.md} +5 -5
- package/{dist/orchestrator/templates/ai-instructions/claude-skill-locale.md → src/orchestrator/templates/ai-src/skills/sungen-locale/SKILL.md} +275 -3
- package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-selector-fix.md → src/orchestrator/templates/ai-src/skills/sungen-selector-fix/SKILL.md} +17 -0
- package/{dist/orchestrator/templates/ai-instructions/claude-skill-selector-fix-mobile.md → src/orchestrator/templates/ai-src/skills/sungen-selector-fix-mobile/SKILL.md} +5 -0
- package/src/orchestrator/templates/{ai-instructions/claude-skill-tc-generation.md → ai-src/skills/sungen-tc-generation/SKILL.md} +5 -0
- package/src/orchestrator/templates/playwright.config.ts +7 -4
- package/dist/orchestrator/templates/ai-instructions/claude-cmd-design.md +0 -12
- package/dist/orchestrator/templates/ai-instructions/claude-skill-selector-fix.md +0 -347
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-add-flow.md +0 -86
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-add-screen.md +0 -131
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-create-test.md +0 -94
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-dashboard.md +0 -65
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-delivery.md +0 -83
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-design.md +0 -13
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-feedback.md +0 -24
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-locale.md +0 -70
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-review.md +0 -38
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-run-test.md +0 -158
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mobile.md +0 -184
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-harness-audit.md +0 -85
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-locale.md +0 -291
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-selector-fix-mobile.md +0 -316
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-selector-keys.md +0 -221
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-tc-generation.md +0 -617
- package/src/orchestrator/templates/ai-instructions/claude-cmd-design.md +0 -12
- package/src/orchestrator/templates/ai-instructions/claude-skill-api-design.md +0 -62
- package/src/orchestrator/templates/ai-instructions/claude-skill-capture-mode-figma-mcp.md +0 -82
- package/src/orchestrator/templates/ai-instructions/claude-skill-capture-mode-figma-pat.md +0 -117
- package/src/orchestrator/templates/ai-instructions/claude-skill-capture-mode-live.md +0 -60
- package/src/orchestrator/templates/ai-instructions/claude-skill-capture-mode-local.md +0 -38
- package/src/orchestrator/templates/ai-instructions/claude-skill-capture.md +0 -35
- package/src/orchestrator/templates/ai-instructions/claude-skill-dashboard.md +0 -121
- package/src/orchestrator/templates/ai-instructions/claude-skill-delivery.md +0 -141
- package/src/orchestrator/templates/ai-instructions/claude-skill-error-mapping.md +0 -176
- package/src/orchestrator/templates/ai-instructions/claude-skill-gherkin-syntax.md +0 -446
- package/src/orchestrator/templates/ai-instructions/claude-skill-ingest-legacy.md +0 -79
- package/src/orchestrator/templates/ai-instructions/claude-skill-mobile-gestures.md +0 -109
- package/src/orchestrator/templates/ai-instructions/claude-skill-selector-fix.md +0 -347
- package/src/orchestrator/templates/ai-instructions/claude-skill-tc-review.md +0 -320
- package/src/orchestrator/templates/ai-instructions/claude-skill-test-design-techniques.md +0 -118
- package/src/orchestrator/templates/ai-instructions/claude-skill-viewpoint-group-a-data-entry.md +0 -203
- package/src/orchestrator/templates/ai-instructions/claude-skill-viewpoint-group-b-data-ops.md +0 -179
- package/src/orchestrator/templates/ai-instructions/claude-skill-viewpoint-group-c-data-explore.md +0 -233
- package/src/orchestrator/templates/ai-instructions/claude-skill-viewpoint-group-d-display.md +0 -226
- package/src/orchestrator/templates/ai-instructions/claude-skill-viewpoint-group-e-identity.md +0 -177
- package/src/orchestrator/templates/ai-instructions/claude-skill-viewpoint.md +0 -118
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-add-flow.md +0 -86
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-add-screen.md +0 -131
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-create-test.md +0 -94
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-dashboard.md +0 -65
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-delivery.md +0 -83
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-design.md +0 -13
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-feedback.md +0 -24
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-locale.md +0 -70
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-review.md +0 -38
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-run-test.md +0 -158
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-api-design.md +0 -62
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mobile.md +0 -184
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mode-figma-mcp.md +0 -82
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mode-figma-pat.md +0 -117
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mode-live.md +0 -60
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mode-local.md +0 -38
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-capture.md +0 -35
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-dashboard.md +0 -121
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-delivery.md +0 -141
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-error-mapping.md +0 -176
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-gherkin-syntax.md +0 -446
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-harness-audit.md +0 -85
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-ingest-legacy.md +0 -79
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-locale.md +0 -291
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-mobile-gestures.md +0 -109
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-selector-fix-mobile.md +0 -316
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-selector-keys.md +0 -221
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-tc-generation.md +0 -617
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-tc-review.md +0 -320
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-test-design-techniques.md +0 -118
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-a-data-entry.md +0 -203
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-b-data-ops.md +0 -179
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-c-data-explore.md +0 -233
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-d-display.md +0 -226
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-e-identity.md +0 -177
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint.md +0 -118
- /package/dist/orchestrator/templates/{ai-instructions/claude-agent-challenge.md → ai-src/agents/challenge.md} +0 -0
- /package/dist/orchestrator/templates/{ai-instructions/claude-agent-discovery.md → ai-src/agents/discovery.md} +0 -0
- /package/dist/orchestrator/templates/{ai-instructions/claude-agent-generator.md → ai-src/agents/generator.md} +0 -0
- /package/dist/orchestrator/templates/{ai-instructions/claude-agent-reviewer.md → ai-src/agents/reviewer.md} +0 -0
- /package/dist/orchestrator/templates/{ai-instructions/claude-config.md → ai-src/config/claude.md} +0 -0
- /package/dist/orchestrator/templates/{ai-instructions/copilot-config.md → ai-src/config/copilot.md} +0 -0
- /package/dist/orchestrator/templates/{ai-instructions/claude-skill-api-design.md → ai-src/skills/sungen-api-design/SKILL.md} +0 -0
- /package/dist/orchestrator/templates/{ai-instructions/claude-skill-capture.md → ai-src/skills/sungen-capture/SKILL.md} +0 -0
- /package/dist/orchestrator/templates/{ai-instructions/claude-skill-capture-mode-figma-mcp.md → ai-src/skills/sungen-capture/mode-figma-mcp.md} +0 -0
- /package/dist/orchestrator/templates/{ai-instructions/claude-skill-capture-mode-figma-pat.md → ai-src/skills/sungen-capture/mode-figma-pat.md} +0 -0
- /package/dist/orchestrator/templates/{ai-instructions/claude-skill-capture-mode-live.md → ai-src/skills/sungen-capture/mode-live.md} +0 -0
- /package/dist/orchestrator/templates/{ai-instructions/claude-skill-capture-mode-local.md → ai-src/skills/sungen-capture/mode-local.md} +0 -0
- /package/dist/orchestrator/templates/{ai-instructions/claude-skill-dashboard.md → ai-src/skills/sungen-dashboard/SKILL.md} +0 -0
- /package/dist/orchestrator/templates/{ai-instructions/claude-skill-delivery.md → ai-src/skills/sungen-delivery/SKILL.md} +0 -0
- /package/dist/orchestrator/templates/{ai-instructions/claude-skill-gherkin-syntax.md → ai-src/skills/sungen-gherkin-syntax/SKILL.md} +0 -0
- /package/dist/orchestrator/templates/{ai-instructions/claude-skill-ingest-legacy.md → ai-src/skills/sungen-ingest-legacy/SKILL.md} +0 -0
- /package/dist/orchestrator/templates/{ai-instructions/claude-skill-mobile-gestures.md → ai-src/skills/sungen-mobile-gestures/SKILL.md} +0 -0
- /package/dist/orchestrator/templates/{ai-instructions/claude-skill-selector-keys.md → ai-src/skills/sungen-selector-keys/SKILL.md} +0 -0
- /package/dist/orchestrator/templates/{ai-instructions/claude-skill-tc-review.md → ai-src/skills/sungen-tc-review/SKILL.md} +0 -0
- /package/dist/orchestrator/templates/{ai-instructions/claude-skill-test-design-techniques.md → ai-src/skills/sungen-test-design-techniques/SKILL.md} +0 -0
- /package/dist/orchestrator/templates/{ai-instructions/claude-skill-viewpoint.md → ai-src/skills/sungen-viewpoint/SKILL.md} +0 -0
- /package/dist/orchestrator/templates/{ai-instructions/claude-skill-viewpoint-group-a-data-entry.md → ai-src/skills/sungen-viewpoint/group-a-data-entry.md} +0 -0
- /package/dist/orchestrator/templates/{ai-instructions/claude-skill-viewpoint-group-b-data-ops.md → ai-src/skills/sungen-viewpoint/group-b-data-ops.md} +0 -0
- /package/dist/orchestrator/templates/{ai-instructions/claude-skill-viewpoint-group-c-data-explore.md → ai-src/skills/sungen-viewpoint/group-c-data-explore.md} +0 -0
- /package/dist/orchestrator/templates/{ai-instructions/claude-skill-viewpoint-group-d-display.md → ai-src/skills/sungen-viewpoint/group-d-display.md} +0 -0
- /package/dist/orchestrator/templates/{ai-instructions/claude-skill-viewpoint-group-e-identity.md → ai-src/skills/sungen-viewpoint/group-e-identity.md} +0 -0
- /package/src/orchestrator/templates/{ai-instructions/claude-agent-challenge.md → ai-src/agents/challenge.md} +0 -0
- /package/src/orchestrator/templates/{ai-instructions/claude-agent-discovery.md → ai-src/agents/discovery.md} +0 -0
- /package/src/orchestrator/templates/{ai-instructions/claude-agent-generator.md → ai-src/agents/generator.md} +0 -0
- /package/src/orchestrator/templates/{ai-instructions/claude-agent-reviewer.md → ai-src/agents/reviewer.md} +0 -0
- /package/src/orchestrator/templates/{ai-instructions/claude-config.md → ai-src/config/claude.md} +0 -0
- /package/src/orchestrator/templates/{ai-instructions/copilot-config.md → ai-src/config/copilot.md} +0 -0
- /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-api-design.md → src/orchestrator/templates/ai-src/skills/sungen-api-design/SKILL.md} +0 -0
- /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-capture.md → src/orchestrator/templates/ai-src/skills/sungen-capture/SKILL.md} +0 -0
- /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mode-figma-mcp.md → src/orchestrator/templates/ai-src/skills/sungen-capture/mode-figma-mcp.md} +0 -0
- /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mode-figma-pat.md → src/orchestrator/templates/ai-src/skills/sungen-capture/mode-figma-pat.md} +0 -0
- /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mode-live.md → src/orchestrator/templates/ai-src/skills/sungen-capture/mode-live.md} +0 -0
- /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mode-local.md → src/orchestrator/templates/ai-src/skills/sungen-capture/mode-local.md} +0 -0
- /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-dashboard.md → src/orchestrator/templates/ai-src/skills/sungen-dashboard/SKILL.md} +0 -0
- /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-delivery.md → src/orchestrator/templates/ai-src/skills/sungen-delivery/SKILL.md} +0 -0
- /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-gherkin-syntax.md → src/orchestrator/templates/ai-src/skills/sungen-gherkin-syntax/SKILL.md} +0 -0
- /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-ingest-legacy.md → src/orchestrator/templates/ai-src/skills/sungen-ingest-legacy/SKILL.md} +0 -0
- /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-mobile-gestures.md → src/orchestrator/templates/ai-src/skills/sungen-mobile-gestures/SKILL.md} +0 -0
- /package/src/orchestrator/templates/{ai-instructions/claude-skill-selector-keys.md → ai-src/skills/sungen-selector-keys/SKILL.md} +0 -0
- /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-tc-review.md → src/orchestrator/templates/ai-src/skills/sungen-tc-review/SKILL.md} +0 -0
- /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-test-design-techniques.md → src/orchestrator/templates/ai-src/skills/sungen-test-design-techniques/SKILL.md} +0 -0
- /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint.md → src/orchestrator/templates/ai-src/skills/sungen-viewpoint/SKILL.md} +0 -0
- /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-a-data-entry.md → src/orchestrator/templates/ai-src/skills/sungen-viewpoint/group-a-data-entry.md} +0 -0
- /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-b-data-ops.md → src/orchestrator/templates/ai-src/skills/sungen-viewpoint/group-b-data-ops.md} +0 -0
- /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-c-data-explore.md → src/orchestrator/templates/ai-src/skills/sungen-viewpoint/group-c-data-explore.md} +0 -0
- /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-d-display.md → src/orchestrator/templates/ai-src/skills/sungen-viewpoint/group-d-display.md} +0 -0
- /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-e-identity.md → src/orchestrator/templates/ai-src/skills/sungen-viewpoint/group-e-identity.md} +0 -0
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: sungen-error-mapping
|
|
3
|
-
description: 'Error diagnosis and fix strategy — systematic debugging flow, error patterns, fix priorities. Auto-loaded during run-test.'
|
|
4
|
-
user-invocable: false
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Diagnosis Flow (before fixing anything)
|
|
8
|
-
|
|
9
|
-
**Step 1: Read the error** — extract: error type, element name, expected vs actual, file:line.
|
|
10
|
-
|
|
11
|
-
**Step 2: Read error context** — check `test-results/` for the snapshot at failure time. This shows the exact page state when the test failed — more reliable than re-navigating with MCP.
|
|
12
|
-
|
|
13
|
-
**Step 3: Compare** — match the failing selector against the snapshot. Ask:
|
|
14
|
-
- Does the element exist on the page?
|
|
15
|
-
- Does the accessible name match exactly?
|
|
16
|
-
- Are there multiple matches (strict mode)?
|
|
17
|
-
- Is the element inside an iframe or dialog?
|
|
18
|
-
- Is the page in the expected state (correct URL, loaded)?
|
|
19
|
-
|
|
20
|
-
Then choose the fix from the patterns below.
|
|
21
|
-
|
|
22
|
-
---
|
|
23
|
-
|
|
24
|
-
## ⛔ Source of truth — classify EVERY failure before you "fix" it
|
|
25
|
-
|
|
26
|
-
`.feature` + `test-data.yaml` + `spec.md` are the **oracle**. The **live page is NOT** — it may be the thing that's broken. A failing test is not automatically a test to "make pass". Classify first:
|
|
27
|
-
|
|
28
|
-
- **Selector-resolution failure** (element not found / wrong locator / strict-mode / wrong element type) → the test looked in the wrong place. **Fix the locator in `selectors.yaml`** (re-snapshot, copy the exact accessible name). Legit auto-fix.
|
|
29
|
-
- **Assertion-value failure** (element FOUND, but observed value ≠ expected) → STOP and ask: *is the TEST wrong, or is the APP wrong?*
|
|
30
|
-
- Expected value/rule is wrong **relative to `spec.md`** (typo, stale test-data) → fix `test-data.yaml`/`.feature` so it matches the **spec** — never the live page.
|
|
31
|
-
- App behaviour contradicts `spec.md` (spec says X, app shows Y) → **CANDIDATE BUG**. **Report it** (let the test FAIL / surface to the QA in the run summary). **NEVER** change the expected value, loosen the rule, weaken the assertion (`toHaveText`→`toContainText` to dodge a mismatch), edit `.feature`, or edit the generated `.spec.ts` to make it pass.
|
|
32
|
-
|
|
33
|
-
> **Cardinal sin (do NOT do this):** a `password > 8 chars` rule fails on a 6-char input → "fix" it to `>= 6` so the test passes. The logic is now meaningless. A failing assertion is a **finding**, not a chore.
|
|
34
|
-
|
|
35
|
-
**Auto-fix loop scope:** the run-test auto-fix loop engages ONLY on **selector-resolution** failures. On an assertion-value failure where the app contradicts the spec → **HALT and report**, do not loop it into passing.
|
|
36
|
-
|
|
37
|
-
**Never hand-edit the generated `.spec.ts`** (e.g. inserting `page.evaluate`/`fetch` to bypass a broken control). `sungen script-check` regenerates the spec from `.feature` and flags any edit as DRIFT — regenerate, don't patch.
|
|
38
|
-
|
|
39
|
-
---
|
|
40
|
-
|
|
41
|
-
## Fix Priority (try in order)
|
|
42
|
-
|
|
43
|
-
1. **Auth issue** — page redirected to login? Fix auth first, everything else is noise
|
|
44
|
-
2. **Element not found** — wrong name/type/value in selectors.yaml. Re-snapshot, copy exact name
|
|
45
|
-
3. **Multiple matches** — add `nth`, `exact: true`, or `scope` to narrow down
|
|
46
|
-
4. **Wrong assertion** — `toHaveText` vs `toHaveValue` mismatch, wrong expected data
|
|
47
|
-
5. **Timing** — SPA not loaded, async content. Add `wait for` step in .feature
|
|
48
|
-
|
|
49
|
-
---
|
|
50
|
-
|
|
51
|
-
## Playwright Errors
|
|
52
|
-
|
|
53
|
-
### Selector errors → fix in `selectors.yaml`
|
|
54
|
-
|
|
55
|
-
| Error | Diagnosis | Fix |
|
|
56
|
-
|---|---|---|
|
|
57
|
-
| strict mode violation | Multiple elements match | Add `nth: 0`, `exact: true`, or more specific `name` |
|
|
58
|
-
| Timeout / not found | Element doesn't exist or name wrong | Re-snapshot → copy exact accessible name. Check iframe/dialog scope |
|
|
59
|
-
| Element is not an input | Wrong element type targeted | Change `type` or `value` to match actual element |
|
|
60
|
-
| not a select | Custom dropdown, not native `<select>` | Set `variant: 'custom'` |
|
|
61
|
-
| Frame not found | iframe selector wrong or doesn't exist | Fix `frame` value, verify iframe in snapshot |
|
|
62
|
-
|
|
63
|
-
### Assertion errors → apply the Source-of-truth gate above FIRST
|
|
64
|
-
|
|
65
|
-
> The "Fix" column below applies **only when the expected value was wrong relative to `spec.md`** (a test defect). If the app's value contradicts the spec, the row is a **candidate bug → report it, do not edit the expected to match live**. Never weaken `toHaveText`→`toContainText` just to pass.
|
|
66
|
-
|
|
67
|
-
| Error | Diagnosis | Fix (only if the TEST was wrong per spec) |
|
|
68
|
-
|---|---|---|
|
|
69
|
-
| toHaveText mismatch | Expected text differs from actual | If the test's expected was wrong per spec → fix value in test-data. If element is input type → change Gherkin type to `field`/`textarea` (triggers `toHaveValue`). If the app value contradicts spec → **report as bug**. |
|
|
70
|
-
| toHaveValue mismatch | Expected value differs from actual | Fix value in test-data |
|
|
71
|
-
| toContainText mismatch | Partial text not found | Fix expected partial text in test-data |
|
|
72
|
-
| toBeVisible timeout | Element exists but hidden, or name wrong | Check: is element conditionally visible? Wrong name? Inside dialog? |
|
|
73
|
-
| toHaveCount mismatch | Row count differs | Fix expected count in test-data. Verify: is table loaded? Filtered? |
|
|
74
|
-
|
|
75
|
-
### Assertion type rule
|
|
76
|
-
|
|
77
|
-
Sungen picks assertion based on element type:
|
|
78
|
-
- **Input** (`field`, `textarea`, `search`, `dropdown`, `slider`) → `toHaveValue()`
|
|
79
|
-
- **Text** (everything else: `message`, `heading`, `label`, `row`) → `toHaveText()`
|
|
80
|
-
- **Partial** (`contains` keyword) → `toContainText()`
|
|
81
|
-
|
|
82
|
-
If `toHaveText` fails on an input → the Gherkin step has wrong target type. Fix: change type in `.feature`.
|
|
83
|
-
|
|
84
|
-
---
|
|
85
|
-
|
|
86
|
-
## Table-Specific Errors
|
|
87
|
-
|
|
88
|
-
| Error | Diagnosis | Fix |
|
|
89
|
-
|---|---|---|
|
|
90
|
-
| `tableRow is not defined` | Column assertion without preceding row scope step | Add `User see [Ref] row in [Table] table with {{v}}` before `User see [Col] column with {{v}}` |
|
|
91
|
-
| `toHaveText` on cell fails (with columns) | Wrong column index in `columns` config | Re-count columns in snapshot (0-indexed). Fix `index` in selectors.yaml |
|
|
92
|
-
| `toBeVisible` on cell fails (no columns) | `filter({ hasText })` didn't match | Check exact cell text in snapshot. Fix value in test-data |
|
|
93
|
-
| Row filter matches 0 rows | Filter text doesn't match any row content | Re-snapshot → find actual row text. Fix filter value in test-data |
|
|
94
|
-
| Row filter matches multiple rows | Filter text is too generic (matches multiple rows) | Use more specific filter text (unique identifier like email, ID) |
|
|
95
|
-
| Table not found | Wrong table name or table not rendered | Re-snapshot → copy exact table accessible name |
|
|
96
|
-
|
|
97
|
-
---
|
|
98
|
-
|
|
99
|
-
## Auth Errors
|
|
100
|
-
|
|
101
|
-
| Symptom | Fix |
|
|
102
|
-
|---|---|
|
|
103
|
-
| Redirect to login page | Auth expired. Ask user to log in manually via MCP browser |
|
|
104
|
-
| `storageState` file not found | Ask user to log in manually via MCP browser, then save storage state |
|
|
105
|
-
| Most tests timeout on first step | Auth expired — ask user to re-authenticate via MCP browser |
|
|
106
|
-
| Page shows home instead of target | SPA + expired auth. Re-authenticate + add `wait for` step |
|
|
107
|
-
|
|
108
|
-
**Never use `sungen makeauth`.** Always let the user log in manually via the MCP browser.
|
|
109
|
-
|
|
110
|
-
---
|
|
111
|
-
|
|
112
|
-
## Sungen Compile Errors
|
|
113
|
-
|
|
114
|
-
| Error | Fix |
|
|
115
|
-
|---|---|
|
|
116
|
-
| Unknown step pattern | Rewrite step to match `sungen-gherkin-syntax` patterns |
|
|
117
|
-
| Missing selector | Add key to `selectors.yaml` |
|
|
118
|
-
| Missing variable | Add key to `test-data.yaml` |
|
|
119
|
-
| Invalid selector type | Use: role/testid/placeholder/label/text/locator/page/upload/frame |
|
|
120
|
-
|
|
121
|
-
---
|
|
122
|
-
|
|
123
|
-
## Flow-Specific Errors
|
|
124
|
-
|
|
125
|
-
| Error | Diagnosis | Fix |
|
|
126
|
-
|---|---|---|
|
|
127
|
-
| Navigation timeout between screens | Cross-screen transition takes too long or URL mismatch | Add explicit `wait for page` step between screen transitions in `.feature`. Verify target URL path |
|
|
128
|
-
| Selector `"screen:element"` not found | Namespace key missing or wrong format | Ensure colon-namespaced key in `selectors.yaml` is **quoted**: `"login:submit":`. Check screen prefix matches `[Screen:Element]` ref in Gherkin |
|
|
129
|
-
| Test data `screen.key` undefined | Phase namespace mismatch | Verify `test-data.yaml` uses dot-namespaced keys: `login.email`, `submission.nominee`. Keys must match `{{screen.key}}` refs in `.feature` |
|
|
130
|
-
| State lost between screens | Auth/session expired during multi-screen flow | Ensure all screens in the flow share the same `@auth:role` tag. Check if the app invalidates sessions on navigation |
|
|
131
|
-
| Duplicate selector key across screens | Two screens use same element name without namespace | Always use `[Screen:Element]` format in flow `.feature`. Selectors must use `"screen:element":` quoted keys |
|
|
132
|
-
|
|
133
|
-
---
|
|
134
|
-
|
|
135
|
-
## Performance & Infrastructure Errors → Fix in `specs/base.ts`
|
|
136
|
-
|
|
137
|
-
All generated `.spec.ts` import from `specs/base.ts` — shared context caching, navigation, overlay cleanup. AI **can and should** tune `base.ts` to match the project.
|
|
138
|
-
|
|
139
|
-
| Symptom | Root cause | Fix |
|
|
140
|
-
|---|---|---|
|
|
141
|
-
| Server 429 (rate limited) | Too many browser contexts | Fix `contextCache` to reuse sessions per `storageState` |
|
|
142
|
-
| Tests slow with `--workers=1` | Redundant navigation | Fix goto patch: skip if `currentPath === url` |
|
|
143
|
-
| Previous test's modal blocks next | Overlay not cleaned up | Add/improve Escape + backdrop click in cleanup hook |
|
|
144
|
-
| All tests fail on first navigation | `page.url()` is `about:blank` | Add try/catch in goto patch |
|
|
145
|
-
| Flaky timeouts on SPA pages | Default timeout too short for app | Increase `actionTimeout` / `navigationTimeout` |
|
|
146
|
-
| Tests pass individually but fail in batch | Shared state leaking between tests | Isolate context per test or reset state in `beforeEach` |
|
|
147
|
-
|
|
148
|
-
### What AI CAN fix in `base.ts`
|
|
149
|
-
|
|
150
|
-
- Timeout tuning (increase for slow APIs, decrease for fast apps)
|
|
151
|
-
- Custom overlay/modal dismiss logic (project has unique close patterns)
|
|
152
|
-
- Navigation wait strategy (`networkidle` vs `domcontentloaded` vs custom)
|
|
153
|
-
- Context caching strategy (per-role, per-session)
|
|
154
|
-
- Cookie/localStorage cleanup between tests
|
|
155
|
-
|
|
156
|
-
### What AI should NOT move into `base.ts`
|
|
157
|
-
|
|
158
|
-
- Individual selector fixes → belong in `selectors.yaml`
|
|
159
|
-
- Test data values → belong in `test-data.yaml`
|
|
160
|
-
- Single-test workarounds → belong in the `.spec.ts` directly
|
|
161
|
-
|
|
162
|
-
---
|
|
163
|
-
|
|
164
|
-
## Smart Fix Strategy
|
|
165
|
-
|
|
166
|
-
### When multiple tests fail on the same element
|
|
167
|
-
Fix the **root cause once** — don't fix each test individually. Group by selector key, fix selectors.yaml, recompile, re-run batch.
|
|
168
|
-
|
|
169
|
-
### When you're unsure about the fix
|
|
170
|
-
**Re-snapshot** — `browser_navigate` to the failing page, take `browser_snapshot`, compare the live state against what the test expects. This is faster than guessing.
|
|
171
|
-
|
|
172
|
-
### When the fix might break other tests
|
|
173
|
-
After fixing selectors.yaml, run ALL tests (not just the failing one) to catch regressions from renamed/changed selectors.
|
|
174
|
-
|
|
175
|
-
### When nothing works after 3 attempts
|
|
176
|
-
Ask the user. The issue might be: dynamic content, race condition, environment-specific state, or a real application bug.
|
|
@@ -1,446 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: sungen-gherkin-syntax
|
|
3
|
-
description: 'Sungen Gherkin patterns, selector types, and YAML key rules. Auto-loaded when writing .feature, selectors.yaml, or test-data.yaml.'
|
|
4
|
-
user-invocable: false
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Standard Syntax
|
|
8
|
-
|
|
9
|
-
```
|
|
10
|
-
[Keyword] User <Action> [Target Name] <Target Type> <in [Parent Name] <Parent Type>> <with {{Value}}> <is State>
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
- **Actor**: Always `User`, always active voice.
|
|
14
|
-
- **Value**: `with {{snake_case}}` — never hardcode static data.
|
|
15
|
-
- **State**: `is <keyword>` — never use `{{}}` for states.
|
|
16
|
-
- **Parent scope**: `in [Parent] parentType` — optional, only when page has 2+ similar blocks needing disambiguation.
|
|
17
|
-
|
|
18
|
-
## Keyword → Action Rules
|
|
19
|
-
|
|
20
|
-
```
|
|
21
|
-
GIVEN → is on
|
|
22
|
-
WHEN → click · fill · select · press · clear · check · uncheck · hover
|
|
23
|
-
[⚠️ wait for — only for Spinner/Modal, minimize usage]
|
|
24
|
-
THEN → see
|
|
25
|
-
AND → inherits from preceding keyword
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
## Step Patterns (70 patterns)
|
|
29
|
-
|
|
30
|
-
### Setup / Form / Interaction
|
|
31
|
-
|
|
32
|
-
```
|
|
33
|
-
User is on [T] page | page with {{v}} | dialog
|
|
34
|
-
User fill [T] field | textarea | search | slider | date-picker with {{v}}
|
|
35
|
-
User fill [T] uploader with {{f}}
|
|
36
|
-
User clear [T] field
|
|
37
|
-
User check [T] checkbox | toggle | radio
|
|
38
|
-
User uncheck [T] checkbox | toggle
|
|
39
|
-
User select [T] dropdown with {{v}}
|
|
40
|
-
User click [T] button | tab | column | breadcrumb
|
|
41
|
-
User click [T] row with {{v}}
|
|
42
|
-
User double click [T] element
|
|
43
|
-
User hover [T] icon | row
|
|
44
|
-
User drag [T] to [T2]
|
|
45
|
-
User expand | collapse [T] row
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
**click + with {{Value}} rule**: NO value for static (`button`, `link`, `icon`, `tab`). WITH value only for dynamic lists (`row`, `item`, `card`, `option`).
|
|
49
|
-
|
|
50
|
-
### Alert / Keyboard / Wait / Scroll
|
|
51
|
-
|
|
52
|
-
```
|
|
53
|
-
User click [OK | Cancel] alert
|
|
54
|
-
User fill [T] alert with {{v}}
|
|
55
|
-
User see [message text] alert
|
|
56
|
-
User press Escape key | Enter on [T] field
|
|
57
|
-
User wait for N seconds | [T] dialog | [T] dialog is STATE | [T] page
|
|
58
|
-
User scroll to [T] section
|
|
59
|
-
User switch to [T] frame | [main] frame
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
> Alert steps must appear BEFORE the action that triggers the dialog.
|
|
63
|
-
|
|
64
|
-
### Assertions (8 patterns → determines Playwright assertion)
|
|
65
|
-
|
|
66
|
-
```
|
|
67
|
-
# 1. Visibility: User see [T] type (NEVER add "is visible") | is hidden
|
|
68
|
-
# 2. Text (toHaveText): User see [T] message | header | label with {{v}}
|
|
69
|
-
# 3. Partial (toContainText): User see [T] text contains {{v}}
|
|
70
|
-
# 4. Input (toHaveValue): User see [T] field | dropdown | date-picker | search | slider with {{v}}
|
|
71
|
-
# 5. State: User see [T] button is disabled | checkbox is checked | dialog with {{v}} is hidden
|
|
72
|
-
# 6. Attribute (toHaveAttribute): User see [T] image | link with {{v}}
|
|
73
|
-
# 7. Count: User see [T] row with {{count}}
|
|
74
|
-
# 8. Page: User see [T] page
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
### Collection / all-card (P5)
|
|
78
|
-
|
|
79
|
-
```
|
|
80
|
-
# Every element's TEXT matches a value (filter correctness, all items belong):
|
|
81
|
-
User see all [Result Product Name] text contains {{category_term}}
|
|
82
|
-
# Every CONTAINER holds a CHILD element (structural per-card proof — prove "each card has X"):
|
|
83
|
-
User see all [Product Card] contain [Product Name]
|
|
84
|
-
User see all [Product Card] contain [Add To Cart] button
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
Use the all-card form whenever a title claims *every / each* card/row exposes something — a single `User see [Add To Cart] button` does NOT prove "each card" and the harness Claim-Proof gate will flag it.
|
|
88
|
-
|
|
89
|
-
### Table
|
|
90
|
-
|
|
91
|
-
```
|
|
92
|
-
User see [Col] column in [Table] table
|
|
93
|
-
User see [Ref] row in [Table] table with {{v}}
|
|
94
|
-
User see [Ref] row in [Table] table with {{v}} is hidden
|
|
95
|
-
User see [Table] table with {{count}} | is empty
|
|
96
|
-
User see [Col] column with {{v}}
|
|
97
|
-
User click [Act] button in [Table] table with {{v}}
|
|
98
|
-
User see [Table] table match data:
|
|
99
|
-
| Header1 | Header2 |
|
|
100
|
-
| {{value1}} | {{value2}} |
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
Row scope: `see [Ref] row in [Table] table with {{v}}` enters scope. Subsequent `see [Col] column with {{v}}` checks cell in that row. Use `table match data:` for multi-row verification.
|
|
104
|
-
|
|
105
|
-
### Database verification (optional Data Driver)
|
|
106
|
-
|
|
107
|
-
Read-only DB-state checks. **Prefer named queries** — SQL lives in `qa/screens/<screen>/database/queries.yaml` (reviewed once, parameterized). Invoke with the `@query:<name>` annotation; it binds the result rows to `{{name}}`, then assert with `expect`:
|
|
108
|
-
|
|
109
|
-
```gherkin
|
|
110
|
-
@query:active_user # precondition: run query, bind {{active_user}}
|
|
111
|
-
@query:orders(buyer={{email}}) # …with explicit param override
|
|
112
|
-
Scenario: ...
|
|
113
|
-
Then expect {{active_user.count}} is at least {{one}} # ≥1 row
|
|
114
|
-
And expect {{active_user.first.status}} is "active" # first row's column
|
|
115
|
-
And expect {{orders.count}} is {{expected}} # exact count
|
|
116
|
-
And User see [Total] text is {{orders.first.total}} # UI ↔ DB
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
Path access on a bound result: `{{q.count}}`/`{{q.length}}`, `{{q.first.col}}`, `{{q.last.col}}`, `{{q[2].col}}`, `{{q.col}}` (= first row's col). `expect A is B` also supports `is at least` / `is at most` / `is not`. Tier-2 declarative (trivial inline, no catalog): `User see [<table>] row where [<col>] is {{v}} [has [<col2>] = "x"]`, `… no row where …`, `… count is {{n}}`. Full grammar + catalog/datasource/secret rules → **Advanced → Database** doc. Only emit DB steps when the project has a `database/` catalog / `datasources.yaml`.
|
|
120
|
-
|
|
121
|
-
### States
|
|
122
|
-
|
|
123
|
-
`hidden` `visible` `disabled` `enabled` `checked` `unchecked` `focused` `empty` `loading` `selected` `sorted ascending` `sorted descending`
|
|
124
|
-
|
|
125
|
-
### Element Types
|
|
126
|
-
|
|
127
|
-
| Group | Types |
|
|
128
|
-
|---|---|
|
|
129
|
-
| **Context** | `page` `dialog` `modal` `drawer` `tab` `alert` `overlay` `step` |
|
|
130
|
-
| **Input** | `field` `textarea` `search` `dropdown` `option` `checkbox` `radio` `toggle` `uploader` `slider` `date-picker` |
|
|
131
|
-
| **Trigger** | `button` `link` `icon` `menuitem` `tag` |
|
|
132
|
-
| **Data** | `table` `row` `column` `cell` `list` `item` `card` `section` |
|
|
133
|
-
| **Feedback** | `message` `header` `label` `text` `tooltip` `badge` `breadcrumb` `image` |
|
|
134
|
-
| **System** | `key` `frame` `spinner` `progressbar` |
|
|
135
|
-
|
|
136
|
-
### Auto-infer (no YAML entry needed)
|
|
137
|
-
|
|
138
|
-
Most elements auto-infer from `[Label] type` → `getByRole(type, { name: 'Label' })`. Only add YAML when the accessible name differs, needs `nth`, or needs `testid`. Full auto-infer table → see `sungen-selector-keys` skill.
|
|
139
|
-
|
|
140
|
-
**Types requiring YAML entry:** `date-picker`, `uploader`, `overlay`, `frame`, `step` - these have no standard ARIA role and need explicit selectors.
|
|
141
|
-
|
|
142
|
-
## YAML Keys
|
|
143
|
-
|
|
144
|
-
`[Reference]` → **lowercase, keep Unicode**: `[Search Content]` → `search content:`, `[Thời gian]` → `thời gian:`
|
|
145
|
-
|
|
146
|
-
- Keys use **spaces** (not dots) as word separators
|
|
147
|
-
- Same label, different element types → add `--type` suffix
|
|
148
|
-
- Same label, nth occurrence → add `--N` suffix
|
|
149
|
-
- Target Name > 30 chars → shorten to 1–3 meaningful words
|
|
150
|
-
|
|
151
|
-
## Dynamic Variables (test-data YAML)
|
|
152
|
-
|
|
153
|
-
Use `{{$var}}` in test-data YAML for values that must be unique per test run. Resolved at **runtime** by `TestDataLoader` — the compiler passes them through unchanged.
|
|
154
|
-
|
|
155
|
-
| Variable | Example | Output |
|
|
156
|
-
|---|---|---|
|
|
157
|
-
| `{{$timestamp}}` | `"User-{{$timestamp}}"` | `"User-1714000000"` |
|
|
158
|
-
| `{{$uuid}}` | `"{{$uuid}}"` | `"a1b2c3d4-..."` |
|
|
159
|
-
| `{{$random:min:max}}` | `"{{$random:1:100}}"` | `"42"` |
|
|
160
|
-
| `{{$date}}` | `"{{$date}}"` | `"2026-04-24"` |
|
|
161
|
-
| `{{$datetime}}` | `"{{$datetime}}"` | `"2026-04-24T10:30:00.000Z"` |
|
|
162
|
-
|
|
163
|
-
**Rules:**
|
|
164
|
-
- `$timestamp` and `$uuid` → same value across all keys in one `load()` call (stable within a test file)
|
|
165
|
-
- `$random` → unique per occurrence (each key gets a different random)
|
|
166
|
-
- Resolved once at load time → every `get()` returns the same resolved value
|
|
167
|
-
- Use for CRUD flows to avoid data collision between parallel runs
|
|
168
|
-
|
|
169
|
-
```yaml
|
|
170
|
-
# test-data/crud-award.yaml
|
|
171
|
-
award:
|
|
172
|
-
name: "Award-{{$timestamp}}"
|
|
173
|
-
email: "test+{{$uuid}}@example.com"
|
|
174
|
-
score: "{{$random:1:100}}"
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
## Selectors (priority order)
|
|
178
|
-
|
|
179
|
-
| type | value | name | use |
|
|
180
|
-
|---|---|---|---|
|
|
181
|
-
| `testid` | data-testid | — | when exists |
|
|
182
|
-
| `role` | button/heading/link… | accessible name | interactive elements |
|
|
183
|
-
| `placeholder` | placeholder text | — | inputs |
|
|
184
|
-
| `label` | label text | — | labeled inputs |
|
|
185
|
-
| `text` | — | — | static text |
|
|
186
|
-
| `locator` | CSS selector | — | last resort |
|
|
187
|
-
| `page` | relative URL | — | navigation |
|
|
188
|
-
| `upload` | — | — | file inputs |
|
|
189
|
-
| `frame` | iframe selector | — | iframes |
|
|
190
|
-
|
|
191
|
-
Options: `nth` `exact` `scope` `match` `variant` `frame` `contenteditable` `columns`
|
|
192
|
-
|
|
193
|
-
## Tags
|
|
194
|
-
|
|
195
|
-
### Functional tags (affect code generation)
|
|
196
|
-
|
|
197
|
-
| Tag | Effect |
|
|
198
|
-
|---|---|
|
|
199
|
-
| `@manual` | Skip in generation |
|
|
200
|
-
| `@auth:role` | Use auth storage state for role |
|
|
201
|
-
| `@no-auth` | Disable inherited auth |
|
|
202
|
-
| `@steps:name` | Define reusable step block (base scenario) |
|
|
203
|
-
| `@extend:name` | Prepend Given→When from @steps block (skip Then) |
|
|
204
|
-
| `@cleanup:overlay` | Auto-cleanup: dismiss dialogs/overlays after each test (cleanupPage) |
|
|
205
|
-
| `@cleanup:forms` | Auto-cleanup: clear form fields after each test (cleanupPage) |
|
|
206
|
-
| `@cleanup:scroll` | Auto-cleanup: scroll to top after each test (cleanupPage) |
|
|
207
|
-
| `@cleanup:storage` | Auto-cleanup: clear sessionStorage after each test (cleanupPage) |
|
|
208
|
-
| `@screenshot:on-failure` | Auto-capture screenshot when test fails (base.ts fixture) |
|
|
209
|
-
| `@parallel` | Opt-out: fresh page per test instead of serial default (for independent scenarios) |
|
|
210
|
-
| `@beforeAll` | Hook: runs once before all tests → `test.beforeAll()` |
|
|
211
|
-
| `@afterEach` | Hook: runs after each test → `test.afterEach()` (custom cleanup) |
|
|
212
|
-
| `@afterAll` | Hook: runs once after all tests → `test.afterAll()` |
|
|
213
|
-
| `@flow` | Mark feature as E2E flow (cross-screen testing) |
|
|
214
|
-
| `@cases:dataset` | Data-driven: run the scenario once per row of the `dataset` LIST in test-data → one `test()` per row |
|
|
215
|
-
| `@query:name` | Database: run the named query from `database/queries.yaml` (precondition) and bind its rows to `{{name}}`; assert with `expect {{name.count}} …` + path access. Override params `@query:name(p={{v}})`. Repeatable. (Optional Data Driver — see Database verification above) |
|
|
216
|
-
| `@api:name` | API: run the named request from `api/apis.yaml` (precondition) and bind the response to `{{name}}`; assert with `expect {{name.status}} …` + path access (`{{name.body.<path>}}`). Override params `@api:name(p={{v}})`. Repeatable. (Optional API Driver) |
|
|
217
|
-
| `@concurrent:N` | API idempotency: fire the bound `@api` request N times in parallel, then bind aggregates on the `@api` name — `{{name.ok_count}}` (2xx count) and `{{name.status_counts}}` (status→count map). Assert the exactly-once invariant (`expect {{name.ok_count}} is 1`); pair with `@query` as a DB oracle. Tag order = run order: `@api` (mutate) before `@query` (verify). (Optional API Driver) |
|
|
218
|
-
| `@hybrid` | One unit, two capabilities: a signed-in browser session (UI) authorizes the `@api` call — the API request reuses the UI `storageState`. (Optional API + UI Drivers) |
|
|
219
|
-
|
|
220
|
-
### Data-driven scenarios (`@cases`)
|
|
221
|
-
|
|
222
|
-
For one test case × many inputs (email/format/boundary validation, decision tables), tag the
|
|
223
|
-
scenario `@cases:<dataset>` and reference each row's columns as `{{col}}`. Put the rows as a LIST
|
|
224
|
-
in test-data — NOT inline; data stays runtime + env-overlayable.
|
|
225
|
-
|
|
226
|
-
```gherkin
|
|
227
|
-
@high @cases:email_validation
|
|
228
|
-
Scenario: VP-VAL-001 The email field rejects invalid formats
|
|
229
|
-
When User fill [Email] field with {{email}}
|
|
230
|
-
Then User see [Login Error] message with {{expected_error}}
|
|
231
|
-
```
|
|
232
|
-
```yaml
|
|
233
|
-
# test-data/<screen>.yaml
|
|
234
|
-
email_validation:
|
|
235
|
-
- { case: "no @", email: "plainaddress", expected_error: "Invalid email" }
|
|
236
|
-
- { case: "valid", email: "ok@x.com", expected_error: "" }
|
|
237
|
-
```
|
|
238
|
-
An optional `case`/`name`/`label` column labels each run. Each row → its own pass/fail. Prefer
|
|
239
|
-
`@cases` over duplicating a scenario per value. (Gherkin `Scenario Outline`/`Examples` is NOT
|
|
240
|
-
supported — use `@cases`.)
|
|
241
|
-
|
|
242
|
-
### Pass-through tags (filter at runtime via Playwright --grep)
|
|
243
|
-
|
|
244
|
-
Any tag not listed above passes through to Playwright `{ tag: [...] }`. Feature-level tags inherit to all scenarios.
|
|
245
|
-
|
|
246
|
-
| Tag | Purpose |
|
|
247
|
-
|---|---|
|
|
248
|
-
| `@smoke` | Quick sanity check — run after every deploy |
|
|
249
|
-
| `@regression` | Full test suite — run nightly or before release |
|
|
250
|
-
| `@high` | Priority: must pass — login, auth, core CRUD, primary business flow |
|
|
251
|
-
| `@normal` | Priority: important — validation rules, secondary features, search/filter |
|
|
252
|
-
| `@low` | Priority: minor/cosmetic — tooltips, hover states, element presence |
|
|
253
|
-
| `@auto` | Standard scenario, ready for automation |
|
|
254
|
-
| Any custom | e.g., `@sprint-42`, `@team-payment` — any tag works |
|
|
255
|
-
|
|
256
|
-
**Assign priority by user impact** (canonical mapping — override only when context differs):
|
|
257
|
-
|
|
258
|
-
| Scenario type | Tag |
|
|
259
|
-
|---|---|
|
|
260
|
-
| Auth redirect / unauthenticated access | `@high` |
|
|
261
|
-
| CRUD happy path (create / update / delete — success) | `@high` |
|
|
262
|
-
| Core business rule, state transition | `@high` |
|
|
263
|
-
| XSS, SQL injection, permission blocked | `@high` |
|
|
264
|
-
| Required field error, unique/duplicate constraint | `@high` |
|
|
265
|
-
| Format validation (email, phone, date…) | `@normal` |
|
|
266
|
-
| Boundary value — inclusive (`<=`, `>=`) → `@high`; standard range → `@normal` | `@normal` |
|
|
267
|
-
| Secondary features (search, filter, sort, pagination) | `@normal` |
|
|
268
|
-
| Element presence, label, placeholder, tooltip | `@low` |
|
|
269
|
-
|
|
270
|
-
**Run filtered:**
|
|
271
|
-
```bash
|
|
272
|
-
npx playwright test --grep "@smoke" # only smoke tests
|
|
273
|
-
npx playwright test --grep "@high" # only high priority
|
|
274
|
-
npx playwright test --grep "@smoke|@high" # smoke OR high
|
|
275
|
-
```
|
|
276
|
-
|
|
277
|
-
### Serial vs Parallel (test execution mode)
|
|
278
|
-
|
|
279
|
-
**Default: serial** — `test.describe.serial()` with shared page. Background runs once in `beforeAll`. Fail → skip remaining.
|
|
280
|
-
|
|
281
|
-
**`@parallel` opt-out** — `test.describe()` with fresh page per test. Background runs as `beforeEach`. Use when scenarios are truly independent (validation rules, permission tests).
|
|
282
|
-
|
|
283
|
-
| Mode | Generated | Page | Background | On fail |
|
|
284
|
-
|---|---|---|---|---|
|
|
285
|
-
| Serial (default) | `test.describe.serial()` | Shared | `beforeAll` (1 goto) | Skip remaining |
|
|
286
|
-
| `@parallel` | `test.describe()` | Fresh per test | `beforeEach` (N goto) | Continue |
|
|
287
|
-
|
|
288
|
-
**`@parallel` is required** when a feature has multiple auth groups (e.g., `@auth:user` + `@no-auth` scenarios). Serial mode uses one shared browser context and cannot mix auth roles. The compiler will error if `@parallel` is missing in this case.
|
|
289
|
-
|
|
290
|
-
### `@flow` tag (E2E cross-screen testing)
|
|
291
|
-
|
|
292
|
-
`@flow` marks a feature as a **flow** — an E2E journey spanning multiple screens. Flows live in `qa/flows/<name>/` with their own selectors, test-data, and requirements.
|
|
293
|
-
|
|
294
|
-
**Key differences from screen tests:**
|
|
295
|
-
|
|
296
|
-
| Aspect | Screen (`qa/screens/`) | Flow (`qa/flows/`) |
|
|
297
|
-
|---|---|---|
|
|
298
|
-
| Scope | Single page | Multiple pages |
|
|
299
|
-
| Selectors | `[Element]` → own YAML | `[Screen:Element]` → own YAML (namespaced) |
|
|
300
|
-
| Test data | `{{variable}}` | `{{phase.variable}}` (namespaced by phase) |
|
|
301
|
-
| Tag | `@auto` / `@smoke` etc. | `@flow` (required at feature level) |
|
|
302
|
-
| Multi-domain | N/A | Absolute URL in selector `path:` skips baseURL |
|
|
303
|
-
|
|
304
|
-
**Selector namespace format:** `[Screen:Element]` where colon separates screen prefix from element name. The YAML key is `"screen:element"` (quoted, lowercase).
|
|
305
|
-
|
|
306
|
-
```gherkin
|
|
307
|
-
# Feature file
|
|
308
|
-
When User fill [Login:Email] field with {{login.email}}
|
|
309
|
-
And User click [Login:Submit] button
|
|
310
|
-
Then User see [Dashboard] page
|
|
311
|
-
When User click [Dashboard:Awards] link
|
|
312
|
-
```
|
|
313
|
-
|
|
314
|
-
```yaml
|
|
315
|
-
# selectors.yaml — keys are namespaced, quoted due to colon
|
|
316
|
-
"login:email":
|
|
317
|
-
type: 'testid'
|
|
318
|
-
value: 'email-input'
|
|
319
|
-
|
|
320
|
-
"login:submit":
|
|
321
|
-
type: 'role'
|
|
322
|
-
value: 'button'
|
|
323
|
-
name: 'Login'
|
|
324
|
-
|
|
325
|
-
dashboard:
|
|
326
|
-
type: 'page'
|
|
327
|
-
value: '/dashboard'
|
|
328
|
-
|
|
329
|
-
"dashboard:awards":
|
|
330
|
-
type: 'role'
|
|
331
|
-
value: 'link'
|
|
332
|
-
name: 'Awards'
|
|
333
|
-
```
|
|
334
|
-
|
|
335
|
-
**Flow structure:**
|
|
336
|
-
- `Background:` — set starting page only (e.g., `Given User is on [Login] page`)
|
|
337
|
-
- Each `Scenario:` — one phase/step of the flow (login, navigate, submit, etc.)
|
|
338
|
-
- Page navigation between scenarios uses `[Screen] page` references
|
|
339
|
-
|
|
340
|
-
**CLI:** `sungen add-flow --flow <name>`, `sungen generate --flow <name>`, `sungen generate --all` (includes flows)
|
|
341
|
-
|
|
342
|
-
### @extend behavior
|
|
343
|
-
|
|
344
|
-
- Tool executes **only Given→When** of `@steps` scenario (skips Then)
|
|
345
|
-
- The `Given` in `@extend` scenario is the **entry assertion** (confirms state after base steps)
|
|
346
|
-
- **Entry assertion MUST use `Given User is on [X] type`** — NEVER `Given User see [X] type`
|
|
347
|
-
- `Given` keyword ONLY allows `is on` action. `see` = `Then` only.
|
|
348
|
-
- If `@steps` scenario fails, `@extend` scenario is **skipped**
|
|
349
|
-
- Name format: `snake_case` or `kebab-case` with module prefix: `@steps:kudos__open_modal`
|
|
350
|
-
|
|
351
|
-
## Common Syntax Errors
|
|
352
|
-
|
|
353
|
-
| Error | Wrong | Correct |
|
|
354
|
-
|---|---|---|
|
|
355
|
-
| Wrong keyword | `Given User click [T] button` | `When User click [T] button` |
|
|
356
|
-
| `see` after Given | `Given User see [T] heading with {{v}}` | `Then User see [T] heading with {{v}}` (or `Given User is on [T] page` for entry assertion) |
|
|
357
|
-
| Name ≠ step type | Scenario name says "modal" but step uses `dialog` | Use the **same element type** in both: "...dialog opens" + `[X] dialog` |
|
|
358
|
-
| Wrong action for type | `When User click [T] checkbox` | `When User check [T] checkbox` |
|
|
359
|
-
| press wrong target | `When User press [Submit] button` | `When User press Enter key` |
|
|
360
|
-
| uncheck radio | `When User uncheck [Male] radio` | `When User check [Female] radio` |
|
|
361
|
-
| Hardcode data | `with {{admin@mail.com}}` | `with {{invalid_email}}` |
|
|
362
|
-
| Missing `is` for state | `with {{text}} hidden` | `with {{text}} is hidden` |
|
|
363
|
-
| State as value | `with {{disabled}}` | `is disabled` |
|
|
364
|
-
| Missing target type | `fill [email] with {{v}}` | `fill [email] field with {{v}}` |
|
|
365
|
-
| Background with scope | `Background: ... And User is on [X] dialog` | Use `@steps` + `@extend` for scope-dependent flows |
|
|
366
|
-
| `is on` after When | `When ... And User is on [X] dialog` | `And User see [X] dialog` or separate Given |
|
|
367
|
-
| Literal URL navigate | `User navigate to "/dashboard"` | `User is on [Dashboard] page` (add page selector in `selectors.yaml`) |
|
|
368
|
-
|
|
369
|
-
## Background vs @steps/@extend
|
|
370
|
-
|
|
371
|
-
Both `Background` and `@steps`/`@extend` are valid — they serve different purposes.
|
|
372
|
-
|
|
373
|
-
| Pattern | Use when | Generates |
|
|
374
|
-
|---|---|---|
|
|
375
|
-
| `Background` | Simple shared setup (navigate to page) | `test.beforeEach()` |
|
|
376
|
-
| `@steps`/`@extend` | Complex reusable flows with scope (dialog, frame) | Inline merged steps in `test()` |
|
|
377
|
-
|
|
378
|
-
**Use `Background` for simple navigation:**
|
|
379
|
-
```gherkin
|
|
380
|
-
Background:
|
|
381
|
-
Given User is on [Dashboard] page
|
|
382
|
-
|
|
383
|
-
Scenario: View stats
|
|
384
|
-
Then User see [Revenue Chart] section
|
|
385
|
-
```
|
|
386
|
-
|
|
387
|
-
**Use `@steps`/`@extend` when scope matters (dialog, frame):**
|
|
388
|
-
```gherkin
|
|
389
|
-
@steps:open_modal
|
|
390
|
-
Scenario: Open modal
|
|
391
|
-
Given User is on [Kudos] page
|
|
392
|
-
When User click [Open] button
|
|
393
|
-
Then User see [Modal] dialog
|
|
394
|
-
|
|
395
|
-
@extend:open_modal
|
|
396
|
-
Scenario: VP-UI-001 Title visible
|
|
397
|
-
Given User is on [Modal] dialog
|
|
398
|
-
Then User see [Title] heading
|
|
399
|
-
```
|
|
400
|
-
|
|
401
|
-
**Avoid `Background` with scope-dependent steps** — `When` + `And User is on [X] dialog` creates keyword mismatch (`is on` = Given, not When). Use `@steps`/`@extend` instead.
|
|
402
|
-
|
|
403
|
-
## Hooks & Cleanup
|
|
404
|
-
|
|
405
|
-
Two layers for test lifecycle management. Prefer `@cleanup:*` tags (Layer 1) — they work with base.ts automatically. Use hook scenarios (Layer 2) only for custom logic.
|
|
406
|
-
|
|
407
|
-
### Layer 1: `@cleanup:*` tags (automatic via base.ts)
|
|
408
|
-
|
|
409
|
-
Feature-level tags that activate cleanup fixtures in base.ts. No Gherkin steps needed.
|
|
410
|
-
|
|
411
|
-
```gherkin
|
|
412
|
-
@auth:admin
|
|
413
|
-
@cleanup:overlay
|
|
414
|
-
@cleanup:forms
|
|
415
|
-
Feature: User Management
|
|
416
|
-
Path: /users
|
|
417
|
-
|
|
418
|
-
Background:
|
|
419
|
-
Given User is on [User Management] page
|
|
420
|
-
|
|
421
|
-
Scenario: Create user shows form
|
|
422
|
-
When User click [Add User] button
|
|
423
|
-
Then User see [Create User] dialog
|
|
424
|
-
|
|
425
|
-
Scenario: Search user by name
|
|
426
|
-
When User fill [Search] field with {{search_name}}
|
|
427
|
-
Then User see [User Row] row
|
|
428
|
-
```
|
|
429
|
-
|
|
430
|
-
| Tag | What base.ts does after each test |
|
|
431
|
-
|---|---|
|
|
432
|
-
| `@cleanup:overlay` | Press Escape, click body, dismiss fixed overlays |
|
|
433
|
-
| `@cleanup:forms` | Clear all input/textarea fields, reset selects |
|
|
434
|
-
| `@cleanup:scroll` | Scroll to top of page |
|
|
435
|
-
| `@cleanup:storage` | Clear sessionStorage |
|
|
436
|
-
|
|
437
|
-
### Layer 2: `@afterEach` scenario (custom cleanup)
|
|
438
|
-
|
|
439
|
-
Only when `@cleanup:*` tags aren't enough — feature-specific logic.
|
|
440
|
-
|
|
441
|
-
### Layer 3: `@beforeAll` / `@afterAll` (optional)
|
|
442
|
-
|
|
443
|
-
For one-time setup/teardown.
|
|
444
|
-
|
|
445
|
-
**Rendering order in `.spec.ts`:**
|
|
446
|
-
`test.describe` → `test.use(storageState)` → `test.use(autoCleanup)` → `test.beforeAll` → `test.beforeEach` → `test.afterEach` → `test.afterAll` → `test()` blocks
|