You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat: warn when a text is passed where a selector is expected
Methods like waitForElement, seeElement and grabTextFrom expect a CSS or
XPath locator and, unlike click or fillField, do not fall back to searching
by text. A sentence passed to them is matched as CSS, finds nothing, and the
step fails on timeout with a message that says nothing about the real cause.
Adds a heuristic that recognises such strings: several words, no CSS or XPath
punctuation, not a chain of tag names. Wired into 32 locator-only methods
across Playwright, Puppeteer and WebDriver.
In debug mode it prints a [Warning] with a suggestion for the method used;
with strict: true it throws InvalidSelector so the test fails immediately
instead of after the full timeout.
Valid locators with spaces are left alone: `div span`, `my-app my-button`,
`text=Save Changes` and `~accessibility id` all pass the check.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NSR3yk8NgMFkPSspsynKUN
Copy file name to clipboardExpand all lines: docs/element-selection.md
+22Lines changed: 22 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -115,11 +115,33 @@ And when you know there are multiple matches and want a specific one, `elementIn
115
115
I.click('a', step.opts({ elementIndex:2 }))
116
116
```
117
117
118
+
## Text Passed Instead of a Selector
119
+
120
+
`waitForElement`, `seeElement`, `waitForVisible` and the rest of the wait/assert family expect a CSS or XPath locator. Unlike `click` or `fillField`, they don't fall back to searching by text. A sentence passed to them is treated as CSS, matches nothing, and the step fails with a timeout that says nothing about the real cause:
121
+
122
+
```js
123
+
I.waitForElement('Description Persistence Suite') // waits 10s, then "still not present on page"
124
+
```
125
+
126
+
CodeceptJS detects this and warns when the run is in debug mode:
127
+
128
+
```
129
+
I wait for element "Description Persistence Suite"
130
+
› [Warning] "Description Persistence Suite" doesn't look like a CSS or XPath selector.
131
+
I.waitForElement() expects an element locator, so this text is matched as CSS
132
+
and finds nothing. Use I.waitForText() to wait for a text on page.
133
+
```
134
+
135
+
With `strict: true` the same check throws `InvalidSelector` instead of warning, so the test fails immediately with a readable message rather than after the full timeout.
136
+
137
+
The check only fires on strings that can't be a selector: they contain a space, carry no CSS or XPath punctuation, and aren't a chain of tag names. `div span`, `my-app my-button`, `text=Save Changes` and `~accessibility id` are all left alone.
138
+
118
139
## Summary
119
140
120
141
| Situation | Approach |
121
142
|-----------|----------|
122
143
| You want to catch ambiguous locators early | Enable `strict: true` in helper config |
144
+
| You passed a text where a selector is expected | Run with `--debug` for the warning, or `strict: true` to fail fast |
123
145
| You need a specific element from a known list | Use `step.opts({ elementIndex: N })`|
124
146
| You want to iterate over all matching elements | Use [`eachElement`](/els) from the `els` module |
125
147
| You need full control over element inspection | Use [`grabWebElements`](/WebElement) to get all matches |
0 commit comments