[
  {
    "path": ".gitignore",
    "content": ".idea/\n*.*~"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2020 Matthew Jaoudi\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# flutter_test_cookbook\n\nA community driven cookbook with _recipes_ (i.e., examples) on how to test your flutter application.\n\n## Recipes\n\nThere are [three pillars](https://flutter.dev/docs/cookbook/testing) of flutter tests:\n1) unit\n2) widget\n3) integration\n\nThis cookbook is mostly concerned with 2 and 3.\n\nCurrently, [flutter_test](https://api.flutter.dev/flutter/flutter_test/flutter_test-library.html) is used for widget tests, and [flutter_driver](https://api.flutter.dev/flutter/flutter_driver/flutter_driver-library.html) is used for integration tests. However, it is possible that `flutter_driver` could eventually be deprecated, and `flutter_test` could be used for both widget and integration tests.\n\n    We're moving away from flutter_driver in favour of extending flutter_test to work on devices.\n\t- Hixie\n\thttps://github.com/flutter/flutter/issues/7474#issuecomment-558882182\n\nBecause of this, the recipes will be split out into two directories: `flutter_test` and `flutter_driver`\n\n### flutter_test recipes\n\n- [How do I run a flutter test?](https://github.com/gadfly361/flutter_test_cookbook/blob/master/recipes/flutter_test/how_do_i_run_a_flutter_test)\n- [How do I find something?](https://github.com/gadfly361/flutter_test_cookbook/blob/master/recipes/flutter_test/how_do_i_find_something)\n- [How do I test routes?](https://github.com/gadfly361/flutter_test_cookbook/blob/master/recipes/flutter_test/how_do_i_test_routes)\n- [How do I drag something?](https://github.com/gadfly361/flutter_test_cookbook/blob/master/recipes/flutter_test/how_do_i_drag_something)\n- [How do I open a Drawer?](https://github.com/gadfly361/flutter_test_cookbook/blob/master/recipes/flutter_test/how_do_i_open_a_drawer)\n- [How do I send a keyboard action like done or next?](https://github.com/gadfly361/flutter_test_cookbook/blob/master/recipes/flutter_test/how_do_i_send_a_keyboard_action)\n- [How do I test an Exception?](https://github.com/gadfly361/flutter_test_cookbook/blob/master/recipes/flutter_test/how_do_i_test_an_exception)\n- [What if I need a BuildContext?](https://github.com/gadfly361/flutter_test_cookbook/blob/master/recipes/flutter_test/what_if_i_need_build_context)\n- [How do I run a script inside a test?](https://github.com/gadfly361/flutter_test_cookbook/blob/master/recipes/flutter_test/how_do_i_run_a_script)\n- [How do I mock an async http request?](https://github.com/gadfly361/flutter_test_cookbook/blob/master/recipes/flutter_test/how_do_i_mock_async_http_request)\n- [How do I mock shared_preferences?](https://github.com/gadfly361/flutter_test_cookbook/blob/master/recipes/flutter_test/how_do_i_mock_shared_preferences)\n- [How do I test an animation?](https://github.com/gadfly361/flutter_test_cookbook/blob/master/recipes/flutter_test/how_do_i_test_an_animation)\n\n### flutter_driver recipes\n\n- [How do I run a flutter driver test?](https://github.com/gadfly361/flutter_test_cookbook/blob/master/recipes/flutter_driver/how_do_i_run_a_flutter_driver_test)\n- [How do I find something?](https://github.com/gadfly361/flutter_test_cookbook/blob/master/recipes/flutter_driver/how_do_i_find_something)\n- [How do I take a screenshot](https://github.com/gadfly361/flutter_test_cookbook/blob/master/recipes/flutter_driver/how_do_i_take_a_screenshot)\n- [How do I dismiss (i.e. pop) a dialog?](https://github.com/gadfly361/flutter_test_cookbook/blob/master/recipes/flutter_driver/how_do_i_pop_dialog)\n- [How do I run a script inside of a test?](https://github.com/gadfly361/flutter_test_cookbook/blob/master/recipes/flutter_driver/how_do_i_run_a_script)\n- [How I run multiple test files without restarting app?](https://github.com/gadfly361/flutter_test_cookbook/blob/master/recipes/flutter_driver/how_do_i_run_multiple_test_files_without_restarting_app)\n\n## External Resources\n\nThis section is a list of external resources that may be useful when exploring how to test your flutter application.\n\n*Written*\n- [Flutter UI Testing (with codemagic)](https://blog.codemagic.io/flutter-ui-testing/)\n- [Mock dependencies using Mockito](https://flutter.dev/docs/cookbook/testing/unit/mocking)\n- [Flutter: Golden tests - compare Widgets with Snapshots](https://medium.com/flutter-community/flutter-golden-tests-compare-widgets-with-snapshots-27f83f266cea)\n- [Testing gestures using Flutter driver](https://medium.com/flutter-community/testing-gestures-using-flutter-driver-b37981c24366)\n- [60 Days of Flutter: Day 4-5: Widget Testing with Flutter](https://medium.com/@adityadroid/60-days-of-flutter-day-4-5-widget-testing-with-flutter-a30236dd04fc)\n- [Blazingly Fast Flutter Driver Tests](https://medium.com/flutter-community/blazingly-fast-flutter-driver-tests-5e375c833aa)\n- [Developing and testing accessible apps in Flutter](https://medium.com/flutter-community/developing-and-testing-accessible-app-in-flutter-1dc1d33c7eea)\n\n\n*Videos*\n- [Flutter: Deep Dive with Widget Tests and Mockito](https://www.youtube.com/watch?v=75i5VmTI6A0)\n- [Bloc Test Tutorial - Easier Way to Test Blocs in Dart & Flutter](https://resocoder.com/2019/11/29/bloc-test-tutorial-easier-way-to-test-blocs-in-dart-flutter/)\n\n\n## Want to contribute?\n\nFirst of all, thank you. Contributions are encouraged!  Please follow the guidelines below.\n\n### Want to suggest a recipe?\n\nIf you'd like to suggest a recipe, please open an issue and add `[recipe-suggestion]` to the beginning of the title.\n\n### Want to add your own recipe?\n\nIf you'd like to add a recipe, please add `[new-recipe]` to the beginning of your PR's title.\n\nEach recipe should:\n\n- be focused on a specific topic\n- be concise\n- have runnable tests\n- only check in 'meaningful' files\n\nNote: if you want to get an early sense of whether or not your recipe will be accepted, please open a `[recipe-suggestion]` issue first.\n\n### Want to fix a typo?\n\nIf you'd like to fix a typo, please add `[fix-typo]` to the beginning of your PR's title.\n\n### Want to correct an error in an existing recipe?\n\nIf you'd like to correct an error in an existing recipe, please add `[fix-recipe]` to the beginning of your PR's title.\n\n### Want to add a link to an external resource?\n\nIf you'd like to add a link to an external resource, please add `[add-resource]` to the beginning of your PR's title.\n\n## LICENSE\n\nCopyright © 2020 Matthew Jaoudi\n\nDistributed under the The MIT License (MIT).\n"
  },
  {
    "path": "recipes/flutter_driver/how_do_i_find_something/.gitignore",
    "content": "# Miscellaneous\n*.class\n*.log\n*.pyc\n*.swp\n.DS_Store\n.atom/\n.buildlog/\n.history\n.svn/\n\n# IntelliJ related\n*.iml\n*.ipr\n*.iws\n.idea/\n\n# The .vscode folder contains launch configuration and tasks you configure in\n# VS Code which you may wish to be included in version control, so this line\n# is commented out by default.\n#.vscode/\n\n# Flutter/Dart/Pub related\n**/doc/api/\n.dart_tool/\n.flutter-plugins\n.flutter-plugins-dependencies\n.packages\n.pub-cache/\n.pub/\n/build/\n\n# Web related\nlib/generated_plugin_registrant.dart\n\n# Exceptions to above rules.\n!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages\n\n# Flutter Test Cookbook (Driver)\n.dart_tool/\n.metadata\n.packages\nandroid/\nios/\npubspec.lock\nftc.iml\n*.*~\ntest/"
  },
  {
    "path": "recipes/flutter_driver/how_do_i_find_something/README.md",
    "content": "# Question\n\nHow do I find something ... whether it be a widget, some text, etc?\n\n# Answer\n\n## 1) Create a flutter application.\n\n```sh\nflutter create ftc\ncd ftc\n```\n\n## 2) Add [flutter_driver](https://api.flutter.dev/flutter/flutter_driver/flutter_driver-library.html) and [test](https://pub.dev/packages/test) to your `pubspec.yaml` file.\n\n```yaml\ndev_dependencies:\n  flutter_driver:\n    sdk: flutter\n  test: any\n```\n\nThen get the dependencies by running:\n\n```sh\nflutter packages get\n```\n\n## 3) Replace the `lib/main.dart` file\n\nReplace the `lib/main.dart` file with the following:\n\n```dart\nimport 'package:flutter/material.dart';\n\nvoid main() => runApp(MyApp());\n\nclass MyApp extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      home: Scaffold(\n        body: Column(\n          children: <Widget>[\n            RaisedButton(\n              onPressed: () => print(\"rasied button was clicked\"),\n              child: Text(\"we will find this by searching for a type\"),\n            ),\n            Text(\n              \"we will find this by searching for text\",\n            ),\n            Text(\n              \"will will find this by searching for a key\",\n              key: Key(\"mykey\"),\n            ),\n          ],\n        ),\n      ),\n    );\n  }\n}\n```\n\n## 4) Create a `test_driver` directory.\n\n```sh\nmkdir test_driver\ncd test_driver\n```\n\n## 5) Add an `example.dart` file.\n\nCreate a `test_driver/example.dart` file, and add the following to it:\n\n```dart\nimport 'package:flutter_driver/driver_extension.dart';\nimport 'package:ftc/main.dart' as app;\n\nvoid main() {\n  // Add the following to leverage flutter_driver\n  enableFlutterDriverExtension();\n\n  app.main();\n}\n```\n\n## 6) Add an `example_test.dart` file.\n\nCreate a `test_driver/example_test.dart` file, and add the following to it:\n\n```dart\nimport 'package:flutter_driver/flutter_driver.dart';\nimport 'package:test/test.dart';\n\nvoid main() {\n  FlutterDriver driver;\n\n  setUpAll(() async {\n    driver = await FlutterDriver.connect();\n  });\n\n  tearDownAll(() async {\n    if (driver != null) {\n      await driver.close();\n    }\n  });\n\n  test(\"let's find a widget by its type\", () async {\n    // There is a RaisedButton in the main.dart file\n    SerializableFinder raisedButtonFinder = find.byType(\"RaisedButton\");\n\n    await driver.waitFor(raisedButtonFinder);\n    await driver.tap(raisedButtonFinder);\n  });\n\n  test(\"let's find a specific string of text\", () async {\n    // This is the exact string of text found in a Text widget in the main.dart file\n    SerializableFinder textFinder =\n        find.text(\"we will find this by searching for text\");\n\n    await driver.waitFor(textFinder);\n  });\n\n  test(\"let's find a widget by its key\", () async {\n    // There is a widget with its key defined as `Key(\"mykey\")` in the main.dart file\n    SerializableFinder keyFinder = find.byValueKey(\"mykey\");\n\n    await driver.waitFor(keyFinder);\n  });\n}\n```\n\n## 7) Run the flutter driver tests\n\n```sh\nflutter driver -t test_driver/example.dart\n```\n\n# Run tests from example code in cookbook itself\n\nIf you have cloned [flutter_test_cookbook](https://github.com/gadfly361/flutter_test_cookbook/tree/master) and simply want to run the tests from this recipe, then:\n\n```sh\nflutter create .\nflutter packages get\nflutter driver -t test_driver/example.dart\n```\n\n# Outputs when recipe was made / updated\n\n## Output of running flutter driver tests\n\n```sh\n$ flutter driver -t test_driver/example.dart \nUsing device iPhone 8.\nStarting application: test_driver/example.dart\nRunning Xcode build...                                                  \n ├─Assembling Flutter resources...                           9.5s\n └─Compiling, linking and signing...                         4.4s\nXcode build done.                                           15.4s\nflutter: Observatory listening on http://127.0.0.1:62625/uVmgCkrhJno=/\n00:00 +0: (setUpAll)\n\n[info ] FlutterDriver: Connecting to Flutter application at http://127.0.0.1:62625/uVmgCkrhJno=/\n[trace] FlutterDriver: Isolate found with number: 2547406183923599\n[trace] FlutterDriver: Isolate is paused at start.\n[trace] FlutterDriver: Attempting to resume isolate\n[trace] FlutterDriver: Waiting for service extension\n[info ] FlutterDriver: Connected to Flutter application.\n00:00 +0: let's find a widget by its type\n\nflutter: rasied button was clicked\n00:00 +1: let's find a specific string of text\n\n00:00 +2: let's find a widget by its key\n\n00:00 +3: (tearDownAll)\n\n00:00 +3: All tests passed!\n\nStopping application instance.\n```\n\n## Output of running `flutter doctor -v`\n\n```sh\n$ flutter doctor -v\n[✓] Flutter (Channel stable, v1.12.13+hotfix.5, on Mac OS X 10.15.2 19C57, locale en-US)\n    • Flutter version 1.12.13+hotfix.5 at /Users/matthew/gadfly/flutter_versions/flutter_1.12.13+hotfix.5\n    • Framework revision 27321ebbad (3 months ago), 2019-12-10 18:15:01 -0800\n    • Engine revision 2994f7e1e6\n    • Dart version 2.7.0\n\n \n[✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)\n    • Android SDK at /Users/matthew/Library/Android/sdk\n    • Android NDK location not configured (optional; useful for native profiling support)\n    • Platform android-29, build-tools 28.0.3\n    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java\n    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)\n    • All Android licenses accepted.\n\n[✓] Xcode - develop for iOS and macOS (Xcode 11.3.1)\n    • Xcode at /Applications/Xcode.app/Contents/Developer\n    • Xcode 11.3.1, Build version 11C504\n    • CocoaPods version 1.8.4\n\n[✓] Android Studio (version 3.4)\n    • Android Studio at /Applications/Android Studio.app/Contents\n    • Flutter plugin version 35.2.1\n    • Dart plugin version 183.6270\n    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)\n\n[✓] IntelliJ IDEA Community Edition (version 2019.3.3)\n    • IntelliJ at /Applications/IntelliJ IDEA CE.app\n    • Flutter plugin version 44.0.3\n    • Dart plugin version 193.6494.35\n\n[✓] VS Code (version 1.41.1)\n    • VS Code at /Applications/Visual Studio Code.app/Contents\n    • Flutter extension version 3.4.1\n\n[✓] Connected device (1 available)\n    • iPhone 8 • AD7A90EB-5E73-427E-B9B7-DD3B07E2FEF1 • ios • com.apple.CoreSimulator.SimRuntime.iOS-13-3 (simulator)\n\n• No issues found!\n```\n"
  },
  {
    "path": "recipes/flutter_driver/how_do_i_find_something/lib/main.dart",
    "content": "import 'package:flutter/material.dart';\n\nvoid main() => runApp(MyApp());\n\nclass MyApp extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      home: Scaffold(\n        body: Column(\n          children: <Widget>[\n            RaisedButton(\n              onPressed: () => print(\"rasied button was clicked\"),\n              child: Text(\"we will find this by searching for a type\"),\n            ),\n            Text(\n              \"we will find this by searching for text\",\n            ),\n            Text(\n              \"will will find this by searching for a key\",\n              key: Key(\"mykey\"),\n            ),\n          ],\n        ),\n      ),\n    );\n  }\n}\n"
  },
  {
    "path": "recipes/flutter_driver/how_do_i_find_something/pubspec.yaml",
    "content": "name: ftc\ndescription: A new Flutter project.\n\nversion: 1.0.0+1\n\nenvironment:\n  sdk: \">=2.1.0 <3.0.0\"\n\ndependencies:\n  flutter:\n    sdk: flutter\n\ndev_dependencies:\n  flutter_driver:\n    sdk: flutter\n  test: any\n"
  },
  {
    "path": "recipes/flutter_driver/how_do_i_find_something/test_driver/example.dart",
    "content": "import 'package:flutter_driver/driver_extension.dart';\nimport 'package:ftc/main.dart' as app;\n\nvoid main() {\n  // Add the following to leverage flutter_driver\n  enableFlutterDriverExtension();\n\n  app.main();\n}\n"
  },
  {
    "path": "recipes/flutter_driver/how_do_i_find_something/test_driver/example_test.dart",
    "content": "import 'package:flutter_driver/flutter_driver.dart';\nimport 'package:test/test.dart';\n\nvoid main() {\n  FlutterDriver driver;\n\n  setUpAll(() async {\n    driver = await FlutterDriver.connect();\n  });\n\n  tearDownAll(() async {\n    if (driver != null) {\n      await driver.close();\n    }\n  });\n\n  test(\"let's find a widget by its type\", () async {\n    // There is a RaisedButton in the main.dart file\n    SerializableFinder raisedButtonFinder = find.byType(\"RaisedButton\");\n\n    await driver.waitFor(raisedButtonFinder);\n    await driver.tap(raisedButtonFinder);\n  });\n\n  test(\"let's find a specific string of text\", () async {\n    // This is the exact string of text found in a Text widget in the main.dart file\n    SerializableFinder textFinder =\n        find.text(\"we will find this by searching for text\");\n\n    await driver.waitFor(textFinder);\n  });\n\n  test(\"let's find a widget by its key\", () async {\n    // There is a widget with its key defined as `Key(\"mykey\")` in the main.dart file\n    SerializableFinder keyFinder = find.byValueKey(\"mykey\");\n\n    await driver.waitFor(keyFinder);\n  });\n}\n"
  },
  {
    "path": "recipes/flutter_driver/how_do_i_pop_dialog/.gitignore",
    "content": "# Miscellaneous\n*.class\n*.log\n*.pyc\n*.swp\n.DS_Store\n.atom/\n.buildlog/\n.history\n.svn/\n\n# IntelliJ related\n*.iml\n*.ipr\n*.iws\n.idea/\n\n# The .vscode folder contains launch configuration and tasks you configure in\n# VS Code which you may wish to be included in version control, so this line\n# is commented out by default.\n#.vscode/\n\n# Flutter/Dart/Pub related\n**/doc/api/\n.dart_tool/\n.flutter-plugins\n.flutter-plugins-dependencies\n.packages\n.pub-cache/\n.pub/\n/build/\n\n# Web related\nlib/generated_plugin_registrant.dart\n\n# Exceptions to above rules.\n!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages\n\n# Flutter Test Cookbook (Driver)\n.dart_tool/\n.metadata\n.packages\nandroid/\nios/\npubspec.lock\nftc.iml\n*.*~\ntest/"
  },
  {
    "path": "recipes/flutter_driver/how_do_i_pop_dialog/README.md",
    "content": "# Question\n\nHow do I dismiss a [Dialog](https://api.flutter.dev/flutter/material/Dialog-class.html) that doesn't have an explicit widget to do so?\n\n# Answer\n\nYou may find yourself creating a Dialog that relies on a user pressing on the [ModalBarrier](https://api.flutter.dev/flutter/widgets/ModalBarrier-class.html) to dismiss it (as opposed to them clicking on an explicit widget like a button).\n\nIn this situation, we can use the [Navigator](https://api.flutter.dev/flutter/dart-html/Navigator-class.html) to pop the Dialog from the stack (i.e. dismiss the Dialog).\n\nTo do so, we can to take advantage of the [DataHandler](https://api.flutter.dev/flutter/flutter_driver_extension/DataHandler.html) found in the [enableFlutterDriverExtension](https://api.flutter.dev/flutter/flutter_driver_extension/enableFlutterDriverExtension.html) function.\n\n## 1) Create a flutter application.\n\n```sh\nflutter create ftc\ncd ftc\n```\n\n## 2) Add [flutter_driver](https://api.flutter.dev/flutter/flutter_driver/flutter_driver-library.html) and [test](https://pub.dev/packages/test) to your `pubspec.yaml` file.\n\n```yaml\ndev_dependencies:\n  flutter_driver:\n    sdk: flutter\n  test: any\n```\n\nThen get the dependencies by running:\n\n```sh\nflutter packages get\n```\n\n## 3) Replace the `lib/main.dart` file\n\nReplace the `lib/main.dart` file with the following:\n\n```dart\nimport 'package:flutter/material.dart';\n\nvoid main() => runApp(MyApp());\n\nGlobalKey<NavigatorState> appNavigatorKey = GlobalKey<NavigatorState>();\n\nclass MyApp extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      // Note: we are adding a navigatorKey here\n      navigatorKey: appNavigatorKey,\n      home: Scaffold(\n        body: Body(),\n      ),\n    );\n  }\n}\n\nclass Body extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return Center(\n      child: RaisedButton(\n        child: Text(\"Open Dialog\"),\n        onPressed: () {\n          showDialog(\n            context: context,\n            builder: (BuildContext _context) {\n              return Dialog(\n                child: SizedBox(\n                  height: 100,\n                  child: Center(\n                    child: Text(\"This is a Dialog\"),\n                  ),\n                ),\n              );\n            },\n          );\n        },\n      ),\n    );\n  }\n}\n```\n\n## 4) Create a `test_driver` directory.\n\n```sh\nmkdir test_driver\ncd test_driver\n```\n\n## 5) Add an `example.dart` file.\n\nCreate a `test_driver/example.dart` file, and add the following to it:\n\n```dart\nimport 'package:flutter_driver/driver_extension.dart';\nimport 'package:ftc/main.dart' as app;\n\nFuture<String> dataHandler(String message) async {\n  // We are using the data handler to execute a pop side-effect\n  if (message == \"pop\") {\n    app.appNavigatorKey.currentState.pop();\n  }\n\n  return null;\n}\n\nvoid main() {\n  enableFlutterDriverExtension(\n    // we are adding the dataHandler here\n    handler: dataHandler,\n  );\n\n  app.main();\n}\n```\n\n## 6) Add an `example_test.dart` file.\n\nCreate a `test_driver/example_test.dart` file, and add the following to it:\n\n```dart\nimport 'package:flutter_driver/flutter_driver.dart';\nimport 'package:test/test.dart';\n\nvoid main() {\n  FlutterDriver driver;\n\n  setUpAll(() async {\n    driver = await FlutterDriver.connect();\n  });\n\n  tearDownAll(() async {\n    if (driver != null) {\n      await driver.close();\n    }\n  });\n\n  test(\"let's open a dialog and then close it\", () async {\n    SerializableFinder raisedButtonFinder = find.byType(\"RaisedButton\");\n    await driver.waitFor(raisedButtonFinder);\n    // tapping the button opens the Dialog\n    await driver.tap(raisedButtonFinder);\n\n    // make sure the the Dialog is open\n    SerializableFinder dialogFinder = find.byType(\"Dialog\");\n    await driver.waitFor(dialogFinder);\n\n    // now, let's close the dialog using the dataHandler we defined in\n    // our [enableFlutterDriverExtension] function.\n    await driver.requestData(\"pop\");\n    \n   // finally, let's wait to make sure the Dialog is gone\n    await driver.waitForAbsent(dialogFinder);\n  });\n}\n```\n\n## 7) Run the flutter driver tests\n\n```sh\nflutter driver -t test_driver/example.dart\n```\n\n# Run tests from example code in cookbook itself\n\nIf you have cloned [flutter_test_cookbook](https://github.com/gadfly361/flutter_test_cookbook/tree/master) and simply want to run the tests from this recipe, then:\n\n```sh\nflutter create .\nflutter packages get\nflutter driver -t test_driver/example.dart\n```\n\n# Outputs when recipe was made / updated\n\n## Output of running flutter driver tests\n\n```sh\n$ flutter driver -t test_driver/example.dart \nUsing device iPhone 8.\nStarting application: test_driver/example.dart\nRunning Xcode build...                                                  \n ├─Assembling Flutter resources...                           2.6s\n └─Compiling, linking and signing...                         2.9s\nXcode build done.                                            6.6s\nflutter: Observatory listening on http://127.0.0.1:51796/uIFIjnNgNMs=/\n00:00 +0: (setUpAll)\n\n[info ] FlutterDriver: Connecting to Flutter application at http://127.0.0.1:51796/uIFIjnNgNMs=/\n[trace] FlutterDriver: Isolate found with number: 491196511285567\n[trace] FlutterDriver: Isolate is paused at start.\n[trace] FlutterDriver: Attempting to resume isolate\n[trace] FlutterDriver: Waiting for service extension\n[info ] FlutterDriver: Connected to Flutter application.\n00:00 +0: let's open a dialog and then close it\n\n00:00 +1: (tearDownAll)\n\n00:00 +1: All tests passed!\n\nStopping application instance.\n```\n\n## Output of running `flutter doctor -v`\n\n```sh\n$ flutter doctor -v\n[✓] Flutter (Channel stable, v1.12.13+hotfix.5, on Mac OS X 10.15.2 19C57, locale en-US)\n    • Flutter version 1.12.13+hotfix.5 at /Users/matthew/gadfly/flutter_versions/flutter_1.12.13+hotfix.5\n    • Framework revision 27321ebbad (3 months ago), 2019-12-10 18:15:01 -0800\n    • Engine revision 2994f7e1e6\n    • Dart version 2.7.0\n\n[✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)\n    • Android SDK at /Users/matthew/Library/Android/sdk\n    • Android NDK location not configured (optional; useful for native profiling support)\n    • Platform android-29, build-tools 28.0.3\n    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java\n    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)\n    • All Android licenses accepted.\n\n[✓] Xcode - develop for iOS and macOS (Xcode 11.3.1)\n    • Xcode at /Applications/Xcode.app/Contents/Developer\n    • Xcode 11.3.1, Build version 11C504\n    • CocoaPods version 1.8.4\n\n[✓] Android Studio (version 3.4)\n    • Android Studio at /Applications/Android Studio.app/Contents\n    • Flutter plugin version 35.2.1\n    • Dart plugin version 183.6270\n    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)\n\n[✓] IntelliJ IDEA Community Edition (version 2019.3.3)\n    • IntelliJ at /Applications/IntelliJ IDEA CE.app\n    • Flutter plugin version 44.0.3\n    • Dart plugin version 193.6494.35\n\n[✓] VS Code (version 1.41.1)\n    • VS Code at /Applications/Visual Studio Code.app/Contents\n    • Flutter extension version 3.4.1\n\n[✓] Connected device (1 available)\n    • iPhone 8 • AD7A90EB-5E73-427E-B9B7-DD3B07E2FEF1 • ios • com.apple.CoreSimulator.SimRuntime.iOS-13-3 (simulator)\n\n• No issues found!\n```\n"
  },
  {
    "path": "recipes/flutter_driver/how_do_i_pop_dialog/lib/main.dart",
    "content": "import 'package:flutter/material.dart';\n\nvoid main() => runApp(MyApp());\n\nGlobalKey<NavigatorState> appNavigatorKey = GlobalKey<NavigatorState>();\n\nclass MyApp extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      // Note: we are adding a navigatorKey here\n      navigatorKey: appNavigatorKey,\n      home: Scaffold(\n        body: Body(),\n      ),\n    );\n  }\n}\n\nclass Body extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return Center(\n      child: RaisedButton(\n        child: Text(\"Open Dialog\"),\n        onPressed: () {\n          showDialog(\n            context: context,\n            builder: (BuildContext _context) {\n              return Dialog(\n                child: SizedBox(\n                  height: 100,\n                  child: Center(\n                    child: Text(\"This is a Dialog\"),\n                  ),\n                ),\n              );\n            },\n          );\n        },\n      ),\n    );\n  }\n}\n"
  },
  {
    "path": "recipes/flutter_driver/how_do_i_pop_dialog/pubspec.yaml",
    "content": "name: ftc\ndescription: A new Flutter project.\n\nversion: 1.0.0+1\n\nenvironment:\n  sdk: \">=2.1.0 <3.0.0\"\n\ndependencies:\n  flutter:\n    sdk: flutter\n\ndev_dependencies:\n  flutter_driver:\n    sdk: flutter\n  test: any\n"
  },
  {
    "path": "recipes/flutter_driver/how_do_i_pop_dialog/test_driver/example.dart",
    "content": "import 'package:flutter_driver/driver_extension.dart';\nimport 'package:ftc/main.dart' as app;\n\nFuture<String> dataHandler(String message) async {\n  // We are using the data handler to execute a pop side-effect\n  if (message == \"pop\") {\n    app.appNavigatorKey.currentState.pop();\n  }\n\n  return null;\n}\n\nvoid main() {\n  enableFlutterDriverExtension(\n    // we are adding the dataHandler here\n    handler: dataHandler,\n  );\n\n  app.main();\n}\n"
  },
  {
    "path": "recipes/flutter_driver/how_do_i_pop_dialog/test_driver/example_test.dart",
    "content": "import 'package:flutter_driver/flutter_driver.dart';\nimport 'package:test/test.dart';\n\nvoid main() {\n  FlutterDriver driver;\n\n  setUpAll(() async {\n    driver = await FlutterDriver.connect();\n  });\n\n  tearDownAll(() async {\n    if (driver != null) {\n      await driver.close();\n    }\n  });\n\n  test(\"let's open a dialog and then close it\", () async {\n    SerializableFinder raisedButtonFinder = find.byType(\"RaisedButton\");\n    await driver.waitFor(raisedButtonFinder);\n    // tapping the button opens the Dialog\n    await driver.tap(raisedButtonFinder);\n\n    // make sure the the Dialog is open\n    SerializableFinder dialogFinder = find.byType(\"Dialog\");\n    await driver.waitFor(dialogFinder);\n\n    // now, let's close the dialog using the dataHandler we defined in\n    // our [enableFlutterDriverExtension] function.\n    await driver.requestData(\"pop\");\n\n    // finally, let's wait to make sure the Dialog is gone\n    await driver.waitForAbsent(dialogFinder);\n  });\n}\n"
  },
  {
    "path": "recipes/flutter_driver/how_do_i_run_a_flutter_driver_test/.gitignore",
    "content": "# Miscellaneous\n*.class\n*.log\n*.pyc\n*.swp\n.DS_Store\n.atom/\n.buildlog/\n.history\n.svn/\n\n# IntelliJ related\n*.iml\n*.ipr\n*.iws\n.idea/\n\n# The .vscode folder contains launch configuration and tasks you configure in\n# VS Code which you may wish to be included in version control, so this line\n# is commented out by default.\n#.vscode/\n\n# Flutter/Dart/Pub related\n**/doc/api/\n.dart_tool/\n.flutter-plugins\n.flutter-plugins-dependencies\n.packages\n.pub-cache/\n.pub/\n/build/\n\n# Web related\nlib/generated_plugin_registrant.dart\n\n# Exceptions to above rules.\n!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages\n\n# Flutter Test Cookbook (Driver)\n.dart_tool/\n.metadata\n.packages\nandroid/\nios/\npubspec.lock\nftc.iml\n*.*~\ntest/"
  },
  {
    "path": "recipes/flutter_driver/how_do_i_run_a_flutter_driver_test/README.md",
    "content": "# Question\n\nHow do I run a [flutter driver](https://api.flutter.dev/flutter/flutter_driver/flutter_driver-library.html) test?\n\n# Answer\n\n## 1) Create a flutter application.\n\n```sh\nflutter create ftc\ncd ftc\n```\n\n## 2) Add [flutter_driver](https://api.flutter.dev/flutter/flutter_driver/flutter_driver-library.html) and [test](https://pub.dev/packages/test) to your `pubspec.yaml` file.\n\n```yaml\ndev_dependencies:\n  flutter_driver:\n    sdk: flutter\n  test: any\n```\n\nThen get the dependencies by running:\n\n```sh\nflutter packages get\n```\n\n## 3) Replace the `lib/main.dart` file\n\nReplace the `lib/main.dart` file with the following:\n\n```dart\nimport 'package:flutter/material.dart';\n\nvoid main() => runApp(MyApp());\n\nclass MyApp extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      home: Scaffold(\n        body: Center(\n          child: Text(\"Hello world\"),\n        ),\n      ),\n    );\n  }\n}\n```\n\n## 4) Create a `test_driver` directory.\n\n```sh\nmkdir test_driver\ncd test_driver\n```\n\n## 5) Add an `example.dart` file.\n\nCreate a `test_driver/example.dart` file, and add the following to it:\n\n```dart\nimport 'package:flutter_driver/driver_extension.dart';\nimport 'package:ftc/main.dart' as app;\n\nvoid main() {\n  // Add the following to leverage flutter_driver\n  enableFlutterDriverExtension();\n\n  app.main();\n}\n```\n\n[Reference](https://flutter.dev/docs/cookbook/testing/integration/introduction#4-instrument-the-app)\n\n## 6) Add an `example_test.dart` file.\n\nCreate a `test_driver/example_test.dart` file, and add the following to it:\n\n```dart\nimport 'package:flutter_driver/flutter_driver.dart';\nimport 'package:test/test.dart';\n\nvoid main() {\n  FlutterDriver driver;\n\n  setUpAll(() async {\n    driver = await FlutterDriver.connect();\n  });\n\n  tearDownAll(() async {\n    if (driver != null) {\n      await driver.close();\n    }\n  });\n\n  test(\"'Hello world' text exists\", () async {\n    SerializableFinder helloWorldTextFinder = find.text(\"Hello world\");\n\n    await driver.waitFor(helloWorldTextFinder);\n  });\n}\n```\n\n## 7) Run the flutter driver tests\n\n```sh\nflutter driver -t test_driver/example.dart\n```\n\n# Run tests from example code in cookbook itself\n\nIf you have cloned [flutter_test_cookbook](https://github.com/gadfly361/flutter_test_cookbook/tree/master) and simply want to run the tests from this recipe, then:\n\n```sh\nflutter create .\nflutter packages get\nflutter driver -t test_driver/example.dart\n```\n\n# Outputs when recipe was made / updated\n\n## Output of running flutter driver tests\n\n```sh\n$ flutter driver -t test_driver/example.dart \nUsing device iPhone 8.\nStarting application: test_driver/example.dart\nRunning Xcode build...                                                  \n ├─Assembling Flutter resources...                           7.9s\n └─Compiling, linking and signing...                         4.1s\nXcode build done.                                           13.2s\nflutter: Observatory listening on http://127.0.0.1:60787/uPVFLEOkdqo=/\n00:00 +0: (setUpAll)\n\n[info ] FlutterDriver: Connecting to Flutter application at http://127.0.0.1:60787/uPVFLEOkdqo=/\n[trace] FlutterDriver: Isolate found with number: 4366875479017451\n[trace] FlutterDriver: Isolate is paused at start.\n[trace] FlutterDriver: Attempting to resume isolate\n[trace] FlutterDriver: Waiting for service extension\n[info ] FlutterDriver: Connected to Flutter application.\n00:00 +0: 'Hello world' text exists\n\n00:00 +1: (tearDownAll)\n\n00:00 +1: All tests passed!\n\nStopping application instance.\n```\n\n## Output of running `flutter doctor -v`\n\n```sh\n$ flutter doctor -v\n[✓] Flutter (Channel stable, v1.12.13+hotfix.5, on Mac OS X 10.15.2\n    19C57, locale en-US)\n    • Flutter version 1.12.13+hotfix.5 at\n      /Users/matthew/gadfly/flutter_versions/flutter_1.12.13+hotfix.5\n    • Framework revision 27321ebbad (7 weeks ago), 2019-12-10 18:15:01\n      -0800\n    • Engine revision 2994f7e1e6\n    • Dart version 2.7.0\n\n[✓] Android toolchain - develop for Android devices (Android SDK\n    version 28.0.3)\n    • Android SDK at /Users/matthew/Library/Android/sdk\n    • Android NDK location not configured (optional; useful for native\n      profiling support)\n    • Platform android-29, build-tools 28.0.3\n    • Java binary at: /Applications/Android\n      Studio.app/Contents/jre/jdk/Contents/Home/bin/java\n    • Java version OpenJDK Runtime Environment (build\n      1.8.0_152-release-1343-b01)\n    • All Android licenses accepted.\n\n[✓] Xcode - develop for iOS and macOS (Xcode 11.3.1)\n    • Xcode at /Applications/Xcode.app/Contents/Developer\n    • Xcode 11.3.1, Build version 11C504\n    • CocoaPods version 1.8.4\n\n[✓] Android Studio (version 3.4)\n    • Android Studio at /Applications/Android Studio.app/Contents\n    • Flutter plugin version 35.2.1\n    • Dart plugin version 183.6270\n    • Java version OpenJDK Runtime Environment (build\n      1.8.0_152-release-1343-b01)\n\n[✓] IntelliJ IDEA Community Edition (version 2019.3.2)\n    • IntelliJ at /Applications/IntelliJ IDEA CE.app\n    • Flutter plugin version 42.1.4\n    • Dart plugin version 193.6015.9\n\n[✓] VS Code (version 1.40.1)\n    • VS Code at /Applications/Visual Studio Code.app/Contents\n    • Flutter extension version 3.4.1\n\n[✓] Connected device (1 available)\n    • iPhone 8 • AD7A90EB-5E73-427E-B9B7-DD3B07E2FEF1 • ios •\n      com.apple.CoreSimulator.SimRuntime.iOS-13-3 (simulator)\n\n• No issues found!\n```\n"
  },
  {
    "path": "recipes/flutter_driver/how_do_i_run_a_flutter_driver_test/lib/main.dart",
    "content": "import 'package:flutter/material.dart';\n\nvoid main() => runApp(MyApp());\n\nclass MyApp extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      home: Scaffold(\n        body: Center(\n          child: Text(\"Hello world\"),\n        ),\n      ),\n    );\n  }\n}\n"
  },
  {
    "path": "recipes/flutter_driver/how_do_i_run_a_flutter_driver_test/pubspec.yaml",
    "content": "name: ftc\n\nversion: 1.0.0+1\n\nenvironment:\n  sdk: \">=2.1.0 <3.0.0\"\n\ndependencies:\n  flutter:\n    sdk: flutter\n\ndev_dependencies:\n  flutter_driver:\n    sdk: flutter\n  test: any\n"
  },
  {
    "path": "recipes/flutter_driver/how_do_i_run_a_flutter_driver_test/test_driver/example.dart",
    "content": "import 'package:flutter_driver/driver_extension.dart';\nimport 'package:ftc/main.dart' as app;\n\nvoid main() {\n  // Add the following to leverage flutter_driver\n  enableFlutterDriverExtension();\n\n  app.main();\n}\n"
  },
  {
    "path": "recipes/flutter_driver/how_do_i_run_a_flutter_driver_test/test_driver/example_test.dart",
    "content": "import 'package:flutter_driver/flutter_driver.dart';\nimport 'package:test/test.dart';\n\nvoid main() {\n  FlutterDriver driver;\n\n  setUpAll(() async {\n    driver = await FlutterDriver.connect();\n  });\n\n  tearDownAll(() async {\n    if (driver != null) {\n      await driver.close();\n    }\n  });\n\n  test(\"'Hello world' text exists\", () async {\n    SerializableFinder helloWorldTextFinder = find.text(\"Hello world\");\n\n    await driver.waitFor(helloWorldTextFinder);\n  });\n}\n"
  },
  {
    "path": "recipes/flutter_driver/how_do_i_run_a_script/.gitignore",
    "content": "# Miscellaneous\n*.class\n*.log\n*.pyc\n*.swp\n.DS_Store\n.atom/\n.buildlog/\n.history\n.svn/\n\n# IntelliJ related\n*.iml\n*.ipr\n*.iws\n.idea/\n\n# The .vscode folder contains launch configuration and tasks you configure in\n# VS Code which you may wish to be included in version control, so this line\n# is commented out by default.\n#.vscode/\n\n# Flutter/Dart/Pub related\n**/doc/api/\n.dart_tool/\n.flutter-plugins\n.flutter-plugins-dependencies\n.packages\n.pub-cache/\n.pub/\n/build/\n\n# Web related\nlib/generated_plugin_registrant.dart\n\n# Exceptions to above rules.\n!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages\n\n# Flutter Test Cookbook (Driver)\n.dart_tool/\n.metadata\n.packages\nandroid/\nios/\npubspec.lock\nftc.iml\n*.*~\ntest/"
  },
  {
    "path": "recipes/flutter_driver/how_do_i_run_a_script/README.md",
    "content": "# Question\n\nHow do I run a script inside of a test?\n\n# Answer\n\nUse [Process.run](https://api.dart.dev/stable/2.7.1/dart-io/Process/run.html)\n\n## 1) Create a flutter application.\n\n```sh\nflutter create ftc\ncd ftc\n```\n\n## 2) Add [flutter_driver](https://api.flutter.dev/flutter/flutter_driver/flutter_driver-library.html) and [test](https://pub.dev/packages/test) to your `pubspec.yaml` file.\n\n```yaml\ndev_dependencies:\n  flutter_driver:\n    sdk: flutter\n  test: any\n```\n\nThen get the dependencies by running:\n\n```sh\nflutter packages get\n```\n\n## 3) Replace the `lib/main.dart` file\n\nReplace the `lib/main.dart` file with the following:\n\n```dart\nimport 'package:flutter/material.dart';\n\nvoid main() => runApp(MyApp());\n\nclass MyApp extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      home: Scaffold(\n        body: Center(\n          child: Text(\"A script will be run during the test\"),\n        ),\n      ),\n    );\n  }\n}\n```\n\n## 4) Create a `test_driver` directory.\n\n```sh\nmkdir test_driver\ncd test_driver\n```\n\n## 5) Add an `example.dart` file.\n\nCreate a `test_driver/example.dart` file, and add the following to it:\n\n```dart\nimport 'package:flutter_driver/driver_extension.dart';\nimport 'package:ftc/main.dart' as app;\n\nvoid main() {\n  // Add the following to leverage flutter_driver\n  enableFlutterDriverExtension();\n\n  app.main();\n}\n```\n\n## 6) Add an `example_test.dart` file.\n\nCreate a `test_driver/example_test.dart` file, and add the following to it:\n\n```dart\nimport 'package:flutter_driver/flutter_driver.dart';\nimport 'package:test/test.dart';\nimport 'dart:io';\n\nvoid main() {\n  FlutterDriver driver;\n\n  setUpAll(() async {\n    driver = await FlutterDriver.connect();\n  });\n\n  tearDownAll(() async {\n    if (driver != null) {\n      await driver.close();\n    }\n  });\n\n  test(\"How do I run a script inside of a test?\", () async {\n    ProcessResult result = await Process.run('./echo.sh', ['1']);\n\n    // Note: echo appends a newline to the result\n    expect(result.stdout, '1\\n');\n  });\n}\n```\n\n## 7) Add an `echo.sh` script\n\nCreate a file called `echo.sh` and add the following to it:\n\n```sh\n#!/bin/bash\n\necho \"$1\"\n```\n\nThen run:\n\n```sh\nchmod +x echo.sh\n```\n\n## 8) Run the flutter driver tests\n\n```sh\nflutter driver -t test_driver/example.dart\n```\n\n# Run tests from example code in cookbook itself\n\nIf you have cloned [flutter_test_cookbook](https://github.com/gadfly361/flutter_test_cookbook/tree/master) and simply want to run the tests from this recipe, then:\n\n```sh\nflutter create .\nflutter packages get\nflutter driver -t test_driver/example.dart\n```\n\n# Outputs when recipe was made / updated\n\n## Output of running flutter driver tests\n\n```sh\n$ flutter driver -t test_driver/example.dart \nUsing device iPhone 8.\nStarting application: test_driver/example.dart\nRunning Xcode build...                                                  \n ├─Assembling Flutter resources...                            2.5s\n └─Compiling, linking and signing...                            ⣷^R                                                                    3.0s\nXcode build done.                                            6.7s\nflutter: Observatory listening on http://127.0.0.1:63926/-gi_tJzC8oY=/\n00:00 +0: (setUpAll)\n\n[info ] FlutterDriver: Connecting to Flutter application at http://127.0.0.1:63926/-gi_tJzC8oY=/\n[trace] FlutterDriver: Isolate found with number: 3688768521236175\n[trace] FlutterDriver: Isolate is paused at start.\n[trace] FlutterDriver: Attempting to resume isolate\n[trace] FlutterDriver: Waiting for service extension\n[info ] FlutterDriver: Connected to Flutter application.\n00:00 +0: How do I run a script inside of a test?\n\n00:00 +1: (tearDownAll)\n\n00:00 +1: All tests passed!\n```\n\n## Output of running `flutter doctor -v`\n\n```sh\n$ flutter doctor -v\n[✓] Flutter (Channel stable, v1.12.13+hotfix.5, on Mac OS X 10.15.2 19C57, locale en-US)\n    • Flutter version 1.12.13+hotfix.5 at /Users/matthew/gadfly/flutter_versions/flutter_1.12.13+hotfix.5\n    • Framework revision 27321ebbad (3 months ago), 2019-12-10 18:15:01 -0800\n    • Engine revision 2994f7e1e6\n    • Dart version 2.7.0\n\n[✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)\n    • Android SDK at /Users/matthew/Library/Android/sdk\n    • Android NDK location not configured (optional; useful for native profiling support)\n    • Platform android-29, build-tools 28.0.3\n    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java\n    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)\n    • All Android licenses accepted.\n\n[✓] Xcode - develop for iOS and macOS (Xcode 11.3.1)\n    • Xcode at /Applications/Xcode.app/Contents/Developer\n    • Xcode 11.3.1, Build version 11C504\n    • CocoaPods version 1.8.4\n\n[✓] Android Studio (version 3.4)\n    • Android Studio at /Applications/Android Studio.app/Contents\n    • Flutter plugin version 35.2.1\n    • Dart plugin version 183.6270\n    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)\n\n[✓] IntelliJ IDEA Community Edition (version 2019.3.3)\n    • IntelliJ at /Applications/IntelliJ IDEA CE.app\n    • Flutter plugin version 44.0.3\n    • Dart plugin version 193.6494.35\n\n[✓] VS Code (version 1.41.1)\n    • VS Code at /Applications/Visual Studio Code.app/Contents\n    • Flutter extension version 3.4.1\n\n[✓] Connected device (1 available)\n    • iPhone 8 • AD7A90EB-5E73-427E-B9B7-DD3B07E2FEF1 • ios • com.apple.CoreSimulator.SimRuntime.iOS-13-3 (simulator)\n\n• No issues found!\n```\n"
  },
  {
    "path": "recipes/flutter_driver/how_do_i_run_a_script/echo.sh",
    "content": "#!/bin/bash\n\necho \"$1\"\n"
  },
  {
    "path": "recipes/flutter_driver/how_do_i_run_a_script/lib/main.dart",
    "content": "import 'package:flutter/material.dart';\n\nvoid main() => runApp(MyApp());\n\nclass MyApp extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      home: Scaffold(\n        body: Center(\n          child: Text(\"A script will be run during the test\"),\n        ),\n      ),\n    );\n  }\n}\n"
  },
  {
    "path": "recipes/flutter_driver/how_do_i_run_a_script/pubspec.yaml",
    "content": "name: ftc\n\nversion: 1.0.0+1\n\nenvironment:\n  sdk: \">=2.1.0 <3.0.0\"\n\ndependencies:\n  flutter:\n    sdk: flutter\n\ndev_dependencies:\n  flutter_driver:\n    sdk: flutter\n  test: any\n"
  },
  {
    "path": "recipes/flutter_driver/how_do_i_run_a_script/test_driver/example.dart",
    "content": "import 'package:flutter_driver/driver_extension.dart';\nimport 'package:ftc/main.dart' as app;\n\nvoid main() {\n  // Add the following to leverage flutter_driver\n  enableFlutterDriverExtension();\n\n  app.main();\n}\n"
  },
  {
    "path": "recipes/flutter_driver/how_do_i_run_a_script/test_driver/example_test.dart",
    "content": "import 'package:flutter_driver/flutter_driver.dart';\nimport 'package:test/test.dart';\nimport 'dart:io';\n\nvoid main() {\n  FlutterDriver driver;\n\n  setUpAll(() async {\n    driver = await FlutterDriver.connect();\n  });\n\n  tearDownAll(() async {\n    if (driver != null) {\n      await driver.close();\n    }\n  });\n\n  test(\"How do I run a script inside of a test?\", () async {\n    ProcessResult result = await Process.run('./echo.sh', ['1']);\n\n    // Note: echo appends a newline to the result\n    expect(result.stdout, '1\\n');\n  });\n}\n"
  },
  {
    "path": "recipes/flutter_driver/how_do_i_run_multiple_test_files_without_restarting_app/.gitignore",
    "content": "# Miscellaneous\n*.class\n*.log\n*.pyc\n*.swp\n.DS_Store\n.atom/\n.buildlog/\n.history\n.svn/\n\n# IntelliJ related\n*.iml\n*.ipr\n*.iws\n.idea/\n\n# The .vscode folder contains launch configuration and tasks you configure in\n# VS Code which you may wish to be included in version control, so this line\n# is commented out by default.\n#.vscode/\n\n# Flutter/Dart/Pub related\n**/doc/api/\n.dart_tool/\n.flutter-plugins\n.flutter-plugins-dependencies\n.packages\n.pub-cache/\n.pub/\n/build/\n\n# Web related\nlib/generated_plugin_registrant.dart\n\n# Exceptions to above rules.\n!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages\n\n# Flutter Test Cookbook (Driver)\n.dart_tool/\n.metadata\n.packages\nandroid/\nios/\npubspec.lock\nftc.iml\n*.*~\ntest/"
  },
  {
    "path": "recipes/flutter_driver/how_do_i_run_multiple_test_files_without_restarting_app/README.md",
    "content": "# Question\n\nHow do I run multiple test files without restarting the app?\n\n# Answer\n\nWe are going to start an app, record its uri, then run our test suites referencing an existing app at the uri.     \n\n## 1) Create a flutter application.\n\n```sh\nflutter create ftc\ncd ftc\n```\n\n## 2) Add [flutter_driver](https://api.flutter.dev/flutter/flutter_driver/flutter_driver-library.html) and [test](https://pub.dev/packages/test) to your `pubspec.yaml` file.\n\n```yaml\ndev_dependencies:\n  flutter_driver:\n    sdk: flutter\n  test: any\n```\n\nThen get the dependencies by running:\n\n```sh\nflutter packages get\n```\n\n## 3) Replace the `lib/main.dart` file\n\nReplace the `lib/main.dart` file with the following:\n\n```dart\nimport 'package:flutter/material.dart';\n\nvoid main() => runApp(MyApp());\n\nclass MyApp extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      home: Scaffold(\n        body: Column(children: [\n          Text(\"Suite 1 will check this\"),\n          Text(\"Suite 2 will check this\"),\n        ]),\n      ),\n    );\n  }\n}\n```\n\n## 4) Create a `test_driver` directory.\n\n```sh\nmkdir test_driver\ncd test_driver\n```\n\n## 5) Add a `start_app.dart` file.\n\nCreate a `test_driver/start_app.dart` file, and add the following to it:\n\n```dart\nimport 'package:flutter_driver/driver_extension.dart';\nimport 'package:ftc/main.dart' as app;\n\nvoid main() {\n  enableFlutterDriverExtension();\n\n  app.main();\n}\n```\n\n## 6) Add a `suite1.dart` file and a `suite1_test.dart` file\n\nCreate a `test_driver/suite1.dart` file, and add the following to it:\n\n```dart\n// Note: this is intentionally blank,\n// but the existence of this file is still needed\n// for flutter drive to run the tests\n```\n\nThen create a `test_driver/suite1_test.dart` file, and add the following to it:\n\n```dart\nimport 'package:flutter_driver/flutter_driver.dart';\nimport 'package:test/test.dart';\n\nvoid main() {\n  FlutterDriver driver;\n\n  setUpAll(() async {\n    driver = await FlutterDriver.connect();\n  });\n\n  tearDownAll(() async {\n    if (driver != null) {\n      await driver.close();\n    }\n  });\n\n  test(\"Suite 1\", () async {\n    SerializableFinder textFinder = find.text(\"Suite 1 will check this\");\n\n    await driver.waitFor(textFinder);\n  });\n}\n```\n\n## 7) Add a `suite2.dart` file and a `suite2_test.dart` file\n\nCreate a `test_driver/suite2.dart` file, and add the following to it:\n\n```dart\n// Note: this is intentionally blank,\n// but the existence of this file is still needed\n// for flutter drive to run the tests\n```\n\nThen create a `test_driver/suite2_test.dart` file, and add the following to it:\n\n```dart\nimport 'package:flutter_driver/flutter_driver.dart';\nimport 'package:test/test.dart';\n\nvoid main() {\n  FlutterDriver driver;\n\n  setUpAll(() async {\n    driver = await FlutterDriver.connect();\n  });\n\n  tearDownAll(() async {\n    if (driver != null) {\n      await driver.close();\n    }\n  });\n\n  test(\"Suite 2\", () async {\n    SerializableFinder textFinder = find.text(\"Suite 2 will check this\");\n\n    await driver.waitFor(textFinder);\n  });\n}\n```\n\n## 8) Add a `run_all_tests.sh` file\n\nCreate a `run_all_tests.sh` file and add the following to it:\n\n```sh\n#!/bin/bash\n\n# start the app and write the uri to a file\nflutter run --target=test_driver/start_app.dart --vmservice-out-file=\"test_driver/uri.txt\" --start-paused --no-resident\n\n# run the test suites using the uri in the aforementioned file\nflutter driver --target=test_driver/suite1.dart --use-existing-app=\"$(cat test_driver/uri.txt)\"\nflutter driver --target=test_driver/suite2.dart --use-existing-app=\"$(cat test_driver/uri.txt)\"\n```\n\nThen make it executable by running\n\n```sh\nchmod +x run_all_tests.sh\n```\n\n## 8) Run the flutter driver tests\n\n```sh\n./run_all_tests.sh\n```\n\n# Run tests from example code in cookbook itself\n\nIf you have cloned [flutter_test_cookbook](https://github.com/gadfly361/flutter_test_cookbook/tree/master) and simply want to run the tests from this recipe, then:\n\n```sh\nflutter create .\nflutter packages get\n./run_all_tests.sh\n```\n\n# Outputs when recipe was made / updated\n\n## Output of running flutter driver tests\n\n```sh\n$ ./run_all_tests.sh \nLaunching test_driver/start_app.dart on iPhone 8 in debug mode...\nRunning Xcode build...                                                  \n ├─Assembling Flutter resources...                           2.6s\n └─Compiling, linking and signing...                         2.9s\nXcode build done.                                            6.7s\nSyncing files to device iPhone 8...                                     \n 4,776ms (!)                                       \nUsing device iPhone 8.\nWill connect to already running application instance.\n00:00 +0: (setUpAll)\n\n[info ] FlutterDriver: Connecting to Flutter application at ws://127.0.0.1:56503/87Z5gLVG5E8=/ws\n[trace] FlutterDriver: Isolate found with number: 1576235581101003\n[trace] FlutterDriver: Isolate is paused at start.\n[trace] FlutterDriver: Attempting to resume isolate\n[trace] FlutterDriver: Waiting for service extension\n[info ] FlutterDriver: Connected to Flutter application.\n00:00 +0: Suite 1\n\n00:00 +1: (tearDownAll)\n\n00:00 +1: All tests passed!\n\nLeaving the application running.\nUsing device iPhone 8.\nWill connect to already running application instance.\n00:00 +0: (setUpAll)\n\n[info ] FlutterDriver: Connecting to Flutter application at ws://127.0.0.1:56503/87Z5gLVG5E8=/ws\n[trace] FlutterDriver: Isolate found with number: 1576235581101003\n[trace] FlutterDriver: Isolate is not paused. Assuming application is ready.\n[info ] FlutterDriver: Connected to Flutter application.\n00:00 +0: Suite 2\n\n00:00 +1: (tearDownAll)\n\n00:00 +1: All tests passed!\n\nLeaving the application running.\n```\n\n## Output of running `flutter doctor -v`\n\n```sh\n$ flutter doctor -v\n[✓] Flutter (Channel stable, v1.12.13+hotfix.5, on Mac OS X 10.15.2 19C57, locale en-US)\n    • Flutter version 1.12.13+hotfix.5 at /Users/matthew/gadfly/flutter_versions/flutter_1.12.13+hotfix.5\n    • Framework revision 27321ebbad (3 months ago), 2019-12-10 18:15:01 -0800\n    • Engine revision 2994f7e1e6\n    • Dart version 2.7.0\n\n[✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)\n    • Android SDK at /Users/matthew/Library/Android/sdk\n    • Android NDK location not configured (optional; useful for native profiling support)\n    • Platform android-29, build-tools 28.0.3\n    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java\n    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)\n    • All Android licenses accepted.\n\n[✓] Xcode - develop for iOS and macOS (Xcode 11.3.1)\n    • Xcode at /Applications/Xcode.app/Contents/Developer\n    • Xcode 11.3.1, Build version 11C504\n    • CocoaPods version 1.8.4\n\n[✓] Android Studio (version 3.4)\n    • Android Studio at /Applications/Android Studio.app/Contents\n    • Flutter plugin version 35.2.1\n    • Dart plugin version 183.6270\n    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)\n\n[✓] IntelliJ IDEA Community Edition (version 2019.3.3)\n    • IntelliJ at /Applications/IntelliJ IDEA CE.app\n    • Flutter plugin version 44.0.3\n    • Dart plugin version 193.6494.35\n\n[✓] VS Code (version 1.41.1)\n    • VS Code at /Applications/Visual Studio Code.app/Contents\n    • Flutter extension version 3.4.1\n\n[✓] Connected device (1 available)\n    • iPhone 8 • AD7A90EB-5E73-427E-B9B7-DD3B07E2FEF1 • ios • com.apple.CoreSimulator.SimRuntime.iOS-13-3 (simulator)\n\n• No issues found!\n```\n"
  },
  {
    "path": "recipes/flutter_driver/how_do_i_run_multiple_test_files_without_restarting_app/lib/main.dart",
    "content": "import 'package:flutter/material.dart';\n\nvoid main() => runApp(MyApp());\n\nclass MyApp extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      home: Scaffold(\n        body: Column(children: [\n          Text(\"Suite 1 will check this\"),\n          Text(\"Suite 2 will check this\"),\n        ]),\n      ),\n    );\n  }\n}\n"
  },
  {
    "path": "recipes/flutter_driver/how_do_i_run_multiple_test_files_without_restarting_app/pubspec.yaml",
    "content": "name: ftc\n\nversion: 1.0.0+1\n\nenvironment:\n  sdk: \">=2.1.0 <3.0.0\"\n\ndependencies:\n  flutter:\n    sdk: flutter\n\ndev_dependencies:\n  flutter_driver:\n    sdk: flutter\n  test: any\n"
  },
  {
    "path": "recipes/flutter_driver/how_do_i_run_multiple_test_files_without_restarting_app/run_all_tests.sh",
    "content": "#!/bin/bash\n\n# start the app and write the uri to a file\nflutter run --target=test_driver/start_app.dart --vmservice-out-file=\"test_driver/uri.txt\" --start-paused --no-resident\n\n# run the test suites using the uri in the aforementioned file\nflutter driver --target=test_driver/suite1.dart --use-existing-app=\"$(cat test_driver/uri.txt)\"\nflutter driver --target=test_driver/suite2.dart --use-existing-app=\"$(cat test_driver/uri.txt)\""
  },
  {
    "path": "recipes/flutter_driver/how_do_i_run_multiple_test_files_without_restarting_app/test_driver/start_app.dart",
    "content": "import 'package:flutter_driver/driver_extension.dart';\nimport 'package:ftc/main.dart' as app;\n\nvoid main() {\n  // Add the following to leverage flutter_driver\n  enableFlutterDriverExtension();\n\n  app.main();\n}\n"
  },
  {
    "path": "recipes/flutter_driver/how_do_i_run_multiple_test_files_without_restarting_app/test_driver/suite1.dart",
    "content": "// Note: this is intentionally blank,\n// but the existence of this file is still needed\n// for flutter drive to run the tests\n"
  },
  {
    "path": "recipes/flutter_driver/how_do_i_run_multiple_test_files_without_restarting_app/test_driver/suite1_test.dart",
    "content": "import 'package:flutter_driver/flutter_driver.dart';\nimport 'package:test/test.dart';\n\nvoid main() {\n  FlutterDriver driver;\n\n  setUpAll(() async {\n    driver = await FlutterDriver.connect();\n  });\n\n  tearDownAll(() async {\n    if (driver != null) {\n      await driver.close();\n    }\n  });\n\n  test(\"Suite 1\", () async {\n    SerializableFinder textFinder = find.text(\"Suite 1 will check this\");\n\n    await driver.waitFor(textFinder);\n  });\n}\n"
  },
  {
    "path": "recipes/flutter_driver/how_do_i_run_multiple_test_files_without_restarting_app/test_driver/suite2.dart",
    "content": "// Note: this is intentionally blank,\n// but the existence of this file is still needed\n// for flutter drive to run the tests\n"
  },
  {
    "path": "recipes/flutter_driver/how_do_i_run_multiple_test_files_without_restarting_app/test_driver/suite2_test.dart",
    "content": "import 'package:flutter_driver/flutter_driver.dart';\nimport 'package:test/test.dart';\n\nvoid main() {\n  FlutterDriver driver;\n\n  setUpAll(() async {\n    driver = await FlutterDriver.connect();\n  });\n\n  tearDownAll(() async {\n    if (driver != null) {\n      await driver.close();\n    }\n  });\n\n  test(\"Suite 2\", () async {\n    SerializableFinder textFinder = find.text(\"Suite 2 will check this\");\n\n    await driver.waitFor(textFinder);\n  });\n}\n"
  },
  {
    "path": "recipes/flutter_driver/how_do_i_take_a_screenshot/.gitignore",
    "content": "# Miscellaneous\n*.class\n*.log\n*.pyc\n*.swp\n.DS_Store\n.atom/\n.buildlog/\n.history\n.svn/\n\n# IntelliJ related\n*.iml\n*.ipr\n*.iws\n.idea/\n\n# The .vscode folder contains launch configuration and tasks you configure in\n# VS Code which you may wish to be included in version control, so this line\n# is commented out by default.\n#.vscode/\n\n# Flutter/Dart/Pub related\n**/doc/api/\n.dart_tool/\n.flutter-plugins\n.flutter-plugins-dependencies\n.packages\n.pub-cache/\n.pub/\n/build/\n\n# Web related\nlib/generated_plugin_registrant.dart\n\n# Exceptions to above rules.\n!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages\n\n# Flutter Test Cookbook (Driver)\n.dart_tool/\n.metadata\n.packages\nandroid/\nios/\npubspec.lock\nftc.iml\n*.*~\ntest/"
  },
  {
    "path": "recipes/flutter_driver/how_do_i_take_a_screenshot/README.md",
    "content": "# Question\n\nHow do I take a screenshot?\n\n# Answer\n\n## 1) Create a flutter application.\n\n```sh\nflutter create ftc\ncd ftc\n```\n\n## 2) Add [flutter_driver](https://api.flutter.dev/flutter/flutter_driver/flutter_driver-library.html) and [test](https://pub.dev/packages/test) to your `pubspec.yaml` file.\n\n```yaml\ndev_dependencies:\n  flutter_driver:\n    sdk: flutter\n  test: any\n```\n\nThen get the dependencies by running:\n\n```sh\nflutter packages get\n```\n\n## 3) Replace the `lib/main.dart` file\n\nReplace the `lib/main.dart` file with the following:\n\n```dart\nimport 'package:flutter/material.dart';\n\nvoid main() => runApp(MyApp());\n\nclass MyApp extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      home: Scaffold(\n        body: Center(\n          child: Text(\"Take a screenshot of me\"),\n        ),\n      ),\n    );\n  }\n}\n```\n\n## 4) Create a `test_driver` directory.\n\n```sh\nmkdir test_driver\ncd test_driver\n```\n\n## 5) Add an `example.dart` file.\n\nCreate a `test_driver/example.dart` file, and add the following to it:\n\n```dart\nimport 'package:flutter_driver/driver_extension.dart';\nimport 'package:ftc/main.dart' as app;\n\nvoid main() {\n  // Add the following to leverage flutter_driver\n  enableFlutterDriverExtension();\n\n  app.main();\n}\n```\n\n## 6) Add an `example_test.dart` file.\n\nCreate a `test_driver/example_test.dart` file, and add the following to it:\n\n```dart\nimport 'package:flutter_driver/flutter_driver.dart';\nimport 'package:test/test.dart';\nimport 'dart:io' show File;\n\nvoid main() {\n  FlutterDriver driver;\n\n  setUpAll(() async {\n    driver = await FlutterDriver.connect();\n  });\n\n  tearDownAll(() async {\n    if (driver != null) {\n      await driver.close();\n    }\n  });\n\n  test(\"How do I take a screenshot?\", () async {\n    // It is good practice to call this before taking a screenshot\n    // to ensure everything has settled\n    await driver.waitUntilNoTransientCallbacks();\n\n    // Take the screenshot and store as a list of ints\n    // Note: the image will be returned as a PNG\n    final List<int> screenshotPixels = await driver.screenshot();\n\n    // Write to a file\n    final File screenshotFile = new File(\"my_screenshot.png\");\n    await screenshotFile.writeAsBytes(screenshotPixels);\n  });\n}\n```\n\n## 7) Run the flutter driver tests\n\n```sh\nflutter driver -t test_driver/example.dart\n```\n\n# Run tests from example code in cookbook itself\n\nIf you have cloned [flutter_test_cookbook](https://github.com/gadfly361/flutter_test_cookbook/tree/master) and simply want to run the tests from this recipe, then:\n\n```sh\nflutter create .\nflutter packages get\nflutter driver -t test_driver/example.dart\n```\n\n# Outputs when recipe was made / updated\n\n## Output of running flutter driver tests\n\n```sh\n$ flutter driver -t test_driver/example.dart \nUsing device iPhone 8.\nStarting application: test_driver/example.dart\nRunning Xcode build...                                                  \n ├─Assembling Flutter resources...                           2.5s\n └─Compiling, linking and signing...                         2.8s\nXcode build done.                                            6.5s\nflutter: Observatory listening on http://127.0.0.1:57202/-lHi4AILSr8=/\n00:00 +0: (setUpAll)\n\n[info ] FlutterDriver: Connecting to Flutter application at http://127.0.0.1:57202/-lHi4AILSr8=/\n[trace] FlutterDriver: Isolate found with number: 2332930742028219\n[trace] FlutterDriver: Isolate is paused at start.\n[trace] FlutterDriver: Attempting to resume isolate\n[trace] FlutterDriver: Waiting for service extension\n[info ] FlutterDriver: Connected to Flutter application.\n00:00 +0: How do I take a screenshot?\n\n00:02 +1: (tearDownAll)\n\n00:02 +1: All tests passed!\n\nStopping application instance.\n```\n\n## Output of running `flutter doctor -v`\n\n```sh\n$ flutter doctor -v\n[✓] Flutter (Channel stable, v1.12.13+hotfix.5, on Mac OS X 10.15.2 19C57, locale en-US)\n    • Flutter version 1.12.13+hotfix.5 at /Users/matthew/gadfly/flutter_versions/flutter_1.12.13+hotfix.5\n    • Framework revision 27321ebbad (3 months ago), 2019-12-10 18:15:01 -0800\n    • Engine revision 2994f7e1e6\n    • Dart version 2.7.0\n\n[✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)\n    • Android SDK at /Users/matthew/Library/Android/sdk\n    • Android NDK location not configured (optional; useful for native profiling support)\n    • Platform android-29, build-tools 28.0.3\n    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java\n    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)\n    • All Android licenses accepted.\n\n[✓] Xcode - develop for iOS and macOS (Xcode 11.3.1)\n    • Xcode at /Applications/Xcode.app/Contents/Developer\n    • Xcode 11.3.1, Build version 11C504\n    • CocoaPods version 1.8.4\n\n[✓] Android Studio (version 3.4)\n    • Android Studio at /Applications/Android Studio.app/Contents\n    • Flutter plugin version 35.2.1\n    • Dart plugin version 183.6270\n    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)\n\n[✓] IntelliJ IDEA Community Edition (version 2019.3.3)\n    • IntelliJ at /Applications/IntelliJ IDEA CE.app\n    • Flutter plugin version 44.0.3\n    • Dart plugin version 193.6494.35\n\n[✓] VS Code (version 1.41.1)\n    • VS Code at /Applications/Visual Studio Code.app/Contents\n    • Flutter extension version 3.4.1\n\n[✓] Connected device (1 available)\n    • iPhone 8 • AD7A90EB-5E73-427E-B9B7-DD3B07E2FEF1 • ios • com.apple.CoreSimulator.SimRuntime.iOS-13-3 (simulator)\n\n• No issues found!\n```\n"
  },
  {
    "path": "recipes/flutter_driver/how_do_i_take_a_screenshot/lib/main.dart",
    "content": "import 'package:flutter/material.dart';\n\nvoid main() => runApp(MyApp());\n\nclass MyApp extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      home: Scaffold(\n        body: Center(\n          child: Text(\"Take a screenshot of me\"),\n        ),\n      ),\n    );\n  }\n}\n"
  },
  {
    "path": "recipes/flutter_driver/how_do_i_take_a_screenshot/pubspec.yaml",
    "content": "name: ftc\n\nversion: 1.0.0+1\n\nenvironment:\n  sdk: \">=2.1.0 <3.0.0\"\n\ndependencies:\n  flutter:\n    sdk: flutter\n\ndev_dependencies:\n  flutter_driver:\n    sdk: flutter\n  test: any\n"
  },
  {
    "path": "recipes/flutter_driver/how_do_i_take_a_screenshot/test_driver/example.dart",
    "content": "import 'package:flutter_driver/driver_extension.dart';\nimport 'package:ftc/main.dart' as app;\n\nvoid main() {\n  // Add the following to leverage flutter_driver\n  enableFlutterDriverExtension();\n\n  app.main();\n}\n"
  },
  {
    "path": "recipes/flutter_driver/how_do_i_take_a_screenshot/test_driver/example_test.dart",
    "content": "import 'package:flutter_driver/flutter_driver.dart';\nimport 'package:test/test.dart';\nimport 'dart:io' show File;\n\nvoid main() {\n  FlutterDriver driver;\n\n  setUpAll(() async {\n    driver = await FlutterDriver.connect();\n  });\n\n  tearDownAll(() async {\n    if (driver != null) {\n      await driver.close();\n    }\n  });\n\n  test(\"How do I take a screenshot?\", () async {\n    // It is good practice to call this before taking a screenshot\n    // to ensure everything has settled\n    await driver.waitUntilNoTransientCallbacks();\n\n    // Take the screenshot and store as a list of ints\n    // Note: the image will be returned as a PNG\n    final List<int> screenshotPixels = await driver.screenshot();\n\n    // Write to a file\n    final File screenshotFile = new File(\"my_screenshot.png\");\n    await screenshotFile.writeAsBytes(screenshotPixels);\n  });\n}\n"
  },
  {
    "path": "recipes/flutter_test/how_do_i_drag_something/.gitignore",
    "content": "# Miscellaneous\n*.class\n*.log\n*.pyc\n*.swp\n.DS_Store\n.atom/\n.buildlog/\n.history\n.svn/\n\n# IntelliJ related\n*.iml\n*.ipr\n*.iws\n.idea/\n\n# The .vscode folder contains launch configuration and tasks you configure in\n# VS Code which you may wish to be included in version control, so this line\n# is commented out by default.\n#.vscode/\n\n# Flutter/Dart/Pub related\n**/doc/api/\n.dart_tool/\n.flutter-plugins\n.flutter-plugins-dependencies\n.packages\n.pub-cache/\n.pub/\n/build/\n\n# Web related\nlib/generated_plugin_registrant.dart\n\n# Exceptions to above rules.\n!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages\n\n# Flutter Test Cookbook (flutter_test)\n.dart_tool/\n.metadata\n.packages\nandroid/\nios/\npubspec.lock\nftc.iml\n*.*~\ntest_driver/"
  },
  {
    "path": "recipes/flutter_test/how_do_i_drag_something/README.md",
    "content": "# Question\n\nHow do I drag something?\n\n# Answer\n\n## 1) Create a flutter application.\n\n```sh\nflutter create ftc\ncd ftc\n```\n\n## 2) Get dependencies\n\n```sh\nflutter packages get\n```\n\n## 3) Replace the `lib/main.dart` file\n\nReplace the `lib/main.dart` file with the following:\n\n```dart\nimport 'package:flutter/material.dart';\n\nvoid main() => runApp(MyApp());\n\nclass MyApp extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      home: Scaffold(\n        appBar: AppBar(),\n        body: Body(),\n      ),\n    );\n  }\n}\n\nclass Body extends StatefulWidget {\n  @override\n  _BodyState createState() => _BodyState();\n}\n\nclass _BodyState extends State<Body> {\n  bool isDragAccepted = false;\n\n  @override\n  Widget build(BuildContext context) {\n    return Column(\n      children: <Widget>[\n        Draggable(\n          feedback: Container(\n            height: 100,\n            width: 100,\n            decoration: BoxDecoration(\n              border: Border.all(width: 2.0, color: Colors.black),\n            ),\n          ),\n          child: Container(\n            height: 100,\n            width: 100,\n            decoration: BoxDecoration(\n              border: Border.all(width: 2.0, color: Colors.black),\n            ),\n            child: Center(\n              child: Text(\"Draggable\"),\n            ),\n          ),\n          childWhenDragging: Container(\n            height: 100,\n            width: 100,\n            decoration: BoxDecoration(\n              border: Border.all(width: 2.0, color: Colors.grey),\n            ),\n          ),\n        ),\n        DragTarget(\n          onAccept: (data) {\n            setState(() {\n              isDragAccepted = true;\n            });\n          },\n          builder: (BuildContext context, candidateData, rejectedData) {\n            return Container(\n              height: 100,\n              width: 100,\n              decoration: BoxDecoration(\n                border: Border.all(\n                    width: 2.0,\n                    color: isDragAccepted ? Colors.green : Colors.black),\n              ),\n              child: Center(\n                child:\n                    Text(isDragAccepted ? \"Successful drag!\" : \"Drag Target\"),\n              ),\n            );\n          },\n        ),\n      ],\n    );\n  }\n}\n```\n\n## 4) Replace the `test/widget_test.dart` file.\n\nReplace the `test/widget_test.dart` file with the following:\n\n```dart\nimport 'package:flutter_test/flutter_test.dart';\nimport 'package:ftc/main.dart';\n\nvoid main() {\n  testWidgets(\"How do I drag something?\", (WidgetTester tester) async {\n    await tester.pumpWidget(MyApp());\n\n    Finder draggableFinder = find.text(\"Draggable\");\n    Finder dragTargetFinder = find.text(\"Drag Target\");\n\n    expect(draggableFinder, findsOneWidget);\n    expect(dragTargetFinder, findsOneWidget);\n\n    await tester.drag(draggableFinder, Offset(0, 100));\n    await tester.pump();\n\n    expect(dragTargetFinder, findsNothing);\n\n    Finder successfulDragFinder = find.text(\"Successful drag!\");\n    expect(successfulDragFinder, findsOneWidget);\n  });\n}\n```\n\n\n## 5) Run the flutter tests\n\n```sh\nflutter test\n```\n\n# Run tests from example code in cookbook itself\n\nIf you have cloned [flutter_test_cookbook](https://github.com/gadfly361/flutter_test_cookbook/tree/master) and simply want to run the tests from this recipe, then:\n\n```sh\nflutter create .\nflutter packages get\nflutter test\n```\n\n# Outputs when recipe was made / updated\n\n## Output of running flutter tests\n\n```sh\n$ flutter test \n00:02 +1: All tests passed!\n```\n\n## Output of running `flutter doctor -v`\n\n```sh\n$ flutter doctor -v\n[✓] Flutter (Channel stable, v1.12.13+hotfix.5, on Mac OS X 10.15.2 19C57, locale en-US)\n    • Flutter version 1.12.13+hotfix.5 at /Users/matthew/gadfly/flutter_versions/flutter_1.12.13+hotfix.5\n    • Framework revision 27321ebbad (3 months ago), 2019-12-10 18:15:01 -0800\n    • Engine revision 2994f7e1e6\n    • Dart version 2.7.0\n\n[✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)\n    • Android SDK at /Users/matthew/Library/Android/sdk\n    • Android NDK location not configured (optional; useful for native profiling support)\n    • Platform android-29, build-tools 28.0.3\n    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java\n    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)\n    • All Android licenses accepted.\n\n[✓] Xcode - develop for iOS and macOS (Xcode 11.3.1)\n    • Xcode at /Applications/Xcode.app/Contents/Developer\n    • Xcode 11.3.1, Build version 11C504\n    • CocoaPods version 1.8.4\n\n[✓] Android Studio (version 3.4)\n    • Android Studio at /Applications/Android Studio.app/Contents\n    • Flutter plugin version 35.2.1\n    • Dart plugin version 183.6270\n    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)\n\n[✓] IntelliJ IDEA Community Edition (version 2019.3.3)\n    • IntelliJ at /Applications/IntelliJ IDEA CE.app\n    • Flutter plugin version 44.0.3\n    • Dart plugin version 193.6494.35\n\n[✓] VS Code (version 1.41.1)\n    • VS Code at /Applications/Visual Studio Code.app/Contents\n    • Flutter extension version 3.4.1\n\n[!] Connected device\n    • Device 9C251FFBA00174 is not authorized.\n      You might need to check your device for an authorization dialog.\n\n! Doctor found issues in 1 category.\n```\n"
  },
  {
    "path": "recipes/flutter_test/how_do_i_drag_something/lib/main.dart",
    "content": "import 'package:flutter/material.dart';\n\nvoid main() => runApp(MyApp());\n\nclass MyApp extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      home: Scaffold(\n        appBar: AppBar(),\n        body: Body(),\n      ),\n    );\n  }\n}\n\nclass Body extends StatefulWidget {\n  @override\n  _BodyState createState() => _BodyState();\n}\n\nclass _BodyState extends State<Body> {\n  bool isDragAccepted = false;\n\n  @override\n  Widget build(BuildContext context) {\n    return Column(\n      children: <Widget>[\n        Draggable(\n          feedback: Container(\n            height: 100,\n            width: 100,\n            decoration: BoxDecoration(\n              border: Border.all(width: 2.0, color: Colors.black),\n            ),\n          ),\n          child: Container(\n            height: 100,\n            width: 100,\n            decoration: BoxDecoration(\n              border: Border.all(width: 2.0, color: Colors.black),\n            ),\n            child: Center(\n              child: Text(\"Draggable\"),\n            ),\n          ),\n          childWhenDragging: Container(\n            height: 100,\n            width: 100,\n            decoration: BoxDecoration(\n              border: Border.all(width: 2.0, color: Colors.grey),\n            ),\n          ),\n        ),\n        DragTarget(\n          onAccept: (data) {\n            setState(() {\n              isDragAccepted = true;\n            });\n          },\n          builder: (BuildContext context, candidateData, rejectedData) {\n            return Container(\n              height: 100,\n              width: 100,\n              decoration: BoxDecoration(\n                border: Border.all(\n                    width: 2.0,\n                    color: isDragAccepted ? Colors.green : Colors.black),\n              ),\n              child: Center(\n                child:\n                    Text(isDragAccepted ? \"Successful drag!\" : \"Drag Target\"),\n              ),\n            );\n          },\n        ),\n      ],\n    );\n  }\n}\n"
  },
  {
    "path": "recipes/flutter_test/how_do_i_drag_something/pubspec.yaml",
    "content": "name: ftc\ndescription: A new Flutter project.\n\nversion: 1.0.0+1\n\nenvironment:\n  sdk: \">=2.1.0 <3.0.0\"\n\ndependencies:\n  flutter:\n    sdk: flutter\n\ndev_dependencies:\n  flutter_test:\n    sdk: flutter\n"
  },
  {
    "path": "recipes/flutter_test/how_do_i_drag_something/test/widget_test.dart",
    "content": "import 'package:flutter_test/flutter_test.dart';\nimport 'package:ftc/main.dart';\n\nvoid main() {\n  testWidgets(\"How do I drag something?\", (WidgetTester tester) async {\n    await tester.pumpWidget(MyApp());\n\n    Finder draggableFinder = find.text(\"Draggable\");\n    Finder dragTargetFinder = find.text(\"Drag Target\");\n\n    expect(draggableFinder, findsOneWidget);\n    expect(dragTargetFinder, findsOneWidget);\n\n    await tester.drag(draggableFinder, Offset(0, 100));\n    await tester.pump();\n\n    expect(dragTargetFinder, findsNothing);\n\n    Finder successfulDragFinder = find.text(\"Successful drag!\");\n    expect(successfulDragFinder, findsOneWidget);\n  });\n}\n"
  },
  {
    "path": "recipes/flutter_test/how_do_i_find_something/.gitignore",
    "content": "# Miscellaneous\n*.class\n*.log\n*.pyc\n*.swp\n.DS_Store\n.atom/\n.buildlog/\n.history\n.svn/\n\n# IntelliJ related\n*.iml\n*.ipr\n*.iws\n.idea/\n\n# The .vscode folder contains launch configuration and tasks you configure in\n# VS Code which you may wish to be included in version control, so this line\n# is commented out by default.\n#.vscode/\n\n# Flutter/Dart/Pub related\n**/doc/api/\n.dart_tool/\n.flutter-plugins\n.flutter-plugins-dependencies\n.packages\n.pub-cache/\n.pub/\n/build/\n\n# Web related\nlib/generated_plugin_registrant.dart\n\n# Exceptions to above rules.\n!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages\n\n# Flutter Test Cookbook (flutter_test)\n.dart_tool/\n.metadata\n.packages\nandroid/\nios/\npubspec.lock\nftc.iml\n*.*~\ntest_driver/"
  },
  {
    "path": "recipes/flutter_test/how_do_i_find_something/README.md",
    "content": "# Question\n\nHow do I find something ... whether it be a widget, some text, etc?\n\n# Answer\n\n## 1) Create a flutter application.\n\n```sh\nflutter create ftc\ncd ftc\n```\n\n## 2) Get dependencies\n\n```sh\nflutter packages get\n```\n\n## 3) Replace the `lib/main.dart` file\n\nReplace the `lib/main.dart` file with the following:\n\n```dart\nimport 'package:flutter/material.dart';\n\nvoid main() => runApp(MyApp());\n\nclass MyApp extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      home: Scaffold(\n        body: Column(\n          children: <Widget>[\n            RaisedButton(\n              onPressed: () => print(\"rasied button was clicked\"),\n              child: Text(\"we will find this by searching for a type\"),\n            ),\n            Text(\n              \"we will find this by searching for text\",\n            ),\n            Text(\n              \"will will find this by searching for a key\",\n              key: Key(\"mykey\"),\n            ),\n          ],\n        ),\n      ),\n    );\n  }\n}\n```\n\n## 4) Replace the `test/widget_test.dart` file.\n\nReplace the `test/widget_test.dart` file with the following:\n\n```dart\nimport 'package:flutter/material.dart';\nimport 'package:flutter_test/flutter_test.dart';\n\nimport 'package:ftc/main.dart';\n\nvoid main() {\n  testWidgets('how do i find something?', (WidgetTester tester) async {\n    await tester.pumpWidget(MyApp());\n\n    // Let's find a widget by its type\n    Finder raisedButtonFinder = find.byType(RaisedButton);\n    expect(raisedButtonFinder, findsOneWidget);\n\n    // Let's find a specific string of text\n    Finder textFinder = find.text(\"we will find this by searching for text\");\n    expect(textFinder, findsOneWidget);\n\n    // Let's find a widget by its key\n    Finder keyFinder = find.byKey(Key(\"mykey\"));\n    expect(keyFinder, findsOneWidget);\n  });\n}\n```\n\n\n## 5) Run the flutter tests\n\n```sh\nflutter test\n```\n\n# Run tests from example code in cookbook itself\n\nIf you have cloned [flutter_test_cookbook](https://github.com/gadfly361/flutter_test_cookbook/tree/master) and simply want to run the tests from this recipe, then:\n\n```sh\nflutter create .\nflutter packages get\nflutter test\n```\n\n# Outputs when recipe was made / updated\n\n## Output of running flutter tests\n\n```sh\n$ flutter test \n00:01 +1: All tests passed!\n```\n\n## Output of running `flutter doctor -v`\n\n```sh\n$ flutter doctor -v\n[✓] Flutter (Channel stable, v1.12.13+hotfix.5, on Mac OS X 10.15.2 19C57, locale en-US)\n    • Flutter version 1.12.13+hotfix.5 at /Users/matthew/gadfly/flutter_versions/flutter_1.12.13+hotfix.5\n    • Framework revision 27321ebbad (3 months ago), 2019-12-10 18:15:01 -0800\n    • Engine revision 2994f7e1e6\n    • Dart version 2.7.0\n\n[✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)\n    • Android SDK at /Users/matthew/Library/Android/sdk\n    • Android NDK location not configured (optional; useful for native profiling support)\n    • Platform android-29, build-tools 28.0.3\n    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java\n    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)\n    • All Android licenses accepted.\n\n[✓] Xcode - develop for iOS and macOS (Xcode 11.3.1)\n    • Xcode at /Applications/Xcode.app/Contents/Developer\n    • Xcode 11.3.1, Build version 11C504\n    • CocoaPods version 1.8.4\n\n[✓] Android Studio (version 3.4)\n    • Android Studio at /Applications/Android Studio.app/Contents\n    • Flutter plugin version 35.2.1\n    • Dart plugin version 183.6270\n    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)\n\n[✓] IntelliJ IDEA Community Edition (version 2019.3.3)\n    • IntelliJ at /Applications/IntelliJ IDEA CE.app\n    • Flutter plugin version 44.0.3\n    • Dart plugin version 193.6494.35\n\n[✓] VS Code (version 1.41.1)\n    • VS Code at /Applications/Visual Studio Code.app/Contents\n    • Flutter extension version 3.4.1\n\n[!] Connected device\n    ! No devices available\n\n! Doctor found issues in 1 category.\n```\n"
  },
  {
    "path": "recipes/flutter_test/how_do_i_find_something/lib/main.dart",
    "content": "import 'package:flutter/material.dart';\n\nvoid main() => runApp(MyApp());\n\nclass MyApp extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      home: Scaffold(\n        body: Column(\n          children: <Widget>[\n            RaisedButton(\n              onPressed: () => print(\"rasied button was clicked\"),\n              child: Text(\"we will find this by searching for a type\"),\n            ),\n            Text(\n              \"we will find this by searching for text\",\n            ),\n            Text(\n              \"will will find this by searching for a key\",\n              key: Key(\"mykey\"),\n            ),\n          ],\n        ),\n      ),\n    );\n  }\n}\n"
  },
  {
    "path": "recipes/flutter_test/how_do_i_find_something/pubspec.yaml",
    "content": "name: ftc\ndescription: A new Flutter project.\n\nversion: 1.0.0+1\n\nenvironment:\n  sdk: \">=2.1.0 <3.0.0\"\n\ndependencies:\n  flutter:\n    sdk: flutter\n\ndev_dependencies:\n  flutter_test:\n    sdk: flutter"
  },
  {
    "path": "recipes/flutter_test/how_do_i_find_something/test/widget_test.dart",
    "content": "import 'package:flutter/material.dart';\nimport 'package:flutter_test/flutter_test.dart';\n\nimport 'package:ftc/main.dart';\n\nvoid main() {\n  testWidgets('how do i find something?', (WidgetTester tester) async {\n    await tester.pumpWidget(MyApp());\n\n    // Let's find a widget by its type\n    Finder raisedButtonFinder = find.byType(RaisedButton);\n    expect(raisedButtonFinder, findsOneWidget);\n\n    // Let's find a specific string of text\n    Finder textFinder = find.text(\"we will find this by searching for text\");\n    expect(textFinder, findsOneWidget);\n\n    // Let's find a widget by its key\n    Finder keyFinder = find.byKey(Key(\"mykey\"));\n    expect(keyFinder, findsOneWidget);\n  });\n}\n"
  },
  {
    "path": "recipes/flutter_test/how_do_i_mock_async_http_request/.gitignore",
    "content": "# Miscellaneous\n*.class\n*.log\n*.pyc\n*.swp\n.DS_Store\n.atom/\n.buildlog/\n.history\n.svn/\n\n# IntelliJ related\n*.iml\n*.ipr\n*.iws\n.idea/\n\n# The .vscode folder contains launch configuration and tasks you configure in\n# VS Code which you may wish to be included in version control, so this line\n# is commented out by default.\n#.vscode/\n\n# Flutter/Dart/Pub related\n**/doc/api/\n.dart_tool/\n.flutter-plugins\n.flutter-plugins-dependencies\n.packages\n.pub-cache/\n.pub/\n/build/\n\n# Web related\nlib/generated_plugin_registrant.dart\n\n# Symbolication related\napp.*.symbols\n\n# Obfuscation related\napp.*.map.json\n\n# Exceptions to above rules.\n!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages\n\n\n# Flutter Test Cookbook (flutter_test)\n.metadata\nandroid/\nios/\npubspec.lock\nftc.iml\n*.*~\ntest_driver/"
  },
  {
    "path": "recipes/flutter_test/how_do_i_mock_async_http_request/README.md",
    "content": "# Question\n\nHow do I mock an async http request?\n\n# Answer\n\nWe will be using the [http](https://pub.dev/packages/http) package to make an http request, and [mockito](https://pub.dev/packages/mockito) to mock it.\n   \n\n## 1) Create a flutter application.\n\n```sh\nflutter create ftc\ncd ftc\n```\n\n## 2) Add http and mockito to your `pubspec.yaml` file\n\n```yaml\ndependencies:\n  flutter:\n    sdk: flutter\n  http: 0.12.1\n\ndev_dependencies:\n  flutter_test:\n    sdk: flutter\n  mockito: 4.1.1\n```\n\nThen get the dependencies by running:\n\n```sh\nflutter packages get\n```\n\n## 3) Replace the `lib/main.dart` file\n\nReplace the `lib/main.dart` file with the following:\n\n```dart\nimport 'dart:convert';\n\nimport 'package:flutter/material.dart';\nimport 'package:http/http.dart' as http;\n\nvoid main() => runApp(MyApp());\n\nclass MyApp extends StatelessWidget {\n  MyApp();\n\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      home: Scaffold(\n        body: Body(),\n      ),\n    );\n  }\n}\n\nclass Body extends StatefulWidget {\n  @override\n  BodyState createState() => BodyState();\n}\n\nclass BodyState extends State<Body> {\n  Todo todo;\n\n  Future<void> asyncOnPressed() async {\n    http.Response response =\n        await http.get('https://jsonplaceholder.typicode.com/todos/1');\n    setState(() {\n      todo = Todo.fromJson(jsonDecode(response.body));\n    });\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return ListView(\n      children: <Widget>[\n        RaisedButton(\n          child: Text('Fetch todo'),\n          onPressed: asyncOnPressed,\n        ),\n        SizedBox(\n          height: 16,\n        ),\n        todo == null\n            ? Container()\n            : Text('Todo: ${todo.title}', key: Key(\"todo-${todo.id}\")),\n      ],\n    );\n  }\n}\n\nclass Todo {\n  final String title;\n  final int id;\n\n  Todo({\n    @required this.title,\n    @required this.id,\n  });\n\n  Todo.fromJson(Map<String, dynamic> json)\n      : title = json['title'],\n        id = json['id'];\n}\n```\n\n## 4) Replace the `test/widget_test.dart` file.\n\nReplace the `test/widget_test.dart` file with the following:\n\n```dart\nimport 'dart:convert';\nimport 'package:flutter/material.dart';\nimport 'package:flutter_test/flutter_test.dart';\nimport 'package:http/http.dart' as http;\nimport 'package:ftc/main.dart';\nimport 'package:mockito/mockito.dart';\n\nclass MockAppHttpClient extends Mock implements http.Client {}\n\nconst String applicationJson = 'application/json; charset=utf-8';\n\nvoid main() {\n  testWidgets(\"A todo item should appear on the screen\",\n      (WidgetTester tester) async {\n    await tester.pumpWidget(MyApp());\n\n    // A todo should not be shown when the page loads\n    expect(find.byKey(Key('todo-1')), findsNothing);\n\n    // Use mockito to mock an http request's response\n    httpClient = MockAppHttpClient();\n    when(\n      httpClient.get(\n        'https://jsonplaceholder.typicode.com/todos/1',\n      ),\n    ).thenAnswer((_) async {\n      return http.Response(\n          jsonEncode({'id': 1, 'title': 'Do the laundry'}), 200,\n          headers: {'content-type': 'application/json; charset=utf-8'});\n    });\n\n    // Make the http request\n    //\n    // IMPORTANT NOTE: We are *not* tapping the [RaisedButton] directly.\n    // Instead, we are finding the state object, and then running the asyncOnPressed function\n    // which is passed to the onPressed of the RaisedButton. If we were to tap the RaisedButton directly,\n    // the test wouldn't wait properly because the onPressed signature is a VoidCallback instead\n    // of an AsyncCallback.\n    await tester.state<BodyState>(find.byType(Body)).asyncOnPressed();\n    await tester.pump();\n\n    // A todo should be shown after the http request receives a response\n    expect(find.byKey(Key('todo-1')), findsOneWidget);\n  });\n}\n```\n\n\n## 5) Run the flutter tests\n\n```sh\nflutter test\n```\n\n# Run tests from example code in cookbook itself\n\nIf you have cloned [flutter_test_cookbook](https://github.com/gadfly361/flutter_test_cookbook/tree/master) and simply want to run the tests from this recipe, then:\n\n```sh\nflutter create .\nflutter packages get\nflutter test\n```\n\n# Outputs when recipe was made / updated\n\n## Output of running flutter tests\n\n```sh\n$ flutter test \n00:02 +1: All tests passed!\n```\n\n## Output of running `flutter doctor -v`\n\n```sh\n$ flutter doctor -v\n[✓] Flutter (Channel stable, v1.17.2, on Mac OS X 10.15.5 19F101, locale en-US)\n    • Flutter version 1.17.2 at /Users/matthew/gadfly/flutter_versions/flutter_1.17.2\n    • Framework revision 5f21edf8b6 (2 weeks ago), 2020-05-28 12:44:12 -0700\n    • Engine revision b851c71829\n    • Dart version 2.8.3\n\n[✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)\n    • Android SDK at /Users/matthew/Library/Android/sdk\n    • Platform android-29, build-tools 28.0.3\n    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java\n    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)\n    • All Android licenses accepted.\n\n[✓] Xcode - develop for iOS and macOS (Xcode 11.5)\n    • Xcode at /Applications/Xcode.app/Contents/Developer\n    • Xcode 11.5, Build version 11E608c\n    • CocoaPods version 1.9.1\n\n[✓] Android Studio (version 3.4)\n    • Android Studio at /Applications/Android Studio.app/Contents\n    • Flutter plugin version 35.2.1\n    • Dart plugin version 183.6270\n    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)\n\n[!] IntelliJ IDEA Ultimate Edition (version 2020.1.2)\n    • IntelliJ at /Applications/IntelliJ IDEA.app\n    ✗ Flutter plugin not installed; this adds Flutter specific functionality.\n    ✗ Dart plugin not installed; this adds Dart specific functionality.\n    • For information about installing plugins, see\n      https://flutter.dev/intellij-setup/#installing-the-plugins\n\n[✓] VS Code (version 1.45.1)\n    • VS Code at /Applications/Visual Studio Code.app/Contents\n    • Flutter extension version 3.10.2\n\n[✓] Connected device (1 available)\n    • iPhone 8 • C9868AFF-E4CE-4C0B-AC2B-9600508F6C1F • ios • com.apple.CoreSimulator.SimRuntime.iOS-13-5 (simulator)\n\n! Doctor found issues in 1 category.\n```\n"
  },
  {
    "path": "recipes/flutter_test/how_do_i_mock_async_http_request/lib/main.dart",
    "content": "import 'dart:convert';\nimport 'package:flutter/material.dart';\nimport 'package:http/http.dart' as http;\n\nvoid main() => runApp(MyApp());\n\nhttp.Client httpClient = http.Client();\n\nclass MyApp extends StatelessWidget {\n  MyApp();\n\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      home: Scaffold(\n        body: Body(),\n      ),\n    );\n  }\n}\n\nclass Body extends StatefulWidget {\n  @override\n  BodyState createState() => BodyState();\n}\n\nclass BodyState extends State<Body> {\n  Todo todo;\n\n  Future<void> asyncOnPressed() async {\n    http.Response response =\n        await httpClient.get('https://jsonplaceholder.typicode.com/todos/1');\n    setState(() {\n      todo = Todo.fromJson(jsonDecode(response.body));\n    });\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return ListView(\n      children: <Widget>[\n        RaisedButton(\n          child: Text('Fetch todo'),\n          onPressed: asyncOnPressed,\n        ),\n        SizedBox(\n          height: 16,\n        ),\n        todo == null\n            ? Container()\n            : Text('Todo: ${todo.title}', key: Key(\"todo-${todo.id}\")),\n      ],\n    );\n  }\n}\n\nclass Todo {\n  final String title;\n  final int id;\n\n  Todo({\n    @required this.title,\n    @required this.id,\n  });\n\n  Todo.fromJson(Map<String, dynamic> json)\n      : title = json['title'],\n        id = json['id'];\n}\n"
  },
  {
    "path": "recipes/flutter_test/how_do_i_mock_async_http_request/pubspec.yaml",
    "content": "name: ftc\ndescription: A new Flutter project.\n\nversion: 1.0.0+1\n\nenvironment:\n  sdk: \">=2.1.0 <3.0.0\"\n\ndependencies:\n  flutter:\n    sdk: flutter\n  http: 0.12.1\n\ndev_dependencies:\n  flutter_test:\n    sdk: flutter\n  mockito: 4.1.1"
  },
  {
    "path": "recipes/flutter_test/how_do_i_mock_async_http_request/test/widget_test.dart",
    "content": "import 'dart:convert';\nimport 'package:flutter/material.dart';\nimport 'package:flutter_test/flutter_test.dart';\nimport 'package:http/http.dart' as http;\nimport 'package:ftc/main.dart';\nimport 'package:mockito/mockito.dart';\n\nclass MockAppHttpClient extends Mock implements http.Client {}\n\nconst String applicationJson = 'application/json; charset=utf-8';\n\nvoid main() {\n  testWidgets(\"A todo item should appear on the screen\",\n      (WidgetTester tester) async {\n    await tester.pumpWidget(MyApp());\n\n    // A todo should not be shown when the page loads\n    expect(find.byKey(Key('todo-1')), findsNothing);\n\n    // Use mockito to mock an http request's response\n    httpClient = MockAppHttpClient();\n    when(\n      httpClient.get(\n        'https://jsonplaceholder.typicode.com/todos/1',\n      ),\n    ).thenAnswer((_) async {\n      return http.Response(\n          jsonEncode({'id': 1, 'title': 'Do the laundry'}), 200,\n          headers: {'content-type': 'application/json; charset=utf-8'});\n    });\n\n    // Make the http request\n    //\n    // IMPORTANT NOTE: We are *not* tapping the [RaisedButton] directly.\n    // Instead, we are finding the state object, and then running the asyncOnPressed function\n    // which is passed to the onPressed of the RaisedButton. If we were to tap the RaisedButton directly,\n    // the test wouldn't wait properly because the onPressed signature is a VoidCallback instead\n    // of an AsyncCallback.\n    await tester.state<BodyState>(find.byType(Body)).asyncOnPressed();\n    await tester.pump();\n\n    // A todo should be shown after the http request receives a response\n    expect(find.byKey(Key('todo-1')), findsOneWidget);\n  });\n}\n"
  },
  {
    "path": "recipes/flutter_test/how_do_i_mock_shared_preferences/.gitignore",
    "content": "# Miscellaneous\n*.class\n*.log\n*.pyc\n*.swp\n.DS_Store\n.atom/\n.buildlog/\n.history\n.svn/\n\n# IntelliJ related\n*.iml\n*.ipr\n*.iws\n.idea/\n\n# The .vscode folder contains launch configuration and tasks you configure in\n# VS Code which you may wish to be included in version control, so this line\n# is commented out by default.\n#.vscode/\n\n# Flutter/Dart/Pub related\n**/doc/api/\n.dart_tool/\n.flutter-plugins\n.flutter-plugins-dependencies\n.packages\n.pub-cache/\n.pub/\n/build/\n\n# Web related\nlib/generated_plugin_registrant.dart\n\n# Exceptions to above rules.\n!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages\n\n# Flutter Test Cookbook (flutter_test)\n.dart_tool/\n.metadata\n.packages\nandroid/\nios/\npubspec.lock\nftc.iml\n*.*~\ntest_driver/"
  },
  {
    "path": "recipes/flutter_test/how_do_i_mock_shared_preferences/README.md",
    "content": "# Question\n\nHow do I mock [shared_preferences](https://pub.dev/packages/shared_preferences)?\n\n# Answer\n\nThere are a few subtle things that can go wrong when testing shared_preferences.  \n\na) If you are grabbing a value from shared_preferences during `initState`, then there is the need for an extra `pump` when testing. \nb) If you try to get shared_preferences in your main file before your call to `runApp`, you may experience an error.  If so, you will need to add a call to [WidgetsFlutterBinding.ensureInitialized](https://api.flutter.dev/flutter/widgets/WidgetsFlutterBinding/ensureInitialized.html) (as well as [TestWidgetsFlutterBinding.ensureInitialized](https://api.flutter.dev/flutter/flutter_test/TestWidgetsFlutterBinding/ensureInitialized.html) to your tests).\n\nThis recipe covers a).   \n\n## 1) Create a flutter application.\n\n```sh\nflutter create ftc\ncd ftc\n```\n\n## 2) Add shared_preferences to your `pubspec.yaml` file\n\n```yaml\ndependencies:\n  flutter:\n    sdk: flutter\n  shared_preferences: 0.5.6+2\n```\n\nThen get the dependencies by running:\n\n```sh\nflutter packages get\n```\n\n## 3) Replace the `lib/main.dart` file\n\nReplace the `lib/main.dart` file with the following:\n\n```dart\nimport 'package:flutter/material.dart';\nimport 'package:shared_preferences/shared_preferences.dart';\n\nvoid main() => runApp(MyApp());\n\nclass MyApp extends StatelessWidget {\n  MyApp();\n\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      home: Scaffold(\n        body: Body(),\n      ),\n    );\n  }\n}\n\nclass Body extends StatefulWidget {\n  @override\n  _BodyState createState() => _BodyState();\n}\n\nclass _BodyState extends State<Body> {\n  int spValue = 0;\n\n  @override\n  void initState() {\n    super.initState();\n    SharedPreferences.getInstance().then((SharedPreferences prefs) {\n      setState(() {\n        spValue = prefs.getInt(\"myValue\") ?? 0;\n      });\n    });\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return Center(\n      child: Text(\"The shared_preferences value is: $spValue\"),\n    );\n  }\n}\n```\n\n## 4) Replace the `test/widget_test.dart` file.\n\nReplace the `test/widget_test.dart` file with the following:\n\n```dart\nimport 'package:flutter_test/flutter_test.dart';\nimport 'package:shared_preferences/shared_preferences.dart';\n\nimport 'package:ftc/main.dart';\n\nvoid main() {\n  // If you're running a test, you can call the `TestWidgetsFlutterBinding.ensureInitialized()` as the first line in your test's `main()` method to initialize the binding.\n  TestWidgetsFlutterBinding.ensureInitialized();\n\n  testWidgets(\n      \"The value displayed should fallback to 0 if the shared_preferences value isn't mocked\",\n      (WidgetTester tester) async {\n    await tester.pumpWidget(MyApp());\n\n    expect(find.text(\"The shared_preferences value is: 0\"), findsOneWidget);\n  });\n\n  testWidgets(\n      \"The value displayed should be updated when mocking initial shared_preferences values\",\n      (WidgetTester tester) async {\n    // We are setting the initial value to 10\n    SharedPreferences.setMockInitialValues({\"myValue\": 10});\n\n    // then we are pumping our top-level widget\n    await tester.pumpWidget(MyApp());\n\n    // However, because we are grabbing shared_preferences value in our initState, and then using setState\n    // to set the value displayed in our app, we need to pump one more time!\n    await tester.pump();\n\n    // Then we expect out mock value to be displayed\n    expect(find.text(\"The shared_preferences value is: 10\"), findsOneWidget);\n  });\n}\n```\n\n\n## 5) Run the flutter tests\n\n```sh\nflutter test\n```\n\n# Run tests from example code in cookbook itself\n\nIf you have cloned [flutter_test_cookbook](https://github.com/gadfly361/flutter_test_cookbook/tree/master) and simply want to run the tests from this recipe, then:\n\n```sh\nflutter create .\nflutter packages get\nflutter test\n```\n\n# Outputs when recipe was made / updated\n\n## Output of running flutter tests\n\n```sh\n$ flutter test \n00:06 +1: All tests passed!  \n```\n\n## Output of running `flutter doctor -v`\n\n```sh\n$ flutter doctor -v\n[✓] Flutter (Channel stable, v1.12.13+hotfix.5, on Mac OS X 10.15.2 19C57, locale en-US)\n    • Flutter version 1.12.13+hotfix.5 at /Users/matthew/gadfly/flutter_versions/flutter_1.12.13+hotfix.5\n    • Framework revision 27321ebbad (3 months ago), 2019-12-10 18:15:01 -0800\n    • Engine revision 2994f7e1e6\n    • Dart version 2.7.0\n\n[✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)\n    • Android SDK at /Users/matthew/Library/Android/sdk\n    • Android NDK location not configured (optional; useful for native profiling support)\n    • Platform android-29, build-tools 28.0.3\n    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java\n    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)\n    • All Android licenses accepted.\n\n[✓] Xcode - develop for iOS and macOS (Xcode 11.3.1)\n    • Xcode at /Applications/Xcode.app/Contents/Developer\n    • Xcode 11.3.1, Build version 11C504\n    • CocoaPods version 1.8.4\n\n[✓] Android Studio (version 3.4)\n    • Android Studio at /Applications/Android Studio.app/Contents\n    • Flutter plugin version 35.2.1\n    • Dart plugin version 183.6270\n    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)\n\n[✓] IntelliJ IDEA Community Edition (version 2019.3.3)\n    • IntelliJ at /Applications/IntelliJ IDEA CE.app\n    • Flutter plugin version 44.0.3\n    • Dart plugin version 193.6494.35\n\n[✓] VS Code (version 1.41.1)\n    • VS Code at /Applications/Visual Studio Code.app/Contents\n    • Flutter extension version 3.4.1\n\n[✓] Connected device (1 available)\n    • iPhone 8 • AD7A90EB-5E73-427E-B9B7-DD3B07E2FEF1 • ios • com.apple.CoreSimulator.SimRuntime.iOS-13-3 (simulator)\n\n• No issues found!\n```\n"
  },
  {
    "path": "recipes/flutter_test/how_do_i_mock_shared_preferences/lib/main.dart",
    "content": "import 'package:flutter/material.dart';\nimport 'package:shared_preferences/shared_preferences.dart';\n\nvoid main() => runApp(MyApp());\n\nclass MyApp extends StatelessWidget {\n  MyApp();\n\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      home: Scaffold(\n        body: Body(),\n      ),\n    );\n  }\n}\n\nclass Body extends StatefulWidget {\n  @override\n  _BodyState createState() => _BodyState();\n}\n\nclass _BodyState extends State<Body> {\n  int spValue = 0;\n\n  @override\n  void initState() {\n    super.initState();\n    SharedPreferences.getInstance().then((SharedPreferences prefs) {\n      setState(() {\n        spValue = prefs.getInt(\"myValue\") ?? 0;\n      });\n    });\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return Center(\n      child: Text(\"The shared_preferences value is: $spValue\"),\n    );\n  }\n}\n"
  },
  {
    "path": "recipes/flutter_test/how_do_i_mock_shared_preferences/pubspec.yaml",
    "content": "name: ftc\ndescription: A new Flutter project.\n\nversion: 1.0.0+1\n\nenvironment:\n  sdk: \">=2.1.0 <3.0.0\"\n\ndependencies:\n  flutter:\n    sdk: flutter\n  shared_preferences: 0.5.6+2\n\ndev_dependencies:\n  flutter_test:\n    sdk: flutter\n"
  },
  {
    "path": "recipes/flutter_test/how_do_i_mock_shared_preferences/test/widget_test.dart",
    "content": "import 'package:flutter_test/flutter_test.dart';\nimport 'package:shared_preferences/shared_preferences.dart';\n\nimport 'package:ftc/main.dart';\n\nvoid main() {\n  // If you're running a test, you can call the `TestWidgetsFlutterBinding.ensureInitialized()` as the first line in your test's `main()` method to initialize the binding.\n  TestWidgetsFlutterBinding.ensureInitialized();\n\n  testWidgets(\n      \"The value displayed should fallback to 0 if the shared_preferences value isn't mocked\",\n      (WidgetTester tester) async {\n    await tester.pumpWidget(MyApp());\n\n    expect(find.text(\"The shared_preferences value is: 0\"), findsOneWidget);\n  });\n\n  testWidgets(\n      \"The value displayed should be updated when mocking initial shared_preferences values\",\n      (WidgetTester tester) async {\n    // We are setting the initial value to 10\n    SharedPreferences.setMockInitialValues({\"myValue\": 10});\n\n    // then we are pumping our top-level widget\n    await tester.pumpWidget(MyApp());\n\n    // However, because we are grabbing shared_preferences value in our initState, and then using setState\n    // to set the value displayed in our app, we need to pump one more time!\n    await tester.pump();\n\n    // Then we expect out mock value to be displayed\n    expect(find.text(\"The shared_preferences value is: 10\"), findsOneWidget);\n  });\n}\n"
  },
  {
    "path": "recipes/flutter_test/how_do_i_open_a_drawer/.gitignore",
    "content": "# Miscellaneous\n*.class\n*.log\n*.pyc\n*.swp\n.DS_Store\n.atom/\n.buildlog/\n.history\n.svn/\n\n# IntelliJ related\n*.iml\n*.ipr\n*.iws\n.idea/\n\n# The .vscode folder contains launch configuration and tasks you configure in\n# VS Code which you may wish to be included in version control, so this line\n# is commented out by default.\n#.vscode/\n\n# Flutter/Dart/Pub related\n**/doc/api/\n.dart_tool/\n.flutter-plugins\n.flutter-plugins-dependencies\n.packages\n.pub-cache/\n.pub/\n/build/\n\n# Web related\nlib/generated_plugin_registrant.dart\n\n# Exceptions to above rules.\n!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages\n\n# Flutter Test Cookbook (flutter_test)\n.dart_tool/\n.metadata\n.packages\nandroid/\nios/\npubspec.lock\nftc.iml\n*.*~\ntest_driver/"
  },
  {
    "path": "recipes/flutter_test/how_do_i_open_a_drawer/README.md",
    "content": "# Question\n\nHow do I open a [Drawer](https://api.flutter.dev/flutter/material/Drawer-class.html)?\n\n# Answer\n\nThere are several methods to open a Drawer:\n\na) Open Drawer by tapping the menu icon in the Appbar\nb) Open Drawer by using scaffoldKey\nc) Open Drawer by using a BuildContext and finding a Scaffold with Scaffold.of\nd) Open Drawer by swiping from the left edge\n\n## 1) Create a flutter application.\n\n```sh\nflutter create ftc\ncd ftc\n```\n\n## 2) Get dependencies\n\n```sh\nflutter packages get\n```\n\n## 3) Replace the `lib/main.dart` file\n\nReplace the `lib/main.dart` file with the following:\n\n```dart\nimport 'package:flutter/material.dart';\n\nvoid main() => runApp(MyApp());\n\nGlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();\n\nclass MyApp extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      home: Scaffold(\n        key: scaffoldKey,\n        appBar: AppBar(),\n        drawer: Drawer(),\n        body: Body(),\n      ),\n    );\n  }\n}\n\nclass Body extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return Center(\n      child: Text(\"There is a drawer\"),\n    );\n  }\n}\n```\n\n## 4) Replace the `test/widget_test.dart` file.\n\nReplace the `test/widget_test.dart` file with the following:\n\n```dart\nimport 'package:flutter/material.dart';\nimport 'package:flutter_test/flutter_test.dart';\n\nimport 'package:ftc/main.dart';\n\nvoid main() {\n  testWidgets('How do I open a Drawer?', (WidgetTester tester) async {\n    await tester.pumpWidget(MyApp());\n\n    Finder drawerFinder = find.byType(Drawer);\n\n    expect(drawerFinder, findsNothing);\n\n    //\n    // Method a)\n    //\n\n    // open Drawer by tapping the menu icon in the Appbar\n    Finder menuIconFinder = find.byIcon(Icons.menu);\n    await tester.tap(menuIconFinder);\n    await tester.pumpAndSettle();\n\n    // confirm that the Drawer is open\n    expect(drawerFinder, findsOneWidget);\n\n    // close Drawer\n    Navigator.of(tester.element(drawerFinder)).pop();\n    await tester.pumpAndSettle();\n    expect(drawerFinder, findsNothing);\n\n    //\n    // Method b)\n    //\n\n    // open Drawer by using scaffoldKey\n    scaffoldKey.currentState.openDrawer();\n    await tester.pumpAndSettle();\n\n    // confirm that the Drawer is open\n    expect(drawerFinder, findsOneWidget);\n\n    // close Drawer\n    Navigator.of(tester.element(drawerFinder)).pop();\n    await tester.pumpAndSettle();\n    expect(drawerFinder, findsNothing);\n\n    //\n    // Method c)\n    //\n\n    // open Drawer by using a BuildContext and finding a Scaffold with Scaffold.of\n    Finder bodyFinder = find.byType(Body);\n    Scaffold.of(tester.element(bodyFinder)).openDrawer();\n    await tester.pumpAndSettle();\n\n    // confirm that the Drawer is open\n    expect(drawerFinder, findsOneWidget);\n\n    // close Drawer\n    Navigator.of(tester.element(drawerFinder)).pop();\n    await tester.pumpAndSettle();\n    expect(drawerFinder, findsNothing);\n\n    //\n    // Method d)\n    //\n\n    // open Drawer by swiping from the left edge\n    await tester.dragFrom(Offset(0, 100), Offset(300, 100));\n    await tester.pumpAndSettle();\n\n    // confirm that the Drawer is open\n    expect(drawerFinder, findsOneWidget);\n\n    // close Drawer\n    Navigator.of(tester.element(drawerFinder)).pop();\n    await tester.pumpAndSettle();\n    expect(drawerFinder, findsNothing);\n  });\n}\n```\n\n\n## 5) Run the flutter tests\n\n```sh\nflutter test\n```\n\n# Run tests from example code in cookbook itself\n\nIf you have cloned [flutter_test_cookbook](https://github.com/gadfly361/flutter_test_cookbook/tree/master) and simply want to run the tests from this recipe, then:\n\n```sh\nflutter create .\nflutter packages get\nflutter test\n```\n\n# Outputs when recipe was made / updated\n\n## Output of running flutter tests\n\n```sh\n$ flutter test \n00:02 +1: All tests passed!  \n```\n\n## Output of running `flutter doctor -v`\n\n```sh\n$ flutter doctor -v\n[✓] Flutter (Channel stable, v1.12.13+hotfix.5, on Mac OS X 10.15.2 19C57, locale en-US)\n    • Flutter version 1.12.13+hotfix.5 at /Users/matthew/gadfly/flutter_versions/flutter_1.12.13+hotfix.5\n    • Framework revision 27321ebbad (3 months ago), 2019-12-10 18:15:01 -0800\n    • Engine revision 2994f7e1e6\n    • Dart version 2.7.0\n\n[✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)\n    • Android SDK at /Users/matthew/Library/Android/sdk\n    • Android NDK location not configured (optional; useful for native profiling support)\n    • Platform android-29, build-tools 28.0.3\n    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java\n    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)\n    • All Android licenses accepted.\n\n[✓] Xcode - develop for iOS and macOS (Xcode 11.3.1)\n    • Xcode at /Applications/Xcode.app/Contents/Developer\n    • Xcode 11.3.1, Build version 11C504\n    • CocoaPods version 1.8.4\n\n[✓] Android Studio (version 3.4)\n    • Android Studio at /Applications/Android Studio.app/Contents\n    • Flutter plugin version 35.2.1\n    • Dart plugin version 183.6270\n    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)\n\n[✓] IntelliJ IDEA Community Edition (version 2019.3.3)\n    • IntelliJ at /Applications/IntelliJ IDEA CE.app\n    • Flutter plugin version 44.0.3\n    • Dart plugin version 193.6494.35\n\n[✓] VS Code (version 1.41.1)\n    • VS Code at /Applications/Visual Studio Code.app/Contents\n    • Flutter extension version 3.4.1\n\n[✓] Connected device (1 available)\n    • iPhone 8 • AD7A90EB-5E73-427E-B9B7-DD3B07E2FEF1 • ios • com.apple.CoreSimulator.SimRuntime.iOS-13-3 (simulator)\n\n• No issues found!\n```"
  },
  {
    "path": "recipes/flutter_test/how_do_i_open_a_drawer/lib/main.dart",
    "content": "import 'package:flutter/material.dart';\n\nvoid main() => runApp(MyApp());\n\nGlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();\n\nclass MyApp extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      home: Scaffold(\n        key: scaffoldKey,\n        appBar: AppBar(),\n        drawer: Drawer(),\n        body: Body(),\n      ),\n    );\n  }\n}\n\nclass Body extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return Center(\n      child: Text(\"There is a drawer\"),\n    );\n  }\n}\n"
  },
  {
    "path": "recipes/flutter_test/how_do_i_open_a_drawer/pubspec.yaml",
    "content": "name: ftc\ndescription: A new Flutter project.\n\nversion: 1.0.0+1\n\nenvironment:\n  sdk: \">=2.1.0 <3.0.0\"\n\ndependencies:\n  flutter:\n    sdk: flutter\n\ndev_dependencies:\n  flutter_test:\n    sdk: flutter\n\n# needed to show menu icon in AppBar\nflutter:\n  uses-material-design: true"
  },
  {
    "path": "recipes/flutter_test/how_do_i_open_a_drawer/test/widget_test.dart",
    "content": "import 'package:flutter/material.dart';\nimport 'package:flutter_test/flutter_test.dart';\n\nimport 'package:ftc/main.dart';\n\nvoid main() {\n  testWidgets('How do I open a Drawer?', (WidgetTester tester) async {\n    await tester.pumpWidget(MyApp());\n\n    Finder drawerFinder = find.byType(Drawer);\n\n    expect(drawerFinder, findsNothing);\n\n    //\n    // Method a)\n    //\n\n    // open Drawer by tapping the menu icon in the Appbar\n    Finder menuIconFinder = find.byIcon(Icons.menu);\n    await tester.tap(menuIconFinder);\n    await tester.pumpAndSettle();\n\n    // confirm that the Drawer is open\n    expect(drawerFinder, findsOneWidget);\n\n    // close Drawer\n    Navigator.of(tester.element(drawerFinder)).pop();\n    await tester.pumpAndSettle();\n    expect(drawerFinder, findsNothing);\n\n    //\n    // Method b)\n    //\n\n    // open Drawer by using scaffoldKey\n    scaffoldKey.currentState.openDrawer();\n    await tester.pumpAndSettle();\n\n    // confirm that the Drawer is open\n    expect(drawerFinder, findsOneWidget);\n\n    // close Drawer\n    Navigator.of(tester.element(drawerFinder)).pop();\n    await tester.pumpAndSettle();\n    expect(drawerFinder, findsNothing);\n\n    //\n    // Method c)\n    //\n\n    // open Drawer by using a BuildContext and finding a Scaffold with Scaffold.of\n    Finder bodyFinder = find.byType(Body);\n    Scaffold.of(tester.element(bodyFinder)).openDrawer();\n    await tester.pumpAndSettle();\n\n    // confirm that the Drawer is open\n    expect(drawerFinder, findsOneWidget);\n\n    // close Drawer\n    Navigator.of(tester.element(drawerFinder)).pop();\n    await tester.pumpAndSettle();\n    expect(drawerFinder, findsNothing);\n\n    //\n    // Method d)\n    //\n\n    // open Drawer by swiping from the left edge\n    await tester.dragFrom(Offset(0, 100), Offset(300, 100));\n    await tester.pumpAndSettle();\n\n    // confirm that the Drawer is open\n    expect(drawerFinder, findsOneWidget);\n\n    // close Drawer\n    Navigator.of(tester.element(drawerFinder)).pop();\n    await tester.pumpAndSettle();\n    expect(drawerFinder, findsNothing);\n  });\n}\n"
  },
  {
    "path": "recipes/flutter_test/how_do_i_run_a_flutter_test/.gitignore",
    "content": "# Miscellaneous\n*.class\n*.log\n*.pyc\n*.swp\n.DS_Store\n.atom/\n.buildlog/\n.history\n.svn/\n\n# IntelliJ related\n*.iml\n*.ipr\n*.iws\n.idea/\n\n# The .vscode folder contains launch configuration and tasks you configure in\n# VS Code which you may wish to be included in version control, so this line\n# is commented out by default.\n#.vscode/\n\n# Flutter/Dart/Pub related\n**/doc/api/\n.dart_tool/\n.flutter-plugins\n.flutter-plugins-dependencies\n.packages\n.pub-cache/\n.pub/\n/build/\n\n# Web related\nlib/generated_plugin_registrant.dart\n\n# Exceptions to above rules.\n!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages\n\n# Flutter Test Cookbook (flutter_test)\n.dart_tool/\n.metadata\n.packages\nandroid/\nios/\npubspec.lock\nftc.iml\n*.*~\ntest_driver/"
  },
  {
    "path": "recipes/flutter_test/how_do_i_run_a_flutter_test/README.md",
    "content": "# Question\n\nHow do I run a [flutter test](https://api.flutter.dev/flutter/flutter_test/flutter_test-library.html) test?\n\n# Answer\n\n## 1) Create a flutter application.\n\n```sh\nflutter create ftc\ncd ftc\n```\n\n## 2) Get dependencies\n\n```sh\nflutter packages get\n```\n\n## 3) Replace the `lib/main.dart` file\n\nReplace the `lib/main.dart` file with the following:\n\n```dart\nimport 'package:flutter/material.dart';\n\nvoid main() => runApp(MyApp());\n\nclass MyApp extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      home: Scaffold(\n        body: Center(\n          child: Text(\"Hello world\"),\n        ),\n      ),\n    );\n  }\n}\n```\n\n## 4) Replace the `test/widget_test.dart` file.\n\nReplace the `test/widget_test.dart` file with the following:\n\n```dart\nimport 'package:flutter_test/flutter_test.dart';\nimport 'package:ftc/main.dart';\n\nvoid main() {\n  testWidgets(\"'Hello world' text exists\", (WidgetTester tester) async {\n    await tester.pumpWidget(MyApp());\n\n    expect(find.text('Hello world'), findsOneWidget);\n  });\n}\n```\n\n\n## 5) Run the flutter tests\n\n```sh\nflutter test\n```\n\n# Run tests from example code in cookbook itself\n\nIf you have cloned [flutter_test_cookbook](https://github.com/gadfly361/flutter_test_cookbook/tree/master) and simply want to run the tests from this recipe, then:\n\n```sh\nflutter create .\nflutter packages get\nflutter test\n```\n\n# Outputs when recipe was made / updated\n\n## Output of running flutter tests\n\n```sh\n$ flutter test \n00:06 +1: All tests passed!  \n```\n\n## Output of running `flutter doctor -v`\n\n```sh\n$ flutter doctor -v\n[✓] Flutter (Channel stable, v1.12.13+hotfix.5, on Mac OS X 10.15.2 19C57, locale en-US)\n    • Flutter version 1.12.13+hotfix.5 at /Users/matthew/gadfly/flutter_versions/flutter_1.12.13+hotfix.5\n    • Framework revision 27321ebbad (3 months ago), 2019-12-10 18:15:01 -0800\n    • Engine revision 2994f7e1e6\n    • Dart version 2.7.0\n\n \n[✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)\n    • Android SDK at /Users/matthew/Library/Android/sdk\n    • Android NDK location not configured (optional; useful for native profiling support)\n    • Platform android-29, build-tools 28.0.3\n    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java\n    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)\n    • All Android licenses accepted.\n\n[✓] Xcode - develop for iOS and macOS (Xcode 11.3.1)\n    • Xcode at /Applications/Xcode.app/Contents/Developer\n    • Xcode 11.3.1, Build version 11C504\n    • CocoaPods version 1.8.4\n\n[✓] Android Studio (version 3.4)\n    • Android Studio at /Applications/Android Studio.app/Contents\n    • Flutter plugin version 35.2.1\n    • Dart plugin version 183.6270\n    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)\n\n[✓] IntelliJ IDEA Community Edition (version 2019.3.3)\n    • IntelliJ at /Applications/IntelliJ IDEA CE.app\n    • Flutter plugin version 44.0.3\n    • Dart plugin version 193.6494.35\n\n[✓] VS Code (version 1.41.1)\n    • VS Code at /Applications/Visual Studio Code.app/Contents\n    • Flutter extension version 3.4.1\n\n[!] Connected device\n    ! No devices available\n\n! Doctor found issues in 1 category.\n```\n"
  },
  {
    "path": "recipes/flutter_test/how_do_i_run_a_flutter_test/lib/main.dart",
    "content": "import 'package:flutter/material.dart';\n\nvoid main() => runApp(MyApp());\n\nclass MyApp extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      home: Scaffold(\n        body: Center(\n          child: Text(\"Hello world\"),\n        ),\n      ),\n    );\n  }\n}\n"
  },
  {
    "path": "recipes/flutter_test/how_do_i_run_a_flutter_test/pubspec.yaml",
    "content": "name: ftc\ndescription: A new Flutter project.\n\nversion: 1.0.0+1\n\nenvironment:\n  sdk: \">=2.1.0 <3.0.0\"\n\ndependencies:\n  flutter:\n    sdk: flutter\n\ndev_dependencies:\n  flutter_test:\n    sdk: flutter"
  },
  {
    "path": "recipes/flutter_test/how_do_i_run_a_flutter_test/test/widget_test.dart",
    "content": "import 'package:flutter_test/flutter_test.dart';\nimport 'package:ftc/main.dart';\n\nvoid main() {\n  testWidgets(\"'Hello world' text exists\", (WidgetTester tester) async {\n    await tester.pumpWidget(MyApp());\n\n    expect(find.text('Hello world'), findsOneWidget);\n  });\n}\n"
  },
  {
    "path": "recipes/flutter_test/how_do_i_run_a_script/.gitignore",
    "content": "# Miscellaneous\n*.class\n*.log\n*.pyc\n*.swp\n.DS_Store\n.atom/\n.buildlog/\n.history\n.svn/\n\n# IntelliJ related\n*.iml\n*.ipr\n*.iws\n.idea/\n\n# The .vscode folder contains launch configuration and tasks you configure in\n# VS Code which you may wish to be included in version control, so this line\n# is commented out by default.\n#.vscode/\n\n# Flutter/Dart/Pub related\n**/doc/api/\n.dart_tool/\n.flutter-plugins\n.flutter-plugins-dependencies\n.packages\n.pub-cache/\n.pub/\n/build/\n\n# Web related\nlib/generated_plugin_registrant.dart\n\n# Exceptions to above rules.\n!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages\n\n# Flutter Test Cookbook (flutter_test)\n.dart_tool/\n.metadata\n.packages\nandroid/\nios/\npubspec.lock\nftc.iml\n*.*~\ntest_driver/"
  },
  {
    "path": "recipes/flutter_test/how_do_i_run_a_script/README.md",
    "content": "# Question\n\nHow do I run a script inside of a test?\n\n# Answer\n\nUse [Process.run](https://api.dart.dev/stable/2.7.1/dart-io/Process/run.html)\n\n## 1) Create a flutter application.\n\n```sh\nflutter create ftc\ncd ftc\n```\n\n## 2) Get dependencies\n\n```sh\nflutter packages get\n```\n\n## 3) Replace the `lib/main.dart` file\n\nReplace the `lib/main.dart` file with the following:\n\n```dart\nimport 'package:flutter/material.dart';\n\nvoid main() => runApp(MyApp());\n\nclass MyApp extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      home: Scaffold(\n        body: Center(\n          child: Text(\"A script will be run during the test\"),\n        ),\n      ),\n    );\n  }\n}\n```\n\n## 4) Replace the `test/widget_test.dart` file.\n\nReplace the `test/widget_test.dart` file with the following:\n\n```dart\nimport 'package:flutter_test/flutter_test.dart';\nimport 'package:ftc/main.dart';\nimport 'dart:io';\n\nvoid main() async {\n  testWidgets(\"How do I run a script?\", (WidgetTester tester) async {\n    await tester.pumpWidget(MyApp());\n\n    // Running a script inside of flutter_test is different than with flutter_driver.\n    // With flutter_test, we need to:\n    // a) use tester.runAsync, and\n    // b) write the path of the script from the perspective of this file\n    ProcessResult result = await tester.runAsync(() async {\n      return await Process.run('../echo.sh', ['1']);\n    });\n\n    //Note: echo appends a newline to the result\n    expect(result.stdout, '1\\n');\n  });\n}\n```\n\n## 5) Add an `echo.sh` script\n\nCreate a file called `echo.sh` and add the following to it:\n\n```sh\n#!/bin/bash\n\necho \"$1\"\n```\n\nThen run:\n\n```sh\nchmod +x echo.sh\n```\n\n\n\n## 6) Run the flutter tests\n\n```sh\nflutter test\n```\n\n# Run tests from example code in cookbook itself\n\nIf you have cloned [flutter_test_cookbook](https://github.com/gadfly361/flutter_test_cookbook/tree/master) and simply want to run the tests from this recipe, then:\n\n```sh\nflutter create .\nflutter packages get\nflutter test\n```\n\n# Outputs when recipe was made / updated\n\n## Output of running flutter tests\n\n```sh\n$ flutter test \n00:01 +1: All tests passed!  \n```\n\n## Output of running `flutter doctor -v`\n\n```sh\n$ flutter doctor -v\n[✓] Flutter (Channel stable, v1.12.13+hotfix.5, on Mac OS X 10.15.2 19C57, locale en-US)\n    • Flutter version 1.12.13+hotfix.5 at /Users/matthew/gadfly/flutter_versions/flutter_1.12.13+hotfix.5\n    • Framework revision 27321ebbad (3 months ago), 2019-12-10 18:15:01 -0800\n    • Engine revision 2994f7e1e6\n    • Dart version 2.7.0\n\n[✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)\n    • Android SDK at /Users/matthew/Library/Android/sdk\n    • Android NDK location not configured (optional; useful for native profiling support)\n    • Platform android-29, build-tools 28.0.3\n    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java\n    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)\n    • All Android licenses accepted.\n\n[✓] Xcode - develop for iOS and macOS (Xcode 11.3.1)\n    • Xcode at /Applications/Xcode.app/Contents/Developer\n    • Xcode 11.3.1, Build version 11C504\n    • CocoaPods version 1.8.4\n\n[✓] Android Studio (version 3.4)\n    • Android Studio at /Applications/Android Studio.app/Contents\n    • Flutter plugin version 35.2.1\n    • Dart plugin version 183.6270\n    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)\n\n[✓] IntelliJ IDEA Community Edition (version 2019.3.3)\n    • IntelliJ at /Applications/IntelliJ IDEA CE.app\n    • Flutter plugin version 44.0.3\n    • Dart plugin version 193.6494.35\n\n[✓] VS Code (version 1.41.1)\n    • VS Code at /Applications/Visual Studio Code.app/Contents\n    • Flutter extension version 3.4.1\n\n[✓] Connected device (1 available)\n    • iPhone 8 • AD7A90EB-5E73-427E-B9B7-DD3B07E2FEF1 • ios • com.apple.CoreSimulator.SimRuntime.iOS-13-3 (simulator)\n\n• No issues found!\n```\n"
  },
  {
    "path": "recipes/flutter_test/how_do_i_run_a_script/echo.sh",
    "content": "#!/bin/bash\n\necho \"$1\"\n"
  },
  {
    "path": "recipes/flutter_test/how_do_i_run_a_script/lib/main.dart",
    "content": "import 'package:flutter/material.dart';\n\nvoid main() => runApp(MyApp());\n\nclass MyApp extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      home: Scaffold(\n        body: Center(\n          child: Text(\"Hello world\"),\n        ),\n      ),\n    );\n  }\n}\n"
  },
  {
    "path": "recipes/flutter_test/how_do_i_run_a_script/pubspec.yaml",
    "content": "name: ftc\ndescription: A new Flutter project.\n\nversion: 1.0.0+1\n\nenvironment:\n  sdk: \">=2.1.0 <3.0.0\"\n\ndependencies:\n  flutter:\n    sdk: flutter\n\ndev_dependencies:\n  flutter_test:\n    sdk: flutter"
  },
  {
    "path": "recipes/flutter_test/how_do_i_run_a_script/test/widget_test.dart",
    "content": "import 'package:flutter_test/flutter_test.dart';\nimport 'package:ftc/main.dart';\nimport 'dart:io';\n\nvoid main() async {\n  testWidgets(\"How do I run a script?\", (WidgetTester tester) async {\n    await tester.pumpWidget(MyApp());\n\n    // Running a script inside of flutter_test is different than with flutter_driver.\n    // With flutter_test, we need to:\n    // a) use tester.runAsync, and\n    // b) write the path of the script from the perspective of this file\n    ProcessResult result = await tester.runAsync(() async {\n      return await Process.run('../echo.sh', ['1']);\n    });\n\n    //Note: echo appends a newline to the result\n    expect(result.stdout, '1\\n');\n  });\n}\n"
  },
  {
    "path": "recipes/flutter_test/how_do_i_send_a_keyboard_action/.gitignore",
    "content": "# Miscellaneous\n*.class\n*.log\n*.pyc\n*.swp\n.DS_Store\n.atom/\n.buildlog/\n.history\n.svn/\n\n# IntelliJ related\n*.iml\n*.ipr\n*.iws\n.idea/\n\n# The .vscode folder contains launch configuration and tasks you configure in\n# VS Code which you may wish to be included in version control, so this line\n# is commented out by default.\n#.vscode/\n\n# Flutter/Dart/Pub related\n**/doc/api/\n.dart_tool/\n.flutter-plugins\n.flutter-plugins-dependencies\n.packages\n.pub-cache/\n.pub/\n/build/\n\n# Web related\nlib/generated_plugin_registrant.dart\n\n# Exceptions to above rules.\n!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages\n\n# Flutter Test Cookbook (flutter_test)\n.dart_tool/\n.metadata\n.packages\nandroid/\nios/\npubspec.lock\nftc.iml\n*.*~\ntest_driver/"
  },
  {
    "path": "recipes/flutter_test/how_do_i_send_a_keyboard_action/README.md",
    "content": "# Question\n\nHow do I send a keyboard action like `done` or `next`?\n\n# Answer\n\n## 1) Create a flutter application.\n\n```sh\nflutter create ftc\ncd ftc\n```\n\n## 2) Get dependencies\n\n```sh\nflutter packages get\n```\n\n## 3) Replace the `lib/main.dart` file\n\nReplace the `lib/main.dart` file with the following:\n\n```dart\nimport 'package:flutter/material.dart';\n\nvoid main() => runApp(MyApp());\n\nclass MyApp extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      home: Scaffold(\n        body: MyForm(),\n      ),\n    );\n  }\n}\n\nclass MyForm extends StatefulWidget {\n  @override\n  _MyFormState createState() => _MyFormState();\n}\n\nclass _MyFormState extends State<MyForm> {\n  // We are creating controllers and focus nodes for our two text fields\n  TextEditingController firstNameController;\n  FocusNode firstNameFocusNode;\n\n  TextEditingController lastNameController;\n  FocusNode lastNameFocusNode;\n\n  @override\n  void initState() {\n    super.initState();\n    firstNameController = TextEditingController();\n    firstNameFocusNode = FocusNode();\n\n    lastNameController = TextEditingController();\n    lastNameFocusNode = FocusNode();\n  }\n\n  // and we are cleaning up after ourselves by disposing the controllers and focus nodes\n  @override\n  void dispose() {\n    firstNameController.dispose();\n    firstNameFocusNode.dispose();\n\n    lastNameController.dispose();\n    lastNameFocusNode.dispose();\n    super.dispose();\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return Column(\n      children: <Widget>[\n        TextField(\n          decoration: InputDecoration(labelText: \"First name\"),\n          textInputAction: TextInputAction.next,\n          controller: firstNameController,\n          focusNode: firstNameFocusNode,\n          // When a user hits 'next' on the keyboard, it will unfocus firstName and focus lastName\n          onSubmitted: (String _firstName) {\n            firstNameFocusNode.unfocus();\n            FocusScope.of(context).requestFocus(lastNameFocusNode);\n          },\n        ),\n        TextField(\n          decoration: InputDecoration(labelText: \"Last name\"),\n          textInputAction: TextInputAction.done,\n          controller: lastNameController,\n          focusNode: lastNameFocusNode,\n          // When a user hits 'done' on the keyboard, it will unfocus lastName and then show a SnackBar with the full name\n          onSubmitted: (String _lastName) {\n            lastNameFocusNode.unfocus();\n            Scaffold.of(context).showSnackBar(SnackBar(\n              content: Text(\n                  \"Your name is: ${firstNameController.text} ${lastNameController.text}\"),\n            ));\n          },\n        ),\n      ],\n    );\n  }\n}\n```\n\n## 4) Replace the `test/widget_test.dart` file.\n\nReplace the `test/widget_test.dart` file with the following:\n\n```dart\nimport 'package:flutter/material.dart';\nimport 'package:flutter_test/flutter_test.dart';\nimport 'package:ftc/main.dart';\n\nvoid main() {\n  testWidgets(\"How do I send a keyboard action?\", (WidgetTester tester) async {\n    await tester.pumpWidget(MyApp());\n\n    // First, let's confirm we have two TextFields on the page\n    Finder firstNameFinder = find.byType(TextField).at(0);\n    Finder lastNameFinder = find.byType(TextField).at(1);\n\n    expect(firstNameFinder, findsOneWidget);\n    expect(lastNameFinder, findsOneWidget);\n\n    // Next, let's enter our first name\n    await tester.showKeyboard(firstNameFinder);\n    tester.testTextInput.enterText(\"John\");\n\n    // Tap the 'next' action in the keyboard\n    await tester.testTextInput.receiveAction(TextInputAction.next);\n\n    // This should automatically focus the last name\n    // which means we don't need to show a new keyboard with a new finder\n    tester.testTextInput.enterText(\"Doe\");\n\n    // Tap the 'done' action in the keyboard\n    await tester.testTextInput.receiveAction(TextInputAction.done);\n\n    // This should open a SnackBar with the entered name\n    await tester.pumpAndSettle();\n    expect(find.text(\"Your name is: John Doe\"), findsOneWidget);\n  });\n}\n```\n\n\n## 5) Run the flutter tests\n\n```sh\nflutter test\n```\n\n# Run tests from example code in cookbook itself\n\nIf you have cloned [flutter_test_cookbook](https://github.com/gadfly361/flutter_test_cookbook/tree/master) and simply want to run the tests from this recipe, then:\n\n```sh\nflutter create .\nflutter packages get\nflutter test\n```\n\n# Outputs when recipe was made / updated\n\n## Output of running flutter tests\n\n```sh\n$ flutter test \n00:02 +1: All tests passed!\n```\n\n## Output of running `flutter doctor -v`\n\n```sh\n$ flutter doctor -v\n[✓] Flutter (Channel stable, v1.12.13+hotfix.5, on Mac OS X 10.15.2 19C57, locale en-US)\n    • Flutter version 1.12.13+hotfix.5 at /Users/matthew/gadfly/flutter_versions/flutter_1.12.13+hotfix.5\n    • Framework revision 27321ebbad (3 months ago), 2019-12-10 18:15:01 -0800\n    • Engine revision 2994f7e1e6\n    • Dart version 2.7.0\n\n[✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)\n    • Android SDK at /Users/matthew/Library/Android/sdk\n    • Android NDK location not configured (optional; useful for native profiling support)\n    • Platform android-29, build-tools 28.0.3\n    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java\n    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)\n    • All Android licenses accepted.\n\n[✓] Xcode - develop for iOS and macOS (Xcode 11.3.1)\n    • Xcode at /Applications/Xcode.app/Contents/Developer\n    • Xcode 11.3.1, Build version 11C504\n    • CocoaPods version 1.8.4\n\n[✓] Android Studio (version 3.4)\n    • Android Studio at /Applications/Android Studio.app/Contents\n    • Flutter plugin version 35.2.1\n    • Dart plugin version 183.6270\n    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)\n\n[✓] IntelliJ IDEA Community Edition (version 2019.3.3)\n    • IntelliJ at /Applications/IntelliJ IDEA CE.app\n    • Flutter plugin version 44.0.3\n    • Dart plugin version 193.6494.35\n\n[✓] VS Code (version 1.41.1)\n    • VS Code at /Applications/Visual Studio Code.app/Contents\n    • Flutter extension version 3.4.1\n\n[!] Connected device\n    ! No devices available\n\n! Doctor found issues in 1 category.\n```\n"
  },
  {
    "path": "recipes/flutter_test/how_do_i_send_a_keyboard_action/lib/main.dart",
    "content": "import 'package:flutter/material.dart';\n\nvoid main() => runApp(MyApp());\n\nclass MyApp extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      home: Scaffold(\n        body: MyForm(),\n      ),\n    );\n  }\n}\n\nclass MyForm extends StatefulWidget {\n  @override\n  _MyFormState createState() => _MyFormState();\n}\n\nclass _MyFormState extends State<MyForm> {\n  // We are creating controllers and focus nodes for our two text fields\n  TextEditingController firstNameController;\n  FocusNode firstNameFocusNode;\n\n  TextEditingController lastNameController;\n  FocusNode lastNameFocusNode;\n\n  @override\n  void initState() {\n    super.initState();\n    firstNameController = TextEditingController();\n    firstNameFocusNode = FocusNode();\n\n    lastNameController = TextEditingController();\n    lastNameFocusNode = FocusNode();\n  }\n\n  // and we are cleaning up after ourselves by disposing the controllers and focus nodes\n  @override\n  void dispose() {\n    firstNameController.dispose();\n    firstNameFocusNode.dispose();\n\n    lastNameController.dispose();\n    lastNameFocusNode.dispose();\n    super.dispose();\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return Column(\n      children: <Widget>[\n        TextField(\n          decoration: InputDecoration(labelText: \"First name\"),\n          textInputAction: TextInputAction.next,\n          controller: firstNameController,\n          focusNode: firstNameFocusNode,\n          // When a user hits 'next' on the keyboard, it will unfocus firstName and focus lastName\n          onSubmitted: (String _firstName) {\n            firstNameFocusNode.unfocus();\n            FocusScope.of(context).requestFocus(lastNameFocusNode);\n          },\n        ),\n        TextField(\n          decoration: InputDecoration(labelText: \"Last name\"),\n          textInputAction: TextInputAction.done,\n          controller: lastNameController,\n          focusNode: lastNameFocusNode,\n          // When a user hits 'done' on the keyboard, it will unfocus lastName and then show a SnackBar with the full name\n          onSubmitted: (String _lastName) {\n            lastNameFocusNode.unfocus();\n            Scaffold.of(context).showSnackBar(SnackBar(\n              content: Text(\n                  \"Your name is: ${firstNameController.text} ${lastNameController.text}\"),\n            ));\n          },\n        ),\n      ],\n    );\n  }\n}\n"
  },
  {
    "path": "recipes/flutter_test/how_do_i_send_a_keyboard_action/pubspec.yaml",
    "content": "name: ftc\ndescription: A new Flutter project.\n\nversion: 1.0.0+1\n\nenvironment:\n  sdk: \">=2.1.0 <3.0.0\"\n\ndependencies:\n  flutter:\n    sdk: flutter\n\ndev_dependencies:\n  flutter_test:\n    sdk: flutter\n"
  },
  {
    "path": "recipes/flutter_test/how_do_i_send_a_keyboard_action/test/widget_test.dart",
    "content": "import 'package:flutter/material.dart';\nimport 'package:flutter_test/flutter_test.dart';\nimport 'package:ftc/main.dart';\n\nvoid main() {\n  testWidgets(\"How do I send a keyboard event?\", (WidgetTester tester) async {\n    await tester.pumpWidget(MyApp());\n\n    // First, let's confirm we have two TextFields on the page\n    Finder firstNameFinder = find.byType(TextField).at(0);\n    Finder lastNameFinder = find.byType(TextField).at(1);\n\n    expect(firstNameFinder, findsOneWidget);\n    expect(lastNameFinder, findsOneWidget);\n\n    // Next, let's enter our first name\n    await tester.showKeyboard(firstNameFinder);\n    tester.testTextInput.enterText(\"John\");\n\n    // Tap the 'next' action in the keyboard\n    await tester.testTextInput.receiveAction(TextInputAction.next);\n\n    // This should automatically focus the last name\n    // which means we don't need to show a new keyboard with a new finder\n    tester.testTextInput.enterText(\"Doe\");\n\n    // Tap the 'done' action in the keyboard\n    await tester.testTextInput.receiveAction(TextInputAction.done);\n\n    // This should open a SnackBar with the entered name\n    await tester.pumpAndSettle();\n    expect(find.text(\"Your name is: John Doe\"), findsOneWidget);\n  });\n}\n"
  },
  {
    "path": "recipes/flutter_test/how_do_i_test_an_animation/.gitignore",
    "content": "# Miscellaneous\n*.class\n*.log\n*.pyc\n*.swp\n.DS_Store\n.atom/\n.buildlog/\n.history\n.svn/\n\n# IntelliJ related\n*.iml\n*.ipr\n*.iws\n.idea/\n\n# The .vscode folder contains launch configuration and tasks you configure in\n# VS Code which you may wish to be included in version control, so this line\n# is commented out by default.\n#.vscode/\n\n# Flutter/Dart/Pub related\n**/doc/api/\n.dart_tool/\n.flutter-plugins\n.flutter-plugins-dependencies\n.packages\n.pub-cache/\n.pub/\n/build/\n\n# Web related\nlib/generated_plugin_registrant.dart\n\n# Exceptions to above rules.\n!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages\n\n# Flutter Test Cookbook (flutter_test)\n.dart_tool/\n.metadata\n.packages\nandroid/\nios/\npubspec.lock\nftc.iml\n*.*~\ntest_driver/"
  },
  {
    "path": "recipes/flutter_test/how_do_i_test_an_animation/README.md",
    "content": "# Question\n\nHow do I test an animation?\n\n# Answer\n\nIn this example, we will be taking a box, with a height of 0, and growing it to 100 over the course of 1000 milliseconds. Since flutter test doesn't automatically pump the widget, we can do it manually and check the box size along the way.\n\n## 1) Create a flutter application.\n\n```sh\nflutter create ftc\ncd ftc\n```\n\n## 2) Get dependencies\n\n```sh\nflutter packages get\n```\n\n## 3) Replace the `lib/main.dart` file\n\nReplace the `lib/main.dart` file with the following:\n\n```dart\nimport 'package:flutter/material.dart';\n\nvoid main() => runApp(MyApp());\n\nclass MyApp extends StatelessWidget {\n  MyApp();\n\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      home: Scaffold(\n        body: Center(\n          child: Body(),\n        ),\n      ),\n    );\n  }\n}\n\nclass Body extends StatefulWidget {\n  Body();\n\n  @override\n  _BodyState createState() => _BodyState();\n}\n\nclass _BodyState extends State<Body> with SingleTickerProviderStateMixin {\n  Animation<double> animation;\n  AnimationController controller;\n\n  @override\n  void initState() {\n    super.initState();\n    controller = AnimationController(\n      vsync: this,\n      duration: Duration(milliseconds: 1000),\n    );\n    animation = Tween<double>(begin: 0, end: 100).animate(controller);\n  }\n\n  @override\n  void dispose() {\n    controller.dispose();\n    super.dispose();\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return Column(\n      children: <Widget>[\n        RaisedButton(\n          onPressed: () {\n            controller.forward();\n          },\n          child: Text(\"Start animation\"),\n        ),\n        AnimatedBuilder(\n          animation: animation,\n          builder: (BuildContext _context, _child) {\n            return Container(\n              key: Key(\"animatedBox\"),\n              height: animation.value,\n              width: animation.value,\n              decoration: BoxDecoration(\n                border: Border.all(\n                  color: Colors.black,\n                  width: 2,\n                ),\n              ),\n            );\n          },\n        )\n      ],\n    );\n  }\n}\n```\n\n## 4) Replace the `test/widget_test.dart` file.\n\nReplace the `test/widget_test.dart` file with the following:\n\n```dart\nimport 'package:flutter/material.dart';\nimport 'package:flutter/rendering.dart';\nimport 'package:flutter_test/flutter_test.dart';\nimport 'package:ftc/main.dart';\n\nvoid main() {\n  testWidgets(\"How do I test an animation?\", (WidgetTester tester) async {\n    await tester.pumpWidget(MyApp());\n\n    Finder startAnimationFinder = find.text(\"Start animation\");\n    Finder animatedBoxFinder = find.byKey(Key(\"animatedBox\"));\n\n    expect(startAnimationFinder, findsOneWidget);\n    expect(animatedBoxFinder, findsOneWidget);\n\n    // The box starts off with a height of 0\n    RenderConstrainedBox animatedBox = tester.renderObject(animatedBoxFinder);\n    expect(animatedBox.size.height, 0);\n\n    // Once we start the animation\n    await tester.tap(startAnimationFinder);\n    await tester.pump();\n\n    // and wait 100 milliseconds\n    await tester.pump(Duration(milliseconds: 100));\n    // we expect the height to grow from 0 to 10\n    expect(animatedBox.size.height, 10);\n\n    // after another 100 milliseconds it should grow to 20\n    await tester.pump(Duration(milliseconds: 100));\n    expect(animatedBox.size.height, 20);\n\n    await tester.pump(Duration(milliseconds: 100));\n    // and then 30\n    expect(animatedBox.size.height, 30);\n\n    await tester.pump(Duration(milliseconds: 100));\n    // and then 40\n    expect(animatedBox.size.height, 40);\n\n    await tester.pump(Duration(milliseconds: 100));\n    // and then 50\n    expect(animatedBox.size.height, 50);\n\n    await tester.pump(Duration(milliseconds: 500));\n    // and then after another 500 milliseconds, the animation should be \n    // complete and be a total height of 100\n    expect(animatedBox.size.height, 100);\n  });\n}\n```\n\n\n## 5) Run the flutter tests\n\n```sh\nflutter test\n```\n\n# Run tests from example code in cookbook itself\n\nIf you have cloned [flutter_test_cookbook](https://github.com/gadfly361/flutter_test_cookbook/tree/master) and simply want to run the tests from this recipe, then:\n\n```sh\nflutter create .\nflutter packages get\nflutter test\n```\n\n# Outputs when recipe was made / updated\n\n## Output of running flutter tests\n\n```sh\n$ flutter test \n00:02 +1: All tests passed!  \n```\n\n## Output of running `flutter doctor -v`\n\n```sh\n$ flutter doctor -v\n[✓] Flutter (Channel stable, v1.12.13+hotfix.5, on Mac OS X 10.15.2 19C57, locale en-US)\n    • Flutter version 1.12.13+hotfix.5 at /Users/matthew/gadfly/flutter_versions/flutter_1.12.13+hotfix.5\n    • Framework revision 27321ebbad (3 months ago), 2019-12-10 18:15:01 -0800\n    • Engine revision 2994f7e1e6\n    • Dart version 2.7.0\n\n[✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)\n    • Android SDK at /Users/matthew/Library/Android/sdk\n    • Android NDK location not configured (optional; useful for native profiling support)\n    • Platform android-29, build-tools 28.0.3\n    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java\n    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)\n    • All Android licenses accepted.\n\n[✓] Xcode - develop for iOS and macOS (Xcode 11.3.1)\n    • Xcode at /Applications/Xcode.app/Contents/Developer\n    • Xcode 11.3.1, Build version 11C504\n    • CocoaPods version 1.8.4\n\n[✓] Android Studio (version 3.4)\n    • Android Studio at /Applications/Android Studio.app/Contents\n    • Flutter plugin version 35.2.1\n    • Dart plugin version 183.6270\n    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)\n\n[✓] IntelliJ IDEA Community Edition (version 2019.3.3)\n    • IntelliJ at /Applications/IntelliJ IDEA CE.app\n    • Flutter plugin version 44.0.3\n    • Dart plugin version 193.6494.35\n\n[✓] VS Code (version 1.41.1)\n    • VS Code at /Applications/Visual Studio Code.app/Contents\n    • Flutter extension version 3.4.1\n\n[!] Connected device\n    • Device 9C251FFBA00174 is not authorized.\n      You might need to check your device for an authorization dialog.\n\n! Doctor found issues in 1 category.\n```\n"
  },
  {
    "path": "recipes/flutter_test/how_do_i_test_an_animation/lib/main.dart",
    "content": "import 'package:flutter/material.dart';\n\nvoid main() => runApp(MyApp());\n\nclass MyApp extends StatelessWidget {\n  MyApp();\n\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      home: Scaffold(\n        body: Center(\n          child: Body(),\n        ),\n      ),\n    );\n  }\n}\n\nclass Body extends StatefulWidget {\n  Body();\n\n  @override\n  _BodyState createState() => _BodyState();\n}\n\nclass _BodyState extends State<Body> with SingleTickerProviderStateMixin {\n  Animation<double> animation;\n  AnimationController controller;\n\n  @override\n  void initState() {\n    super.initState();\n    controller = AnimationController(\n      vsync: this,\n      duration: Duration(milliseconds: 1000),\n    );\n    animation = Tween<double>(begin: 0, end: 100).animate(controller);\n  }\n\n  @override\n  void dispose() {\n    controller.dispose();\n    super.dispose();\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return Column(\n      children: <Widget>[\n        RaisedButton(\n          onPressed: () {\n            controller.forward();\n          },\n          child: Text(\"Start animation\"),\n        ),\n        AnimatedBuilder(\n          animation: animation,\n          builder: (BuildContext _context, _child) {\n            return Container(\n              key: Key(\"animatedBox\"),\n              height: animation.value,\n              width: animation.value,\n              decoration: BoxDecoration(\n                border: Border.all(\n                  color: Colors.black,\n                  width: 2,\n                ),\n              ),\n            );\n          },\n        )\n      ],\n    );\n  }\n}\n"
  },
  {
    "path": "recipes/flutter_test/how_do_i_test_an_animation/pubspec.yaml",
    "content": "name: ftc\ndescription: A new Flutter project.\n\nversion: 1.0.0+1\n\nenvironment:\n  sdk: \">=2.1.0 <3.0.0\"\n\ndependencies:\n  flutter:\n    sdk: flutter\n\ndev_dependencies:\n  flutter_test:\n    sdk: flutter\n"
  },
  {
    "path": "recipes/flutter_test/how_do_i_test_an_animation/test/widget_test.dart",
    "content": "import 'package:flutter/material.dart';\nimport 'package:flutter/rendering.dart';\nimport 'package:flutter_test/flutter_test.dart';\nimport 'package:ftc/main.dart';\n\nvoid main() {\n  testWidgets(\"How do I test an animation?\", (WidgetTester tester) async {\n    await tester.pumpWidget(MyApp());\n\n    Finder startAnimationFinder = find.text(\"Start animation\");\n    Finder animatedBoxFinder = find.byKey(Key(\"animatedBox\"));\n\n    expect(startAnimationFinder, findsOneWidget);\n    expect(animatedBoxFinder, findsOneWidget);\n\n    // The box starts off with a height of 0\n    RenderConstrainedBox animatedBox = tester.renderObject(animatedBoxFinder);\n    expect(animatedBox.size.height, 0);\n\n    // Once we start the animation\n    await tester.tap(startAnimationFinder);\n    await tester.pump();\n\n    // and wait 100 milliseconds\n    await tester.pump(Duration(milliseconds: 100));\n    // we expect the height to grow from 0 to 10\n    expect(animatedBox.size.height, 10);\n\n    // after another 100 milliseconds it should grow to 20\n    await tester.pump(Duration(milliseconds: 100));\n    expect(animatedBox.size.height, 20);\n\n    await tester.pump(Duration(milliseconds: 100));\n    // and then 30\n    expect(animatedBox.size.height, 30);\n\n    await tester.pump(Duration(milliseconds: 100));\n    // and then 40\n    expect(animatedBox.size.height, 40);\n\n    await tester.pump(Duration(milliseconds: 100));\n    // and then 50\n    expect(animatedBox.size.height, 50);\n\n    await tester.pump(Duration(milliseconds: 500));\n    // and then after another 500 milliseconds, the animation should be\n    // complete and be a total height of 100\n    expect(animatedBox.size.height, 100);\n  });\n}\n"
  },
  {
    "path": "recipes/flutter_test/how_do_i_test_an_exception/.gitignore",
    "content": "# Miscellaneous\n*.class\n*.log\n*.pyc\n*.swp\n.DS_Store\n.atom/\n.buildlog/\n.history\n.svn/\n\n# IntelliJ related\n*.iml\n*.ipr\n*.iws\n.idea/\n\n# The .vscode folder contains launch configuration and tasks you configure in\n# VS Code which you may wish to be included in version control, so this line\n# is commented out by default.\n#.vscode/\n\n# Flutter/Dart/Pub related\n**/doc/api/\n.dart_tool/\n.flutter-plugins\n.flutter-plugins-dependencies\n.packages\n.pub-cache/\n.pub/\n/build/\n\n# Web related\nlib/generated_plugin_registrant.dart\n\n# Exceptions to above rules.\n!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages\n\n# Flutter Test Cookbook (flutter_test)\n.dart_tool/\n.metadata\n.packages\nandroid/\nios/\npubspec.lock\nftc.iml\n*.*~\ntest_driver/"
  },
  {
    "path": "recipes/flutter_test/how_do_i_test_an_exception/README.md",
    "content": "# Question\n\nHow do I test an Exception?\n\n# Answer\n\n## 1) Create a flutter application.\n\n```sh\nflutter create ftc\ncd ftc\n```\n\n## 2) Get dependencies\n\n```sh\nflutter packages get\n```\n\n## 3) Replace the `lib/main.dart` file\n\nReplace the `lib/main.dart` file with the following:\n\n```dart\nimport 'package:flutter/material.dart';\n\nvoid main() => runApp(MyApp());\n\nclass MyApp extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      home: Scaffold(\n        body: Column(children: [\n          RaisedButton(\n            child: Text(\"Throw Exception\"),\n            onPressed: () {\n              throw Exception();\n            },\n          ),\n          RaisedButton(\n            child: Text(\"Throw MyCustomException\"),\n            onPressed: () {\n              throw MyCustomException();\n            },\n          ),\n        ]),\n      ),\n    );\n  }\n}\n\nclass MyCustomException implements Exception {\n  MyCustomException();\n}\n```\n\n## 4) Replace the `test/widget_test.dart` file.\n\nReplace the `test/widget_test.dart` file with the following:\n\n```dart\nimport 'package:flutter/material.dart';\nimport 'package:flutter_test/flutter_test.dart';\n\nimport 'package:ftc/main.dart';\n\nvoid main() {\n  testWidgets(\"How do I test for an exception?\", (WidgetTester tester) async {\n    await tester.pumpWidget(MyApp());\n\n    Finder exceptionButtonFinder = find.byType(RaisedButton).at(0);\n    Finder customExceptionButtonFinder = find.byType(RaisedButton).at(1);\n\n    await tester.tap(exceptionButtonFinder);\n    Exception exception = tester.takeException();\n    expect(exception, isException);\n\n    await tester.tap(customExceptionButtonFinder);\n    Exception customException = tester.takeException();\n    expect(customException, isInstanceOf<MyCustomException>());\n  });\n}\n```\n\n\n## 5) Run the flutter tests\n\n```sh\nflutter test\n```\n\n# Run tests from example code in cookbook itself\n\nIf you have cloned [flutter_test_cookbook](https://github.com/gadfly361/flutter_test_cookbook/tree/master) and simply want to run the tests from this recipe, then:\n\n```sh\nflutter create .\nflutter packages get\nflutter test\n```\n\n# Outputs when recipe was made / updated\n\n## Output of running flutter tests\n\n```sh\n$ flutter test \n00:02 +1: All tests passed!  \n```\n\n## Output of running `flutter doctor -v`\n\n```sh\n$ flutter doctor -v\n[✓] Flutter (Channel stable, v1.12.13+hotfix.5, on Mac OS X 10.15.2 19C57, locale en-US)\n    • Flutter version 1.12.13+hotfix.5 at /Users/matthew/gadfly/flutter_versions/flutter_1.12.13+hotfix.5\n    • Framework revision 27321ebbad (3 months ago), 2019-12-10 18:15:01 -0800\n    • Engine revision 2994f7e1e6\n    • Dart version 2.7.0\n\n[✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)\n    • Android SDK at /Users/matthew/Library/Android/sdk\n    • Android NDK location not configured (optional; useful for native profiling support)\n    • Platform android-29, build-tools 28.0.3\n    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java\n    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)\n    • All Android licenses accepted.\n\n[✓] Xcode - develop for iOS and macOS (Xcode 11.3.1)\n    • Xcode at /Applications/Xcode.app/Contents/Developer\n    • Xcode 11.3.1, Build version 11C504\n    • CocoaPods version 1.8.4\n\n[✓] Android Studio (version 3.4)\n    • Android Studio at /Applications/Android Studio.app/Contents\n    • Flutter plugin version 35.2.1\n    • Dart plugin version 183.6270\n    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)\n\n[✓] IntelliJ IDEA Community Edition (version 2019.3.3)\n    • IntelliJ at /Applications/IntelliJ IDEA CE.app\n    • Flutter plugin version 44.0.3\n    • Dart plugin version 193.6494.35\n\n[✓] VS Code (version 1.41.1)\n    • VS Code at /Applications/Visual Studio Code.app/Contents\n    • Flutter extension version 3.4.1\n\n[✓] Connected device (1 available)\n    • iPhone 8 • AD7A90EB-5E73-427E-B9B7-DD3B07E2FEF1 • ios • com.apple.CoreSimulator.SimRuntime.iOS-13-3 (simulator)\n\n• No issues found!\n```\n"
  },
  {
    "path": "recipes/flutter_test/how_do_i_test_an_exception/lib/main.dart",
    "content": "import 'package:flutter/material.dart';\n\nvoid main() => runApp(MyApp());\n\nclass MyApp extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      home: Scaffold(\n        body: Column(children: [\n          RaisedButton(\n            child: Text(\"Throw Exception\"),\n            onPressed: () {\n              throw Exception();\n            },\n          ),\n          RaisedButton(\n            child: Text(\"Throw MyCustomException\"),\n            onPressed: () {\n              throw MyCustomException();\n            },\n          ),\n        ]),\n      ),\n    );\n  }\n}\n\nclass MyCustomException implements Exception {\n  MyCustomException();\n}\n"
  },
  {
    "path": "recipes/flutter_test/how_do_i_test_an_exception/pubspec.yaml",
    "content": "name: ftc\ndescription: A new Flutter project.\n\nversion: 1.0.0+1\n\nenvironment:\n  sdk: \">=2.1.0 <3.0.0\"\n\ndependencies:\n  flutter:\n    sdk: flutter\n\ndev_dependencies:\n  flutter_test:\n    sdk: flutter\n"
  },
  {
    "path": "recipes/flutter_test/how_do_i_test_an_exception/test/widget_test.dart",
    "content": "import 'package:flutter/material.dart';\nimport 'package:flutter_test/flutter_test.dart';\n\nimport 'package:ftc/main.dart';\n\nvoid main() {\n  testWidgets(\"How do I test for an exception?\", (WidgetTester tester) async {\n    await tester.pumpWidget(MyApp());\n\n    Finder exceptionButtonFinder = find.byType(RaisedButton).at(0);\n    Finder customExceptionButtonFinder = find.byType(RaisedButton).at(1);\n\n    await tester.tap(exceptionButtonFinder);\n    Exception exception = tester.takeException();\n    expect(exception, isException);\n\n    await tester.tap(customExceptionButtonFinder);\n    Exception customException = tester.takeException();\n    expect(customException, isInstanceOf<MyCustomException>());\n  });\n}\n"
  },
  {
    "path": "recipes/flutter_test/how_do_i_test_routes/.gitignore",
    "content": "# Miscellaneous\n*.class\n*.log\n*.pyc\n*.swp\n.DS_Store\n.atom/\n.buildlog/\n.history\n.svn/\n\n# IntelliJ related\n*.iml\n*.ipr\n*.iws\n.idea/\n\n# The .vscode folder contains launch configuration and tasks you configure in\n# VS Code which you may wish to be included in version control, so this line\n# is commented out by default.\n#.vscode/\n\n# Flutter/Dart/Pub related\n**/doc/api/\n.dart_tool/\n.flutter-plugins\n.flutter-plugins-dependencies\n.packages\n.pub-cache/\n.pub/\n/build/\n\n# Web related\nlib/generated_plugin_registrant.dart\n\n# Exceptions to above rules.\n!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages\n\n# Flutter Test Cookbook (flutter_test)\n.dart_tool/\n.metadata\n.packages\nandroid/\nios/\npubspec.lock\nftc.iml\n*.*~\ntest_driver/"
  },
  {
    "path": "recipes/flutter_test/how_do_i_test_routes/README.md",
    "content": "# Question\n\nHow do I test routes?\n\n# Answer\n\n## 1) Create a flutter application.\n\n```sh\nflutter create ftc\ncd ftc\n```\n\n## 2) Get dependencies\n\n```sh\nflutter packages get\n```\n\n## 3) Replace the `lib/main.dart` file\n\nReplace the `lib/main.dart` file with the following:\n\n```dart\nimport 'package:flutter/material.dart';\n\nvoid main() => runApp(MyApp());\n\nclass MyApp extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      initialRoute: \"/page1\",\n      routes: {\n        \"/page1\": (BuildContext context) => Page1(),\n        \"/page2\": (BuildContext context) => Page2(),\n        \"/page3\": (BuildContext context) => Page3(),\n      },\n    );\n  }\n}\n\nclass Page1 extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      appBar: AppBar(\n        title: Text(\"Page 1\"),\n      ),\n      body: Column(\n        children: <Widget>[\n          RaisedButton(\n            onPressed: () => Navigator.of(context).pushNamed(\"/page2\"),\n            child: Text(\"pushNamed to page2\"),\n          ),\n          RaisedButton(\n            onPressed: () =>\n                Navigator.of(context).pushReplacementNamed(\"/page2\"),\n            child: Text(\"pushReplacementNamed to page2\"),\n          )\n        ],\n      ),\n    );\n  }\n}\n\nclass Page2 extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      appBar: AppBar(\n        title: Text(\"Page 2\"),\n      ),\n      body: Column(\n        children: <Widget>[\n          RaisedButton(\n            onPressed: () => Navigator.of(context).pushNamed(\"/page3\"),\n            child: Text(\"pushNamed to page3\"),\n          ),\n        ],\n      ),\n    );\n  }\n}\n\nclass Page3 extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      appBar: AppBar(\n        title: Text(\"Page 3\"),\n      ),\n      body: Column(\n        children: <Widget>[\n          RaisedButton(\n            onPressed: () => Navigator.of(context).pop(),\n            child: Text(\"pop\"),\n          ),\n          RaisedButton(\n            onPressed: () => Navigator.of(context).popUntil((Route route) {\n              return route.settings.name == \"/page1\";\n            }),\n            child: Text(\"popUntil page1\"),\n          )\n        ],\n      ),\n    );\n  }\n}\n```\n\n## 4) Replace the `test/widget_test.dart` file.\n\nReplace the `test/widget_test.dart` file with the following:\n\n```dart\nimport 'package:flutter_test/flutter_test.dart';\nimport 'package:ftc/main.dart';\n\nvoid main() {\n  testWidgets(\"How do I test routes?\", (WidgetTester tester) async {\n    await tester.pumpWidget(MyApp());\n\n    // First, let's make sure we are on /page1\n    expect(find.byType(Page1), findsOneWidget);\n    expect(find.byType(Page2), findsNothing);\n    expect(find.byType(Page3), findsNothing);\n\n    //\n    // Next, let's navigate to /page2\n    //\n    await tester.tap(find.text(\"pushNamed to page2\"));\n    await tester.pumpAndSettle();\n\n    // Confirm we are on /page2\n    expect(find.byType(Page1), findsNothing);\n    expect(find.byType(Page2), findsOneWidget);\n    expect(find.byType(Page3), findsNothing);\n\n    // However, since routes are in a stack, and we pushed page2 on top of page1,\n    // we should confirm that page1 still exists.\n    // We can do this by setting `skipOffstage` to false.\n    expect(find.byType(Page1, skipOffstage: false), findsOneWidget);\n    expect(find.byType(Page2, skipOffstage: false), findsOneWidget);\n    expect(find.byType(Page3, skipOffstage: false), findsNothing);\n\n    //\n    // Next, let's navigate to /page3\n    //\n\n    await tester.tap(find.text(\"pushNamed to page3\"));\n    await tester.pumpAndSettle();\n\n    // Confirm we are on /page3\n    expect(find.byType(Page1), findsNothing);\n    expect(find.byType(Page2), findsNothing);\n    expect(find.byType(Page3), findsOneWidget);\n    expect(find.byType(Page1, skipOffstage: false), findsOneWidget);\n    expect(find.byType(Page2, skipOffstage: false), findsOneWidget);\n    expect(find.byType(Page3, skipOffstage: false), findsOneWidget);\n\n    //\n    // Next, let's navigate back to /page2\n    //\n\n    await tester.tap(find.text(\"pop\"));\n    await tester.pumpAndSettle();\n\n    // confirm we are on /page2\n    expect(find.byType(Page1), findsNothing);\n    expect(find.byType(Page2), findsOneWidget);\n    expect(find.byType(Page3), findsNothing);\n    expect(find.byType(Page1, skipOffstage: false), findsOneWidget);\n    expect(find.byType(Page2, skipOffstage: false), findsOneWidget);\n    expect(find.byType(Page3, skipOffstage: false), findsNothing);\n\n    //\n    // Finally, let's navigate back to /page3 and then popUntil we are on /page1\n    //\n\n    await tester.tap(find.text(\"pushNamed to page3\"));\n    await tester.pumpAndSettle();\n\n    // Confirm we are on /page3\n    expect(find.byType(Page1), findsNothing);\n    expect(find.byType(Page2), findsNothing);\n    expect(find.byType(Page3), findsOneWidget);\n    expect(find.byType(Page1, skipOffstage: false), findsOneWidget);\n    expect(find.byType(Page2, skipOffstage: false), findsOneWidget);\n    expect(find.byType(Page3, skipOffstage: false), findsOneWidget);\n\n    await tester.tap(find.text(\"popUntil page1\"));\n    await tester.pumpAndSettle();\n\n    // Confirm we are on /page1\n    expect(find.byType(Page1), findsOneWidget);\n    expect(find.byType(Page2), findsNothing);\n    expect(find.byType(Page3), findsNothing);\n    expect(find.byType(Page1, skipOffstage: false), findsOneWidget);\n    expect(find.byType(Page2, skipOffstage: false), findsNothing);\n    expect(find.byType(Page3, skipOffstage: false), findsNothing);\n  });\n}\n```\n\n\n## 5) Run the flutter tests\n\n```sh\nflutter test\n```\n\n# Run tests from example code in cookbook itself\n\nIf you have cloned [flutter_test_cookbook](https://github.com/gadfly361/flutter_test_cookbook/tree/master) and simply want to run the tests from this recipe, then:\n\n```sh\nflutter create .\nflutter packages get\nflutter test\n```\n\n# Outputs when recipe was made / updated\n\n## Output of running flutter tests\n\n```sh\n$ flutter test \n00:02 +1: All tests passed!\n```\n\n## Output of running `flutter doctor -v`\n\n```sh\n$ flutter doctor -v\n[✓] Flutter (Channel stable, v1.12.13+hotfix.5, on Mac OS X 10.15.2 19C57, locale en-US)\n    • Flutter version 1.12.13+hotfix.5 at /Users/matthew/gadfly/flutter_versions/flutter_1.12.13+hotfix.5\n    • Framework revision 27321ebbad (3 months ago), 2019-12-10 18:15:01 -0800\n    • Engine revision 2994f7e1e6\n    • Dart version 2.7.0\n\n[✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)\n    • Android SDK at /Users/matthew/Library/Android/sdk\n    • Android NDK location not configured (optional; useful for native profiling support)\n    • Platform android-29, build-tools 28.0.3\n    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java\n    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)\n    • All Android licenses accepted.\n\n[✓] Xcode - develop for iOS and macOS (Xcode 11.3.1)\n    • Xcode at /Applications/Xcode.app/Contents/Developer\n    • Xcode 11.3.1, Build version 11C504\n    • CocoaPods version 1.8.4\n\n[✓] Android Studio (version 3.4)\n    • Android Studio at /Applications/Android Studio.app/Contents\n    • Flutter plugin version 35.2.1\n    • Dart plugin version 183.6270\n    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)\n\n[✓] IntelliJ IDEA Community Edition (version 2019.3.3)\n    • IntelliJ at /Applications/IntelliJ IDEA CE.app\n    • Flutter plugin version 44.0.3\n    • Dart plugin version 193.6494.35\n\n[✓] VS Code (version 1.41.1)\n    • VS Code at /Applications/Visual Studio Code.app/Contents\n    • Flutter extension version 3.4.1\n\n[✓] Connected device (1 available)\n    • iPhone 8 • AD7A90EB-5E73-427E-B9B7-DD3B07E2FEF1 • ios • com.apple.CoreSimulator.SimRuntime.iOS-13-3 (simulator)\n\n• No issues found!\n```\n"
  },
  {
    "path": "recipes/flutter_test/how_do_i_test_routes/lib/main.dart",
    "content": "import 'package:flutter/material.dart';\n\nvoid main() => runApp(MyApp());\n\nclass MyApp extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      initialRoute: \"/page1\",\n      routes: {\n        \"/page1\": (BuildContext context) => Page1(),\n        \"/page2\": (BuildContext context) => Page2(),\n        \"/page3\": (BuildContext context) => Page3(),\n      },\n    );\n  }\n}\n\nclass Page1 extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      appBar: AppBar(\n        title: Text(\"Page 1\"),\n      ),\n      body: Column(\n        children: <Widget>[\n          RaisedButton(\n            onPressed: () => Navigator.of(context).pushNamed(\"/page2\"),\n            child: Text(\"pushNamed to page2\"),\n          ),\n          RaisedButton(\n            onPressed: () =>\n                Navigator.of(context).pushReplacementNamed(\"/page2\"),\n            child: Text(\"pushReplacementNamed to page2\"),\n          )\n        ],\n      ),\n    );\n  }\n}\n\nclass Page2 extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      appBar: AppBar(\n        title: Text(\"Page 2\"),\n      ),\n      body: Column(\n        children: <Widget>[\n          RaisedButton(\n            onPressed: () => Navigator.of(context).pushNamed(\"/page3\"),\n            child: Text(\"pushNamed to page3\"),\n          ),\n        ],\n      ),\n    );\n  }\n}\n\nclass Page3 extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      appBar: AppBar(\n        title: Text(\"Page 3\"),\n      ),\n      body: Column(\n        children: <Widget>[\n          RaisedButton(\n            onPressed: () => Navigator.of(context).pop(),\n            child: Text(\"pop\"),\n          ),\n          RaisedButton(\n            onPressed: () => Navigator.of(context).popUntil((Route route) {\n              return route.settings.name == \"/page1\";\n            }),\n            child: Text(\"popUntil page1\"),\n          )\n        ],\n      ),\n    );\n  }\n}\n"
  },
  {
    "path": "recipes/flutter_test/how_do_i_test_routes/pubspec.yaml",
    "content": "name: ftc\ndescription: A new Flutter project.\n\nversion: 1.0.0+1\n\nenvironment:\n  sdk: \">=2.1.0 <3.0.0\"\n\ndependencies:\n  flutter:\n    sdk: flutter\n\ndev_dependencies:\n  flutter_test:\n    sdk: flutter\n"
  },
  {
    "path": "recipes/flutter_test/how_do_i_test_routes/test/widget_test.dart",
    "content": "import 'package:flutter_test/flutter_test.dart';\nimport 'package:ftc/main.dart';\n\nvoid main() {\n  testWidgets(\"How do I test routes?\", (WidgetTester tester) async {\n    await tester.pumpWidget(MyApp());\n\n    // First, let's make sure we are on /page1\n    expect(find.byType(Page1), findsOneWidget);\n    expect(find.byType(Page2), findsNothing);\n    expect(find.byType(Page3), findsNothing);\n\n    //\n    // Next, let's navigate to /page2\n    //\n    await tester.tap(find.text(\"pushNamed to page2\"));\n    await tester.pumpAndSettle();\n\n    // Confirm we are on /page2\n    expect(find.byType(Page1), findsNothing);\n    expect(find.byType(Page2), findsOneWidget);\n    expect(find.byType(Page3), findsNothing);\n\n    // However, since routes are in a stack, and we pushed page2 on top of page1,\n    // we should confirm that page1 still exists.\n    // We can do this by setting `skipOffstage` to false.\n    expect(find.byType(Page1, skipOffstage: false), findsOneWidget);\n    expect(find.byType(Page2, skipOffstage: false), findsOneWidget);\n    expect(find.byType(Page3, skipOffstage: false), findsNothing);\n\n    //\n    // Next, let's navigate to /page3\n    //\n\n    await tester.tap(find.text(\"pushNamed to page3\"));\n    await tester.pumpAndSettle();\n\n    // Confirm we are on /page3\n    expect(find.byType(Page1), findsNothing);\n    expect(find.byType(Page2), findsNothing);\n    expect(find.byType(Page3), findsOneWidget);\n    expect(find.byType(Page1, skipOffstage: false), findsOneWidget);\n    expect(find.byType(Page2, skipOffstage: false), findsOneWidget);\n    expect(find.byType(Page3, skipOffstage: false), findsOneWidget);\n\n    //\n    // Next, let's navigate back to /page2\n    //\n\n    await tester.tap(find.text(\"pop\"));\n    await tester.pumpAndSettle();\n\n    // confirm we are on /page2\n    expect(find.byType(Page1), findsNothing);\n    expect(find.byType(Page2), findsOneWidget);\n    expect(find.byType(Page3), findsNothing);\n    expect(find.byType(Page1, skipOffstage: false), findsOneWidget);\n    expect(find.byType(Page2, skipOffstage: false), findsOneWidget);\n    expect(find.byType(Page3, skipOffstage: false), findsNothing);\n\n    //\n    // Finally, let's navigate back to /page3 and then popUntil we are on /page1\n    //\n\n    await tester.tap(find.text(\"pushNamed to page3\"));\n    await tester.pumpAndSettle();\n\n    // Confirm we are on /page3\n    expect(find.byType(Page1), findsNothing);\n    expect(find.byType(Page2), findsNothing);\n    expect(find.byType(Page3), findsOneWidget);\n    expect(find.byType(Page1, skipOffstage: false), findsOneWidget);\n    expect(find.byType(Page2, skipOffstage: false), findsOneWidget);\n    expect(find.byType(Page3, skipOffstage: false), findsOneWidget);\n\n    await tester.tap(find.text(\"popUntil page1\"));\n    await tester.pumpAndSettle();\n\n    // Confirm we are on /page1\n    expect(find.byType(Page1), findsOneWidget);\n    expect(find.byType(Page2), findsNothing);\n    expect(find.byType(Page3), findsNothing);\n    expect(find.byType(Page1, skipOffstage: false), findsOneWidget);\n    expect(find.byType(Page2, skipOffstage: false), findsNothing);\n    expect(find.byType(Page3, skipOffstage: false), findsNothing);\n  });\n}\n"
  },
  {
    "path": "recipes/flutter_test/what_if_i_need_build_context/.gitignore",
    "content": "# Miscellaneous\n*.class\n*.log\n*.pyc\n*.swp\n.DS_Store\n.atom/\n.buildlog/\n.history\n.svn/\n\n# IntelliJ related\n*.iml\n*.ipr\n*.iws\n.idea/\n\n# The .vscode folder contains launch configuration and tasks you configure in\n# VS Code which you may wish to be included in version control, so this line\n# is commented out by default.\n#.vscode/\n\n# Flutter/Dart/Pub related\n**/doc/api/\n.dart_tool/\n.flutter-plugins\n.flutter-plugins-dependencies\n.packages\n.pub-cache/\n.pub/\n/build/\n\n# Web related\nlib/generated_plugin_registrant.dart\n\n# Exceptions to above rules.\n!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages\n\n# Flutter Test Cookbook (flutter_test)\n.dart_tool/\n.metadata\n.packages\nandroid/\nios/\npubspec.lock\nftc.iml\n*.*~\ntest_driver/"
  },
  {
    "path": "recipes/flutter_test/what_if_i_need_build_context/README.md",
    "content": "# Question\n\nWhat do I do if I need a [BuildContext](https://api.flutter.dev/flutter/widgets/BuildContext-class.html)?\n\n# Answer\n\nThere are several reasons we might _want_ to use a BuildContext in our tests (it is a matter of opinion if we actually should).\n\nThere are two main methods to get a BuildContext when using flutter_test.\n\na) Finding an [Element](https://api.flutter.dev/flutter/widgets/Element-class.html) and taking advantage of the fact that [an Element can be used as a BuildContext](https://www.reddit.com/r/Flutter/comments/bcmj70/please_tell_me_simply_what_is_context_and_build/eldf63d?utm_source=share&utm_medium=web2x)\n\nb) Using a [GlobalKey](https://api.flutter.dev/flutter/widgets/GlobalKey-class.html)\n\nFor the sake of this recipe, we are going to use a _contrived_ example.  We have two pages, Page1 and Page2, and we want to navigate between them in our tests using a [Navigator](https://api.flutter.dev/flutter/dart-html/Navigator-class.html).\n\n## 1) Create a flutter application.\n\n```sh\nflutter create ftc\ncd ftc\n```\n\n## 2) Get dependencies\n\n```sh\nflutter packages get\n```\n\n## 3) Replace the `lib/main.dart` file\n\nReplace the `lib/main.dart` file with the following:\n\n```dart\nimport 'package:flutter/material.dart';\n\nvoid main() => runApp(MyApp());\n\nclass MyApp extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      initialRoute: \"/page1\",\n      routes: {\n        \"/page1\": (BuildContext context) => Page1(),\n        \"/page2\": (BuildContext context) => Page2(),\n      },\n    );\n  }\n}\n\nclass Page1 extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      body: Center(child: Text(\"Page 1\")),\n    );\n  }\n}\n\nclass Page2 extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      body: Center(child: Text(\"Page 2\")),\n    );\n  }\n}\n```\n\n## 4) Replace the `test/widget_test.dart` file.\n\nReplace the `test/widget_test.dart` file with the following:\n\n```dart\nimport 'package:flutter/material.dart';\nimport 'package:flutter_test/flutter_test.dart';\n\nimport 'package:ftc/main.dart';\n\nvoid main() {\n  testWidgets(\"What if I need a build context?\", (WidgetTester tester) async {\n    await tester.pumpWidget(MyApp());\n    Finder page1Finder = find.byType(Page1);\n    Finder page2Finder = find.byType(Page2);\n\n    // Since the initial route was for /page1\n    // we expect to see a [Page1] widget and not a [Page2] widget\n    expect(page1Finder, findsOneWidget);\n    expect(page2Finder, findsNothing);\n\n    //\n    // Method a)\n    //\n\n    // get [BuildContext] from an element\n    BuildContext page1BuildContext = tester.element(page1Finder);\n\n    // find the closest [Navigator] (which is made available because of [MaterialApp])\n    // and pushNamed to /page2\n    Navigator.of(page1BuildContext).pushNamed(\"/page2\");\n\n    // Note, since we are using a [MaterialApp] and its named routes use the [MaterialPageRoute],\n    // there is a transition of 300 ms\n    // https://github.com/flutter/flutter/blob/e58dc16d7bec7199190f1408667e24e38328cc3b/packages/flutter/lib/src/material/page.dart#L61\n    // ... so we will need to pump until that transition has settled\n    await tester.pumpAndSettle();\n\n    // We now expect to be on [Page2]\n    expect(page1Finder, findsNothing);\n    expect(page2Finder, findsOneWidget);\n\n    //\n    // Method b)\n    //\n\n    // get [BuildContext] from a [GlobalKey]\n    BuildContext page2BuildContext = page2ScaffoldKey.currentContext;\n\n    // Let's navigate back to [Page1]\n    Navigator.of(page2BuildContext).pushNamed(\"/page1\");\n    await tester.pumpAndSettle();\n\n    // We now expect to be on [Page1] again\n    expect(page1Finder, findsOneWidget);\n    expect(page2Finder, findsNothing);\n  });\n}\n```\n\n\n## 5) Run the flutter tests\n\n```sh\nflutter test\n```\n\n# Run tests from example code in cookbook itself\n\nIf you have cloned [flutter_test_cookbook](https://github.com/gadfly361/flutter_test_cookbook/tree/master) and simply want to run the tests from this recipe, then:\n\n```sh\nflutter create .\nflutter packages get\nflutter test\n```\n\n# Outputs when recipe was made / updated\n\n## Output of running flutter tests\n\n```sh\n$ flutter test \n00:02 +1: All tests passed!\n```\n\n## Output of running `flutter doctor -v`\n\n```sh\n$ flutter doctor -v\n[✓] Flutter (Channel stable, v1.12.13+hotfix.5, on Mac OS X 10.15.2 19C57, locale en-US)\n    • Flutter version 1.12.13+hotfix.5 at /Users/matthew/gadfly/flutter_versions/flutter_1.12.13+hotfix.5\n    • Framework revision 27321ebbad (3 months ago), 2019-12-10 18:15:01 -0800\n    • Engine revision 2994f7e1e6\n    • Dart version 2.7.0\n\n[✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)\n    • Android SDK at /Users/matthew/Library/Android/sdk\n    • Android NDK location not configured (optional; useful for native profiling support)\n    • Platform android-29, build-tools 28.0.3\n    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java\n    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)\n    • All Android licenses accepted.\n\n[✓] Xcode - develop for iOS and macOS (Xcode 11.3.1)\n    • Xcode at /Applications/Xcode.app/Contents/Developer\n    • Xcode 11.3.1, Build version 11C504\n    • CocoaPods version 1.8.4\n\n[✓] Android Studio (version 3.4)\n    • Android Studio at /Applications/Android Studio.app/Contents\n    • Flutter plugin version 35.2.1\n    • Dart plugin version 183.6270\n    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)\n\n[✓] IntelliJ IDEA Community Edition (version 2019.3.3)\n    • IntelliJ at /Applications/IntelliJ IDEA CE.app\n    • Flutter plugin version 44.0.3\n    • Dart plugin version 193.6494.35\n\n[✓] VS Code (version 1.41.1)\n    • VS Code at /Applications/Visual Studio Code.app/Contents\n    • Flutter extension version 3.4.1\n\n[!] Connected device\n    ! No devices available\n\n! Doctor found issues in 1 category.\n```\n"
  },
  {
    "path": "recipes/flutter_test/what_if_i_need_build_context/lib/main.dart",
    "content": "import 'package:flutter/material.dart';\n\nvoid main() => runApp(MyApp());\n\nclass MyApp extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      initialRoute: \"/page1\",\n      routes: {\n        \"/page1\": (BuildContext context) => Page1(),\n        \"/page2\": (BuildContext context) => Page2(),\n      },\n    );\n  }\n}\n\nclass Page1 extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      body: Center(child: Text(\"Page 1\")),\n    );\n  }\n}\n\nGlobalKey<ScaffoldState> page2ScaffoldKey = GlobalKey<ScaffoldState>();\n\nclass Page2 extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      key: page2ScaffoldKey,\n      body: Center(child: Text(\"Page 2\")),\n    );\n  }\n}\n"
  },
  {
    "path": "recipes/flutter_test/what_if_i_need_build_context/pubspec.yaml",
    "content": "name: ftc\ndescription: A new Flutter project.\n\nversion: 1.0.0+1\n\nenvironment:\n  sdk: \">=2.1.0 <3.0.0\"\n\ndependencies:\n  flutter:\n    sdk: flutter\n\ndev_dependencies:\n  flutter_test:\n    sdk: flutter\n"
  },
  {
    "path": "recipes/flutter_test/what_if_i_need_build_context/test/widget_test.dart",
    "content": "import 'package:flutter/material.dart';\nimport 'package:flutter_test/flutter_test.dart';\n\nimport 'package:ftc/main.dart';\n\nvoid main() {\n  testWidgets(\"What if I need a build context?\", (WidgetTester tester) async {\n    await tester.pumpWidget(MyApp());\n    Finder page1Finder = find.byType(Page1);\n    Finder page2Finder = find.byType(Page2);\n\n    // Since the initial route was for /page1\n    // we expect to see a [Page1] widget and not a [Page2] widget\n    expect(page1Finder, findsOneWidget);\n    expect(page2Finder, findsNothing);\n\n    //\n    // Method a)\n    //\n\n    // get [BuildContext] from an element\n    BuildContext page1BuildContext = tester.element(page1Finder);\n\n    // find the closest [Navigator] (which is made available because of [MaterialApp])\n    // and pushNamed to /page2\n    Navigator.of(page1BuildContext).pushNamed(\"/page2\");\n\n    // Note, since we are using a [MaterialApp] and its named routes use the [MaterialPageRoute],\n    // there is a transition of 300 ms\n    // https://github.com/flutter/flutter/blob/e58dc16d7bec7199190f1408667e24e38328cc3b/packages/flutter/lib/src/material/page.dart#L61\n    // ... so we will need to pump until that transition has settled\n    await tester.pumpAndSettle();\n\n    // We now expect to be on [Page2]\n    expect(page1Finder, findsNothing);\n    expect(page2Finder, findsOneWidget);\n\n    //\n    // Method b)\n    //\n\n    // get [BuildContext] from a [GlobalKey]\n    BuildContext page2BuildContext = page2ScaffoldKey.currentContext;\n\n    // Let's navigate back to [Page1]\n    Navigator.of(page2BuildContext).pushNamed(\"/page1\");\n    await tester.pumpAndSettle();\n\n    // We now expect to be on [Page1] again\n    expect(page1Finder, findsOneWidget);\n    expect(page2Finder, findsNothing);\n  });\n}\n"
  }
]