Skip to content

feat(locator): add first() and last() narrowing methods (#132) - #143

Merged
shossain786 merged 1 commit into
seleniumboot:masterfrom
PUSHPAK-JAISWAL:feat/locator-first-last
Oct 10, 2026
Merged

shossain786 merged 1 commit into
seleniumboot:masterfrom
PUSHPAK-JAISWAL:feat/locator-first-last

Conversation

@PUSHPAK-JAISWAL

Copy link
Copy Markdown
Contributor

What & why

Adds first() and last() narrowing methods to Locator as thin, readable wrappers:

  • first() narrows matched elements to the first item (equivalent to nth(0)).
  • last() narrows matched elements to the last item.

Previously, Locator supported nth(int) but lacked dedicated first() and last() convenience methods for the most common narrowing calls (e.g., getByRole(Role.LISTITEM).first()).

last() resolves lazily at action time inside resolveAll() on every poll rather than fixing an index at build time. This ensures that dynamic DOM updates, element list growth, and the framework's auto-wait contract (#67 / #68) work correctly: candidates are re-queried from scratch on every poll and retried until timeouts.explicit.

Closes #132

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

  • Lazy Action-Time Resolution: last() stores no element references or indices at build time. When a terminal action (click(), getText(), element(), etc.) runs, candidates.get(candidates.size() - 1) is evaluated at poll time.
  • Auto-Wait Contract: If the list is initially empty, resolveAll() throws LocatorException, which is caught by the retry loop and polled until elements appear or explicit timeout elapses. If an element goes stale between check and action, it re-resolves and picks the fresh element.
  • Chaining Precedence: Calling first(), last(), or nth(index) cleanly clears previous index-narrowing flags on the locator instance.
  • Docs & Changelog:
    • Javadoc with code examples added to both public methods in Locator.java.
    • Added narrowing reference line to docs-site/docs/guides/semantic-locators.md.
    • Added unreleased changelog entries to both docs-site/docs/changelog.md and CHANGELOG.md.
  • Test Suite: 46 unit tests in LocatorTest and LocatorStaleElementTest pass, and the full 587-test suite passes with 0 failures.

@shossain786
shossain786 merged commit d6f1fc2 into seleniumboot:master Oct 10, 2026
@shossain786

shossain786 commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

Merged — thanks @PUSHPAK-JAISWAL. Resolving last() at action time instead of fixing an index, and the stale-element tests for it, are exactly what this needed. It'll go out with the next release.

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): first() and last()

2 participants