fix: make XPath relative in buildLocatorString for within() scope#5474
fix: make XPath relative in buildLocatorString for within() scope#5474mirao wants to merge 2 commits intocodeceptjs:4.xfrom
Conversation
…deceptjs#5473) Playwright's XPath engine auto-converts "//..." to ".//..." when searching within an element, but only when the selector starts with "/". Locator methods like at(), first(), last() wrap XPath in parentheses (e.g. "(//...)[position()=1]"), bypassing that auto-conversion and causing XPath to search from the document root instead of the within() scope. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
@mirao I didn't see how it is related to within Can we detect that we are triggering locator from page root or from an other element and apply transformation only when it is needed? |
…odeceptjs#5473) Adds a Playwright acceptance test that verifies XPath from locate().at().find() is correctly scoped when used inside within(). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@DavertMik Good points, I've pushed a second commit that adds an acceptance test proving it works with test/acceptance/within_test.js — new scenario Scenario('within with locate().at().find() should scope XPath @Playwright', async ({ I }) => {
I.amOnPage('/form/bug5473')
await within('#list2', async () => {
await I.see('Second', locate('.item').at(1).find('.label'))
})
})Without the fix: fails — finds "First" from Regarding applying the transformation only when needed: However, the transformation is safe to apply unconditionally because |
Summary
buildLocatorString()solocate().at(),.first(),.last()work correctly insidewithin()with Playwright helper//...to.//...when the root is not a Document, but only when the selector starts with/. Locator methods likeat()wrap XPath in parentheses (e.g.(//...)[position()=1]), bypassing that auto-conversion.before the first//that follows any leading parenthesesFixes #5473
Test plan
buildLocatorStringcoveringat(),first(),last(),at().find(), plain XPath, already-relative XPath, and CSS passthrough#seeAttributesOnElementsunrelated to this change)🤖 Generated with Claude Code