Problem
findElements() in element_helper.dart unconditionally applies .hitTestable() to all element lookups (line 45). This makes it impossible to find and interact with widgets that use rendererIgnoresPointer: true internally — like Pinput OTP fields.
The cached finder carries .hitTestable() into SetTextHandler, which passes it to WidgetTester.enterText(). Since enterText() internally searches for an EditableText descendant, and Pinput's EditableText has rendererIgnoresPointer: true, the search fails.
Steps to Reproduce
- Add a Pinput widget with a
ValueKey: Pinput(key: ValueKey('otp_input'), length: 6)
- Try to find it:
browser.flutterByValueKey$('otp_input') → fails with "not present in DOM... considering only hit-testable widgets"
- Wrapping in
GestureDetector, Semantics, or SizedBox does not help — Pinput's internal render tree always blocks hit-testing
Why It Fails
Pinput's widget tree includes:
IgnorePointer wrapping content
EditableText with rendererIgnoresPointer: true
The .hitTestable() filter rejects these. But WidgetTester.enterText() does NOT need hit-testing — it finds EditableText by walking the widget tree directly.
How Patrol Solves This
Patrol successfully enters text into Pinput using the same WidgetTester.enterText(). The difference: Patrol does NOT bake .hitTestable() into the finder passed to enterText().
Pinput's own test suite confirms this pattern works:
await tester.enterText(find.byType(EditableText), '1234');
Suggested Fix
PR #39 addresses this by removing the unconditional .hitTestable() and adding an isVisibleOnAppScreen() fallback.
Environment
- appium_flutter_server: 0.0.33
- Pinput: 5.0.2
- Flutter: 3.32+
- Platform: Android 14 emulator
Related
Problem
findElements()inelement_helper.dartunconditionally applies.hitTestable()to all element lookups (line 45). This makes it impossible to find and interact with widgets that userendererIgnoresPointer: trueinternally — like Pinput OTP fields.The cached finder carries
.hitTestable()intoSetTextHandler, which passes it toWidgetTester.enterText(). SinceenterText()internally searches for anEditableTextdescendant, and Pinput'sEditableTexthasrendererIgnoresPointer: true, the search fails.Steps to Reproduce
ValueKey:Pinput(key: ValueKey('otp_input'), length: 6)browser.flutterByValueKey$('otp_input')→ fails with "not present in DOM... considering only hit-testable widgets"GestureDetector,Semantics, orSizedBoxdoes not help — Pinput's internal render tree always blocks hit-testingWhy It Fails
Pinput's widget tree includes:
IgnorePointerwrapping contentEditableTextwithrendererIgnoresPointer: trueThe
.hitTestable()filter rejects these. ButWidgetTester.enterText()does NOT need hit-testing — it findsEditableTextby walking the widget tree directly.How Patrol Solves This
Patrol successfully enters text into Pinput using the same
WidgetTester.enterText(). The difference: Patrol does NOT bake.hitTestable()into the finder passed toenterText().Pinput's own test suite confirms this pattern works:
Suggested Fix
PR #39 addresses this by removing the unconditional
.hitTestable()and adding anisVisibleOnAppScreen()fallback.Environment
Related