@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
package/README.md
CHANGED
|
@@ -218,13 +218,12 @@ Feature: Login Screen
|
|
|
218
218
|
| Pattern | Example |
|
|
219
219
|
|---|---|
|
|
220
220
|
| Column exists | `User see [Email] column in [Users] table` |
|
|
221
|
-
| Row exists | `User see [Users] table
|
|
222
|
-
|
|
|
223
|
-
| Row count | `User see [Users] table with {{count}}
|
|
224
|
-
| Cell by filter | `User see [Users] table row with {{name}} has [Status] with {{status}}` |
|
|
225
|
-
| Cell by index | `User see [Users] table row 1 [Name] cell with {{name}}` |
|
|
226
|
-
| Action in row | `User click [Edit] in [Users] table row with {{name}}` |
|
|
221
|
+
| Row exists | `User see [Username] row in [Users] table with {{name}}` |
|
|
222
|
+
| Row hidden | `User see [Username] row in [Users] table with {{name}} is hidden` |
|
|
223
|
+
| Row count | `User see [Users] table with {{count}}` |
|
|
227
224
|
| Empty table | `User see [Users] table is empty` |
|
|
225
|
+
| Cell value | `User see [Status] column with {{status}}` (row scoped) |
|
|
226
|
+
| Action in row | `User click [Edit] button in [Users] table with {{name}}` |
|
|
228
227
|
|
|
229
228
|
### Scope
|
|
230
229
|
|
|
@@ -336,11 +335,11 @@ specs/generated/<name>/
|
|
|
336
335
|
|
|
337
336
|
Full documentation at **[sungen.sun-asterisk.vn](https://sungen.sun-asterisk.vn)**
|
|
338
337
|
|
|
339
|
-
- **[Installation Guide](https://
|
|
340
|
-
- **[Quick Start](https://
|
|
341
|
-
- **[Selector YAML Guide](https://
|
|
342
|
-
- **[Tips & Troubleshooting](https://
|
|
343
|
-
- **[Gherkin
|
|
338
|
+
- **[Installation Guide](https://sun-asterisk.github.io/sungen/docs/guides/installation)** — Windows (Git Bash + VS Code + Copilot), macOS, Linux
|
|
339
|
+
- **[Quick Start](https://sun-asterisk.github.io/sungen/docs/guides/quick-start)** — From zero to running tests
|
|
340
|
+
- **[Selector YAML Guide](https://sun-asterisk.github.io/sungen/docs/guides/selector-override)** — NFC keys, auto-infer, Japanese/Vietnamese support
|
|
341
|
+
- **[Tips & Troubleshooting](https://sun-asterisk.github.io/sungen/docs/guides/tips)** — When AI gets stuck fixing tests
|
|
342
|
+
- **[Gherkin Patterns](https://sun-asterisk.github.io/sungen/docs/gherkin/patterns)** — Full grammar, all patterns, compiler rules
|
|
344
343
|
|
|
345
344
|
---
|
|
346
345
|
|
package/dist/cli/index.js
CHANGED
|
@@ -16,7 +16,7 @@ async function main() {
|
|
|
16
16
|
program
|
|
17
17
|
.name('sungen')
|
|
18
18
|
.description('Deterministic E2E Test Compiler — Gherkin + Selectors → Playwright')
|
|
19
|
-
.version('2.
|
|
19
|
+
.version('2.4.1');
|
|
20
20
|
// Global options
|
|
21
21
|
program
|
|
22
22
|
.option('-v, --verbose', 'Enable verbose logging');
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
export interface DataTableRow {
|
|
2
|
+
cells: string[];
|
|
3
|
+
}
|
|
4
|
+
export interface ParsedDataTable {
|
|
5
|
+
headers: string[];
|
|
6
|
+
rows: DataTableRow[];
|
|
7
|
+
}
|
|
1
8
|
export interface ParsedStep {
|
|
2
9
|
keyword: string;
|
|
3
10
|
text: string;
|
|
@@ -9,6 +16,7 @@ export interface ParsedStep {
|
|
|
9
16
|
featurePath?: string;
|
|
10
17
|
parentRef?: string;
|
|
11
18
|
parentType?: string;
|
|
19
|
+
dataTable?: ParsedDataTable;
|
|
12
20
|
}
|
|
13
21
|
export interface ParsedScenario {
|
|
14
22
|
name: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/generators/gherkin-parser/index.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/generators/gherkin-parser/index.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,IAAI,EAAE,YAAY,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,eAAe,CAAC;CAC7B;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B,SAAS,EAAE,cAAc,EAAE,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,MAAM,CAAiB;;IAS/B;;OAEG;IACH,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa;IA6BjD;;OAEG;IACH,OAAO,CAAC,eAAe;IAgBvB;;OAEG;IACH,OAAO,CAAC,cAAc;IAkBtB;;OAEG;IACH,OAAO,CAAC,SAAS;IA2EjB;;OAEG;IACH,MAAM,CAAC,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE;CAmB3D"}
|
|
@@ -156,6 +156,17 @@ class GherkinParser {
|
|
|
156
156
|
const afterElement = text.slice(selectorMatch.index + selectorMatch[0].length);
|
|
157
157
|
nth = selector_resolver_1.SelectorResolver.extractNthFromStep(afterElement);
|
|
158
158
|
}
|
|
159
|
+
// Extract inline data table (Cucumber DataTable syntax)
|
|
160
|
+
let dataTable;
|
|
161
|
+
if (step.dataTable && step.dataTable.rows && step.dataTable.rows.length >= 2) {
|
|
162
|
+
const rows = step.dataTable.rows;
|
|
163
|
+
dataTable = {
|
|
164
|
+
headers: rows[0].cells.map((cell) => cell.value),
|
|
165
|
+
rows: rows.slice(1).map((row) => ({
|
|
166
|
+
cells: row.cells.map((cell) => cell.value),
|
|
167
|
+
})),
|
|
168
|
+
};
|
|
169
|
+
}
|
|
159
170
|
return {
|
|
160
171
|
keyword: step.keyword.trim(),
|
|
161
172
|
text: step.text, // Preserve original text (with parent scoping) for pattern matching
|
|
@@ -166,6 +177,7 @@ class GherkinParser {
|
|
|
166
177
|
nth,
|
|
167
178
|
parentRef,
|
|
168
179
|
parentType,
|
|
180
|
+
dataTable,
|
|
169
181
|
};
|
|
170
182
|
}
|
|
171
183
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/generators/gherkin-parser/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,cAAc;AACd,2DAA6C;AAC7C,6DAA+C;AAC/C,4CAAoB;AACpB,gDAAwB;AACxB,iFAA6E;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/generators/gherkin-parser/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -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}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/generators/test-generator/patterns/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAWtD;;GAEG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAqB;;IAMrC;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAe/B;;OAEG;IACH,eAAe,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IAK3C;;OAEG;IACH,WAAW,CAAC,IAAI,EAAE,UAAU,GAAG,WAAW,GAAG,IAAI;IASjD;;;OAGG;IACH,YAAY,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,cAAc,GAAG,UAAU,GAAG,IAAI;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/generators/test-generator/patterns/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAWtD;;GAEG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAqB;;IAMrC;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAe/B;;OAEG;IACH,eAAe,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IAK3C;;OAEG;IACH,WAAW,CAAC,IAAI,EAAE,UAAU,GAAG,WAAW,GAAG,IAAI;IASjD;;;OAGG;IACH,YAAY,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,cAAc,GAAG,UAAU,GAAG,IAAI;IAgC1E;;;;;;;OAOG;IACH,OAAO,CAAC,MAAM,CAAC,oBAAoB;IAyBnC;;OAEG;IACH,OAAO,CAAC,cAAc;IAOtB;;OAEG;IACH,WAAW,IAAI,WAAW,EAAE;IAI5B;;OAEG;IACH,eAAe,IAAI,MAAM;CAG1B;AAGD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,cAAc,SAAS,CAAC"}
|
|
@@ -79,7 +79,8 @@ class PatternRegistry {
|
|
|
79
79
|
if (pattern.resolver) {
|
|
80
80
|
const resolved = pattern.resolver(step, context);
|
|
81
81
|
// Auto-inject parent scoping if step has parentRef
|
|
82
|
-
|
|
82
|
+
// Skip for table-* patterns — they resolve the table name internally from step text
|
|
83
|
+
if (step.parentRef && step.parentType && !pattern.name.startsWith('table-')) {
|
|
83
84
|
resolved.data.parentLocator = PatternRegistry.resolveParentLocator(step.parentRef, step.parentType, context);
|
|
84
85
|
}
|
|
85
86
|
const code = context.templateEngine.renderStep(resolved.templateName, resolved.data);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/generators/test-generator/patterns/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAGA,+DAA2D;AAC3D,mDAA+C;AAC/C,iEAA6D;AAC7D,6DAAyD;AACzD,qDAAiD;AACjD,2DAAuD;AACvD,uDAAmD;AACnD,qDAAiD;AACjD,qDAAiD;AAEjD;;GAEG;AACH,MAAa,eAAe;IAG1B;QAFQ,aAAQ,GAAkB,EAAE,CAAC;QAGnC,IAAI,CAAC,uBAAuB,EAAE,CAAC;IACjC,CAAC;IAED;;OAEG;IACK,uBAAuB;QAC7B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,8BAAa,CAAC,CAAC;QACrC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,wCAAkB,CAAC,CAAC;QAC1C,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,4BAAY,CAAC,CAAC;QACpC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,0CAAmB,CAAC,CAAC;QAC3C,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,sCAAiB,CAAC,CAAC;QACzC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,oCAAgB,CAAC,CAAC;QACxC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,gCAAc,CAAC,CAAC;QACtC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,8BAAa,CAAC,CAAC;QACrC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,8BAAa,CAAC,CAAC;QAErC,kCAAkC;QAClC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC;IACtE,CAAC;IAED;;OAEG;IACH,eAAe,CAAC,OAAoB;QAClC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC5B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC;IACtE,CAAC;IAED;;OAEG;IACH,WAAW,CAAC,IAAgB;QAC1B,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACpC,IAAI,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC/C,OAAO,OAAO,CAAC;YACjB,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;OAGG;IACH,YAAY,CAAC,IAAgB,EAAE,OAAuB;QACpD,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QACvC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,IAAI,CAAC;QACd,CAAC;QAED,+DAA+D;QAC/D,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YACrB,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YAEjD,mDAAmD;YACnD,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/generators/test-generator/patterns/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Table Patterns
|
|
3
3
|
* Handles: table row assertions, table cell lookups, actions in table rows
|
|
4
|
+
*
|
|
5
|
+
* Syntax (v2.4 final):
|
|
6
|
+
* - User see [Col] column in [Table] table # column exists
|
|
7
|
+
* - User see [Ref] row in [Table] table with {{value}} # row exists (enters row scope)
|
|
8
|
+
* - User see [Ref] row in [Table] table with {{value}} is hidden # row hidden
|
|
9
|
+
* - User see [Table] table with {{count}} # row count
|
|
10
|
+
* - User see [Table] table is empty # empty table
|
|
11
|
+
* - User see [Col] column with {{value}} # cell value (row scoped — handled in step-mapper)
|
|
12
|
+
* - User click [Act] button in [Table] table with {{filter}} # action in row
|
|
13
|
+
* - User see [Table] table match data: # exact table match with inline DataTable
|
|
14
|
+
* | Header1 | Header2 |
|
|
15
|
+
* | {{value1}} | {{value2}} |
|
|
4
16
|
*/
|
|
5
17
|
import { StepPattern } from './types';
|
|
6
18
|
export declare const tablePatterns: StepPattern[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"table-patterns.d.ts","sourceRoot":"","sources":["../../../../src/generators/test-generator/patterns/table-patterns.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"table-patterns.d.ts","sourceRoot":"","sources":["../../../../src/generators/test-generator/patterns/table-patterns.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,WAAW,EAAkB,MAAM,SAAS,CAAC;AAkBtD,eAAO,MAAM,aAAa,EAAE,WAAW,EAmPtC,CAAC"}
|
|
@@ -2,54 +2,85 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Table Patterns
|
|
4
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}} |
|
|
5
17
|
*/
|
|
6
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
19
|
exports.tablePatterns = void 0;
|
|
20
|
+
/** Helper: check if current step is in a Given context */
|
|
21
|
+
function isGivenContext(context) {
|
|
22
|
+
return context.effectiveKeyword === 'Given';
|
|
23
|
+
}
|
|
24
|
+
/** Map Gherkin element type to Playwright ARIA role */
|
|
25
|
+
const typeToRole = {
|
|
26
|
+
button: 'button',
|
|
27
|
+
link: 'link',
|
|
28
|
+
checkbox: 'checkbox',
|
|
29
|
+
icon: 'img',
|
|
30
|
+
image: 'img',
|
|
31
|
+
radio: 'radio',
|
|
32
|
+
switch: 'switch',
|
|
33
|
+
};
|
|
8
34
|
exports.tablePatterns = [
|
|
9
|
-
// "User see [
|
|
10
|
-
// Also accepts: "User see [Users] table has {{count}} rows" (backward compat)
|
|
35
|
+
// "User see [Table] table with {{count}}" — row count (no "rows" keyword needed)
|
|
11
36
|
{
|
|
12
37
|
name: 'table-row-count',
|
|
13
38
|
matcher: (step) => {
|
|
14
|
-
return
|
|
15
|
-
/\
|
|
16
|
-
!!step.dataRef
|
|
39
|
+
return step.elementType === 'table' &&
|
|
40
|
+
/\btable\s+with\b/i.test(step.text) &&
|
|
41
|
+
!!step.dataRef &&
|
|
42
|
+
!/\brow\b/i.test(step.text) &&
|
|
43
|
+
!/\bcolumn\b/i.test(step.text) &&
|
|
44
|
+
!/\bempty\b/i.test(step.text);
|
|
17
45
|
},
|
|
18
46
|
resolver: (step, context) => {
|
|
19
47
|
const resolved = context.selectorResolver.resolveSelector(step.selectorRef, context.featureName, 'table', step.nth);
|
|
20
48
|
const count = context.dataResolver.resolveData(step.dataRef, context.featureName);
|
|
49
|
+
const isGiven = isGivenContext(context);
|
|
21
50
|
return {
|
|
22
51
|
templateName: 'table-row-count',
|
|
23
|
-
data: { ...resolved, expectedCount: count },
|
|
24
|
-
comment:
|
|
52
|
+
data: { ...resolved, expectedCount: count, isGiven },
|
|
53
|
+
comment: `${isGiven ? 'Wait' : 'Assert'} ${step.selectorRef} table has ${count} rows`,
|
|
25
54
|
};
|
|
26
55
|
},
|
|
27
56
|
priority: 16,
|
|
28
57
|
},
|
|
29
|
-
// "User see [
|
|
30
|
-
// Preferred: "User see [Email] column in [Users] table" (parent scoping)
|
|
58
|
+
// "User see [Col] column in [Table] table"
|
|
31
59
|
{
|
|
32
60
|
name: 'table-column-exists',
|
|
33
61
|
matcher: (step) => {
|
|
34
|
-
return /\
|
|
35
|
-
/\
|
|
62
|
+
return /\bcolumn\s+in\b/i.test(step.text) &&
|
|
63
|
+
/\btable\b/i.test(step.text) &&
|
|
64
|
+
!step.dataRef;
|
|
36
65
|
},
|
|
37
66
|
resolver: (step, context) => {
|
|
38
|
-
//
|
|
67
|
+
// brackets[0] = Col, brackets[1] = Table
|
|
39
68
|
const brackets = step.text.match(/\[([^\]]+)\]/g) || [];
|
|
40
|
-
const columnName = brackets
|
|
69
|
+
const columnName = brackets[0]?.replace(/[\[\]]/g, '') || 'Unknown';
|
|
70
|
+
const tableName = brackets.length >= 2
|
|
41
71
|
? brackets[1].replace(/[\[\]]/g, '')
|
|
42
|
-
: '
|
|
43
|
-
const resolved = context.selectorResolver.resolveSelector(
|
|
72
|
+
: brackets[0]?.replace(/[\[\]]/g, '') || '';
|
|
73
|
+
const resolved = context.selectorResolver.resolveSelector(tableName, context.featureName, 'table', step.nth);
|
|
74
|
+
const isGiven = isGivenContext(context);
|
|
44
75
|
return {
|
|
45
76
|
templateName: 'table-column-exists',
|
|
46
|
-
data: { ...resolved, columnName },
|
|
47
|
-
comment:
|
|
77
|
+
data: { ...resolved, columnName, isGiven },
|
|
78
|
+
comment: `${isGiven ? 'Wait' : 'Assert'} ${columnName} column in ${tableName} table`,
|
|
48
79
|
};
|
|
49
80
|
},
|
|
50
81
|
priority: 16,
|
|
51
82
|
},
|
|
52
|
-
// "User see [
|
|
83
|
+
// "User see [Table] table is empty"
|
|
53
84
|
{
|
|
54
85
|
name: 'table-is-empty',
|
|
55
86
|
matcher: (step) => {
|
|
@@ -57,139 +88,152 @@ exports.tablePatterns = [
|
|
|
57
88
|
},
|
|
58
89
|
resolver: (step, context) => {
|
|
59
90
|
const resolved = context.selectorResolver.resolveSelector(step.selectorRef, context.featureName, 'table', step.nth);
|
|
91
|
+
const isGiven = isGivenContext(context);
|
|
60
92
|
return {
|
|
61
93
|
templateName: 'table-empty',
|
|
62
|
-
data: { ...resolved },
|
|
63
|
-
comment:
|
|
94
|
+
data: { ...resolved, isGiven },
|
|
95
|
+
comment: `${isGiven ? 'Wait' : 'Assert'} ${step.selectorRef} table is empty`,
|
|
64
96
|
};
|
|
65
97
|
},
|
|
66
98
|
priority: 16,
|
|
67
99
|
},
|
|
68
|
-
// "User see [
|
|
100
|
+
// "User see [Ref] row in [Table] table with {{value}}" — row exists (enters row scope)
|
|
69
101
|
{
|
|
70
|
-
name: 'table-
|
|
102
|
+
name: 'table-row-exists',
|
|
71
103
|
matcher: (step) => {
|
|
72
|
-
return
|
|
73
|
-
/\
|
|
104
|
+
return step.elementType === 'row' &&
|
|
105
|
+
/\bin\b.*\btable\b/i.test(step.text) &&
|
|
106
|
+
/\bwith\b/i.test(step.text) &&
|
|
107
|
+
!!step.dataRef &&
|
|
108
|
+
!/\bis\s+hidden\b/i.test(step.text);
|
|
74
109
|
},
|
|
75
110
|
resolver: (step, context) => {
|
|
76
|
-
//
|
|
111
|
+
// brackets[0] = Ref (row label), brackets[1] = Table
|
|
77
112
|
const brackets = step.text.match(/\[([^\]]+)\]/g) || [];
|
|
78
|
-
const
|
|
79
|
-
const
|
|
113
|
+
const rowLabel = brackets[0]?.replace(/[\[\]]/g, '') || '';
|
|
114
|
+
const tableName = brackets.length >= 2
|
|
80
115
|
? brackets[1].replace(/[\[\]]/g, '')
|
|
81
116
|
: '';
|
|
82
|
-
// Extract data refs: first is filter, second is cell value
|
|
83
|
-
const dataRefs = step.text.match(/\{\{([^}]+)\}\}/g) || [];
|
|
84
|
-
const filterRef = dataRefs[0]?.replace(/\{\{|\}\}/g, '') || '';
|
|
85
|
-
const valueRef = dataRefs.length >= 2
|
|
86
|
-
? dataRefs[1].replace(/\{\{|\}\}/g, '')
|
|
87
|
-
: '';
|
|
88
|
-
const filterValue = filterRef
|
|
89
|
-
? context.dataResolver.resolveData(filterRef, context.featureName)
|
|
90
|
-
: '';
|
|
91
|
-
const cellValue = valueRef
|
|
92
|
-
? context.dataResolver.resolveData(valueRef, context.featureName)
|
|
93
|
-
: '';
|
|
94
117
|
const resolved = context.selectorResolver.resolveSelector(tableName, context.featureName, 'table', step.nth);
|
|
118
|
+
const filterValue = context.dataResolver.resolveData(step.dataRef, context.featureName);
|
|
119
|
+
const isGiven = isGivenContext(context);
|
|
95
120
|
return {
|
|
96
|
-
templateName: 'table-
|
|
97
|
-
data: { ...resolved, filterValue,
|
|
98
|
-
comment:
|
|
121
|
+
templateName: 'table-row-exists',
|
|
122
|
+
data: { ...resolved, filterValue, isGiven },
|
|
123
|
+
comment: `${isGiven ? 'Wait' : 'Assert'} ${rowLabel} row in ${tableName} table with ${step.dataRef}`,
|
|
99
124
|
};
|
|
100
125
|
},
|
|
101
126
|
priority: 17,
|
|
102
127
|
},
|
|
103
|
-
// "User see [
|
|
128
|
+
// "User see [Ref] row in [Table] table with {{value}} is hidden"
|
|
104
129
|
{
|
|
105
|
-
name: 'table-
|
|
130
|
+
name: 'table-row-hidden',
|
|
106
131
|
matcher: (step) => {
|
|
107
|
-
return
|
|
108
|
-
/\
|
|
132
|
+
return step.elementType === 'row' &&
|
|
133
|
+
/\bin\b.*\btable\b/i.test(step.text) &&
|
|
134
|
+
/\bwith\b/i.test(step.text) &&
|
|
135
|
+
!!step.dataRef &&
|
|
136
|
+
/\bis\s+hidden\b/i.test(step.text);
|
|
109
137
|
},
|
|
110
138
|
resolver: (step, context) => {
|
|
139
|
+
// brackets[0] = Ref (row label), brackets[1] = Table
|
|
111
140
|
const brackets = step.text.match(/\[([^\]]+)\]/g) || [];
|
|
112
|
-
const
|
|
113
|
-
const
|
|
141
|
+
const rowLabel = brackets[0]?.replace(/[\[\]]/g, '') || '';
|
|
142
|
+
const tableName = brackets.length >= 2
|
|
114
143
|
? brackets[1].replace(/[\[\]]/g, '')
|
|
115
144
|
: '';
|
|
116
|
-
const rowMatch = step.text.match(/\brow\s+(\d+)\b/i);
|
|
117
|
-
const rowIndex = rowMatch ? parseInt(rowMatch[1], 10) : 1;
|
|
118
|
-
const cellValue = step.dataRef
|
|
119
|
-
? context.dataResolver.resolveData(step.dataRef, context.featureName)
|
|
120
|
-
: '';
|
|
121
145
|
const resolved = context.selectorResolver.resolveSelector(tableName, context.featureName, 'table', step.nth);
|
|
122
|
-
return {
|
|
123
|
-
templateName: 'table-cell-by-index',
|
|
124
|
-
data: { ...resolved, rowIndex, columnName, cellValue },
|
|
125
|
-
comment: `Assert ${tableName} table row ${rowIndex} ${columnName} cell = ${step.dataRef}`,
|
|
126
|
-
};
|
|
127
|
-
},
|
|
128
|
-
priority: 17,
|
|
129
|
-
},
|
|
130
|
-
// "User see [Users] table row with {{name}}" (preferred)
|
|
131
|
-
// Also accepts: "User see [Users] table has row with {{name}}" (backward compat)
|
|
132
|
-
{
|
|
133
|
-
name: 'table-row-exists',
|
|
134
|
-
matcher: (step) => {
|
|
135
|
-
return /\btable\s+(?:has\s+)?row\s+with\b/i.test(step.text) && !!step.dataRef;
|
|
136
|
-
},
|
|
137
|
-
resolver: (step, context) => {
|
|
138
|
-
const resolved = context.selectorResolver.resolveSelector(step.selectorRef, context.featureName, 'table', step.nth);
|
|
139
|
-
const filterValue = context.dataResolver.resolveData(step.dataRef, context.featureName);
|
|
140
|
-
return {
|
|
141
|
-
templateName: 'table-row-exists',
|
|
142
|
-
data: { ...resolved, filterValue },
|
|
143
|
-
comment: `Assert ${step.selectorRef} table has row with ${step.dataRef}`,
|
|
144
|
-
};
|
|
145
|
-
},
|
|
146
|
-
priority: 18,
|
|
147
|
-
},
|
|
148
|
-
// "User see [Users] table has no row with {{name}}"
|
|
149
|
-
{
|
|
150
|
-
name: 'table-row-not-exists',
|
|
151
|
-
matcher: (step) => {
|
|
152
|
-
return /\btable\s+has\s+no\s+row\s+with\b/i.test(step.text) && !!step.dataRef;
|
|
153
|
-
},
|
|
154
|
-
resolver: (step, context) => {
|
|
155
|
-
const resolved = context.selectorResolver.resolveSelector(step.selectorRef, context.featureName, 'table', step.nth);
|
|
156
146
|
const filterValue = context.dataResolver.resolveData(step.dataRef, context.featureName);
|
|
147
|
+
const isGiven = isGivenContext(context);
|
|
157
148
|
return {
|
|
158
149
|
templateName: 'table-row-not-exists',
|
|
159
|
-
data: { ...resolved, filterValue },
|
|
160
|
-
comment:
|
|
150
|
+
data: { ...resolved, filterValue, isGiven },
|
|
151
|
+
comment: `${isGiven ? 'Wait' : 'Assert'} ${rowLabel} row in ${tableName} table is hidden`,
|
|
161
152
|
};
|
|
162
153
|
},
|
|
163
154
|
priority: 19,
|
|
164
155
|
},
|
|
165
|
-
// "User click [
|
|
156
|
+
// "User click [Act] button in [Table] table with {{filter}}" — action in row
|
|
166
157
|
{
|
|
167
158
|
name: 'table-action-in-row',
|
|
168
159
|
matcher: (step) => {
|
|
169
|
-
return /\bin\b.*\btable\
|
|
160
|
+
return /\bin\b.*\btable\b/i.test(step.text) &&
|
|
161
|
+
/\bwith\b/i.test(step.text) &&
|
|
162
|
+
!!step.dataRef &&
|
|
163
|
+
step.elementType !== 'column' &&
|
|
164
|
+
step.elementType !== 'row' &&
|
|
165
|
+
step.elementType !== 'table';
|
|
170
166
|
},
|
|
171
167
|
resolver: (step, context) => {
|
|
168
|
+
// brackets[0] = Act (element name), brackets[1] = Table
|
|
172
169
|
const brackets = step.text.match(/\[([^\]]+)\]/g) || [];
|
|
173
170
|
const elementName = brackets[0]?.replace(/[\[\]]/g, '') || '';
|
|
174
171
|
const tableName = brackets.length >= 2
|
|
175
172
|
? brackets[1].replace(/[\[\]]/g, '')
|
|
176
173
|
: '';
|
|
177
|
-
const
|
|
178
|
-
|
|
179
|
-
const filterValue = filterRef
|
|
180
|
-
? context.dataResolver.resolveData(filterRef, context.featureName)
|
|
174
|
+
const filterValue = step.dataRef
|
|
175
|
+
? context.dataResolver.resolveData(step.dataRef, context.featureName)
|
|
181
176
|
: '';
|
|
182
177
|
const tableResolved = context.selectorResolver.resolveSelector(tableName, context.featureName, 'table', 0);
|
|
183
|
-
// Determine action
|
|
178
|
+
// Determine action from step text
|
|
184
179
|
const actionMatch = step.text.match(/\b(click|check|uncheck)\b/i);
|
|
185
180
|
const action = actionMatch ? actionMatch[1].toLowerCase() : 'click';
|
|
181
|
+
// Extract element type (word after [Act]) and map to ARIA role
|
|
182
|
+
const elementTypeMatch = step.text.match(/\]\s+([\w-]+)\s+in\b/i);
|
|
183
|
+
const elementType = elementTypeMatch ? elementTypeMatch[1].toLowerCase() : 'button';
|
|
184
|
+
const elementRole = typeToRole[elementType] || elementType;
|
|
186
185
|
return {
|
|
187
186
|
templateName: 'table-action-in-row',
|
|
188
|
-
data: { ...tableResolved, elementName, filterValue, action },
|
|
189
|
-
comment: `${action} ${elementName} in ${tableName} table row with ${
|
|
187
|
+
data: { ...tableResolved, elementName, filterValue, action, elementRole },
|
|
188
|
+
comment: `${action} ${elementName} in ${tableName} table row with ${step.dataRef}`,
|
|
190
189
|
};
|
|
191
190
|
},
|
|
192
191
|
priority: 17,
|
|
193
192
|
},
|
|
193
|
+
// "User see [Table] table match data:" — filter-based table match with inline DataTable
|
|
194
|
+
// First row = headers, remaining rows = expected data
|
|
195
|
+
// Uses filter({ hasText }) per row — resilient to data changes, row ordering, extra rows
|
|
196
|
+
{
|
|
197
|
+
name: 'table-match-data',
|
|
198
|
+
matcher: (step) => {
|
|
199
|
+
return step.elementType === 'table' &&
|
|
200
|
+
/\btable\s+match\s+data\b/i.test(step.text) &&
|
|
201
|
+
!!step.dataTable;
|
|
202
|
+
},
|
|
203
|
+
resolver: (step, context) => {
|
|
204
|
+
const resolved = context.selectorResolver.resolveSelector(step.selectorRef, context.featureName, 'table', step.nth);
|
|
205
|
+
const dataTable = step.dataTable;
|
|
206
|
+
// Resolve {{variable}} references in cell values
|
|
207
|
+
const resolvedRows = dataTable.rows.map(row => ({
|
|
208
|
+
cells: row.cells.map(cell => {
|
|
209
|
+
const varMatch = cell.match(/^\{\{([a-z0-9\-\.\_]+)\}\}$/i);
|
|
210
|
+
if (varMatch) {
|
|
211
|
+
return context.dataResolver.resolveData(varMatch[1], context.featureName);
|
|
212
|
+
}
|
|
213
|
+
return cell;
|
|
214
|
+
}),
|
|
215
|
+
}));
|
|
216
|
+
// Pre-compute filter-based assertion lines
|
|
217
|
+
// For each expected row: chain .filter({ hasText }) for all cell values, then assert visible
|
|
218
|
+
const assertions = [];
|
|
219
|
+
for (const row of resolvedRows) {
|
|
220
|
+
const filters = row.cells
|
|
221
|
+
.map(cell => `.filter({ hasText: '${cell.replace(/'/g, "\\'")}' })`)
|
|
222
|
+
.join('');
|
|
223
|
+
assertions.push(`await expect(rows${filters}).toBeVisible();`);
|
|
224
|
+
}
|
|
225
|
+
const isGiven = isGivenContext(context);
|
|
226
|
+
return {
|
|
227
|
+
templateName: 'table-match-data',
|
|
228
|
+
data: {
|
|
229
|
+
...resolved,
|
|
230
|
+
assertions,
|
|
231
|
+
isGiven,
|
|
232
|
+
},
|
|
233
|
+
comment: `${isGiven ? 'Wait' : 'Assert'} ${step.selectorRef} table contains ${resolvedRows.length} expected row(s)`,
|
|
234
|
+
};
|
|
235
|
+
},
|
|
236
|
+
priority: 20, // Higher than other table patterns to match first
|
|
237
|
+
},
|
|
194
238
|
];
|
|
195
239
|
//# sourceMappingURL=table-patterns.js.map
|