@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
|
@@ -9,6 +9,7 @@ import { glob } from 'glob';
|
|
|
9
9
|
import { LiveScanResult, LiveScanScenario, LiveScanOptions } from './types';
|
|
10
10
|
import { replaySteps } from './step-replayer';
|
|
11
11
|
import { writeMatrix } from './matrix-writer';
|
|
12
|
+
import { readMatrix, mergeMatrixElements } from './matrix-reader';
|
|
12
13
|
import { readBaseUrlFromPlaywrightConfig } from './config-reader';
|
|
13
14
|
|
|
14
15
|
export class LiveScanner {
|
|
@@ -68,9 +69,19 @@ export class LiveScanner {
|
|
|
68
69
|
const featureName = path.basename(featureFile, '.feature');
|
|
69
70
|
console.log(`\n📄 Scanning feature: ${featureName}`);
|
|
70
71
|
|
|
72
|
+
// Load existing matrix for incremental scan (non-force mode)
|
|
73
|
+
let existingResult: LiveScanResult | null = null;
|
|
74
|
+
if (!this.options.force) {
|
|
75
|
+
const matrixPath = path.join(selectorsDir, `${featureName}.live-scan.yaml`);
|
|
76
|
+
existingResult = readMatrix(matrixPath);
|
|
77
|
+
if (existingResult) {
|
|
78
|
+
console.log(` 📦 Found existing scan — resolved elements will be skipped`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
71
82
|
try {
|
|
72
83
|
const parsed = parser.parseFeatureFile(featureFile);
|
|
73
|
-
const result = await this.scanFeature(browser, playwright, parsed, baseUrl);
|
|
84
|
+
const result = await this.scanFeature(browser, playwright, parsed, baseUrl, existingResult);
|
|
74
85
|
results.push(result);
|
|
75
86
|
|
|
76
87
|
// Write matrix file
|
|
@@ -112,11 +123,15 @@ export class LiveScanner {
|
|
|
112
123
|
browser: any,
|
|
113
124
|
playwright: any,
|
|
114
125
|
feature: any,
|
|
115
|
-
baseUrl: string
|
|
126
|
+
baseUrl: string,
|
|
127
|
+
existingResult?: LiveScanResult | null
|
|
116
128
|
): Promise<LiveScanResult> {
|
|
117
129
|
const featurePath = feature.path || '/';
|
|
118
130
|
const scenarios: Record<string, LiveScanScenario> = {};
|
|
119
131
|
|
|
132
|
+
// Build merged existing elements map for skip logic
|
|
133
|
+
const existingElements = existingResult ? mergeMatrixElements(existingResult) : undefined;
|
|
134
|
+
|
|
120
135
|
// Build a map of @steps scenarios for resolution
|
|
121
136
|
const stepsMap = new Map<string, any>();
|
|
122
137
|
for (const scenario of feature.scenarios) {
|
|
@@ -167,7 +182,7 @@ export class LiveScanner {
|
|
|
167
182
|
const page = await context.newPage();
|
|
168
183
|
|
|
169
184
|
try {
|
|
170
|
-
const result = await replaySteps(page, steps, featurePath, baseUrl);
|
|
185
|
+
const result = await replaySteps(page, steps, featurePath, baseUrl, existingElements);
|
|
171
186
|
|
|
172
187
|
scenarios[scenarioKey] = {
|
|
173
188
|
auth: authRole,
|
|
@@ -178,6 +193,9 @@ export class LiveScanner {
|
|
|
178
193
|
|
|
179
194
|
// Print element summary
|
|
180
195
|
const elementCount = Object.keys(result.elements).length;
|
|
196
|
+
const skipped = Object.values(result.elements).filter(
|
|
197
|
+
(e: any) => e.skipped
|
|
198
|
+
).length;
|
|
181
199
|
const resolved = Object.values(result.elements).filter(
|
|
182
200
|
(e: any) => e.matchMethod !== 'unresolved'
|
|
183
201
|
).length;
|
|
@@ -185,7 +203,8 @@ export class LiveScanner {
|
|
|
185
203
|
(e: any) => e.warning
|
|
186
204
|
).length;
|
|
187
205
|
|
|
188
|
-
|
|
206
|
+
const skippedInfo = skipped > 0 ? `, ${skipped} cached` : '';
|
|
207
|
+
console.log(` 📊 Elements: ${resolved}/${elementCount} resolved${skippedInfo}${warnings > 0 ? `, ${warnings} warnings` : ''}`);
|
|
189
208
|
|
|
190
209
|
for (const error of result.errors) {
|
|
191
210
|
console.log(` ⚠️ ${error}`);
|
|
@@ -193,6 +212,10 @@ export class LiveScanner {
|
|
|
193
212
|
|
|
194
213
|
// Print per-element status
|
|
195
214
|
for (const [key, el] of Object.entries(result.elements) as any) {
|
|
215
|
+
if (el.skipped) {
|
|
216
|
+
// Already printed in replaySteps
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
196
219
|
if (el.matchMethod === 'unresolved') {
|
|
197
220
|
console.log(` ✗ [${el.gherkinRef}] ${el.gherkinType} → NOT FOUND`);
|
|
198
221
|
} else if (el.warning) {
|
|
@@ -31,12 +31,33 @@ export async function replaySteps(
|
|
|
31
31
|
page: Page,
|
|
32
32
|
steps: ParsedStepInfo[],
|
|
33
33
|
featurePath: string,
|
|
34
|
-
baseUrl: string
|
|
34
|
+
baseUrl: string,
|
|
35
|
+
existingElements?: Record<string, LiveElement>
|
|
35
36
|
): Promise<ReplayResult> {
|
|
36
37
|
const elements: Record<string, LiveElement> = {};
|
|
37
38
|
const errors: string[] = [];
|
|
38
39
|
let currentContext: ElementContext = 'page';
|
|
39
40
|
|
|
41
|
+
// Pre-scan: detect which base keys have multiple normalized element types
|
|
42
|
+
// so we can append --type suffix (matching scaffold generator behavior)
|
|
43
|
+
// Uses normalizeElementType to match scaffold generator's extractTargetType mapping
|
|
44
|
+
// e.g. modal/dialog both normalize to 'dialog', so they won't create a false conflict
|
|
45
|
+
const typesPerKey = new Map<string, Set<string>>();
|
|
46
|
+
for (const step of steps) {
|
|
47
|
+
if (!step.selectorRef) continue;
|
|
48
|
+
const baseKey = generateElementKey(step.selectorRef, step.elementType, step.nth);
|
|
49
|
+
const action = detectAction(step.text);
|
|
50
|
+
const normalizedType = normalizeElementType(step.elementType || 'button', action);
|
|
51
|
+
if (!typesPerKey.has(baseKey)) {
|
|
52
|
+
typesPerKey.set(baseKey, new Set());
|
|
53
|
+
}
|
|
54
|
+
typesPerKey.get(baseKey)!.add(normalizedType);
|
|
55
|
+
}
|
|
56
|
+
const conflictKeys = new Set<string>();
|
|
57
|
+
for (const [key, types] of typesPerKey) {
|
|
58
|
+
if (types.size > 1) conflictKeys.add(key);
|
|
59
|
+
}
|
|
60
|
+
|
|
40
61
|
for (const step of steps) {
|
|
41
62
|
try {
|
|
42
63
|
const action = detectAction(step.text);
|
|
@@ -46,7 +67,9 @@ export async function replaySteps(
|
|
|
46
67
|
await page.goto(baseUrl + featurePath, { waitUntil: 'networkidle', timeout: 15000 });
|
|
47
68
|
await settle(page);
|
|
48
69
|
if (step.selectorRef) {
|
|
49
|
-
const
|
|
70
|
+
const baseKey = generateElementKey(step.selectorRef, step.elementType, step.nth);
|
|
71
|
+
const normalizedType = normalizeElementType(step.elementType || 'page', action);
|
|
72
|
+
const key = conflictKeys.has(baseKey) ? `${baseKey}--${normalizedType}` : baseKey;
|
|
50
73
|
// Record the page element but don't search for it on the DOM
|
|
51
74
|
elements[key] = {
|
|
52
75
|
gherkinRef: step.selectorRef,
|
|
@@ -71,9 +94,36 @@ export async function replaySteps(
|
|
|
71
94
|
// Skip steps without element references
|
|
72
95
|
if (!step.selectorRef) continue;
|
|
73
96
|
|
|
74
|
-
const
|
|
75
|
-
const nth = step.nth || 0;
|
|
97
|
+
const baseKey = generateElementKey(step.selectorRef, step.elementType, step.nth);
|
|
76
98
|
const elementType = step.elementType || 'button';
|
|
99
|
+
const normalizedType = normalizeElementType(elementType, action);
|
|
100
|
+
const key = conflictKeys.has(baseKey) ? `${baseKey}--${normalizedType}` : baseKey;
|
|
101
|
+
const nth = step.nth || 0;
|
|
102
|
+
|
|
103
|
+
// Skip column-type elements — they use header text matching, no DOM lookup needed
|
|
104
|
+
if (normalizedType === 'column') {
|
|
105
|
+
console.log(` ⏭️ [${step.selectorRef}] column → skipped (table header match)`);
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Skip if element already resolved in existing scan (non-force mode)
|
|
110
|
+
if (existingElements && existingElements[key] && existingElements[key].matchMethod !== 'unresolved') {
|
|
111
|
+
elements[key] = existingElements[key];
|
|
112
|
+
(elements[key] as any).skipped = true;
|
|
113
|
+
console.log(` ⏩ [${step.selectorRef}] ${elementType} → cached (${existingElements[key].selectorType})`);
|
|
114
|
+
|
|
115
|
+
// Still execute clicks for cached elements to maintain page state
|
|
116
|
+
if (action === 'click') {
|
|
117
|
+
try {
|
|
118
|
+
await executeClick(page, step.selectorRef, elementType, nth);
|
|
119
|
+
await settle(page);
|
|
120
|
+
currentContext = await detectCurrentContext(page, currentContext, step.text);
|
|
121
|
+
} catch {
|
|
122
|
+
// Click failed for cached element, continue anyway
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
77
127
|
|
|
78
128
|
// Find the element on the page
|
|
79
129
|
const element = await findElement(page, step.selectorRef, elementType, nth);
|
|
@@ -208,10 +258,46 @@ async function settle(page: Page): Promise<void> {
|
|
|
208
258
|
await page.waitForTimeout(300);
|
|
209
259
|
}
|
|
210
260
|
|
|
211
|
-
function generateElementKey(ref: string, elementType?: string): string {
|
|
261
|
+
function generateElementKey(ref: string, elementType?: string, nth?: number): string {
|
|
212
262
|
// Use the same key generation as the scaffold generator
|
|
213
263
|
// so live-scan keys match scaffold keys in the map command.
|
|
214
|
-
|
|
264
|
+
// Append --N suffix for nth > 0, consistent with scaffold generator format.
|
|
265
|
+
const baseKey = SelectorResolver.generateKey(ref);
|
|
266
|
+
return nth && nth > 0 ? `${baseKey}--${nth}` : baseKey;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Normalize element type to match scaffold generator's extractTargetType() mapping.
|
|
271
|
+
* e.g. modal→dialog, img/icon/logo→img, input→field, select→dropdown, etc.
|
|
272
|
+
*/
|
|
273
|
+
function normalizeElementType(elementType: string, action: string): string {
|
|
274
|
+
const t = elementType.toLowerCase();
|
|
275
|
+
if (t === 'page') return 'page';
|
|
276
|
+
if (t === 'link') return 'link';
|
|
277
|
+
if (t === 'button') return 'button';
|
|
278
|
+
if (t === 'radio') return 'radio';
|
|
279
|
+
if (t === 'dropdown' || t === 'select') return 'dropdown';
|
|
280
|
+
if (t === 'checkbox') return 'checkbox';
|
|
281
|
+
if (t === 'field' || t === 'input') return 'field';
|
|
282
|
+
if (t === 'textbox') return 'textbox';
|
|
283
|
+
if (t === 'textarea') return 'textarea';
|
|
284
|
+
if (t === 'text') return 'text';
|
|
285
|
+
if (t === 'label') return 'label';
|
|
286
|
+
if (t === 'uploader') return 'uploader';
|
|
287
|
+
if (t === 'element') return 'element';
|
|
288
|
+
if (t === 'column' || t === 'columnheader') return 'column';
|
|
289
|
+
if (t === 'logo' || t === 'image' || t === 'img' || t === 'icon') return 'img';
|
|
290
|
+
if (t === 'dialog' || t === 'modal') return 'dialog';
|
|
291
|
+
if (t === 'heading' || t === 'header') return 'heading';
|
|
292
|
+
if (t === 'title' || t === 'caption' || t === 'message') return 'text';
|
|
293
|
+
// Default based on action (matches scaffold generator)
|
|
294
|
+
switch (action) {
|
|
295
|
+
case 'click': return 'text';
|
|
296
|
+
case 'fill': return 'field';
|
|
297
|
+
case 'see': return 'text';
|
|
298
|
+
case 'select': return 'dropdown';
|
|
299
|
+
default: return 'element';
|
|
300
|
+
}
|
|
215
301
|
}
|
|
216
302
|
|
|
217
303
|
function escapeRegex(str: string): string {
|
|
@@ -8,10 +8,11 @@ import * as path from 'path';
|
|
|
8
8
|
import yaml from 'yaml';
|
|
9
9
|
import { ValidationIssue } from './index';
|
|
10
10
|
import { SelectorResolver } from '../../generators/test-generator/utils/selector-resolver';
|
|
11
|
+
import { VALID_SELECTOR_TYPES, SelectorType } from '../../utils/selector-types';
|
|
11
12
|
|
|
12
13
|
interface SelectorEntry {
|
|
13
14
|
selector?: string;
|
|
14
|
-
type?:
|
|
15
|
+
type?: SelectorType;
|
|
15
16
|
value?: string;
|
|
16
17
|
name?: string;
|
|
17
18
|
nth?: number;
|
|
@@ -19,7 +20,7 @@ interface SelectorEntry {
|
|
|
19
20
|
|
|
20
21
|
type SelectorFile = Record<string, SelectorEntry>;
|
|
21
22
|
|
|
22
|
-
const VALID_TYPES =
|
|
23
|
+
const VALID_TYPES = VALID_SELECTOR_TYPES;
|
|
23
24
|
|
|
24
25
|
export class SelectorValidator {
|
|
25
26
|
private screenName: string;
|
|
@@ -8,10 +8,11 @@ import path from 'path';
|
|
|
8
8
|
import yaml from 'yaml';
|
|
9
9
|
import { glob } from 'glob';
|
|
10
10
|
import { SelectorResolver } from '../test-generator/utils/selector-resolver';
|
|
11
|
+
import { SelectorType } from '../../utils/selector-types';
|
|
11
12
|
|
|
12
13
|
export interface ScaffoldElement {
|
|
13
14
|
locator: string;
|
|
14
|
-
type:
|
|
15
|
+
type: SelectorType;
|
|
15
16
|
value: string;
|
|
16
17
|
name?: string; // For role type (accessible name), or label text
|
|
17
18
|
nth: number;
|
|
@@ -176,6 +177,9 @@ export class ScaffoldGenerator {
|
|
|
176
177
|
if (/^element\b/.test(lowerText) || /^\d*\s*element\b/.test(lowerText)) {
|
|
177
178
|
return 'element';
|
|
178
179
|
}
|
|
180
|
+
if (/^(column|columnheader)\b/.test(lowerText) || /^\d*\s*(column|columnheader)\b/.test(lowerText)) {
|
|
181
|
+
return 'column';
|
|
182
|
+
}
|
|
179
183
|
if (/^(logo|image|img|icon)\b/.test(lowerText) || /^\d*\s*(logo|image|img|icon)\b/.test(lowerText)) {
|
|
180
184
|
return 'img';
|
|
181
185
|
}
|
|
@@ -395,9 +399,19 @@ export class ScaffoldGenerator {
|
|
|
395
399
|
};
|
|
396
400
|
|
|
397
401
|
case 'see':
|
|
402
|
+
// Column type: used for table column cell assertions, no DOM selector needed
|
|
403
|
+
if (targetType === 'column') {
|
|
404
|
+
return {
|
|
405
|
+
locator: '',
|
|
406
|
+
type: 'column',
|
|
407
|
+
value: element.rawText,
|
|
408
|
+
nth,
|
|
409
|
+
};
|
|
410
|
+
}
|
|
411
|
+
|
|
398
412
|
// For assertions - respect targetType for role-based elements
|
|
399
413
|
if (targetType === 'img' || targetType === 'button' || targetType === 'link' ||
|
|
400
|
-
targetType === 'checkbox' || targetType === 'radio' || targetType === 'heading' || targetType === 'dialog') {
|
|
414
|
+
targetType === 'checkbox' || targetType === 'radio' || targetType === 'heading' || targetType === 'dialog' || targetType === 'dropdown') {
|
|
401
415
|
const seeRoleValue = this.getRoleValue(targetType);
|
|
402
416
|
return {
|
|
403
417
|
locator: '',
|
|
@@ -469,6 +483,8 @@ export class ScaffoldGenerator {
|
|
|
469
483
|
return 'heading';
|
|
470
484
|
case 'dialog':
|
|
471
485
|
return 'dialog';
|
|
486
|
+
case 'dropdown':
|
|
487
|
+
return 'button';
|
|
472
488
|
default:
|
|
473
489
|
return 'button'; // Default to button
|
|
474
490
|
}
|
|
@@ -643,6 +659,11 @@ export class ScaffoldGenerator {
|
|
|
643
659
|
const enriched: ScaffoldResult = { ...scaffold };
|
|
644
660
|
|
|
645
661
|
for (const [key, scaffoldElement] of Object.entries(enriched)) {
|
|
662
|
+
// Column-type elements use header text matching, skip live-scan enrichment
|
|
663
|
+
if (scaffoldElement.type === 'column') continue;
|
|
664
|
+
// Target elements (empty value) are matched by data value at runtime, skip enrichment
|
|
665
|
+
if (!scaffoldElement.value && !scaffoldElement.name) continue;
|
|
666
|
+
|
|
646
667
|
// Try exact key first, then base key without --N suffix or --type suffix
|
|
647
668
|
let liveElement = elements[key];
|
|
648
669
|
if (!liveElement && key.includes('--')) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
await page.getByRole('{{role}}').filter({ hasText: '{{escapeQuotes dataValue}}' }).waitFor({ state: '{{state}}' });
|
package/src/generators/test-generator/adapters/playwright/templates/steps/actions/wait-for-role.hbs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
await page.getByRole('{{role}}').waitFor({ state: '{{state}}' });
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
await
|
|
1
|
+
await page.waitForLoadState('networkidle');
|
|
2
|
+
await expect({{> locator}}).toBeChecked();
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
await page.waitForLoadState('networkidle');
|
|
2
|
+
const {{columnIndexVar}} = (await page.getByRole('columnheader').allTextContents()).findIndex(h => h.includes('{{columnName}}'));
|
|
3
|
+
await expect(page.getByRole('row').nth({{rowNth}}).getByRole('cell').nth({{columnIndexVar}})).toHaveText('{{dataValue}}');
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
await
|
|
1
|
+
await page.waitForLoadState('networkidle');
|
|
2
|
+
await expect({{> locator}}).toContainText('{{expectedText}}');
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
await
|
|
1
|
+
await page.waitForLoadState('networkidle');
|
|
2
|
+
await expect({{> locator}}).toHaveCount({{expectedCount}});
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
await
|
|
1
|
+
await page.waitForLoadState('networkidle');
|
|
2
|
+
await expect({{> locator}}).toBeDisabled();
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
await
|
|
1
|
+
await page.waitForLoadState('networkidle');
|
|
2
|
+
await expect({{> locator-base}}.filter({ hasText: /^{{escapeRegex dataValue}}$/ }){{> locator-nth}}).toBeDisabled();
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
await page.waitForLoadState('networkidle');
|
|
1
2
|
{{#if name}}
|
|
2
|
-
await expect(page.getByRole('{{role}}', { name: '{{escapeQuotes name}}'{{#if exact}}, exact: true{{/if}} }).filter({ hasText:
|
|
3
|
+
await expect(page.getByRole('{{role}}', { name: '{{escapeQuotes name}}'{{#if exact}}, exact: true{{/if}} }).filter({ hasText: /^{{escapeRegex dataValue}}$/ }){{#if (gt nth 0)}}.nth({{subtract nth 1}}){{/if}}).toBeDisabled();
|
|
3
4
|
{{else}}
|
|
4
|
-
await expect(page.getByRole('{{role}}'{{#if exact}}, { exact: true }{{/if}}).filter({ hasText:
|
|
5
|
-
{{/if}}
|
|
5
|
+
await expect(page.getByRole('{{role}}'{{#if exact}}, { exact: true }{{/if}}).filter({ hasText: /^{{escapeRegex dataValue}}$/ }){{#if (gt nth 0)}}.nth({{subtract nth 1}}){{/if}}).toBeDisabled();
|
|
6
|
+
{{/if}}
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
await
|
|
1
|
+
await page.waitForLoadState('networkidle');
|
|
2
|
+
await expect(page.getByText('{{escapeQuotes selectorRef}}').filter({ hasText: {{#if (eq selectorValue "")}}/.*{{escapeRegex dataValue}}$/{{else}}'{{escapeQuotes dataValue}}'{{/if}} }){{#if (gt nth 0)}}.nth({{subtract nth 1}}){{/if}}).toBeDisabled();
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
await
|
|
1
|
+
await page.waitForLoadState('networkidle');
|
|
2
|
+
await expect({{> locator}}).toBeEmpty();
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
await
|
|
1
|
+
await page.waitForLoadState('networkidle');
|
|
2
|
+
await expect({{> locator}}).toBeEnabled();
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
await
|
|
1
|
+
await page.waitForLoadState('networkidle');
|
|
2
|
+
await expect({{> locator}}).toBeFocused();
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
await
|
|
1
|
+
await page.waitForLoadState('networkidle');
|
|
2
|
+
await expect({{> locator}}).toHaveText('{{expectedText}}');
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
await
|
|
1
|
+
await page.waitForLoadState('networkidle');
|
|
2
|
+
await expect({{> locator-base}}.filter({ hasText: /^{{escapeRegex dataValue}}$/ }){{> locator-nth}}).toBeHidden();
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
await page.waitForLoadState('networkidle');
|
|
1
2
|
{{#if name}}
|
|
2
|
-
await expect(page.getByRole('{{role}}', { name: '{{escapeQuotes name}}'{{#if exact}}, exact: true{{/if}} }).filter({ hasText:
|
|
3
|
+
await expect(page.getByRole('{{role}}', { name: '{{escapeQuotes name}}'{{#if exact}}, exact: true{{/if}} }).filter({ hasText: /^{{escapeRegex dataValue}}$/ }){{#if (gt nth 0)}}.nth({{subtract nth 1}}){{/if}}).toBeHidden();
|
|
3
4
|
{{else}}
|
|
4
|
-
await expect(page.getByRole('{{role}}'{{#if exact}}, { exact: true }{{/if}}).filter({ hasText:
|
|
5
|
-
{{/if}}
|
|
5
|
+
await expect(page.getByRole('{{role}}'{{#if exact}}, { exact: true }{{/if}}).filter({ hasText: /^{{escapeRegex dataValue}}$/ }){{#if (gt nth 0)}}.nth({{subtract nth 1}}){{/if}}).toBeHidden();
|
|
6
|
+
{{/if}}
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
await
|
|
1
|
+
await page.waitForLoadState('networkidle');
|
|
2
|
+
await expect(page.getByText('{{escapeQuotes selectorRef}}').filter({ hasText: {{#if (eq selectorValue "")}}/.*{{escapeRegex dataValue}}$/{{else}}'{{escapeQuotes dataValue}}'{{/if}} }){{#if (gt nth 0)}}.nth({{subtract nth 1}}){{/if}}).toBeHidden();
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
await
|
|
1
|
+
await page.waitForLoadState('networkidle');
|
|
2
|
+
await expect({{> locator}}.getByRole('listitem')).toHaveCount({{expectedCount}});
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
await
|
|
1
|
+
await page.waitForLoadState('networkidle');
|
|
2
|
+
await expect({{> locator}}).toBeChecked({ checked: false });
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
await
|
|
1
|
+
await page.waitForLoadState('networkidle');
|
|
2
|
+
await expect({{> locator}}).toBeVisible();
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
await
|
|
1
|
+
await page.waitForLoadState('networkidle');
|
|
2
|
+
await expect({{> locator-base}}.filter({ hasText: /^{{escapeRegex dataValue}}$/ }){{> locator-nth}}).toBeVisible();
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
await page.waitForLoadState('networkidle');
|
|
1
2
|
{{#if name}}
|
|
2
3
|
{{#if dataValue}}
|
|
3
|
-
await expect(page.getByRole('{{role}}', { name: '{{escapeQuotes name}}'{{#if exact}}, exact: true{{/if}} }).filter({ hasText:
|
|
4
|
+
await expect(page.getByRole('{{role}}', { name: '{{escapeQuotes name}}'{{#if exact}}, exact: true{{/if}} }).filter({ hasText: /^{{escapeRegex dataValue}}$/ }){{#if (gt nth 0)}}.nth({{subtract nth 1}}){{/if}}).toBeVisible();
|
|
4
5
|
{{else}}
|
|
5
6
|
await expect(page.getByRole('{{role}}', { name: '{{escapeQuotes name}}'{{#if exact}}, exact: true{{/if}} }){{#if (gt nth 0)}}.nth({{subtract nth 1}}){{/if}}).toBeVisible();
|
|
6
7
|
{{/if}}
|
|
7
8
|
{{else}}
|
|
8
|
-
await expect(page.getByRole('{{role}}'{{#if exact}}, { exact: true }{{/if}}).filter({ hasText:
|
|
9
|
-
{{/if}}
|
|
9
|
+
await expect(page.getByRole('{{role}}'{{#if exact}}, { exact: true }{{/if}}).filter({ hasText: /^{{escapeRegex dataValue}}$/ }){{#if (gt nth 0)}}.nth({{subtract nth 1}}){{/if}}).toBeVisible();
|
|
10
|
+
{{/if}}
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
await
|
|
1
|
+
await page.waitForLoadState('networkidle');
|
|
2
|
+
await expect(page.getByText('{{escapeQuotes value}}').filter({ hasText: /^{{escapeRegex dataValue}}$/ })).toBeVisible();
|
package/src/generators/test-generator/adapters/playwright/templates/steps/navigation/navigation.hbs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
await page.goto('{{#if baseURL}}{{baseURL}}{{/if}}{{path}}');
|
|
1
|
+
await page.goto('{{#if baseURL}}{{baseURL}}{{/if}}{{path}}', { waitUntil: 'networkidle' });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
await {{> locator-base}}.filter({ hasText:
|
|
1
|
+
await {{> locator-base}}.filter({ hasText: /^{{escapeRegex dataValue}}$/ }){{> locator-nth}}.waitFor({ state: '{{state}}' });
|