-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Description
The documentation of CommonFinders.text states that it "Finds [Text] and [EditableText] widgets containing string equal to the text argument."
Given this documentation, I was expecting that CommonFinders.text will find a Text widget containing the string, even if the widget is created using Text.rich.
However, in this case the finder does not seem to find the Widget:
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
// This works
testWidgets('finds Text widget', (WidgetTester tester) async {
final Text text = new Text('a');
await tester.pumpWidget(new MaterialApp(home: text));
expect(find.text('a'), findsOneWidget);
});
// This fails
testWidgets('finds Text widget created with Text.rich', (WidgetTester tester) async {
final Text text = new Text.rich(new TextSpan(text: 'a'));
await tester.pumpWidget(new MaterialApp(home: text));
expect(find.text('a'), findsOneWidget);
});
}My understanding is that CommonFinders.text should also find the widget in the second case, as it is a Text widget, containing (exactly) the string passed to the finder. The only difference is the internal structure (string stored in Text.data property vs. stored in Text.textSpan property), which should not matter to the finder I think (even in the first case, TextFinder.build wraps the string in a RichText widget).
This is the implementation of MatchFinder.matches in _TextFinder:
@override
bool matches(Element candidate) {
if (candidate.widget is Text) {
final Text textWidget = candidate.widget;
return textWidget.data == text;
} else if (candidate.widget is EditableText) {
final EditableText editable = candidate.widget;
return editable.controller.text == text;
}
return false;
}
It only checks for the data property in the widget, which is null in case the Text was created using Text.rich. I think the matcher should also take textSpan into consideration, something like this:
return textWidget.data == text || textWidget.textSpan.toPlainText() == text;
Alternatively, I could also imaging Text having something similar to TextSpan.toPlainText, returning whatever the (unstructured) text content is, and then using this in the matcher.