@sun-asterisk/sungen 1.0.15 → 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 +2 -0
- package/dist/generators/gherkin-parser/index.d.ts.map +1 -1
- package/dist/generators/gherkin-parser/index.js +6 -1
- package/dist/generators/gherkin-parser/index.js.map +1 -1
- package/dist/generators/scaffold-generator/index.d.ts.map +1 -1
- package/dist/generators/scaffold-generator/index.js +7 -2
- 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/assertions/disabled-assertion.hbs +1 -2
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/disabled-with-role-variable-assertion.hbs +5 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/disabled-with-variable-assertion.hbs +1 -1
- 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-role-variable-assertion.hbs +5 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/hidden-with-variable-assertion.hbs +1 -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/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/partials/locator-strategies/testid.hbs +1 -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 +34 -62
- package/dist/generators/test-generator/patterns/assertion-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 +8 -11
- package/dist/generators/test-generator/patterns/interaction-patterns.js.map +1 -1
- package/dist/generators/test-generator/template-engine.d.ts.map +1 -1
- package/dist/generators/test-generator/template-engine.js +6 -2
- package/dist/generators/test-generator/template-engine.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 +5 -3
- package/dist/generators/test-generator/utils/selector-resolver.js.map +1 -1
- package/dist/input/cli-adapter.js +1 -1
- package/package.json +1 -1
- package/src/generators/cli.ts +1 -1
- package/src/generators/gherkin-parser/index.ts +8 -1
- package/src/generators/scaffold-generator/index.ts +7 -2
- 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/assertions/disabled-assertion.hbs +1 -2
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/disabled-with-role-variable-assertion.hbs +5 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/disabled-with-variable-assertion.hbs +1 -1
- 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-role-variable-assertion.hbs +5 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/hidden-with-variable-assertion.hbs +1 -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/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/partials/locator-strategies/testid.hbs +1 -1
- package/src/generators/test-generator/code-generator.ts +70 -15
- package/src/generators/test-generator/patterns/assertion-patterns.ts +34 -67
- package/src/generators/test-generator/patterns/interaction-patterns.ts +8 -13
- package/src/generators/test-generator/template-engine.ts +4 -2
- package/src/generators/test-generator/utils/selector-resolver.ts +5 -3
- package/src/input/cli-adapter.ts +1 -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
|
@@ -52,7 +52,7 @@ export const assertionPatterns: StepPattern[] = [
|
|
|
52
52
|
!!step.selectorRef &&
|
|
53
53
|
!!step.dataRef &&
|
|
54
54
|
step.text.includes('with') &&
|
|
55
|
-
/\
|
|
55
|
+
/\bis hidden\b/.test(step.text),
|
|
56
56
|
generator: (step, context) => {
|
|
57
57
|
let resolved: any = {};
|
|
58
58
|
try {
|
|
@@ -99,8 +99,10 @@ export const assertionPatterns: StepPattern[] = [
|
|
|
99
99
|
}
|
|
100
100
|
|
|
101
101
|
const code = context.templateEngine.renderStep('hidden-with-variable-assertion', {
|
|
102
|
-
variable: escapedVariable,
|
|
103
102
|
selectorRef: step.selectorRef,
|
|
103
|
+
selectorValue: resolved.value || '',
|
|
104
|
+
dataValue,
|
|
105
|
+
nth: resolved.nth || 0,
|
|
104
106
|
});
|
|
105
107
|
return { code, comment: `Assert ${step.selectorRef} hidden with ${step.dataRef}` };
|
|
106
108
|
},
|
|
@@ -114,7 +116,7 @@ export const assertionPatterns: StepPattern[] = [
|
|
|
114
116
|
!!step.selectorRef &&
|
|
115
117
|
!!step.dataRef &&
|
|
116
118
|
step.text.includes('with') &&
|
|
117
|
-
/\
|
|
119
|
+
/\bis disabled\b/.test(step.text),
|
|
118
120
|
generator: (step, context) => {
|
|
119
121
|
let resolved: any = {};
|
|
120
122
|
try {
|
|
@@ -161,8 +163,10 @@ export const assertionPatterns: StepPattern[] = [
|
|
|
161
163
|
}
|
|
162
164
|
|
|
163
165
|
const code = context.templateEngine.renderStep('disabled-with-variable-assertion', {
|
|
164
|
-
variable: escapedVariable,
|
|
165
166
|
selectorRef: step.selectorRef,
|
|
167
|
+
selectorValue: resolved.value || '',
|
|
168
|
+
dataValue,
|
|
169
|
+
nth: resolved.nth || 0,
|
|
166
170
|
});
|
|
167
171
|
return { code, comment: `Assert ${step.selectorRef} disabled with ${step.dataRef}` };
|
|
168
172
|
},
|
|
@@ -250,7 +254,10 @@ export const assertionPatterns: StepPattern[] = [
|
|
|
250
254
|
} else {
|
|
251
255
|
// Empty selector - use variable only
|
|
252
256
|
const code = context.templateEngine.renderStep('visible-with-variable-assertion', {
|
|
253
|
-
|
|
257
|
+
selectorRef: step.selectorRef,
|
|
258
|
+
selectorValue: resolved.value || '',
|
|
259
|
+
dataValue,
|
|
260
|
+
nth: resolved.nth || 0,
|
|
254
261
|
});
|
|
255
262
|
return {
|
|
256
263
|
code,
|
|
@@ -258,46 +265,7 @@ export const assertionPatterns: StepPattern[] = [
|
|
|
258
265
|
};
|
|
259
266
|
}
|
|
260
267
|
},
|
|
261
|
-
priority: 13,
|
|
262
|
-
},
|
|
263
|
-
{
|
|
264
|
-
name: 'should-be-visible-with-value',
|
|
265
|
-
matcher: (step: ParsedStep) =>
|
|
266
|
-
(step.text.includes('should see') ||
|
|
267
|
-
step.text.match(/\b(see|sees)\s+\[/)) &&
|
|
268
|
-
!!step.selectorRef &&
|
|
269
|
-
!!step.dataRef &&
|
|
270
|
-
step.text.includes('with'),
|
|
271
|
-
generator: (step, context) => {
|
|
272
|
-
const resolved = context.selectorResolver.resolveSelector(step.selectorRef!, undefined, step.elementType, step.nth);
|
|
273
|
-
|
|
274
|
-
// Resolve the data value
|
|
275
|
-
let dataValue: string;
|
|
276
|
-
try {
|
|
277
|
-
dataValue = context.dataResolver.resolveData(step.dataRef!, context.featureName);
|
|
278
|
-
} catch (error) {
|
|
279
|
-
dataValue = `\${${step.dataRef}}`;
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
// Container types (row, list-item/listitem) use .filter({ hasText }) instead of regex
|
|
283
|
-
const filterTypes = ['row', 'listitem', 'list-item'];
|
|
284
|
-
const normalizedType = step.elementType || '';
|
|
285
|
-
const useFilter = filterTypes.includes(normalizedType) || filterTypes.includes(resolved.role || '');
|
|
286
|
-
|
|
287
|
-
// When using .filter({ hasText }), name is redundant — data value identifies the element
|
|
288
|
-
const templateData = useFilter
|
|
289
|
-
? { ...(() => { const { name: _n, ...rest } = resolved; return rest; })(), dataValue, dataRef: step.dataRef }
|
|
290
|
-
: { ...resolved, dataValue, dataRef: step.dataRef };
|
|
291
|
-
|
|
292
|
-
const templateName = useFilter ? 'visible-with-filter-assertion' : 'visible-with-value-assertion';
|
|
293
|
-
const code = context.templateEngine.renderStep(templateName, templateData);
|
|
294
|
-
|
|
295
|
-
return {
|
|
296
|
-
code,
|
|
297
|
-
comment: `Assert ${step.selectorRef} with value ${step.dataRef}`,
|
|
298
|
-
};
|
|
299
|
-
},
|
|
300
|
-
priority: 11, // Lower than see-with-variable (13) so variable-only pattern matches first
|
|
268
|
+
priority: 13,
|
|
301
269
|
},
|
|
302
270
|
{
|
|
303
271
|
name: 'should-be-visible',
|
|
@@ -318,15 +286,14 @@ export const assertionPatterns: StepPattern[] = [
|
|
|
318
286
|
priority: 10,
|
|
319
287
|
},
|
|
320
288
|
{
|
|
321
|
-
name: '
|
|
289
|
+
name: 'is-hidden',
|
|
290
|
+
// "see [target] is hidden" — no variable version; with-variable handled by see-with-variable-hidden
|
|
322
291
|
matcher: (step: ParsedStep) =>
|
|
323
|
-
(step.text
|
|
324
|
-
|
|
325
|
-
step.text.includes('should not see')) &&
|
|
326
|
-
!!step.selectorRef,
|
|
292
|
+
/\b(see|sees)\s+\[/.test(step.text) && /\bis hidden\b/.test(step.text) &&
|
|
293
|
+
!step.dataRef && !!step.selectorRef,
|
|
327
294
|
generator: (step, context) => {
|
|
328
295
|
const resolved = context.selectorResolver.resolveSelector(step.selectorRef!, undefined, step.elementType, step.nth);
|
|
329
|
-
const code = context.templateEngine.renderStep('
|
|
296
|
+
const code = context.templateEngine.renderStep('is-hidden-assertion', { ...resolved, selectorRef: step.selectorRef });
|
|
330
297
|
return {
|
|
331
298
|
code,
|
|
332
299
|
comment: `Assert ${step.selectorRef} is not visible`,
|
|
@@ -337,7 +304,7 @@ export const assertionPatterns: StepPattern[] = [
|
|
|
337
304
|
{
|
|
338
305
|
name: 'should-be-enabled',
|
|
339
306
|
matcher: (step: ParsedStep) =>
|
|
340
|
-
step.text
|
|
307
|
+
/\b(see|sees)\s+\[/.test(step.text) && /\bis enabled\b/.test(step.text) && !!step.selectorRef,
|
|
341
308
|
generator: (step, context) => {
|
|
342
309
|
const resolved = context.selectorResolver.resolveSelector(step.selectorRef!, undefined, step.elementType, step.nth);
|
|
343
310
|
const code = context.templateEngine.renderStep('enabled-assertion', { ...resolved, selectorRef: step.selectorRef });
|
|
@@ -346,12 +313,12 @@ export const assertionPatterns: StepPattern[] = [
|
|
|
346
313
|
comment: `Assert ${step.selectorRef} is enabled`,
|
|
347
314
|
};
|
|
348
315
|
},
|
|
349
|
-
priority:
|
|
316
|
+
priority: 11,
|
|
350
317
|
},
|
|
351
318
|
{
|
|
352
319
|
name: 'should-be-disabled',
|
|
353
320
|
matcher: (step: ParsedStep) =>
|
|
354
|
-
step.text
|
|
321
|
+
/\b(see|sees)\s+\[/.test(step.text) && /\bis disabled\b/.test(step.text) && !!step.selectorRef,
|
|
355
322
|
generator: (step, context) => {
|
|
356
323
|
const resolved = context.selectorResolver.resolveSelector(step.selectorRef!, undefined, step.elementType, step.nth);
|
|
357
324
|
const code = context.templateEngine.renderStep('disabled-assertion', { ...resolved, selectorRef: step.selectorRef });
|
|
@@ -360,7 +327,7 @@ export const assertionPatterns: StepPattern[] = [
|
|
|
360
327
|
comment: `Assert ${step.selectorRef} is disabled`,
|
|
361
328
|
};
|
|
362
329
|
},
|
|
363
|
-
priority:
|
|
330
|
+
priority: 11,
|
|
364
331
|
},
|
|
365
332
|
{
|
|
366
333
|
name: 'should-contain-text',
|
|
@@ -399,9 +366,9 @@ export const assertionPatterns: StepPattern[] = [
|
|
|
399
366
|
priority: 10,
|
|
400
367
|
},
|
|
401
368
|
{
|
|
402
|
-
name: '
|
|
369
|
+
name: 'is-empty',
|
|
403
370
|
matcher: (step: ParsedStep) =>
|
|
404
|
-
step.text
|
|
371
|
+
/\b(see|sees)\s+\[/.test(step.text) && /\bis empty\b/.test(step.text) && !!step.selectorRef,
|
|
405
372
|
generator: (step, context) => {
|
|
406
373
|
const resolved = context.selectorResolver.resolveSelector(step.selectorRef!, undefined, step.elementType, step.nth);
|
|
407
374
|
const code = context.templateEngine.renderStep('empty-assertion', { ...resolved, selectorRef: step.selectorRef });
|
|
@@ -410,12 +377,12 @@ export const assertionPatterns: StepPattern[] = [
|
|
|
410
377
|
comment: `Assert ${step.selectorRef} is empty`,
|
|
411
378
|
};
|
|
412
379
|
},
|
|
413
|
-
priority:
|
|
380
|
+
priority: 11,
|
|
414
381
|
},
|
|
415
382
|
{
|
|
416
|
-
name: '
|
|
383
|
+
name: 'is-checked',
|
|
417
384
|
matcher: (step: ParsedStep) =>
|
|
418
|
-
step.text
|
|
385
|
+
/\b(see|sees)\s+\[/.test(step.text) && /\bis checked\b/.test(step.text) && !!step.selectorRef,
|
|
419
386
|
generator: (step, context) => {
|
|
420
387
|
const resolved = context.selectorResolver.resolveSelector(step.selectorRef!, undefined, step.elementType, step.nth);
|
|
421
388
|
const code = context.templateEngine.renderStep('checked-assertion', { ...resolved, selectorRef: step.selectorRef });
|
|
@@ -424,12 +391,12 @@ export const assertionPatterns: StepPattern[] = [
|
|
|
424
391
|
comment: `Assert ${step.selectorRef} is checked`,
|
|
425
392
|
};
|
|
426
393
|
},
|
|
427
|
-
priority:
|
|
394
|
+
priority: 11,
|
|
428
395
|
},
|
|
429
396
|
{
|
|
430
|
-
name: '
|
|
397
|
+
name: 'is-unchecked',
|
|
431
398
|
matcher: (step: ParsedStep) =>
|
|
432
|
-
step.text
|
|
399
|
+
/\b(see|sees)\s+\[/.test(step.text) && /\bis unchecked\b/.test(step.text) && !!step.selectorRef,
|
|
433
400
|
generator: (step, context) => {
|
|
434
401
|
const resolved = context.selectorResolver.resolveSelector(step.selectorRef!, undefined, step.elementType, step.nth);
|
|
435
402
|
const code = context.templateEngine.renderStep('not-checked-assertion', { ...resolved, selectorRef: step.selectorRef });
|
|
@@ -438,12 +405,12 @@ export const assertionPatterns: StepPattern[] = [
|
|
|
438
405
|
comment: `Assert ${step.selectorRef} is unchecked`,
|
|
439
406
|
};
|
|
440
407
|
},
|
|
441
|
-
priority:
|
|
408
|
+
priority: 11,
|
|
442
409
|
},
|
|
443
410
|
{
|
|
444
|
-
name: '
|
|
411
|
+
name: 'is-focused',
|
|
445
412
|
matcher: (step: ParsedStep) =>
|
|
446
|
-
step.text
|
|
413
|
+
/\b(see|sees)\s+\[/.test(step.text) && /\bis focused\b/.test(step.text) && !!step.selectorRef,
|
|
447
414
|
generator: (step, context) => {
|
|
448
415
|
const resolved = context.selectorResolver.resolveSelector(step.selectorRef!, undefined, step.elementType, step.nth);
|
|
449
416
|
const code = context.templateEngine.renderStep('focused-assertion', { ...resolved, selectorRef: step.selectorRef });
|
|
@@ -452,7 +419,7 @@ export const assertionPatterns: StepPattern[] = [
|
|
|
452
419
|
comment: `Assert ${step.selectorRef} is focused`,
|
|
453
420
|
};
|
|
454
421
|
},
|
|
455
|
-
priority:
|
|
422
|
+
priority: 11,
|
|
456
423
|
},
|
|
457
424
|
{
|
|
458
425
|
name: 'see-data-text',
|
|
@@ -32,11 +32,11 @@ function elementKeywordToRole(text: string): string | null {
|
|
|
32
32
|
* Uses template engine for framework-agnostic code generation
|
|
33
33
|
*/
|
|
34
34
|
export const interactionPatterns: StepPattern[] = [
|
|
35
|
-
//
|
|
35
|
+
// Unknown element with variable pattern (selector value is empty, identified by filter)
|
|
36
36
|
// Matches: "When User click [target order] row with {{order_name}}"
|
|
37
|
-
// Generates: await page.getByText(
|
|
37
|
+
// Generates: await page.getByText('').filter({ hasText: /.*value of order_name$/ }).click();
|
|
38
38
|
{
|
|
39
|
-
name: '
|
|
39
|
+
name: 'unknown-element-action',
|
|
40
40
|
matcher: (step: ParsedStep) => {
|
|
41
41
|
// Check if selectorRef starts with "target " (target element indicator)
|
|
42
42
|
const isTargetElement = step.selectorRef && /^target\s/i.test(step.selectorRef);
|
|
@@ -71,8 +71,6 @@ export const interactionPatterns: StepPattern[] = [
|
|
|
71
71
|
dataValue = `\${${step.dataRef}}`;
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
const escapedVariable = dataValue.replace(/[.*+?^${}()|[\]\\/]/g, '\\$&');
|
|
75
|
-
|
|
76
74
|
// Determine the action method (click, hover, etc.)
|
|
77
75
|
let actionMethod = 'click';
|
|
78
76
|
if (step.text.includes('hover')) {
|
|
@@ -81,13 +79,9 @@ export const interactionPatterns: StepPattern[] = [
|
|
|
81
79
|
actionMethod = 'dblclick';
|
|
82
80
|
}
|
|
83
81
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
: `.*${escapedVariable}`;
|
|
88
|
-
|
|
89
|
-
const code = context.templateEngine.renderStep('target-element-action', {
|
|
90
|
-
pattern: regexPattern,
|
|
82
|
+
const code = context.templateEngine.renderStep('unknown-element-action', {
|
|
83
|
+
selectorValue,
|
|
84
|
+
dataValue,
|
|
91
85
|
action: actionMethod,
|
|
92
86
|
nth,
|
|
93
87
|
});
|
|
@@ -156,7 +150,8 @@ export const interactionPatterns: StepPattern[] = [
|
|
|
156
150
|
{
|
|
157
151
|
name: 'double-click',
|
|
158
152
|
matcher: (step: ParsedStep) =>
|
|
159
|
-
step.text.includes('double')
|
|
153
|
+
(step.text.includes('double click') || step.text.includes('double-click') ||
|
|
154
|
+
(step.text.includes('double') && step.text.includes('clicks'))) && !!step.selectorRef,
|
|
160
155
|
generator: (step, context) => {
|
|
161
156
|
const resolved = context.selectorResolver.resolveSelector(step.selectorRef!, undefined, step.elementType, step.nth);
|
|
162
157
|
|
|
@@ -22,11 +22,13 @@ export class TemplateEngine {
|
|
|
22
22
|
});
|
|
23
23
|
|
|
24
24
|
Handlebars.registerHelper('escapeQuotes', function(text: string) {
|
|
25
|
-
|
|
25
|
+
if (text == null) return '';
|
|
26
|
+
return String(text).replace(/'/g, "\\'");
|
|
26
27
|
});
|
|
27
28
|
|
|
28
29
|
Handlebars.registerHelper('escapeRegex', function(text: string) {
|
|
29
|
-
|
|
30
|
+
if (text == null) return '';
|
|
31
|
+
return String(text).replace(/[.*+?^${}()|[\]\\/]/g, '\\$&');
|
|
30
32
|
});
|
|
31
33
|
|
|
32
34
|
// Comparison helpers for conditional logic
|
|
@@ -283,7 +283,7 @@ export class SelectorResolver {
|
|
|
283
283
|
* NOTE: textbox/textarea must precede "text" to prevent partial matching.
|
|
284
284
|
*/
|
|
285
285
|
static extractNthFromStep(afterElement: string): number {
|
|
286
|
-
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)?\s*(\d+)\b/i;
|
|
286
|
+
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;
|
|
287
287
|
const match = nthRegex.exec(afterElement);
|
|
288
288
|
return match ? parseInt(match[1], 10) : 0;
|
|
289
289
|
}
|
|
@@ -348,6 +348,7 @@ export class SelectorResolver {
|
|
|
348
348
|
'row': () => ({ strategy: 'role', role: 'row', name: label, value: 'row', nth: 0 }),
|
|
349
349
|
'table': () => ({ strategy: 'role', role: 'table', name: label, value: 'table', nth: 0 }),
|
|
350
350
|
'columnheader': () => ({ strategy: 'role', role: 'columnheader', name: label, value: 'columnheader', nth: 0 }),
|
|
351
|
+
'heading': () => ({ strategy: 'role', role: 'heading', name: label, value: 'heading', nth: 0 }),
|
|
351
352
|
'list': () => ({ strategy: 'role', role: 'list', name: label, value: 'list', nth: 0 }),
|
|
352
353
|
'listitem': () => ({ strategy: 'role', role: 'listitem', value: 'listitem', nth: 0 }),
|
|
353
354
|
};
|
|
@@ -366,9 +367,10 @@ export class SelectorResolver {
|
|
|
366
367
|
// Text-like aliases → "text"
|
|
367
368
|
'title': 'text',
|
|
368
369
|
'label': 'text',
|
|
369
|
-
'heading': 'text',
|
|
370
|
-
'header': 'text',
|
|
371
370
|
'caption': 'text',
|
|
371
|
+
// Heading aliases → "heading" (role-based)
|
|
372
|
+
'heading': 'heading',
|
|
373
|
+
'header': 'heading',
|
|
372
374
|
'message': 'text',
|
|
373
375
|
// Table-related aliases
|
|
374
376
|
'column': 'columnheader',
|
package/src/input/cli-adapter.ts
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
await page.getByText(/{{pattern}}/i{{#if (shouldUseExact selectorRef)}}, { exact: true }{{/if}}){{#if (gt nth 0)}}.nth({{subtract nth 1}}){{/if}}.{{action}}();
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
await expect({{> locator}}).not.toBeVisible();
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
await expect({{> locator-base}}.filter({ hasText: '{{escapeQuotes dataValue}}' }){{> locator-nth}}).toBeVisible();
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
await page.goto('{{path}}');
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
await page.getByText(/{{pattern}}/i{{#if (shouldUseExact selectorRef)}}, { exact: true }{{/if}}){{#if (gt nth 0)}}.nth({{subtract nth 1}}){{/if}}.{{action}}();
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
await expect({{> locator}}).not.toBeVisible();
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
await expect({{> locator-base}}.filter({ hasText: '{{escapeQuotes dataValue}}' }){{> locator-nth}}).toBeVisible();
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
await page.goto('{{path}}');
|