Repository navigation
fix: look up a missing page object element once per wait attempt - #2472
Merged
Merged
Conversation
Fixes appium#2034 Fields with mobile annotations resolve through pagefactory.bys.builder.ByChained, even with one annotation. Its findElement() wrapped the chain in a FluentWait with the default 500 ms timeout and interval, inside the wait that AppiumElementLocator already runs with the decorator timeout. A missing element got two lookups and at least 500 ms per attempt, also with Duration.ZERO. The chain now runs once and the locator owns the wait. Commands I ran, with the result. ./gradlew :test, filtered to MissingElementLookupTest master 92c2dc8 expected [accessibilityId: Not Exists] but was [accessibilityId: Not Exists, accessibilityId: Not Exists] this commit 1 test, 0 failures ./gradlew clean build (JDK 26.0.2, Selenium 4.50.0) BUILD SUCCESSFUL, core 206 tests and selenium-bridge 12 tests, 0 failures page object from the issue, Duration.ZERO and -1 ms, local endpoint 11.0.0 jar 2 POST /element per click this commit 1 POST /element per click I didn't run the Android, iOS and Flutter e2e lanes.
theluckystrike
requested review from
SrinivasanTarget,
mykola-mokhnach,
saikrishna321 and
valfirst
as code owners
October 8, 2026 02:44
mykola-mokhnach
approved these changes
Oct 8, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Change list
pagefactory.bys.builder.ByChained.findElement()runs its locator chain once instead of inside its ownFluentWait.MissingElementLookupTestchecks that a page object field with a missing element andDuration.ZEROsends one lookup and doesn't wait.Types of changes
Details
Fixes #2034.
Fields with mobile annotations such as
@AndroidFindByresolve throughByChained, even with a single annotation.ByChained.findElement()wrapped the chain innew FluentWait<>(context), which has the default 500 ms timeout and 500 ms polling interval.AppiumElementLocatoralready waits with the timeout given toAppiumFieldDecorator(or@WithTimeout). So a missing element got a hidden second wait inside each attempt of the real one, with twoPOST /elementcalls and at least 500 ms per attempt, also forDuration.ZERO. The locator now owns the wait alone, which matchessupport.pagefactory.ByChainedand plaindriver.findElement().Results from my runs on this branch (JDK 26.0.2, Gradle 9.8.0 wrapper, Selenium 4.50.0).
./gradlew :test --tests 'io.appium.java_client.pagefactory_tests.MissingElementLookupTest'fails onmaster92c2dc8 withexpected: <[AppiumBy.accessibilityId: Not Exists]> but was: <[AppiumBy.accessibilityId: Not Exists, AppiumBy.accessibilityId: Not Exists]>and passes with the change../gradlew clean buildpasses, with 206 core tests and 12selenium-bridgetests, 0 failures, plus checkstyle and javadoc.@AndroidFindBy(accessibility = "Not Exists"),new AppiumFieldDecorator(driver, Duration.ZERO), thenclick()) ran against a local HTTP endpoint that records requests and answersno such element. The 11.0.0 jar from Maven Central sends 2POST /elementper click forDuration.ZEROand forDuration.ofMillis(-1). The jar built from this branch sends 1 for each, and the-1 mscase drops from 880 ms to 315 ms.The Android, iOS and Flutter e2e lanes need devices and didn't run here.
This PR was prepared with Claude Code. Every result above comes from a local run.