Reputation: 5857
If we have a TextSpan
that is a child of a RichText
widget, how would you test the text content.
new TextSpan(
text: 'Hello world!',
style: new TextStyle(color: Colors.black),
)
In your tests, with a Text
widget, you can use expect(find.text('Hello world!'), findsOneWidget)
, but this doesn't work if you have a TextSpan
.
expect(find.byType(TextSpan), findsOneWidget)
also does not find any widgets of type TextSpan
.
Upvotes: 21
Views: 6039
Reputation: 4348
You can find the RichText widget instead. Here's the find.byWidgetPredicate call.
expect(find.byWidgetPredicate((widget) => fromRichTextToPlainText(widget) == 'Hello world!'), findsOneWidget);
Here's the fromRichTextToPlainText helper function. Pass it the RichText widget, it will return the plain text for all the underlying TextSpans.
String? fromRichTextToPlainText(final Widget widget) {
if (widget is RichText) {
if (widget.text is TextSpan) {
final buffer = StringBuffer();
(widget.text as TextSpan).computeToPlainText(buffer);
return buffer.toString();
}
}
return null;
}
Upvotes: 4
Reputation: 609
In case someone needs to not just find the widget, but also tap on it:
Finding a TextSpan to tap on with Flutter tests
Upvotes: 0
Reputation: 136
It can be achieved by using byWidgetPredicate
expect(
find.byWidgetPredicate((widget) =>
widget is RichText &&
widget.text.toPlainText() ==
'Hello World!.'),
findsOneWidget);
Upvotes: 9
Reputation: 1446
From above snippets - I found below bit customised version helpful to me..
String? fromRichTextToPlainText(final Widget widget) {
if (widget is RichText) {
return widget.text.toPlainText();
}
return null;
}
expect(
find.byWidgetPredicate(
(widget) => fromRichTextToPlainText(widget) == 'My Rich Text'),
findsOneWidget);
Upvotes: 0
Reputation: 2163
In addition to Rémi's answer, here is the way to find the text from a RichText
.
You set the key to the RichText
and then you can do:
Finder widgetFinder = find.byKey(key);
Finder rtFinder =
find.descendant(of: widgetFinder, matching: find.byType(RichText));
RichText richText = rtFinder.evaluate().first.widget as RichText;
String richTextText = richText.text.toPlainText();
print('Text from Text widget: $richTextText');
expect(richTextText, 'This is my text',
reason: 'Text from found text widget do not match');
Upvotes: 9
Reputation: 276957
That's not possible. As TextSpan
doesn't actually render anything.
It is data information used by another object to actually render something.
What you can do instead is to find the widget to which you pass your TextSpan
. And then verify it's correct
Upvotes: 10