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
80a8c562
Commit
80a8c562
authored
Apr 14, 2017
by
Hans Muller
Committed by
GitHub
Apr 14, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
WidgetTester enterText() and showKeyboard() can specify an EditableText ancestor (#9398)
parent
dbfa747b
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
92 additions
and
40 deletions
+92
-40
text_field_test.dart
packages/flutter/test/material/text_field_test.dart
+19
-19
form_test.dart
packages/flutter/test/widgets/form_test.dart
+8
-8
finders.dart
packages/flutter_test/lib/src/finders.dart
+20
-5
widget_tester.dart
packages/flutter_test/lib/src/widget_tester.dart
+21
-8
widget_tester_test.dart
packages/flutter_test/test/widget_tester_test.dart
+24
-0
No files found.
packages/flutter/test/material/text_field_test.dart
View file @
80a8c562
...
...
@@ -103,7 +103,7 @@ void main() {
Future
<
Null
>
checkText
(
String
testValue
)
async
{
return
TestAsyncUtils
.
guard
(()
async
{
await
tester
.
enterText
(
find
.
byType
(
EditableText
),
testValue
);
await
tester
.
enterText
(
find
.
byType
(
TextField
),
testValue
);
// Check that the onChanged event handler fired.
expect
(
textFieldValue
,
equals
(
testValue
));
...
...
@@ -137,7 +137,7 @@ void main() {
}
await
tester
.
pumpWidget
(
builder
());
await
tester
.
showKeyboard
(
find
.
byType
(
EditableText
));
await
tester
.
showKeyboard
(
find
.
byType
(
TextField
));
final
EditableTextState
editableText
=
tester
.
state
(
find
.
byType
(
EditableText
));
...
...
@@ -157,7 +157,7 @@ void main() {
}
await
checkCursorToggle
();
await
tester
.
showKeyboard
(
find
.
byType
(
EditableText
));
await
tester
.
showKeyboard
(
find
.
byType
(
TextField
));
// Try the test again with a nonempty EditableText.
tester
.
testTextInput
.
updateEditingValue
(
const
TextEditingValue
(
...
...
@@ -182,7 +182,7 @@ void main() {
}
await
tester
.
pumpWidget
(
builder
());
await
tester
.
showKeyboard
(
find
.
byType
(
EditableText
));
await
tester
.
showKeyboard
(
find
.
byType
(
TextField
));
const
String
testValue
=
'ABC'
;
tester
.
testTextInput
.
updateEditingValue
(
const
TextEditingValue
(
...
...
@@ -211,7 +211,7 @@ void main() {
expect
(
controller
.
selection
.
extentOffset
,
-
1
);
final
String
testValue
=
'abc def ghi'
;
await
tester
.
enterText
(
find
.
byType
(
EditableText
),
testValue
);
await
tester
.
enterText
(
find
.
byType
(
TextField
),
testValue
);
await
tester
.
pumpWidget
(
builder
());
...
...
@@ -249,7 +249,7 @@ void main() {
await
tester
.
pumpWidget
(
builder
());
final
String
testValue
=
'abc def ghi'
;
await
tester
.
enterText
(
find
.
byType
(
EditableText
),
testValue
);
await
tester
.
enterText
(
find
.
byType
(
TextField
),
testValue
);
expect
(
controller
.
value
.
text
,
testValue
);
await
tester
.
pumpWidget
(
builder
());
...
...
@@ -284,7 +284,7 @@ void main() {
await
tester
.
pumpWidget
(
builder
());
final
String
testValue
=
'abc def ghi'
;
await
tester
.
enterText
(
find
.
byType
(
EditableText
),
testValue
);
await
tester
.
enterText
(
find
.
byType
(
TextField
),
testValue
);
await
tester
.
pumpWidget
(
builder
());
...
...
@@ -346,7 +346,7 @@ void main() {
await
tester
.
pumpWidget
(
builder
());
final
String
testValue
=
'abc def ghi'
;
await
tester
.
enterText
(
find
.
byType
(
EditableText
),
testValue
);
await
tester
.
enterText
(
find
.
byType
(
TextField
),
testValue
);
await
tester
.
pumpWidget
(
builder
());
// Tap the selection handle to bring up the "paste / select all" menu.
...
...
@@ -398,7 +398,7 @@ void main() {
await
tester
.
pumpWidget
(
builder
());
final
String
testValue
=
'abc def ghi'
;
await
tester
.
enterText
(
find
.
byType
(
EditableText
),
testValue
);
await
tester
.
enterText
(
find
.
byType
(
TextField
),
testValue
);
await
tester
.
pumpWidget
(
builder
());
// Tap the selection handle to bring up the "paste / select all" menu.
...
...
@@ -449,12 +449,12 @@ void main() {
final
RenderBox
inputBox
=
findInputBox
();
final
Size
emptyInputSize
=
inputBox
.
size
;
await
tester
.
enterText
(
find
.
byType
(
EditableText
),
'No wrapping here.'
);
await
tester
.
enterText
(
find
.
byType
(
TextField
),
'No wrapping here.'
);
await
tester
.
pumpWidget
(
builder
(
3
));
expect
(
findInputBox
(),
equals
(
inputBox
));
expect
(
inputBox
.
size
,
equals
(
emptyInputSize
));
await
tester
.
enterText
(
find
.
byType
(
EditableText
),
kThreeLines
);
await
tester
.
enterText
(
find
.
byType
(
TextField
),
kThreeLines
);
await
tester
.
pumpWidget
(
builder
(
3
));
expect
(
findInputBox
(),
equals
(
inputBox
));
expect
(
inputBox
.
size
,
greaterThan
(
emptyInputSize
));
...
...
@@ -462,13 +462,13 @@ void main() {
final
Size
threeLineInputSize
=
inputBox
.
size
;
// An extra line won't increase the size because we max at 3.
await
tester
.
enterText
(
find
.
byType
(
EditableText
),
kFourLines
);
await
tester
.
enterText
(
find
.
byType
(
TextField
),
kFourLines
);
await
tester
.
pumpWidget
(
builder
(
3
));
expect
(
findInputBox
(),
equals
(
inputBox
));
expect
(
inputBox
.
size
,
threeLineInputSize
);
// But now it will.
await
tester
.
enterText
(
find
.
byType
(
EditableText
),
kFourLines
);
await
tester
.
enterText
(
find
.
byType
(
TextField
),
kFourLines
);
await
tester
.
pumpWidget
(
builder
(
4
));
expect
(
findInputBox
(),
equals
(
inputBox
));
expect
(
inputBox
.
size
,
greaterThan
(
threeLineInputSize
));
...
...
@@ -493,7 +493,7 @@ void main() {
final
String
testValue
=
kThreeLines
;
final
String
cutValue
=
'First line of stuff '
;
await
tester
.
enterText
(
find
.
byType
(
EditableText
),
testValue
);
await
tester
.
enterText
(
find
.
byType
(
TextField
),
testValue
);
await
tester
.
pumpWidget
(
builder
());
...
...
@@ -572,7 +572,7 @@ void main() {
await
tester
.
pumpWidget
(
builder
());
await
tester
.
pump
(
const
Duration
(
seconds:
1
));
await
tester
.
enterText
(
find
.
byType
(
EditableText
),
kFourLines
);
await
tester
.
enterText
(
find
.
byType
(
TextField
),
kFourLines
);
await
tester
.
pumpWidget
(
builder
());
await
tester
.
pump
(
const
Duration
(
seconds:
1
));
...
...
@@ -660,7 +660,7 @@ void main() {
Future
<
Null
>
checkText
(
String
testValue
)
{
return
TestAsyncUtils
.
guard
(()
async
{
await
tester
.
enterText
(
find
.
byType
(
EditableText
),
testValue
);
await
tester
.
enterText
(
find
.
byType
(
TextField
),
testValue
);
// Check that the onChanged event handler fired.
expect
(
textFieldValue
,
equals
(
testValue
));
...
...
@@ -694,7 +694,7 @@ void main() {
Future
<
Null
>
checkText
(
String
testValue
)
async
{
return
TestAsyncUtils
.
guard
(()
async
{
await
tester
.
enterText
(
find
.
byType
(
EditableText
),
testValue
);
await
tester
.
enterText
(
find
.
byType
(
TextField
),
testValue
);
// Check that the onChanged event handler fired.
expect
(
textFieldValue
,
equals
(
testValue
));
...
...
@@ -866,7 +866,7 @@ void main() {
expect
(
topLeft
.
dx
,
equals
(
399.0
));
await
tester
.
enterText
(
find
.
byType
(
EditableText
),
'abcd'
);
await
tester
.
enterText
(
find
.
byType
(
TextField
),
'abcd'
);
await
tester
.
pump
();
topLeft
=
editable
.
localToGlobal
(
...
...
@@ -900,7 +900,7 @@ void main() {
expect
(
topLeft
.
dx
,
equals
(
399.0
));
await
tester
.
enterText
(
find
.
byType
(
EditableText
),
'abcd'
);
await
tester
.
enterText
(
find
.
byType
(
TextField
),
'abcd'
);
await
tester
.
pump
();
topLeft
=
editable
.
localToGlobal
(
...
...
packages/flutter/test/widgets/form_test.dart
View file @
80a8c562
...
...
@@ -28,7 +28,7 @@ void main() {
expect
(
fieldValue
,
isNull
);
Future
<
Null
>
checkText
(
String
testValue
)
async
{
await
tester
.
enterText
(
find
.
byType
(
EditableText
),
testValue
);
await
tester
.
enterText
(
find
.
byType
(
TextFormField
),
testValue
);
formKey
.
currentState
.
save
();
// pump'ing is unnecessary because callback happens regardless of frames
expect
(
fieldValue
,
equals
(
testValue
));
...
...
@@ -58,7 +58,7 @@ void main() {
expect
(
fieldValue
,
isNull
);
Future
<
Null
>
checkText
(
String
testValue
)
async
{
await
tester
.
enterText
(
find
.
byType
(
EditableText
),
testValue
);
await
tester
.
enterText
(
find
.
byType
(
TextField
),
testValue
);
// pump'ing is unnecessary because callback happens regardless of frames
expect
(
fieldValue
,
equals
(
testValue
));
}
...
...
@@ -90,7 +90,7 @@ void main() {
Future
<
Null
>
checkErrorText
(
String
testValue
)
async
{
formKey
.
currentState
.
reset
();
await
tester
.
enterText
(
find
.
byType
(
EditableText
),
testValue
);
await
tester
.
enterText
(
find
.
byType
(
TextFormField
),
testValue
);
await
tester
.
pumpWidget
(
builder
(
false
));
// We have to manually validate if we're not autovalidating.
...
...
@@ -101,7 +101,7 @@ void main() {
// Try again with autovalidation. Should validate immediately.
formKey
.
currentState
.
reset
();
await
tester
.
enterText
(
find
.
byType
(
EditableText
),
testValue
);
await
tester
.
enterText
(
find
.
byType
(
TextFormField
),
testValue
);
await
tester
.
pumpWidget
(
builder
(
true
));
expect
(
find
.
text
(
errorText
(
testValue
)),
findsOneWidget
);
...
...
@@ -141,7 +141,7 @@ void main() {
await
tester
.
pumpWidget
(
builder
());
Future
<
Null
>
checkErrorText
(
String
testValue
)
async
{
await
tester
.
enterText
(
find
.
byType
(
EditableText
).
first
,
testValue
);
await
tester
.
enterText
(
find
.
byType
(
TextFormField
).
first
,
testValue
);
await
tester
.
pump
();
// Check for a new Text widget with our error text.
...
...
@@ -172,7 +172,7 @@ void main() {
}
await
tester
.
pumpWidget
(
builder
());
await
tester
.
showKeyboard
(
find
.
byType
(
EditableText
));
await
tester
.
showKeyboard
(
find
.
byType
(
TextFormField
));
// initial value should be loaded into keyboard editing state
expect
(
tester
.
testTextInput
.
editingState
,
isNotNull
);
...
...
@@ -184,7 +184,7 @@ void main() {
// sanity check, make sure we can still edit the text and everything updates
expect
(
inputKey
.
currentState
.
value
,
equals
(
initialValue
));
await
tester
.
enterText
(
find
.
byType
(
EditableText
),
'world'
);
await
tester
.
enterText
(
find
.
byType
(
TextFormField
),
'world'
);
await
tester
.
pump
();
expect
(
inputKey
.
currentState
.
value
,
equals
(
'world'
));
expect
(
editableText
.
widget
.
controller
.
text
,
equals
(
'world'
));
...
...
@@ -214,7 +214,7 @@ void main() {
expect
(
fieldValue
,
isNull
);
expect
(
formKey
.
currentState
.
validate
(),
isTrue
);
await
tester
.
enterText
(
find
.
byType
(
EditableText
),
'Test'
);
await
tester
.
enterText
(
find
.
byType
(
TextFormField
),
'Test'
);
await
tester
.
pumpWidget
(
builder
(
false
));
// Form wasn't saved yet.
...
...
packages/flutter_test/lib/src/finders.dart
View file @
80a8c562
...
...
@@ -189,10 +189,13 @@ class CommonFinders {
/// of: find.widgetWithText(Row, 'label_1'), matching: find.text('value_1')
/// ), findsOneWidget);
///
/// If the [matchRoot] argument is true then the widget(s) specified by [of]
/// will be matched along with the descendants.
///
/// If the [skipOffstage] argument is true (the default), then nodes that are
/// [Offstage] or that are from inactive [Route]s are skipped.
Finder
descendant
({
Finder
of
,
Finder
matching
,
bool
skipOffstage:
true
})
{
return
new
_DescendantFinder
(
of
,
matching
,
skipOffstage:
skipOffstage
);
Finder
descendant
({
Finder
of
,
Finder
matching
,
bool
matchRoot:
false
,
bool
skipOffstage:
true
})
{
return
new
_DescendantFinder
(
of
,
matching
,
matchRoot:
matchRoot
,
skipOffstage:
skipOffstage
);
}
}
...
...
@@ -488,13 +491,21 @@ class _ElementPredicateFinder extends MatchFinder {
}
class
_DescendantFinder
extends
Finder
{
_DescendantFinder
(
this
.
ancestor
,
this
.
descendant
,
{
bool
skipOffstage:
true
})
:
super
(
skipOffstage:
skipOffstage
);
_DescendantFinder
(
this
.
ancestor
,
this
.
descendant
,
{
this
.
matchRoot
:
false
,
bool
skipOffstage:
true
,
})
:
super
(
skipOffstage:
skipOffstage
);
final
Finder
ancestor
;
final
Finder
descendant
;
final
bool
matchRoot
;
@override
String
get
description
=>
'
${descendant.description}
that has ancestor(s) with
${ancestor.description}
'
;
String
get
description
{
if
(
matchRoot
)
return
'
${descendant.description}
in the subtree(s) beginning with
${ancestor.description}
'
;
return
'
${descendant.description}
that has ancestor(s) with
${ancestor.description}
'
;
}
@override
Iterable
<
Element
>
apply
(
Iterable
<
Element
>
candidates
)
{
...
...
@@ -503,8 +514,12 @@ class _DescendantFinder extends Finder {
@override
Iterable
<
Element
>
get
allCandidates
{
return
ancestor
.
evaluate
().
expand
(
final
Iterable
<
Element
>
ancestorElements
=
ancestor
.
evaluate
();
final
List
<
Element
>
candidates
=
ancestorElements
.
expand
(
(
Element
element
)
=>
collectAllElementsFrom
(
element
,
skipOffstage:
skipOffstage
)
).
toSet
().
toList
();
if
(
matchRoot
)
candidates
.
insertAll
(
0
,
ancestorElements
);
return
candidates
;
}
}
packages/flutter_test/lib/src/widget_tester.dart
View file @
80a8c562
...
...
@@ -436,19 +436,25 @@ class WidgetTester extends WidgetController implements HitTestDispatcher, Ticker
/// Returns the TestTextInput singleton.
///
/// Typical app tests will not need to use this value. To add text to widgets
/// like [
Input] or [
TextField], call [enterText].
/// like [
TextField] or [Form
TextField], call [enterText].
TestTextInput
get
testTextInput
=>
binding
.
testTextInput
;
/// Give the
EditableTex
t widget specified by [finder] the focus, as if the
/// Give the
text inpu
t widget specified by [finder] the focus, as if the
/// onscreen keyboard had appeared.
///
/// Tests that just need to add text to widgets like [Input] or [TextField]
/// only need to call [enterText].
/// The widget specified by [finder] must be an [EditableText] or have
/// an [EditableText] descendant. For example `find.byType(TextField)`
/// or `find.byType(FormTextField)`, or `find.byType(EditableText)`.
///
/// Tests that just need to add text to widgets like [TextField]
/// or [FormTextField] only need to call [enterText].
Future
<
Null
>
showKeyboard
(
Finder
finder
)
async
{
return
TestAsyncUtils
.
guard
(()
async
{
// TODO(hansmuller): Once find.descendant (#7789) lands replace the following
// RHS with state(find.descendant(finder), find.byType(EditableText)).
final
EditableTextState
editable
=
state
(
finder
);
final
EditableTextState
editable
=
state
(
find
.
descendant
(
of:
finder
,
matching:
find
.
byType
(
EditableText
),
matchRoot:
true
,
));
if
(
editable
!=
binding
.
focusedEditable
)
{
binding
.
focusedEditable
=
editable
;
await
pump
();
...
...
@@ -456,8 +462,15 @@ class WidgetTester extends WidgetController implements HitTestDispatcher, Ticker
});
}
/// Give the
EditableTex
t widget specified by [finder] the focus and
/// Give the
text inpu
t widget specified by [finder] the focus and
/// enter [text] as if it been provided by the onscreen keyboard.
///
/// The widget specified by [finder] must be an [EditableText] or have
/// an [EditableText] descendant. For example `find.byType(TextField)`
/// or `find.byType(FormTextField)`, or `find.byType(EditableText)`.
///
/// To just give [finder] the focus without entering any text,
/// see [showKeyboard].
Future
<
Null
>
enterText
(
Finder
finder
,
String
text
)
async
{
return
TestAsyncUtils
.
guard
(()
async
{
await
showKeyboard
(
finder
);
...
...
packages/flutter_test/test/widget_tester_test.dart
View file @
80a8c562
...
...
@@ -184,6 +184,30 @@ void main() {
contains
(
'Actual: ?:<zero widgets with text "bar" that has ancestor(s) with type Column with text "foo"'
)
);
});
testWidgets
(
'Root not matched by default'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
new
Row
(
children:
<
Widget
>[
new
Column
(
children:
<
Text
>[
const
Text
(
'foo'
),
const
Text
(
'bar'
)])
]));
expect
(
find
.
descendant
(
of:
find
.
widgetWithText
(
Row
,
'foo'
),
matching:
find
.
byType
(
Row
),
),
findsNothing
);
});
testWidgets
(
'Match the root'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
new
Row
(
children:
<
Widget
>[
new
Column
(
children:
<
Text
>[
const
Text
(
'foo'
),
const
Text
(
'bar'
)])
]));
expect
(
find
.
descendant
(
of:
find
.
widgetWithText
(
Row
,
'foo'
),
matching:
find
.
byType
(
Row
),
matchRoot:
true
,
),
findsOneWidget
);
});
});
testWidgets
(
'hasRunningAnimations control test'
,
(
WidgetTester
tester
)
async
{
...
...
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