Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test flutter url_launcher that email app opens?

I do have a Snackbar with a SnackbarAction which should open the default email app with a default subject and body on tap. I am wondering if there is somehow the possibility to verify if this really happens with some unit tests.

My Snackbar code looks like this:

SnackBar get snackbar =>
      SnackBar(
          content: Text(message),
          action: SnackBarAction(
              key: const Key('ErrorSnackbarAction'),
              label: AppLocalizations
                  .of(_context)
                  .report,
              onPressed: () async => await launch('mailto:[email protected]?subject=TestSubject&body=TestBody')));

I am already verifying the appearance which works fine:

group('ErrorSnackbar', () {
  testWidgets('appearance test', (WidgetTester tester) async {
    await tester.pumpWidget(_generateSnackbarApp());

    await _showSnackbar(tester);

    expect(find.text(userMessage), findsOneWidget);
    expect(find.byWidgetPredicate((Widget widget) =>
    widget is SnackBarAction && widget.label == 'Report'), findsOneWidget);
  });

  testWidgets('error report test', (WidgetTester tester) async {
    await tester.pumpWidget(_generateSnackbarApp());

    await _showSnackbar(tester);

    tester.tap(find.byKey(errorSnackbarAction));
    await tester.pump();

   // how to verify that the default email app was opened
  // with expected subject and body?

  });
});
like image 914
fezu54 Avatar asked Feb 25 '19 15:02

fezu54


2 Answers

Short answer: You can't.

The launch with mailto is handled by the OS of the device and is out of context of the flutter app. As the flutter test package focuses on the flutter app, what happens on the OS is out of reach.

like image 110
Muldec Avatar answered Oct 09 '22 12:10

Muldec


You can ensure that launchUrl is called and the expected parameters were passed. The url_launcher package should be tested. Therefore, we can expect that the email app opens, when we call launchUrl with the mailto: schema.

Here is a short introduction on how to test the url_launcher package:

Add plugin_platform_interface and url_launcher_platform_interface to your dev dependencies:

dev_dependencies:
  flutter_test:
    sdk: flutter
  plugin_platform_interface: any
  url_launcher_platform_interface: any

Copy the mock_url_launcher_platform.dart from the url_launcher package: https://github.com/flutter/plugins/blob/main/packages/url_launcher/url_launcher/test/mocks/mock_url_launcher_platform.dart

Now you can test the launchUrl calls like this:

void main() {
  late MockUrlLauncher mock;

  setUp(() {
    mock = MockUrlLauncher();
    UrlLauncherPlatform.instance = mock;
  });

  group('$Link', () {
    testWidgets('calls url_launcher for external URLs with blank target',
        (WidgetTester tester) async {
      FollowLink? followLink;

      await tester.pumpWidget(Link(
        uri: Uri.parse('http://example.com/foobar'),
        target: LinkTarget.blank,
        builder: (BuildContext context, FollowLink? followLink2) {
          followLink = followLink2;
          return Container();
        },
      ));

      mock
        ..setLaunchExpectations(
          url: 'http://example.com/foobar',
          useSafariVC: false,
          useWebView: false,
          universalLinksOnly: false,
          enableJavaScript: true,
          enableDomStorage: true,
          headers: <String, String>{},
          webOnlyWindowName: null,
        )
        ..setResponse(true);
      await followLink!();
      expect(mock.canLaunchCalled, isTrue);
      expect(mock.launchCalled, isTrue);
    });
  });
}

Copied the test from https://github.com/flutter/plugins/blob/main/packages/url_launcher/url_launcher/test/link_test.dart

like image 1
Nils Reichardt Avatar answered Oct 09 '22 11:10

Nils Reichardt