@sun-asterisk/sungen 3.2.32 → 3.2.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/commands/audit.d.ts +5 -0
- package/dist/cli/commands/audit.d.ts.map +1 -1
- package/dist/cli/commands/audit.js +26 -4
- package/dist/cli/commands/audit.js.map +1 -1
- package/dist/cli/commands/capability.d.ts.map +1 -1
- package/dist/cli/commands/capability.js +35 -17
- package/dist/cli/commands/capability.js.map +1 -1
- package/dist/cli/commands/changed.d.ts.map +1 -1
- package/dist/cli/commands/changed.js +2 -3
- package/dist/cli/commands/changed.js.map +1 -1
- package/dist/cli/commands/dashboard.d.ts.map +1 -1
- package/dist/cli/commands/dashboard.js +2 -28
- package/dist/cli/commands/dashboard.js.map +1 -1
- package/dist/cli/commands/delivery.d.ts.map +1 -1
- package/dist/cli/commands/delivery.js +79 -53
- package/dist/cli/commands/delivery.js.map +1 -1
- package/dist/cli/commands/generate.d.ts.map +1 -1
- package/dist/cli/commands/generate.js +14 -7
- package/dist/cli/commands/generate.js.map +1 -1
- package/dist/cli/commands/results-merge.d.ts +9 -0
- package/dist/cli/commands/results-merge.d.ts.map +1 -1
- package/dist/cli/commands/results-merge.js +9 -12
- package/dist/cli/commands/results-merge.js.map +1 -1
- package/dist/cli/commands/results-sanitize.d.ts.map +1 -1
- package/dist/cli/commands/results-sanitize.js +2 -13
- package/dist/cli/commands/results-sanitize.js.map +1 -1
- package/dist/cli/commands/select.d.ts +12 -0
- package/dist/cli/commands/select.d.ts.map +1 -0
- package/dist/cli/commands/select.js +122 -0
- package/dist/cli/commands/select.js.map +1 -0
- package/dist/cli/commands/update.d.ts.map +1 -1
- package/dist/cli/commands/update.js +3 -0
- package/dist/cli/commands/update.js.map +1 -1
- package/dist/cli/index.js +7 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/dashboard/snapshot-builder.d.ts.map +1 -1
- package/dist/dashboard/snapshot-builder.js +6 -10
- package/dist/dashboard/snapshot-builder.js.map +1 -1
- package/dist/dashboard/templates/index.html +1 -1
- package/dist/dashboard/types.d.ts +1 -0
- package/dist/dashboard/types.d.ts.map +1 -1
- package/dist/exporters/csv-exporter.d.ts.map +1 -1
- package/dist/exporters/csv-exporter.js +11 -10
- package/dist/exporters/csv-exporter.js.map +1 -1
- package/dist/exporters/feature-parser.d.ts +21 -0
- package/dist/exporters/feature-parser.d.ts.map +1 -1
- package/dist/exporters/feature-parser.js +32 -1
- package/dist/exporters/feature-parser.js.map +1 -1
- package/dist/exporters/json-exporter.d.ts.map +1 -1
- package/dist/exporters/json-exporter.js +7 -0
- package/dist/exporters/json-exporter.js.map +1 -1
- package/dist/exporters/locale-variants.d.ts +7 -1
- package/dist/exporters/locale-variants.d.ts.map +1 -1
- package/dist/exporters/locale-variants.js +23 -16
- package/dist/exporters/locale-variants.js.map +1 -1
- package/dist/exporters/manual-hybrid-oracle.d.ts +54 -0
- package/dist/exporters/manual-hybrid-oracle.d.ts.map +1 -0
- package/dist/exporters/manual-hybrid-oracle.js +114 -0
- package/dist/exporters/manual-hybrid-oracle.js.map +1 -0
- package/dist/exporters/matrix/build.d.ts.map +1 -1
- package/dist/exporters/matrix/build.js +19 -9
- package/dist/exporters/matrix/build.js.map +1 -1
- package/dist/exporters/matrix/carry-manual-results.d.ts +70 -0
- package/dist/exporters/matrix/carry-manual-results.d.ts.map +1 -0
- package/dist/exporters/matrix/carry-manual-results.js +232 -0
- package/dist/exporters/matrix/carry-manual-results.js.map +1 -0
- package/dist/exporters/matrix/export.d.ts +5 -0
- package/dist/exporters/matrix/export.d.ts.map +1 -1
- package/dist/exporters/matrix/export.js +8 -1
- package/dist/exporters/matrix/export.js.map +1 -1
- package/dist/exporters/matrix/gates.js +6 -0
- package/dist/exporters/matrix/gates.js.map +1 -1
- package/dist/exporters/matrix/render-testcase-sheet.d.ts.map +1 -1
- package/dist/exporters/matrix/render-testcase-sheet.js +10 -4
- package/dist/exporters/matrix/render-testcase-sheet.js.map +1 -1
- package/dist/exporters/matrix/types.d.ts +8 -1
- package/dist/exporters/matrix/types.d.ts.map +1 -1
- package/dist/exporters/matrix/types.js.map +1 -1
- package/dist/exporters/matrix/wording.d.ts +8 -1
- package/dist/exporters/matrix/wording.d.ts.map +1 -1
- package/dist/exporters/matrix/wording.js +37 -2
- package/dist/exporters/matrix/wording.js.map +1 -1
- package/dist/exporters/run-environment.d.ts +32 -0
- package/dist/exporters/run-environment.d.ts.map +1 -0
- package/dist/exporters/run-environment.js +125 -0
- package/dist/exporters/run-environment.js.map +1 -0
- package/dist/exporters/scenario-merger.d.ts +18 -0
- package/dist/exporters/scenario-merger.d.ts.map +1 -1
- package/dist/exporters/scenario-merger.js +47 -3
- package/dist/exporters/scenario-merger.js.map +1 -1
- package/dist/exporters/test-data-resolver.d.ts +0 -4
- package/dist/exporters/test-data-resolver.d.ts.map +1 -1
- package/dist/exporters/test-data-resolver.js +0 -7
- package/dist/exporters/test-data-resolver.js.map +1 -1
- package/dist/exporters/xlsx-exporter.d.ts +2 -0
- package/dist/exporters/xlsx-exporter.d.ts.map +1 -1
- package/dist/exporters/xlsx-exporter.js +7 -2
- package/dist/exporters/xlsx-exporter.js.map +1 -1
- package/dist/generators/gherkin-parser/index.d.ts +11 -4
- package/dist/generators/gherkin-parser/index.d.ts.map +1 -1
- package/dist/generators/gherkin-parser/index.js +49 -19
- package/dist/generators/gherkin-parser/index.js.map +1 -1
- package/dist/generators/test-generator/adapters/adapter-interface.d.ts +4 -0
- package/dist/generators/test-generator/adapters/adapter-interface.d.ts.map +1 -1
- package/dist/generators/test-generator/adapters/appium/templates/steps/actions/reinstall-app-action.hbs +2 -2
- package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/label-value-assertion.hbs +8 -2
- package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/visible-with-role-variable-assertion.hbs +7 -3
- package/dist/generators/test-generator/adapters/appium/templates/test-file.hbs +68 -4
- package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/click-select-action.hbs +1 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/select-action.hbs +1 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/label-value-assertion.hbs +7 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-with-role-variable-assertion.hbs +8 -4
- package/dist/generators/test-generator/adapters/playwright/templates/steps/partials/pick-option.hbs +13 -0
- package/dist/generators/test-generator/adapters/playwright/templates/steps/partials/url-assertion.hbs +5 -1
- package/dist/generators/test-generator/adapters/playwright/templates/test-file.hbs +16 -0
- package/dist/generators/test-generator/code-generator.d.ts +2 -1
- package/dist/generators/test-generator/code-generator.d.ts.map +1 -1
- package/dist/generators/test-generator/code-generator.js +90 -5
- package/dist/generators/test-generator/code-generator.js.map +1 -1
- package/dist/generators/test-generator/diagnostics.d.ts +36 -5
- package/dist/generators/test-generator/diagnostics.d.ts.map +1 -1
- package/dist/generators/test-generator/diagnostics.js +35 -4
- package/dist/generators/test-generator/diagnostics.js.map +1 -1
- package/dist/generators/test-generator/patterns/index.d.ts +12 -2
- package/dist/generators/test-generator/patterns/index.d.ts.map +1 -1
- package/dist/generators/test-generator/patterns/index.js +15 -9
- package/dist/generators/test-generator/patterns/index.js.map +1 -1
- package/dist/generators/test-generator/patterns/types.d.ts +15 -0
- package/dist/generators/test-generator/patterns/types.d.ts.map +1 -1
- package/dist/generators/test-generator/patterns/with-parent-scope.d.ts +5 -0
- package/dist/generators/test-generator/patterns/with-parent-scope.d.ts.map +1 -1
- package/dist/generators/test-generator/patterns/with-parent-scope.js +6 -0
- package/dist/generators/test-generator/patterns/with-parent-scope.js.map +1 -1
- package/dist/generators/test-generator/step-mapper.d.ts +46 -0
- package/dist/generators/test-generator/step-mapper.d.ts.map +1 -1
- package/dist/generators/test-generator/step-mapper.js +84 -9
- package/dist/generators/test-generator/step-mapper.js.map +1 -1
- package/dist/generators/test-generator/utils/data-resolver.d.ts +25 -0
- package/dist/generators/test-generator/utils/data-resolver.d.ts.map +1 -1
- package/dist/generators/test-generator/utils/data-resolver.js +39 -8
- package/dist/generators/test-generator/utils/data-resolver.js.map +1 -1
- package/dist/generators/test-generator/utils/selector-entry-fields.d.ts.map +1 -1
- package/dist/generators/test-generator/utils/selector-entry-fields.js +1 -0
- package/dist/generators/test-generator/utils/selector-entry-fields.js.map +1 -1
- package/dist/generators/test-generator/utils/selector-resolver.d.ts +37 -4
- package/dist/generators/test-generator/utils/selector-resolver.d.ts.map +1 -1
- package/dist/generators/test-generator/utils/selector-resolver.js +212 -79
- package/dist/generators/test-generator/utils/selector-resolver.js.map +1 -1
- package/dist/harness/audit.d.ts +3 -0
- package/dist/harness/audit.d.ts.map +1 -1
- package/dist/harness/audit.js +29 -12
- package/dist/harness/audit.js.map +1 -1
- package/dist/harness/capability.d.ts +7 -1
- package/dist/harness/capability.d.ts.map +1 -1
- package/dist/harness/capability.js +15 -12
- package/dist/harness/capability.js.map +1 -1
- package/dist/harness/catalog/universal-viewpoints.yaml +5 -5
- package/dist/harness/config-file.d.ts +17 -0
- package/dist/harness/config-file.d.ts.map +1 -0
- package/dist/harness/config-file.js +100 -0
- package/dist/harness/config-file.js.map +1 -0
- package/dist/harness/data-driven-lint.d.ts.map +1 -1
- package/dist/harness/data-driven-lint.js +69 -27
- package/dist/harness/data-driven-lint.js.map +1 -1
- package/dist/harness/depth-lint.d.ts.map +1 -1
- package/dist/harness/depth-lint.js +2 -1
- package/dist/harness/depth-lint.js.map +1 -1
- package/dist/harness/flow-check.d.ts.map +1 -1
- package/dist/harness/flow-check.js +6 -2
- package/dist/harness/flow-check.js.map +1 -1
- package/dist/harness/keyword-match.d.ts +59 -0
- package/dist/harness/keyword-match.d.ts.map +1 -0
- package/dist/harness/keyword-match.js +86 -0
- package/dist/harness/keyword-match.js.map +1 -0
- package/dist/harness/next-step.d.ts.map +1 -1
- package/dist/harness/next-step.js +1 -0
- package/dist/harness/next-step.js.map +1 -1
- package/dist/harness/parse.d.ts +24 -0
- package/dist/harness/parse.d.ts.map +1 -1
- package/dist/harness/parse.js +117 -13
- package/dist/harness/parse.js.map +1 -1
- package/dist/harness/perf.d.ts +7 -1
- package/dist/harness/perf.d.ts.map +1 -1
- package/dist/harness/perf.js +13 -10
- package/dist/harness/perf.js.map +1 -1
- package/dist/harness/quality-gates.d.ts +9 -2
- package/dist/harness/quality-gates.d.ts.map +1 -1
- package/dist/harness/quality-gates.js +22 -8
- package/dist/harness/quality-gates.js.map +1 -1
- package/dist/harness/query-catalog.js +0 -0
- package/dist/harness/query-catalog.js.map +1 -1
- package/dist/harness/read-text.d.ts +21 -0
- package/dist/harness/read-text.d.ts.map +1 -1
- package/dist/harness/read-text.js +32 -1
- package/dist/harness/read-text.js.map +1 -1
- package/dist/harness/secret-scan.d.ts +27 -1
- package/dist/harness/secret-scan.d.ts.map +1 -1
- package/dist/harness/secret-scan.js +57 -4
- package/dist/harness/secret-scan.js.map +1 -1
- package/dist/harness/select-by-ids.d.ts +31 -0
- package/dist/harness/select-by-ids.d.ts.map +1 -0
- package/dist/harness/select-by-ids.js +106 -0
- package/dist/harness/select-by-ids.js.map +1 -0
- package/dist/harness/sensors.d.ts +20 -1
- package/dist/harness/sensors.d.ts.map +1 -1
- package/dist/harness/sensors.js +102 -27
- package/dist/harness/sensors.js.map +1 -1
- package/dist/harness/spec-branches.d.ts +0 -18
- package/dist/harness/spec-branches.d.ts.map +1 -1
- package/dist/harness/spec-branches.js +24 -3
- package/dist/harness/spec-branches.js.map +1 -1
- package/dist/harness/spec-coverage.d.ts.map +1 -1
- package/dist/harness/spec-coverage.js +14 -4
- package/dist/harness/spec-coverage.js.map +1 -1
- package/dist/harness/ui-inventory.d.ts +40 -0
- package/dist/harness/ui-inventory.d.ts.map +1 -0
- package/dist/harness/ui-inventory.js +191 -0
- package/dist/harness/ui-inventory.js.map +1 -0
- package/dist/harness/viewpoint-ledger.d.ts.map +1 -1
- package/dist/harness/viewpoint-ledger.js +66 -10
- package/dist/harness/viewpoint-ledger.js.map +1 -1
- package/dist/harness/write-atomic.d.ts +2 -0
- package/dist/harness/write-atomic.d.ts.map +1 -0
- package/dist/harness/write-atomic.js +62 -0
- package/dist/harness/write-atomic.js.map +1 -0
- package/dist/orchestrator/ai-skills/writer.d.ts.map +1 -1
- package/dist/orchestrator/ai-skills/writer.js +15 -7
- package/dist/orchestrator/ai-skills/writer.js.map +1 -1
- package/dist/orchestrator/assets-drift.d.ts.map +1 -1
- package/dist/orchestrator/assets-drift.js +11 -6
- package/dist/orchestrator/assets-drift.js.map +1 -1
- package/dist/orchestrator/project-deps-sync.d.ts.map +1 -1
- package/dist/orchestrator/project-deps-sync.js +22 -1
- package/dist/orchestrator/project-deps-sync.js.map +1 -1
- package/dist/orchestrator/project-initializer.d.ts +8 -0
- package/dist/orchestrator/project-initializer.d.ts.map +1 -1
- package/dist/orchestrator/project-initializer.js +49 -7
- package/dist/orchestrator/project-initializer.js.map +1 -1
- package/dist/orchestrator/screen-manager.d.ts.map +1 -1
- package/dist/orchestrator/screen-manager.js +3 -11
- package/dist/orchestrator/screen-manager.js.map +1 -1
- package/dist/orchestrator/security-overrides-catalog.d.ts +39 -0
- package/dist/orchestrator/security-overrides-catalog.d.ts.map +1 -0
- package/dist/orchestrator/security-overrides-catalog.js +63 -0
- package/dist/orchestrator/security-overrides-catalog.js.map +1 -0
- package/dist/orchestrator/security-overrides.d.ts +51 -0
- package/dist/orchestrator/security-overrides.d.ts.map +1 -0
- package/dist/orchestrator/security-overrides.js +165 -0
- package/dist/orchestrator/security-overrides.js.map +1 -0
- package/dist/orchestrator/templates/ai-src/agents/discovery.md +11 -3
- package/dist/orchestrator/templates/ai-src/agents/reviewer.md +8 -0
- package/dist/orchestrator/templates/ai-src/commands/create-test.md +2 -2
- package/dist/orchestrator/templates/ai-src/commands/review.md +2 -2
- package/dist/orchestrator/templates/ai-src/commands/run-test.md +70 -13
- package/dist/orchestrator/templates/ai-src/skills/sungen-capture/mode-local.md +2 -2
- package/dist/orchestrator/templates/ai-src/skills/sungen-delivery/SKILL.md +14 -0
- package/dist/orchestrator/templates/ai-src/skills/sungen-error-mapping/SKILL.md +23 -1
- package/dist/orchestrator/templates/ai-src/skills/sungen-gherkin-syntax/SKILL.md +26 -8
- package/dist/orchestrator/templates/ai-src/skills/sungen-selector-fix/SKILL.md +58 -14
- package/dist/orchestrator/templates/ai-src/skills/sungen-selector-keys/SKILL.md +13 -1
- package/dist/orchestrator/templates/ai-src/skills/sungen-tc-generation/SKILL.md +41 -1
- package/dist/orchestrator/templates/ai-src/skills/sungen-tc-review/SKILL.md +7 -0
- package/dist/orchestrator/templates/playwright.config.ts +4 -2
- package/dist/orchestrator/templates/specs-locale-fixture.ts +21 -9
- package/dist/orchestrator/templates/specs-pw-shape-reporter.ts +0 -0
- package/dist/orchestrator/templates/specs-url-assert.d.ts +17 -1
- package/dist/orchestrator/templates/specs-url-assert.d.ts.map +1 -1
- package/dist/orchestrator/templates/specs-url-assert.js +38 -4
- package/dist/orchestrator/templates/specs-url-assert.js.map +1 -1
- package/dist/orchestrator/templates/specs-url-assert.ts +47 -4
- package/dist/orchestrator/templates/wdio.conf.ts +24 -1
- package/dist/orchestrator/trace-mode-install.d.ts +14 -0
- package/dist/orchestrator/trace-mode-install.d.ts.map +1 -0
- package/dist/orchestrator/trace-mode-install.js +132 -0
- package/dist/orchestrator/trace-mode-install.js.map +1 -0
- package/dist/orchestrator/viewpoint-pattern-catalog.d.ts +20 -0
- package/dist/orchestrator/viewpoint-pattern-catalog.d.ts.map +1 -0
- package/dist/orchestrator/viewpoint-pattern-catalog.js +45 -0
- package/dist/orchestrator/viewpoint-pattern-catalog.js.map +1 -0
- package/package.json +3 -3
- package/src/cli/commands/audit.ts +24 -5
- package/src/cli/commands/capability.ts +51 -18
- package/src/cli/commands/changed.ts +2 -4
- package/src/cli/commands/dashboard.ts +1 -26
- package/src/cli/commands/delivery.ts +75 -48
- package/src/cli/commands/generate.ts +15 -7
- package/src/cli/commands/results-merge.ts +9 -9
- package/src/cli/commands/results-sanitize.ts +2 -9
- package/src/cli/commands/select.ts +88 -0
- package/src/cli/commands/update.ts +3 -0
- package/src/cli/index.ts +7 -2
- package/src/dashboard/snapshot-builder.ts +6 -8
- package/src/dashboard/templates/index.html +1 -1
- package/src/dashboard/types.ts +1 -0
- package/src/exporters/csv-exporter.ts +7 -10
- package/src/exporters/feature-parser.ts +32 -2
- package/src/exporters/json-exporter.ts +6 -1
- package/src/exporters/locale-variants.ts +23 -17
- package/src/exporters/manual-hybrid-oracle.ts +112 -0
- package/src/exporters/matrix/build.ts +20 -10
- package/src/exporters/matrix/carry-manual-results.ts +229 -0
- package/src/exporters/matrix/export.ts +14 -4
- package/src/exporters/matrix/gates.ts +6 -0
- package/src/exporters/matrix/render-testcase-sheet.ts +10 -4
- package/src/exporters/matrix/types.ts +8 -1
- package/src/exporters/matrix/wording.ts +36 -2
- package/src/exporters/run-environment.ts +89 -0
- package/src/exporters/scenario-merger.ts +49 -4
- package/src/exporters/test-data-resolver.ts +0 -6
- package/src/exporters/xlsx-exporter.ts +7 -2
- package/src/generators/gherkin-parser/index.ts +50 -18
- package/src/generators/test-generator/adapters/adapter-interface.ts +6 -2
- package/src/generators/test-generator/adapters/appium/templates/steps/actions/reinstall-app-action.hbs +2 -2
- package/src/generators/test-generator/adapters/appium/templates/steps/assertions/label-value-assertion.hbs +8 -2
- package/src/generators/test-generator/adapters/appium/templates/steps/assertions/visible-with-role-variable-assertion.hbs +7 -3
- package/src/generators/test-generator/adapters/appium/templates/test-file.hbs +68 -4
- package/src/generators/test-generator/adapters/playwright/templates/steps/actions/click-select-action.hbs +1 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/actions/select-action.hbs +1 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/label-value-assertion.hbs +7 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-with-role-variable-assertion.hbs +8 -4
- package/src/generators/test-generator/adapters/playwright/templates/steps/partials/pick-option.hbs +13 -0
- package/src/generators/test-generator/adapters/playwright/templates/steps/partials/url-assertion.hbs +5 -1
- package/src/generators/test-generator/adapters/playwright/templates/test-file.hbs +16 -0
- package/src/generators/test-generator/code-generator.ts +77 -5
- package/src/generators/test-generator/diagnostics.ts +36 -5
- package/src/generators/test-generator/patterns/index.ts +15 -8
- package/src/generators/test-generator/patterns/types.ts +15 -0
- package/src/generators/test-generator/patterns/with-parent-scope.ts +6 -0
- package/src/generators/test-generator/step-mapper.ts +90 -8
- package/src/generators/test-generator/utils/data-resolver.ts +41 -12
- package/src/generators/test-generator/utils/selector-entry-fields.ts +1 -0
- package/src/generators/test-generator/utils/selector-resolver.ts +238 -82
- package/src/harness/audit.ts +37 -16
- package/src/harness/capability.ts +23 -12
- package/src/harness/catalog/universal-viewpoints.yaml +5 -5
- package/src/harness/config-file.ts +66 -0
- package/src/harness/data-driven-lint.ts +82 -24
- package/src/harness/depth-lint.ts +2 -1
- package/src/harness/flow-check.ts +6 -2
- package/src/harness/keyword-match.ts +85 -0
- package/src/harness/next-step.ts +1 -0
- package/src/harness/parse.ts +123 -16
- package/src/harness/perf.ts +15 -7
- package/src/harness/quality-gates.ts +22 -8
- package/src/harness/query-catalog.ts +0 -0
- package/src/harness/read-text.ts +32 -1
- package/src/harness/secret-scan.ts +60 -4
- package/src/harness/select-by-ids.ts +83 -0
- package/src/harness/sensors.ts +109 -28
- package/src/harness/spec-branches.ts +6 -3
- package/src/harness/spec-coverage.ts +14 -4
- package/src/harness/ui-inventory.ts +164 -0
- package/src/harness/viewpoint-ledger.ts +59 -12
- package/src/harness/write-atomic.ts +22 -0
- package/src/orchestrator/ai-skills/writer.ts +18 -3
- package/src/orchestrator/assets-drift.ts +10 -5
- package/src/orchestrator/project-deps-sync.ts +23 -1
- package/src/orchestrator/project-initializer.ts +54 -6
- package/src/orchestrator/screen-manager.ts +3 -11
- package/src/orchestrator/security-overrides-catalog.ts +69 -0
- package/src/orchestrator/security-overrides.ts +149 -0
- package/src/orchestrator/templates/ai-src/agents/discovery.md +11 -3
- package/src/orchestrator/templates/ai-src/agents/reviewer.md +8 -0
- package/src/orchestrator/templates/ai-src/commands/create-test.md +2 -2
- package/src/orchestrator/templates/ai-src/commands/review.md +2 -2
- package/src/orchestrator/templates/ai-src/commands/run-test.md +70 -13
- package/src/orchestrator/templates/ai-src/skills/sungen-capture/mode-local.md +2 -2
- package/src/orchestrator/templates/ai-src/skills/sungen-delivery/SKILL.md +14 -0
- package/src/orchestrator/templates/ai-src/skills/sungen-error-mapping/SKILL.md +23 -1
- package/src/orchestrator/templates/ai-src/skills/sungen-gherkin-syntax/SKILL.md +26 -8
- package/src/orchestrator/templates/ai-src/skills/sungen-selector-fix/SKILL.md +58 -14
- package/src/orchestrator/templates/ai-src/skills/sungen-selector-keys/SKILL.md +13 -1
- package/src/orchestrator/templates/ai-src/skills/sungen-tc-generation/SKILL.md +41 -1
- package/src/orchestrator/templates/ai-src/skills/sungen-tc-review/SKILL.md +7 -0
- package/src/orchestrator/templates/playwright.config.ts +4 -2
- package/src/orchestrator/templates/specs-locale-fixture.ts +21 -9
- package/src/orchestrator/templates/specs-pw-shape-reporter.ts +0 -0
- package/src/orchestrator/templates/specs-url-assert.ts +47 -4
- package/src/orchestrator/templates/wdio.conf.ts +24 -1
- package/src/orchestrator/trace-mode-install.ts +94 -0
- package/src/orchestrator/viewpoint-pattern-catalog.ts +58 -0
|
@@ -193,6 +193,7 @@ export class PatternRegistry {
|
|
|
193
193
|
comment: resolved.comment,
|
|
194
194
|
pattern: pattern.name,
|
|
195
195
|
templateData: resolved.data,
|
|
196
|
+
parentLocator,
|
|
196
197
|
};
|
|
197
198
|
}
|
|
198
199
|
|
|
@@ -202,7 +203,7 @@ export class PatternRegistry {
|
|
|
202
203
|
if (generatorStateMiss) return generatorStateMiss;
|
|
203
204
|
// A generator returning nothing still falls through to the no-pattern path.
|
|
204
205
|
const generated = pattern.generator(step, scoped);
|
|
205
|
-
return generated ? { ...generated, pattern: pattern.name } : null;
|
|
206
|
+
return generated ? { ...generated, pattern: pattern.name, parentLocator } : null;
|
|
206
207
|
}
|
|
207
208
|
|
|
208
209
|
return null;
|
|
@@ -447,17 +448,23 @@ export class PatternRegistry {
|
|
|
447
448
|
|
|
448
449
|
/**
|
|
449
450
|
* Resolve a `{{var}}` written where literal text is expected, leaving anything else untouched.
|
|
450
|
-
*
|
|
451
|
-
*
|
|
451
|
+
*
|
|
452
|
+
* An unresolvable ref is NOT kept as written. That was the last of the #781 swallows, and the
|
|
453
|
+
* hardest to see, because the old rationale — "the locator is then wrong in a way the author can
|
|
454
|
+
* read, which beats losing the whole step" — is true of a locator NAME and false here. The second
|
|
455
|
+
* `with` in `see [Tag] header with {{label}} in [Job Card] card with {{job_title}}` binds to the
|
|
456
|
+
* PARENT scope, so the value lands in `.filter({ hasText: '{{job_title}}' })`: a scope that can
|
|
457
|
+
* never match, compiled with ZERO diagnostics and `generate` exiting 0. The author then reads a
|
|
458
|
+
* "element not found" timeout that says nothing about the missing test-data key.
|
|
459
|
+
*
|
|
460
|
+
* Letting it throw routes it to StepMapper.mapStep like every other ref, so the step names the
|
|
461
|
+
* ref and the file it wanted. Only a string that IS exactly `{{ref}}` is ever resolved here;
|
|
462
|
+
* anything else is returned untouched, so ordinary literal text is unaffected.
|
|
452
463
|
*/
|
|
453
464
|
private static resolveInlineData(text: string, context: PatternContext): string {
|
|
454
465
|
const match = text.match(/^\{\{([a-z0-9\-._]+)\}\}$/i);
|
|
455
466
|
if (!match) return text;
|
|
456
|
-
|
|
457
|
-
return context.dataResolver.resolveData(match[1], context.featureName);
|
|
458
|
-
} catch {
|
|
459
|
-
return text;
|
|
460
|
-
}
|
|
467
|
+
return context.dataResolver.resolveData(match[1], context.featureName);
|
|
461
468
|
}
|
|
462
469
|
|
|
463
470
|
/**
|
|
@@ -96,6 +96,21 @@ export interface PatternContext {
|
|
|
96
96
|
adapterName?: string;
|
|
97
97
|
/** Compile-diagnostics channel, so the pattern layer can report instead of throwing. */
|
|
98
98
|
diagnostics?: DiagnosticsSink;
|
|
99
|
+
/**
|
|
100
|
+
* The container locator the step's `in [Parent] <type>` clause resolved to, already rendered —
|
|
101
|
+
* set by `withParentScope`, absent when the step carries no scope clause.
|
|
102
|
+
*
|
|
103
|
+
* `withParentScope` also stamps this onto everything the pattern RESOLVES, which is the seam that
|
|
104
|
+
* serves the ordinary case. It is not enough on its own: a pattern whose locator is not built from
|
|
105
|
+
* a selectors.yaml entry never has a `resolved` object to carry it. `see [学科] label with {{v}}`
|
|
106
|
+
* is exactly that — the ref names on-screen CAPTION text, so the common case has no entry at all,
|
|
107
|
+
* `resolveSelector` throws, and the branch renders from `{}`. The scope was then dropped with no
|
|
108
|
+
* diagnostic (#747), which is the silence #667 set out to end.
|
|
109
|
+
*
|
|
110
|
+
* Read it ONLY where the template's locator is built inline rather than from `resolved`; every
|
|
111
|
+
* other pattern gets the scope through `resolved` and must not apply it twice.
|
|
112
|
+
*/
|
|
113
|
+
parentLocator?: string;
|
|
99
114
|
/** App profile (qa/app.yaml merged over presets/defaults) — widget variants, recipes,
|
|
100
115
|
* loading indicator, table row conventions. Typed loosely to keep the SPI decoupled;
|
|
101
116
|
* the concrete shape is ResolvedAppProfile. */
|
|
@@ -14,6 +14,11 @@ import { PatternContext } from './types';
|
|
|
14
14
|
* Only the target's own scope is stamped; anything a pattern resolves that ALREADY carries a
|
|
15
15
|
* `parentLocator` is left alone, so a pattern that builds its own container chain (table rows) keeps
|
|
16
16
|
* winning over the generic one.
|
|
17
|
+
*
|
|
18
|
+
* The scope also rides on the CONTEXT itself, not only on what the pattern resolves. A pattern whose
|
|
19
|
+
* locator is built inline — `see [X] label with {{v}}` matches on-screen caption text and usually
|
|
20
|
+
* has no selectors.yaml entry at all, so `resolveSelector` throws and the branch renders from `{}` —
|
|
21
|
+
* has no `resolved` object for the stamp to land on, and lost the scope silently (#747).
|
|
17
22
|
*/
|
|
18
23
|
export function withParentScope(context: PatternContext, parentLocator: string): PatternContext {
|
|
19
24
|
const scope = <T>(resolved: T): T =>
|
|
@@ -35,6 +40,7 @@ export function withParentScope(context: PatternContext, parentLocator: string):
|
|
|
35
40
|
|
|
36
41
|
return {
|
|
37
42
|
...context,
|
|
43
|
+
parentLocator,
|
|
38
44
|
selectorResolver,
|
|
39
45
|
renderLocator: (resolved: any) => context.renderLocator(scope(resolved)),
|
|
40
46
|
};
|
|
@@ -4,7 +4,7 @@ import { TemplateEngine } from './template-engine';
|
|
|
4
4
|
import { adapterRegistry } from './adapters';
|
|
5
5
|
import { PatternRegistry, PatternContext, Platform } from './patterns';
|
|
6
6
|
import { SelectorResolver, type ResolvedSelector } from './utils/selector-resolver';
|
|
7
|
-
import { DataResolver } from './utils/data-resolver';
|
|
7
|
+
import { DataResolver, DataRefError } from './utils/data-resolver';
|
|
8
8
|
import { locatorIdentityKey } from './utils/dialog-scope-identity';
|
|
9
9
|
import { DiagnosticsCollector } from './diagnostics';
|
|
10
10
|
import { unsupportedStepCode } from './patterns/unsupported-step-code';
|
|
@@ -44,6 +44,9 @@ export interface MappedStep {
|
|
|
44
44
|
imports?: string[]; // Required imports
|
|
45
45
|
pattern?: string; // Name of the step form that produced the code (post-map guards read it)
|
|
46
46
|
templateData?: Record<string, any>; // What the resolver handed the template (e.g. a recorded refusal)
|
|
47
|
+
/** The container locator the step's `in [Parent] <type>` clause resolved to, when it carried one.
|
|
48
|
+
* Recorded so a post-map guard can check the scope actually reached the code (SG-W028, #747). */
|
|
49
|
+
parentLocator?: string;
|
|
47
50
|
}
|
|
48
51
|
|
|
49
52
|
/**
|
|
@@ -226,7 +229,45 @@ export class StepMapper {
|
|
|
226
229
|
* Map a Gherkin step to Playwright code
|
|
227
230
|
* Uses pattern registry first, falls back to AI if enabled
|
|
228
231
|
*/
|
|
232
|
+
/**
|
|
233
|
+
* SG-E038 — the ONE place an unresolvable `{{var}}` is answered.
|
|
234
|
+
*
|
|
235
|
+
* Twenty-four step patterns used to catch the resolver's failure each in their own way and
|
|
236
|
+
* substitute the placeholder TEXT as the value, so `fill [ID] with {{valid_partner_id}}` shipped
|
|
237
|
+
* `fill('${valid_partner_id}')` — 20 literal characters typed into the app, `generate` exiting 0,
|
|
238
|
+
* and a scenario that failed exactly where it was written to fail, for the reason it was written
|
|
239
|
+
* to fail. Nothing told the run apart from a correct one (#781).
|
|
240
|
+
*
|
|
241
|
+
* The step now compiles to a throw naming the ref and the file, which is the house answer to
|
|
242
|
+
* "the compiler would otherwise invent something" (SG-E023/E024/E026 all work this way). A throw
|
|
243
|
+
* is preferred over letting the error kill the feature file, because one run then reports EVERY
|
|
244
|
+
* unresolved ref instead of the first; `--strict` turns the diagnostic into exit 1.
|
|
245
|
+
*/
|
|
229
246
|
mapStep(step: ParsedStep): MappedStep | Promise<MappedStep> {
|
|
247
|
+
try {
|
|
248
|
+
return this.mapStepResolving(step);
|
|
249
|
+
} catch (err) {
|
|
250
|
+
if (err instanceof DataRefError) return this.unresolvedDataRef(step, err);
|
|
251
|
+
throw err;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
private unresolvedDataRef(step: ParsedStep, err: DataRefError): MappedStep {
|
|
256
|
+
const fix = err.file
|
|
257
|
+
? `add a "${err.dataRef}" key to ${err.file}`
|
|
258
|
+
: `define "${err.dataRef}" in the feature's test-data file`;
|
|
259
|
+
const reason =
|
|
260
|
+
`step "${step.text}": {{${err.dataRef}}} does not resolve — ${err.message}. `
|
|
261
|
+
+ `${fix}, or reference a key that exists. The step compiles to this throw rather than `
|
|
262
|
+
+ `typing the literal text "\${${err.dataRef}}" into the app as if it were data.`;
|
|
263
|
+
this.diagnostics?.add('SG-E038', reason, { feature: this.featureName, step: step.text });
|
|
264
|
+
return {
|
|
265
|
+
code: unsupportedStepCode(reason),
|
|
266
|
+
comment: `Unresolved {{${err.dataRef}}} — see SG-E038: ${step.text}`,
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
private mapStepResolving(step: ParsedStep): MappedStep | Promise<MappedStep> {
|
|
230
271
|
this.stepCounter++;
|
|
231
272
|
|
|
232
273
|
// Track effective keyword: And/But inherit from previous Given/When/Then
|
|
@@ -377,12 +418,7 @@ export class StepMapper {
|
|
|
377
418
|
// Case 3: [panel] dialog with {{value}}
|
|
378
419
|
// Use dataRef as filter text — the dialog name is dynamic (from test-data),
|
|
379
420
|
// so use .filter({ hasText }) instead of { name } for reliable matching
|
|
380
|
-
|
|
381
|
-
try {
|
|
382
|
-
filterText = this.dataResolver.resolveData(step.dataRef, this.featureName);
|
|
383
|
-
} catch {
|
|
384
|
-
filterText = `\${${step.dataRef}}`;
|
|
385
|
-
}
|
|
421
|
+
const filterText = this.dataResolver.resolveData(step.dataRef, this.featureName);
|
|
386
422
|
contextVars.dialogFilterText = filterText;
|
|
387
423
|
// The declared entry still owns the ROOT the filter applies to — but only when it
|
|
388
424
|
// is a non-role strategy (locator/testid/css). A role entry keeps the bare
|
|
@@ -474,6 +510,10 @@ export class StepMapper {
|
|
|
474
510
|
if (rowFilterDropped) return rowFilterDropped;
|
|
475
511
|
const badType = this.checkUnknownSelectorType(step, mappedStep);
|
|
476
512
|
if (badType) return badType;
|
|
513
|
+
// LAST of the guards, and deliberately so: every check above can REPLACE the step with a
|
|
514
|
+
// refusal, and reporting a dropped scope against code that is about to be discarded is the
|
|
515
|
+
// "two contradictory messages about one step" this guard's own doc rules out.
|
|
516
|
+
this.checkParentScopeDropped(step, mappedStep);
|
|
477
517
|
return mappedStep;
|
|
478
518
|
}
|
|
479
519
|
|
|
@@ -745,6 +785,49 @@ export class StepMapper {
|
|
|
745
785
|
return null;
|
|
746
786
|
}
|
|
747
787
|
|
|
788
|
+
/**
|
|
789
|
+
* The container scope parsed, resolved — and then never reached the emitted code.
|
|
790
|
+
*
|
|
791
|
+
* #667 closed the parse-time half of this: an `in [X] <word>` whose `<word>` is not a container
|
|
792
|
+
* type is reported (SG-W028) rather than truncated. It could not close the render-time half,
|
|
793
|
+
* because honouring the scope is per-template work: the registry stamps `parentLocator` on what a
|
|
794
|
+
* RESOLVER hands back and `withParentScope` stamps it on what any pattern RESOLVES, but a branch
|
|
795
|
+
* that builds its locator inline and renders from hand-picked fields receives neither. Three did,
|
|
796
|
+
* and `see [学科] label with {{v}} in [Education Card 6] card` compiled to a page-wide
|
|
797
|
+
* `getByText` with no diagnostic at all (#747) — a green test reading a card the sentence never
|
|
798
|
+
* names, findable only by diffing the generated spec against the Gherkin.
|
|
799
|
+
*
|
|
800
|
+
* So the fact is taken from the OUTPUT, exactly as SG-W032 takes the row filter from `.filter(`:
|
|
801
|
+
* every path that honours a container scope emits the resolved container locator verbatim, so its
|
|
802
|
+
* absence from the code IS the drop. That makes the guard total — it covers every template that
|
|
803
|
+
* exists now and every one added later, without a list to keep in sync.
|
|
804
|
+
*
|
|
805
|
+
* A step already refused elsewhere is excluded: it compiles to a `throw`, and a second opinion on
|
|
806
|
+
* top of a refusal is two contradictory messages about one step (SG-W032's reasoning, unchanged).
|
|
807
|
+
* The `throw` test covers a refusal the PATTERN layer recorded; a refusal one of the guards above
|
|
808
|
+
* substitutes is covered by call order instead — this one runs last.
|
|
809
|
+
*
|
|
810
|
+
* Returns `void`, not `MappedStep | null` like its siblings: it only ever REPORTS. Typed that way
|
|
811
|
+
* on purpose, so a future edit copying the sibling shape cannot assume a replacement step is being
|
|
812
|
+
* consumed when nothing is looking at one.
|
|
813
|
+
*/
|
|
814
|
+
private checkParentScopeDropped(step: ParsedStep, mapped: MappedStep): void {
|
|
815
|
+
const parent = mapped.parentLocator;
|
|
816
|
+
if (!parent) return;
|
|
817
|
+
const code = mapped.code || '';
|
|
818
|
+
if (code.startsWith('throw new Error(')) return;
|
|
819
|
+
if (code.includes(parent)) return;
|
|
820
|
+
|
|
821
|
+
this.diagnostics?.add('SG-W028',
|
|
822
|
+
`step "${step.text}" names the container [${step.parentRef}] but the generated code does not `
|
|
823
|
+
+ `scope to it — the step runs against the WHOLE page, so it fails where the target repeats and `
|
|
824
|
+
+ `passes on a DIFFERENT [${step.parentRef}] where it does not. The "${mapped.pattern}" step `
|
|
825
|
+
+ `form does not carry a container scope. Assert on an element the container owns (give it a `
|
|
826
|
+
+ `selectors.yaml entry and use "has text"/"contains"), or drop the clause so the sentence `
|
|
827
|
+
+ `matches what is actually checked.`,
|
|
828
|
+
{ feature: this.featureName, step: step.text });
|
|
829
|
+
}
|
|
830
|
+
|
|
748
831
|
private checkAssertionClauseSwallowed(step: ParsedStep, mapped: MappedStep): MappedStep | null {
|
|
749
832
|
const code = mapped.code || '';
|
|
750
833
|
// Bare visibility: nothing but a visible/displayed assertion on one locator.
|
|
@@ -831,7 +914,6 @@ export class StepMapper {
|
|
|
831
914
|
// delimiters, so the code may carry `__SUNGEN_TD\$key\$__` instead of the plain form.
|
|
832
915
|
const marker = DataResolver.encodeMarker(step.dataRef);
|
|
833
916
|
if (code.includes(marker) || code.includes(marker.replace(/\$/g, '\\$'))) return;
|
|
834
|
-
if (code.includes(`\${${step.dataRef}}`)) return; // unresolved fallback
|
|
835
917
|
if (code.includes(step.dataRef)) return; // testData.set('ref'), comments
|
|
836
918
|
try {
|
|
837
919
|
const value = this.dataResolver.resolveData(step.dataRef, this.featureName);
|
|
@@ -1,6 +1,33 @@
|
|
|
1
1
|
import * as path from 'path';
|
|
2
2
|
import { readYamlIfExists } from '../../../utils/yaml-io';
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* A `{{var}}` the compiler could not resolve: missing data file, missing key, or a key holding
|
|
6
|
+
* something that is not a primitive.
|
|
7
|
+
*
|
|
8
|
+
* A TYPE rather than a message convention, because the one thing callers must never do with this
|
|
9
|
+
* failure is guess. Twenty-four step patterns used to catch it and substitute the placeholder text
|
|
10
|
+
* as the VALUE — `fill('${valid_partner_id}')` typed 20 literal characters into the app, `generate`
|
|
11
|
+
* exited 0, and the scenario failed at the assertion it was written to fail at, for the reason it
|
|
12
|
+
* was written to fail. Nothing distinguished that run from a correct one (#781).
|
|
13
|
+
*
|
|
14
|
+
* So the failure is now carried, not converted, and it is answered in exactly one place —
|
|
15
|
+
* `StepMapper.mapStep`, which turns it into SG-E038 plus a step that throws by name. Catching this
|
|
16
|
+
* anywhere else to produce a value is the defect, and the type is what makes that visible in review.
|
|
17
|
+
*/
|
|
18
|
+
export class DataRefError extends Error {
|
|
19
|
+
constructor(
|
|
20
|
+
message: string,
|
|
21
|
+
/** The `{{ref}}` as written in the feature, e.g. `valid_partner_id` or `user.email`. */
|
|
22
|
+
readonly dataRef: string,
|
|
23
|
+
/** The test-data file consulted, relative to the project root. Absent when no file was reached. */
|
|
24
|
+
readonly file?: string,
|
|
25
|
+
) {
|
|
26
|
+
super(message);
|
|
27
|
+
this.name = 'DataRefError';
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
4
31
|
/**
|
|
5
32
|
* DataResolver - Resolves data references to actual values
|
|
6
33
|
*
|
|
@@ -106,16 +133,17 @@ export class DataResolver {
|
|
|
106
133
|
|
|
107
134
|
private resolveValue(dataRef: string, featureName?: string): string {
|
|
108
135
|
const { fileName, valuePath } = this.parseDataRef(dataRef, featureName);
|
|
109
|
-
const data = this.loadDataFile(fileName);
|
|
136
|
+
const data = this.loadDataFile(fileName, dataRef);
|
|
137
|
+
const rel = this.screenName
|
|
138
|
+
? `qa/${this.flowMode ? 'flows' : 'screens'}/${this.screenName}/test-data/${fileName}.yaml`
|
|
139
|
+
: undefined;
|
|
110
140
|
|
|
111
141
|
let current = data;
|
|
112
142
|
for (const key of valuePath) {
|
|
113
143
|
if (current && typeof current === 'object' && key in current) {
|
|
114
144
|
current = current[key];
|
|
115
145
|
} else {
|
|
116
|
-
throw new
|
|
117
|
-
`Data path not found: ${dataRef}. Failed at key: ${key}`
|
|
118
|
-
);
|
|
146
|
+
throw new DataRefError(`Data path not found: ${dataRef}. Failed at key: ${key}`, dataRef, rel);
|
|
119
147
|
}
|
|
120
148
|
}
|
|
121
149
|
|
|
@@ -124,8 +152,10 @@ export class DataResolver {
|
|
|
124
152
|
} else if (typeof current === 'number' || typeof current === 'boolean') {
|
|
125
153
|
return String(current);
|
|
126
154
|
} else {
|
|
127
|
-
throw new
|
|
128
|
-
`Data reference ${dataRef} must resolve to a primitive value, got: ${typeof current}
|
|
155
|
+
throw new DataRefError(
|
|
156
|
+
`Data reference ${dataRef} must resolve to a primitive value, got: ${typeof current}`,
|
|
157
|
+
dataRef,
|
|
158
|
+
rel,
|
|
129
159
|
);
|
|
130
160
|
}
|
|
131
161
|
}
|
|
@@ -147,7 +177,7 @@ export class DataResolver {
|
|
|
147
177
|
}
|
|
148
178
|
|
|
149
179
|
if (parts.length < 2) {
|
|
150
|
-
throw new
|
|
180
|
+
throw new DataRefError(`Invalid data reference: ${dataRef}. Expected format: file.path.to.value or provide featureName`, dataRef);
|
|
151
181
|
}
|
|
152
182
|
return { fileName: parts[0], valuePath: parts.slice(1) };
|
|
153
183
|
}
|
|
@@ -168,24 +198,23 @@ export class DataResolver {
|
|
|
168
198
|
* Load data file from disk (with caching)
|
|
169
199
|
* Merges base + env-specific: {name}.yaml + {name}.{SUNGEN_ENV}.yaml
|
|
170
200
|
*/
|
|
171
|
-
private loadDataFile(fileName: string): any {
|
|
201
|
+
private loadDataFile(fileName: string, dataRef: string): any {
|
|
172
202
|
if (this.dataCache.has(fileName)) {
|
|
173
203
|
return this.dataCache.get(fileName)!;
|
|
174
204
|
}
|
|
175
205
|
|
|
176
206
|
if (!this.screenName) {
|
|
177
|
-
throw new
|
|
207
|
+
throw new DataRefError(`Data resolution requires screen/flow context for "${fileName}"`, dataRef);
|
|
178
208
|
}
|
|
179
209
|
|
|
180
210
|
const subDir = this.flowMode ? 'flows' : 'screens';
|
|
181
211
|
const baseDir = path.join(process.cwd(), 'qa', subDir, this.screenName, 'test-data');
|
|
182
212
|
const basePath = path.join(baseDir, `${fileName}.yaml`);
|
|
213
|
+
const rel = `qa/${subDir}/${this.screenName}/test-data/${fileName}.yaml`;
|
|
183
214
|
const data = readYamlIfExists(basePath);
|
|
184
215
|
|
|
185
216
|
if (!data || typeof data !== 'object' || Object.keys(data).length === 0) {
|
|
186
|
-
throw new
|
|
187
|
-
`Data file not found or empty: qa/${subDir}/${this.screenName}/test-data/${fileName}.yaml`
|
|
188
|
-
);
|
|
217
|
+
throw new DataRefError(`Data file not found or empty: ${rel}`, dataRef, rel);
|
|
189
218
|
}
|
|
190
219
|
|
|
191
220
|
let merged = { ...data };
|
|
@@ -36,6 +36,7 @@ export const CONSUMED_ENTRY_FIELDS: ReadonlySet<string> = new Set([
|
|
|
36
36
|
'scope', // dialog/landmark scoping in the locator partial
|
|
37
37
|
'match', // collapses into `exact` for getByText
|
|
38
38
|
'anchor', // page assertions — the rendered-content proof (#662)
|
|
39
|
+
'query', // page assertions — `any` drops the bare-page no-query rule (#748)
|
|
39
40
|
'android', // appium adapter → androidSelector (#392)
|
|
40
41
|
'ios', // appium adapter → iosSelector (#392)
|
|
41
42
|
'variant', // widget recipes / native select / upload subtype
|