@sun-asterisk/sungen 3.2.24 → 3.2.25
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/context-router.d.ts.map +1 -1
- package/dist/capabilities/context-router.js +15 -7
- package/dist/capabilities/context-router.js.map +1 -1
- package/dist/cli/commands/capability.d.ts.map +1 -1
- package/dist/cli/commands/capability.js +6 -48
- package/dist/cli/commands/capability.js.map +1 -1
- package/dist/cli/commands/changed.d.ts +14 -0
- package/dist/cli/commands/changed.d.ts.map +1 -0
- package/dist/cli/commands/changed.js +128 -0
- package/dist/cli/commands/changed.js.map +1 -0
- package/dist/cli/commands/delivery.d.ts.map +1 -1
- package/dist/cli/commands/delivery.js +25 -1
- package/dist/cli/commands/delivery.js.map +1 -1
- package/dist/cli/commands/generate.js +1 -1
- package/dist/cli/commands/generate.js.map +1 -1
- package/dist/cli/commands/results-merge.d.ts +19 -0
- package/dist/cli/commands/results-merge.d.ts.map +1 -0
- package/dist/cli/commands/results-merge.js +191 -0
- package/dist/cli/commands/results-merge.js.map +1 -0
- package/dist/cli/commands/update.d.ts.map +1 -1
- package/dist/cli/commands/update.js +100 -12
- package/dist/cli/commands/update.js.map +1 -1
- package/dist/cli/index.js +4 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/exporters/api-catalog-loader.d.ts.map +1 -1
- package/dist/exporters/api-catalog-loader.js +10 -3
- package/dist/exporters/api-catalog-loader.js.map +1 -1
- package/dist/exporters/api-testcase-formatter.d.ts +9 -0
- package/dist/exporters/api-testcase-formatter.d.ts.map +1 -1
- package/dist/exporters/api-testcase-formatter.js +55 -3
- package/dist/exporters/api-testcase-formatter.js.map +1 -1
- package/dist/exporters/csv-exporter.d.ts.map +1 -1
- package/dist/exporters/csv-exporter.js +10 -1
- package/dist/exporters/csv-exporter.js.map +1 -1
- package/dist/exporters/json-exporter.d.ts.map +1 -1
- package/dist/exporters/json-exporter.js +6 -1
- package/dist/exporters/json-exporter.js.map +1 -1
- package/dist/exporters/matrix/build.d.ts.map +1 -1
- package/dist/exporters/matrix/build.js +10 -0
- package/dist/exporters/matrix/build.js.map +1 -1
- package/dist/exporters/matrix/export.js +1 -1
- package/dist/exporters/matrix/export.js.map +1 -1
- package/dist/exporters/matrix/render-csv.d.ts.map +1 -1
- package/dist/exporters/matrix/render-csv.js +5 -1
- package/dist/exporters/matrix/render-csv.js.map +1 -1
- package/dist/exporters/matrix/render-xlsx.d.ts.map +1 -1
- package/dist/exporters/matrix/render-xlsx.js +4 -1
- package/dist/exporters/matrix/render-xlsx.js.map +1 -1
- package/dist/exporters/matrix/types.d.ts +7 -0
- package/dist/exporters/matrix/types.d.ts.map +1 -1
- package/dist/exporters/matrix/types.js.map +1 -1
- package/dist/exporters/playwright-report-parser.d.ts +17 -2
- package/dist/exporters/playwright-report-parser.d.ts.map +1 -1
- package/dist/exporters/playwright-report-parser.js +68 -8
- package/dist/exporters/playwright-report-parser.js.map +1 -1
- package/dist/exporters/results-merge.d.ts +46 -0
- package/dist/exporters/results-merge.d.ts.map +1 -0
- package/dist/exporters/results-merge.js +148 -0
- package/dist/exporters/results-merge.js.map +1 -0
- package/dist/exporters/selector-key-resolver.d.ts +4 -0
- package/dist/exporters/selector-key-resolver.d.ts.map +1 -1
- package/dist/exporters/selector-key-resolver.js +101 -1
- package/dist/exporters/selector-key-resolver.js.map +1 -1
- package/dist/exporters/types.d.ts +8 -1
- package/dist/exporters/types.d.ts.map +1 -1
- package/dist/exporters/xlsx-report-builder.d.ts.map +1 -1
- package/dist/exporters/xlsx-report-builder.js +5 -4
- package/dist/exporters/xlsx-report-builder.js.map +1 -1
- package/dist/generators/gherkin-parser/index.d.ts +2 -0
- package/dist/generators/gherkin-parser/index.d.ts.map +1 -1
- package/dist/generators/gherkin-parser/index.js +52 -1
- package/dist/generators/gherkin-parser/index.js.map +1 -1
- package/dist/generators/test-generator/adapters/adapter-interface.d.ts +20 -10
- package/dist/generators/test-generator/adapters/adapter-interface.d.ts.map +1 -1
- package/dist/generators/test-generator/adapters/appium/appium-adapter.d.ts +2 -11
- package/dist/generators/test-generator/adapters/appium/appium-adapter.d.ts.map +1 -1
- package/dist/generators/test-generator/adapters/appium/appium-adapter.js.map +1 -1
- package/dist/generators/test-generator/adapters/appium/templates/imports.hbs +3 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/actions/date-picker-unsupported.hbs +4 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/actions/lifecycle-missing-app-id.hbs +5 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/matches-format-assertion.hbs +15 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/visible-filtered-assertion.hbs +5 -2
- package/dist/generators/test-generator/adapters/appium/templates/test-file.hbs +185 -26
- package/dist/generators/test-generator/adapters/playwright/playwright-adapter.d.ts +2 -11
- package/dist/generators/test-generator/adapters/playwright/playwright-adapter.d.ts.map +1 -1
- package/dist/generators/test-generator/adapters/playwright/playwright-adapter.js.map +1 -1
- package/dist/generators/test-generator/adapters/playwright/templates/imports.hbs +3 -0
- package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/select-action.hbs +17 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/attribute-assertion.hbs +6 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/have-value-assertion.hbs +18 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/hidden-with-filter-assertion.hbs +5 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/matches-format-assertion.hbs +5 -0
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/state-with-filter-assertion.hbs +4 -2
- package/dist/generators/test-generator/adapters/playwright/templates/steps/navigation/wait-for-element-with-text.hbs +4 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/partials/recipe-expect-text.hbs +1 -1
- package/dist/generators/test-generator/code-generator.d.ts +6 -0
- package/dist/generators/test-generator/code-generator.d.ts.map +1 -1
- package/dist/generators/test-generator/code-generator.js +80 -7
- package/dist/generators/test-generator/code-generator.js.map +1 -1
- package/dist/generators/test-generator/diagnostics.d.ts +60 -6
- package/dist/generators/test-generator/diagnostics.d.ts.map +1 -1
- package/dist/generators/test-generator/diagnostics.js +59 -5
- package/dist/generators/test-generator/diagnostics.js.map +1 -1
- package/dist/generators/test-generator/patterns/expect-patterns.d.ts +7 -0
- package/dist/generators/test-generator/patterns/expect-patterns.d.ts.map +1 -1
- package/dist/generators/test-generator/patterns/expect-patterns.js +36 -2
- package/dist/generators/test-generator/patterns/expect-patterns.js.map +1 -1
- package/dist/generators/test-generator/patterns/index.d.ts +19 -12
- package/dist/generators/test-generator/patterns/index.d.ts.map +1 -1
- package/dist/generators/test-generator/patterns/index.js +58 -38
- package/dist/generators/test-generator/patterns/index.js.map +1 -1
- package/dist/generators/test-generator/patterns/types.d.ts +23 -0
- package/dist/generators/test-generator/patterns/types.d.ts.map +1 -1
- package/dist/generators/test-generator/patterns/unsupported-step-code.d.ts +18 -0
- package/dist/generators/test-generator/patterns/unsupported-step-code.d.ts.map +1 -0
- package/dist/generators/test-generator/patterns/unsupported-step-code.js +23 -0
- package/dist/generators/test-generator/patterns/unsupported-step-code.js.map +1 -0
- package/dist/generators/test-generator/recipe-expander.js +9 -1
- package/dist/generators/test-generator/recipe-expander.js.map +1 -1
- package/dist/generators/test-generator/reset-tier.d.ts +68 -0
- package/dist/generators/test-generator/reset-tier.d.ts.map +1 -0
- package/dist/generators/test-generator/reset-tier.js +94 -0
- package/dist/generators/test-generator/reset-tier.js.map +1 -0
- package/dist/generators/test-generator/step-mapper.d.ts +39 -0
- package/dist/generators/test-generator/step-mapper.d.ts.map +1 -1
- package/dist/generators/test-generator/step-mapper.js +144 -5
- package/dist/generators/test-generator/step-mapper.js.map +1 -1
- package/dist/generators/test-generator/template-engine.d.ts +2 -10
- package/dist/generators/test-generator/template-engine.d.ts.map +1 -1
- package/dist/generators/test-generator/template-engine.js +16 -2
- package/dist/generators/test-generator/template-engine.js.map +1 -1
- package/dist/generators/test-generator/utils/format-pattern.d.ts +35 -0
- package/dist/generators/test-generator/utils/format-pattern.d.ts.map +1 -0
- package/dist/generators/test-generator/utils/format-pattern.js +82 -0
- package/dist/generators/test-generator/utils/format-pattern.js.map +1 -0
- package/dist/generators/test-generator/utils/js-literal-scanner.d.ts +42 -0
- package/dist/generators/test-generator/utils/js-literal-scanner.d.ts.map +1 -0
- package/dist/generators/test-generator/utils/js-literal-scanner.js +142 -0
- package/dist/generators/test-generator/utils/js-literal-scanner.js.map +1 -0
- package/dist/generators/test-generator/utils/mask-refs-for-matching.d.ts +18 -0
- package/dist/generators/test-generator/utils/mask-refs-for-matching.d.ts.map +1 -0
- package/dist/generators/test-generator/utils/mask-refs-for-matching.js +25 -0
- package/dist/generators/test-generator/utils/mask-refs-for-matching.js.map +1 -0
- package/dist/generators/test-generator/utils/runtime-data-transformer.d.ts +9 -1
- package/dist/generators/test-generator/utils/runtime-data-transformer.d.ts.map +1 -1
- package/dist/generators/test-generator/utils/runtime-data-transformer.js +124 -63
- package/dist/generators/test-generator/utils/runtime-data-transformer.js.map +1 -1
- package/dist/generators/test-generator/utils/selector-resolver.d.ts.map +1 -1
- package/dist/generators/test-generator/utils/selector-resolver.js +20 -1
- package/dist/generators/test-generator/utils/selector-resolver.js.map +1 -1
- package/dist/generators/test-generator/utils/spec-syntax-check.d.ts +14 -0
- package/dist/generators/test-generator/utils/spec-syntax-check.d.ts.map +1 -0
- package/dist/generators/test-generator/utils/spec-syntax-check.js +26 -0
- package/dist/generators/test-generator/utils/spec-syntax-check.js.map +1 -0
- package/dist/harness/annotation-overrides.d.ts +0 -12
- package/dist/harness/annotation-overrides.d.ts.map +1 -1
- package/dist/harness/annotation-overrides.js +9 -5
- package/dist/harness/annotation-overrides.js.map +1 -1
- package/dist/harness/audit.js +4 -4
- package/dist/harness/audit.js.map +1 -1
- package/dist/harness/capability-plan.d.ts +2 -1
- package/dist/harness/capability-plan.d.ts.map +1 -1
- package/dist/harness/capability-plan.js +8 -3
- package/dist/harness/capability-plan.js.map +1 -1
- package/dist/harness/capability.d.ts +11 -0
- package/dist/harness/capability.d.ts.map +1 -1
- package/dist/harness/capability.js +8 -0
- package/dist/harness/capability.js.map +1 -1
- package/dist/harness/catalog/drivers.yaml +5 -0
- package/dist/harness/parse.d.ts.map +1 -1
- package/dist/harness/parse.js +5 -1
- package/dist/harness/parse.js.map +1 -1
- package/dist/harness/run-manifest.d.ts +58 -0
- package/dist/harness/run-manifest.d.ts.map +1 -0
- package/dist/harness/run-manifest.js +264 -0
- package/dist/harness/run-manifest.js.map +1 -0
- package/dist/harness/viewpoint-ledger.d.ts +1 -1
- package/dist/harness/viewpoint-ledger.d.ts.map +1 -1
- package/dist/harness/viewpoint-ledger.js +25 -4
- package/dist/harness/viewpoint-ledger.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/orchestrator/lockstep-version.d.ts +22 -0
- package/dist/orchestrator/lockstep-version.d.ts.map +1 -0
- package/dist/orchestrator/lockstep-version.js +58 -0
- package/dist/orchestrator/lockstep-version.js.map +1 -0
- package/dist/orchestrator/project-deps-sync.d.ts +39 -0
- package/dist/orchestrator/project-deps-sync.d.ts.map +1 -0
- package/dist/orchestrator/project-deps-sync.js +175 -0
- package/dist/orchestrator/project-deps-sync.js.map +1 -0
- package/dist/orchestrator/project-initializer.d.ts.map +1 -1
- package/dist/orchestrator/project-initializer.js +5 -2
- package/dist/orchestrator/project-initializer.js.map +1 -1
- package/dist/orchestrator/templates/ai-src/commands/run-test.md +109 -0
- package/dist/orchestrator/templates/ai-src/config/claude.md +1 -1
- package/dist/orchestrator/templates/ai-src/config/copilot.md +1 -1
- package/dist/orchestrator/templates/ai-src/skills/sungen-api-design/SKILL.md +49 -0
- package/dist/orchestrator/templates/ai-src/skills/sungen-error-mapping/SKILL.md +14 -3
- package/dist/orchestrator/templates/ai-src/skills/sungen-gherkin-syntax/SKILL.md +110 -6
- package/dist/orchestrator/templates/ai-src/skills/sungen-locale/SKILL.md +1 -1
- package/dist/orchestrator/templates/ai-src/skills/sungen-mobile-gestures/SKILL.md +8 -0
- package/dist/orchestrator/templates/ai-src/skills/sungen-selector-fix/SKILL.md +1 -1
- package/dist/orchestrator/templates/ai-src/skills/sungen-tc-generation/SKILL.md +9 -0
- package/dist/orchestrator/templates/ai-src/skills/sungen-tc-review/SKILL.md +15 -0
- package/dist/orchestrator/templates/env.appium.example +10 -0
- package/dist/orchestrator/templates/specs-api.d.ts +4 -2
- package/dist/orchestrator/templates/specs-api.d.ts.map +1 -1
- package/dist/orchestrator/templates/specs-api.js +233 -10
- package/dist/orchestrator/templates/specs-api.js.map +1 -1
- package/dist/orchestrator/templates/specs-api.ts +214 -11
- package/dist/orchestrator/templates/specs-regex-escape.d.ts +13 -0
- package/dist/orchestrator/templates/specs-regex-escape.d.ts.map +1 -0
- package/dist/orchestrator/templates/specs-regex-escape.js +19 -0
- package/dist/orchestrator/templates/specs-regex-escape.js.map +1 -0
- package/dist/orchestrator/templates/specs-regex-escape.ts +16 -0
- package/dist/orchestrator/templates/specs-test-data.ts +53 -6
- package/dist/orchestrator/templates/wdio.conf.ts +28 -9
- package/package.json +8 -6
- package/src/capabilities/context-router.ts +13 -5
- package/src/cli/commands/capability.ts +4 -38
- package/src/cli/commands/changed.ts +104 -0
- package/src/cli/commands/delivery.ts +27 -2
- package/src/cli/commands/generate.ts +1 -1
- package/src/cli/commands/results-merge.ts +153 -0
- package/src/cli/commands/update.ts +72 -13
- package/src/cli/index.ts +4 -0
- package/src/exporters/api-catalog-loader.ts +10 -2
- package/src/exporters/api-testcase-formatter.ts +59 -3
- package/src/exporters/csv-exporter.ts +11 -2
- package/src/exporters/json-exporter.ts +7 -2
- package/src/exporters/matrix/build.ts +9 -0
- package/src/exporters/matrix/export.ts +1 -1
- package/src/exporters/matrix/render-csv.ts +5 -1
- package/src/exporters/matrix/render-xlsx.ts +4 -1
- package/src/exporters/matrix/types.ts +7 -0
- package/src/exporters/playwright-report-parser.ts +68 -9
- package/src/exporters/results-merge.ts +150 -0
- package/src/exporters/selector-key-resolver.ts +81 -1
- package/src/exporters/types.ts +8 -1
- package/src/exporters/xlsx-report-builder.ts +5 -4
- package/src/generators/gherkin-parser/index.ts +55 -1
- package/src/generators/test-generator/adapters/adapter-interface.ts +23 -1
- package/src/generators/test-generator/adapters/appium/appium-adapter.ts +2 -2
- package/src/generators/test-generator/adapters/appium/templates/imports.hbs +3 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/actions/date-picker-unsupported.hbs +4 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/actions/lifecycle-missing-app-id.hbs +5 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/assertions/matches-format-assertion.hbs +15 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/assertions/visible-filtered-assertion.hbs +5 -2
- package/src/generators/test-generator/adapters/appium/templates/test-file.hbs +185 -26
- package/src/generators/test-generator/adapters/playwright/playwright-adapter.ts +2 -2
- package/src/generators/test-generator/adapters/playwright/templates/imports.hbs +3 -0
- package/src/generators/test-generator/adapters/playwright/templates/steps/actions/select-action.hbs +17 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/attribute-assertion.hbs +6 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/have-value-assertion.hbs +18 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/hidden-with-filter-assertion.hbs +5 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/matches-format-assertion.hbs +5 -0
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/state-with-filter-assertion.hbs +4 -2
- package/src/generators/test-generator/adapters/playwright/templates/steps/navigation/wait-for-element-with-text.hbs +4 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/partials/recipe-expect-text.hbs +1 -1
- package/src/generators/test-generator/code-generator.ts +86 -7
- package/src/generators/test-generator/diagnostics.ts +60 -6
- package/src/generators/test-generator/patterns/expect-patterns.ts +37 -2
- package/src/generators/test-generator/patterns/index.ts +58 -33
- package/src/generators/test-generator/patterns/types.ts +36 -0
- package/src/generators/test-generator/patterns/unsupported-step-code.ts +19 -0
- package/src/generators/test-generator/recipe-expander.ts +9 -1
- package/src/generators/test-generator/reset-tier.ts +93 -0
- package/src/generators/test-generator/step-mapper.ts +149 -6
- package/src/generators/test-generator/template-engine.ts +18 -3
- package/src/generators/test-generator/utils/format-pattern.ts +79 -0
- package/src/generators/test-generator/utils/js-literal-scanner.ts +132 -0
- package/src/generators/test-generator/utils/mask-refs-for-matching.ts +21 -0
- package/src/generators/test-generator/utils/runtime-data-transformer.ts +126 -76
- package/src/generators/test-generator/utils/selector-resolver.ts +22 -1
- package/src/generators/test-generator/utils/spec-syntax-check.ts +22 -0
- package/src/harness/annotation-overrides.ts +10 -5
- package/src/harness/audit.ts +4 -4
- package/src/harness/capability-plan.ts +10 -5
- package/src/harness/capability.ts +16 -0
- package/src/harness/catalog/drivers.yaml +5 -0
- package/src/harness/parse.ts +5 -1
- package/src/harness/run-manifest.ts +254 -0
- package/src/harness/viewpoint-ledger.ts +26 -5
- package/src/index.ts +1 -0
- package/src/orchestrator/lockstep-version.ts +46 -0
- package/src/orchestrator/project-deps-sync.ts +175 -0
- package/src/orchestrator/project-initializer.ts +5 -2
- package/src/orchestrator/templates/ai-src/commands/run-test.md +109 -0
- package/src/orchestrator/templates/ai-src/config/claude.md +1 -1
- package/src/orchestrator/templates/ai-src/config/copilot.md +1 -1
- package/src/orchestrator/templates/ai-src/skills/sungen-api-design/SKILL.md +49 -0
- package/src/orchestrator/templates/ai-src/skills/sungen-error-mapping/SKILL.md +14 -3
- package/src/orchestrator/templates/ai-src/skills/sungen-gherkin-syntax/SKILL.md +110 -6
- package/src/orchestrator/templates/ai-src/skills/sungen-locale/SKILL.md +1 -1
- package/src/orchestrator/templates/ai-src/skills/sungen-mobile-gestures/SKILL.md +8 -0
- package/src/orchestrator/templates/ai-src/skills/sungen-selector-fix/SKILL.md +1 -1
- package/src/orchestrator/templates/ai-src/skills/sungen-tc-generation/SKILL.md +9 -0
- package/src/orchestrator/templates/ai-src/skills/sungen-tc-review/SKILL.md +15 -0
- package/src/orchestrator/templates/env.appium.example +10 -0
- package/src/orchestrator/templates/specs-api.ts +214 -11
- package/src/orchestrator/templates/specs-regex-escape.ts +16 -0
- package/src/orchestrator/templates/specs-test-data.ts +53 -6
- package/src/orchestrator/templates/wdio.conf.ts +28 -9
|
@@ -14,27 +14,14 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.PatternRegistry = void 0;
|
|
18
|
-
exports.maskRefsForMatching = maskRefsForMatching;
|
|
17
|
+
exports.PatternRegistry = exports.unsupportedStepCode = exports.maskRefsForMatching = void 0;
|
|
19
18
|
exports.normalizeVerbs = normalizeVerbs;
|
|
20
19
|
const registry_1 = require("../../../capabilities/registry");
|
|
21
20
|
const discover_1 = require("../../../capabilities/discover");
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
* so a data ref like `{{double_click_guard_account.email}}` would spuriously satisfy the click
|
|
27
|
-
* matcher and pre-empt fill. The content is replaced with an inert placeholder (`~` — carries no
|
|
28
|
-
* verb/keyword/digit substring) rather than emptied, so structural matchers that require a NON-EMPTY
|
|
29
|
-
* ref survive too — e.g. `expect {{a}} is {{b}}` matches `\{\{[^}]+\}\}`, and `in [X] table` /
|
|
30
|
-
* `/\bto\s+\[/` keep their delimiters. The resolver/generator always receives the ORIGINAL step, so
|
|
31
|
-
* value extraction and codegen are unaffected.
|
|
32
|
-
*/
|
|
33
|
-
function maskRefsForMatching(text) {
|
|
34
|
-
return text
|
|
35
|
-
.replace(/\{\{[^}]*\}\}/g, '{{~}}')
|
|
36
|
-
.replace(/\[[^\]]*\]/g, '[~]');
|
|
37
|
-
}
|
|
21
|
+
const mask_refs_for_matching_1 = require("../utils/mask-refs-for-matching");
|
|
22
|
+
Object.defineProperty(exports, "maskRefsForMatching", { enumerable: true, get: function () { return mask_refs_for_matching_1.maskRefsForMatching; } });
|
|
23
|
+
const unsupported_step_code_1 = require("./unsupported-step-code");
|
|
24
|
+
Object.defineProperty(exports, "unsupportedStepCode", { enumerable: true, get: function () { return unsupported_step_code_1.unsupportedStepCode; } });
|
|
38
25
|
/**
|
|
39
26
|
* Gesture forms that OWN the word "tap" — each has its own pattern keyed on it (`mobile-double-tap`
|
|
40
27
|
* at priority 17, `tap-top-of-element` at 18) and means MORE than a click. They are the one
|
|
@@ -88,22 +75,6 @@ function normalizeVerbs(text) {
|
|
|
88
75
|
* propagating untouched.
|
|
89
76
|
*/
|
|
90
77
|
const TEMPLATE_NOT_FOUND = /^Template not found: (.+)\.hbs in any subfolder$/;
|
|
91
|
-
/**
|
|
92
|
-
* The step body emitted in place of code the active adapter cannot produce. A comment alone would
|
|
93
|
-
* let the test go GREEN having asserted nothing — the silent-loss class this SPI exists to close —
|
|
94
|
-
* so the step throws at run time as well as reporting at compile time.
|
|
95
|
-
*
|
|
96
|
-
* `JSON.stringify` does the quoting, NOT a hand-rolled `replace(/'/g, …)`. The reason string embeds
|
|
97
|
-
* arbitrary author text (the step sentence), and hand-escaping only the quote character is wrong for
|
|
98
|
-
* any input containing a backslash or a raw newline: a step ending `…\` would emit `'…\\'`, whose
|
|
99
|
-
* trailing escaped-backslash-then-quote breaks the literal and takes the WHOLE generated spec down
|
|
100
|
-
* with a syntax error — reopening, one level deeper, the exact "one bad step kills the file" failure
|
|
101
|
-
* this function exists to prevent. Step text here is routinely non-ASCII (Vietnamese, Japanese),
|
|
102
|
-
* which JSON.stringify also handles correctly.
|
|
103
|
-
*/
|
|
104
|
-
function unsupportedStepCode(reason) {
|
|
105
|
-
return `throw new Error(${JSON.stringify(`[sungen] ${reason}`)});`;
|
|
106
|
-
}
|
|
107
78
|
/**
|
|
108
79
|
* Pattern Registry - manages all step patterns
|
|
109
80
|
*/
|
|
@@ -140,7 +111,7 @@ class PatternRegistry {
|
|
|
140
111
|
// THEN normalise `tap` → `click`, so the mobile phrasing reaches the whole shared vocabulary
|
|
141
112
|
// instead of only the three patterns that happen to key on "tap". Masking first is what keeps a
|
|
142
113
|
// `[Tap Water]` ref from being read as a verb.
|
|
143
|
-
const matchStep = { ...step, text: normalizeVerbs(maskRefsForMatching(step.text)) };
|
|
114
|
+
const matchStep = { ...step, text: normalizeVerbs((0, mask_refs_for_matching_1.maskRefsForMatching)(step.text)) };
|
|
144
115
|
for (const pattern of this.patterns) {
|
|
145
116
|
if (this.matchesPattern(matchStep, pattern.matcher)) {
|
|
146
117
|
return pattern;
|
|
@@ -159,7 +130,7 @@ class PatternRegistry {
|
|
|
159
130
|
// pattern in priority order instead of crashing or silently dropping the step.
|
|
160
131
|
// Matching mirrors findPattern exactly: refs masked FIRST (so `[Tap Water]` is not a
|
|
161
132
|
// verb), then `tap` → `click` normalisation for the mobile vocabulary.
|
|
162
|
-
const matchStep = { ...step, text: normalizeVerbs(maskRefsForMatching(step.text)) };
|
|
133
|
+
const matchStep = { ...step, text: normalizeVerbs((0, mask_refs_for_matching_1.maskRefsForMatching)(step.text)) };
|
|
163
134
|
for (const pattern of this.patterns) {
|
|
164
135
|
if (!this.matchesPattern(matchStep, pattern.matcher))
|
|
165
136
|
continue;
|
|
@@ -175,6 +146,16 @@ class PatternRegistry {
|
|
|
175
146
|
const resolved = pattern.resolver(step, context);
|
|
176
147
|
if (!resolved)
|
|
177
148
|
continue; // resolver declined — fall through
|
|
149
|
+
// State-clause gate. Deliberately AFTER the resolver, not before it: a resolver may return
|
|
150
|
+
// null to say "not mine after all", and the search then continues to a lower-priority
|
|
151
|
+
// pattern that may well be the one that asserts the state. Gating earlier judged a pattern
|
|
152
|
+
// that had not yet claimed the step — `row-count` declines a non-numeric `{{value}}` so
|
|
153
|
+
// `see [R] row with {{status_label}} is disabled` should reach see-with-variable-disabled,
|
|
154
|
+
// but the gate short-circuited it into a throw. Only the pattern that actually OWNS the
|
|
155
|
+
// step gets to be judged on what it drops.
|
|
156
|
+
const resolverStateMiss = PatternRegistry.stateMiss(pattern, context, step);
|
|
157
|
+
if (resolverStateMiss)
|
|
158
|
+
return resolverStateMiss;
|
|
178
159
|
// Auto-inject parent scoping if step has parentRef
|
|
179
160
|
// Skip for table-* patterns — they resolve the table name internally from step text
|
|
180
161
|
if (step.parentRef && step.parentType && !pattern.name.startsWith('table-')) {
|
|
@@ -187,6 +168,10 @@ class PatternRegistry {
|
|
|
187
168
|
};
|
|
188
169
|
}
|
|
189
170
|
if (pattern.generator) {
|
|
171
|
+
// A legacy generator has no decline path, so this pattern owns the step already.
|
|
172
|
+
const generatorStateMiss = PatternRegistry.stateMiss(pattern, context, step);
|
|
173
|
+
if (generatorStateMiss)
|
|
174
|
+
return generatorStateMiss;
|
|
190
175
|
return pattern.generator(step, context);
|
|
191
176
|
}
|
|
192
177
|
return null;
|
|
@@ -220,10 +205,45 @@ class PatternRegistry {
|
|
|
220
205
|
step: step.text,
|
|
221
206
|
});
|
|
222
207
|
return {
|
|
223
|
-
code: unsupportedStepCode(reason),
|
|
208
|
+
code: (0, unsupported_step_code_1.unsupportedStepCode)(reason),
|
|
224
209
|
comment: `${supported}-only step on the ${adapter} adapter — see SG-W020`,
|
|
225
210
|
};
|
|
226
211
|
}
|
|
212
|
+
/**
|
|
213
|
+
* SG-E021 — the step carries a trailing state clause the matched pattern does not account for.
|
|
214
|
+
*
|
|
215
|
+
* Priority decides which pattern wins, and the winner is not always the one that reads the clause:
|
|
216
|
+
* `see [X] page is hidden` matched `page-assertion` (13) ahead of `is-hidden` (11), so `is hidden`
|
|
217
|
+
* was dropped and the step compiled to `toHaveURL(...)` — asserting the page IS shown, the exact
|
|
218
|
+
* inverse of the sentence, and passing. Nothing detected it, because the clause lived only inside
|
|
219
|
+
* `step.text` and each pattern re-regexed it privately.
|
|
220
|
+
*
|
|
221
|
+
* `states` makes the claim explicit and checkable: a pattern declares what its template accounts
|
|
222
|
+
* for, and anything else lands here. Strict reading — an ABSENT `states` accounts for nothing —
|
|
223
|
+
* because the failure modes are asymmetric. Under-declaring throws on valid input, which is loud,
|
|
224
|
+
* local, and fixed by one annotation. Over-declaring restores the silent inversion this exists to
|
|
225
|
+
* close, and nothing catches it again.
|
|
226
|
+
*/
|
|
227
|
+
static stateMiss(pattern, context, step) {
|
|
228
|
+
const state = step.state;
|
|
229
|
+
if (!state)
|
|
230
|
+
return null;
|
|
231
|
+
if (pattern.states?.includes(state))
|
|
232
|
+
return null;
|
|
233
|
+
const reason = `step "${step.text}" carries the state clause "is ${state}", but the pattern that matched it ` +
|
|
234
|
+
`("${pattern.name}") does not assert that state — the clause would be SILENTLY DROPPED and the ` +
|
|
235
|
+
`step would check something other than what it reads as. Use a step form that owns the state ` +
|
|
236
|
+
`(e.g. "User see [Ref] <type> is ${state}" on the element itself), or drop the clause if the ` +
|
|
237
|
+
`bare assertion is what you meant. If sungen cannot express the check, tag the scenario @manual.`;
|
|
238
|
+
context.diagnostics?.add('SG-E021', reason, {
|
|
239
|
+
feature: context.featureName,
|
|
240
|
+
step: step.text,
|
|
241
|
+
});
|
|
242
|
+
return {
|
|
243
|
+
code: (0, unsupported_step_code_1.unsupportedStepCode)(reason),
|
|
244
|
+
comment: `"is ${state}" not asserted by "${pattern.name}" — see SG-E021`,
|
|
245
|
+
};
|
|
246
|
+
}
|
|
227
247
|
/**
|
|
228
248
|
* SG-E020 — the pattern is in-platform but the active adapter ships no template for it. A gap in
|
|
229
249
|
* the adapter, not in the authored Gherkin: name every coordinate a reader needs to act on it.
|
|
@@ -238,7 +258,7 @@ class PatternRegistry {
|
|
|
238
258
|
step: step.text,
|
|
239
259
|
});
|
|
240
260
|
return {
|
|
241
|
-
code: unsupportedStepCode(reason),
|
|
261
|
+
code: (0, unsupported_step_code_1.unsupportedStepCode)(reason),
|
|
242
262
|
comment: `no ${adapter} template for "${templateName}" — see SG-E020`,
|
|
243
263
|
};
|
|
244
264
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/generators/test-generator/patterns/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/generators/test-generator/patterns/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -19,6 +19,15 @@ export interface DiagnosticsSink {
|
|
|
19
19
|
* behaviour.
|
|
20
20
|
*/
|
|
21
21
|
export type Platform = 'web' | 'mobile';
|
|
22
|
+
/**
|
|
23
|
+
* The canonical state clauses an assertion step may carry, exactly as documented for authors in
|
|
24
|
+
* `README.md` ("States") and in the `sungen-gherkin-syntax` skill. Deliberately CLOSED: real feature
|
|
25
|
+
* files carry trailing phrases like `is rejected` / `is active` / `is unchanged` that belong to other
|
|
26
|
+
* grammars or are prose, and reading those as state clauses would put valid steps in front of the
|
|
27
|
+
* SG-E021 gate. Widening this union widens that gate — add a member only alongside a pattern that
|
|
28
|
+
* asserts it.
|
|
29
|
+
*/
|
|
30
|
+
export type StateClause = 'hidden' | 'visible' | 'disabled' | 'enabled' | 'checked' | 'unchecked' | 'focused' | 'empty' | 'loading' | 'selected' | 'sorted ascending' | 'sorted descending';
|
|
22
31
|
/**
|
|
23
32
|
* Pattern matcher function or regex
|
|
24
33
|
*/
|
|
@@ -99,5 +108,19 @@ export interface StepPattern {
|
|
|
99
108
|
* emitted when absent.
|
|
100
109
|
*/
|
|
101
110
|
platformAlternative?: string;
|
|
111
|
+
/**
|
|
112
|
+
* State clauses this pattern's generated code ACTUALLY asserts. ABSENT = asserts none.
|
|
113
|
+
*
|
|
114
|
+
* The contract runs in one direction and is easy to get backwards: declaring a state is a promise
|
|
115
|
+
* that the emitted code checks it. A pattern that wins a step carrying an UNDECLARED state clause
|
|
116
|
+
* emits SG-E021 and compiles to a loud `throw`, because the alternative is what this field exists
|
|
117
|
+
* to prevent — the clause being silently dropped and the assertion reading as something it is not.
|
|
118
|
+
* (`see [X] page is hidden` matched `page-assertion` at a higher priority than `is-hidden`, so the
|
|
119
|
+
* clause vanished and the step asserted the OPPOSITE: that the page IS displayed.)
|
|
120
|
+
*
|
|
121
|
+
* So: under-declaring throws on valid input, over-declaring re-opens the silent-drop hole. Declare
|
|
122
|
+
* a state only after reading the template the resolver names.
|
|
123
|
+
*/
|
|
124
|
+
states?: ReadonlyArray<StateClause>;
|
|
102
125
|
}
|
|
103
126
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/generators/test-generator/patterns/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/generators/test-generator/patterns/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The step body emitted in place of code sungen cannot honestly produce — because the active adapter
|
|
3
|
+
* ships no template for it (SG-E020), because the pattern is off-platform (SG-W020), because the
|
|
4
|
+
* matched pattern would silently DROP the author's state clause (SG-E021), or because no pattern
|
|
5
|
+
* matched at all (SG-W001/SG-W011). A comment alone would let the test go GREEN having asserted
|
|
6
|
+
* nothing — the silent-loss class these diagnostics exist to close — so the step throws at run time
|
|
7
|
+
* as well as reporting at compile time.
|
|
8
|
+
*
|
|
9
|
+
* `JSON.stringify` does the quoting, NOT a hand-rolled `replace(/'/g, …)`. The reason string embeds
|
|
10
|
+
* arbitrary author text (the step sentence), and hand-escaping only the quote character is wrong for
|
|
11
|
+
* any input containing a backslash or a raw newline: a step ending `…\` would emit `'…\\'`, whose
|
|
12
|
+
* trailing escaped-backslash-then-quote breaks the literal and takes the WHOLE generated spec down
|
|
13
|
+
* with a syntax error — reopening, one level deeper, the exact "one bad step kills the file" failure
|
|
14
|
+
* this function exists to prevent. Step text here is routinely non-ASCII (Vietnamese, Japanese),
|
|
15
|
+
* which JSON.stringify also handles correctly.
|
|
16
|
+
*/
|
|
17
|
+
export declare function unsupportedStepCode(reason: string): string;
|
|
18
|
+
//# sourceMappingURL=unsupported-step-code.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unsupported-step-code.d.ts","sourceRoot":"","sources":["../../../../src/generators/test-generator/patterns/unsupported-step-code.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAE1D"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.unsupportedStepCode = unsupportedStepCode;
|
|
4
|
+
/**
|
|
5
|
+
* The step body emitted in place of code sungen cannot honestly produce — because the active adapter
|
|
6
|
+
* ships no template for it (SG-E020), because the pattern is off-platform (SG-W020), because the
|
|
7
|
+
* matched pattern would silently DROP the author's state clause (SG-E021), or because no pattern
|
|
8
|
+
* matched at all (SG-W001/SG-W011). A comment alone would let the test go GREEN having asserted
|
|
9
|
+
* nothing — the silent-loss class these diagnostics exist to close — so the step throws at run time
|
|
10
|
+
* as well as reporting at compile time.
|
|
11
|
+
*
|
|
12
|
+
* `JSON.stringify` does the quoting, NOT a hand-rolled `replace(/'/g, …)`. The reason string embeds
|
|
13
|
+
* arbitrary author text (the step sentence), and hand-escaping only the quote character is wrong for
|
|
14
|
+
* any input containing a backslash or a raw newline: a step ending `…\` would emit `'…\\'`, whose
|
|
15
|
+
* trailing escaped-backslash-then-quote breaks the literal and takes the WHOLE generated spec down
|
|
16
|
+
* with a syntax error — reopening, one level deeper, the exact "one bad step kills the file" failure
|
|
17
|
+
* this function exists to prevent. Step text here is routinely non-ASCII (Vietnamese, Japanese),
|
|
18
|
+
* which JSON.stringify also handles correctly.
|
|
19
|
+
*/
|
|
20
|
+
function unsupportedStepCode(reason) {
|
|
21
|
+
return `throw new Error(${JSON.stringify(`[sungen] ${reason}`)});`;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=unsupported-step-code.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unsupported-step-code.js","sourceRoot":"","sources":["../../../../src/generators/test-generator/patterns/unsupported-step-code.ts"],"names":[],"mappings":";;AAgBA,kDAEC;AAlBD;;;;;;;;;;;;;;;GAeG;AACH,SAAgB,mBAAmB,CAAC,MAAc;IAChD,OAAO,mBAAmB,IAAI,CAAC,SAAS,CAAC,YAAY,MAAM,EAAE,CAAC,IAAI,CAAC;AACrE,CAAC"}
|
|
@@ -89,8 +89,16 @@ function expandPrimitive(prim, ctx, itemVar) {
|
|
|
89
89
|
return { partial: 'recipe-click-text', targetExpr: expr };
|
|
90
90
|
}
|
|
91
91
|
case 'expectText': {
|
|
92
|
+
// `exact: true` asserts the element's WHOLE text (toHaveText) instead of a substring
|
|
93
|
+
// (toContainText) — same opt-in flag `clickText` carries. Substring stays the default so
|
|
94
|
+
// existing recipes keep their behavior.
|
|
92
95
|
const o = (typeof arg === 'object' && arg !== null ? arg : {});
|
|
93
|
-
return {
|
|
96
|
+
return {
|
|
97
|
+
partial: 'recipe-expect-text',
|
|
98
|
+
targetExpr: targetExpr(o.locator ?? '$trigger'),
|
|
99
|
+
valueExpr: valueExpr(o.value ?? '$value'),
|
|
100
|
+
exact: o.exact === true,
|
|
101
|
+
};
|
|
94
102
|
}
|
|
95
103
|
case 'expectValue': {
|
|
96
104
|
const o = (typeof arg === 'object' && arg !== null ? arg : {});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recipe-expander.js","sourceRoot":"","sources":["../../../src/generators/test-generator/recipe-expander.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"recipe-expander.js","sourceRoot":"","sources":["../../../src/generators/test-generator/recipe-expander.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mobile reset tiers — how much state a scenario starts from.
|
|
3
|
+
*
|
|
4
|
+
* Web gets a clean slate for free: a URL reload is effectively a fresh state. Mobile does not. To save
|
|
5
|
+
* time, mobile automation keeps the app alive across a whole session, so the end state of one scenario
|
|
6
|
+
* becomes the start state of the next — which breaks test independence three ways: scenarios can no
|
|
7
|
+
* longer run in isolation or in parallel, a "nearly right" leftover state makes the FOLLOWING scenario
|
|
8
|
+
* fail for reasons that have nothing to do with it, and a scenario that dies mid-flow poisons every
|
|
9
|
+
* scenario after it.
|
|
10
|
+
*
|
|
11
|
+
* The reason nobody just reinstalls between scenarios is cost: a cold start is 5–30s, which across a
|
|
12
|
+
* large suite is the whole CI budget. So the state layers (local DB, cache, prefs, keychain, OS
|
|
13
|
+
* permissions) need a LADDER rather than one all-or-nothing switch — the same conclusion every major
|
|
14
|
+
* framework reached (Appium's `mobile: clearApp`, Detox's `device.reloadReactNative()`, the OS-level
|
|
15
|
+
* reset APIs in XCUITest/Espresso).
|
|
16
|
+
*
|
|
17
|
+
* none — nothing is reset. State carries over BY DESIGN (a cart that accumulates across scenarios).
|
|
18
|
+
* soft — terminateApp + activateApp. Clears in-memory state and the navigation stack. THE DEFAULT,
|
|
19
|
+
* and exactly what the compiler emitted before tiers existed, so no existing suite changes.
|
|
20
|
+
* data — soft + wipe the app's data layer (local DB, cache, prefs, keychain).
|
|
21
|
+
* full — remove + reinstall. Also resets permissions and any install-time state.
|
|
22
|
+
*
|
|
23
|
+
* Declared per feature via `@reset:<tier>`; a run can RAISE the floor with SUNGEN_RESET_TIER without
|
|
24
|
+
* regenerating specs (resolved inside the generated spec, the same runtime model as test-data overlays).
|
|
25
|
+
*/
|
|
26
|
+
/** Ordered weakest → strongest. Index order IS the comparison, so never reorder this. */
|
|
27
|
+
export declare const RESET_TIERS: readonly ["none", "soft", "data", "full"];
|
|
28
|
+
export type ResetTier = (typeof RESET_TIERS)[number];
|
|
29
|
+
/**
|
|
30
|
+
* `soft` — the behaviour the appium adapter emitted before tiers existed. Keeping it the default is
|
|
31
|
+
* what makes this feature additive: an untagged feature compiles to the same spec it did before.
|
|
32
|
+
*/
|
|
33
|
+
export declare const DEFAULT_RESET_TIER: ResetTier;
|
|
34
|
+
/**
|
|
35
|
+
* Read the `@reset:<tier>` tag off a tag list.
|
|
36
|
+
*
|
|
37
|
+
* Returns `undefined` when no `@reset:` tag is present — deliberately NOT the default. Callers need to
|
|
38
|
+
* tell "absent" from "explicitly soft": a scenario with no tag must inherit its feature's tier, and
|
|
39
|
+
* collapsing absent into `soft` here would silently RAISE a `@reset:none` feature.
|
|
40
|
+
*
|
|
41
|
+
* An unrecognized value warns and yields the default rather than throwing, matching how `@cleanup:`
|
|
42
|
+
* handles an unknown key — a typo in a tag should not stop a build.
|
|
43
|
+
*/
|
|
44
|
+
export declare function parseResetTier(tags: string[]): ResetTier | undefined;
|
|
45
|
+
/** The stronger of two tiers. Used to combine a declared tier with a run-level floor. */
|
|
46
|
+
export declare function maxResetTier(a: ResetTier, b: ResetTier): ResetTier;
|
|
47
|
+
/**
|
|
48
|
+
* One rung harder — what the NEXT scenario resets to after this one failed.
|
|
49
|
+
*
|
|
50
|
+
* A failed scenario left unknown state behind (a half-written local DB, an open modal) that a plain
|
|
51
|
+
* process relaunch does not undo, so the scenario after it deserves a stronger reset than it asked for.
|
|
52
|
+
*
|
|
53
|
+
* `none` is a FIXED POINT, on purpose. It is an explicit "state carries over" contract — a chain of
|
|
54
|
+
* scenarios building up one cart. Escalating it would silently break that contract, and the chain is
|
|
55
|
+
* already dead once one link fails, so the relaunch would only change how the rest fail, not whether.
|
|
56
|
+
*
|
|
57
|
+
* Applies to the next DIFFERENT scenario only — never to a RETRY of the one that just failed. The
|
|
58
|
+
* runner re-runs a failed scenario, and giving attempt 2 a stronger reset would break the guarantee
|
|
59
|
+
* `mochaOpts.retries` rests on: race victims recover on attempt 2, real failures fail both attempts.
|
|
60
|
+
* A dirty-state failure IS a real failure; if its retry silently got a wiped data layer it would pass,
|
|
61
|
+
* the reporter keeps the last attempt, and a scenario that only works after a wipe would ship as a
|
|
62
|
+
* clean `Passed`. That false pass is worse than the flakiness escalation was added to fix.
|
|
63
|
+
*
|
|
64
|
+
* The generated spec emits this same ladder inline; both exist so the compiler and the runtime cannot
|
|
65
|
+
* drift apart, and a test asserts they agree.
|
|
66
|
+
*/
|
|
67
|
+
export declare function escalateResetTier(tier: ResetTier): ResetTier;
|
|
68
|
+
//# sourceMappingURL=reset-tier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reset-tier.d.ts","sourceRoot":"","sources":["../../../src/generators/test-generator/reset-tier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,yFAAyF;AACzF,eAAO,MAAM,WAAW,2CAA4C,CAAC;AAErE,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AAErD;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,SAAkB,CAAC;AAMpD;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,SAAS,GAAG,SAAS,CAOpE;AAED,yFAAyF;AACzF,wBAAgB,YAAY,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,GAAG,SAAS,CAElE;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,SAAS,GAAG,SAAS,CAO5D"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Mobile reset tiers — how much state a scenario starts from.
|
|
4
|
+
*
|
|
5
|
+
* Web gets a clean slate for free: a URL reload is effectively a fresh state. Mobile does not. To save
|
|
6
|
+
* time, mobile automation keeps the app alive across a whole session, so the end state of one scenario
|
|
7
|
+
* becomes the start state of the next — which breaks test independence three ways: scenarios can no
|
|
8
|
+
* longer run in isolation or in parallel, a "nearly right" leftover state makes the FOLLOWING scenario
|
|
9
|
+
* fail for reasons that have nothing to do with it, and a scenario that dies mid-flow poisons every
|
|
10
|
+
* scenario after it.
|
|
11
|
+
*
|
|
12
|
+
* The reason nobody just reinstalls between scenarios is cost: a cold start is 5–30s, which across a
|
|
13
|
+
* large suite is the whole CI budget. So the state layers (local DB, cache, prefs, keychain, OS
|
|
14
|
+
* permissions) need a LADDER rather than one all-or-nothing switch — the same conclusion every major
|
|
15
|
+
* framework reached (Appium's `mobile: clearApp`, Detox's `device.reloadReactNative()`, the OS-level
|
|
16
|
+
* reset APIs in XCUITest/Espresso).
|
|
17
|
+
*
|
|
18
|
+
* none — nothing is reset. State carries over BY DESIGN (a cart that accumulates across scenarios).
|
|
19
|
+
* soft — terminateApp + activateApp. Clears in-memory state and the navigation stack. THE DEFAULT,
|
|
20
|
+
* and exactly what the compiler emitted before tiers existed, so no existing suite changes.
|
|
21
|
+
* data — soft + wipe the app's data layer (local DB, cache, prefs, keychain).
|
|
22
|
+
* full — remove + reinstall. Also resets permissions and any install-time state.
|
|
23
|
+
*
|
|
24
|
+
* Declared per feature via `@reset:<tier>`; a run can RAISE the floor with SUNGEN_RESET_TIER without
|
|
25
|
+
* regenerating specs (resolved inside the generated spec, the same runtime model as test-data overlays).
|
|
26
|
+
*/
|
|
27
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
28
|
+
exports.DEFAULT_RESET_TIER = exports.RESET_TIERS = void 0;
|
|
29
|
+
exports.parseResetTier = parseResetTier;
|
|
30
|
+
exports.maxResetTier = maxResetTier;
|
|
31
|
+
exports.escalateResetTier = escalateResetTier;
|
|
32
|
+
/** Ordered weakest → strongest. Index order IS the comparison, so never reorder this. */
|
|
33
|
+
exports.RESET_TIERS = ['none', 'soft', 'data', 'full'];
|
|
34
|
+
/**
|
|
35
|
+
* `soft` — the behaviour the appium adapter emitted before tiers existed. Keeping it the default is
|
|
36
|
+
* what makes this feature additive: an untagged feature compiles to the same spec it did before.
|
|
37
|
+
*/
|
|
38
|
+
exports.DEFAULT_RESET_TIER = 'soft';
|
|
39
|
+
function isResetTier(value) {
|
|
40
|
+
return exports.RESET_TIERS.includes(value);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Read the `@reset:<tier>` tag off a tag list.
|
|
44
|
+
*
|
|
45
|
+
* Returns `undefined` when no `@reset:` tag is present — deliberately NOT the default. Callers need to
|
|
46
|
+
* tell "absent" from "explicitly soft": a scenario with no tag must inherit its feature's tier, and
|
|
47
|
+
* collapsing absent into `soft` here would silently RAISE a `@reset:none` feature.
|
|
48
|
+
*
|
|
49
|
+
* An unrecognized value warns and yields the default rather than throwing, matching how `@cleanup:`
|
|
50
|
+
* handles an unknown key — a typo in a tag should not stop a build.
|
|
51
|
+
*/
|
|
52
|
+
function parseResetTier(tags) {
|
|
53
|
+
const tag = tags.find((t) => t.startsWith('@reset:'));
|
|
54
|
+
if (!tag)
|
|
55
|
+
return undefined;
|
|
56
|
+
const value = tag.slice('@reset:'.length).trim().toLowerCase();
|
|
57
|
+
if (isResetTier(value))
|
|
58
|
+
return value;
|
|
59
|
+
console.warn(`⚠ Unknown @reset:${value} — valid tiers: ${exports.RESET_TIERS.join(', ')}. Using '${exports.DEFAULT_RESET_TIER}'.`);
|
|
60
|
+
return exports.DEFAULT_RESET_TIER;
|
|
61
|
+
}
|
|
62
|
+
/** The stronger of two tiers. Used to combine a declared tier with a run-level floor. */
|
|
63
|
+
function maxResetTier(a, b) {
|
|
64
|
+
return exports.RESET_TIERS.indexOf(a) >= exports.RESET_TIERS.indexOf(b) ? a : b;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* One rung harder — what the NEXT scenario resets to after this one failed.
|
|
68
|
+
*
|
|
69
|
+
* A failed scenario left unknown state behind (a half-written local DB, an open modal) that a plain
|
|
70
|
+
* process relaunch does not undo, so the scenario after it deserves a stronger reset than it asked for.
|
|
71
|
+
*
|
|
72
|
+
* `none` is a FIXED POINT, on purpose. It is an explicit "state carries over" contract — a chain of
|
|
73
|
+
* scenarios building up one cart. Escalating it would silently break that contract, and the chain is
|
|
74
|
+
* already dead once one link fails, so the relaunch would only change how the rest fail, not whether.
|
|
75
|
+
*
|
|
76
|
+
* Applies to the next DIFFERENT scenario only — never to a RETRY of the one that just failed. The
|
|
77
|
+
* runner re-runs a failed scenario, and giving attempt 2 a stronger reset would break the guarantee
|
|
78
|
+
* `mochaOpts.retries` rests on: race victims recover on attempt 2, real failures fail both attempts.
|
|
79
|
+
* A dirty-state failure IS a real failure; if its retry silently got a wiped data layer it would pass,
|
|
80
|
+
* the reporter keeps the last attempt, and a scenario that only works after a wipe would ship as a
|
|
81
|
+
* clean `Passed`. That false pass is worse than the flakiness escalation was added to fix.
|
|
82
|
+
*
|
|
83
|
+
* The generated spec emits this same ladder inline; both exist so the compiler and the runtime cannot
|
|
84
|
+
* drift apart, and a test asserts they agree.
|
|
85
|
+
*/
|
|
86
|
+
function escalateResetTier(tier) {
|
|
87
|
+
switch (tier) {
|
|
88
|
+
case 'none': return 'none';
|
|
89
|
+
case 'soft': return 'data';
|
|
90
|
+
case 'data': return 'full';
|
|
91
|
+
case 'full': return 'full';
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=reset-tier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reset-tier.js","sourceRoot":"","sources":["../../../src/generators/test-generator/reset-tier.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;;;AA2BH,wCAOC;AAGD,oCAEC;AAsBD,8CAOC;AAlED,yFAAyF;AAC5E,QAAA,WAAW,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAU,CAAC;AAIrE;;;GAGG;AACU,QAAA,kBAAkB,GAAc,MAAM,CAAC;AAEpD,SAAS,WAAW,CAAC,KAAa;IAChC,OAAQ,mBAAiC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AAC5D,CAAC;AAED;;;;;;;;;GASG;AACH,SAAgB,cAAc,CAAC,IAAc;IAC3C,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC;IACtD,IAAI,CAAC,GAAG;QAAE,OAAO,SAAS,CAAC;IAC3B,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC/D,IAAI,WAAW,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,oBAAoB,KAAK,mBAAmB,mBAAW,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,0BAAkB,IAAI,CAAC,CAAC;IACnH,OAAO,0BAAkB,CAAC;AAC5B,CAAC;AAED,yFAAyF;AACzF,SAAgB,YAAY,CAAC,CAAY,EAAE,CAAY;IACrD,OAAO,mBAAW,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,mBAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAClE,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,SAAgB,iBAAiB,CAAC,IAAe;IAC/C,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,MAAM,CAAC,CAAC,OAAO,MAAM,CAAC;QAC3B,KAAK,MAAM,CAAC,CAAC,OAAO,MAAM,CAAC;QAC3B,KAAK,MAAM,CAAC,CAAC,OAAO,MAAM,CAAC;QAC3B,KAAK,MAAM,CAAC,CAAC,OAAO,MAAM,CAAC;IAC7B,CAAC;AACH,CAAC"}
|
|
@@ -130,6 +130,23 @@ export declare class StepMapper {
|
|
|
130
130
|
* disappears from the output (e.g. issue #464). Warning-only: loose containment
|
|
131
131
|
* checks err on the side of NOT flagging.
|
|
132
132
|
*/
|
|
133
|
+
/**
|
|
134
|
+
* SG-E023 — an assertion CLAUSE was swallowed and the step became a bare visibility check.
|
|
135
|
+
*
|
|
136
|
+
* The sibling of SG-E021, for the clauses that are not states. SG-E021 closed the state case
|
|
137
|
+
* declaratively — a pattern lists the states it accounts for and anything else throws — but a
|
|
138
|
+
* dropped `matches` / `contains` / `has text` still slid through: reproduced live, a `matches
|
|
139
|
+
* "<format>"` step compiled by a sungen predating that step lost the assertion entirely, emitted
|
|
140
|
+
* no warning, and left a `toBeVisible()` that passed whatever the label said.
|
|
141
|
+
*
|
|
142
|
+
* So: if the code is a bare visibility assertion while the text still carries a clause that
|
|
143
|
+
* means something STRONGER, compile a throw instead (the SG-W001/SG-E020 treatment). A red test
|
|
144
|
+
* naming the swallowed clause costs minutes; a green one that asserts nothing costs a release.
|
|
145
|
+
*
|
|
146
|
+
* Deliberately narrow — it fires only on the bare-visibility shape, so a pattern that genuinely
|
|
147
|
+
* consumed the clause (`is-hidden`, `contains`, `matches-format`, the state family) is untouched.
|
|
148
|
+
*/
|
|
149
|
+
private checkAssertionClauseSwallowed;
|
|
133
150
|
private checkDataRefConsumed;
|
|
134
151
|
/**
|
|
135
152
|
* Generate column assertion scoped to the current row.
|
|
@@ -151,6 +168,28 @@ export declare class StepMapper {
|
|
|
151
168
|
/**
|
|
152
169
|
* Create pattern context for generators
|
|
153
170
|
*/
|
|
171
|
+
/**
|
|
172
|
+
* SG-W023 — a mobile SETUP step that emitted no executable code, so a declared precondition is
|
|
173
|
+
* never actually established.
|
|
174
|
+
*
|
|
175
|
+
* `Given the user is logged out` matches `user-not-logged-in` → the `clear-auth` template, which on
|
|
176
|
+
* Appium is a bare comment: mobile auth lives in the keychain and prefs, not in cookies, so there
|
|
177
|
+
* is nothing a per-step action can clear. The step therefore READS as establishing a precondition
|
|
178
|
+
* and establishes nothing — the scenario runs against whatever the previous one left signed in.
|
|
179
|
+
* Same false-pass class as SG-W022, reached through setup instead of assertion.
|
|
180
|
+
*
|
|
181
|
+
* Keyed on the EMITTED CODE, not on a template name (MappedStep does not carry one), so any future
|
|
182
|
+
* setup template that degrades to a comment is caught by the same check. The phrasings mirror the
|
|
183
|
+
* matchers in driver-ui's `setupPatterns`; `application is running` and `user is logged in` are
|
|
184
|
+
* absent on purpose — the first is legitimately empty on mobile (wdio capabilities already launched
|
|
185
|
+
* the app) and the second is a TODO template on BOTH adapters, so neither is a mobile-specific gap.
|
|
186
|
+
*
|
|
187
|
+
* Deliberately NOT compiled to a `throw`, unlike SG-W020/SG-E021: an unestablished precondition
|
|
188
|
+
* weakens the setup rather than inverting an assertion, and throwing would break every mobile suite
|
|
189
|
+
* that already carries one of these steps. The remedy named in the message is a feature-level reset
|
|
190
|
+
* tier, because app state is reset in the `beforeEach` hook — not mid-scenario by a step.
|
|
191
|
+
*/
|
|
192
|
+
private checkSetupNoOpOnMobile;
|
|
154
193
|
/**
|
|
155
194
|
* SG-W022 — a `page` assertion that emitted no executable code on mobile.
|
|
156
195
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"step-mapper.d.ts","sourceRoot":"","sources":["../../../src/generators/test-generator/step-mapper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAM/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"step-mapper.d.ts","sourceRoot":"","sources":["../../../src/generators/test-generator/step-mapper.ts"],"names":[],"mappings":"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"}
|