@vijaypjavvadi/bdd2pw 2.2.5 → 2.2.6
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/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,77 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
9
9
|
|
|
10
10
|
_Nothing yet._
|
|
11
11
|
|
|
12
|
+
## [2.2.6] — 2026-05-11
|
|
13
|
+
|
|
14
|
+
### Fixed — BUG-10 (P2): locator extractor picks framework-internal CSS classes
|
|
15
|
+
|
|
16
|
+
Cloud-job report 2026-05-11 20:08 against `https://preview.owasp-juice.shop`:
|
|
17
|
+
Angular's runtime-managed form-state classes (`.ng-untouched`,
|
|
18
|
+
`.ng-pristine`, `.ng-dirty`) were being picked as both the POM
|
|
19
|
+
field-name source AND the locator CSS selector. The POM emitted
|
|
20
|
+
`ngUntouchedInput = page.locator('.ng-untouched')` and the LLM then
|
|
21
|
+
used `ngUntouchedInput` for "search field has not yet been
|
|
22
|
+
interacted with" preconditions. The assertion failed because:
|
|
23
|
+
|
|
24
|
+
1. `.ng-untouched` flips to `.ng-touched` the moment focus enters
|
|
25
|
+
the input — locators built on it are flaky by construction.
|
|
26
|
+
2. Every Angular input shares the same state classes, so the
|
|
27
|
+
selector also fails strict-mode uniqueness.
|
|
28
|
+
3. The field name itself is misleading — no test author would call
|
|
29
|
+
the search box "ng untouched input".
|
|
30
|
+
|
|
31
|
+
Same class of bug applies to anything prefixed `mat-*` (Angular
|
|
32
|
+
Material), `cdk-*` (CDK overlays / focus traps), `mdc-*` (Material
|
|
33
|
+
Design Components), and `_ngcontent-*` / `_nghost-*` (Angular view
|
|
34
|
+
encapsulation markers).
|
|
35
|
+
|
|
36
|
+
**Fix (two layers in `src/transformers/locatorPicker.ts`):**
|
|
37
|
+
|
|
38
|
+
1. **Field-name source.** `cssSelectorToName` now skips
|
|
39
|
+
framework-prefix classes when walking a multi-class selector and
|
|
40
|
+
returns the first user-named class instead. For
|
|
41
|
+
`.ng-untouched.search-input` it returns `"search input"`, not
|
|
42
|
+
`"ng untouched"`. If EVERY class on the element is framework-only,
|
|
43
|
+
it returns undefined and the caller falls through to
|
|
44
|
+
`<role|tag>Element` — for an Angular input with no other handles,
|
|
45
|
+
the synthesised field name becomes `inputElement` rather than
|
|
46
|
+
`ngUntouchedInput`.
|
|
47
|
+
|
|
48
|
+
2. **CSS-fallback gate.** `pickLocator`'s step-6 CSS fallback now
|
|
49
|
+
refuses framework-only selectors via `isFrameworkOnlySelector`.
|
|
50
|
+
When the element has no role / label / placeholder / testId /
|
|
51
|
+
text / xpath and the only CSS handle is something like
|
|
52
|
+
`.ng-untouched.ng-pristine`, we emit a tag-only locator
|
|
53
|
+
(`page.locator("input")`) and flag it `confidence: "fallback"`.
|
|
54
|
+
Tag-only is non-ideal but at least matches a real DOM element
|
|
55
|
+
instead of a transient state class.
|
|
56
|
+
|
|
57
|
+
New exports (both pure, easy to compose into future emitter rules):
|
|
58
|
+
- `isFrameworkClass(cls: string): boolean`
|
|
59
|
+
- `isFrameworkOnlySelector(selector: string | undefined): boolean`
|
|
60
|
+
|
|
61
|
+
Detection covered: `ng-*`, `mat-*`, `cdk-*`, `mdc-*`,
|
|
62
|
+
`_ngcontent-*`, `_nghost-*`. Hyphen-after-prefix is required so we
|
|
63
|
+
don't accidentally flag user-named classes like `nginx-banner` or
|
|
64
|
+
`ngo-button`.
|
|
65
|
+
|
|
66
|
+
### Tests
|
|
67
|
+
|
|
68
|
+
`tests/unit/locatorPicker.test.ts` — full coverage for BUG-10:
|
|
69
|
+
- `isFrameworkClass` matches every prefix, leaves user classes
|
|
70
|
+
alone (including the deliberate near-misses `nginx-banner`,
|
|
71
|
+
`ngo-button`, `material-card`).
|
|
72
|
+
- `isFrameworkOnlySelector` flags pure framework selectors,
|
|
73
|
+
declines mixed selectors, declines `#id`-bearing selectors, declines
|
|
74
|
+
non-class selectors.
|
|
75
|
+
- `pickLocator` drops a framework-only CSS selector and falls back
|
|
76
|
+
to tag-only.
|
|
77
|
+
- `pickLocator` preserves selectors that have at least one
|
|
78
|
+
user-named class.
|
|
79
|
+
- `synthFieldName` skips framework classes and falls through to
|
|
80
|
+
`<role|tag>Element`.
|
|
81
|
+
- `synthFieldName` picks the user-named class in a mixed selector.
|
|
82
|
+
|
|
12
83
|
## [2.2.5] — 2026-05-11
|
|
13
84
|
|
|
14
85
|
### Fixed — BUG-9 (P0): POM field name starting with a digit broke entire spec
|
|
@@ -16,6 +16,18 @@ import type { ElementIR, LocatorChoice } from "../types";
|
|
|
16
16
|
* candidate locator, we fall down the chain.
|
|
17
17
|
*/
|
|
18
18
|
export declare function pickLocator(element: ElementIR, allElements: ElementIR[]): LocatorChoice;
|
|
19
|
+
/** True when `cls` looks like a framework-internal class. */
|
|
20
|
+
export declare function isFrameworkClass(cls: string): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* True when `selector` reduces to *only* framework-internal classes
|
|
23
|
+
* (e.g. `.ng-untouched.ng-pristine`). Such selectors are unstable
|
|
24
|
+
* runtime markers and must not be used as Playwright locators.
|
|
25
|
+
*
|
|
26
|
+
* Selectors with at least one non-framework class
|
|
27
|
+
* (`.ng-untouched.search-input`) are NOT flagged — the non-framework
|
|
28
|
+
* class can still drive a useful locator.
|
|
29
|
+
*/
|
|
30
|
+
export declare function isFrameworkOnlySelector(selector: string | undefined): boolean;
|
|
19
31
|
/**
|
|
20
32
|
* Dedupe a list of locator choices.
|
|
21
33
|
*
|
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
*/
|
|
13
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
14
|
exports.pickLocator = pickLocator;
|
|
15
|
+
exports.isFrameworkClass = isFrameworkClass;
|
|
16
|
+
exports.isFrameworkOnlySelector = isFrameworkOnlySelector;
|
|
15
17
|
exports.dedupeLocators = dedupeLocators;
|
|
16
18
|
const naming_1 = require("../utils/naming");
|
|
17
19
|
/**
|
|
@@ -85,8 +87,12 @@ function pickLocator(element, allElements) {
|
|
|
85
87
|
confidence: rivals.length === 0 ? "unique" : "ambiguous",
|
|
86
88
|
};
|
|
87
89
|
}
|
|
88
|
-
// 6. CSS selector
|
|
89
|
-
|
|
90
|
+
// 6. CSS selector — but reject framework-only class selectors
|
|
91
|
+
// (Angular's `.ng-untouched`, Material's `.mat-form-field`, etc.).
|
|
92
|
+
// These are runtime state markers that change as the user
|
|
93
|
+
// interacts with the page, so locators built on them are flaky.
|
|
94
|
+
// See BUG-10 / v2.2.6.
|
|
95
|
+
if (element.cssSelector && !isFrameworkOnlySelector(element.cssSelector)) {
|
|
90
96
|
return {
|
|
91
97
|
api: "locator",
|
|
92
98
|
args: JSON.stringify(element.cssSelector),
|
|
@@ -105,7 +111,12 @@ function pickLocator(element, allElements) {
|
|
|
105
111
|
confidence: "fallback",
|
|
106
112
|
};
|
|
107
113
|
}
|
|
108
|
-
// Nothing usable — emit a tag-only locator and flag as fallback
|
|
114
|
+
// Nothing usable — emit a tag-only locator and flag as fallback.
|
|
115
|
+
// v2.2.6 — if we got here because the only CSS selector was
|
|
116
|
+
// framework-internal (and there was no role / label / placeholder /
|
|
117
|
+
// testId / text / xpath), the tag-only fallback is the least-bad
|
|
118
|
+
// option. It at least matches a visible DOM element rather than a
|
|
119
|
+
// transient state class.
|
|
109
120
|
return {
|
|
110
121
|
api: "locator",
|
|
111
122
|
args: JSON.stringify(element.tag),
|
|
@@ -127,6 +138,68 @@ function pickLocator(element, allElements) {
|
|
|
127
138
|
* `notificationBanner`) is what a test author would write by hand.
|
|
128
139
|
*/
|
|
129
140
|
const STATUS_REGION_RE = /(error|alert|message|warning|success|notification|status)/i;
|
|
141
|
+
/**
|
|
142
|
+
* v2.2.6 — BUG-10. CSS class prefixes that frameworks generate at runtime
|
|
143
|
+
* for their own bookkeeping (form-state, view-encapsulation, theming,
|
|
144
|
+
* etc.). These classes:
|
|
145
|
+
*
|
|
146
|
+
* - Change at runtime (`.ng-untouched` → `.ng-touched` the moment the
|
|
147
|
+
* user types), so selecting by them gives flaky locators.
|
|
148
|
+
* - Are not user-facing — no test author would write
|
|
149
|
+
* `await expect(page.locator('.ng-untouched')).toBeVisible()` by hand.
|
|
150
|
+
* - Mass-collide across the DOM (every Angular input has the same
|
|
151
|
+
* state classes), so locator-by-class is non-unique anyway.
|
|
152
|
+
*
|
|
153
|
+
* Covered prefixes:
|
|
154
|
+
* - `ng-*` Angular core (ng-untouched, ng-pristine, ng-dirty, …)
|
|
155
|
+
* - `mat-*` Angular Material
|
|
156
|
+
* - `cdk-*` Angular CDK (overlay, focus-trap, etc.)
|
|
157
|
+
* - `mdc-*` Material Design Components (web)
|
|
158
|
+
* - `_ngcontent-*` Angular view encapsulation attribute-like classes
|
|
159
|
+
* - `_nghost-*` Angular view encapsulation host markers
|
|
160
|
+
*
|
|
161
|
+
* Hyphen is required after the prefix so we don't accidentally exclude
|
|
162
|
+
* legitimate classes like `ngo-button` (user-named) or `cdkit` (rare but
|
|
163
|
+
* possible). The `_ngcontent-` / `_nghost-` patterns are handled with an
|
|
164
|
+
* explicit underscore prefix.
|
|
165
|
+
*/
|
|
166
|
+
const FRAMEWORK_CLASS_RE = /^(?:ng-|mat-|cdk-|mdc-|_ngcontent-|_nghost-)/i;
|
|
167
|
+
/** True when `cls` looks like a framework-internal class. */
|
|
168
|
+
function isFrameworkClass(cls) {
|
|
169
|
+
return FRAMEWORK_CLASS_RE.test(cls);
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Extract all bare class names from a CSS selector. Tolerant of compound
|
|
173
|
+
* selectors like `div.foo.bar#main` (returns `["foo", "bar"]`).
|
|
174
|
+
*/
|
|
175
|
+
function extractClasses(selector) {
|
|
176
|
+
const out = [];
|
|
177
|
+
const re = /\.([a-zA-Z_][\w-]*)/g;
|
|
178
|
+
let m;
|
|
179
|
+
while ((m = re.exec(selector)) !== null)
|
|
180
|
+
out.push(m[1]);
|
|
181
|
+
return out;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* True when `selector` reduces to *only* framework-internal classes
|
|
185
|
+
* (e.g. `.ng-untouched.ng-pristine`). Such selectors are unstable
|
|
186
|
+
* runtime markers and must not be used as Playwright locators.
|
|
187
|
+
*
|
|
188
|
+
* Selectors with at least one non-framework class
|
|
189
|
+
* (`.ng-untouched.search-input`) are NOT flagged — the non-framework
|
|
190
|
+
* class can still drive a useful locator.
|
|
191
|
+
*/
|
|
192
|
+
function isFrameworkOnlySelector(selector) {
|
|
193
|
+
if (!selector)
|
|
194
|
+
return false;
|
|
195
|
+
// If there's an #id, we can't claim "framework only" — id is independent.
|
|
196
|
+
if (/#[a-zA-Z][\w-]*/.test(selector))
|
|
197
|
+
return false;
|
|
198
|
+
const classes = extractClasses(selector);
|
|
199
|
+
if (classes.length === 0)
|
|
200
|
+
return false; // not a class-based selector
|
|
201
|
+
return classes.every(isFrameworkClass);
|
|
202
|
+
}
|
|
130
203
|
/**
|
|
131
204
|
* Synthesise a camelCase TS field name for an element.
|
|
132
205
|
*
|
|
@@ -175,10 +248,23 @@ function synthFieldName(element) {
|
|
|
175
248
|
}
|
|
176
249
|
/**
|
|
177
250
|
* Best-effort name extraction from a CSS selector. Handles common shapes:
|
|
178
|
-
* #username
|
|
179
|
-
* .foo-bar
|
|
180
|
-
* div#main
|
|
181
|
-
* a.wp-block-btn
|
|
251
|
+
* #username → "username"
|
|
252
|
+
* .foo-bar → "foo bar"
|
|
253
|
+
* div#main → "main"
|
|
254
|
+
* a.wp-block-btn → "wp block btn"
|
|
255
|
+
* input.ng-untouched.search-input → "search input" (v2.2.6)
|
|
256
|
+
*
|
|
257
|
+
* v2.2.6 — BUG-10. When the selector has multiple classes, skip
|
|
258
|
+
* framework-internal classes (`ng-*`, `mat-*`, `cdk-*`, `mdc-*`,
|
|
259
|
+
* `_ngcontent-*`, `_nghost-*`) and pick the first user-named class.
|
|
260
|
+
* Without this filter, juice-shop's `.ng-untouched.search-input` gets
|
|
261
|
+
* named "ng untouched" → `ngUntouchedInput`, which is a flaky state
|
|
262
|
+
* locator and a confusing field name.
|
|
263
|
+
*
|
|
264
|
+
* If EVERY class is framework-internal, returns undefined so the caller
|
|
265
|
+
* falls through to `<role|tag>Element` rather than naming the field
|
|
266
|
+
* after a transient state class.
|
|
267
|
+
*
|
|
182
268
|
* Returns undefined for selectors with no usable id/class.
|
|
183
269
|
*/
|
|
184
270
|
function cssSelectorToName(selector) {
|
|
@@ -188,9 +274,14 @@ function cssSelectorToName(selector) {
|
|
|
188
274
|
const idMatch = selector.match(/#([a-zA-Z][\w-]*)/);
|
|
189
275
|
if (idMatch)
|
|
190
276
|
return idMatch[1].replace(/-/g, " ");
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
277
|
+
// Walk all classes, return the first non-framework one.
|
|
278
|
+
const classes = extractClasses(selector);
|
|
279
|
+
for (const cls of classes) {
|
|
280
|
+
if (!isFrameworkClass(cls))
|
|
281
|
+
return cls.replace(/-/g, " ");
|
|
282
|
+
}
|
|
283
|
+
// All classes were framework-internal — fall through to the caller's
|
|
284
|
+
// next priority (typically `<role|tag>Element`).
|
|
194
285
|
return undefined;
|
|
195
286
|
}
|
|
196
287
|
function roleToSuffix(role, tag) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"locatorPicker.js","sourceRoot":"","sources":["../../src/transformers/locatorPicker.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;AAUH,
|
|
1
|
+
{"version":3,"file":"locatorPicker.js","sourceRoot":"","sources":["../../src/transformers/locatorPicker.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vijaypjavvadi/bdd2pw",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.6",
|
|
4
4
|
"description": "Scaffold runnable Playwright TypeScript tests from Gherkin .feature files. Detects existing Page Objects, scans live pages via Microsoft Playwright MCP, emits POMs + specs, ready for execution. CLI + HTTP service. Optional governed LLM fallback (Anthropic / OpenAI / Gemini).",
|
|
5
5
|
"bin": {
|
|
6
6
|
"bdd2pw": "dist/cli.js"
|