Skip to content

feat(locator): waitFor, allTextContents, element screenshot (#135) - #150

Merged
shossain786 merged 3 commits into
seleniumboot:masterfrom
PUSHPAK-JAISWAL:feat/locator-waitfor-alltext-screenshot
Oct 14, 2026
Merged

shossain786 merged 3 commits into
seleniumboot:masterfrom
PUSHPAK-JAISWAL:feat/locator-waitfor-alltext-screenshot

Conversation

@PUSHPAK-JAISWAL

Copy link
Copy Markdown
Contributor

What & why

Adds three new capabilities to Locator inspired by Playwright's locator API:

  1. waitFor(State) and waitFor(): waits for an element to reach a target lifecycle state (VISIBLE, HIDDEN, ATTACHED, DETACHED) with auto-wait retrying up to timeouts.explicit.
  2. allTextContents(): retrieves the text of all matching elements in a single pass, returning immediately without waiting when no matches are found.
  3. screenshot() and screenshot(Path): captures an element's PNG screenshot bytes and writes them to a file path, auto-waiting for visibility and re-resolving on every poll.

All terminal actions re-resolve elements from scratch on each poll, surviving stale element reference exceptions and late-appearing elements (#67/#68).

Closes #135

Type of change

  • Bug fix
  • New feature (opt-in, aligned with the framework philosophy)
  • Documentation
  • Internal refactor / test coverage

Checklist

  • All existing tests pass (mvn clean verify)
  • New behaviour is covered by unit tests
  • No new external dependencies introduced without prior discussion
  • Code follows existing conventions (no new frameworks, minimal abstraction)
  • No breaking changes to @SeleniumBootApi public APIs (or a major version bump is justified below)
  • Docs updated if user-facing behaviour changed (docs-site/)

Notes for reviewers

  • State is exposed as @SeleniumBootApi(since = "3.9.0") in com.seleniumboot.locator.
  • waitFor() defaults to State.VISIBLE.
  • Element references in polling loops are strictly locally scoped to avoid hanging references or memory leaks.
  • Zero extra dependencies added.

@shossain786

Copy link
Copy Markdown
Contributor

Thanks again, Pushpak: this is a solid, well-tested contribution. I checked it out and ran the suite: 658 run, 0 failures (638 on master + your 20), and the Javadoc, docs and changelog entries are all there.

Before merging I found two places where the behaviour doesn't match the "re-resolve from scratch and retry stale elements" contract from #67/#68. I reproduced both with a throwaway unit test against this branch:

  1. waitFor(State.HIDDEN) passes on a stale element. In checkState, the HIDDEN case returns TRUE when isDisplayed() throws StaleElementReferenceException. If the spinner is re-rendered and the new one is still displayed, waitFor(HIDDEN) returns immediately, which is exactly the flake the contract is meant to prevent. Stale should be retried (return null), and only "no element resolves" or "resolves and !isDisplayed()" should count as hidden. DETACHED has the same shape: a stale reference is not proof that the element is gone, so it should re-resolve and only pass when resolve() finds nothing.
    The existing waitFor_hidden_elementGoesStaleWhileChecking_reResolves test passes only because the stale path short-circuits to success; it never verifies the second findElements call. Making the second lookup return a still-displayed element (and expecting a LocatorException) would pin the fix.

  2. allTextContents() throws on a stale element. It resolves the list once and then calls getText() on each element, so an element re-rendered between those two steps surfaces a raw StaleElementReferenceException. A small retry around the resolve-and-read (re-resolve on stale, without waiting for the list to be non-empty) would keep the "no wait on empty" behaviour and satisfy the contract. This one has no stale test yet, and the PR description lists it under the stale-safe actions.

Smaller things, not blockers:

  • allTextContents() returns rendered text for visible elements but textContent for hidden ones. That's a defensible fallback, just worth one sentence in the Javadoc so users aren't surprised.
  • Stray trailing blank lines at the end of State.java and LocatorTest.java.

Happy to merge once 1 and 2 are in. Ping me if you want to talk any of it through.

@PUSHPAK-JAISWAL

Copy link
Copy Markdown
Contributor Author

@shossain786 ok i am working on this

…r-alltext-screenshot

# Conflicts:
#	CHANGELOG.md
#	docs-site/docs/changelog.md
@PUSHPAK-JAISWAL

Copy link
Copy Markdown
Contributor Author

@shossain786 i have made the necessary changes.

@shossain786
shossain786 merged commit 0b85a2b into seleniumboot:master Oct 14, 2026
2 checks passed
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.

feat(locator): waitFor, allTextContents, element screenshot

2 participants