Merge pull request #83 from DrMarcII/exceptions

Improve stack traces using stack_trace Chain.
diff --git a/lib/core.dart b/lib/core.dart
index f6ea1e2..fca9ee5 100644
--- a/lib/core.dart
+++ b/lib/core.dart
@@ -19,7 +19,7 @@
 import 'dart:math' show Point, Rectangle;
 
 import 'package:crypto/crypto.dart' show CryptoUtils;
-import 'package:stack_trace/stack_trace.dart' show Trace;
+import 'package:stack_trace/stack_trace.dart' show Chain;
 
 import 'src/command_processor.dart' show CommandProcessor;
 
diff --git a/lib/src/command_event.dart b/lib/src/command_event.dart
index 62a21cb..c678b82 100644
--- a/lib/src/command_event.dart
+++ b/lib/src/command_event.dart
@@ -17,7 +17,7 @@
   final String method;
   final String endPoint;
   final params;
-  final Trace stackTrace;
+  final StackTrace stackTrace;
   final DateTime startTime;
   final DateTime endTime;
   final exception;
diff --git a/lib/src/web_driver.dart b/lib/src/web_driver.dart
index 113ffc2..f000da5 100644
--- a/lib/src/web_driver.dart
+++ b/lib/src/web_driver.dart
@@ -20,11 +20,13 @@
   final Map<String, dynamic> capabilities;
   final String id;
   final Uri uri;
+  final bool filterStackTraces;
 
   final _onCommandController =
       new StreamController<WebDriverCommandEvent>.broadcast();
 
-  WebDriver(this._commandProcessor, Uri uri, String id, this.capabilities)
+  WebDriver(this._commandProcessor, Uri uri, String id, this.capabilities,
+      {this.filterStackTraces: true})
       : this.uri = uri,
         this.id = id,
         this._prefix = uri.resolve('session/$id/');
@@ -74,9 +76,11 @@
   }
 
   /// Quit the browser.
-  Future quit() async {
+  Future quit({bool closeSession: true}) async {
     try {
-      await _commandProcessor.delete(uri.resolve('session/$id'));
+      if (closeSession) {
+        await _commandProcessor.delete(uri.resolve('session/$id'));
+      }
     } finally {
       await _commandProcessor.close();
     }
@@ -196,7 +200,11 @@
   Future _performRequest(
       Function fn, String method, String command, params) async {
     var startTime = new DateTime.now();
-    var trace = new Trace.current(1);
+    var trace = new Chain.current();
+    if (filterStackTraces) {
+      trace = trace.foldFrames(
+          (f) => f.library.startsWith('package:webdriver/'), terse: true);
+    }
     var result;
     var exception;
     try {
@@ -204,7 +212,7 @@
       return result;
     } catch (e) {
       exception = e;
-      rethrow;
+      return new Future.error(e, trace);
     } finally {
       _onCommandController.add(new WebDriverCommandEvent(
           method: method,
diff --git a/lib/src/web_element.dart b/lib/src/web_element.dart
index 4c5de03..3869348 100644
--- a/lib/src/web_element.dart
+++ b/lib/src/web_element.dart
@@ -128,19 +128,12 @@
       } else {
         out..write('.findElements(');
       }
-      out
-        ..write(locator)
-        ..write(')');
+      out..write(locator)..write(')');
     } else {
-      out
-        ..write('.')
-        ..write(locator);
+      out..write('.')..write(locator);
     }
     if (index != null) {
-      out
-        ..write('[')
-        ..write(index)
-        ..write(']');
+      out..write('[')..write(index)..write(']');
     }
     return out.toString();
   }
diff --git a/pubspec.yaml b/pubspec.yaml
index 112f72d..0a00481 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
 name: webdriver
-version: 0.10.0-pre.10
+version: 0.10.0-pre.11
 author: Marc Fisher II <fisherii@google.com>
 description: >
   Provides WebDriver bindings for Dart. These use the WebDriver JSON interface,
@@ -9,7 +9,8 @@
   sdk: '>=1.9.0 <2.0.0'
 dependencies:
   crypto: '^0.9.0'
-  matcher: '^0.12.0'
+  matcher: '^0.12.0+1'
+  stack_trace: '^1.3.3'
 dev_dependencies:
   path: '^1.3.5'
-  test: '^0.12.0'
+  test: '^0.12.3+3'
diff --git a/test/src/command_event.dart b/test/src/command_event.dart
index 0c2ff2d..aea573f 100644
--- a/test/src/command_event.dart
+++ b/test/src/command_event.dart
@@ -44,7 +44,6 @@
     });
 
     test('handles exceptions', () async {
-      var trace = new Trace.current(1);
       try {
         await driver.switchTo.alert;
       } catch (e) {}
@@ -54,11 +53,10 @@
       expect(events[1].exception, new isInstanceOf<WebDriverException>());
       expect(events[1].result, isNull);
       expect(events[1].startTime.isBefore(events[1].endTime), isTrue);
-      compareTraces(events[1].stackTrace, trace);
+      expect(events[1].stackTrace, new isInstanceOf<Chain>());
     });
 
     test('handles normal operation', () async {
-      var trace = new Trace.current(1);
       await driver.findElements(const By.cssSelector('nosuchelement')).toList();
       await waitFor(() => events, matcher: hasLength(2));
       expect(events[1].method, 'POST');
@@ -66,20 +64,7 @@
       expect(events[1].exception, isNull);
       expect(events[1].result, hasLength(0));
       expect(events[1].startTime.isBefore(events[1].endTime), isTrue);
-      compareTraces(events[1].stackTrace, trace);
+      expect(events[1].stackTrace, new isInstanceOf<Chain>());
     });
   }, testOn: '!js');
 }
-
-void compareTraces(Trace actual, Trace expected) {
-  expect(actual.frames.length, greaterThanOrEqualTo(expected.frames.length));
-  var index1 = actual.frames.length - 1;
-  var index2 = expected.frames.length - 1;
-
-  while (index2 >= 0) {
-    expect(
-        actual.frames[index1].toString(), expected.frames[index2].toString());
-    index1--;
-    index2--;
-  }
-}