[flutter_driver] Fix flutter driver to enable integ tests

- flutter driver was connecting to moduleContext but never using it
- moved TestRunner.fidl connection to the test file since it needs
  to be exposed to test author for future use.
- Changed IntentHandler and Intent to allow null action intents.

This makes _extension_wrapper use async bindings and the new sdk.

Test:
fx shell /pkgfs/packages/topaz_modular_integration_tests/0/bin/run_topaz_modular_integration_tests.sh slider_mod_tests

DX-625 #done

Change-Id: Id7b0e69075cbd0261e07996f438ed130a833159a
diff --git a/examples/modular/slider_mod/BUILD.gn b/examples/modular/slider_mod/BUILD.gn
index 97f43e5..543a602 100644
--- a/examples/modular/slider_mod/BUILD.gn
+++ b/examples/modular/slider_mod/BUILD.gn
@@ -13,7 +13,7 @@
 
   # This creates a flutter_driver enabled binary that will enable extensions for
   # testing when run in an environment along with TestRunner.
-  # flutter_driver_extendable = true # TODO uncomment this test after DX-625 is fixed
+  flutter_driver_extendable = true
 
   sources = [
     "src/widgets/slider_scaffold.dart",
diff --git a/examples/modular/slider_mod/lib/main.dart b/examples/modular/slider_mod/lib/main.dart
index f360b2a..0bd9792 100644
--- a/examples/modular/slider_mod/lib/main.dart
+++ b/examples/modular/slider_mod/lib/main.dart
@@ -2,12 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'package:fuchsia_logger/logger.dart';
 import 'package:fuchsia_modular/module.dart';
-
 import 'src/handlers/root_intent_handler.dart';
 
 void main() {
-  setupLogger(name: 'slider_mod');
   Module().registerIntentHandler(RootIntentHandler());
 }
diff --git a/examples/modular/slider_mod/meta/slider_mod.cmx b/examples/modular/slider_mod/meta/slider_mod.cmx
index 210f362..edc5609 100644
--- a/examples/modular/slider_mod/meta/slider_mod.cmx
+++ b/examples/modular/slider_mod/meta/slider_mod.cmx
@@ -13,7 +13,8 @@
             "fuchsia.ui.policy.Presenter",
             "fuchsia.modular.Clipboard",
             "fuchsia.modular.ComponentContext",
-            "fuchsia.modular.ModuleContext"
+            "fuchsia.modular.ModuleContext",
+            "fuchsia.testing.runner.TestRunner"
         ]
     }
 }
diff --git a/examples/modular/slider_mod/test/slider_mod_widget_test.dart b/examples/modular/slider_mod/test/slider_mod_widget_test.dart
index d171a2a..226f756 100644
--- a/examples/modular/slider_mod/test/slider_mod_widget_test.dart
+++ b/examples/modular/slider_mod/test/slider_mod_widget_test.dart
@@ -4,11 +4,13 @@
 
 import 'package:flutter_driver/flutter_driver.dart';
 import 'package:fuchsia_remote_debug_protocol/logging.dart';
+import 'package:fidl_fuchsia_testing_runner/fidl_async.dart';
+import 'package:fuchsia/services.dart';
 import 'package:test/test.dart';
 
 void main() {
   FlutterDriver driver;
-
+  TestRunnerProxy testRunner;
   // The following boilerplate is a one time setup required to make
   // flutter_driver work in Fuchsia.
   //
@@ -16,29 +18,37 @@
   // instance of the Dart VM, and spawns an Isolate (isolated Dart execution
   // context) containing your module.
   setUpAll(() async {
+    // Connect to the fuchsia test runner
+    testRunner = new TestRunnerProxy();
+    connectToEnvironmentService(testRunner);
+
     // The mod under test
-    // const Pattern isolatePattern = 'slider_mod';
+    const Pattern isolatePattern = 'slider_mod';
     Logger.globalLevel = LoggingLevel.all;
     // Occasionally this will crash if this delay isn't here.
     await new Future<Null>.delayed(const Duration(milliseconds: 500));
     // Creates an object you can use to search for your mod on the machine
-    // driver = await FlutterDriver.connect(
-    //     fuchsiaModuleTarget: isolatePattern,
-    //     printCommunication: true,
-    //     logCommunicationToFile: false);
+    driver = await FlutterDriver.connect(
+        fuchsiaModuleTarget: isolatePattern,
+        printCommunication: true,
+        logCommunicationToFile: false);
   });
 
   tearDownAll(() async {
     await driver?.close();
+    // Must be invoked before closing the connection to this interface;
+    // otherwise the TestRunner service will assume that the connection broke
+    // due to the test crashing.
+    await testRunner.done();
   });
 
   test(
       'Verify the agent is connected and replies with the correct Fibonacci '
       'result', () async {
-    print('hello world!');
+    print('tapping on Calc Fibonacci button');
     await driver.tap(find.text('Calc Fibonacci'));
-    print('after tap');
+    print('verifying the result');
     await driver.waitFor(find.text('Result: 2'));
-    // TODO add the rest of the test here
-  }, skip: 're-enable after DX-625 is fixed');
+    print('test is finished successfully');
+  });
 }
diff --git a/public/dart/fuchsia_modular/lib/src/module/intent.dart b/public/dart/fuchsia_modular/lib/src/module/intent.dart
index f3d1b8f..029364c 100644
--- a/public/dart/fuchsia_modular/lib/src/module/intent.dart
+++ b/public/dart/fuchsia_modular/lib/src/module/intent.dart
@@ -58,8 +58,7 @@
   Intent({
     @required String action,
     String handler,
-  })  : assert(action != null),
-        super(
+  }) : super(
           action: action,
           handler: handler,
           parameters: [],
diff --git a/public/dart/fuchsia_modular/lib/src/module/internal/_fidl_transformers.dart b/public/dart/fuchsia_modular/lib/src/module/internal/_fidl_transformers.dart
index 7225dd5..b68c62b 100644
--- a/public/dart/fuchsia_modular/lib/src/module/internal/_fidl_transformers.dart
+++ b/public/dart/fuchsia_modular/lib/src/module/internal/_fidl_transformers.dart
@@ -29,18 +29,10 @@
     throw Exception('fidlIntent must not be null in convertFidlIntentToIntent');
   }
 
-  Intent intent;
-  if (fidlIntent.action != null) {
-    intent = Intent(
-      action: fidlIntent.action,
-      handler: fidlIntent.handler,
-    );
-  } else {
-    throw ModuleStateException(
-        'Unable to convert Intent. Intents must have a valid action. '
-        'Ensure that the intent you are trying to convert has a '
-        'valid action before proceeding.');
-  }
+  Intent intent = Intent(
+    action: fidlIntent.action,
+    handler: fidlIntent.handler,
+  );
 
   // We shouldn't have null fidl intent parameters but in the case that we
   // do we avoid adding them as it will cause a crash.
diff --git a/runtime/flutter_runner/build/gen_debug_wrapper_main.py b/runtime/flutter_runner/build/gen_debug_wrapper_main.py
index 1c1cd2f..5526d85 100755
--- a/runtime/flutter_runner/build/gen_debug_wrapper_main.py
+++ b/runtime/flutter_runner/build/gen_debug_wrapper_main.py
@@ -29,56 +29,45 @@
   outfile.write('''
 
 
-// ignore_for_file: directives_ordering
 // ignore_for_file: avoid_relative_lib_imports
-// ignore_for_file: unawaited_futures
 import 'dart:async';
 
-import 'package:fidl/fidl.dart';
-
-import 'package:fidl_fuchsia_sys/fidl.dart';
-import 'package:fidl_fuchsia_testing_runner/fidl.dart';
+import 'package:fidl_fuchsia_testing_runner/fidl_async.dart';
+import 'package:fuchsia/services.dart';
 import 'package:flutter_driver/driver_extension.dart';
-import 'package:lib.app.dart/app.dart';
-import 'package:lib.module.dart/module.dart';
 ''')
   outfile.write("import '%s' as flutter_app_main;\n" % args.main_dart)
   outfile.write('''
 void main(List<String> args) async {
-
   assert(await (() async {
-    final StartupContext startupContext = new StartupContext.fromStartupInfo();
-    final ServiceProviderProxy envServices = startupContext.environmentServices;
-    final TestRunnerProxy testRunner = new TestRunnerProxy();
-    final ModuleContextClient moduleContext = new ModuleContextClient();
-    connectToService(envServices, moduleContext.proxy.ctrl);
-    try {
-      connectToService(envServices, testRunner.ctrl);
-    } on Exception catch (e) {
-      // TODO(awdavies): Use the logger instead.
-      print(e.toString());
-    }
-    final Completer<Null> completer = new Completer<Null>();
-    testRunner.ctrl.error.then((ProxyError err) {
-      if (!completer.isCompleted) {
-        completer.completeError(err);
-      }
-    });
-    testRunner.done(completer.complete);
-    await completer.future.timeout(
-        const Duration(seconds: 5)).then((_) {
+    // TODO(awdavies): Use the logger instead.
+    print('Overriding app main method because flutter_driver_extendable '
+        'is enabled in the build file');
 
+    // TODO(DX-634): don't reply on testRunner if possible
+    final TestRunnerProxy testRunner = TestRunnerProxy();
+    connectToEnvironmentService(testRunner);
+    try {
+      await testRunner.done();
+
+      // Enables Flutter Driver VM service extension
+      //
+      // This extension is required for tests that use package:flutter_driver
+      // to drive applications from a separate process.
       enableFlutterDriverExtension();
+
       // TODO(awdavies): Use the logger instead.
       print('flutter driver extensions enabled.');
-    }, onError: (_) {
+      //ignore: avoid_catches_without_on_clauses
+    } catch (e) {
       // TODO(awdavies): Use the logger instead.
       // Noop.
-      print('flutter driver extensions not enabled.');
-    });
+      print('flutter driver extensions not enabled. $e');
+    }
     // Always return true so that the assert succeeds.
     return true;
   }()));
+  // Execute the main method of the app under test
   var res = (flutter_app_main.main as dynamic)();
   if (res != null && res is Future) {
     await res;