@sungen/driver-ui 3.2.34 → 3.3.0-alpha.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/dist/app-profile-presets.d.ts +12 -0
- package/dist/app-profile-presets.d.ts.map +1 -0
- package/dist/app-profile-presets.js +85 -0
- package/dist/app-profile-presets.js.map +1 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +93 -0
- package/dist/index.js.map +1 -0
- package/dist/patterns/assertion-patterns.d.ts +13 -0
- package/dist/patterns/assertion-patterns.d.ts.map +1 -0
- package/dist/patterns/assertion-patterns.js +903 -0
- package/dist/patterns/assertion-patterns.js.map +1 -0
- package/dist/patterns/capture-patterns.d.ts +21 -0
- package/dist/patterns/capture-patterns.d.ts.map +1 -0
- package/dist/patterns/capture-patterns.js +174 -0
- package/dist/patterns/capture-patterns.js.map +1 -0
- package/dist/patterns/focus-patterns.d.ts +22 -0
- package/dist/patterns/focus-patterns.d.ts.map +1 -0
- package/dist/patterns/focus-patterns.js +79 -0
- package/dist/patterns/focus-patterns.js.map +1 -0
- package/dist/patterns/form-patterns.d.ts +6 -0
- package/dist/patterns/form-patterns.d.ts.map +1 -0
- package/dist/patterns/form-patterns.js +239 -0
- package/dist/patterns/form-patterns.js.map +1 -0
- package/dist/patterns/interaction-patterns.d.ts +20 -0
- package/dist/patterns/interaction-patterns.d.ts.map +1 -0
- package/dist/patterns/interaction-patterns.js +633 -0
- package/dist/patterns/interaction-patterns.js.map +1 -0
- package/dist/patterns/keyboard-patterns.d.ts +7 -0
- package/dist/patterns/keyboard-patterns.d.ts.map +1 -0
- package/dist/patterns/keyboard-patterns.js +57 -0
- package/dist/patterns/keyboard-patterns.js.map +1 -0
- package/dist/patterns/navigation-patterns.d.ts +6 -0
- package/dist/patterns/navigation-patterns.d.ts.map +1 -0
- package/dist/patterns/navigation-patterns.js +185 -0
- package/dist/patterns/navigation-patterns.js.map +1 -0
- package/dist/patterns/scope-patterns.d.ts +7 -0
- package/dist/patterns/scope-patterns.d.ts.map +1 -0
- package/dist/patterns/scope-patterns.js +36 -0
- package/dist/patterns/scope-patterns.js.map +1 -0
- package/dist/patterns/scroll-patterns.d.ts +7 -0
- package/dist/patterns/scroll-patterns.d.ts.map +1 -0
- package/dist/patterns/scroll-patterns.js +25 -0
- package/dist/patterns/scroll-patterns.js.map +1 -0
- package/dist/patterns/setup-patterns.d.ts +6 -0
- package/dist/patterns/setup-patterns.d.ts.map +1 -0
- package/dist/patterns/setup-patterns.js +75 -0
- package/dist/patterns/setup-patterns.js.map +1 -0
- package/dist/patterns/storage-patterns.d.ts +26 -0
- package/dist/patterns/storage-patterns.d.ts.map +1 -0
- package/dist/patterns/storage-patterns.js +142 -0
- package/dist/patterns/storage-patterns.js.map +1 -0
- package/dist/patterns/table-pagination-patterns.d.ts +42 -0
- package/dist/patterns/table-pagination-patterns.d.ts.map +1 -0
- package/dist/patterns/table-pagination-patterns.js +93 -0
- package/dist/patterns/table-pagination-patterns.js.map +1 -0
- package/dist/patterns/table-patterns.d.ts +19 -0
- package/dist/patterns/table-patterns.d.ts.map +1 -0
- package/dist/patterns/table-patterns.js +594 -0
- package/dist/patterns/table-patterns.js.map +1 -0
- package/dist/trace-identity/aria-snapshot-head.d.ts +23 -0
- package/dist/trace-identity/aria-snapshot-head.d.ts.map +1 -0
- package/dist/trace-identity/aria-snapshot-head.js +26 -0
- package/dist/trace-identity/aria-snapshot-head.js.map +1 -0
- package/dist/trace-identity/playwright-identity-resolver.d.ts +10 -0
- package/dist/trace-identity/playwright-identity-resolver.d.ts.map +1 -0
- package/dist/trace-identity/playwright-identity-resolver.js +130 -0
- package/dist/trace-identity/playwright-identity-resolver.js.map +1 -0
- package/dist/trace-identity/trace-run-record-reporter.d.ts +41 -0
- package/dist/trace-identity/trace-run-record-reporter.d.ts.map +1 -0
- package/dist/trace-identity/trace-run-record-reporter.js +113 -0
- package/dist/trace-identity/trace-run-record-reporter.js.map +1 -0
- package/dist/utils/column-header.d.ts +37 -0
- package/dist/utils/column-header.d.ts.map +1 -0
- package/dist/utils/column-header.js +46 -0
- package/dist/utils/column-header.js.map +1 -0
- package/dist/utils/row-index.d.ts +18 -0
- package/dist/utils/row-index.d.ts.map +1 -0
- package/dist/utils/row-index.js +39 -0
- package/dist/utils/row-index.js.map +1 -0
- package/dist/utils/url-path-regex.d.ts +45 -0
- package/dist/utils/url-path-regex.d.ts.map +1 -0
- package/dist/utils/url-path-regex.js +68 -0
- package/dist/utils/url-path-regex.js.map +1 -0
- package/package.json +7 -3
- package/src/index.ts +10 -1
- package/src/trace-identity/aria-snapshot-head.ts +33 -0
- package/src/trace-identity/playwright-identity-resolver.ts +123 -0
- package/src/trace-identity/trace-run-record-reporter.ts +105 -0
|
@@ -0,0 +1,594 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Table Patterns
|
|
4
|
+
* Handles: table row assertions, table cell lookups, actions in table rows
|
|
5
|
+
*
|
|
6
|
+
* Syntax (v2.4 final):
|
|
7
|
+
* - User see [Col] column in [Table] table # column exists
|
|
8
|
+
* - User see [Ref] row in [Table] table with {{value}} # row exists (enters row scope)
|
|
9
|
+
* - User see [Ref] row in [Table] table with {{value}} is hidden # row hidden
|
|
10
|
+
* - User see [Table] table with {{count}} # row count
|
|
11
|
+
* - User see [Table] table is empty # empty table
|
|
12
|
+
* - User see [Col] column with {{value}} # cell value (row scoped — handled in step-mapper)
|
|
13
|
+
* - User click [Act] button in [Table] table with {{filter}} # action in row
|
|
14
|
+
* - User see [Table] table match data: # exact table match with inline DataTable
|
|
15
|
+
* | Header1 | Header2 |
|
|
16
|
+
* | {{value1}} | {{value2}} |
|
|
17
|
+
*/
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
exports.tablePatterns = void 0;
|
|
20
|
+
const row_index_1 = require("../utils/row-index");
|
|
21
|
+
const column_header_1 = require("../utils/column-header");
|
|
22
|
+
/**
|
|
23
|
+
* Row LABEL resolution — `[First Contact Row] row in [T] table` (cb59e157, SG-W010).
|
|
24
|
+
*
|
|
25
|
+
* A `type: locator` entry for the row label positions ONE row (`tbody tr:first-child`, relative to
|
|
26
|
+
* the table) and the step asserts that exact row. No entry → the label is display-only and the
|
|
27
|
+
* historical filter-by-value query runs, byte-identical. Shared by the exists/hidden twins so the
|
|
28
|
+
* two can never drift apart again — `is hidden` used to compute the label and use it only in the
|
|
29
|
+
* comment (issue #688).
|
|
30
|
+
*
|
|
31
|
+
* NOT the row SHAPE. `div.job-row` (what every row matches) is a property of the table and lives on
|
|
32
|
+
* the table entry as `rows:`; put through this branch it strict-mode-fails, which is what the
|
|
33
|
+
* runtime `toHaveCount(1)` guard in the positioned templates now says out loud.
|
|
34
|
+
*/
|
|
35
|
+
function resolveRowLabel(rowLabel, tableName, context) {
|
|
36
|
+
if (!rowLabel || rowLabel === tableName)
|
|
37
|
+
return undefined;
|
|
38
|
+
try {
|
|
39
|
+
const rowResolved = context.selectorResolver.resolveSelector(rowLabel, context.featureName, 'row', 0);
|
|
40
|
+
if (rowResolved.strategy === 'locator' && rowResolved.value && rowResolved.value.trim()) {
|
|
41
|
+
return rowResolved.value;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
// no selectors.yaml entry for the row label — display-only label (fallback)
|
|
46
|
+
}
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* SG-W016 — a table located by CSS that declares no `rows:` (issue #688).
|
|
51
|
+
*
|
|
52
|
+
* Every table template assumes an ARIA table: rows are `getByRole('row')`. A list built from plain
|
|
53
|
+
* <div>s has no role=row, so that universe is 0 elements — `is hidden` and `is empty` then pass
|
|
54
|
+
* without checking anything, counts and clicks time out. The compiler cannot see the DOM, so this is
|
|
55
|
+
* a heuristic and a WARNING: a CSS/testid-located table whose value does not even mention `table`
|
|
56
|
+
* is the shape where the assumption most often fails. `role: table`, `table.users`, or a declared
|
|
57
|
+
* `rows:` are all evidence the author has thought about it, and stay silent. Once per table per
|
|
58
|
+
* feature — the same table is named by every row step of a scenario.
|
|
59
|
+
*/
|
|
60
|
+
const warnedTables = new WeakMap();
|
|
61
|
+
function warnIfRowsLikelyMissing(resolved, tableName, context, stepText) {
|
|
62
|
+
const sink = context.diagnostics;
|
|
63
|
+
if (!sink || resolved.rows)
|
|
64
|
+
return;
|
|
65
|
+
const strategy = String(resolved.strategy);
|
|
66
|
+
if (strategy === 'role') {
|
|
67
|
+
// A ROLE-located table was exempt outright, which read the exemption as "the author chose a
|
|
68
|
+
// role, so they thought about it". They did — but `role: list` or `role: region` contains no
|
|
69
|
+
// role=row either, so those tables hit the very failure this warning exists to name while
|
|
70
|
+
// staying completely silent. Only the roles that DO hold rows are evidence of anything.
|
|
71
|
+
const role = String(resolved.value ?? '').trim().toLowerCase();
|
|
72
|
+
if (role === 'table' || role === 'grid' || role === 'treegrid')
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
else if (!['css', 'locator', 'testid', 'id'].includes(strategy)) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
if (/\btable\b/i.test(String(resolved.value ?? '')))
|
|
79
|
+
return;
|
|
80
|
+
const key = `${context.featureName ?? ''}::${tableName}`;
|
|
81
|
+
let seen = warnedTables.get(sink);
|
|
82
|
+
if (!seen) {
|
|
83
|
+
seen = new Set();
|
|
84
|
+
warnedTables.set(sink, seen);
|
|
85
|
+
}
|
|
86
|
+
if (seen.has(key))
|
|
87
|
+
return;
|
|
88
|
+
seen.add(key);
|
|
89
|
+
sink.add('SG-W016', `table "[${tableName}]" is located by ${resolved.strategy} ("${resolved.value}") and declares no "rows:" — if its rows are not role="row" (a <div> list, or a role that holds no rows such as list/region), every table step resolves 0 rows: "is hidden" and "is empty" pass without checking anything, counts and clicks time out. Declare the row shape on the table entry, e.g. "rows: 'div.job-row'", or locate the table by role: table.`, { feature: context.featureName, step: stepText });
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Does a declared `rows:` SHAPE select `<tr>` elements?
|
|
93
|
+
*
|
|
94
|
+
* `rows:` says what a row LOOKS like; it does not say the markup is not a table. `rows: 'tbody tr'`
|
|
95
|
+
* on a real <table> is a documented, working combination — it pins the row universe without
|
|
96
|
+
* changing what a row IS, so ARIA rows and `td, th` cells are still there. Only a shape built from
|
|
97
|
+
* something else (`div.job-row`, `li.card`) loses them, and that is the case the cell-reading steps
|
|
98
|
+
* cannot serve.
|
|
99
|
+
*
|
|
100
|
+
* Keying those steps on "a shape is declared" instead turned a correct table red: the refusal below
|
|
101
|
+
* would tell an author with a real <table> that their rows "are not ARIA rows", which is false, and
|
|
102
|
+
* a compile-time throw has to be right.
|
|
103
|
+
*
|
|
104
|
+
* Read as an element token so `div.tray` and `[data-tr]` are not mistaken for `tr`.
|
|
105
|
+
*/
|
|
106
|
+
function rowShapeKeepsTableRoles(rows) {
|
|
107
|
+
return !!rows && /(^|[\s>+~,(])tr\b/i.test(rows);
|
|
108
|
+
}
|
|
109
|
+
/** Helper: check if current step is in a Given context */
|
|
110
|
+
function isGivenContext(context) {
|
|
111
|
+
return context.effectiveKeyword === 'Given';
|
|
112
|
+
}
|
|
113
|
+
/** Map Gherkin element type to Playwright ARIA role */
|
|
114
|
+
const typeToRole = {
|
|
115
|
+
button: 'button',
|
|
116
|
+
link: 'link',
|
|
117
|
+
checkbox: 'checkbox',
|
|
118
|
+
icon: 'img',
|
|
119
|
+
image: 'img',
|
|
120
|
+
radio: 'radio',
|
|
121
|
+
switch: 'switch',
|
|
122
|
+
};
|
|
123
|
+
exports.tablePatterns = [
|
|
124
|
+
// "User see [Table] table with {{count}}" — row count (no "rows" keyword needed)
|
|
125
|
+
{
|
|
126
|
+
name: 'table-row-count',
|
|
127
|
+
platforms: ['web'],
|
|
128
|
+
platformAlternative: 'there is no HTML table on a native screen - assert the list count through a visible counter element, or through @query against the backend',
|
|
129
|
+
matcher: (step) => {
|
|
130
|
+
return step.elementType === 'table' &&
|
|
131
|
+
/\btable\s+with\b/i.test(step.text) &&
|
|
132
|
+
!!step.dataRef &&
|
|
133
|
+
!/\brow\b/i.test(step.text) &&
|
|
134
|
+
!/\bcolumn\b/i.test(step.text) &&
|
|
135
|
+
!/\bempty\b/i.test(step.text);
|
|
136
|
+
},
|
|
137
|
+
resolver: (step, context) => {
|
|
138
|
+
const resolved = context.selectorResolver.resolveSelector(step.selectorRef, context.featureName, 'table', step.nth);
|
|
139
|
+
const count = context.dataResolver.resolveData(step.dataRef, context.featureName);
|
|
140
|
+
warnIfRowsLikelyMissing(resolved, step.selectorRef, context, step.text);
|
|
141
|
+
const isGiven = isGivenContext(context);
|
|
142
|
+
return {
|
|
143
|
+
templateName: 'table-row-count',
|
|
144
|
+
data: { ...resolved, expectedCount: count, isGiven },
|
|
145
|
+
comment: `${isGiven ? 'Wait' : 'Assert'} ${step.selectorRef} table has ${count} rows`,
|
|
146
|
+
};
|
|
147
|
+
},
|
|
148
|
+
priority: 16,
|
|
149
|
+
},
|
|
150
|
+
// "User see [Col] column in [Table] table"
|
|
151
|
+
{
|
|
152
|
+
name: 'table-column-exists',
|
|
153
|
+
platforms: ['web'],
|
|
154
|
+
platformAlternative: 'there is no HTML table on a native screen - assert the header element by accessibility-id instead',
|
|
155
|
+
matcher: (step) => {
|
|
156
|
+
return /\bcolumn\s+in\b/i.test(step.text) &&
|
|
157
|
+
/\btable\b/i.test(step.text) &&
|
|
158
|
+
!step.dataRef;
|
|
159
|
+
},
|
|
160
|
+
resolver: (step, context) => {
|
|
161
|
+
// brackets[0] = Col, brackets[1] = Table
|
|
162
|
+
const brackets = step.text.match(/\[([^\]]+)\]/g) || [];
|
|
163
|
+
const columnName = brackets[0]?.replace(/[\[\]]/g, '') || 'Unknown';
|
|
164
|
+
const tableName = brackets.length >= 2
|
|
165
|
+
? brackets[1].replace(/[\[\]]/g, '')
|
|
166
|
+
: brackets[0]?.replace(/[\[\]]/g, '') || '';
|
|
167
|
+
const resolved = context.selectorResolver.resolveSelector(tableName, context.featureName, 'table', step.nth);
|
|
168
|
+
// The DOM header text is declarable — the bracket label is the TEST's name for the column,
|
|
169
|
+
// not the page's (issue #674). See resolveColumnHeaderName for the precedence.
|
|
170
|
+
const headerName = (0, column_header_1.resolveColumnHeaderName)(columnName, context, resolved);
|
|
171
|
+
const isGiven = isGivenContext(context);
|
|
172
|
+
return {
|
|
173
|
+
templateName: 'table-column-exists',
|
|
174
|
+
data: { ...resolved, columnName: headerName, isGiven },
|
|
175
|
+
comment: `${isGiven ? 'Wait' : 'Assert'} ${columnName} column in ${tableName} table`,
|
|
176
|
+
};
|
|
177
|
+
},
|
|
178
|
+
priority: 16,
|
|
179
|
+
},
|
|
180
|
+
// "User see [Table] table is empty"
|
|
181
|
+
{
|
|
182
|
+
name: 'table-is-empty',
|
|
183
|
+
platforms: ['web'],
|
|
184
|
+
platformAlternative: 'there is no HTML table on a native screen - assert the empty-state element is visible and a row marker `is hidden`',
|
|
185
|
+
states: ['empty'],
|
|
186
|
+
matcher: (step) => {
|
|
187
|
+
return /\btable\s+is\s+empty\b/i.test(step.text);
|
|
188
|
+
},
|
|
189
|
+
resolver: (step, context) => {
|
|
190
|
+
const resolved = context.selectorResolver.resolveSelector(step.selectorRef, context.featureName, 'table', step.nth);
|
|
191
|
+
warnIfRowsLikelyMissing(resolved, step.selectorRef, context, step.text);
|
|
192
|
+
const isGiven = isGivenContext(context);
|
|
193
|
+
return {
|
|
194
|
+
templateName: 'table-empty',
|
|
195
|
+
data: { ...resolved, isGiven },
|
|
196
|
+
comment: `${isGiven ? 'Wait' : 'Assert'} ${step.selectorRef} table is empty`,
|
|
197
|
+
};
|
|
198
|
+
},
|
|
199
|
+
priority: 16,
|
|
200
|
+
},
|
|
201
|
+
// "User see [Result Row] row with {{n}}" — COUNT of matching rows (#575 field report).
|
|
202
|
+
// Every doc layer (Pattern 5, the gherkin-syntax skill's "# 7. Count") promises this
|
|
203
|
+
// form counts, and authors write it meaning a count ("40 results after load-more") —
|
|
204
|
+
// but it fell through to see-with-variable and compiled to toHaveText('40') against
|
|
205
|
+
// the row's ENTIRE text: a test that can essentially never pass, emitted silently.
|
|
206
|
+
// The value decides: a numeric base value is a count; any other value keeps the text
|
|
207
|
+
// semantics (asserting a row's full text equals a bare number is no real intent).
|
|
208
|
+
// `row in [Table] table with` (row scope/exists) and `is hidden` stay untouched.
|
|
209
|
+
{
|
|
210
|
+
name: 'row-count',
|
|
211
|
+
matcher: (step) => {
|
|
212
|
+
return step.elementType === 'row' &&
|
|
213
|
+
/\brow\s+with\b/i.test(step.text) &&
|
|
214
|
+
!!step.dataRef && !!step.selectorRef &&
|
|
215
|
+
!/\bin\b.*\btable\b/i.test(step.text) &&
|
|
216
|
+
!/\bis\s+hidden\b/i.test(step.text);
|
|
217
|
+
},
|
|
218
|
+
resolver: (step, context) => {
|
|
219
|
+
// Decide by the BASE literal (runtime mode returns an opaque marker from resolveData).
|
|
220
|
+
const base = context.dataResolver.peekBaseValue?.(step.dataRef, context.featureName);
|
|
221
|
+
if (base === undefined || !/^\d+$/.test(String(base).trim()))
|
|
222
|
+
return null; // not numeric → fall through to text semantics
|
|
223
|
+
const resolved = context.selectorResolver.resolveSelector(step.selectorRef, context.featureName, 'row', step.nth);
|
|
224
|
+
const count = context.dataResolver.resolveData(step.dataRef, context.featureName);
|
|
225
|
+
return {
|
|
226
|
+
templateName: 'count-assertion',
|
|
227
|
+
data: { ...resolved, expectedCount: count },
|
|
228
|
+
comment: `Assert ${step.selectorRef} row count is ${count}`,
|
|
229
|
+
};
|
|
230
|
+
},
|
|
231
|
+
priority: 18, // above see-with-variable (14) — the count reading wins for numeric values
|
|
232
|
+
},
|
|
233
|
+
// "User see [Ref] row in [Table] table with {{value}}" — row exists (enters row scope)
|
|
234
|
+
{
|
|
235
|
+
name: 'table-row-exists',
|
|
236
|
+
platforms: ['web'],
|
|
237
|
+
platformAlternative: 'there is no HTML table on a native screen - assert the row element by accessibility-id (`Then User see [Row 1 Title] has text {{v}}`)',
|
|
238
|
+
matcher: (step) => {
|
|
239
|
+
return step.elementType === 'row' &&
|
|
240
|
+
/\bin\b.*\btable\b/i.test(step.text) &&
|
|
241
|
+
/\bwith\b/i.test(step.text) &&
|
|
242
|
+
!!step.dataRef &&
|
|
243
|
+
!/\bis\s+hidden\b/i.test(step.text);
|
|
244
|
+
},
|
|
245
|
+
resolver: (step, context) => {
|
|
246
|
+
// brackets[0] = Ref (row label), brackets[1] = Table
|
|
247
|
+
const brackets = step.text.match(/\[([^\]]+)\]/g) || [];
|
|
248
|
+
const rowLabel = brackets[0]?.replace(/[\[\]]/g, '') || '';
|
|
249
|
+
const tableName = brackets.length >= 2
|
|
250
|
+
? brackets[1].replace(/[\[\]]/g, '')
|
|
251
|
+
: '';
|
|
252
|
+
const resolved = context.selectorResolver.resolveSelector(tableName, context.featureName, 'table', step.nth);
|
|
253
|
+
const filterValue = context.dataResolver.resolveData(step.dataRef, context.featureName);
|
|
254
|
+
// Field report: the row label used to be DECORATIVE (comment-only) — a
|
|
255
|
+
// positional intent like `[First Contact Row]` silently degraded to an
|
|
256
|
+
// anywhere-in-the-table existence check, so ordering rules never failed.
|
|
257
|
+
// Now the label follows the same "resolve via selectors.yaml, fall back
|
|
258
|
+
// when absent" convention as every other [Ref]: a `type: locator` entry
|
|
259
|
+
// (RELATIVE to the table, e.g. `tbody tr:first-child`) positions the row,
|
|
260
|
+
// and the assertion becomes toContainText on that exact row. No entry →
|
|
261
|
+
// the historical filter-by-value behavior, byte-identical.
|
|
262
|
+
const rowSelector = resolveRowLabel(rowLabel, tableName, context);
|
|
263
|
+
if (!rowSelector)
|
|
264
|
+
warnIfRowsLikelyMissing(resolved, tableName, context, step.text);
|
|
265
|
+
const isGiven = isGivenContext(context);
|
|
266
|
+
return {
|
|
267
|
+
templateName: 'table-row-exists',
|
|
268
|
+
data: { ...resolved, filterValue, isGiven, rowSelector, rowLabel },
|
|
269
|
+
comment: rowSelector
|
|
270
|
+
? `${isGiven ? 'Wait' : 'Assert'} ${rowLabel} (positioned row) in ${tableName} table contains ${step.dataRef}`
|
|
271
|
+
: `${isGiven ? 'Wait' : 'Assert'} ${rowLabel} row in ${tableName} table with ${step.dataRef}`,
|
|
272
|
+
};
|
|
273
|
+
},
|
|
274
|
+
priority: 17,
|
|
275
|
+
},
|
|
276
|
+
// "User see [Ref] row in [Table] table with {{value}} is hidden"
|
|
277
|
+
{
|
|
278
|
+
name: 'table-row-hidden',
|
|
279
|
+
platforms: ['web'],
|
|
280
|
+
platformAlternative: 'there is no HTML table on a native screen - assert the row element `is hidden` by accessibility-id',
|
|
281
|
+
states: ['hidden'],
|
|
282
|
+
matcher: (step) => {
|
|
283
|
+
return step.elementType === 'row' &&
|
|
284
|
+
/\bin\b.*\btable\b/i.test(step.text) &&
|
|
285
|
+
/\bwith\b/i.test(step.text) &&
|
|
286
|
+
!!step.dataRef &&
|
|
287
|
+
/\bis\s+hidden\b/i.test(step.text);
|
|
288
|
+
},
|
|
289
|
+
resolver: (step, context) => {
|
|
290
|
+
// brackets[0] = Ref (row label), brackets[1] = Table
|
|
291
|
+
const brackets = step.text.match(/\[([^\]]+)\]/g) || [];
|
|
292
|
+
const rowLabel = brackets[0]?.replace(/[\[\]]/g, '') || '';
|
|
293
|
+
const tableName = brackets.length >= 2
|
|
294
|
+
? brackets[1].replace(/[\[\]]/g, '')
|
|
295
|
+
: '';
|
|
296
|
+
const resolved = context.selectorResolver.resolveSelector(tableName, context.featureName, 'table', step.nth);
|
|
297
|
+
const filterValue = context.dataResolver.resolveData(step.dataRef, context.featureName);
|
|
298
|
+
// Same label contract as the exists twin (issue #688): a declared positioned row is asserted
|
|
299
|
+
// NOT to hold the value; an undeclared label keeps the filter-by-value count-0 query.
|
|
300
|
+
const rowSelector = resolveRowLabel(rowLabel, tableName, context);
|
|
301
|
+
if (!rowSelector)
|
|
302
|
+
warnIfRowsLikelyMissing(resolved, tableName, context, step.text);
|
|
303
|
+
const isGiven = isGivenContext(context);
|
|
304
|
+
return {
|
|
305
|
+
templateName: 'table-row-not-exists',
|
|
306
|
+
data: { ...resolved, filterValue, isGiven, rowSelector, rowLabel },
|
|
307
|
+
comment: rowSelector
|
|
308
|
+
? `${isGiven ? 'Wait' : 'Assert'} ${rowLabel} (positioned row) in ${tableName} table does not contain ${step.dataRef}`
|
|
309
|
+
: `${isGiven ? 'Wait' : 'Assert'} ${rowLabel} row in ${tableName} table is hidden`,
|
|
310
|
+
};
|
|
311
|
+
},
|
|
312
|
+
priority: 19,
|
|
313
|
+
},
|
|
314
|
+
// "User click [Act] button in [Table] table with {{filter}}" — action in row
|
|
315
|
+
{
|
|
316
|
+
// FR2 (issue #468): positional row — `User click [Act] button in [Table] table row {{n}}`.
|
|
317
|
+
// Selecting by POSITION (not content) compiles remember+act steps onto the same
|
|
318
|
+
// `getByRole('row').nth(...)` chain, eliminating the read-then-act two-query race
|
|
319
|
+
// where a re-render between queries hits two different rows. Row numbering follows
|
|
320
|
+
// qa/app.yaml conventions.table (row_base, header_is_row).
|
|
321
|
+
name: 'table-action-in-row-nth',
|
|
322
|
+
platforms: ['web'],
|
|
323
|
+
platformAlternative: 'there is no HTML table on a native screen - tap the control on the nth row element itself (`When User tap [Row 2 Delete] button`)',
|
|
324
|
+
matcher: (step) => {
|
|
325
|
+
return row_index_1.TABLE_ROW_NTH.test(step.text) &&
|
|
326
|
+
/\b(click|clicks|check|checks|uncheck|unchecks)\b/i.test(step.text) &&
|
|
327
|
+
!/\bremember\b/i.test(step.text) &&
|
|
328
|
+
/\bin\b.*\btable\b/i.test(step.text);
|
|
329
|
+
},
|
|
330
|
+
resolver: (step, context) => {
|
|
331
|
+
const brackets = step.text.match(/\[([^\]]+)\]/g) || [];
|
|
332
|
+
const elementName = brackets[0]?.replace(/[\[\]]/g, '') || '';
|
|
333
|
+
const tableName = brackets.length >= 2 ? brackets[1].replace(/[\[\]]/g, '') : '';
|
|
334
|
+
const rowToken = step.text.match(row_index_1.TABLE_ROW_NTH)[1];
|
|
335
|
+
const tableResolved = context.selectorResolver.resolveSelector(tableName, context.featureName, 'table', 0);
|
|
336
|
+
warnIfRowsLikelyMissing(tableResolved, tableName, context, step.text);
|
|
337
|
+
// Plural forms are admitted by the matcher above, so they must be READ here too: the old
|
|
338
|
+
// `\b(click|check|uncheck)\b` matched none of "clicks"/"checks"/"unchecks" (the trailing "s"
|
|
339
|
+
// kills the closing boundary), so every plural step silently fell back to 'click' — an
|
|
340
|
+
// `unchecks` step compiled to a click. `uncheck` is listed before `check` so the longer verb
|
|
341
|
+
// wins the alternation.
|
|
342
|
+
const actionMatch = step.text.match(/\b(clicks?|unchecks?|checks?)\b/i);
|
|
343
|
+
const action = actionMatch ? actionMatch[1].toLowerCase().replace(/s$/, '') : 'click';
|
|
344
|
+
const elementTypeMatch = step.text.match(/\]\s+([\w-]+)\s+in\b/i);
|
|
345
|
+
const elementType = elementTypeMatch ? elementTypeMatch[1].toLowerCase() : 'button';
|
|
346
|
+
const elementRole = typeToRole[elementType] || elementType;
|
|
347
|
+
let actionLocator;
|
|
348
|
+
// Resolved from the ROW'S CONTROL, never from the table: the template data below spreads
|
|
349
|
+
// `tableResolved`, so a bare `checkedClass` there would be the TABLE's signal pinned onto the
|
|
350
|
+
// control inside the row (issue #730). The catch path leaves it undefined — with no YAML entry
|
|
351
|
+
// there is no declaration to read, and the emitted call stays byte-identical to before.
|
|
352
|
+
let actionCheckedClass;
|
|
353
|
+
let actionCheckedAttribute;
|
|
354
|
+
try {
|
|
355
|
+
const elementResolved = context.selectorResolver.resolveSelector(elementName, context.featureName, elementType, step.nth);
|
|
356
|
+
actionLocator = context.renderLocator({ ...elementResolved, parentLocator: 'tableRow' });
|
|
357
|
+
actionCheckedClass = elementResolved.checkedClass;
|
|
358
|
+
actionCheckedAttribute = elementResolved.checkedAttribute;
|
|
359
|
+
}
|
|
360
|
+
catch {
|
|
361
|
+
const escapedName = String(elementName)
|
|
362
|
+
.replace(/\\/g, '\\\\').replace(/'/g, "\\'")
|
|
363
|
+
.replace(/\n/g, '\\n').replace(/\r/g, '\\r').replace(/\t/g, '\\t');
|
|
364
|
+
actionLocator = `tableRow.getByRole('${elementRole}', { name: '${escapedName}' })`;
|
|
365
|
+
}
|
|
366
|
+
// A declared row SHAPE never matches the header row, so the header offset does not apply.
|
|
367
|
+
const rowIndex = (0, row_index_1.rowIndexExpr)(rowToken, context, { headerInRows: !tableResolved.rows });
|
|
368
|
+
return {
|
|
369
|
+
templateName: 'table-action-in-row-nth',
|
|
370
|
+
data: { ...tableResolved, elementName, action, actionLocator, actionCheckedClass, actionCheckedAttribute, rowIndexExpr: rowIndex },
|
|
371
|
+
comment: `${action} ${elementName} in ${tableName} table row ${rowToken}`,
|
|
372
|
+
};
|
|
373
|
+
},
|
|
374
|
+
priority: 18,
|
|
375
|
+
},
|
|
376
|
+
{
|
|
377
|
+
name: 'table-action-in-row',
|
|
378
|
+
platforms: ['web'],
|
|
379
|
+
platformAlternative: 'there is no HTML table on a native screen - tap the control on the row element itself (`When User tap [Row 1 Delete] button`)',
|
|
380
|
+
matcher: (step) => {
|
|
381
|
+
// The VERB is required, exactly as the `-nth` twin above requires it. Without this test the
|
|
382
|
+
// pattern claimed every `in [T] table with {{v}}` sentence, verb or not, and the resolver's
|
|
383
|
+
// `|| 'click'` default then turned an ASSERTION into a click: `Then User see [Status] text in
|
|
384
|
+
// [Job Table] table with {{v}}` compiled to `.click()`, so the scenario went green having
|
|
385
|
+
// checked nothing. An action pattern must not be reachable from a sentence that names no
|
|
386
|
+
// action. `remember` is excluded for the same reason it is on the twin — it reads a value.
|
|
387
|
+
return /\bin\b.*\btable\b/i.test(step.text) &&
|
|
388
|
+
/\bwith\b/i.test(step.text) &&
|
|
389
|
+
/\b(clicks?|unchecks?|checks?)\b/i.test(step.text) &&
|
|
390
|
+
!/\bremember\b/i.test(step.text) &&
|
|
391
|
+
!!step.dataRef &&
|
|
392
|
+
step.elementType !== 'column' &&
|
|
393
|
+
step.elementType !== 'row' &&
|
|
394
|
+
step.elementType !== 'table';
|
|
395
|
+
},
|
|
396
|
+
resolver: (step, context) => {
|
|
397
|
+
// brackets[0] = Act (element name), brackets[1] = Table
|
|
398
|
+
const brackets = step.text.match(/\[([^\]]+)\]/g) || [];
|
|
399
|
+
const elementName = brackets[0]?.replace(/[\[\]]/g, '') || '';
|
|
400
|
+
const tableName = brackets.length >= 2
|
|
401
|
+
? brackets[1].replace(/[\[\]]/g, '')
|
|
402
|
+
: '';
|
|
403
|
+
const filterValue = step.dataRef
|
|
404
|
+
? context.dataResolver.resolveData(step.dataRef, context.featureName)
|
|
405
|
+
: '';
|
|
406
|
+
const tableResolved = context.selectorResolver.resolveSelector(tableName, context.featureName, 'table', 0);
|
|
407
|
+
warnIfRowsLikelyMissing(tableResolved, tableName, context, step.text);
|
|
408
|
+
// Determine action from step text
|
|
409
|
+
// Plural forms are admitted by the matcher above, so they must be READ here too: the old
|
|
410
|
+
// `\b(click|check|uncheck)\b` matched none of "clicks"/"checks"/"unchecks" (the trailing "s"
|
|
411
|
+
// kills the closing boundary), so every plural step silently fell back to 'click' — an
|
|
412
|
+
// `unchecks` step compiled to a click. `uncheck` is listed before `check` so the longer verb
|
|
413
|
+
// wins the alternation.
|
|
414
|
+
const actionMatch = step.text.match(/\b(clicks?|unchecks?|checks?)\b/i);
|
|
415
|
+
const action = actionMatch ? actionMatch[1].toLowerCase().replace(/s$/, '') : 'click';
|
|
416
|
+
// Extract element type (word after [Act]) and map to ARIA role
|
|
417
|
+
const elementTypeMatch = step.text.match(/\]\s+([\w-]+)\s+in\b/i);
|
|
418
|
+
const elementType = elementTypeMatch ? elementTypeMatch[1].toLowerCase() : 'button';
|
|
419
|
+
const elementRole = typeToRole[elementType] || elementType;
|
|
420
|
+
// Resolve the inner action element through selectors.yaml (honoring any
|
|
421
|
+
// AI-authored locator / testid / custom name), scoped to the matched row via
|
|
422
|
+
// parentLocator. When no YAML entry exists the resolver auto-infers role+name,
|
|
423
|
+
// and when resolution throws we rebuild the historical getByRole string — so the
|
|
424
|
+
// no-entry / unmapped cases stay byte-identical to the previous hardcoded output.
|
|
425
|
+
let actionLocator;
|
|
426
|
+
// Resolved from the ROW'S CONTROL, never from the table: the template data below spreads
|
|
427
|
+
// `tableResolved`, so a bare `checkedClass` there would be the TABLE's signal pinned onto the
|
|
428
|
+
// control inside the row (issue #730). The catch path leaves it undefined — with no YAML entry
|
|
429
|
+
// there is no declaration to read, and the emitted call stays byte-identical to before.
|
|
430
|
+
let actionCheckedClass;
|
|
431
|
+
let actionCheckedAttribute;
|
|
432
|
+
try {
|
|
433
|
+
const elementResolved = context.selectorResolver.resolveSelector(elementName, context.featureName, elementType, step.nth);
|
|
434
|
+
actionLocator = context.renderLocator({ ...elementResolved, parentLocator: 'tableRow' });
|
|
435
|
+
actionCheckedClass = elementResolved.checkedClass;
|
|
436
|
+
actionCheckedAttribute = elementResolved.checkedAttribute;
|
|
437
|
+
}
|
|
438
|
+
catch {
|
|
439
|
+
const escapedName = String(elementName)
|
|
440
|
+
.replace(/\\/g, '\\\\').replace(/'/g, "\\'")
|
|
441
|
+
.replace(/\n/g, '\\n').replace(/\r/g, '\\r').replace(/\t/g, '\\t');
|
|
442
|
+
actionLocator = `tableRow.getByRole('${elementRole}', { name: '${escapedName}' })`;
|
|
443
|
+
}
|
|
444
|
+
return {
|
|
445
|
+
templateName: 'table-action-in-row',
|
|
446
|
+
data: { ...tableResolved, elementName, filterValue, action, elementRole, actionLocator, actionCheckedClass, actionCheckedAttribute },
|
|
447
|
+
comment: `${action} ${elementName} in ${tableName} table row with ${step.dataRef}`,
|
|
448
|
+
};
|
|
449
|
+
},
|
|
450
|
+
priority: 17,
|
|
451
|
+
},
|
|
452
|
+
// "User see [Table] table match data:" — filter-based table match with inline DataTable
|
|
453
|
+
// First row = headers, remaining rows = expected data
|
|
454
|
+
// Uses filter({ hasText }) per row — resilient to data changes, row ordering, extra rows
|
|
455
|
+
{
|
|
456
|
+
name: 'table-match-data',
|
|
457
|
+
platforms: ['web'],
|
|
458
|
+
platformAlternative: 'there is no HTML table on a native screen - assert each row element by accessibility-id, or verify the set through @query against the backend',
|
|
459
|
+
matcher: (step) => {
|
|
460
|
+
return step.elementType === 'table' &&
|
|
461
|
+
/\btable\s+match\s+data\b/i.test(step.text) &&
|
|
462
|
+
!!step.dataTable;
|
|
463
|
+
},
|
|
464
|
+
resolver: (step, context) => {
|
|
465
|
+
const resolved = context.selectorResolver.resolveSelector(step.selectorRef, context.featureName, 'table', step.nth);
|
|
466
|
+
const dataTable = step.dataTable;
|
|
467
|
+
warnIfRowsLikelyMissing(resolved, step.selectorRef, context, step.text);
|
|
468
|
+
// Resolve {{variable}} references in a cell (headers included — i18n headers are legal)
|
|
469
|
+
const resolveCell = (cell) => {
|
|
470
|
+
const varMatch = cell.match(/^\{\{([a-z0-9\-\.\_]+)\}\}$/i);
|
|
471
|
+
if (varMatch) {
|
|
472
|
+
return context.dataResolver.resolveData(varMatch[1], context.featureName);
|
|
473
|
+
}
|
|
474
|
+
return cell;
|
|
475
|
+
};
|
|
476
|
+
const headers = dataTable.headers.map(resolveCell);
|
|
477
|
+
const resolvedRows = dataTable.rows.map(row => ({ cells: row.cells.map(resolveCell) }));
|
|
478
|
+
const esc = (s) => s.replace(/'/g, "\\'");
|
|
479
|
+
// Where a CELL lives, decided at compile time from the table's own declaration.
|
|
480
|
+
//
|
|
481
|
+
// The runtime header read below only works on a real <table>: it reads `thead tr` and then
|
|
482
|
+
// addresses cells as `td, th`. A list whose rows are declared with a `rows:` SHAPE is built
|
|
483
|
+
// from <div>s, where `thead tr` is 0 elements forever — not a render race — and `td, th` is
|
|
484
|
+
// 0 elements too, so the step can never pass however long it waits. Declaring `columns:`
|
|
485
|
+
// replaces the read entirely: the index is known at compile time, and a column that names
|
|
486
|
+
// its own `elements.cell` addresses the cell without any table role at all.
|
|
487
|
+
const declaredColumns = resolved.columns ?? {};
|
|
488
|
+
const columnFor = (header) => {
|
|
489
|
+
const key = header.trim().toLowerCase().normalize('NFC');
|
|
490
|
+
const direct = declaredColumns[key];
|
|
491
|
+
if (direct)
|
|
492
|
+
return direct;
|
|
493
|
+
return Object.values(declaredColumns).find((c) => String(c?.header ?? '').trim().toLowerCase().normalize('NFC') === key);
|
|
494
|
+
};
|
|
495
|
+
// A shape that still selects <tr> keeps its ARIA rows and its `td, th` cells, so the runtime
|
|
496
|
+
// header read below serves it exactly as it always did. Only a shape built from something else
|
|
497
|
+
// needs — and can use — the compile-time map.
|
|
498
|
+
const shapeHidesTableRoles = !!resolved.rows && !rowShapeKeepsTableRoles(resolved.rows);
|
|
499
|
+
// Usable means the column names the selector that matches its cell INSIDE a row. An `index:`
|
|
500
|
+
// alone cannot help here: it indexes the `td, th` set, which is empty on this markup.
|
|
501
|
+
const unmapped = headers.filter((h) => !columnFor(h)?.elements?.cell);
|
|
502
|
+
const mappedByCellSelector = shapeHidesTableRoles && unmapped.length === 0;
|
|
503
|
+
// A row shape that hides the table roles, with no cell selector to reach the cells by, cannot
|
|
504
|
+
// be served at all — refuse now, loudly, rather than emit an assertion that waits out every
|
|
505
|
+
// timeout before failing on a header row that will never exist.
|
|
506
|
+
if (shapeHidesTableRoles && unmapped.length > 0) {
|
|
507
|
+
const reason = `step "${step.text}" runs \`table match data:\` against table `
|
|
508
|
+
+ `"[${step.selectorRef}]", whose rows are declared with a "rows:" shape — so the rows are `
|
|
509
|
+
+ `not ARIA rows, their cells are not "td, th", and there is no "thead tr" to read the `
|
|
510
|
+
+ `header row from. This assertion cannot pass on that markup however long it waits. `
|
|
511
|
+
+ `Declare the columns it needs (${unmapped.map((h) => `"${h}"`).join(', ')}) on the table `
|
|
512
|
+
+ `entry, each with the selector that matches its cell inside a row: "columns:\\n `
|
|
513
|
+
+ `${(unmapped[0] ?? 'title').trim().toLowerCase()}:\\n index: 0\\n header: `
|
|
514
|
+
+ `'${unmapped[0] ?? 'Title'}'\\n elements:\\n cell:\\n type: locator\\n `
|
|
515
|
+
+ ` value: '.your-cell-class'".`;
|
|
516
|
+
context.diagnostics?.add('SG-E035', reason, { feature: context.featureName, step: step.text });
|
|
517
|
+
return {
|
|
518
|
+
templateName: 'table-match-data',
|
|
519
|
+
data: {
|
|
520
|
+
...resolved,
|
|
521
|
+
assertions: [`throw new Error(${JSON.stringify(`[sungen] ${reason}`)});`],
|
|
522
|
+
isGiven: isGivenContext(context),
|
|
523
|
+
},
|
|
524
|
+
comment: `Unsupported table match data on a declared row shape — see SG-E035: ${step.text}`,
|
|
525
|
+
};
|
|
526
|
+
}
|
|
527
|
+
// Header → cell mapping (field report: the header row was parsed and then IGNORED —
|
|
528
|
+
// rows were asserted as chained row-level hasText filters, so column-swapped data and
|
|
529
|
+
// duplicate values like '-' still passed). Now:
|
|
530
|
+
// 1. span guard — rowspan/colspan shifts ordinal mapping; fail loud instead of
|
|
531
|
+
// asserting the wrong cells (span support is a documented follow-up);
|
|
532
|
+
// 2. resolve each DataTable header to its DOM column index AT RUNTIME by header text
|
|
533
|
+
// (exact after trim, else a UNIQUE contains-match to tolerate sort icons); a
|
|
534
|
+
// missing/ambiguous header fails with the actual header row in the message —
|
|
535
|
+
// robust to extra DOM columns (leading checkbox…) that break compile-time nth;
|
|
536
|
+
// 3. locate each expected row by the chained co-occurrence filters (kept — resilient
|
|
537
|
+
// to row order and extra rows), then prove EVERY cell under its own header with
|
|
538
|
+
// an exact toHaveText. `td, th` ordinals count all DOM cells on both the header
|
|
539
|
+
// and body sides, so indexes stay aligned even with hidden columns.
|
|
540
|
+
const assertions = [];
|
|
541
|
+
assertions.push(`await expect(table.locator('[rowspan]:not([rowspan="1"]), [colspan]:not([colspan="1"])'), 'table match data: rowspan/colspan tables are not supported yet — header-to-cell mapping would be wrong').toHaveCount(0);`);
|
|
542
|
+
// The cell expression for one DataTable column, scoped to `row`.
|
|
543
|
+
let cellExpr;
|
|
544
|
+
if (mappedByCellSelector) {
|
|
545
|
+
// Declared cell selectors: no header row is read at run time, so there is nothing to race
|
|
546
|
+
// with. Taken ONLY when the shape hides the table roles and every header has one — on a real
|
|
547
|
+
// table the runtime lookup is strictly better, because it is robust to extra DOM columns (a
|
|
548
|
+
// leading checkbox) that a compile-time index cannot see. Switching a working table onto
|
|
549
|
+
// compile-time indexes because it happens to declare `columns:` for some other step would
|
|
550
|
+
// silently re-point its assertions at different cells.
|
|
551
|
+
cellExpr = (header) => context.renderLocator({
|
|
552
|
+
...context.selectorResolver.resolveNestedEntry(columnFor(header).elements.cell, header),
|
|
553
|
+
parentLocator: 'row',
|
|
554
|
+
});
|
|
555
|
+
}
|
|
556
|
+
else {
|
|
557
|
+
// The historical runtime mapping, for a table that declares nothing. The span guard above
|
|
558
|
+
// is NOT a wait: `toHaveCount(0)` is already true of an empty DOM, so it returns on the
|
|
559
|
+
// first poll and the one-shot read below then sees an empty header row. This assertion
|
|
560
|
+
// waits for the header row to actually hold cells before reading it.
|
|
561
|
+
assertions.push(`await expect(table.locator('thead tr').first().locator('th, td'), 'table match data: the header row is still empty — the table had not rendered by the time this assertion read it').not.toHaveCount(0);`);
|
|
562
|
+
assertions.push(`const __headers = (await table.locator('thead tr').first().locator('th, td').allTextContents()).map((t) => t.trim());`);
|
|
563
|
+
assertions.push(`const __colIdx = (h: string): number => { const i = __headers.indexOf(h); if (i !== -1) return i; const c = __headers.filter((t) => t.includes(h)); if (c.length === 1) return __headers.indexOf(c[0]); throw new Error(\`table match data: header "\${h}" \${c.length ? 'is ambiguous' : 'not found'} in table header row [\${__headers.join(' | ')}]\`); };`);
|
|
564
|
+
cellExpr = (header) => `row.locator('td, th').nth(__colIdx('${esc(header)}'))`;
|
|
565
|
+
}
|
|
566
|
+
for (const row of resolvedRows) {
|
|
567
|
+
const filters = row.cells
|
|
568
|
+
.map(cell => `.filter({ hasText: '${esc(cell)}' })`)
|
|
569
|
+
.join('');
|
|
570
|
+
assertions.push(`{`);
|
|
571
|
+
assertions.push(` const row = rows${filters};`);
|
|
572
|
+
row.cells.forEach((cell, i) => {
|
|
573
|
+
const header = headers[i];
|
|
574
|
+
if (header === undefined)
|
|
575
|
+
return;
|
|
576
|
+
assertions.push(` await expect(${cellExpr(header)}).toHaveText('${esc(cell)}');`);
|
|
577
|
+
});
|
|
578
|
+
assertions.push(`}`);
|
|
579
|
+
}
|
|
580
|
+
const isGiven = isGivenContext(context);
|
|
581
|
+
return {
|
|
582
|
+
templateName: 'table-match-data',
|
|
583
|
+
data: {
|
|
584
|
+
...resolved,
|
|
585
|
+
assertions,
|
|
586
|
+
isGiven,
|
|
587
|
+
},
|
|
588
|
+
comment: `${isGiven ? 'Wait' : 'Assert'} ${step.selectorRef} table contains ${resolvedRows.length} expected row(s)`,
|
|
589
|
+
};
|
|
590
|
+
},
|
|
591
|
+
priority: 20, // Higher than other table patterns to match first
|
|
592
|
+
},
|
|
593
|
+
];
|
|
594
|
+
//# sourceMappingURL=table-patterns.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"table-patterns.js","sourceRoot":"","sources":["../../src/patterns/table-patterns.ts"],"names":[],"mappings":"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"}
|