@sun-asterisk/sungen 1.0.19 → 1.0.21
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/README.md +3 -3
- package/dist/cli/commands/add.d.ts +3 -0
- package/dist/cli/commands/add.d.ts.map +1 -0
- package/dist/cli/commands/add.js +27 -0
- package/dist/cli/commands/add.js.map +1 -0
- package/dist/cli/commands/cache-clear.d.ts +3 -0
- package/dist/cli/commands/cache-clear.d.ts.map +1 -0
- package/dist/cli/commands/cache-clear.js +24 -0
- package/dist/cli/commands/cache-clear.js.map +1 -0
- package/dist/cli/commands/full.d.ts +3 -0
- package/dist/cli/commands/full.d.ts.map +1 -0
- package/dist/cli/commands/full.js +37 -0
- package/dist/cli/commands/full.js.map +1 -0
- package/dist/cli/commands/generate.d.ts +3 -0
- package/dist/cli/commands/generate.d.ts.map +1 -0
- package/dist/cli/commands/generate.js +53 -0
- package/dist/cli/commands/generate.js.map +1 -0
- package/dist/cli/commands/init.d.ts +3 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +20 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/live-scan.d.ts +3 -0
- package/dist/cli/commands/live-scan.d.ts.map +1 -0
- package/dist/cli/commands/{live-scan-command.js → live-scan.js} +22 -16
- package/dist/cli/commands/live-scan.js.map +1 -0
- package/dist/cli/commands/makeauth.d.ts +3 -0
- package/dist/cli/commands/makeauth.d.ts.map +1 -0
- package/dist/cli/commands/makeauth.js +76 -0
- package/dist/cli/commands/makeauth.js.map +1 -0
- package/dist/cli/commands/map.d.ts +3 -0
- package/dist/cli/commands/map.d.ts.map +1 -0
- package/dist/cli/commands/map.js +93 -0
- package/dist/cli/commands/map.js.map +1 -0
- package/dist/cli/commands/validate.d.ts +3 -0
- package/dist/cli/commands/validate.d.ts.map +1 -0
- package/dist/cli/commands/validate.js +43 -0
- package/dist/cli/commands/validate.js.map +1 -0
- package/dist/cli/index.js +29 -442
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/types.d.ts +9 -0
- package/dist/cli/types.d.ts.map +1 -0
- package/dist/cli/types.js +7 -0
- package/dist/cli/types.js.map +1 -0
- package/dist/cli/utils.d.ts +6 -0
- package/dist/cli/utils.d.ts.map +1 -0
- package/dist/cli/utils.js +101 -0
- package/dist/cli/utils.js.map +1 -0
- package/dist/core/live-scanner/matrix-reader.d.ts.map +1 -1
- package/dist/core/live-scanner/matrix-reader.js +2 -40
- package/dist/core/live-scanner/matrix-reader.js.map +1 -1
- package/dist/core/live-scanner/scanner.d.ts.map +1 -1
- package/dist/core/live-scanner/scanner.js +22 -4
- package/dist/core/live-scanner/scanner.js.map +1 -1
- package/dist/core/live-scanner/step-replayer.d.ts +1 -1
- package/dist/core/live-scanner/step-replayer.d.ts.map +1 -1
- package/dist/core/live-scanner/step-replayer.js +107 -6
- package/dist/core/live-scanner/step-replayer.js.map +1 -1
- package/dist/core/live-scanner/types.d.ts +1 -0
- package/dist/core/live-scanner/types.d.ts.map +1 -1
- package/dist/core/validator/selector-validator.d.ts.map +1 -1
- package/dist/core/validator/selector-validator.js +2 -1
- package/dist/core/validator/selector-validator.js.map +1 -1
- package/dist/generators/scaffold-generator/index.d.ts +2 -1
- package/dist/generators/scaffold-generator/index.d.ts.map +1 -1
- package/dist/generators/scaffold-generator/index.js +21 -1
- package/dist/generators/scaffold-generator/index.js.map +1 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/click-select-action.hbs +2 -0
- package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/wait-for-role-with-data.hbs +1 -0
- package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/wait-for-role.hbs +1 -0
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/checked-assertion.hbs +2 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/column-cell-assertion.hbs +3 -0
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/contain-text-assertion.hbs +2 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/count-assertion.hbs +2 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/disabled-assertion.hbs +2 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/disabled-with-filter-assertion.hbs +2 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/disabled-with-role-variable-assertion.hbs +4 -3
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/disabled-with-variable-assertion.hbs +2 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/empty-assertion.hbs +2 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/enabled-assertion.hbs +2 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/focused-assertion.hbs +2 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/have-text-assertion.hbs +2 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/hidden-dialog-heading-assertion.hbs +2 -0
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/hidden-with-filter-assertion.hbs +2 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/hidden-with-role-variable-assertion.hbs +4 -3
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/hidden-with-variable-assertion.hbs +2 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/is-hidden-assertion.hbs +1 -0
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/list-item-count-assertion.hbs +2 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/not-checked-assertion.hbs +2 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/page-assertion.hbs +1 -0
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-assertion.hbs +2 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-dialog-heading-assertion.hbs +2 -0
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-with-locator-variable-assertion.hbs +2 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-with-role-variable-assertion.hbs +4 -3
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-with-value-assertion.hbs +2 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-with-variable-assertion.hbs +1 -0
- package/dist/generators/test-generator/adapters/playwright/templates/steps/navigation/navigation.hbs +1 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/navigation/wait-for-element-with-text.hbs +1 -1
- package/dist/generators/test-generator/patterns/assertion-patterns.d.ts.map +1 -1
- package/dist/generators/test-generator/patterns/assertion-patterns.js +95 -58
- package/dist/generators/test-generator/patterns/assertion-patterns.js.map +1 -1
- package/dist/generators/test-generator/patterns/form-patterns.d.ts +0 -2
- package/dist/generators/test-generator/patterns/form-patterns.d.ts.map +1 -1
- package/dist/generators/test-generator/patterns/form-patterns.js +34 -47
- package/dist/generators/test-generator/patterns/form-patterns.js.map +1 -1
- package/dist/generators/test-generator/patterns/index.d.ts +3 -1
- package/dist/generators/test-generator/patterns/index.d.ts.map +1 -1
- package/dist/generators/test-generator/patterns/index.js +20 -3
- package/dist/generators/test-generator/patterns/index.js.map +1 -1
- package/dist/generators/test-generator/patterns/interaction-patterns.d.ts +0 -1
- package/dist/generators/test-generator/patterns/interaction-patterns.d.ts.map +1 -1
- package/dist/generators/test-generator/patterns/interaction-patterns.js +44 -85
- package/dist/generators/test-generator/patterns/interaction-patterns.js.map +1 -1
- package/dist/generators/test-generator/patterns/legacy-patterns.d.ts +7 -0
- package/dist/generators/test-generator/patterns/legacy-patterns.d.ts.map +1 -0
- package/dist/generators/test-generator/patterns/legacy-patterns.js +98 -0
- package/dist/generators/test-generator/patterns/legacy-patterns.js.map +1 -0
- package/dist/generators/test-generator/patterns/navigation-patterns.d.ts +0 -2
- package/dist/generators/test-generator/patterns/navigation-patterns.d.ts.map +1 -1
- package/dist/generators/test-generator/patterns/navigation-patterns.js +14 -42
- package/dist/generators/test-generator/patterns/navigation-patterns.js.map +1 -1
- package/dist/generators/test-generator/patterns/setup-patterns.d.ts +0 -1
- package/dist/generators/test-generator/patterns/setup-patterns.d.ts.map +1 -1
- package/dist/generators/test-generator/patterns/setup-patterns.js +23 -35
- package/dist/generators/test-generator/patterns/setup-patterns.js.map +1 -1
- package/dist/generators/test-generator/patterns/types.d.ts +18 -3
- package/dist/generators/test-generator/patterns/types.d.ts.map +1 -1
- package/dist/generators/test-generator/step-mapper.d.ts +0 -15
- package/dist/generators/test-generator/step-mapper.d.ts.map +1 -1
- package/dist/generators/test-generator/step-mapper.js +4 -106
- package/dist/generators/test-generator/step-mapper.js.map +1 -1
- package/dist/{executor/test-generator.d.ts → generators/test-generator/types.d.ts} +4 -25
- package/dist/generators/test-generator/types.d.ts.map +1 -0
- package/dist/generators/test-generator/types.js +106 -0
- package/dist/generators/test-generator/types.js.map +1 -0
- package/dist/generators/test-generator/utils/data-resolver.d.ts.map +1 -1
- package/dist/generators/test-generator/utils/data-resolver.js +8 -17
- package/dist/generators/test-generator/utils/data-resolver.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 +10 -18
- package/dist/generators/test-generator/utils/selector-resolver.js.map +1 -1
- package/dist/orchestrator/cache-manager.d.ts +1 -23
- package/dist/orchestrator/cache-manager.d.ts.map +1 -1
- package/dist/orchestrator/cache-manager.js +1 -87
- package/dist/orchestrator/cache-manager.js.map +1 -1
- package/dist/orchestrator/pipeline.d.ts +11 -28
- package/dist/orchestrator/pipeline.d.ts.map +1 -1
- package/dist/orchestrator/pipeline.js +52 -371
- package/dist/orchestrator/pipeline.js.map +1 -1
- package/dist/orchestrator/reporter.d.ts +1 -1
- package/dist/orchestrator/reporter.d.ts.map +1 -1
- package/dist/orchestrator/screen-manager.js +1 -1
- package/dist/orchestrator/screen-manager.js.map +1 -1
- package/dist/utils/feature-finder.d.ts +9 -0
- package/dist/utils/feature-finder.d.ts.map +1 -0
- package/dist/utils/feature-finder.js +67 -0
- package/dist/utils/feature-finder.js.map +1 -0
- package/dist/utils/screen-paths.d.ts +10 -0
- package/dist/utils/screen-paths.d.ts.map +1 -0
- package/dist/utils/screen-paths.js +73 -0
- package/dist/utils/screen-paths.js.map +1 -0
- package/dist/utils/selector-loader.d.ts +6 -0
- package/dist/utils/selector-loader.d.ts.map +1 -0
- package/dist/utils/selector-loader.js +20 -0
- package/dist/utils/selector-loader.js.map +1 -0
- package/dist/utils/selector-types.d.ts +7 -0
- package/dist/utils/selector-types.d.ts.map +1 -0
- package/dist/utils/selector-types.js +19 -0
- package/dist/utils/selector-types.js.map +1 -0
- package/dist/utils/test-data-loader.d.ts +6 -0
- package/dist/utils/test-data-loader.d.ts.map +1 -0
- package/dist/utils/test-data-loader.js +20 -0
- package/dist/utils/test-data-loader.js.map +1 -0
- package/dist/utils/yaml-io.d.ts +14 -0
- package/dist/utils/yaml-io.d.ts.map +1 -0
- package/dist/utils/yaml-io.js +72 -0
- package/dist/utils/yaml-io.js.map +1 -0
- package/package.json +1 -1
- package/src/cli/commands/add.ts +25 -0
- package/src/cli/commands/cache-clear.ts +22 -0
- package/src/cli/commands/full.ts +35 -0
- package/src/cli/commands/generate.ts +55 -0
- package/src/cli/commands/init.ts +17 -0
- package/src/cli/commands/{live-scan-command.ts → live-scan.ts} +21 -18
- package/src/cli/commands/makeauth.ts +77 -0
- package/src/cli/commands/map.ts +97 -0
- package/src/cli/commands/validate.ts +43 -0
- package/src/cli/index.ts +32 -473
- package/src/cli/types.ts +9 -0
- package/src/cli/utils.ts +106 -0
- package/src/core/live-scanner/matrix-reader.ts +2 -8
- package/src/core/live-scanner/scanner.ts +27 -4
- package/src/core/live-scanner/step-replayer.ts +92 -6
- package/src/core/live-scanner/types.ts +1 -0
- package/src/core/validator/selector-validator.ts +3 -2
- package/src/generators/scaffold-generator/index.ts +23 -2
- package/src/generators/test-generator/adapters/playwright/templates/steps/actions/click-select-action.hbs +2 -0
- package/src/generators/test-generator/adapters/playwright/templates/steps/actions/wait-for-role-with-data.hbs +1 -0
- package/src/generators/test-generator/adapters/playwright/templates/steps/actions/wait-for-role.hbs +1 -0
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/checked-assertion.hbs +2 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/column-cell-assertion.hbs +3 -0
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/contain-text-assertion.hbs +2 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/count-assertion.hbs +2 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/disabled-assertion.hbs +2 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/disabled-with-filter-assertion.hbs +2 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/disabled-with-role-variable-assertion.hbs +4 -3
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/disabled-with-variable-assertion.hbs +2 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/empty-assertion.hbs +2 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/enabled-assertion.hbs +2 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/focused-assertion.hbs +2 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/have-text-assertion.hbs +2 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/hidden-dialog-heading-assertion.hbs +2 -0
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/hidden-with-filter-assertion.hbs +2 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/hidden-with-role-variable-assertion.hbs +4 -3
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/hidden-with-variable-assertion.hbs +2 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/is-hidden-assertion.hbs +1 -0
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/list-item-count-assertion.hbs +2 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/not-checked-assertion.hbs +2 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/page-assertion.hbs +1 -0
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-assertion.hbs +2 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-dialog-heading-assertion.hbs +2 -0
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-with-locator-variable-assertion.hbs +2 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-with-role-variable-assertion.hbs +4 -3
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-with-value-assertion.hbs +2 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-with-variable-assertion.hbs +1 -0
- package/src/generators/test-generator/adapters/playwright/templates/steps/navigation/navigation.hbs +1 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/navigation/wait-for-element-with-text.hbs +1 -1
- package/src/generators/test-generator/patterns/assertion-patterns.ts +102 -62
- package/src/generators/test-generator/patterns/form-patterns.ts +38 -60
- package/src/generators/test-generator/patterns/index.ts +22 -4
- package/src/generators/test-generator/patterns/interaction-patterns.ts +47 -107
- package/src/generators/test-generator/patterns/legacy-patterns.ts +104 -0
- package/src/generators/test-generator/patterns/navigation-patterns.ts +27 -69
- package/src/generators/test-generator/patterns/setup-patterns.ts +23 -41
- package/src/generators/test-generator/patterns/types.ts +26 -9
- package/src/generators/test-generator/step-mapper.ts +4 -124
- package/src/generators/test-generator/types.ts +131 -0
- package/src/generators/test-generator/utils/data-resolver.ts +8 -13
- package/src/generators/test-generator/utils/selector-resolver.ts +15 -17
- package/src/orchestrator/cache-manager.ts +1 -107
- package/src/orchestrator/pipeline.ts +58 -433
- package/src/orchestrator/reporter.ts +1 -1
- package/src/orchestrator/screen-manager.ts +1 -1
- package/src/utils/feature-finder.ts +33 -0
- package/src/utils/screen-paths.ts +37 -0
- package/src/utils/selector-loader.ts +23 -0
- package/src/utils/selector-types.ts +17 -0
- package/src/utils/test-data-loader.ts +23 -0
- package/src/utils/yaml-io.ts +33 -0
- package/dist/cli/commands/auto-tag-command.d.ts +0 -8
- package/dist/cli/commands/auto-tag-command.d.ts.map +0 -1
- package/dist/cli/commands/auto-tag-command.js +0 -104
- package/dist/cli/commands/auto-tag-command.js.map +0 -1
- package/dist/cli/commands/live-scan-command.d.ts +0 -9
- package/dist/cli/commands/live-scan-command.d.ts.map +0 -1
- package/dist/cli/commands/live-scan-command.js.map +0 -1
- package/dist/executor/playwright/playwright-generator.d.ts +0 -33
- package/dist/executor/playwright/playwright-generator.d.ts.map +0 -1
- package/dist/executor/playwright/playwright-generator.js +0 -136
- package/dist/executor/playwright/playwright-generator.js.map +0 -1
- package/dist/executor/test-generator.d.ts.map +0 -1
- package/dist/executor/test-generator.js +0 -30
- package/dist/executor/test-generator.js.map +0 -1
- package/dist/generators/cli.d.ts +0 -7
- package/dist/generators/cli.d.ts.map +0 -1
- package/dist/generators/cli.js +0 -570
- package/dist/generators/cli.js.map +0 -1
- package/dist/input/cli-adapter.d.ts +0 -75
- package/dist/input/cli-adapter.d.ts.map +0 -1
- package/dist/input/cli-adapter.js +0 -218
- package/dist/input/cli-adapter.js.map +0 -1
- package/dist/input/config-adapter.d.ts +0 -25
- package/dist/input/config-adapter.d.ts.map +0 -1
- package/dist/input/config-adapter.js +0 -70
- package/dist/input/config-adapter.js.map +0 -1
- package/dist/input/input-adapter.d.ts +0 -28
- package/dist/input/input-adapter.d.ts.map +0 -1
- package/dist/input/input-adapter.js +0 -17
- package/dist/input/input-adapter.js.map +0 -1
- package/dist/input/vscode-adapter.d.ts +0 -62
- package/dist/input/vscode-adapter.d.ts.map +0 -1
- package/dist/input/vscode-adapter.js +0 -64
- package/dist/input/vscode-adapter.js.map +0 -1
- package/dist/tools/auto-tagger.d.ts +0 -107
- package/dist/tools/auto-tagger.d.ts.map +0 -1
- package/dist/tools/auto-tagger.js +0 -502
- package/dist/tools/auto-tagger.js.map +0 -1
- package/src/cli/commands/auto-tag-command.ts +0 -80
- package/src/executor/playwright/playwright-generator.ts +0 -125
- package/src/executor/test-generator.ts +0 -90
- package/src/generators/cli.ts +0 -640
- package/src/input/cli-adapter.ts +0 -233
- package/src/input/config-adapter.ts +0 -71
- package/src/input/input-adapter.ts +0 -32
- package/src/input/vscode-adapter.ts +0 -90
- package/src/tools/auto-tagger.ts +0 -572
|
@@ -3,7 +3,6 @@ import { StepPattern } from './types';
|
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Setup and precondition patterns: application setup, authentication state, etc.
|
|
6
|
-
* Uses templates for framework-agnostic code generation
|
|
7
6
|
*/
|
|
8
7
|
export const setupPatterns: StepPattern[] = [
|
|
9
8
|
{
|
|
@@ -12,14 +11,11 @@ export const setupPatterns: StepPattern[] = [
|
|
|
12
11
|
step.text.includes('application is running') ||
|
|
13
12
|
step.text.includes('application running') ||
|
|
14
13
|
step.text.includes('app is running'),
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
comment: `Setup: Application is running`,
|
|
21
|
-
};
|
|
22
|
-
},
|
|
14
|
+
resolver: (step, context) => ({
|
|
15
|
+
templateName: 'application-running',
|
|
16
|
+
data: {},
|
|
17
|
+
comment: `Setup: Application is running`,
|
|
18
|
+
}),
|
|
23
19
|
priority: 5,
|
|
24
20
|
},
|
|
25
21
|
{
|
|
@@ -28,14 +24,11 @@ export const setupPatterns: StepPattern[] = [
|
|
|
28
24
|
step.text.includes('user is not logged in') ||
|
|
29
25
|
step.text.includes('not logged in') ||
|
|
30
26
|
step.text.includes('logged out'),
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
comment: `Clear authentication state (ensure user is logged out)`,
|
|
37
|
-
};
|
|
38
|
-
},
|
|
27
|
+
resolver: (step, context) => ({
|
|
28
|
+
templateName: 'clear-auth',
|
|
29
|
+
data: {},
|
|
30
|
+
comment: `Clear authentication state (ensure user is logged out)`,
|
|
31
|
+
}),
|
|
39
32
|
priority: 9,
|
|
40
33
|
},
|
|
41
34
|
{
|
|
@@ -44,16 +37,11 @@ export const setupPatterns: StepPattern[] = [
|
|
|
44
37
|
(step.text.includes('user is logged in') ||
|
|
45
38
|
step.text.includes('logged in as')) &&
|
|
46
39
|
!step.text.includes('not logged in'),
|
|
47
|
-
|
|
48
|
-
// Check if there's a data reference for user credentials
|
|
40
|
+
resolver: (step, context) => {
|
|
49
41
|
const userRef = step.dataRef || 'valid_user';
|
|
50
|
-
|
|
51
|
-
const code = context.templateEngine.renderStep('user-login-todo', {
|
|
52
|
-
userRef,
|
|
53
|
-
});
|
|
54
|
-
|
|
55
42
|
return {
|
|
56
|
-
|
|
43
|
+
templateName: 'user-login-todo',
|
|
44
|
+
data: { userRef },
|
|
57
45
|
comment: `Setup: User logged in as ${userRef}`,
|
|
58
46
|
};
|
|
59
47
|
},
|
|
@@ -65,14 +53,11 @@ export const setupPatterns: StepPattern[] = [
|
|
|
65
53
|
step.text.includes('database is empty') ||
|
|
66
54
|
step.text.includes('database is cleared') ||
|
|
67
55
|
step.text.includes('clear database'),
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
comment: `Setup: Clear/reset database`,
|
|
74
|
-
};
|
|
75
|
-
},
|
|
56
|
+
resolver: (step, context) => ({
|
|
57
|
+
templateName: 'clear-database',
|
|
58
|
+
data: {},
|
|
59
|
+
comment: `Setup: Clear/reset database`,
|
|
60
|
+
}),
|
|
76
61
|
priority: 7,
|
|
77
62
|
},
|
|
78
63
|
{
|
|
@@ -81,14 +66,11 @@ export const setupPatterns: StepPattern[] = [
|
|
|
81
66
|
step.text.includes('clean browser state') ||
|
|
82
67
|
step.text.includes('fresh browser') ||
|
|
83
68
|
step.text.includes('new browser session'),
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
comment: `Clear browser state (cookies, storage)`,
|
|
90
|
-
};
|
|
91
|
-
},
|
|
69
|
+
resolver: (step, context) => ({
|
|
70
|
+
templateName: 'clear-browser-state',
|
|
71
|
+
data: {},
|
|
72
|
+
comment: `Clear browser state (cookies, storage)`,
|
|
73
|
+
}),
|
|
92
74
|
priority: 8,
|
|
93
75
|
},
|
|
94
76
|
];
|
|
@@ -9,12 +9,26 @@ import { DataResolver } from '../utils/data-resolver';
|
|
|
9
9
|
export type PatternMatcher = RegExp | ((step: ParsedStep) => boolean);
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
|
-
* Pattern generator function
|
|
12
|
+
* Pattern generator function (legacy — calls templateEngine directly)
|
|
13
13
|
*/
|
|
14
14
|
export type PatternGenerator = (step: ParsedStep, context: PatternContext) => MappedStep;
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
|
-
*
|
|
17
|
+
* Resolved step template data — framework-agnostic
|
|
18
|
+
*/
|
|
19
|
+
export interface StepTemplateData {
|
|
20
|
+
templateName: string;
|
|
21
|
+
data: Record<string, any>;
|
|
22
|
+
comment?: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Pattern resolver function — returns template name + data, does NOT render
|
|
27
|
+
*/
|
|
28
|
+
export type PatternResolver = (step: ParsedStep, context: PatternContext) => StepTemplateData;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Context passed to pattern generators/resolvers
|
|
18
32
|
*/
|
|
19
33
|
export interface PatternContext {
|
|
20
34
|
stepCounter: number;
|
|
@@ -23,19 +37,22 @@ export interface PatternContext {
|
|
|
23
37
|
selectorResolver: SelectorResolver;
|
|
24
38
|
dataResolver: DataResolver;
|
|
25
39
|
renderLocator: (resolved: any) => string;
|
|
26
|
-
baseURL?: string;
|
|
27
|
-
featureName?: string;
|
|
28
|
-
screenName?: string;
|
|
29
|
-
featurePath?: string;
|
|
30
|
-
scenarioSteps?: ParsedStep[];
|
|
40
|
+
baseURL?: string;
|
|
41
|
+
featureName?: string;
|
|
42
|
+
screenName?: string;
|
|
43
|
+
featurePath?: string;
|
|
44
|
+
scenarioSteps?: ParsedStep[];
|
|
31
45
|
}
|
|
32
46
|
|
|
33
47
|
/**
|
|
34
48
|
* Step pattern definition
|
|
49
|
+
* Supports both `resolver` (preferred) and `generator` (legacy).
|
|
50
|
+
* If both are provided, `resolver` takes precedence.
|
|
35
51
|
*/
|
|
36
52
|
export interface StepPattern {
|
|
37
53
|
name: string;
|
|
38
54
|
matcher: PatternMatcher;
|
|
39
|
-
|
|
40
|
-
|
|
55
|
+
resolver?: PatternResolver;
|
|
56
|
+
generator?: PatternGenerator;
|
|
57
|
+
priority?: number;
|
|
41
58
|
}
|
|
@@ -140,15 +140,6 @@ export class StepMapper {
|
|
|
140
140
|
return mappedStep;
|
|
141
141
|
}
|
|
142
142
|
|
|
143
|
-
// Fallback: Try legacy patterns for backward compatibility
|
|
144
|
-
const legacyStep = this.tryLegacyPatterns(step);
|
|
145
|
-
if (legacyStep) {
|
|
146
|
-
if (this.verbose) {
|
|
147
|
-
console.log(` ✓ Legacy pattern matched: ${step.text.substring(0, 50)}...`);
|
|
148
|
-
}
|
|
149
|
-
return legacyStep;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
143
|
// Fallback to AI if enabled
|
|
153
144
|
if (this.useAI && this.aiMapper) {
|
|
154
145
|
if (this.verbose) {
|
|
@@ -170,7 +161,10 @@ export class StepMapper {
|
|
|
170
161
|
private createPatternContext(): PatternContext {
|
|
171
162
|
return {
|
|
172
163
|
stepCounter: this.stepCounter,
|
|
173
|
-
extractScreenId:
|
|
164
|
+
extractScreenId: (selectorRef: string) => {
|
|
165
|
+
const match = selectorRef.match(/\[([\w-]+)\./);
|
|
166
|
+
return match ? match[1] : 'unknown';
|
|
167
|
+
},
|
|
174
168
|
templateEngine: this.templateEngine,
|
|
175
169
|
selectorResolver: this.selectorResolver,
|
|
176
170
|
dataResolver: this.dataResolver,
|
|
@@ -183,118 +177,4 @@ export class StepMapper {
|
|
|
183
177
|
};
|
|
184
178
|
}
|
|
185
179
|
|
|
186
|
-
/**
|
|
187
|
-
* Extract screen ID from selector reference
|
|
188
|
-
*/
|
|
189
|
-
private extractScreenId(selectorRef: string): string {
|
|
190
|
-
const match = selectorRef.match(/\[([\w-]+)\./);
|
|
191
|
-
return match ? match[1] : 'unknown';
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* Try legacy patterns for backward compatibility
|
|
196
|
-
* These are patterns not yet migrated to the pattern registry
|
|
197
|
-
*/
|
|
198
|
-
private tryLegacyPatterns(step: ParsedStep): MappedStep | null {
|
|
199
|
-
const { text, selectorRef, dataRef, value } = step;
|
|
200
|
-
|
|
201
|
-
// Login pattern
|
|
202
|
-
if (text.includes('user is logged in as') && dataRef) {
|
|
203
|
-
return this.mapLoginStep(dataRef);
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
// Error message assertions
|
|
207
|
-
if (text.includes('error message') && text.includes('should')) {
|
|
208
|
-
return this.mapErrorMessageAssertion();
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
// Generic message assertions
|
|
212
|
-
if (text.includes('message') && text.includes('should be displayed')) {
|
|
213
|
-
return this.mapGenericMessageAssertion(text);
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
// Message with value assertions
|
|
217
|
-
if (text.includes('should see message') && value) {
|
|
218
|
-
return this.mapMessageAssertion(value, selectorRef);
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
// AI response assertions
|
|
222
|
-
if (text.includes('user should see') && text.includes('AI response') && selectorRef) {
|
|
223
|
-
return this.mapAIResponseAssertion(selectorRef);
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
// Message count assertions
|
|
227
|
-
if (text.includes('messages in') && selectorRef) {
|
|
228
|
-
return this.mapMessageCountAssertion(text, selectorRef);
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
// Message contains assertions
|
|
232
|
-
if (text.includes('should contain') && text.includes('messages') && selectorRef) {
|
|
233
|
-
return this.mapMessageCountAssertion(text, selectorRef);
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
return null;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
// ========================================
|
|
240
|
-
// LEGACY METHODS (to be migrated to patterns)
|
|
241
|
-
// ========================================
|
|
242
|
-
|
|
243
|
-
private mapLoginStep(dataRef: string): MappedStep {
|
|
244
|
-
const varName = dataRef.replace(/[^a-zA-Z0-9]/g, '_') + '_' + this.stepCounter;
|
|
245
|
-
return {
|
|
246
|
-
code: this.templateEngine.renderStep('login', { varName, dataRef }),
|
|
247
|
-
comment: `Login as ${dataRef}`,
|
|
248
|
-
};
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
private mapErrorMessageAssertion(): MappedStep {
|
|
252
|
-
return {
|
|
253
|
-
code: this.templateEngine.renderStep('error-message-assertion', {}),
|
|
254
|
-
comment: 'Assert error message is displayed',
|
|
255
|
-
};
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
private mapGenericMessageAssertion(text: string): MappedStep {
|
|
259
|
-
const messageType = text.includes('welcome') ? 'welcome' :
|
|
260
|
-
text.includes('success') ? 'success' : 'message';
|
|
261
|
-
return {
|
|
262
|
-
code: this.templateEngine.renderStep('generic-message-assertion', { messageType }),
|
|
263
|
-
comment: `Assert ${messageType} message is displayed`,
|
|
264
|
-
};
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
private mapMessageAssertion(value: string, selectorRef?: string): MappedStep {
|
|
268
|
-
const varName = (selectorRef || 'message').replace(/[^a-zA-Z0-9]/g, '_') + '_' + this.stepCounter;
|
|
269
|
-
return {
|
|
270
|
-
code: this.templateEngine.renderStep('message-assertion-body', { varName, value, selectorRef }),
|
|
271
|
-
comment: `Assert message: ${value}`,
|
|
272
|
-
};
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
private mapAIResponseAssertion(selectorRef: string): MappedStep {
|
|
276
|
-
const screenId = this.extractScreenId(selectorRef);
|
|
277
|
-
const varName = selectorRef.replace(/[^a-zA-Z0-9]/g, '_') + '_' + this.stepCounter;
|
|
278
|
-
return {
|
|
279
|
-
code: this.templateEngine.renderStep('ai-response-assertion-selector', { varName, selectorRef, screenId }),
|
|
280
|
-
comment: `Assert AI response in ${selectorRef}`,
|
|
281
|
-
};
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
private mapMessageCountAssertion(text: string, selectorRef: string): MappedStep {
|
|
285
|
-
const match = text.match(/(\d+)\s+messages?/);
|
|
286
|
-
const expectedCount = match ? parseInt(match[1]) : 1;
|
|
287
|
-
const screenId = this.extractScreenId(selectorRef);
|
|
288
|
-
const varName = selectorRef.replace(/[^a-zA-Z0-9]/g, '_') + '_' + this.stepCounter;
|
|
289
|
-
|
|
290
|
-
return {
|
|
291
|
-
code: this.templateEngine.renderStep('message-count-assertion', {
|
|
292
|
-
varName,
|
|
293
|
-
selectorRef,
|
|
294
|
-
screenId,
|
|
295
|
-
expectedCount,
|
|
296
|
-
}),
|
|
297
|
-
comment: `Assert ${expectedCount} messages in ${selectorRef}`,
|
|
298
|
-
};
|
|
299
|
-
}
|
|
300
180
|
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test Generator Interface
|
|
3
|
+
* Defines contract for test framework code generators
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { RuntimeConfig } from '../../config/config-schema';
|
|
7
|
+
import { ParsedFeature } from '../../core/selector-base/gherkin-parser';
|
|
8
|
+
import * as path from 'path';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Main Test Generator Interface
|
|
12
|
+
*/
|
|
13
|
+
export interface TestGenerator {
|
|
14
|
+
readonly framework: string;
|
|
15
|
+
|
|
16
|
+
generate(
|
|
17
|
+
feature: ParsedFeature,
|
|
18
|
+
selectors: Record<string, any>,
|
|
19
|
+
testData: Record<string, any>,
|
|
20
|
+
config: RuntimeConfig
|
|
21
|
+
): Promise<GeneratedTest>;
|
|
22
|
+
|
|
23
|
+
getFileExtension(): string;
|
|
24
|
+
|
|
25
|
+
validate(): boolean;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Generated Test Result (executor-level)
|
|
30
|
+
*/
|
|
31
|
+
export interface GeneratedTest {
|
|
32
|
+
feature: string;
|
|
33
|
+
outputPath: string;
|
|
34
|
+
code: string;
|
|
35
|
+
stats: GenerationStats;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Generation Statistics
|
|
40
|
+
*/
|
|
41
|
+
export interface GenerationStats {
|
|
42
|
+
totalScenarios: number;
|
|
43
|
+
totalSteps: number;
|
|
44
|
+
dictionaryMatched: number;
|
|
45
|
+
aiGenerated: number;
|
|
46
|
+
todoCount: number;
|
|
47
|
+
generationTime: number;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Test Generator Factory
|
|
52
|
+
*/
|
|
53
|
+
export class TestGeneratorFactory {
|
|
54
|
+
static create(framework: string, config: RuntimeConfig): TestGenerator {
|
|
55
|
+
switch (framework) {
|
|
56
|
+
case 'playwright': {
|
|
57
|
+
const { CodeGenerator } = require('./code-generator');
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
framework: 'playwright',
|
|
61
|
+
|
|
62
|
+
async generate(
|
|
63
|
+
feature: ParsedFeature,
|
|
64
|
+
selectors: Record<string, any>,
|
|
65
|
+
testData: Record<string, any>,
|
|
66
|
+
cfg: RuntimeConfig
|
|
67
|
+
): Promise<GeneratedTest> {
|
|
68
|
+
const startTime = Date.now();
|
|
69
|
+
|
|
70
|
+
let screenName: string | undefined;
|
|
71
|
+
if (feature.sourceFile) {
|
|
72
|
+
const sourceDir = path.dirname(feature.sourceFile);
|
|
73
|
+
const parts = sourceDir.split(path.sep);
|
|
74
|
+
const screensIndex = parts.indexOf('screens');
|
|
75
|
+
if (screensIndex >= 0 && screensIndex < parts.length - 2) {
|
|
76
|
+
screenName = parts[screensIndex + 1];
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const generator = new CodeGenerator({
|
|
81
|
+
useAI: cfg.testGenerator.enableAIFallback,
|
|
82
|
+
verbose: cfg.verbose,
|
|
83
|
+
screenName,
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
const outputDir = cfg.paths.specsDir;
|
|
87
|
+
const result = await generator.generateTest(feature, outputDir);
|
|
88
|
+
generator.writeTest(result);
|
|
89
|
+
|
|
90
|
+
const countSteps = (f: ParsedFeature) =>
|
|
91
|
+
f.scenarios.reduce((sum: number, s: any) => sum + (s.steps ? s.steps.length : 0), 0);
|
|
92
|
+
const countTodos = (code: string) => (code.match(/\/\/ TODO/g) || []).length;
|
|
93
|
+
|
|
94
|
+
const stats: GenerationStats = {
|
|
95
|
+
totalScenarios: feature.scenarios.length,
|
|
96
|
+
totalSteps: countSteps(feature),
|
|
97
|
+
dictionaryMatched: 0,
|
|
98
|
+
aiGenerated: 0,
|
|
99
|
+
todoCount: countTodos(result.code),
|
|
100
|
+
generationTime: Date.now() - startTime,
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
return {
|
|
104
|
+
feature: feature.name,
|
|
105
|
+
outputPath: result.filePath,
|
|
106
|
+
code: result.code,
|
|
107
|
+
stats,
|
|
108
|
+
};
|
|
109
|
+
},
|
|
110
|
+
|
|
111
|
+
getFileExtension() {
|
|
112
|
+
return '.spec.ts';
|
|
113
|
+
},
|
|
114
|
+
|
|
115
|
+
validate() {
|
|
116
|
+
return true;
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
case 'appium':
|
|
122
|
+
throw new Error('Appium generator not yet implemented');
|
|
123
|
+
|
|
124
|
+
case 'integration':
|
|
125
|
+
throw new Error('Integration test generator not yet implemented');
|
|
126
|
+
|
|
127
|
+
default:
|
|
128
|
+
throw new Error(`Unsupported test framework: ${framework}`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as fs from 'fs';
|
|
2
2
|
import * as path from 'path';
|
|
3
3
|
import yaml from 'yaml';
|
|
4
|
+
import { readYamlIfExists } from '../../../utils/yaml-io';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* DataResolver - Resolves data references to actual values
|
|
@@ -102,13 +103,10 @@ export class DataResolver {
|
|
|
102
103
|
|
|
103
104
|
// Load in reverse priority order (base first, then overrides on top)
|
|
104
105
|
for (const p of [...possiblePaths].reverse()) {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
merged = { ...merged, ...data };
|
|
110
|
-
found = true;
|
|
111
|
-
}
|
|
106
|
+
const data = readYamlIfExists(p);
|
|
107
|
+
if (data && typeof data === 'object' && Object.keys(data).length > 0) {
|
|
108
|
+
merged = { ...merged, ...data };
|
|
109
|
+
found = true;
|
|
112
110
|
}
|
|
113
111
|
}
|
|
114
112
|
|
|
@@ -131,13 +129,10 @@ export class DataResolver {
|
|
|
131
129
|
const possiblePaths = this.getPossibleDataPaths(fileName);
|
|
132
130
|
|
|
133
131
|
for (const p of possiblePaths) {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
const content = fs.readFileSync(p, 'utf-8');
|
|
137
|
-
const data = yaml.parse(content);
|
|
138
|
-
|
|
132
|
+
const data = readYamlIfExists(p);
|
|
133
|
+
if (data !== null) {
|
|
139
134
|
// Skip if file is empty or only contains null/undefined
|
|
140
|
-
if (data ===
|
|
135
|
+
if (data === undefined || (typeof data === 'object' && Object.keys(data).length === 0)) {
|
|
141
136
|
continue;
|
|
142
137
|
}
|
|
143
138
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as fs from 'fs';
|
|
2
2
|
import * as path from 'path';
|
|
3
3
|
import yaml from 'yaml';
|
|
4
|
+
import { readYaml, readYamlIfExists } from '../../../utils/yaml-io';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Remove Vietnamese diacritics (accents) from text
|
|
@@ -187,10 +188,12 @@ function convertJapaneseToRomaji(text: string): string {
|
|
|
187
188
|
return result;
|
|
188
189
|
}
|
|
189
190
|
|
|
191
|
+
import { SelectorType } from '../../../utils/selector-types';
|
|
192
|
+
|
|
190
193
|
// New structured selector format
|
|
191
194
|
interface SelectorEntry {
|
|
192
195
|
locator?: string; // CSS locator (optional, empty string means use type/value)
|
|
193
|
-
type?:
|
|
196
|
+
type?: SelectorType; // Locator strategy
|
|
194
197
|
value?: string; // Natural language value for the locator (e.g., 'button', 'link' for role)
|
|
195
198
|
name?: string; // Accessible name for role-based selectors (e.g., 'Login', 'Submit')
|
|
196
199
|
nth?: number; // Element index (0 = no index, 1+ = append .nth())
|
|
@@ -285,7 +288,7 @@ export class SelectorResolver {
|
|
|
285
288
|
* NOTE: textbox/textarea must precede "text" to prevent partial matching.
|
|
286
289
|
*/
|
|
287
290
|
static extractNthFromStep(afterElement: string): number {
|
|
288
|
-
const nthRegex = /^\s*(?:field|button|textbox|textarea|text|link|input|element|item|logo|image|img|icon|raw|table|columnheader|list|listitem|row|checkbox|radio|dropdown|select|uploader|heading|header)?\s*(\d+)\b/i;
|
|
291
|
+
const nthRegex = /^\s*(?:field|button|textbox|textarea|text|link|input|element|item|logo|image|img|icon|raw|table|column|columnheader|list|listitem|row|checkbox|radio|dropdown|select|uploader|heading|header)?\s*(\d+)\b/i;
|
|
289
292
|
const match = nthRegex.exec(afterElement);
|
|
290
293
|
return match ? parseInt(match[1], 10) : 0;
|
|
291
294
|
}
|
|
@@ -683,19 +686,17 @@ export class SelectorResolver {
|
|
|
683
686
|
// 1. Try load base file (screen-level shared selectors) - OPTIONAL
|
|
684
687
|
if (this.screenName) {
|
|
685
688
|
const basePath = this.findBaseSelectorPath(this.screenName);
|
|
686
|
-
if (basePath
|
|
687
|
-
const
|
|
688
|
-
const baseSelectors = yaml.parse(baseContent) as SelectorFile;
|
|
689
|
+
if (basePath) {
|
|
690
|
+
const baseSelectors = readYamlIfExists<SelectorFile>(basePath);
|
|
689
691
|
if (baseSelectors) {
|
|
690
692
|
Object.assign(selectors, baseSelectors);
|
|
691
693
|
}
|
|
692
694
|
}
|
|
693
|
-
|
|
695
|
+
|
|
694
696
|
// Load base override file
|
|
695
697
|
const baseOverridePath = this.findOverrideSelectorPath(this.screenName);
|
|
696
|
-
if (baseOverridePath
|
|
697
|
-
const
|
|
698
|
-
const overrideSelectors = yaml.parse(overrideContent) as SelectorFile;
|
|
698
|
+
if (baseOverridePath) {
|
|
699
|
+
const overrideSelectors = readYamlIfExists<SelectorFile>(baseOverridePath);
|
|
699
700
|
if (overrideSelectors) {
|
|
700
701
|
Object.assign(selectors, overrideSelectors);
|
|
701
702
|
}
|
|
@@ -713,18 +714,16 @@ export class SelectorResolver {
|
|
|
713
714
|
);
|
|
714
715
|
}
|
|
715
716
|
} else {
|
|
716
|
-
const
|
|
717
|
-
const featureSelectors = yaml.parse(featureContent) as SelectorFile;
|
|
717
|
+
const featureSelectors = readYamlIfExists<SelectorFile>(featurePath);
|
|
718
718
|
if (featureSelectors) {
|
|
719
719
|
Object.assign(selectors, featureSelectors);
|
|
720
720
|
}
|
|
721
721
|
}
|
|
722
|
-
|
|
722
|
+
|
|
723
723
|
// 3. Load feature override file
|
|
724
724
|
const featureOverridePath = this.findOverrideSelectorPath(featureName);
|
|
725
|
-
if (featureOverridePath
|
|
726
|
-
const
|
|
727
|
-
const overrideSelectors = yaml.parse(overrideContent) as SelectorFile;
|
|
725
|
+
if (featureOverridePath) {
|
|
726
|
+
const overrideSelectors = readYamlIfExists<SelectorFile>(featureOverridePath);
|
|
728
727
|
if (overrideSelectors) {
|
|
729
728
|
Object.assign(selectors, overrideSelectors);
|
|
730
729
|
}
|
|
@@ -944,8 +943,7 @@ export class SelectorResolver {
|
|
|
944
943
|
);
|
|
945
944
|
}
|
|
946
945
|
|
|
947
|
-
const
|
|
948
|
-
const selectorFile = yaml.parse(content) as LegacySelectorFile;
|
|
946
|
+
const selectorFile = readYaml<LegacySelectorFile>(filePath);
|
|
949
947
|
|
|
950
948
|
this.selectorCache.set(cacheKey, selectorFile);
|
|
951
949
|
return selectorFile;
|