@sun-asterisk/sungen 2.3.1 → 2.4.1

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.
Files changed (105) hide show
  1. package/README.md +10 -11
  2. package/dist/cli/index.js +1 -1
  3. package/dist/generators/gherkin-parser/index.d.ts +8 -0
  4. package/dist/generators/gherkin-parser/index.d.ts.map +1 -1
  5. package/dist/generators/gherkin-parser/index.js +12 -0
  6. package/dist/generators/gherkin-parser/index.js.map +1 -1
  7. package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/table-action-in-row.hbs +1 -1
  8. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/table-column-exists.hbs +5 -1
  9. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/table-match-data.hbs +15 -0
  10. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/table-row-exists.hbs +7 -1
  11. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/table-row-not-exists.hbs +5 -1
  12. package/dist/generators/test-generator/patterns/index.d.ts.map +1 -1
  13. package/dist/generators/test-generator/patterns/index.js +2 -1
  14. package/dist/generators/test-generator/patterns/index.js.map +1 -1
  15. package/dist/generators/test-generator/patterns/table-patterns.d.ts +12 -0
  16. package/dist/generators/test-generator/patterns/table-patterns.d.ts.map +1 -1
  17. package/dist/generators/test-generator/patterns/table-patterns.js +142 -98
  18. package/dist/generators/test-generator/patterns/table-patterns.js.map +1 -1
  19. package/dist/generators/test-generator/patterns/types.d.ts +2 -0
  20. package/dist/generators/test-generator/patterns/types.d.ts.map +1 -1
  21. package/dist/generators/test-generator/step-mapper.d.ts +13 -0
  22. package/dist/generators/test-generator/step-mapper.d.ts.map +1 -1
  23. package/dist/generators/test-generator/step-mapper.js +80 -0
  24. package/dist/generators/test-generator/step-mapper.js.map +1 -1
  25. package/dist/orchestrator/ai-rules-updater.d.ts.map +1 -1
  26. package/dist/orchestrator/ai-rules-updater.js +8 -6
  27. package/dist/orchestrator/ai-rules-updater.js.map +1 -1
  28. package/dist/orchestrator/project-initializer.d.ts.map +1 -1
  29. package/dist/orchestrator/project-initializer.js +33 -2
  30. package/dist/orchestrator/project-initializer.js.map +1 -1
  31. package/dist/orchestrator/screen-manager.js +1 -1
  32. package/dist/orchestrator/screen-manager.js.map +1 -1
  33. package/dist/orchestrator/templates/ai-instructions/claude-cmd-add-screen.md +5 -5
  34. package/{src/orchestrator/templates/ai-instructions/claude-cmd-make-tc.md → dist/orchestrator/templates/ai-instructions/claude-cmd-create-test.md} +7 -7
  35. package/dist/orchestrator/templates/ai-instructions/claude-cmd-review.md +21 -0
  36. package/dist/orchestrator/templates/ai-instructions/claude-cmd-run-test.md +32 -0
  37. package/dist/orchestrator/templates/ai-instructions/claude-config.md +65 -12
  38. package/dist/orchestrator/templates/ai-instructions/claude-skill-error-mapping.md +128 -52
  39. package/dist/orchestrator/templates/ai-instructions/claude-skill-gherkin-syntax.md +15 -39
  40. package/dist/orchestrator/templates/ai-instructions/claude-skill-selector-fix.md +72 -259
  41. package/dist/orchestrator/templates/ai-instructions/claude-skill-tc-generation.md +57 -205
  42. package/dist/orchestrator/templates/ai-instructions/claude-skill-tc-review.md +104 -0
  43. package/dist/orchestrator/templates/ai-instructions/claude-skill-viewpoint.md +188 -0
  44. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-add-screen.md +4 -4
  45. package/dist/orchestrator/templates/ai-instructions/{copilot-cmd-make-tc.md → copilot-cmd-create-test.md} +8 -8
  46. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-review.md +24 -0
  47. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-run-test.md +35 -0
  48. package/dist/orchestrator/templates/ai-instructions/copilot-config.md +66 -13
  49. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-error-mapping.md +128 -52
  50. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-gherkin-syntax.md +15 -39
  51. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-selector-fix.md +72 -234
  52. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-tc-generation.md +57 -205
  53. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-tc-review.md +104 -0
  54. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint.md +188 -0
  55. package/dist/orchestrator/templates/readme.md +85 -22
  56. package/package.json +1 -1
  57. package/src/cli/index.ts +1 -1
  58. package/src/generators/gherkin-parser/index.ts +23 -0
  59. package/src/generators/test-generator/adapters/playwright/templates/steps/actions/table-action-in-row.hbs +1 -1
  60. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/table-column-exists.hbs +5 -1
  61. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/table-match-data.hbs +15 -0
  62. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/table-row-exists.hbs +7 -1
  63. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/table-row-not-exists.hbs +5 -1
  64. package/src/generators/test-generator/patterns/index.ts +2 -1
  65. package/src/generators/test-generator/patterns/table-patterns.ts +155 -111
  66. package/src/generators/test-generator/patterns/types.ts +2 -0
  67. package/src/generators/test-generator/step-mapper.ts +87 -1
  68. package/src/orchestrator/ai-rules-updater.ts +8 -6
  69. package/src/orchestrator/project-initializer.ts +38 -2
  70. package/src/orchestrator/screen-manager.ts +1 -1
  71. package/src/orchestrator/templates/ai-instructions/claude-cmd-add-screen.md +5 -5
  72. package/{dist/orchestrator/templates/ai-instructions/claude-cmd-make-tc.md → src/orchestrator/templates/ai-instructions/claude-cmd-create-test.md} +7 -7
  73. package/src/orchestrator/templates/ai-instructions/claude-cmd-review.md +21 -0
  74. package/src/orchestrator/templates/ai-instructions/claude-cmd-run-test.md +32 -0
  75. package/src/orchestrator/templates/ai-instructions/claude-config.md +65 -12
  76. package/src/orchestrator/templates/ai-instructions/claude-skill-error-mapping.md +128 -52
  77. package/src/orchestrator/templates/ai-instructions/claude-skill-gherkin-syntax.md +15 -39
  78. package/src/orchestrator/templates/ai-instructions/claude-skill-selector-fix.md +72 -259
  79. package/src/orchestrator/templates/ai-instructions/claude-skill-tc-generation.md +57 -205
  80. package/src/orchestrator/templates/ai-instructions/claude-skill-tc-review.md +104 -0
  81. package/src/orchestrator/templates/ai-instructions/claude-skill-viewpoint.md +188 -0
  82. package/src/orchestrator/templates/ai-instructions/copilot-cmd-add-screen.md +4 -4
  83. package/src/orchestrator/templates/ai-instructions/{copilot-cmd-make-tc.md → copilot-cmd-create-test.md} +8 -8
  84. package/src/orchestrator/templates/ai-instructions/copilot-cmd-review.md +24 -0
  85. package/src/orchestrator/templates/ai-instructions/copilot-cmd-run-test.md +35 -0
  86. package/src/orchestrator/templates/ai-instructions/copilot-config.md +66 -13
  87. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-error-mapping.md +128 -52
  88. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-gherkin-syntax.md +15 -39
  89. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-selector-fix.md +72 -234
  90. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-tc-generation.md +57 -205
  91. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-tc-review.md +104 -0
  92. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint.md +188 -0
  93. package/src/orchestrator/templates/readme.md +85 -22
  94. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/table-cell-by-filter.hbs +0 -2
  95. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/table-cell-by-index.hbs +0 -2
  96. package/dist/orchestrator/templates/ai-instructions/claude-cmd-make-test.md +0 -29
  97. package/dist/orchestrator/templates/ai-instructions/claude-skill-gherkin-review.md +0 -228
  98. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-make-test.md +0 -32
  99. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-gherkin-review.md +0 -228
  100. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/table-cell-by-filter.hbs +0 -2
  101. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/table-cell-by-index.hbs +0 -2
  102. package/src/orchestrator/templates/ai-instructions/claude-cmd-make-test.md +0 -29
  103. package/src/orchestrator/templates/ai-instructions/claude-skill-gherkin-review.md +0 -228
  104. package/src/orchestrator/templates/ai-instructions/copilot-cmd-make-test.md +0 -32
  105. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-gherkin-review.md +0 -228
@@ -1,6 +1,6 @@
1
1
  # Sungen Test Automation
2
2
 
3
- This project uses [Sungen v2](https://github.com/sun-asterisk/sungen) — a deterministic E2E test compiler.
3
+ This project uses [Sungen v2.4.1](https://github.com/sun-asterisk/sungen) — a deterministic E2E test compiler.
4
4
 
5
5
  ## How it works
6
6
 
@@ -37,16 +37,16 @@ sungen generate → compiles Gherkin + selectors + data → Playwright .spec.ts
37
37
  ## Workflow
38
38
 
39
39
  ```
40
- Step 1 Step 2 Step 3
41
- ┌──────────┐ ┌──────────┐ ┌──────────┐
42
- │ /add- │────────▶│ /make-tc │────────▶│ /make-
43
- │ screen │ │ │ │ test │
44
- └──────────┘ └──────────┘ └──────────┘
45
- Scaffold Pick sections Generate
46
- directories → design TCs selectors
47
- → generate → compile
48
- .feature + → run tests
49
- test-data → auto-fix
40
+ Step 1 Step 2 Step 3 Step 4
41
+ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
42
+ │ /add- │────────▶│ /create- │────────▶│ /run- │────────▶│ /review
43
+ │ screen │ │ test │ │ test │ │ │
44
+ └──────────┘ └──────────┘ └──────────┘ └──────────┘
45
+ Scaffold Pick sections Generate Review
46
+ directories → design TCs selectors syntax &
47
+ → generate → compile coverage
48
+ .feature + → run tests → score &
49
+ test-data → auto-fix auto-fix
50
50
  ```
51
51
 
52
52
  Use AI commands (Claude Code or GitHub Copilot) to drive the workflow:
@@ -63,7 +63,7 @@ Scaffolds `qa/screens/<name>/` with empty feature, selectors, test-data, and req
63
63
 
64
64
  | Claude Code | GitHub Copilot (VS Code) |
65
65
  |---|---|
66
- | `/sungen:make-tc login` | `/sungen-make-tc login` |
66
+ | `/sungen:create-test login` | `/sungen-create-test login` |
67
67
 
68
68
  AI acts as a **Senior QA Engineer**:
69
69
  1. Reads `requirements/spec.md` for screen specs (fields, validation, business rules, states)
@@ -76,7 +76,7 @@ AI acts as a **Senior QA Engineer**:
76
76
 
77
77
  | Claude Code | GitHub Copilot (VS Code) |
78
78
  |---|---|
79
- | `/sungen:make-test login` | `/sungen-make-test login` |
79
+ | `/sungen:run-test login` | `/sungen-run-test login` |
80
80
 
81
81
  AI acts as a **Senior Developer**:
82
82
  1. Navigates to live page, takes snapshot, verifies DOM properties
@@ -84,6 +84,17 @@ AI acts as a **Senior Developer**:
84
84
  3. Compiles Gherkin → Playwright `.spec.ts`
85
85
  4. Runs tests, auto-fixes selectors on failure (up to 5 attempts)
86
86
 
87
+ ### Step 4: Review test cases
88
+
89
+ | Claude Code | GitHub Copilot (VS Code) |
90
+ |---|---|
91
+ | `/sungen:review login` | `/sungen-review login` |
92
+
93
+ AI acts as a **Senior QA Reviewer**:
94
+ 1. Validates syntax against all Gherkin rules
95
+ 2. Scores coverage across viewpoint categories
96
+ 3. Can auto-fix issues when `--fix` flag is used
97
+
87
98
  ### Auth setup
88
99
 
89
100
  If any page requires authentication, the AI will ask you to **log in manually via the MCP browser** during Step 2 or Step 3. No separate auth command needed.
@@ -123,38 +134,85 @@ Add to `.vscode/settings.json` to auto-load Gherkin syntax when editing `.featur
123
134
  ### Syntax
124
135
 
125
136
  ```
126
- User <action> [<Target>] <type> with {{<Value>}}
137
+ [Keyword] User <action> [Target] <type> <in [Parent] parentType> <with {{value}}> <is state>
127
138
  ```
128
139
 
129
140
  - `[Target]` → selector reference → lookup in `selectors/*.yaml`
130
- - `{{Value}}` → test data reference → lookup in `test-data/*.yaml`
131
- - `<type>` → element type: button, link, field, heading, text, etc.
141
+ - `{{value}}` → test data reference → lookup in `test-data/*.yaml`
142
+ - `<type>` → element type: button, link, field, heading, text, table, etc.
143
+ - `in [Parent] parentType` → optional parent scope for disambiguation
132
144
 
133
145
  ### Key Patterns
134
146
 
135
147
  | Pattern | Example |
136
148
  |---|---|
137
149
  | Navigate | `User is on [login] page` |
150
+ | Navigate with data | `User is on [user detail] page with {{user_id}}` |
138
151
  | Click | `User click [Submit] button` |
139
152
  | Fill | `User fill [Email] field with {{email}}` |
140
- | Assert visible | `User see [Welcome] heading is visible` |
153
+ | Select | `User select [Country] dropdown with {{country}}` |
154
+ | Check | `User check [Remember me] checkbox` |
155
+ | Upload | `User fill [Avatar] uploader with {{file}}` |
156
+ | Clear | `User clear [Search] field` |
157
+ | Hover | `User hover [Info] icon` |
158
+ | Keyboard | `User press Enter on [Search] field` |
159
+ | Scroll | `User scroll to [Footer] section` |
160
+ | Assert visible | `User see [Welcome] heading` |
161
+ | Assert hidden | `User see [Error] message is hidden` |
141
162
  | Assert text | `User see [Title] heading with {{title}}` |
163
+ | Assert value | `User see [Email] field with {{email}}` |
142
164
  | Assert state | `User see [Submit] button is disabled` |
143
- | Wait for | `User wait for [Modal] dialog is visible` |
144
- | Table row | `User see [Users] table row with {{name}}` |
165
+ | Contains text | `User see [Message] text contains {{partial}}` |
166
+ | Wait for | `User wait for [Modal] dialog` |
167
+ | Table row | `User see [Username] row in [Users] table with {{name}}` |
168
+ | Table cell | `User see [Status] column with {{status}}` (row scoped) |
145
169
  | Table column | `User see [Email] column in [Users] table` |
170
+ | Table count | `User see [Users] table with {{count}}` |
171
+ | Table empty | `User see [Users] table is empty` |
172
+ | Table action | `User click [Edit] button in [Users] table with {{name}}` |
173
+ | Table match | `User see [Users] table match data:` + inline DataTable |
174
+ | Alert | `User click [OK] alert` |
175
+ | Frame | `User switch to [Payment] frame` |
176
+
177
+ ### Table Match Data
178
+
179
+ Verify multiple rows exist using filter-based matching (resilient to data changes and row reordering):
180
+
181
+ ```gherkin
182
+ Then User see [Users] table match data:
183
+ | ID | Name | Status |
184
+ | {{id_1}} | {{name_1}} | {{status_1}} |
185
+ | {{id_2}} | {{name_2}} | {{status_2}} |
186
+ ```
187
+
188
+ First row = headers, remaining rows = expected data. For single-row verification + actions, use row scope patterns instead.
146
189
 
147
- States: `hidden` `visible` `disabled` `enabled` `checked` `unchecked` `focused` `empty` `loading` `selected`
190
+ ### States
191
+
192
+ `hidden` `visible` `disabled` `enabled` `checked` `unchecked` `focused` `empty` `loading` `selected` `sorted ascending` `sorted descending`
193
+
194
+ ### Element Types
195
+
196
+ | Group | Types |
197
+ |---|---|
198
+ | **Context** | `page` `dialog` `modal` `drawer` `tab` `alert` `overlay` `step` |
199
+ | **Input** | `field` `textarea` `search` `dropdown` `option` `checkbox` `radio` `toggle` `uploader` `slider` `date-picker` |
200
+ | **Trigger** | `button` `link` `icon` `menuitem` `tag` |
201
+ | **Data** | `table` `row` `column` `cell` `list` `item` `card` `section` |
202
+ | **Feedback** | `message` `header` `label` `text` `tooltip` `badge` `breadcrumb` `image` |
203
+ | **System** | `key` `frame` `spinner` `progressbar` |
148
204
 
149
205
  ### Tags
150
206
 
151
207
  | Tag | Purpose |
152
208
  |---|---|
209
+ | `@auto` | Standard scenario, ready for automation |
210
+ | `@manual` | Skip scenario in generation |
211
+ | `@smoke` / `@regression` | Test suite grouping |
153
212
  | `@auth:role` | Use Playwright storage state for auth |
154
213
  | `@no-auth` | Disable inherited auth for this scenario |
155
214
  | `@steps:name` | Define reusable step group |
156
215
  | `@extend:name` | Inherit steps from another scenario |
157
- | `@manual` | Skip scenario in generation |
158
216
 
159
217
  ### YAML Selector Keys
160
218
 
@@ -167,10 +225,15 @@ Keys are **lowercase with spaces**, Unicode preserved:
167
225
 
168
226
  ```yaml
169
227
  search:
170
- type: 'placeholder' # testid, role, placeholder, label, text, locator, page
228
+ type: 'placeholder' # testid, role, placeholder, label, text, locator, page, upload, frame
171
229
  value: 'Search users' # placeholder text, role name, CSS selector, etc.
172
230
  name: 'Search' # accessible name (for role type)
173
231
  nth: 0 # element index (for multiple matches)
232
+ exact: true # exact name matching
233
+ columns: # table column config (for table type)
234
+ status:
235
+ index: 2
236
+ header: Status
174
237
  ```
175
238
 
176
239
  Priority: `data-testid` > `role+name` > `placeholder` > `label` > `text` > `CSS locator`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sun-asterisk/sungen",
3
- "version": "2.3.1",
3
+ "version": "2.4.1",
4
4
  "description": "Deterministic E2E Test Compiler - Gherkin + Selectors → Playwright tests",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/src/cli/index.ts CHANGED
@@ -17,7 +17,7 @@ async function main() {
17
17
  program
18
18
  .name('sungen')
19
19
  .description('Deterministic E2E Test Compiler — Gherkin + Selectors → Playwright')
20
- .version('2.3.1');
20
+ .version('2.4.1');
21
21
 
22
22
  // Global options
23
23
  program
@@ -5,6 +5,15 @@ import fs from 'fs';
5
5
  import path from 'path';
6
6
  import { SelectorResolver } from '../test-generator/utils/selector-resolver';
7
7
 
8
+ export interface DataTableRow {
9
+ cells: string[]; // Cell values in order
10
+ }
11
+
12
+ export interface ParsedDataTable {
13
+ headers: string[]; // First row = column headers
14
+ rows: DataTableRow[]; // Remaining rows = data rows
15
+ }
16
+
8
17
  export interface ParsedStep {
9
18
  keyword: string; // Given, When, Then, And, But
10
19
  text: string; // Original step text
@@ -16,6 +25,7 @@ export interface ParsedStep {
16
25
  featurePath?: string; // NEW: Feature path for page type (e.g., "/", "/dashboard")
17
26
  parentRef?: string; // Parent scope reference: "in [Parent Name] parentType" → parentRef = "Parent Name"
18
27
  parentType?: string; // Parent scope type: table, list, section, dialog, form
28
+ dataTable?: ParsedDataTable; // Inline data table (Cucumber DataTable syntax)
19
29
  }
20
30
 
21
31
  export interface ParsedScenario {
@@ -172,6 +182,18 @@ export class GherkinParser {
172
182
  nth = SelectorResolver.extractNthFromStep(afterElement);
173
183
  }
174
184
 
185
+ // Extract inline data table (Cucumber DataTable syntax)
186
+ let dataTable: ParsedDataTable | undefined;
187
+ if (step.dataTable && step.dataTable.rows && step.dataTable.rows.length >= 2) {
188
+ const rows = step.dataTable.rows;
189
+ dataTable = {
190
+ headers: rows[0].cells.map((cell: any) => cell.value),
191
+ rows: rows.slice(1).map((row: any) => ({
192
+ cells: row.cells.map((cell: any) => cell.value),
193
+ })),
194
+ };
195
+ }
196
+
175
197
  return {
176
198
  keyword: step.keyword.trim(),
177
199
  text: step.text, // Preserve original text (with parent scoping) for pattern matching
@@ -182,6 +204,7 @@ export class GherkinParser {
182
204
  nth,
183
205
  parentRef,
184
206
  parentType,
207
+ dataTable,
185
208
  };
186
209
  }
187
210
 
@@ -1,2 +1,2 @@
1
1
  { const tableRow = {{> locator}}.getByRole('row').filter({ hasText: '{{escapeQuotes filterValue}}' });
2
- await tableRow.getByRole('button', { name: '{{escapeQuotes elementName}}' }).{{action}}(); }
2
+ await tableRow.getByRole('{{elementRole}}', { name: '{{escapeQuotes elementName}}' }).{{action}}(); }
@@ -1 +1,5 @@
1
- await expect({{> locator}}.getByRole('columnheader', { name: '{{escapeQuotes columnName}}' })).toBeVisible();
1
+ {{~#if isGiven}}
2
+ await {{> locator}}.getByRole('columnheader', { name: '{{escapeQuotes columnName}}' }).waitFor();
3
+ {{~else}}
4
+ await expect({{> locator}}.getByRole('columnheader', { name: '{{escapeQuotes columnName}}' })).toBeVisible();
5
+ {{~/if}}
@@ -0,0 +1,15 @@
1
+ {{~#if isGiven~}}
2
+ {
3
+ const rows = {{> locator}}.locator('tbody').getByRole('row');
4
+ {{#each assertions}}
5
+ {{this}}
6
+ {{/each~}}
7
+ }
8
+ {{~else~}}
9
+ {
10
+ const rows = {{> locator}}.locator('tbody').getByRole('row');
11
+ {{#each assertions}}
12
+ {{this}}
13
+ {{/each~}}
14
+ }
15
+ {{~/if}}
@@ -1 +1,7 @@
1
- await expect({{> locator}}.getByRole('row').filter({ hasText: '{{escapeQuotes filterValue}}' })).toBeVisible();
1
+ {{~#if isGiven}}
2
+ const tableRow = {{> locator}}.getByRole('row').filter({ hasText: '{{escapeQuotes filterValue}}' });
3
+ await tableRow.waitFor();
4
+ {{~else}}
5
+ const tableRow = {{> locator}}.getByRole('row').filter({ hasText: '{{escapeQuotes filterValue}}' });
6
+ await expect(tableRow).toBeVisible();
7
+ {{~/if}}
@@ -1 +1,5 @@
1
- await expect({{> locator}}.getByRole('row').filter({ hasText: '{{escapeQuotes filterValue}}' })).toHaveCount(0);
1
+ {{~#if isGiven}}
2
+ await {{> locator}}.getByRole('row').filter({ hasText: '{{escapeQuotes filterValue}}' }).waitFor({ state: 'hidden' });
3
+ {{~else}}
4
+ await expect({{> locator}}.getByRole('row').filter({ hasText: '{{escapeQuotes filterValue}}' })).toHaveCount(0);
5
+ {{~/if}}
@@ -74,7 +74,8 @@ export class PatternRegistry {
74
74
  const resolved = pattern.resolver(step, context);
75
75
 
76
76
  // Auto-inject parent scoping if step has parentRef
77
- if (step.parentRef && step.parentType) {
77
+ // Skip for table-* patterns — they resolve the table name internally from step text
78
+ if (step.parentRef && step.parentType && !pattern.name.startsWith('table-')) {
78
79
  resolved.data.parentLocator = PatternRegistry.resolveParentLocator(
79
80
  step.parentRef, step.parentType, context
80
81
  );