Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
4d73448b
Unverified
Commit
4d73448b
authored
Aug 03, 2022
by
Jia Hao
Committed by
GitHub
Aug 03, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[flutter_test] Add flag to send device pointer events to the framework (#108430)
parent
dbadee00
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
105 additions
and
2 deletions
+105
-2
binding.dart
packages/flutter_test/lib/src/binding.dart
+43
-1
widget_tester.dart
packages/flutter_test/lib/src/widget_tester.dart
+8
-0
live_binding_test.dart
packages/flutter_test/test/live_binding_test.dart
+54
-1
No files found.
packages/flutter_test/lib/src/binding.dart
View file @
4d73448b
...
...
@@ -494,9 +494,25 @@ abstract class TestWidgetsFlutterBinding extends BindingBase
///
/// When [handlePointerEvent] is called directly, [pointerEventSource]
/// is [TestBindingEventSource.device].
///
/// This means that pointer events triggered by the [WidgetController] (e.g.
/// via [WidgetController.tap]) will result in actual interactions with the
/// UI, but other pointer events such as those from physical taps will be
/// dropped. See also [shouldPropagateDevicePointerEvents] if this is
/// undesired.
TestBindingEventSource
get
pointerEventSource
=>
_pointerEventSource
;
TestBindingEventSource
_pointerEventSource
=
TestBindingEventSource
.
device
;
/// Whether pointer events from [TestBindingEventSource.device] will be
/// propagated to the framework, or dropped.
///
/// Setting this can be useful to interact with the app in some other way
/// besides through the [WidgetController], such as with `adb shell input tap`
/// on Android.
///
/// See also [pointerEventSource].
bool
shouldPropagateDevicePointerEvents
=
false
;
/// Dispatch an event to the targets found by a hit test on its position,
/// and remember its source as [pointerEventSource].
///
...
...
@@ -836,6 +852,7 @@ abstract class TestWidgetsFlutterBinding extends BindingBase
final
bool
autoUpdateGoldensBeforeTest
=
autoUpdateGoldenFiles
&&
!
isBrowser
;
final
TestExceptionReporter
reportTestExceptionBeforeTest
=
reportTestException
;
final
ErrorWidgetBuilder
errorWidgetBuilderBeforeTest
=
ErrorWidget
.
builder
;
final
bool
shouldPropagateDevicePointerEventsBeforeTest
=
shouldPropagateDevicePointerEvents
;
// run the test
await
testBody
();
...
...
@@ -854,6 +871,7 @@ abstract class TestWidgetsFlutterBinding extends BindingBase
_verifyAutoUpdateGoldensUnset
(
autoUpdateGoldensBeforeTest
&&
!
isBrowser
);
_verifyReportTestExceptionUnset
(
reportTestExceptionBeforeTest
);
_verifyErrorWidgetBuilderUnset
(
errorWidgetBuilderBeforeTest
);
_verifyShouldPropagateDevicePointerEventsUnset
(
shouldPropagateDevicePointerEventsBeforeTest
);
_verifyInvariants
();
}
...
...
@@ -943,6 +961,21 @@ abstract class TestWidgetsFlutterBinding extends BindingBase
}());
}
void
_verifyShouldPropagateDevicePointerEventsUnset
(
bool
valueBeforeTest
)
{
assert
(()
{
if
(
shouldPropagateDevicePointerEvents
!=
valueBeforeTest
)
{
FlutterError
.
reportError
(
FlutterErrorDetails
(
exception:
FlutterError
(
'The value of shouldPropagateDevicePointerEvents was changed by the test.'
,
),
stack:
StackTrace
.
current
,
library
:
'Flutter test framework'
,
));
}
return
true
;
}());
}
/// Called by the [testWidgets] function after a test is executed.
void
postTest
()
{
assert
(
inTest
);
...
...
@@ -1595,7 +1628,8 @@ class LiveTestWidgetsFlutterBinding extends TestWidgetsFlutterBinding {
///
/// Normally, device events are silently dropped. However, if this property is
/// set to a non-null value, then the events will be routed to its
/// [HitTestDispatcher.dispatchEvent] method instead.
/// [HitTestDispatcher.dispatchEvent] method instead, unless
/// [shouldPropagateDevicePointerEvents] is true.
///
/// Events dispatched by [TestGesture] are not affected by this.
HitTestDispatcher
?
deviceEventDispatcher
;
...
...
@@ -1630,6 +1664,10 @@ class LiveTestWidgetsFlutterBinding extends TestWidgetsFlutterBinding {
super
.
handlePointerEvent
(
event
);
break
;
case
TestBindingEventSource
.
device
:
if
(
shouldPropagateDevicePointerEvents
)
{
super
.
handlePointerEvent
(
event
);
break
;
}
if
(
deviceEventDispatcher
!=
null
)
{
// The pointer events received with this source has a global position
// (see [handlePointerEventForSource]). Transform it to the local
...
...
@@ -1651,6 +1689,10 @@ class LiveTestWidgetsFlutterBinding extends TestWidgetsFlutterBinding {
break
;
case
TestBindingEventSource
.
device
:
assert
(
hitTestResult
!=
null
||
event
is
PointerAddedEvent
||
event
is
PointerRemovedEvent
);
if
(
shouldPropagateDevicePointerEvents
)
{
super
.
dispatchEvent
(
event
,
hitTestResult
);
break
;
}
assert
(
deviceEventDispatcher
!=
null
);
if
(
hitTestResult
!=
null
)
{
deviceEventDispatcher
!.
dispatchEvent
(
event
,
hitTestResult
);
...
...
packages/flutter_test/lib/src/widget_tester.dart
View file @
4d73448b
...
...
@@ -502,6 +502,10 @@ Future<void> expectLater(
///
/// For convenience, instances of this class (such as the one provided by
/// `testWidgets`) can be used as the `vsync` for `AnimationController` objects.
///
/// When the binding is [LiveTestWidgetsFlutterBinding], events from
/// [LiveTestWidgetsFlutterBinding.deviceEventDispatcher] will be handled in
/// [dispatchEvent].
class
WidgetTester
extends
WidgetController
implements
HitTestDispatcher
,
TickerProvider
{
WidgetTester
.
_
(
super
.
binding
)
{
if
(
binding
is
LiveTestWidgetsFlutterBinding
)
{
...
...
@@ -817,6 +821,10 @@ class WidgetTester extends WidgetController implements HitTestDispatcher, Ticker
}
/// Handler for device events caught by the binding in live test mode.
///
/// [PointerDownEvent]s received here will only print a diagnostic message
/// showing possible [Finder]s that can be used to interact with the widget at
/// the location of [result].
@override
void
dispatchEvent
(
PointerEvent
event
,
HitTestResult
result
)
{
if
(
event
is
PointerDownEvent
)
{
...
...
packages/flutter_test/test/live_binding_test.dart
View file @
4d73448b
...
...
@@ -8,7 +8,7 @@ import 'package:flutter_test/flutter_test.dart';
// This file is for testings that require a `LiveTestWidgetsFlutterBinding`
void
main
(
)
{
LiveTestWidgetsFlutterBinding
();
final
LiveTestWidgetsFlutterBinding
binding
=
LiveTestWidgetsFlutterBinding
();
testWidgets
(
'Input PointerAddedEvent'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
const
MaterialApp
(
home:
Text
(
'Test'
)));
await
tester
.
pump
();
...
...
@@ -99,4 +99,57 @@ void main() {
await
expectLater
(
tester
.
binding
.
reassembleApplication
(),
completes
);
},
timeout:
const
Timeout
(
Duration
(
seconds:
30
)));
testWidgets
(
'shouldPropagateDevicePointerEvents can override events from
${TestBindingEventSource.device}
'
,
(
WidgetTester
tester
)
async
{
binding
.
shouldPropagateDevicePointerEvents
=
true
;
await
tester
.
pumpWidget
(
_ShowNumTaps
());
final
Offset
position
=
tester
.
getCenter
(
find
.
text
(
'0'
));
// Simulates a real device tap.
//
// `handlePointerEventForSource defaults to sending events using
// TestBindingEventSource.device. This will not be forwarded to the actual
// gesture handlers, unless `shouldPropagateDevicePointerEvents` is true.
binding
.
handlePointerEventForSource
(
PointerDownEvent
(
position:
position
),
);
binding
.
handlePointerEventForSource
(
PointerUpEvent
(
position:
position
),
);
await
tester
.
pump
();
expect
(
find
.
text
(
'1'
),
findsOneWidget
);
// Reset the value, otherwise the test will fail when it checks that this
// has not been changed as an invariant.
binding
.
shouldPropagateDevicePointerEvents
=
false
;
});
}
/// A widget that shows the number of times it has been tapped.
class
_ShowNumTaps
extends
StatefulWidget
{
@override
_ShowNumTapsState
createState
()
=>
_ShowNumTapsState
();
}
class
_ShowNumTapsState
extends
State
<
_ShowNumTaps
>
{
int
_counter
=
0
;
@override
Widget
build
(
BuildContext
context
)
{
return
GestureDetector
(
onTap:
()
{
setState
(()
{
_counter
++;
});
},
child:
Directionality
(
textDirection:
TextDirection
.
ltr
,
child:
Text
(
_counter
.
toString
()),
),
);
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment