@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.
- package/README.md +10 -11
- package/dist/cli/index.js +1 -1
- package/dist/generators/gherkin-parser/index.d.ts +8 -0
- package/dist/generators/gherkin-parser/index.d.ts.map +1 -1
- package/dist/generators/gherkin-parser/index.js +12 -0
- package/dist/generators/gherkin-parser/index.js.map +1 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/table-action-in-row.hbs +1 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/table-column-exists.hbs +5 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/table-match-data.hbs +15 -0
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/table-row-exists.hbs +7 -1
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/table-row-not-exists.hbs +5 -1
- package/dist/generators/test-generator/patterns/index.d.ts.map +1 -1
- package/dist/generators/test-generator/patterns/index.js +2 -1
- package/dist/generators/test-generator/patterns/index.js.map +1 -1
- package/dist/generators/test-generator/patterns/table-patterns.d.ts +12 -0
- package/dist/generators/test-generator/patterns/table-patterns.d.ts.map +1 -1
- package/dist/generators/test-generator/patterns/table-patterns.js +142 -98
- package/dist/generators/test-generator/patterns/table-patterns.js.map +1 -1
- package/dist/generators/test-generator/patterns/types.d.ts +2 -0
- package/dist/generators/test-generator/patterns/types.d.ts.map +1 -1
- package/dist/generators/test-generator/step-mapper.d.ts +13 -0
- package/dist/generators/test-generator/step-mapper.d.ts.map +1 -1
- package/dist/generators/test-generator/step-mapper.js +80 -0
- package/dist/generators/test-generator/step-mapper.js.map +1 -1
- package/dist/orchestrator/ai-rules-updater.d.ts.map +1 -1
- package/dist/orchestrator/ai-rules-updater.js +8 -6
- package/dist/orchestrator/ai-rules-updater.js.map +1 -1
- package/dist/orchestrator/project-initializer.d.ts.map +1 -1
- package/dist/orchestrator/project-initializer.js +33 -2
- package/dist/orchestrator/project-initializer.js.map +1 -1
- package/dist/orchestrator/screen-manager.js +1 -1
- package/dist/orchestrator/screen-manager.js.map +1 -1
- package/dist/orchestrator/templates/ai-instructions/claude-cmd-add-screen.md +5 -5
- package/{src/orchestrator/templates/ai-instructions/claude-cmd-make-tc.md → dist/orchestrator/templates/ai-instructions/claude-cmd-create-test.md} +7 -7
- package/dist/orchestrator/templates/ai-instructions/claude-cmd-review.md +21 -0
- package/dist/orchestrator/templates/ai-instructions/claude-cmd-run-test.md +32 -0
- package/dist/orchestrator/templates/ai-instructions/claude-config.md +65 -12
- package/dist/orchestrator/templates/ai-instructions/claude-skill-error-mapping.md +128 -52
- package/dist/orchestrator/templates/ai-instructions/claude-skill-gherkin-syntax.md +15 -39
- package/dist/orchestrator/templates/ai-instructions/claude-skill-selector-fix.md +72 -259
- package/dist/orchestrator/templates/ai-instructions/claude-skill-tc-generation.md +57 -205
- package/dist/orchestrator/templates/ai-instructions/claude-skill-tc-review.md +104 -0
- package/dist/orchestrator/templates/ai-instructions/claude-skill-viewpoint.md +188 -0
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-add-screen.md +4 -4
- package/dist/orchestrator/templates/ai-instructions/{copilot-cmd-make-tc.md → copilot-cmd-create-test.md} +8 -8
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-review.md +24 -0
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-run-test.md +35 -0
- package/dist/orchestrator/templates/ai-instructions/copilot-config.md +66 -13
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-error-mapping.md +128 -52
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-gherkin-syntax.md +15 -39
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-selector-fix.md +72 -234
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-tc-generation.md +57 -205
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-tc-review.md +104 -0
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint.md +188 -0
- package/dist/orchestrator/templates/readme.md +85 -22
- package/package.json +1 -1
- package/src/cli/index.ts +1 -1
- package/src/generators/gherkin-parser/index.ts +23 -0
- package/src/generators/test-generator/adapters/playwright/templates/steps/actions/table-action-in-row.hbs +1 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/table-column-exists.hbs +5 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/table-match-data.hbs +15 -0
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/table-row-exists.hbs +7 -1
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/table-row-not-exists.hbs +5 -1
- package/src/generators/test-generator/patterns/index.ts +2 -1
- package/src/generators/test-generator/patterns/table-patterns.ts +155 -111
- package/src/generators/test-generator/patterns/types.ts +2 -0
- package/src/generators/test-generator/step-mapper.ts +87 -1
- package/src/orchestrator/ai-rules-updater.ts +8 -6
- package/src/orchestrator/project-initializer.ts +38 -2
- package/src/orchestrator/screen-manager.ts +1 -1
- package/src/orchestrator/templates/ai-instructions/claude-cmd-add-screen.md +5 -5
- package/{dist/orchestrator/templates/ai-instructions/claude-cmd-make-tc.md → src/orchestrator/templates/ai-instructions/claude-cmd-create-test.md} +7 -7
- package/src/orchestrator/templates/ai-instructions/claude-cmd-review.md +21 -0
- package/src/orchestrator/templates/ai-instructions/claude-cmd-run-test.md +32 -0
- package/src/orchestrator/templates/ai-instructions/claude-config.md +65 -12
- package/src/orchestrator/templates/ai-instructions/claude-skill-error-mapping.md +128 -52
- package/src/orchestrator/templates/ai-instructions/claude-skill-gherkin-syntax.md +15 -39
- package/src/orchestrator/templates/ai-instructions/claude-skill-selector-fix.md +72 -259
- package/src/orchestrator/templates/ai-instructions/claude-skill-tc-generation.md +57 -205
- package/src/orchestrator/templates/ai-instructions/claude-skill-tc-review.md +104 -0
- package/src/orchestrator/templates/ai-instructions/claude-skill-viewpoint.md +188 -0
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-add-screen.md +4 -4
- package/src/orchestrator/templates/ai-instructions/{copilot-cmd-make-tc.md → copilot-cmd-create-test.md} +8 -8
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-review.md +24 -0
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-run-test.md +35 -0
- package/src/orchestrator/templates/ai-instructions/copilot-config.md +66 -13
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-error-mapping.md +128 -52
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-gherkin-syntax.md +15 -39
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-selector-fix.md +72 -234
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-tc-generation.md +57 -205
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-tc-review.md +104 -0
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint.md +188 -0
- package/src/orchestrator/templates/readme.md +85 -22
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/table-cell-by-filter.hbs +0 -2
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/table-cell-by-index.hbs +0 -2
- package/dist/orchestrator/templates/ai-instructions/claude-cmd-make-test.md +0 -29
- package/dist/orchestrator/templates/ai-instructions/claude-skill-gherkin-review.md +0 -228
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-make-test.md +0 -32
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-gherkin-review.md +0 -228
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/table-cell-by-filter.hbs +0 -2
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/table-cell-by-index.hbs +0 -2
- package/src/orchestrator/templates/ai-instructions/claude-cmd-make-test.md +0 -29
- package/src/orchestrator/templates/ai-instructions/claude-skill-gherkin-review.md +0 -228
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-make-test.md +0 -32
- 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- │────────▶│ /
|
|
43
|
-
│ screen │ │
|
|
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:
|
|
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:
|
|
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> [
|
|
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
|
-
- `{{
|
|
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
|
-
|
|
|
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
|
-
|
|
|
144
|
-
|
|
|
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
|
|
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
package/src/cli/index.ts
CHANGED
|
@@ -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('
|
|
2
|
+
await tableRow.getByRole('{{elementRole}}', { name: '{{escapeQuotes elementName}}' }).{{action}}(); }
|
|
@@ -1 +1,5 @@
|
|
|
1
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
);
|