@sungen/driver-ui 3.2.21 → 3.2.22-beta.2
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sungen/driver-ui",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.22-beta.2",
|
|
4
4
|
"description": "Sungen UI capability (Playwright) — step patterns, viewpoint gate, and phase hooks. Plugs into @sun-asterisk/sungen via the capability SPI.",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"types": "src/index.ts",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"author": "eqe team (engineer & quality) — Sun Asterisk",
|
|
14
14
|
"license": "MIT",
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@sun-asterisk/sungen": "3.2.
|
|
16
|
+
"@sun-asterisk/sungen": "3.2.22-beta.2"
|
|
17
17
|
},
|
|
18
18
|
"peerDependencies": {
|
|
19
19
|
"@playwright/test": "^1.57.0"
|
|
@@ -125,8 +125,15 @@ export const capturePatterns: StepPattern[] = [
|
|
|
125
125
|
selectorRef: step.selectorRef,
|
|
126
126
|
childRef: step.childRef,
|
|
127
127
|
stepCounter: sc,
|
|
128
|
-
//
|
|
129
|
-
|
|
128
|
+
// C4 — plain variable NAMES only, no built locator expression. `.nth()` is a
|
|
129
|
+
// Playwright-only method; baking it into a string here (as the driver-agnostic
|
|
130
|
+
// pattern layer) leaked into the Appium output. Each adapter's own
|
|
131
|
+
// all-contain-element template composes its own per-index child chain
|
|
132
|
+
// (Playwright: `{{containerVar}}.nth({{containerIndexVar}})`; Appium:
|
|
133
|
+
// `{{containerVar}}[{{containerIndexVar}}]`).
|
|
134
|
+
containerVar: `__cards_${sc}`,
|
|
135
|
+
containerIndexVar: `__i_${sc}`,
|
|
136
|
+
child,
|
|
130
137
|
},
|
|
131
138
|
comment: `Assert all ${step.selectorRef} contain [${step.childRef}]`,
|
|
132
139
|
};
|
|
@@ -561,7 +561,7 @@ export const interactionPatterns: StepPattern[] = [
|
|
|
561
561
|
if (!allRefs || allRefs.length < 2) {
|
|
562
562
|
return {
|
|
563
563
|
templateName: 'drag-action',
|
|
564
|
-
data: { strategy: 'text', value: step.selectorRef,
|
|
564
|
+
data: { strategy: 'text', value: step.selectorRef, targetStrategy: 'locator', targetValue: 'TODO' },
|
|
565
565
|
comment: `Drag ${step.selectorRef} (missing target)`,
|
|
566
566
|
};
|
|
567
567
|
}
|
|
@@ -571,30 +571,20 @@ export const interactionPatterns: StepPattern[] = [
|
|
|
571
571
|
const sourceResolved = context.selectorResolver.resolveSelector(sourceRef, undefined, step.elementType, step.nth);
|
|
572
572
|
const targetResolved = context.selectorResolver.resolveSelector(targetRef, undefined, undefined, 0);
|
|
573
573
|
|
|
574
|
-
//
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
targetLocator = targetResolved.name
|
|
579
|
-
? `page.getByRole('${targetResolved.role}', { name: '${targetResolved.name}' })`
|
|
580
|
-
: `page.getByRole('${targetResolved.role}')`;
|
|
581
|
-
break;
|
|
582
|
-
case 'testid':
|
|
583
|
-
targetLocator = `page.getByTestId('${targetResolved.value}')`;
|
|
584
|
-
break;
|
|
585
|
-
case 'text':
|
|
586
|
-
targetLocator = `page.getByText('${targetResolved.value}')`;
|
|
587
|
-
break;
|
|
588
|
-
case 'locator':
|
|
589
|
-
targetLocator = `page.locator('${targetResolved.value}')`;
|
|
590
|
-
break;
|
|
591
|
-
default:
|
|
592
|
-
targetLocator = `page.getByText('${targetRef}')`;
|
|
593
|
-
}
|
|
594
|
-
|
|
574
|
+
// C3 — pass the resolved TARGET selector FIELDS, not a built Playwright locator string.
|
|
575
|
+
// Each adapter's own drag-action template renders the target locator for its own
|
|
576
|
+
// framework (Playwright: page.getByRole/getByText/...; Appium: an accessibility-id/xpath
|
|
577
|
+
// $() lookup — it already consumes this exact shape).
|
|
595
578
|
return {
|
|
596
579
|
templateName: 'drag-action',
|
|
597
|
-
data: {
|
|
580
|
+
data: {
|
|
581
|
+
...sourceResolved,
|
|
582
|
+
targetStrategy: targetResolved.strategy,
|
|
583
|
+
targetValue: targetResolved.value,
|
|
584
|
+
targetName: targetResolved.name,
|
|
585
|
+
targetRole: targetResolved.role,
|
|
586
|
+
targetRef,
|
|
587
|
+
},
|
|
598
588
|
comment: `Drag ${sourceRef} to ${targetRef}`,
|
|
599
589
|
};
|
|
600
590
|
},
|
|
@@ -113,6 +113,40 @@ export const tablePatterns: StepPattern[] = [
|
|
|
113
113
|
priority: 16,
|
|
114
114
|
},
|
|
115
115
|
|
|
116
|
+
// "User see [Result Row] row with {{n}}" — COUNT of matching rows (#575 field report).
|
|
117
|
+
// Every doc layer (Pattern 5, the gherkin-syntax skill's "# 7. Count") promises this
|
|
118
|
+
// form counts, and authors write it meaning a count ("40 results after load-more") —
|
|
119
|
+
// but it fell through to see-with-variable and compiled to toHaveText('40') against
|
|
120
|
+
// the row's ENTIRE text: a test that can essentially never pass, emitted silently.
|
|
121
|
+
// The value decides: a numeric base value is a count; any other value keeps the text
|
|
122
|
+
// semantics (asserting a row's full text equals a bare number is no real intent).
|
|
123
|
+
// `row in [Table] table with` (row scope/exists) and `is hidden` stay untouched.
|
|
124
|
+
{
|
|
125
|
+
name: 'row-count',
|
|
126
|
+
matcher: (step) => {
|
|
127
|
+
return step.elementType === 'row' &&
|
|
128
|
+
/\brow\s+with\b/i.test(step.text) &&
|
|
129
|
+
!!step.dataRef && !!step.selectorRef &&
|
|
130
|
+
!/\bin\b.*\btable\b/i.test(step.text) &&
|
|
131
|
+
!/\bis\s+hidden\b/i.test(step.text);
|
|
132
|
+
},
|
|
133
|
+
resolver: (step, context) => {
|
|
134
|
+
// Decide by the BASE literal (runtime mode returns an opaque marker from resolveData).
|
|
135
|
+
const base = context.dataResolver.peekBaseValue?.(step.dataRef!, context.featureName);
|
|
136
|
+
if (base === undefined || !/^\d+$/.test(String(base).trim())) return null as any; // not numeric → fall through to text semantics
|
|
137
|
+
const resolved = context.selectorResolver.resolveSelector(
|
|
138
|
+
step.selectorRef!, context.featureName, 'row', step.nth
|
|
139
|
+
);
|
|
140
|
+
const count = context.dataResolver.resolveData(step.dataRef!, context.featureName);
|
|
141
|
+
return {
|
|
142
|
+
templateName: 'count-assertion',
|
|
143
|
+
data: { ...resolved, expectedCount: count },
|
|
144
|
+
comment: `Assert ${step.selectorRef} row count is ${count}`,
|
|
145
|
+
};
|
|
146
|
+
},
|
|
147
|
+
priority: 18, // above see-with-variable (14) — the count reading wins for numeric values
|
|
148
|
+
},
|
|
149
|
+
|
|
116
150
|
// "User see [Ref] row in [Table] table with {{value}}" — row exists (enters row scope)
|
|
117
151
|
{
|
|
118
152
|
name: 'table-row-exists',
|