[flutter_test] Add an option to hide pointer crosshairs in live tests
- Dominant language
- Dart
- Stars
- 179k
- Forks
- 31.1k
- PR merge metrics
- PR metrics pending
Description
## Use case
`LiveTestWidgetsFlutterBinding` paints a circular crosshair for pointer events
generated by `WidgetTester`, `TestGesture`, and other test APIs. The overlay is
helpful when watching an interactive test, but there is currently no public API
to disable it.
Some live-test use cases need test-generated input without additional visuals:
- Capturing clean screenshots or golden images.
- Recording demos driven by `WidgetTester`.
- Running debug/runtime automation while observing the real application UI.
- Providing a custom pointer visualization in a test harness.
For example, the following live test displays a crosshair at the button:
```dart
void main() {
final binding = LiveTestWidgetsFlutterBinding.ensureInitialized();
binding.framePolicy = LiveTestWidgetsFlutterBindingFramePolicy.fullyLive;
testWidgets('tap a button', (WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
home: Center(
child: FilledButton(
onPressed: () {},
child: const Text('Tap'),
),
),
),
);
await tester.tap(find.text('Tap'));
await tester.pump();
});
}
```
Changing `LiveTestWidgetsFlutterBinding.framePolicy` is not an equivalent
workaround. A frame policy controls when frames are scheduled and rendered,
whereas this request only concerns whether the test pointer overlay is shown.
For example, switching away from `fullyLive` can change animation and pumping
behavior that the test relies on.
Waiting for the crosshair to fade adds unnecessary delays and can make
screenshot timing fragile. A package cannot cleanly solve this either because
the pointer records and painting logic are private implementation details of
`LiveTestWidgetsFlutterBinding`.
Flutter issue
[#128100](https://github.com/flutter/flutter/issues/128100) previously
described pointer crosshairs appearing in integration-test screenshots. An
explicit visibility option would also address that use case.
## Proposal
Add a public, backward-compatible option to
`LiveTestWidgetsFlutterBinding`:
```dart
final binding = LiveTestWidgetsFlutterBinding.ensureInitialized();
binding.showTestPointerCrosshairs = false;
```
Proposed API:
```dart
/// Whether pointer crosshairs generated by test pointer events are shown.
///
/// This only affects the visual representation of test pointers. Pointer
/// events are still dispatched normally when this property is false.
///
/// This property is independent of [framePolicy], which controls how frames
/// are scheduled.
///
/// Defaults to true.
bool get showTestPointerCrosshairs;
set showTestPointerCrosshairs(bool value);
```
The property would default to `true`, preserving existing behavior.
When set to `false`, the binding would:
- Stop creating and updating `_LiveTestPointerRecord` objects.
- Clear any active pointer records and schedule a repaint so an existing
crosshair disappears immediately.
- Continue forwarding test pointer events to
`super.handlePointerEvent(event)`.
- Leave device-sourced pointer handling and frame-policy behavior unchanged.
This keeps pointer visualization configurable without coupling it to event
delivery or frame scheduling.
Contributor guide
Assessment
This issue has not been assessed yet.