@sun-asterisk/sungen 1.0.14 → 1.0.16
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/generators/cli.js +1 -1
- package/dist/generators/gherkin-parser/index.d.ts +3 -0
- package/dist/generators/gherkin-parser/index.d.ts.map +1 -1
- package/dist/generators/gherkin-parser/index.js +14 -1
- package/dist/generators/gherkin-parser/index.js.map +1 -1
- package/dist/generators/scaffold-generator/index.d.ts +4 -1
- package/dist/generators/scaffold-generator/index.d.ts.map +1 -1
- package/dist/generators/scaffold-generator/index.js +46 -18
- package/dist/generators/scaffold-generator/index.js.map +1 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/click-element-with-text.hbs +1 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/radio-select-action.hbs +1 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/unknown-element-action.hbs +1 -0
- package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/upload-action.hbs +1 -0
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/disabled-assertion.hbs +1 -2
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/disabled-with-filter-assertion.hbs +1 -0
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/disabled-with-role-variable-assertion.hbs +5 -0
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/disabled-with-variable-assertion.hbs +1 -0
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/empty-assertion.hbs +1 -2
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/enabled-assertion.hbs +1 -2
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/hidden-with-filter-assertion.hbs +1 -0
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/hidden-with-role-variable-assertion.hbs +5 -0
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/hidden-with-variable-assertion.hbs +1 -0
- 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/not-checked-assertion.hbs +1 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-with-locator-variable-assertion.hbs +1 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-with-role-variable-assertion.hbs +5 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-with-value-assertion.hbs +1 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-with-variable-assertion.hbs +1 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/navigation/wait-for-element-with-text.hbs +1 -0
- package/dist/generators/test-generator/adapters/playwright/templates/steps/partials/locator-base.hbs +10 -0
- package/dist/generators/test-generator/adapters/playwright/templates/steps/partials/locator-nth.hbs +1 -0
- package/dist/generators/test-generator/adapters/playwright/templates/steps/partials/locator-strategies/default.hbs +1 -0
- package/dist/generators/test-generator/adapters/playwright/templates/steps/partials/locator-strategies/id.hbs +1 -0
- package/dist/generators/test-generator/adapters/playwright/templates/steps/partials/locator-strategies/label.hbs +1 -0
- package/dist/generators/test-generator/adapters/playwright/templates/steps/partials/locator-strategies/locator.hbs +1 -0
- package/dist/generators/test-generator/adapters/playwright/templates/steps/partials/locator-strategies/placeholder.hbs +1 -0
- package/dist/generators/test-generator/adapters/playwright/templates/steps/partials/locator-strategies/role.hbs +1 -0
- package/dist/generators/test-generator/adapters/playwright/templates/steps/partials/locator-strategies/testid.hbs +1 -0
- package/dist/generators/test-generator/adapters/playwright/templates/steps/partials/locator-strategies/text.hbs +1 -0
- package/dist/generators/test-generator/adapters/playwright/templates/steps/partials/locator.hbs +10 -1
- package/dist/generators/test-generator/code-generator.d.ts +3 -1
- package/dist/generators/test-generator/code-generator.d.ts.map +1 -1
- package/dist/generators/test-generator/code-generator.js +66 -14
- package/dist/generators/test-generator/code-generator.js.map +1 -1
- package/dist/generators/test-generator/patterns/assertion-patterns.d.ts.map +1 -1
- package/dist/generators/test-generator/patterns/assertion-patterns.js +148 -73
- package/dist/generators/test-generator/patterns/assertion-patterns.js.map +1 -1
- package/dist/generators/test-generator/patterns/form-patterns.d.ts.map +1 -1
- package/dist/generators/test-generator/patterns/form-patterns.js +37 -5
- package/dist/generators/test-generator/patterns/form-patterns.js.map +1 -1
- package/dist/generators/test-generator/patterns/interaction-patterns.d.ts.map +1 -1
- package/dist/generators/test-generator/patterns/interaction-patterns.js +116 -20
- package/dist/generators/test-generator/patterns/interaction-patterns.js.map +1 -1
- package/dist/generators/test-generator/patterns/navigation-patterns.d.ts.map +1 -1
- package/dist/generators/test-generator/patterns/navigation-patterns.js +1 -1
- package/dist/generators/test-generator/patterns/navigation-patterns.js.map +1 -1
- package/dist/generators/test-generator/step-mapper.d.ts +1 -0
- package/dist/generators/test-generator/step-mapper.d.ts.map +1 -1
- package/dist/generators/test-generator/step-mapper.js +15 -0
- package/dist/generators/test-generator/step-mapper.js.map +1 -1
- package/dist/generators/test-generator/template-engine.d.ts +5 -0
- package/dist/generators/test-generator/template-engine.d.ts.map +1 -1
- package/dist/generators/test-generator/template-engine.js +67 -3
- package/dist/generators/test-generator/template-engine.js.map +1 -1
- package/dist/generators/test-generator/utils/selector-resolver.d.ts +14 -1
- package/dist/generators/test-generator/utils/selector-resolver.d.ts.map +1 -1
- package/dist/generators/test-generator/utils/selector-resolver.js +32 -5
- package/dist/generators/test-generator/utils/selector-resolver.js.map +1 -1
- package/dist/input/cli-adapter.js +1 -1
- package/dist/orchestrator/project-initializer.d.ts.map +1 -1
- package/dist/orchestrator/project-initializer.js +2 -1
- package/dist/orchestrator/project-initializer.js.map +1 -1
- package/package.json +1 -1
- package/src/generators/cli.ts +1 -1
- package/src/generators/gherkin-parser/index.ts +18 -1
- package/src/generators/scaffold-generator/index.ts +50 -22
- package/src/generators/test-generator/adapters/playwright/templates/steps/actions/click-element-with-text.hbs +1 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/actions/radio-select-action.hbs +1 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/actions/unknown-element-action.hbs +1 -0
- package/src/generators/test-generator/adapters/playwright/templates/steps/actions/upload-action.hbs +1 -0
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/disabled-assertion.hbs +1 -2
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/disabled-with-filter-assertion.hbs +1 -0
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/disabled-with-role-variable-assertion.hbs +5 -0
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/disabled-with-variable-assertion.hbs +1 -0
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/empty-assertion.hbs +1 -2
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/enabled-assertion.hbs +1 -2
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/hidden-with-filter-assertion.hbs +1 -0
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/hidden-with-role-variable-assertion.hbs +5 -0
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/hidden-with-variable-assertion.hbs +1 -0
- 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/not-checked-assertion.hbs +1 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-with-locator-variable-assertion.hbs +1 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-with-role-variable-assertion.hbs +5 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-with-value-assertion.hbs +1 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-with-variable-assertion.hbs +1 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/navigation/wait-for-element-with-text.hbs +1 -0
- package/src/generators/test-generator/adapters/playwright/templates/steps/partials/locator-base.hbs +10 -0
- package/src/generators/test-generator/adapters/playwright/templates/steps/partials/locator-nth.hbs +1 -0
- package/src/generators/test-generator/adapters/playwright/templates/steps/partials/locator-strategies/default.hbs +1 -0
- package/src/generators/test-generator/adapters/playwright/templates/steps/partials/locator-strategies/id.hbs +1 -0
- package/src/generators/test-generator/adapters/playwright/templates/steps/partials/locator-strategies/label.hbs +1 -0
- package/src/generators/test-generator/adapters/playwright/templates/steps/partials/locator-strategies/locator.hbs +1 -0
- package/src/generators/test-generator/adapters/playwright/templates/steps/partials/locator-strategies/placeholder.hbs +1 -0
- package/src/generators/test-generator/adapters/playwright/templates/steps/partials/locator-strategies/role.hbs +1 -0
- package/src/generators/test-generator/adapters/playwright/templates/steps/partials/locator-strategies/testid.hbs +1 -0
- package/src/generators/test-generator/adapters/playwright/templates/steps/partials/locator-strategies/text.hbs +1 -0
- package/src/generators/test-generator/adapters/playwright/templates/steps/partials/locator.hbs +10 -1
- package/src/generators/test-generator/code-generator.ts +70 -15
- package/src/generators/test-generator/patterns/assertion-patterns.ts +171 -78
- package/src/generators/test-generator/patterns/form-patterns.ts +39 -5
- package/src/generators/test-generator/patterns/interaction-patterns.ts +126 -24
- package/src/generators/test-generator/patterns/navigation-patterns.ts +2 -1
- package/src/generators/test-generator/step-mapper.ts +18 -2
- package/src/generators/test-generator/template-engine.ts +74 -3
- package/src/generators/test-generator/utils/selector-resolver.ts +34 -5
- package/src/input/cli-adapter.ts +1 -1
- package/src/orchestrator/project-initializer.ts +2 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/target-element-action.hbs +0 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/not-visible-assertion.hbs +0 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-with-filter-assertion.hbs +0 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/navigation/page-navigation.hbs +0 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/actions/target-element-action.hbs +0 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/not-visible-assertion.hbs +0 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-with-filter-assertion.hbs +0 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/navigation/page-navigation.hbs +0 -1
|
@@ -23,7 +23,8 @@ export const assertionPatterns: StepPattern[] = [
|
|
|
23
23
|
const resolved = context.selectorResolver.resolveSelector(
|
|
24
24
|
step.selectorRef,
|
|
25
25
|
context.featureName,
|
|
26
|
-
step.elementType
|
|
26
|
+
step.elementType,
|
|
27
|
+
step.nth
|
|
27
28
|
);
|
|
28
29
|
// Use selector's value as the path for URL assertion
|
|
29
30
|
path = resolved.value || path;
|
|
@@ -42,6 +43,134 @@ export const assertionPatterns: StepPattern[] = [
|
|
|
42
43
|
};
|
|
43
44
|
},
|
|
44
45
|
priority: 13, // Higher priority than general visibility
|
|
46
|
+
},
|
|
47
|
+
// Pattern: Then User see [panel] dialog with {{kudo.title}} hidden -> toBeHidden()
|
|
48
|
+
{
|
|
49
|
+
name: 'see-with-variable-hidden',
|
|
50
|
+
matcher: (step: ParsedStep) =>
|
|
51
|
+
(step.text.includes('should see') || step.text.match(/\b(see|sees)\s+\[/)) &&
|
|
52
|
+
!!step.selectorRef &&
|
|
53
|
+
!!step.dataRef &&
|
|
54
|
+
step.text.includes('with') &&
|
|
55
|
+
/\bis hidden\b/.test(step.text),
|
|
56
|
+
generator: (step, context) => {
|
|
57
|
+
let resolved: any = {};
|
|
58
|
+
try {
|
|
59
|
+
resolved = context.selectorResolver.resolveSelector(
|
|
60
|
+
step.selectorRef!,
|
|
61
|
+
context.featureName,
|
|
62
|
+
step.elementType,
|
|
63
|
+
step.nth
|
|
64
|
+
);
|
|
65
|
+
} catch (error) {}
|
|
66
|
+
|
|
67
|
+
let dataValue: string;
|
|
68
|
+
try {
|
|
69
|
+
dataValue = context.dataResolver.resolveData(step.dataRef!, context.featureName);
|
|
70
|
+
} catch (error) {
|
|
71
|
+
dataValue = `\${${step.dataRef}}`;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const escapedVariable = dataValue.replace(/[.*+?^${}()|[\]\\/]/g, '\\$&');
|
|
75
|
+
|
|
76
|
+
if (resolved.strategy === 'locator') {
|
|
77
|
+
const code = context.templateEngine.renderStep('hidden-with-filter-assertion', {
|
|
78
|
+
...resolved, dataValue, nth: resolved.nth || 0,
|
|
79
|
+
});
|
|
80
|
+
return { code, comment: `Assert ${step.selectorRef} hidden with ${step.dataRef}` };
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (resolved.strategy === 'role' && resolved.role) {
|
|
84
|
+
const code = context.templateEngine.renderStep('hidden-with-role-variable-assertion', {
|
|
85
|
+
role: resolved.role,
|
|
86
|
+
name: resolved.name && resolved.name.trim() ? resolved.name : undefined,
|
|
87
|
+
dataValue,
|
|
88
|
+
nth: resolved.nth || 0,
|
|
89
|
+
});
|
|
90
|
+
return { code, comment: `Assert ${step.selectorRef} hidden with ${step.dataRef}` };
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const selectorValue = resolved.value || '';
|
|
94
|
+
if (selectorValue && selectorValue.trim()) {
|
|
95
|
+
const code = context.templateEngine.renderStep('hidden-with-filter-assertion', {
|
|
96
|
+
...resolved, dataValue, nth: resolved.nth || 0,
|
|
97
|
+
});
|
|
98
|
+
return { code, comment: `Assert ${step.selectorRef} hidden with ${step.dataRef}` };
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const code = context.templateEngine.renderStep('hidden-with-variable-assertion', {
|
|
102
|
+
selectorRef: step.selectorRef,
|
|
103
|
+
selectorValue: resolved.value || '',
|
|
104
|
+
dataValue,
|
|
105
|
+
nth: resolved.nth || 0,
|
|
106
|
+
});
|
|
107
|
+
return { code, comment: `Assert ${step.selectorRef} hidden with ${step.dataRef}` };
|
|
108
|
+
},
|
|
109
|
+
priority: 14,
|
|
110
|
+
},
|
|
111
|
+
// Pattern: Then User see [submit] button with {{label}} disabled -> toBeDisabled()
|
|
112
|
+
{
|
|
113
|
+
name: 'see-with-variable-disabled',
|
|
114
|
+
matcher: (step: ParsedStep) =>
|
|
115
|
+
(step.text.includes('should see') || step.text.match(/\b(see|sees)\s+\[/)) &&
|
|
116
|
+
!!step.selectorRef &&
|
|
117
|
+
!!step.dataRef &&
|
|
118
|
+
step.text.includes('with') &&
|
|
119
|
+
/\bis disabled\b/.test(step.text),
|
|
120
|
+
generator: (step, context) => {
|
|
121
|
+
let resolved: any = {};
|
|
122
|
+
try {
|
|
123
|
+
resolved = context.selectorResolver.resolveSelector(
|
|
124
|
+
step.selectorRef!,
|
|
125
|
+
context.featureName,
|
|
126
|
+
step.elementType,
|
|
127
|
+
step.nth
|
|
128
|
+
);
|
|
129
|
+
} catch (error) {}
|
|
130
|
+
|
|
131
|
+
let dataValue: string;
|
|
132
|
+
try {
|
|
133
|
+
dataValue = context.dataResolver.resolveData(step.dataRef!, context.featureName);
|
|
134
|
+
} catch (error) {
|
|
135
|
+
dataValue = `\${${step.dataRef}}`;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const escapedVariable = dataValue.replace(/[.*+?^${}()|[\]\\/]/g, '\\$&');
|
|
139
|
+
|
|
140
|
+
if (resolved.strategy === 'locator') {
|
|
141
|
+
const code = context.templateEngine.renderStep('disabled-with-filter-assertion', {
|
|
142
|
+
...resolved, dataValue, nth: resolved.nth || 0,
|
|
143
|
+
});
|
|
144
|
+
return { code, comment: `Assert ${step.selectorRef} disabled with ${step.dataRef}` };
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (resolved.strategy === 'role' && resolved.role) {
|
|
148
|
+
const code = context.templateEngine.renderStep('disabled-with-role-variable-assertion', {
|
|
149
|
+
role: resolved.role,
|
|
150
|
+
name: resolved.name && resolved.name.trim() ? resolved.name : undefined,
|
|
151
|
+
dataValue,
|
|
152
|
+
nth: resolved.nth || 0,
|
|
153
|
+
});
|
|
154
|
+
return { code, comment: `Assert ${step.selectorRef} disabled with ${step.dataRef}` };
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const selectorValue = resolved.value || '';
|
|
158
|
+
if (selectorValue && selectorValue.trim()) {
|
|
159
|
+
const code = context.templateEngine.renderStep('disabled-with-filter-assertion', {
|
|
160
|
+
...resolved, dataValue, nth: resolved.nth || 0,
|
|
161
|
+
});
|
|
162
|
+
return { code, comment: `Assert ${step.selectorRef} disabled with ${step.dataRef}` };
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const code = context.templateEngine.renderStep('disabled-with-variable-assertion', {
|
|
166
|
+
selectorRef: step.selectorRef,
|
|
167
|
+
selectorValue: resolved.value || '',
|
|
168
|
+
dataValue,
|
|
169
|
+
nth: resolved.nth || 0,
|
|
170
|
+
});
|
|
171
|
+
return { code, comment: `Assert ${step.selectorRef} disabled with ${step.dataRef}` };
|
|
172
|
+
},
|
|
173
|
+
priority: 14,
|
|
45
174
|
},
|
|
46
175
|
// NEW: Assertion with variable (handles both empty selector and static + variable)
|
|
47
176
|
// Pattern: Then User see [error] message with {{fail_message}}
|
|
@@ -61,8 +190,9 @@ export const assertionPatterns: StepPattern[] = [
|
|
|
61
190
|
try {
|
|
62
191
|
resolved = context.selectorResolver.resolveSelector(
|
|
63
192
|
step.selectorRef!,
|
|
64
|
-
context.featureName,
|
|
65
|
-
step.elementType
|
|
193
|
+
context.featureName,
|
|
194
|
+
step.elementType,
|
|
195
|
+
step.nth
|
|
66
196
|
);
|
|
67
197
|
} catch (error) {
|
|
68
198
|
// Selector not in YAML or context issue - will use variable-only
|
|
@@ -124,7 +254,10 @@ export const assertionPatterns: StepPattern[] = [
|
|
|
124
254
|
} else {
|
|
125
255
|
// Empty selector - use variable only
|
|
126
256
|
const code = context.templateEngine.renderStep('visible-with-variable-assertion', {
|
|
127
|
-
|
|
257
|
+
selectorRef: step.selectorRef,
|
|
258
|
+
selectorValue: resolved.value || '',
|
|
259
|
+
dataValue,
|
|
260
|
+
nth: resolved.nth || 0,
|
|
128
261
|
});
|
|
129
262
|
return {
|
|
130
263
|
code,
|
|
@@ -132,46 +265,7 @@ export const assertionPatterns: StepPattern[] = [
|
|
|
132
265
|
};
|
|
133
266
|
}
|
|
134
267
|
},
|
|
135
|
-
priority: 13,
|
|
136
|
-
},
|
|
137
|
-
{
|
|
138
|
-
name: 'should-be-visible-with-value',
|
|
139
|
-
matcher: (step: ParsedStep) =>
|
|
140
|
-
(step.text.includes('should see') ||
|
|
141
|
-
step.text.match(/\b(see|sees)\s+\[/)) &&
|
|
142
|
-
!!step.selectorRef &&
|
|
143
|
-
!!step.dataRef &&
|
|
144
|
-
step.text.includes('with'),
|
|
145
|
-
generator: (step, context) => {
|
|
146
|
-
const resolved = context.selectorResolver.resolveSelector(step.selectorRef!, undefined, step.elementType);
|
|
147
|
-
|
|
148
|
-
// Resolve the data value
|
|
149
|
-
let dataValue: string;
|
|
150
|
-
try {
|
|
151
|
-
dataValue = context.dataResolver.resolveData(step.dataRef!, context.featureName);
|
|
152
|
-
} catch (error) {
|
|
153
|
-
dataValue = `\${${step.dataRef}}`;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// Container types (row, list-item/listitem) use .filter({ hasText }) instead of regex
|
|
157
|
-
const filterTypes = ['row', 'listitem', 'list-item'];
|
|
158
|
-
const normalizedType = step.elementType || '';
|
|
159
|
-
const useFilter = filterTypes.includes(normalizedType) || filterTypes.includes(resolved.role || '');
|
|
160
|
-
|
|
161
|
-
// When using .filter({ hasText }), name is redundant — data value identifies the element
|
|
162
|
-
const templateData = useFilter
|
|
163
|
-
? { ...(() => { const { name: _n, ...rest } = resolved; return rest; })(), dataValue, dataRef: step.dataRef }
|
|
164
|
-
: { ...resolved, dataValue, dataRef: step.dataRef };
|
|
165
|
-
|
|
166
|
-
const templateName = useFilter ? 'visible-with-filter-assertion' : 'visible-with-value-assertion';
|
|
167
|
-
const code = context.templateEngine.renderStep(templateName, templateData);
|
|
168
|
-
|
|
169
|
-
return {
|
|
170
|
-
code,
|
|
171
|
-
comment: `Assert ${step.selectorRef} with value ${step.dataRef}`,
|
|
172
|
-
};
|
|
173
|
-
},
|
|
174
|
-
priority: 11, // Lower than see-with-variable (13) so variable-only pattern matches first
|
|
268
|
+
priority: 13,
|
|
175
269
|
},
|
|
176
270
|
{
|
|
177
271
|
name: 'should-be-visible',
|
|
@@ -182,7 +276,7 @@ export const assertionPatterns: StepPattern[] = [
|
|
|
182
276
|
step.text.match(/\b(see|sees)\s+\[/)) &&
|
|
183
277
|
!!step.selectorRef,
|
|
184
278
|
generator: (step, context) => {
|
|
185
|
-
const resolved = context.selectorResolver.resolveSelector(step.selectorRef!, undefined, step.elementType);
|
|
279
|
+
const resolved = context.selectorResolver.resolveSelector(step.selectorRef!, undefined, step.elementType, step.nth);
|
|
186
280
|
const code = context.templateEngine.renderStep('visible-assertion', { ...resolved, selectorRef: step.selectorRef });
|
|
187
281
|
return {
|
|
188
282
|
code,
|
|
@@ -192,15 +286,14 @@ export const assertionPatterns: StepPattern[] = [
|
|
|
192
286
|
priority: 10,
|
|
193
287
|
},
|
|
194
288
|
{
|
|
195
|
-
name: '
|
|
289
|
+
name: 'is-hidden',
|
|
290
|
+
// "see [target] is hidden" — no variable version; with-variable handled by see-with-variable-hidden
|
|
196
291
|
matcher: (step: ParsedStep) =>
|
|
197
|
-
(step.text
|
|
198
|
-
|
|
199
|
-
step.text.includes('should not see')) &&
|
|
200
|
-
!!step.selectorRef,
|
|
292
|
+
/\b(see|sees)\s+\[/.test(step.text) && /\bis hidden\b/.test(step.text) &&
|
|
293
|
+
!step.dataRef && !!step.selectorRef,
|
|
201
294
|
generator: (step, context) => {
|
|
202
|
-
const resolved = context.selectorResolver.resolveSelector(step.selectorRef!, undefined, step.elementType);
|
|
203
|
-
const code = context.templateEngine.renderStep('
|
|
295
|
+
const resolved = context.selectorResolver.resolveSelector(step.selectorRef!, undefined, step.elementType, step.nth);
|
|
296
|
+
const code = context.templateEngine.renderStep('is-hidden-assertion', { ...resolved, selectorRef: step.selectorRef });
|
|
204
297
|
return {
|
|
205
298
|
code,
|
|
206
299
|
comment: `Assert ${step.selectorRef} is not visible`,
|
|
@@ -211,37 +304,37 @@ export const assertionPatterns: StepPattern[] = [
|
|
|
211
304
|
{
|
|
212
305
|
name: 'should-be-enabled',
|
|
213
306
|
matcher: (step: ParsedStep) =>
|
|
214
|
-
step.text
|
|
307
|
+
/\b(see|sees)\s+\[/.test(step.text) && /\bis enabled\b/.test(step.text) && !!step.selectorRef,
|
|
215
308
|
generator: (step, context) => {
|
|
216
|
-
const resolved = context.selectorResolver.resolveSelector(step.selectorRef!, undefined, step.elementType);
|
|
309
|
+
const resolved = context.selectorResolver.resolveSelector(step.selectorRef!, undefined, step.elementType, step.nth);
|
|
217
310
|
const code = context.templateEngine.renderStep('enabled-assertion', { ...resolved, selectorRef: step.selectorRef });
|
|
218
311
|
return {
|
|
219
312
|
code,
|
|
220
313
|
comment: `Assert ${step.selectorRef} is enabled`,
|
|
221
314
|
};
|
|
222
315
|
},
|
|
223
|
-
priority:
|
|
316
|
+
priority: 11,
|
|
224
317
|
},
|
|
225
318
|
{
|
|
226
319
|
name: 'should-be-disabled',
|
|
227
320
|
matcher: (step: ParsedStep) =>
|
|
228
|
-
step.text
|
|
321
|
+
/\b(see|sees)\s+\[/.test(step.text) && /\bis disabled\b/.test(step.text) && !!step.selectorRef,
|
|
229
322
|
generator: (step, context) => {
|
|
230
|
-
const resolved = context.selectorResolver.resolveSelector(step.selectorRef!, undefined, step.elementType);
|
|
323
|
+
const resolved = context.selectorResolver.resolveSelector(step.selectorRef!, undefined, step.elementType, step.nth);
|
|
231
324
|
const code = context.templateEngine.renderStep('disabled-assertion', { ...resolved, selectorRef: step.selectorRef });
|
|
232
325
|
return {
|
|
233
326
|
code,
|
|
234
327
|
comment: `Assert ${step.selectorRef} is disabled`,
|
|
235
328
|
};
|
|
236
329
|
},
|
|
237
|
-
priority:
|
|
330
|
+
priority: 11,
|
|
238
331
|
},
|
|
239
332
|
{
|
|
240
333
|
name: 'should-contain-text',
|
|
241
334
|
matcher: (step: ParsedStep) =>
|
|
242
335
|
step.text.includes('should contain') && !!step.selectorRef && !!(step.value || step.dataRef),
|
|
243
336
|
generator: (step, context) => {
|
|
244
|
-
const resolved = context.selectorResolver.resolveSelector(step.selectorRef!, undefined, step.elementType);
|
|
337
|
+
const resolved = context.selectorResolver.resolveSelector(step.selectorRef!, undefined, step.elementType, step.nth);
|
|
245
338
|
const expectedText = step.value || `\${${step.dataRef}}`;
|
|
246
339
|
const code = context.templateEngine.renderStep('contain-text-assertion', {
|
|
247
340
|
...resolved,
|
|
@@ -259,7 +352,7 @@ export const assertionPatterns: StepPattern[] = [
|
|
|
259
352
|
matcher: (step: ParsedStep) =>
|
|
260
353
|
step.text.includes('should have text') && !!step.selectorRef && !!(step.value || step.dataRef),
|
|
261
354
|
generator: (step, context) => {
|
|
262
|
-
const resolved = context.selectorResolver.resolveSelector(step.selectorRef!, undefined, step.elementType);
|
|
355
|
+
const resolved = context.selectorResolver.resolveSelector(step.selectorRef!, undefined, step.elementType, step.nth);
|
|
263
356
|
const expectedText = step.value || `\${${step.dataRef}}`;
|
|
264
357
|
const code = context.templateEngine.renderStep('have-text-assertion', {
|
|
265
358
|
...resolved,
|
|
@@ -273,60 +366,60 @@ export const assertionPatterns: StepPattern[] = [
|
|
|
273
366
|
priority: 10,
|
|
274
367
|
},
|
|
275
368
|
{
|
|
276
|
-
name: '
|
|
369
|
+
name: 'is-empty',
|
|
277
370
|
matcher: (step: ParsedStep) =>
|
|
278
|
-
step.text
|
|
371
|
+
/\b(see|sees)\s+\[/.test(step.text) && /\bis empty\b/.test(step.text) && !!step.selectorRef,
|
|
279
372
|
generator: (step, context) => {
|
|
280
|
-
const resolved = context.selectorResolver.resolveSelector(step.selectorRef!, undefined, step.elementType);
|
|
373
|
+
const resolved = context.selectorResolver.resolveSelector(step.selectorRef!, undefined, step.elementType, step.nth);
|
|
281
374
|
const code = context.templateEngine.renderStep('empty-assertion', { ...resolved, selectorRef: step.selectorRef });
|
|
282
375
|
return {
|
|
283
376
|
code,
|
|
284
377
|
comment: `Assert ${step.selectorRef} is empty`,
|
|
285
378
|
};
|
|
286
379
|
},
|
|
287
|
-
priority:
|
|
380
|
+
priority: 11,
|
|
288
381
|
},
|
|
289
382
|
{
|
|
290
|
-
name: '
|
|
383
|
+
name: 'is-checked',
|
|
291
384
|
matcher: (step: ParsedStep) =>
|
|
292
|
-
step.text
|
|
385
|
+
/\b(see|sees)\s+\[/.test(step.text) && /\bis checked\b/.test(step.text) && !!step.selectorRef,
|
|
293
386
|
generator: (step, context) => {
|
|
294
|
-
const resolved = context.selectorResolver.resolveSelector(step.selectorRef!, undefined, step.elementType);
|
|
387
|
+
const resolved = context.selectorResolver.resolveSelector(step.selectorRef!, undefined, step.elementType, step.nth);
|
|
295
388
|
const code = context.templateEngine.renderStep('checked-assertion', { ...resolved, selectorRef: step.selectorRef });
|
|
296
389
|
return {
|
|
297
390
|
code,
|
|
298
391
|
comment: `Assert ${step.selectorRef} is checked`,
|
|
299
392
|
};
|
|
300
393
|
},
|
|
301
|
-
priority:
|
|
394
|
+
priority: 11,
|
|
302
395
|
},
|
|
303
396
|
{
|
|
304
|
-
name: '
|
|
397
|
+
name: 'is-unchecked',
|
|
305
398
|
matcher: (step: ParsedStep) =>
|
|
306
|
-
step.text
|
|
399
|
+
/\b(see|sees)\s+\[/.test(step.text) && /\bis unchecked\b/.test(step.text) && !!step.selectorRef,
|
|
307
400
|
generator: (step, context) => {
|
|
308
|
-
const resolved = context.selectorResolver.resolveSelector(step.selectorRef!, undefined, step.elementType);
|
|
401
|
+
const resolved = context.selectorResolver.resolveSelector(step.selectorRef!, undefined, step.elementType, step.nth);
|
|
309
402
|
const code = context.templateEngine.renderStep('not-checked-assertion', { ...resolved, selectorRef: step.selectorRef });
|
|
310
403
|
return {
|
|
311
404
|
code,
|
|
312
405
|
comment: `Assert ${step.selectorRef} is unchecked`,
|
|
313
406
|
};
|
|
314
407
|
},
|
|
315
|
-
priority:
|
|
408
|
+
priority: 11,
|
|
316
409
|
},
|
|
317
410
|
{
|
|
318
|
-
name: '
|
|
411
|
+
name: 'is-focused',
|
|
319
412
|
matcher: (step: ParsedStep) =>
|
|
320
|
-
step.text
|
|
413
|
+
/\b(see|sees)\s+\[/.test(step.text) && /\bis focused\b/.test(step.text) && !!step.selectorRef,
|
|
321
414
|
generator: (step, context) => {
|
|
322
|
-
const resolved = context.selectorResolver.resolveSelector(step.selectorRef!, undefined, step.elementType);
|
|
415
|
+
const resolved = context.selectorResolver.resolveSelector(step.selectorRef!, undefined, step.elementType, step.nth);
|
|
323
416
|
const code = context.templateEngine.renderStep('focused-assertion', { ...resolved, selectorRef: step.selectorRef });
|
|
324
417
|
return {
|
|
325
418
|
code,
|
|
326
419
|
comment: `Assert ${step.selectorRef} is focused`,
|
|
327
420
|
};
|
|
328
421
|
},
|
|
329
|
-
priority:
|
|
422
|
+
priority: 11,
|
|
330
423
|
},
|
|
331
424
|
{
|
|
332
425
|
name: 'see-data-text',
|
|
@@ -379,7 +472,7 @@ export const assertionPatterns: StepPattern[] = [
|
|
|
379
472
|
}
|
|
380
473
|
}
|
|
381
474
|
|
|
382
|
-
const resolved = context.selectorResolver.resolveSelector(step.selectorRef!, undefined, step.elementType);
|
|
475
|
+
const resolved = context.selectorResolver.resolveSelector(step.selectorRef!, undefined, step.elementType, step.nth);
|
|
383
476
|
const code = context.templateEngine.renderStep('list-item-count-assertion', {
|
|
384
477
|
...resolved,
|
|
385
478
|
expectedCount,
|
|
@@ -413,7 +506,7 @@ export const assertionPatterns: StepPattern[] = [
|
|
|
413
506
|
}
|
|
414
507
|
}
|
|
415
508
|
|
|
416
|
-
const resolved = context.selectorResolver.resolveSelector(step.selectorRef!, undefined, step.elementType);
|
|
509
|
+
const resolved = context.selectorResolver.resolveSelector(step.selectorRef!, undefined, step.elementType, step.nth);
|
|
417
510
|
const code = context.templateEngine.renderStep('count-assertion', {
|
|
418
511
|
...resolved,
|
|
419
512
|
expectedCount,
|
|
@@ -7,12 +7,46 @@ import { StepPattern } from './types';
|
|
|
7
7
|
* Resolvers return metadata, templates handle framework syntax
|
|
8
8
|
*/
|
|
9
9
|
export const formPatterns: StepPattern[] = [
|
|
10
|
+
{
|
|
11
|
+
name: 'upload-file',
|
|
12
|
+
matcher: (step: ParsedStep) =>
|
|
13
|
+
(step.text.includes('fill') || step.text.includes('fills')) &&
|
|
14
|
+
step.elementType === 'uploader' &&
|
|
15
|
+
!!step.selectorRef &&
|
|
16
|
+
!!(step.dataRef || step.value),
|
|
17
|
+
generator: (step, context) => {
|
|
18
|
+
const resolved = context.selectorResolver.resolveSelector(step.selectorRef!, undefined, step.elementType, step.nth);
|
|
19
|
+
|
|
20
|
+
let fileName: string;
|
|
21
|
+
if (step.dataRef) {
|
|
22
|
+
try {
|
|
23
|
+
fileName = context.dataResolver.resolveData(step.dataRef, context.featureName);
|
|
24
|
+
} catch (error) {
|
|
25
|
+
fileName = `\${${step.dataRef}}`;
|
|
26
|
+
}
|
|
27
|
+
} else {
|
|
28
|
+
fileName = step.value!;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const code = context.templateEngine.renderStep('upload-action', {
|
|
32
|
+
...resolved,
|
|
33
|
+
selectorRef: step.selectorRef,
|
|
34
|
+
fileName,
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
return {
|
|
38
|
+
code,
|
|
39
|
+
comment: `Upload file ${fileName} via ${step.selectorRef}`,
|
|
40
|
+
};
|
|
41
|
+
},
|
|
42
|
+
priority: 12,
|
|
43
|
+
},
|
|
10
44
|
{
|
|
11
45
|
name: 'fill-input',
|
|
12
46
|
matcher: (step: ParsedStep) =>
|
|
13
47
|
(step.text.includes('fills') || step.text.includes('fill') || step.text.includes('inputs') || step.text.includes('input')) && !!step.selectorRef && !!(step.dataRef || step.value),
|
|
14
48
|
generator: (step, context) => {
|
|
15
|
-
const resolved = context.selectorResolver.resolveSelector(step.selectorRef!, undefined, step.elementType);
|
|
49
|
+
const resolved = context.selectorResolver.resolveSelector(step.selectorRef!, undefined, step.elementType, step.nth);
|
|
16
50
|
|
|
17
51
|
// Resolve data reference to actual value
|
|
18
52
|
let value: string;
|
|
@@ -46,7 +80,7 @@ export const formPatterns: StepPattern[] = [
|
|
|
46
80
|
matcher: (step: ParsedStep) =>
|
|
47
81
|
step.text.includes('checks') && !!step.selectorRef,
|
|
48
82
|
generator: (step, context) => {
|
|
49
|
-
const resolved = context.selectorResolver.resolveSelector(step.selectorRef!, undefined, step.elementType);
|
|
83
|
+
const resolved = context.selectorResolver.resolveSelector(step.selectorRef!, undefined, step.elementType, step.nth);
|
|
50
84
|
|
|
51
85
|
const code = context.templateEngine.renderStep('check-action', { ...resolved, selectorRef: step.selectorRef });
|
|
52
86
|
|
|
@@ -62,7 +96,7 @@ export const formPatterns: StepPattern[] = [
|
|
|
62
96
|
matcher: (step: ParsedStep) =>
|
|
63
97
|
step.text.includes('unchecks') && !!step.selectorRef,
|
|
64
98
|
generator: (step, context) => {
|
|
65
|
-
const resolved = context.selectorResolver.resolveSelector(step.selectorRef!, undefined, step.elementType);
|
|
99
|
+
const resolved = context.selectorResolver.resolveSelector(step.selectorRef!, undefined, step.elementType, step.nth);
|
|
66
100
|
|
|
67
101
|
const code = context.templateEngine.renderStep('uncheck-action', { ...resolved, selectorRef: step.selectorRef });
|
|
68
102
|
|
|
@@ -80,7 +114,7 @@ export const formPatterns: StepPattern[] = [
|
|
|
80
114
|
!!step.selectorRef &&
|
|
81
115
|
!!(step.dataRef || step.value),
|
|
82
116
|
generator: (step, context) => {
|
|
83
|
-
const resolved = context.selectorResolver.resolveSelector(step.selectorRef!, undefined, step.elementType);
|
|
117
|
+
const resolved = context.selectorResolver.resolveSelector(step.selectorRef!, undefined, step.elementType, step.nth);
|
|
84
118
|
|
|
85
119
|
// Resolve data reference to actual value
|
|
86
120
|
let value: string;
|
|
@@ -130,7 +164,7 @@ export const formPatterns: StepPattern[] = [
|
|
|
130
164
|
matcher: (step: ParsedStep) =>
|
|
131
165
|
step.text.includes('clears') && !!step.selectorRef,
|
|
132
166
|
generator: (step, context) => {
|
|
133
|
-
const resolved = context.selectorResolver.resolveSelector(step.selectorRef!, undefined, step.elementType);
|
|
167
|
+
const resolved = context.selectorResolver.resolveSelector(step.selectorRef!, undefined, step.elementType, step.nth);
|
|
134
168
|
|
|
135
169
|
const code = context.templateEngine.renderStep('clear-action', { ...resolved, selectorRef: step.selectorRef });
|
|
136
170
|
|