Merge pull request #84 from DrMarcII/step_mode

Add support for installing a Stepper into WebDriver, an object that c…
diff --git a/lib/core.dart b/lib/core.dart
index fca9ee5..4b71483 100644
--- a/lib/core.dart
+++ b/lib/core.dart
@@ -22,6 +22,7 @@
 import 'package:stack_trace/stack_trace.dart' show Chain;
 
 import 'src/command_processor.dart' show CommandProcessor;
+import 'src/stepper.dart' show Stepper;
 
 export 'src/exception.dart';
 
diff --git a/lib/src/stepper.dart b/lib/src/stepper.dart
new file mode 100644
index 0000000..f878f49
--- /dev/null
+++ b/lib/src/stepper.dart
@@ -0,0 +1,11 @@
+library webdriver.stepper;
+
+import 'dart:async';
+
+class Stepper {
+  const Stepper();
+
+  /// returns true if command should be executed, false if should not be executed.
+  Future<bool> step(String method, String command, params) =>
+      new Future.value(true);
+}
diff --git a/lib/src/web_driver.dart b/lib/src/web_driver.dart
index f000da5..9c79992 100644
--- a/lib/src/web_driver.dart
+++ b/lib/src/web_driver.dart
@@ -21,6 +21,7 @@
   final String id;
   final Uri uri;
   final bool filterStackTraces;
+  Stepper stepper;
 
   final _onCommandController =
       new StreamController<WebDriverCommandEvent>.broadcast();
@@ -208,8 +209,13 @@
     var result;
     var exception;
     try {
-      result = await fn();
-      return result;
+      if (stepper == null || await stepper.step(method, command, params)) {
+        result = await fn();
+        return result;
+      } else {
+        result = 'skipped';
+        return null;
+      }
     } catch (e) {
       exception = e;
       return new Future.error(e, trace);
diff --git a/lib/support/stdio_stepper.dart b/lib/support/stdio_stepper.dart
new file mode 100644
index 0000000..eea1711
--- /dev/null
+++ b/lib/support/stdio_stepper.dart
@@ -0,0 +1,46 @@
+library webdriver.support.stdio_stepper;
+
+import 'dart:async';
+import 'dart:convert';
+import 'dart:io';
+
+import 'package:webdriver/src/stepper.dart';
+
+/// Provides a command line interface for stepping through or skipping
+/// WebDriver commands.
+class StdioStepper implements Stepper {
+  StdioStepper() {
+    stdin.lineMode = true;
+  }
+
+  Future<bool> step(String method, String command, params) async {
+    print('$method $command(${JSON.encode(params)}):');
+    while (true) {
+      var command = stdin.readLineSync(retainNewlines: false).trim();
+      switch (command) {
+        case 'continue':
+        case 'c':
+          return true;
+        case 'skip':
+        case 's':
+          return false;
+        case 'break':
+        case 'b':
+          throw new Exception('process ended by user.');
+        case 'help':
+        case 'h':
+          _printUsage();
+          break;
+        default:
+          print('invalid command: `$command` enter `h` or `help` for help.');
+      }
+    }
+  }
+
+  _printUsage() {
+    print('`c` or `continue`: to execute command');
+    print('`s` or `skip`: skip command');
+    print('`b` or `break`: stop execution');
+    print('`h` or `help`: display this message');
+  }
+}
diff --git a/pubspec.yaml b/pubspec.yaml
index 0a00481..9a06818 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,16 +1,16 @@
 name: webdriver
-version: 0.10.0-pre.11
+version: 0.10.0-pre.12
 author: Marc Fisher II <fisherii@google.com>
 description: >
   Provides WebDriver bindings for Dart. These use the WebDriver JSON interface,
   and as such, require the use of the WebDriver remote server.
 homepage: https://github.com/google/webdriver.dart
 environment:
-  sdk: '>=1.9.0 <2.0.0'
+  sdk: '>=1.10.0 <2.0.0'
 dependencies:
   crypto: '^0.9.0'
   matcher: '^0.12.0+1'
-  stack_trace: '^1.3.3'
-dev_dependencies:
   path: '^1.3.5'
-  test: '^0.12.3+3'
+  stack_trace: '^1.3.4'
+dev_dependencies:
+  test: '^0.12.3+5'