simc / auto_size_text

Flutter widget that automatically resizes text to fit perfectly within its bounds.
https://pub.dev/packages/auto_size_text
MIT License
2.06k stars 241 forks source link

Integration Tests do not work with AutoSizeText.rich(..) constructor #32

Closed sceee closed 5 years ago

sceee commented 5 years ago

Steps to Reproduce Thanks to https://github.com/leisim/auto_size_text/issues/27 I wanted to now check strings in my integration tests with driver.getText(myTextKeyFinder). Unfortunately, it does not seem to work with AutoSizeText.rich(..) constructed AutoSizeText widgets.

If I look at the tree with the Dart DevTools, the tree looks the following:

Obviously, if I then do the following:

String myElementText = await driver.getText(myTextKeyFinder);
expect(myElementText , 'My Text');

it fails because the Text widget with the key has no text and the RichText with my text has no key.

So in this case I would expect the RichText widget to have receive the key. Then I guess it would work.

Code sample

AutoSizeText.rich(
        TextSpan(
          style: _style,
          children: getStyledSpans( //getStyledSpans is a List<TextSpan>
            _text,
            _style,
          ),
        ),
        textAlign: _textAlign,
        maxLines: _maxLines,
        textKey: _textKey,
      ),

Screenshots N/A

Version

simc commented 5 years ago

This code works fine:

testWidgets('Uses textKey', (tester) async {
  var key = GlobalKey();
  await tester.pumpWidget(
    Directionality(
      textDirection: TextDirection.ltr,
      child: Center(
        child: AutoSizeText.rich(
          TextSpan(text: 'A rich text'),
          textKey: key,
        ),
      ),
    ),
  );
  print(find.byKey(key).evaluate().first);
});

AutoSizeText just passes the textKey to a Text.rich() widget as you can see here so there should be no difference to using Text.rich() directly.

sceee commented 5 years ago

@leisim thanks for the fast answer.

I see, the issue here is that for the RichText I use, I have to chain TextSpans. That's why I set the children property of the topmost TextSpan because I am formatting text here like the following: "This is my sample text."

As far as I know, the only way to do this with RichText is to chain the TextSpans.

And when you chain it, the key gets propagated to the wrong widget in the end.

Actually, I am not sure if this is a problem of AutoSizeText or the RichText itself but I would guess most RichText use-cases are the way I use them - to format portions of the text. Because formatting a single line can also be done with a regular Text field. What do you think?

simc commented 5 years ago

What happenes if you replace AutoSizeText.rich() with Text.rich()?

To be honest, I'm not that experienced with integration tests but I think that AutoSizeText behaves exactly the same as Text. In that case you'll need to open an issue in the Flutter repository or ask on StackOverflow.

sceee commented 5 years ago

@leisim I now got it working (at least for widget tests). See my answer here, maybe it helps someone that also stumbles across this issue: https://stackoverflow.com/questions/51238526/testing-text-in-textspan/57860023#57860023

I could not yet figure it out for integration tests but at least I now know parts of it. So it's something that should be possible with dart itself. Thanks anyway for your help!

vini2001 commented 3 years ago

This is very late but maybe it can help someone else, as I went through the same issue. I was able to get the text like this:

String getRichTextValue(Map<String, Object> widgetDiagnosis) {
  final properties = widgetDiagnosis['properties'];
  for(final dynamic property in properties) {
    if(property['name'] == 'text') {
      if(property['value'] != null) return property['value'];
    }
  }
  return "NOT FOUND";
}

final richTextItem = await driver.getWidgetDiagnostics(
            find.descendant(of: find.byValueKey(key), matching: find.byType('RichText')),
);
final itemValue = getRichTextValue(richTextItem);

Notice that the key property is the one set on AutoSizeText.rich() textKey property. Worked well for me.