Skip to content

feat(Playwright): visibleLocator config option - #5707

Open
DavertMik wants to merge 1 commit into
4.xfrom
feature/playwright-visible-locator
Open

feat(Playwright): visibleLocator config option#5707
DavertMik wants to merge 1 commit into
4.xfrom
feature/playwright-visible-locator

Conversation

@DavertMik

Copy link
Copy Markdown
Contributor

Adds a visibleLocator option to the Playwright helper, built on locator.visible() from Playwright 1.63.

When enabled, locators used to find elements match only visible ones, so actions no longer pick a hidden duplicate and then time out on actionability.

helpers: { Playwright: { visibleLocator: true } }
I.click('Save')                                       // visible only
I.click('Save', stepOpts({ visibleLocator: false }))  // matches hidden too

How it resolves

One value is read at the findElements chokepoint:

store.currentStep?.opts?.visibleLocator ?? helper.options.visibleLocator

Step opts beat helper config, the same way exact, strictMode and elementIndex already work. visibleLocator is documented in the StepOptions typedef alongside them.

.visible() is applied everywhere a Locator becomes an element array — the plain matcher.locator(), handleRoleLocator, findByPlaywrightLocator ({pw:} locators), the two getByRole('button'|'link') fallbacks in findClickable, and findByRole (selectOption's combobox/listbox path). findClickable, findCheckable and findFields all bottom out there, so click, check, fill, select, attach, focus and moveCursorTo are covered without threading a parameter through them.

withVisibleLocator throws a named error if the installed Playwright predates 1.63, since playwright is a peer install.

Behaviour changes when enabled

  • A locator matching only hidden elements fails as "element not found" instead of timing out on actionability.
  • strict: true ignores hidden duplicates, so cases that previously failed with MultipleElementsFound now pass.
  • Elements hidden by CSS — such as a custom checkbox built on a visually hidden native input — are no longer found.

Not covered

  • seeElementInDOM, dontSeeElementInDOM and seeNumberOfElements opt out by writing visibleLocator: false into the current step's opts, since they assert DOM presence regardless of visibility. That opt-out only fires inside a recorded step — called directly on a helper instance outside a step, they filter. This is the same blind spot every existing step opt has.
  • dragAndDrop passes selectors to Playwright directly rather than building a Locator, so it is excluded and named as such in the config docs.

Testing

playwright devDependency bumped to ^1.63.0.

8 tests in test/helper/webapi.js, following the existing #elementIndex step option pattern and reusing the /invisible_elements fixture: config on/off, per-step on/off, all-hidden → not found, DOM assertions unaffected, fields/checkboxes, plus a combobox case covering the findByRole path. Guarded with isHelper('Playwright'), so Puppeteer and WebDriver skip them.

  • Playwright helper suite: 440 passing, 3 failingseeTraffic and two makeApiRequest tests, all hitting external hosts and failing identically on a clean tree.
  • Puppeteer: all 8 pending, 0 failures.
  • Acceptance (test/acceptance/codecept.Playwright.js): 59 passed, 1 failed — the localhost:3001 API call, also failing on a clean tree.

Note for review

PlaywrightLocator.js now imports withVisibleLocator from Playwright.js, which already imports it back. The cycle resolves (function declarations hoist, the call happens at runtime) and Playwright.js is the only importer of that module. If a cycle is unwelcome on this branch, moving the two resolver functions into lib/helper/extras/ breaks it.

🤖 Generated with Claude Code

https://claude.ai/code/session_01D6RydiYkagn6C8Pts2Leou

Appends Playwright's locator.visible() (1.63+) to locators, so actions
match only visible elements. Resolved per step: stepOpts({ visibleLocator })
overrides the helper config, following exact/strictMode/elementIndex.

seeElementInDOM, dontSeeElementInDOM and seeNumberOfElements opt out by
setting the step option, since they assert DOM presence regardless of
visibility.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D6RydiYkagn6C8Pts2Leou
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant