24

For example, I may have one RichText in current widget tree, that looks like

RichText(
 text: TextSpan(
   text: 'Hello ',
   style: DefaultTextStyle.of(context).style,
   children: <TextSpan>[
     TextSpan(text: 'bold', style: TextStyle(fontWeight: FontWeight.bold)),
     TextSpan(text: ' world!'),
   ],
 ),
)

I try to use find.text('Hello bold world!') but it doesn't work because it's not a Text.

Ravindra S. Patil
  • 11,757
  • 3
  • 13
  • 40
Wei Song
  • 1,517
  • 3
  • 11
  • 9

4 Answers4

29

Framework solution

I have recently contributed this feature to the Flutter framework, i.e. to the built-in finders.

find.text()

You can now enable a findRichText parameter, which will then also find standalone RichText widgets:

find.text(
  'Hello bold world!',
  findRichText: true,
)
creativecreatorormaybenot
  • 114,516
  • 58
  • 291
  • 402
23

Simplest solution is to put a key on the RichText and read it that way.

If that's not a good fit for whatever reason, you can use find.byWidgetPredicate and pass a function that matches RichText widgets whose text.toPlainText() returns the string you want.

Ian Hickson
  • 8,174
  • 1
  • 29
  • 22
  • 13
    Thanks, the second solution will be like:`expect(find.byWidgetPredicate((Widget widget) => widget is RichText && widget.text.toPlainText() == 'Hello bold world'), findsOneWidget);` – GEPD Jul 18 '19 at 18:14
  • In my case, widget.text.toPlainText() actually contained 0-width space characters at the end (probably because of empty spans). The only way I got it to work was to use .startsWith : `(widget) => widget is RichText && widget.text.toPlainText().startsWith('hello')` – Andrei Tudor Diaconu Sep 17 '20 at 15:48
14

Here's the find.byWidgetPredicate call.

find.byWidgetPredicate((widget) => fromRichTextToPlainText(widget) == 'Hello bold world!')

Here's the fromRichTextToPlainText helper function. Pass it the RichText widget, it will return the plain text.

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;
}
Bienvenido David
  • 4,118
  • 1
  • 25
  • 16
1

I solved for this by digging into the widget a bit more manually

    final richTextWidget = tester.element(richTextFinder).widget as RichText;
    print(richTextWidget.text.children);

With the children, I can assert they are generated as expected

futbolpal
  • 1,388
  • 2
  • 13
  • 19