Merge pull request #16 from kevmoo/master

A lot of test cleanup
diff --git a/lib/src/webdriver.dart b/lib/src/web_driver.dart
similarity index 100%
rename from lib/src/webdriver.dart
rename to lib/src/web_driver.dart
diff --git a/lib/src/webelement.dart b/lib/src/web_element.dart
similarity index 100%
rename from lib/src/webelement.dart
rename to lib/src/web_element.dart
diff --git a/lib/webdriver.dart b/lib/webdriver.dart
index daf7719..889f64a 100644
--- a/lib/webdriver.dart
+++ b/lib/webdriver.dart
@@ -22,6 +22,6 @@
 part 'src/options.dart';
 part 'src/target_locator.dart';
 part 'src/touch.dart';
-part 'src/webdriver.dart';
-part 'src/webelement.dart';
+part 'src/web_driver.dart';
+part 'src/web_element.dart';
 part 'src/window.dart';
diff --git a/test/pageloader_test.dart b/test/pageloader_test.dart
index e9ca35c..96bc8cc 100644
--- a/test/pageloader_test.dart
+++ b/test/pageloader_test.dart
@@ -1,19 +1,18 @@
 library webdriver_test;
 
-import 'dart:io' as io;
 import 'package:webdriver/pageloader.dart';
 import 'package:webdriver/webdriver.dart';
 import 'package:unittest/unittest.dart';
-import 'package:unittest/vm_config.dart';
+import 'package:unittest/compact_vm_config.dart';
+
+import 'test_util.dart';
 
 /**
  * These tests are not expected to be run as part of normal automated testing,
  * as they are slow and they have external dependencies.
  */
-main() {
-  useVMConfiguration();
-
-  io.File file = new io.File('test_page.html');
+void main() {
+  useCompactVMConfiguration();
 
   WebDriver driver;
   PageLoader loader;
@@ -22,7 +21,7 @@
         .then((_driver) {
           driver = _driver;
           loader = new PageLoader(driver);
-          return driver.get('file://' + file.fullPathSync());
+          return driver.get(testPagePath);
         }));
 
   tearDown(() => driver.quit());
diff --git a/test/src/alert_test.dart b/test/src/alert_test.dart
index 87707f9..8d54b29 100644
--- a/test/src/alert_test.dart
+++ b/test/src/alert_test.dart
@@ -1,70 +1,71 @@
-part of webdriver_test;
+library webdriver_test.alert;
 
-class AlertTest {
-  main() {
+import 'package:unittest/unittest.dart';
+import 'package:webdriver/webdriver.dart';
+import '../test_util.dart';
 
+void main() {
 
-    group('Alert', () {
+  group('Alert', () {
 
-      WebDriver driver;
-      WebElement button;
-      WebElement output;
+    WebDriver driver;
+    WebElement button;
+    WebElement output;
 
-      setUp(() {
-        return WebDriver.createDriver(desiredCapabilities: Capabilities.chrome)
-            .then((_driver) => driver = _driver)
-            .then((_) => driver.get(_testPagePath))
-            .then((_) => driver.findElement(new By.tagName('button')))
-            .then((_element) => button = _element)
-            .then((_) => driver.findElement(new By.id('settable')))
-            .then((_element) => output = _element);
-      });
+    setUp(() {
+      return WebDriver.createDriver(desiredCapabilities: Capabilities.chrome)
+          .then((_driver) => driver = _driver)
+          .then((_) => driver.get(testPagePath))
+          .then((_) => driver.findElement(new By.tagName('button')))
+          .then((_element) => button = _element)
+          .then((_) => driver.findElement(new By.id('settable')))
+          .then((_element) => output = _element);
+    });
 
-      tearDown(() => driver.quit());
+    tearDown(() => driver.quit());
 
-      test('no alert', () {
-        return driver.switchTo.alert.catchError((error) {
-          expect(error, isWebDriverError);
-        });
-      });
-
-      test('text', () {
-        return button.click().then((_) => driver.switchTo.alert)
-            .then((alert) {
-              expect(alert.text, 'button clicked');
-              return alert.dismiss();
-            });
-      });
-
-      test('accept', () {
-        return button.click().then((_) => driver.switchTo.alert)
-            .then((alert) => alert.accept())
-            .then((_) => output.text)
-            .then((text) {
-              expect(text, startsWith('accepted'));
-            });
-      });
-
-      test('dismiss', () {
-        return button.click().then((_) => driver.switchTo.alert)
-            .then((alert) => alert.dismiss())
-            .then((_) => output.text)
-            .then((text) {
-              expect(text, startsWith('dismissed'));
-            });
-      });
-
-      test('sendKeys', () {
-        Alert alert;
-        return button.click().then((_) => driver.switchTo.alert)
-            .then((_alert) => alert = _alert)
-            .then((_) => alert.sendKeys('some keys'))
-            .then((_) => alert.accept())
-            .then((_) => output.text)
-            .then((text) {
-              expect(text, endsWith('some keys'));
-            });
+    test('no alert', () {
+      return driver.switchTo.alert.catchError((error) {
+        expect(error, isWebDriverError);
       });
     });
-  }
+
+    test('text', () {
+      return button.click().then((_) => driver.switchTo.alert)
+          .then((alert) {
+            expect(alert.text, 'button clicked');
+            return alert.dismiss();
+          });
+    });
+
+    test('accept', () {
+      return button.click().then((_) => driver.switchTo.alert)
+          .then((alert) => alert.accept())
+          .then((_) => output.text)
+          .then((text) {
+            expect(text, startsWith('accepted'));
+          });
+    });
+
+    test('dismiss', () {
+      return button.click().then((_) => driver.switchTo.alert)
+          .then((alert) => alert.dismiss())
+          .then((_) => output.text)
+          .then((text) {
+            expect(text, startsWith('dismissed'));
+          });
+    });
+
+    test('sendKeys', () {
+      Alert alert;
+      return button.click().then((_) => driver.switchTo.alert)
+          .then((_alert) => alert = _alert)
+          .then((_) => alert.sendKeys('some keys'))
+          .then((_) => alert.accept())
+          .then((_) => output.text)
+          .then((text) {
+            expect(text, endsWith('some keys'));
+          });
+    });
+  });
 }
diff --git a/test/src/keyboard_test.dart b/test/src/keyboard_test.dart
index 5a2a2b4..442a1d9 100644
--- a/test/src/keyboard_test.dart
+++ b/test/src/keyboard_test.dart
@@ -1,58 +1,60 @@
-part of webdriver_test;
+library webdriver_test.keyboard;
 
-class KeyboardTest {
-  main() {
+import 'package:unittest/unittest.dart';
+import 'package:webdriver/webdriver.dart';
+import '../test_util.dart';
 
-    group('Keyboard', () {
+void main() {
 
-      WebDriver driver;
-      WebElement textInput;
+  group('Keyboard', () {
 
-      setUp(() {
-        return WebDriver.createDriver(desiredCapabilities: Capabilities.firefox)
-            .then((_driver) => driver = _driver)
-            .then((_) => driver.get(_testPagePath))
-            .then((_) =>
-                driver.findElement(new By.cssSelector('input[type=text]')))
-            .then((_element) => textInput = _element)
-            .then((_) => driver.mouse.moveTo(element: textInput).click());
-      });
+    WebDriver driver;
+    WebElement textInput;
 
-      tearDown(() => driver.quit());
-
-      test('sendKeys -- once', () {
-        return driver.keyboard.sendKeys('abcdef')
-            .then((_) => textInput.attributes['value'])
-            .then((value) {
-              expect(value, 'abcdef');
-            });
-      });
-
-      test('sendKeys -- twice', () {
-        return driver.keyboard.sendKeys('abc').sendKeys('def')
-            .then((_) => textInput.attributes['value'])
-            .then((value) {
-              expect(value, 'abcdef');
-            });
-      });
-
-      test('sendKeys -- list', () {
-        return driver.keyboard.sendKeys(['a', 'b', 'c', 'd', 'e', 'f'])
-            .then((_) => textInput.attributes['value'])
-            .then((value) {
-              expect(value, 'abcdef');
-            });
-      });
-
-      // doesn't work with chromedriver
-      // https://code.google.com/p/chromedriver/issues/detail?id=443
-      test('sendKeys -- with tab', () {
-        return driver.keyboard.sendKeys(['abc', Keys.TAB, 'def'])
-            .then((_) => textInput.attributes['value'])
-            .then((value) {
-              expect(value, 'abc');
-            });
-      });
+    setUp(() {
+      return WebDriver.createDriver(desiredCapabilities: Capabilities.firefox)
+          .then((_driver) => driver = _driver)
+          .then((_) => driver.get(testPagePath))
+          .then((_) =>
+              driver.findElement(new By.cssSelector('input[type=text]')))
+          .then((_element) => textInput = _element)
+          .then((_) => driver.mouse.moveTo(element: textInput).click());
     });
-  }
+
+    tearDown(() => driver.quit());
+
+    test('sendKeys -- once', () {
+      return driver.keyboard.sendKeys('abcdef')
+          .then((_) => textInput.attributes['value'])
+          .then((value) {
+            expect(value, 'abcdef');
+          });
+    });
+
+    test('sendKeys -- twice', () {
+      return driver.keyboard.sendKeys('abc').sendKeys('def')
+          .then((_) => textInput.attributes['value'])
+          .then((value) {
+            expect(value, 'abcdef');
+          });
+    });
+
+    test('sendKeys -- list', () {
+      return driver.keyboard.sendKeys(['a', 'b', 'c', 'd', 'e', 'f'])
+          .then((_) => textInput.attributes['value'])
+          .then((value) {
+            expect(value, 'abcdef');
+          });
+    });
+
+    // doesn't work with chromedriver
+    // https://code.google.com/p/chromedriver/issues/detail?id=443
+    test('sendKeys -- with tab', () {
+      return driver.keyboard.sendKeys(['abc', Keys.TAB, 'def'])
+          .then((_) => textInput.attributes['value'])
+          .then((value) {
+            expect(value, 'abc');
+            });
+    });
+  });
 }
diff --git a/test/src/mouse_test.dart b/test/src/mouse_test.dart
index ded8238..e4807d2 100644
--- a/test/src/mouse_test.dart
+++ b/test/src/mouse_test.dart
@@ -1,62 +1,64 @@
-part of webdriver_test;
+library webdriver_test.mouse;
 
-class MouseTest {
-  main() {
+import 'package:unittest/unittest.dart';
+import 'package:webdriver/webdriver.dart';
+import '../test_util.dart';
 
-    group('Mouse', () {
+void main() {
 
-      WebDriver driver;
-      WebElement button;
+  group('Mouse', () {
 
-      setUp(() {
-        return WebDriver.createDriver(desiredCapabilities: Capabilities.chrome)
-            .then((_driver) => driver = _driver)
-            .then((_) => driver.get(_testPagePath))
-            .then((_) => driver.findElement(new By.tagName('button')))
-            .then((_e) => button = _e);
-      });
+    WebDriver driver;
+    WebElement button;
 
-      tearDown(() => driver.quit());
-
-      test('moveTo element/click', () {
-        return driver.mouse.moveTo(element: button)
-            .click()
-            .then((_) => driver.switchTo.alert)
-            .then((alert) => alert.dismiss);
-      });
-
-      test('moveTo coordinates/click', () {
-        return button.location
-            .then((pos) => driver.mouse
-                .moveTo(xOffset: pos.x + 5, yOffset: pos.y + 5)
-                .click())
-            .then((_) => driver.switchTo.alert)
-            .then((alert) => alert.dismiss);
-      });
-
-      test('moveTo element coordinates/click', () {
-        return driver.mouse.moveTo(element: button, xOffset: 5, yOffset: 5)
-            .click()
-            .then((_) => driver.switchTo.alert)
-            .then((alert) => alert.dismiss);
-      });
-
-      // TODO(DrMarcII): Better up/down tests
-      test('down/up', () {
-        return driver.mouse.moveTo(element: button)
-            .down()
-            .up()
-            .then((_) => driver.switchTo.alert)
-            .then((alert) => alert.dismiss);
-      });
-
-      // TODO(DrMarcII): Better double click test
-      test('doubleClick', () {
-        return driver.mouse.moveTo(element: button)
-            .doubleClick()
-            .then((_) => driver.switchTo.alert)
-            .then((alert) => alert.dismiss);
-      });
+    setUp(() {
+      return WebDriver.createDriver(desiredCapabilities: Capabilities.chrome)
+          .then((_driver) => driver = _driver)
+          .then((_) => driver.get(testPagePath))
+          .then((_) => driver.findElement(new By.tagName('button')))
+          .then((_e) => button = _e);
     });
-  }
+
+    tearDown(() => driver.quit());
+
+    test('moveTo element/click', () {
+      return driver.mouse.moveTo(element: button)
+          .click()
+          .then((_) => driver.switchTo.alert)
+          .then((alert) => alert.dismiss);
+    });
+
+    test('moveTo coordinates/click', () {
+      return button.location
+          .then((pos) => driver.mouse
+              .moveTo(xOffset: pos.x + 5, yOffset: pos.y + 5)
+              .click())
+          .then((_) => driver.switchTo.alert)
+          .then((alert) => alert.dismiss);
+    });
+
+    test('moveTo element coordinates/click', () {
+      return driver.mouse.moveTo(element: button, xOffset: 5, yOffset: 5)
+          .click()
+          .then((_) => driver.switchTo.alert)
+          .then((alert) => alert.dismiss);
+    });
+
+    // TODO(DrMarcII): Better up/down tests
+    test('down/up', () {
+      return driver.mouse.moveTo(element: button)
+          .down()
+          .up()
+          .then((_) => driver.switchTo.alert)
+          .then((alert) => alert.dismiss);
+    });
+
+    // TODO(DrMarcII): Better double click test
+    test('doubleClick', () {
+      return driver.mouse.moveTo(element: button)
+          .doubleClick()
+          .then((_) => driver.switchTo.alert)
+          .then((alert) => alert.dismiss);
+    });
+  });
 }
diff --git a/test/src/navigation_test.dart b/test/src/navigation_test.dart
index e1d90af..217c7f4 100644
--- a/test/src/navigation_test.dart
+++ b/test/src/navigation_test.dart
@@ -1,45 +1,47 @@
-part of webdriver_test;
+library webdriver_test.navigation;
 
-class NavigationTest {
-  main() {
+import 'package:unittest/unittest.dart';
+import 'package:webdriver/webdriver.dart';
+import '../test_util.dart';
 
-    group('Navigation', () {
+void main() {
 
-      WebDriver driver;
+  group('Navigation', () {
 
-      setUp(() {
-        return WebDriver.createDriver(desiredCapabilities: Capabilities.chrome)
-            .then((_driver) => driver = _driver)
-            .then((_) => driver.get('http://www.google.com'));
-      });
+    WebDriver driver;
 
-      tearDown(() => driver.quit());
+    setUp(() {
+      return WebDriver.createDriver(desiredCapabilities: Capabilities.chrome)
+          .then((_driver) => driver = _driver)
+          .then((_) => driver.get('http://www.google.com'));
+    });
 
-      test('forward/back', () {
-        return driver.get('http://www.yahoo.com')
-            .then((_) => driver.navigate.back())
-            .then((_) => driver.title)
-            .then((title) {
-              expect(title, contains('Google'));
-              return driver.navigate.forward();
-            })
-            .then((_) => driver.title)
-            .then((title) {
-              expect(title, contains('Yahoo'));
-            });
-      });
+    tearDown(() => driver.quit());
 
-      test('refresh', () {
-        var element;
-        return driver.findElement(new By.name('q'))
-            .then((_e) => element = _e)
-            .then((_) => driver.navigate.refresh())
-            .then((_) => element.name)
-            .catchError((error) {
-              // search should be stale after refresh
+    test('forward/back', () {
+      return driver.get('http://www.yahoo.com')
+          .then((_) => driver.navigate.back())
+          .then((_) => driver.title)
+          .then((title) {
+            expect(title, contains('Google'));
+            return driver.navigate.forward();
+          })
+          .then((_) => driver.title)
+          .then((title) {
+            expect(title, contains('Yahoo'));
+          });
+    });
+
+    test('refresh', () {
+      var element;
+      return driver.findElement(new By.name('q'))
+          .then((_e) => element = _e)
+          .then((_) => driver.navigate.refresh())
+          .then((_) => element.name)
+          .catchError((error) {
+            // search should be stale after refresh
               expect(error, isWebDriverError);
             });
-      });
     });
-  }
+  });
 }
diff --git a/test/src/options_test.dart b/test/src/options_test.dart
index 4f6ad24..db289ce 100644
--- a/test/src/options_test.dart
+++ b/test/src/options_test.dart
@@ -1,105 +1,106 @@
-part of webdriver_test;
+library webdriver_test.options;
 
-class OptionsTest {
-  main() {
+import 'package:unittest/unittest.dart';
+import 'package:webdriver/webdriver.dart';
 
-    group('Cookies', () {
+void main() {
 
-      WebDriver driver;
+  group('Cookies', () {
 
-      setUp(() {
-        return WebDriver.createDriver(desiredCapabilities: Capabilities.chrome)
-            .then((_driver) => driver = _driver)
-            .then((_) => driver.get('http://www.google.com'));
-      });
+    WebDriver driver;
 
-      tearDown(() => driver.quit());
-
-      test('add simple cookie', () {
-        return driver.cookies.add(new Cookie('mycookie', 'myvalue'))
-            .then((_) => driver.cookies.all)
-            .then((cookies) {
-              bool found = false;
-              for (var cookie in cookies) {
-                if (cookie.name == 'mycookie') {
-                  found = true;
-                  expect(cookie.value, 'myvalue');
-                }
-              }
-              expect(found, isTrue);
-            });
-      });
-
-      test('add complex cookie', () {
-        var date = new DateTime.utc(2014);
-        return driver.cookies
-            .add(new Cookie(
-                'mycookie',
-                'myvalue',
-                path: '/',
-                domain: '.google.com',
-                secure: false,
-                expiry: date))
-            .then((_) => driver.cookies.all)
-            .then((cookies) {
-              bool found = false;
-              for (var cookie in cookies) {
-                if (cookie.name == 'mycookie') {
-                  found = true;
-                  expect(cookie.value, 'myvalue');
-                  expect(cookie.expiry, date);
-                }
-              }
-              expect(found, isTrue);
-            });
-      });
-
-      test('delete cookie', () {
-        return driver.cookies.add(new Cookie('mycookie', 'myvalue'))
-            .then((_) => driver.cookies.delete('mycookie'))
-            .then((_) => driver.cookies.all)
-            .then((cookies) {
-              bool found = false;
-              for (var cookie in cookies) {
-                if (cookie.name == 'mycookie') {
-                  found = true;
-                }
-              }
-              expect(found, isFalse);
-            });
-      });
-
-      test('delete all cookies', () {
-        return driver.cookies.deleteAll()
-            .then((_) => driver.cookies.all)
-            .then((cookies) {
-              expect(cookies, isEmpty);
-            });
-      });
+    setUp(() {
+      return WebDriver.createDriver(desiredCapabilities: Capabilities.chrome)
+          .then((_driver) => driver = _driver)
+          .then((_) => driver.get('http://www.google.com'));
     });
 
-    group('TimeOuts', () {
-      WebDriver driver;
+    tearDown(() => driver.quit());
 
-      setUp(() {
-        return WebDriver.createDriver(desiredCapabilities: Capabilities.chrome)
-            .then((_driver) => driver = _driver);
-      });
-
-      tearDown(() => driver.quit());
-
-      // TODO(DrMarcII): Figure out how to tell if timeouts are correctly set
-      test('set all timeouts', () {
-        return driver.timeouts.setScriptTimeout(new Duration(seconds: 5))
-            .then((_) => driver.timeouts
-                .setImplicitTimeout(new Duration(seconds: 1)))
-            .then((_) => driver.timeouts
-                .setPageLoadTimeout(new Duration(seconds: 10)))
-            .then((_) => driver.timeouts
-                .setAsyncScriptTimeout(new Duration(seconds: 7)))
-            .then((_) => driver.timeouts
-                .setImplicitWaitTimeout(new Duration(seconds: 2)));
-      });
+    test('add simple cookie', () {
+      return driver.cookies.add(new Cookie('mycookie', 'myvalue'))
+          .then((_) => driver.cookies.all)
+          .then((cookies) {
+            bool found = false;
+            for (var cookie in cookies) {
+              if (cookie.name == 'mycookie') {
+                found = true;
+                expect(cookie.value, 'myvalue');
+              }
+            }
+            expect(found, isTrue);
+          });
     });
-  }
+
+    test('add complex cookie', () {
+      var date = new DateTime.utc(2014);
+      return driver.cookies
+          .add(new Cookie(
+              'mycookie',
+              'myvalue',
+              path: '/',
+              domain: '.google.com',
+              secure: false,
+              expiry: date))
+          .then((_) => driver.cookies.all)
+          .then((cookies) {
+            bool found = false;
+            for (var cookie in cookies) {
+              if (cookie.name == 'mycookie') {
+                found = true;
+                expect(cookie.value, 'myvalue');
+                expect(cookie.expiry, date);
+              }
+            }
+            expect(found, isTrue);
+          });
+    });
+
+    test('delete cookie', () {
+      return driver.cookies.add(new Cookie('mycookie', 'myvalue'))
+          .then((_) => driver.cookies.delete('mycookie'))
+          .then((_) => driver.cookies.all)
+          .then((cookies) {
+            bool found = false;
+            for (var cookie in cookies) {
+              if (cookie.name == 'mycookie') {
+                found = true;
+              }
+            }
+            expect(found, isFalse);
+          });
+    });
+
+    test('delete all cookies', () {
+      return driver.cookies.deleteAll()
+          .then((_) => driver.cookies.all)
+          .then((cookies) {
+            expect(cookies, isEmpty);
+          });
+    });
+  });
+
+  group('TimeOuts', () {
+    WebDriver driver;
+
+    setUp(() {
+      return WebDriver.createDriver(desiredCapabilities: Capabilities.chrome)
+          .then((_driver) => driver = _driver);
+    });
+
+    tearDown(() => driver.quit());
+
+    // TODO(DrMarcII): Figure out how to tell if timeouts are correctly set
+    test('set all timeouts', () {
+      return driver.timeouts.setScriptTimeout(new Duration(seconds: 5))
+          .then((_) => driver.timeouts
+              .setImplicitTimeout(new Duration(seconds: 1)))
+          .then((_) => driver.timeouts
+              .setPageLoadTimeout(new Duration(seconds: 10)))
+          .then((_) => driver.timeouts
+              .setAsyncScriptTimeout(new Duration(seconds: 7)))
+          .then((_) => driver.timeouts
+              .setImplicitWaitTimeout(new Duration(seconds: 2)));
+    });
+  });
 }
diff --git a/test/src/target_locator_test.dart b/test/src/target_locator_test.dart
index e492ae2..3005c4d 100644
--- a/test/src/target_locator_test.dart
+++ b/test/src/target_locator_test.dart
@@ -1,57 +1,59 @@
-part of webdriver_test;
+library webdriver_test.target_locator;
+
+import 'package:unittest/unittest.dart';
+import 'package:webdriver/webdriver.dart';
+import '../test_util.dart';
 
 /**
  * Tests for switchTo.frame(). switchTo.window() and switchTo.alert are tested
  * in other classes.
  */
-class TargetLocatorTest {
-  main() {
+void main() {
 
-    group('TargetLocator', () {
+  group('TargetLocator', () {
 
-      WebDriver driver;
-      WebElement frame;
+    WebDriver driver;
+    WebElement frame;
 
-      setUp(() {
-        return WebDriver.createDriver(desiredCapabilities: Capabilities.chrome)
-            .then((_driver) => driver = _driver)
-            .then((_) => driver.get(_testPagePath))
-            .then((_) => driver.findElement(new By.name('frame')))
-            .then((_e) => frame = _e);
-      });
-
-      tearDown(() => driver.quit());
-
-      test('frame index', () {
-        return driver.switchTo.frame(0)
-            .then((_) => driver.pageSource)
-            .then((source) {
-              expect(source, contains('this is a frame'));
-            });
-      });
-
-      test('frame name', () {
-        return driver.switchTo.frame('frame')
-            .then((_) => driver.pageSource)
-            .then((source) {
-              expect(source, contains('this is a frame'));
-            });
-      });
-
-      test('frame element', () {
-        return driver.switchTo.frame(frame)
-            .then((_) => driver.pageSource)
-            .then((source) {
-              expect(source, contains('this is a frame'));
-            });
-      });
-
-      test('root frame', () {
-        return driver.switchTo.frame(frame)
-            .then((_) => driver.switchTo.frame())
-            .then((_) => driver.pageSource)
-            .then((_) => driver.findElement(new By.tagName('button')));
-      });
+    setUp(() {
+      return WebDriver.createDriver(desiredCapabilities: Capabilities.chrome)
+          .then((_driver) => driver = _driver)
+          .then((_) => driver.get(testPagePath))
+          .then((_) => driver.findElement(new By.name('frame')))
+          .then((_e) => frame = _e);
     });
-  }
+
+    tearDown(() => driver.quit());
+
+    test('frame index', () {
+      return driver.switchTo.frame(0)
+          .then((_) => driver.pageSource)
+          .then((source) {
+            expect(source, contains('this is a frame'));
+          });
+    });
+
+    test('frame name', () {
+      return driver.switchTo.frame('frame')
+          .then((_) => driver.pageSource)
+          .then((source) {
+            expect(source, contains('this is a frame'));
+          });
+    });
+
+    test('frame element', () {
+      return driver.switchTo.frame(frame)
+          .then((_) => driver.pageSource)
+          .then((source) {
+            expect(source, contains('this is a frame'));
+          });
+    });
+
+    test('root frame', () {
+      return driver.switchTo.frame(frame)
+          .then((_) => driver.switchTo.frame())
+          .then((_) => driver.pageSource)
+          .then((_) => driver.findElement(new By.tagName('button')));
+    });
+  });
 }
diff --git a/test/src/web_driver_test.dart b/test/src/web_driver_test.dart
new file mode 100644
index 0000000..3139c7c
--- /dev/null
+++ b/test/src/web_driver_test.dart
@@ -0,0 +1,228 @@
+library webdriver_test.web_driver;
+
+import 'package:unittest/unittest.dart';
+import 'package:webdriver/webdriver.dart';
+import '../test_util.dart';
+
+void main() {
+
+  group('WebDriver', () {
+    group('create', () {
+      test('default', () {
+        WebDriver driver;
+        return WebDriver.createDriver()
+            .then((_driver) {
+              driver = _driver;
+            })
+            .then((_) => driver.get('http://www.google.com'))
+            .then((_) => driver.findElement(new By.name('q')))
+            .then((element) => element.name)
+            .then((name) {
+              expect(name, 'input');
+              return driver.quit();
+            });
+      });
+
+      test('chrome', () {
+        WebDriver driver;
+        return WebDriver
+            .createDriver(desiredCapabilities: Capabilities.chrome)
+            .then((_driver) {
+              driver = _driver;
+            })
+            .then((_) => driver.get('http://www.google.com'))
+            .then((_) => driver.findElement(new By.name('q')))
+            .then((element) => element.name)
+            .then((name) {
+              expect(name, 'input');
+              return driver.quit();
+            });
+      });
+
+      test('firefox', () {
+        WebDriver driver;
+        return WebDriver
+            .createDriver(desiredCapabilities: Capabilities.firefox)
+            .then((_driver) {
+              driver = _driver;
+            })
+            .then((_) => driver.get('http://www.google.com'))
+            .then((_) => driver.findElement(new By.name('q')))
+            .then((element) => element.name)
+            .then((name) {
+              expect(name, 'input');
+              return driver.quit();
+            });
+      });
+    });
+
+    group('methods', () {
+      WebDriver driver;
+
+      setUp(() {
+        return WebDriver
+            .createDriver(desiredCapabilities: Capabilities.chrome)
+            .then((_driver) => driver = _driver)
+            .then((_) => driver.get(testPagePath));
+      });
+
+      tearDown(() => driver.quit());
+
+      test('get', () {
+        return driver.get('http://www.google.com')
+            .then((_) => driver.findElement(new By.name('q')))
+            .then((_) => driver.get('http://www.yahoo.com'))
+            .then((_) => driver.findElement(new By.name('p')));
+      });
+
+      test('currentUrl', () {
+        return driver.currentUrl.then((url) {
+          expect(url, startsWith('file:'));
+          expect(url, endsWith('test_page.html'));
+          return driver.get('http://www.google.com');
+        })
+        .then((_) => driver.currentUrl)
+        .then((url) {
+          expect(url, contains('www.google.com'));
+        });
+      });
+
+      test('findElement -- success', () {
+        driver.findElement(new By.tagName('tr'))
+            .then(expectAsync1((element) {
+              expect(element, isWebElement);
+            }));
+      });
+
+      test('findElement -- failure', () {
+        return driver.findElement(new By.id('non-existent-id'))
+            .catchError((error) {
+              expect(error, isWebDriverError);
+            });
+      });
+
+      test('findElements -- 1 found', () {
+        return driver.findElements(new By.cssSelector('input[type=text]'))
+            .then((elements) {
+              expect(elements, hasLength(1));
+              expect(elements, everyElement(isWebElement));
+            });
+      });
+
+      test('findElements -- 4 found', () {
+        return driver.findElements(new By.tagName('td'))
+            .then((elements) {
+              expect(elements, hasLength(4));
+              expect(elements, everyElement(isWebElement));
+            });
+      });
+
+      test('findElements -- 0 found', () {
+        return driver.findElements(new By.id('non-existent-id'))
+            .then((elements) {
+              expect(elements, isEmpty);
+            });
+      });
+
+      test('pageSource', () {
+        return driver.pageSource.then((source) {
+          expect(source, contains('<title>test_page</title>'));
+        });
+      });
+
+      test('close/windowHandles', () {
+        int numHandles;
+        return driver.windowHandles
+            .then((handles) => numHandles = handles.length)
+            .then((_) =>
+                driver.findElement(new By.partialLinkText('Open copy')))
+            .then((element) => element.click())
+            .then((_) => driver.close())
+            .then((_) => driver.windowHandles)
+            .then((handles) {
+              expect(handles, hasLength(numHandles));
+            });
+      });
+
+      test('windowHandle', () {
+        String origHandle;
+        String newHandle;
+        return driver.windowHandle
+            .then((_handle) => origHandle = _handle)
+            .then((_) =>
+                driver.findElement(new By.partialLinkText('Open copy')))
+            .then((element) => element.click())
+            .then((_) => driver.windowHandles)
+            .then((handles) {
+              for (String aHandle in handles) {
+                if (aHandle != origHandle) {
+                  newHandle = aHandle;
+                  return driver.switchTo.window(aHandle);
+                }
+              }
+            })
+            .then((_) => driver.windowHandle)
+            .then((finalHandle) {
+              expect(finalHandle, newHandle);
+            });
+      });
+
+      // TODO(DrMarcII): Figure out why this doesn't pass
+//        test('activeElement', () {
+//          return driver.activeElement
+//              .then((element) {
+//                expect(element, isNull);
+//                return driver
+//                    .findElement(new By.cssSelector('input[type=text]'));
+//              })
+//              .then((element) => element.click())
+//              .then((_) => driver.activeElement)
+//              .then((element) => element.name)
+//              .then((name) {
+//                expect(name, 'input');
+//              });
+//        });
+
+      test('windows', () {
+        return driver.windows.then((windows) {
+          expect(windows, hasLength(isPositive));
+          expect(windows, everyElement(new isInstanceOf<Window>()));
+        });
+      });
+
+      test('execute', () {
+        WebElement button;
+        String script = '''
+            arguments[1].textContent = arguments[0];
+            return arguments[1];''';
+        return driver.findElement(new By.tagName('button'))
+            .then((_e) => button = _e)
+            .then((_) => driver.execute(script, ['new text', button]))
+            .then((WebElement e) {
+              expect(e.text, completion('new text'));
+            });
+      });
+
+      test('executeAsync', () {
+        WebElement button;
+        String script = '''
+            arguments[1].textContent = arguments[0];
+            arguments[2](arguments[1]);''';
+        return driver.findElement(new By.tagName('button'))
+            .then((_e) => button = _e)
+            .then((_) => driver.executeAsync(script, ['new text', button]))
+            .then((WebElement e) {
+              expect(e.text, completion('new text'));
+            });
+      });
+
+      test('captureScreenshot', () {
+        return driver.captureScreenshot()
+            .then((screenshot) {
+              expect(screenshot, hasLength(isPositive));
+              expect(screenshot, everyElement(new isInstanceOf<int>()));
+            });
+      });
+    });
+  });
+}
diff --git a/test/src/web_element_test.dart b/test/src/web_element_test.dart
new file mode 100644
index 0000000..e227155
--- /dev/null
+++ b/test/src/web_element_test.dart
@@ -0,0 +1,207 @@
+library webdriver_test.web_element;
+
+import 'package:unittest/unittest.dart';
+import 'package:webdriver/webdriver.dart';
+import '../test_util.dart';
+
+void main() {
+
+  group('WebElement', () {
+
+    WebDriver driver;
+    WebElement table;
+    WebElement button;
+    WebElement form;
+    WebElement textInput;
+    WebElement checkbox;
+    WebElement disabled;
+    WebElement invisible;
+
+    setUp(() {
+      return WebDriver.createDriver(desiredCapabilities: Capabilities.chrome)
+          .then((_driver) => driver = _driver)
+          .then((_) => driver.get(testPagePath))
+          .then((_) => driver.findElement(new By.tagName('table')))
+          .then((_element) => table = _element)
+          .then((_) => driver.findElement(new By.tagName('button')))
+          .then((_element) => button = _element)
+          .then((_) => driver.findElement(new By.tagName('form')))
+          .then((_element) => form = _element)
+          .then((_) =>
+              driver.findElement(new By.cssSelector('input[type=text]')))
+          .then((_element) => textInput = _element)
+          .then((_) =>
+              driver.findElement(new By.cssSelector('input[type=checkbox]')))
+          .then((_element) => checkbox = _element)
+          .then((_) =>
+              driver.findElement(new By.cssSelector('input[type=password]')))
+          .then((_element) => disabled = _element)
+          .then((_) => driver.findElement(new By.tagName('div')))
+          .then((_element) => invisible = _element);
+    });
+
+    tearDown(() => driver.quit());
+
+    test('click', () {
+      return button.click()
+        .then((_) => driver.switchTo.alert)
+        .then((alert) =>  alert.accept());
+    });
+
+    test('submit', () {
+      return form.submit()
+        .then((_) => driver.switchTo.alert)
+        .then((alert) {
+          // TODO(DrMarcII): Switch to hasProperty matchers
+          expect(alert.text, 'form submitted');
+          return alert.accept();
+        });
+    });
+
+    test('sendKeys', () {
+      return textInput.sendKeys('some keys')
+        .then((_) => textInput.attributes['value'])
+        .then((value) {
+          expect(value, 'some keys');
+        });
+    });
+
+    test('clear', () {
+      return textInput.sendKeys('some keys')
+        .then((_) => textInput.clear())
+        .then((_) => textInput.attributes['value'])
+        .then((value) {
+          expect(value, '');
+        });
+    });
+
+    test('enabled', () {
+      expect(table.enabled, completion(isTrue));
+      expect(button.enabled, completion(isTrue));
+      expect(form.enabled, completion(isTrue));
+      expect(textInput.enabled, completion(isTrue));
+      expect(checkbox.enabled, completion(isTrue));
+      expect(disabled.enabled, completion(isFalse));
+    });
+
+    test('displayed', () {
+      expect(table.displayed, completion(isTrue));
+      expect(button.displayed, completion(isTrue));
+      expect(form.displayed, completion(isTrue));
+      expect(textInput.displayed, completion(isTrue));
+      expect(checkbox.displayed, completion(isTrue));
+      expect(disabled.displayed, completion(isTrue));
+      expect(invisible.displayed, completion(isFalse));
+    });
+
+    test('location -- table', () {
+      return table.location.then((location) {
+        expect(location, isPoint);
+        // TODO(DrMarcII): Switch to hasProperty matchers
+        expect(location.x, isNonNegative);
+        expect(location.y, isNonNegative);
+      });
+    });
+
+    test('location -- invisible', () {
+      return invisible.location.then((location) {
+        expect(location, isPoint);
+        // TODO(DrMarcII): Switch to hasProperty matchers
+        expect(location.x, 0);
+        expect(location.y, 0);
+      });
+    });
+
+    test('size -- table', () {
+      return table.size.then((size) {
+        expect(size, isSize);
+        // TODO(DrMarcII): Switch to hasProperty matchers
+        expect(size.width, isNonNegative);
+        expect(size.height, isNonNegative);
+      });
+    });
+
+    test('size -- invisible', () {
+      return invisible.size.then((size) {
+        expect(size, isSize);
+        // TODO(DrMarcII): I thought these should be 0
+        // TODO(DrMarcII): Switch to hasProperty matchers
+        expect(size.width, isNonNegative);
+        expect(size.height, isNonNegative);
+      });
+    });
+
+    test('name', () {
+      expect(table.name, completion('table'));
+      expect(button.name, completion('button'));
+      expect(form.name, completion('form'));
+      expect(textInput.name, completion('input'));
+    });
+
+    test('text', () {
+      expect(table.text, completion('r1c1 r1c2\nr2c1 r2c2'));
+      expect(button.text, completion('button'));
+      expect(invisible.text, completion(''));
+    });
+
+    test('findElement -- success', () {
+      return table.findElement(new By.tagName('tr'))
+          .then((element) {
+            expect(element, isWebElement);
+          });
+    });
+
+    test('findElement -- failure', () {
+      return button.findElement(new By.tagName('tr'))
+          .catchError((error) {
+            expect(error, isWebDriverError);
+          });
+    });
+
+    test('findElements -- 1 found', () {
+      return form.findElements(new By.cssSelector('input[type=text]'))
+          .then((elements) {
+            expect(elements, hasLength(1));
+            expect(elements, everyElement(isWebElement));
+          });
+    });
+
+    test('findElements -- 4 found', () {
+      return table.findElements(new By.tagName('td'))
+          .then((elements) {
+            expect(elements, hasLength(4));
+            expect(elements, everyElement(isWebElement));
+          });
+    });
+
+    test('findElements -- 0 found', () {
+      return form.findElements(new By.tagName('td'))
+          .then((elements) {
+            expect(elements, isEmpty);
+          });
+    });
+
+    test('attributes', () {
+      expect(table.attributes['id'], completion('table1'));
+      expect(table.attributes['non-standard'],
+          completion('a non standard attr'));
+      expect(table.attributes['disabled'], completion(isNull));
+      expect(disabled.attributes['disabled'], completion('true'));
+    });
+
+    test('cssProperties', () {
+      expect(invisible.cssProperties['display'], completion('none'));
+      expect(invisible.cssProperties['background-color'],
+          completion('rgba(255, 0, 0, 1)'));
+      expect(invisible.cssProperties['direction'], completion('ltr'));
+    });
+
+    test('equals', () {
+      expect(invisible.equals(disabled), completion(isFalse));
+      return driver.findElement(new By.cssSelector('table'))
+        .then((element) {
+          expect(element.equals(table), completion(isTrue));
+        });
+    });
+  });
+}
diff --git a/test/src/webdriver_test.dart b/test/src/webdriver_test.dart
deleted file mode 100644
index 9051e14..0000000
--- a/test/src/webdriver_test.dart
+++ /dev/null
@@ -1,227 +0,0 @@
-part of webdriver_test;
-
-class WebDriverTest {
-  main() {
-
-    WebDriver driver;
-
-    group('WebDriver', () {
-      group('create', () {
-        test('default', () {
-          WebDriver driver;
-          return WebDriver.createDriver()
-              .then((_driver) {
-                driver = _driver;
-              })
-              .then((_) => driver.get('http://www.google.com'))
-              .then((_) => driver.findElement(new By.name('q')))
-              .then((element) => element.name)
-              .then((name) {
-                expect(name, 'input');
-                return driver.quit();
-              });
-        });
-
-        test('chrome', () {
-          WebDriver driver;
-          return WebDriver
-              .createDriver(desiredCapabilities: Capabilities.chrome)
-              .then((_driver) {
-                driver = _driver;
-              })
-              .then((_) => driver.get('http://www.google.com'))
-              .then((_) => driver.findElement(new By.name('q')))
-              .then((element) => element.name)
-              .then((name) {
-                expect(name, 'input');
-                return driver.quit();
-              });
-        });
-
-        test('firefox', () {
-          WebDriver driver;
-          return WebDriver
-              .createDriver(desiredCapabilities: Capabilities.firefox)
-              .then((_driver) {
-                driver = _driver;
-              })
-              .then((_) => driver.get('http://www.google.com'))
-              .then((_) => driver.findElement(new By.name('q')))
-              .then((element) => element.name)
-              .then((name) {
-                expect(name, 'input');
-                return driver.quit();
-              });
-        });
-      });
-
-      group('methods', () {
-
-        setUp(() {
-          return WebDriver
-              .createDriver(desiredCapabilities: Capabilities.chrome)
-              .then((_driver) => driver = _driver)
-              .then((_) => driver.get(_testPagePath));
-        });
-
-        tearDown(() => driver.quit());
-
-        test('get', () {
-          return driver.get('http://www.google.com')
-              .then((_) => driver.findElement(new By.name('q')))
-              .then((_) => driver.get('http://www.yahoo.com'))
-              .then((_) => driver.findElement(new By.name('p')));
-        });
-
-        test('currentUrl', () {
-          return driver.currentUrl.then((url) {
-            expect(url, startsWith('file:'));
-            expect(url, endsWith('test_page.html'));
-            return driver.get('http://www.google.com');
-          })
-          .then((_) => driver.currentUrl)
-          .then((url) {
-            expect(url, contains('www.google.com'));
-          });
-        });
-
-        test('findElement -- success', () {
-          driver.findElement(new By.tagName('tr'))
-              .then(expectAsync1((element) {
-                expect(element, isWebElement);
-              }));
-        });
-
-        test('findElement -- failure', () {
-          return driver.findElement(new By.id('non-existent-id'))
-              .catchError((error) {
-                expect(error, isWebDriverError);
-              });
-        });
-
-        test('findElements -- 1 found', () {
-          return driver.findElements(new By.cssSelector('input[type=text]'))
-              .then((elements) {
-                expect(elements, hasLength(1));
-                expect(elements, everyElement(isWebElement));
-              });
-        });
-
-        test('findElements -- 4 found', () {
-          return driver.findElements(new By.tagName('td'))
-              .then((elements) {
-                expect(elements, hasLength(4));
-                expect(elements, everyElement(isWebElement));
-              });
-        });
-
-        test('findElements -- 0 found', () {
-          return driver.findElements(new By.id('non-existent-id'))
-              .then((elements) {
-                expect(elements, isEmpty);
-              });
-        });
-
-        test('pageSource', () {
-          return driver.pageSource.then((source) {
-            expect(source, contains('<title>test_page</title>'));
-          });
-        });
-
-        test('close/windowHandles', () {
-          int numHandles;
-          return driver.windowHandles
-              .then((handles) => numHandles = handles.length)
-              .then((_) =>
-                  driver.findElement(new By.partialLinkText('Open copy')))
-              .then((element) => element.click())
-              .then((_) => driver.close())
-              .then((_) => driver.windowHandles)
-              .then((handles) {
-                expect(handles, hasLength(numHandles));
-              });
-        });
-
-        test('windowHandle', () {
-          String origHandle;
-          String newHandle;
-          return driver.windowHandle
-              .then((_handle) => origHandle = _handle)
-              .then((_) =>
-                  driver.findElement(new By.partialLinkText('Open copy')))
-              .then((element) => element.click())
-              .then((_) => driver.windowHandles)
-              .then((handles) {
-                for (String aHandle in handles) {
-                  if (aHandle != origHandle) {
-                    newHandle = aHandle;
-                    return driver.switchTo.window(aHandle);
-                  }
-                }
-              })
-              .then((_) => driver.windowHandle)
-              .then((finalHandle) {
-                expect(finalHandle, newHandle);
-              });
-        });
-
-        // TODO(DrMarcII): Figure out why this doesn't pass
-//        test('activeElement', () {
-//          return driver.activeElement
-//              .then((element) {
-//                expect(element, isNull);
-//                return driver
-//                    .findElement(new By.cssSelector('input[type=text]'));
-//              })
-//              .then((element) => element.click())
-//              .then((_) => driver.activeElement)
-//              .then((element) => element.name)
-//              .then((name) {
-//                expect(name, 'input');
-//              });
-//        });
-
-        test('windows', () {
-          return driver.windows.then((windows) {
-            expect(windows, hasLength(isPositive));
-            expect(windows, everyElement(new isInstanceOf<Window>()));
-          });
-        });
-
-        test('execute', () {
-          WebElement button;
-          String script = '''
-              arguments[1].textContent = arguments[0];
-              return arguments[1];''';
-          return driver.findElement(new By.tagName('button'))
-              .then((_e) => button = _e)
-              .then((_) => driver.execute(script, ['new text', button]))
-              .then((WebElement e) {
-                expect(e.text, completion('new text'));
-              });
-        });
-
-        test('executeAsync', () {
-          WebElement button;
-          String script = '''
-              arguments[1].textContent = arguments[0];
-              arguments[2](arguments[1]);''';
-          return driver.findElement(new By.tagName('button'))
-              .then((_e) => button = _e)
-              .then((_) => driver.executeAsync(script, ['new text', button]))
-              .then((WebElement e) {
-                expect(e.text, completion('new text'));
-              });
-        });
-
-        test('captureScreenshot', () {
-          return driver.captureScreenshot()
-              .then((screenshot) {
-                expect(screenshot, hasLength(isPositive));
-                expect(screenshot, everyElement(new isInstanceOf<int>()));
-              });
-        });
-      });
-    });
-  }
-}
diff --git a/test/src/webelement_test.dart b/test/src/webelement_test.dart
deleted file mode 100644
index 3c46a90..0000000
--- a/test/src/webelement_test.dart
+++ /dev/null
@@ -1,205 +0,0 @@
-part of webdriver_test;
-
-class WebElementTest {
-  main() {
-
-    group('WebElement', () {
-
-      WebDriver driver;
-      WebElement table;
-      WebElement button;
-      WebElement form;
-      WebElement textInput;
-      WebElement checkbox;
-      WebElement disabled;
-      WebElement invisible;
-
-      setUp(() {
-        return WebDriver.createDriver(desiredCapabilities: Capabilities.chrome)
-            .then((_driver) => driver = _driver)
-            .then((_) => driver.get(_testPagePath))
-            .then((_) => driver.findElement(new By.tagName('table')))
-            .then((_element) => table = _element)
-            .then((_) => driver.findElement(new By.tagName('button')))
-            .then((_element) => button = _element)
-            .then((_) => driver.findElement(new By.tagName('form')))
-            .then((_element) => form = _element)
-            .then((_) =>
-                driver.findElement(new By.cssSelector('input[type=text]')))
-            .then((_element) => textInput = _element)
-            .then((_) =>
-                driver.findElement(new By.cssSelector('input[type=checkbox]')))
-            .then((_element) => checkbox = _element)
-            .then((_) =>
-                driver.findElement(new By.cssSelector('input[type=password]')))
-            .then((_element) => disabled = _element)
-            .then((_) => driver.findElement(new By.tagName('div')))
-            .then((_element) => invisible = _element);
-      });
-
-      tearDown(() => driver.quit());
-
-      test('click', () {
-        return button.click()
-          .then((_) => driver.switchTo.alert)
-          .then((alert) =>  alert.accept());
-      });
-
-      test('submit', () {
-        return form.submit()
-          .then((_) => driver.switchTo.alert)
-          .then((alert) {
-            // TODO(DrMarcII): Switch to hasProperty matchers
-            expect(alert.text, 'form submitted');
-            return alert.accept();
-          });
-      });
-
-      test('sendKeys', () {
-        return textInput.sendKeys('some keys')
-          .then((_) => textInput.attributes['value'])
-          .then((value) {
-            expect(value, 'some keys');
-          });
-      });
-
-      test('clear', () {
-        return textInput.sendKeys('some keys')
-          .then((_) => textInput.clear())
-          .then((_) => textInput.attributes['value'])
-          .then((value) {
-            expect(value, '');
-          });
-      });
-
-      test('enabled', () {
-        expect(table.enabled, completion(isTrue));
-        expect(button.enabled, completion(isTrue));
-        expect(form.enabled, completion(isTrue));
-        expect(textInput.enabled, completion(isTrue));
-        expect(checkbox.enabled, completion(isTrue));
-        expect(disabled.enabled, completion(isFalse));
-      });
-
-      test('displayed', () {
-        expect(table.displayed, completion(isTrue));
-        expect(button.displayed, completion(isTrue));
-        expect(form.displayed, completion(isTrue));
-        expect(textInput.displayed, completion(isTrue));
-        expect(checkbox.displayed, completion(isTrue));
-        expect(disabled.displayed, completion(isTrue));
-        expect(invisible.displayed, completion(isFalse));
-      });
-
-      test('location -- table', () {
-        return table.location.then((location) {
-          expect(location, isPoint);
-          // TODO(DrMarcII): Switch to hasProperty matchers
-          expect(location.x, isNonNegative);
-          expect(location.y, isNonNegative);
-        });
-      });
-
-      test('location -- invisible', () {
-        return invisible.location.then((location) {
-          expect(location, isPoint);
-          // TODO(DrMarcII): Switch to hasProperty matchers
-          expect(location.x, 0);
-          expect(location.y, 0);
-        });
-      });
-
-      test('size -- table', () {
-        return table.size.then((size) {
-          expect(size, isSize);
-          // TODO(DrMarcII): Switch to hasProperty matchers
-          expect(size.width, isNonNegative);
-          expect(size.height, isNonNegative);
-        });
-      });
-
-      test('size -- invisible', () {
-        return invisible.size.then((size) {
-          expect(size, isSize);
-          // TODO(DrMarcII): I thought these should be 0
-          // TODO(DrMarcII): Switch to hasProperty matchers
-          expect(size.width, isNonNegative);
-          expect(size.height, isNonNegative);
-        });
-      });
-
-      test('name', () {
-        expect(table.name, completion('table'));
-        expect(button.name, completion('button'));
-        expect(form.name, completion('form'));
-        expect(textInput.name, completion('input'));
-      });
-
-      test('text', () {
-        expect(table.text, completion('r1c1 r1c2\nr2c1 r2c2'));
-        expect(button.text, completion('button'));
-        expect(invisible.text, completion(''));
-      });
-
-      test('findElement -- success', () {
-        return table.findElement(new By.tagName('tr'))
-            .then((element) {
-              expect(element, isWebElement);
-            });
-      });
-
-      test('findElement -- failure', () {
-        return button.findElement(new By.tagName('tr'))
-            .catchError((error) {
-              expect(error, isWebDriverError);
-            });
-      });
-
-      test('findElements -- 1 found', () {
-        return form.findElements(new By.cssSelector('input[type=text]'))
-            .then((elements) {
-              expect(elements, hasLength(1));
-              expect(elements, everyElement(isWebElement));
-            });
-      });
-
-      test('findElements -- 4 found', () {
-        return table.findElements(new By.tagName('td'))
-            .then((elements) {
-              expect(elements, hasLength(4));
-              expect(elements, everyElement(isWebElement));
-            });
-      });
-
-      test('findElements -- 0 found', () {
-        return form.findElements(new By.tagName('td'))
-            .then((elements) {
-              expect(elements, isEmpty);
-            });
-      });
-
-      test('attributes', () {
-        expect(table.attributes['id'], completion('table1'));
-        expect(table.attributes['non-standard'],
-            completion('a non standard attr'));
-        expect(table.attributes['disabled'], completion(isNull));
-        expect(disabled.attributes['disabled'], completion('true'));
-      });
-
-      test('cssProperties', () {
-        expect(invisible.cssProperties['display'], completion('none'));
-        expect(invisible.cssProperties['background-color'],
-            completion('rgba(255, 0, 0, 1)'));
-        expect(invisible.cssProperties['direction'], completion('ltr'));
-      });
-
-      test('equals', () {
-        expect(invisible.equals(disabled), completion(isFalse));
-        return driver.findElement(new By.cssSelector('table'))
-          .then((element) {
-            expect(element.equals(table), completion(isTrue));
-          });
-      });
-    });
-  }
-}
diff --git a/test/src/window_test.dart b/test/src/window_test.dart
index 468680c..489ec0f 100644
--- a/test/src/window_test.dart
+++ b/test/src/window_test.dart
@@ -1,52 +1,54 @@
-part of webdriver_test;
+library webdriver_test.window;
 
-class WindowTest {
-  main() {
+import 'package:unittest/unittest.dart';
+import 'package:webdriver/webdriver.dart';
+import '../test_util.dart';
 
-    group('Window', () {
+void main() {
 
-      WebDriver driver;
+  group('Window', () {
 
-      setUp(() {
-        return WebDriver.createDriver(desiredCapabilities: Capabilities.chrome)
-            .then((_driver) => driver = _driver);
-      });
+    WebDriver driver;
 
-      tearDown(() => driver.quit());
+    setUp(() {
+      return WebDriver.createDriver(desiredCapabilities: Capabilities.chrome)
+          .then((_driver) => driver = _driver);
+    });
 
-      test('size', () {
-        return driver.window.setSize(new Size(400, 600))
-            .then((_) => driver.window.size)
-            .then((size) {
-              expect(size, isSize);
-              // TODO(DrMarcII): Switch to hasProperty matchers
-              expect(size.height, 400);
-              expect(size.width, 600);
-            });
-      });
+    tearDown(() => driver.quit());
 
-      test('location', () {
-        return driver.window.setLocation(new Point(10, 20))
-            .then((_) => driver.window.location)
+    test('size', () {
+      return driver.window.setSize(new Size(400, 600))
+          .then((_) => driver.window.size)
+          .then((size) {
+            expect(size, isSize);
+            // TODO(DrMarcII): Switch to hasProperty matchers
+            expect(size.height, 400);
+            expect(size.width, 600);
+          });
+    });
+
+    test('location', () {
+      return driver.window.setLocation(new Point(10, 20))
+          .then((_) => driver.window.location)
+          .then((point) {
+            expect(point, isPoint);
+            // TODO(DrMarcII): Switch to hasProperty matchers
+            expect(point.x, 10);
+            expect(point.y, 20);
+          });
+    });
+
+    // fails in some cases with multiple monitors
+    test('maximize', () {
+      return driver.window.maximize()
+          .then((_) => driver.window.location)
             .then((point) {
               expect(point, isPoint);
               // TODO(DrMarcII): Switch to hasProperty matchers
-              expect(point.x, 10);
-              expect(point.y, 20);
+              expect(point.x, 0);
+              expect(point.y, 0);
             });
-      });
-
-      // fails in some cases with multiple monitors
-      test('maximize', () {
-        return driver.window.maximize()
-            .then((_) => driver.window.location)
-              .then((point) {
-                expect(point, isPoint);
-                // TODO(DrMarcII): Switch to hasProperty matchers
-                expect(point.x, 0);
-                expect(point.y, 0);
-              });
-      });
     });
-  }
+  });
 }
diff --git a/test/test_util.dart b/test/test_util.dart
new file mode 100644
index 0000000..2ea87de
--- /dev/null
+++ b/test/test_util.dart
@@ -0,0 +1,30 @@
+library webdriver_test_util;
+
+import 'dart:io';
+import 'package:path/path.dart' as pathos;
+import 'package:unittest/unittest.dart';
+import 'package:webdriver/webdriver.dart';
+
+final Matcher isWebDriverError = new isInstanceOf<WebDriverError>();
+final Matcher isWebElement = new isInstanceOf<WebElement>();
+final Matcher isSize = new isInstanceOf<Size>();
+final Matcher isPoint = new isInstanceOf<Point>();
+
+String get testPagePath {
+  if(_testPagePath == null) {
+    _testPagePath = _getTestPagePath();
+  }
+  return _testPagePath;
+}
+
+String _getTestPagePath() {
+  var testPagePath = pathos.join(pathos.current, 'test', 'test_page.html');
+  testPagePath = pathos.absolute(testPagePath);
+  if(!FileSystemEntity.isFileSync(testPagePath)) {
+    throw new Exception('Could not find the test file at "$testPagePath".'
+        ' Make sure you are running tests from the root of the project.');
+  }
+  return pathos.toUri(testPagePath).toString();
+}
+
+String _testPagePath;
diff --git a/test/webdriver_test.dart b/test/webdriver_test.dart
index 389ae0f..858db1d 100644
--- a/test/webdriver_test.dart
+++ b/test/webdriver_test.dart
@@ -1,25 +1,16 @@
 library webdriver_test;
 
-import 'dart:io' as io;
-import 'package:path/path.dart' as pathos;
-import 'package:webdriver/webdriver.dart';
-import 'package:unittest/unittest.dart';
 import 'package:unittest/compact_vm_config.dart';
 
-part 'src/alert_test.dart';
-part 'src/keyboard_test.dart';
-part 'src/mouse_test.dart';
-part 'src/navigation_test.dart';
-part 'src/options_test.dart';
-part 'src/target_locator_test.dart';
-part 'src/webdriver_test.dart';
-part 'src/webelement_test.dart';
-part 'src/window_test.dart';
-
-final Matcher isWebDriverError = new isInstanceOf<WebDriverError>();
-final Matcher isWebElement = new isInstanceOf<WebElement>();
-final Matcher isSize = new isInstanceOf<Size>();
-final Matcher isPoint = new isInstanceOf<Point>();
+import 'src/alert_test.dart' as alert;
+import 'src/keyboard_test.dart' as keyboard;
+import 'src/mouse_test.dart' as mouse;
+import 'src/navigation_test.dart' as navigation;
+import 'src/options_test.dart' as options;
+import 'src/target_locator_test.dart' as target_locator;
+import 'src/web_driver_test.dart' as web_driver;
+import 'src/web_element_test.dart' as web_element;
+import 'src/window_test.dart' as window;
 
 /**
  * These tests are not expected to be run as part of normal automated testing,
@@ -28,23 +19,13 @@
 void main() {
   useCompactVMConfiguration();
 
-  new AlertTest().main();
-  new KeyboardTest().main();
-  new MouseTest().main();
-  new NavigationTest().main();
-  new OptionsTest().main();
-  new TargetLocatorTest().main();
-  new WebDriverTest().main();
-  new WebElementTest().main();
-  new WindowTest().main();
-}
-
-final _testPagePath = _getTestPagePath();
-
-String _getTestPagePath() {
-  var scriptPath = (new io.Options()).script;
-  var scriptDir = pathos.dirname(scriptPath);
-  var testPagePath = pathos.join(scriptDir, 'test_page.html');
-  testPagePath = pathos.absolute(testPagePath);
-  return pathos.toUri(testPagePath).toString();
+  alert.main();
+  keyboard.main();
+  mouse.main();
+  navigation.main();
+  options.main();
+  target_locator.main();
+  web_driver.main();
+  web_element.main();
+  window.main();
 }