diff --git a/.gitignore b/.gitignore
index 7d66c8f2a1e4676611797a4b5ecfb6b95bfff817..24d5788003525f864748d0714b6ae80152122a8e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,3 +18,4 @@ Thumbs.db
 /automation-tests/credentials.yaml
 /automation-tests/sauce.yaml
 automation-tests/persona_server/results/*
+/automation-tests/chromedriver.log
\ No newline at end of file
diff --git a/automation-tests/README.md b/automation-tests/README.md
index a78a9dd1f47a04158d1e94bc9536354f64962d85..5f23585901b64eea5d60f3d31643e52095b50bc1 100644
--- a/automation-tests/README.md
+++ b/automation-tests/README.md
@@ -1,7 +1,7 @@
 getting started
 ===============
 
-# I'm super impatient. Let's get going in 10 sec or less.
+# I'm super impatient. Let's get going in 10 sec or less. (But I don't run Windows)
 
 TL;DR: just execute ```./run.py``` from inside the automation-tests directory.
 
@@ -15,7 +15,7 @@ If you want to run that single test against your ephemeral instance called 'foo'
 
 If you want to run all the tests, create a dummy user, put its info in credentials.yaml, then do ```run.py --all``` to run all the tests, including 123done and myfavoritebeer tests.
 
-If you want to run all the tests against all the browsers, using sauce labs credentials, then do ```run.py --everywhere```.
+If you want to run all the tests against all the browsers, using any browsers the script can find locally, then do ```run.py --everywhere```.
 
 # I've got time. Tell me more!
 
@@ -23,7 +23,7 @@ OK, sure...
 
 ## how to run selenium tests inside the automation-tests directory against ephemeral, stage, or prod environments
 
-Node bindings aren't as mature as python for Selenium 2 API (webdriver), so we're using python bindings instead. This requires some python-centric setup, but it shouldn't take more than 15 minutes or so to get up and running.
+Node bindings aren't as mature as python for Selenium 2 API (webdriver), so we're using python bindings instead. This requires some python-centric setup, but it shouldn't take more than 15 minutes or so to get up and running, unless you're running Windows. See the bottom of this page for Windows setup instructions.
 
 These tests currently only hit myfavoritebeers and 123done domains. For example, to test an ephemeral install named foo.personatest.org, you can pass 'foo.123done.org' into the py.test baseurl parameter (this is covered again in the examples section).
 
@@ -114,3 +114,12 @@ Refer to [mozilla's pytest_mozwebqa](https://github.com/davehunt/pytest-mozwebqa
 
 A note about upstreaming bidpom changes: this codebase contains [mozilla's bidpom](https://github.com/mozilla/bidpom) as [git-subtree](https://github.com/apenwarr/git-subtree/blob/master/git-subtree.txt). This allows us to pull in changes from upstream, while easily tracking the bidpom code to branches. It's unlikely that we'll need to push or pull to upstream frequently, but for details on doing so, see also apenwarr's [blog post](http://apenwarr.ca/log/?m=200904#30).
 
+## Setting up Python in a Windows Environment
+
+Note: this post talks about python 2.5, but you need to install 2.6 or 2.7, and not 3.x.
+
+http://blog.sadphaeton.com/2009/01/20/python-development-windows-part-1installing-python.html
+http://blog.sadphaeton.com/2009/01/20/python-development-windows-part-2-installing-easyinstallcould-be-easier.html
+
+Alternately, think about running under cygwin instead.
+
diff --git a/automation-tests/browserid/pages/account_manager.py b/automation-tests/browserid/pages/account_manager.py
index 4a4e036dcd5f77c254beec95328d2d8132ca1216..3b97ce51193a4cfc4f2ca583878350541755f78d 100644
--- a/automation-tests/browserid/pages/account_manager.py
+++ b/automation-tests/browserid/pages/account_manager.py
@@ -28,7 +28,9 @@ class AccountManager(Base):
 
     @property
     def signed_in(self):
-        return not self.selenium.find_element(By.CSS_SELECTOR, 'body.not_authenticated')
+        WebDriverWait(self.selenium, self.timeout).until(
+            lambda s: s.execute_script('return jQuery.active == 0'))
+        return 'not_authenticated' not in self.selenium.find_element(By.TAG_NAME, 'body').get_attribute('class')
 
     @property
     def emails(self):
diff --git a/automation-tests/run.py b/automation-tests/run.py
index 42aac3023292a3d01e769377160350c817652a44..6e6f404151e8f6ae88da8bfeff57815ff8868c45 100755
--- a/automation-tests/run.py
+++ b/automation-tests/run.py
@@ -10,8 +10,12 @@ import sys
 # used to check for existence of virtualenv and pip.
 # lifted from: http://stackoverflow.com/questions/377017
 def which(program):
+    if platform.system() == 'Windows':
+        program += '.exe'
+
     def is_exe(fpath):
         return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
+
     fpath, fname = os.path.split(program)
     if fpath:
         if is_exe(program):
@@ -46,21 +50,12 @@ def main():
                       ' not the full domain name ("foo.123done.org")')
     parser.add_option('--everywhere', '-e', dest='run_everywhere', action='store_true',
                       help='like --all, but run all tests on all supported' +
-                           ' browsers using sauce labs credentials either' +
-                           ' specified in sauce.yaml or in environment' +
-                           ' variables PERSONA_SAUCE_USER, PERSONA_SAUCE_PASSWORD,' +
-                           ' and PERSONA_SAUCE_APIKEY.')
+                           ' browsers available locally.')
     options, arguments = parser.parse_args()
 
-    # you can't specify both --all and --everywhere
-    if options.run_everywhere and options.run_all:
-            sys.stderr.write("either use --all or --everywhere, not both")
-            exit(1)
-
     # 1. check that python is the right version 
-    # TODO: would 2.6 actually work?
-    if sys.version_info < (2,7,0):
-        sys.stderr.write('python 2.7 or later is required to run the tests\n')
+    if sys.version_info < (2,6,0):
+        sys.stderr.write('python 2.6 or later is required to run the tests\n')
         exit(1)
 
     # 2. check that virtualenv and pip exist. if not, bail.
@@ -83,75 +78,78 @@ def main():
     # 4. check the ephemeral instance to hit.
     host = options.target_hostname
 
-    # 5. check for/create sauce.yaml, if necessary
-    if options.run_everywhere:
-        # if sauce.yaml does not exist,
-        if not os.path.isfile('sauce.yaml'):
-            # look for environmental variables PERSONA_SAUCE_*
-            try:
-                username = os.environ['PERSONA_SAUCE_USER']
-                password = os.environ['PERSONA_SAUCE_PASSWORD']
-                api_key  = os.environ['PERSONA_SAUCE_APIKEY']
-            # if they are missing, bail
-            except KeyError:
-                sys.stderr.write('Sauce labs credentials are needed to run' +
-                    ' tests everywhere. Add credentials to sauce.yaml or, if' +
-                    ' you have access to persona dev secrets, check that' +
-                    ' the PERSONA_SAUCE_USER, PERSONA_SAUCE_PASSWORD, and' +
-                    ' PERSONA_SAUCE_APIKEY environmental variables are set.\n')
-                exit(1)
-            # if they are present, write them out to sauce.yaml
-            try:
-                saucefile = open('sauce.yaml', 'w')
-                saucefile.write('username: ' + username + '\n')
-                saucefile.write('password: ' + password + '\n')
-                saucefile.write('api-key: ' + api_key + '\n')
-                saucefile.close()
-            # if you can't open the file for editing, bail
-            except IOError:
-                sys.stderr.write('Unable to open sauce.yaml to write out' +
-                    ' credentials. Either create sauce.yaml manually, or' +
-                    ' ensure the test process has permission to create the file.\n')
-                exit(1)
-
-    # 6. run the tests
+    # 5 check for and/or create credentials.yaml
+    if not os.path.isfile('credentials.yaml'):
+        # look for env variables
+        try:
+            email = os.environ['PERSONA_EMAIL']
+            password = os.environ['PERSONA_PASSWORD']
+        # if they are missing, bail
+        except KeyError:
+            sys.stderr.write('Existing validated user credentials are needed to run' +
+                ' tests for 123done and myfavoritebeer. Please set them in the' +
+                ' PERSONA_EMAIL and PERSONA_PASSWORD environmental variables.\n')
+            exit(1)
+        # if they are present, write them out to credentials.yaml
+        try:
+            credentialsfile = open('credentials.yaml', 'w')
+            credentialsfile.write('default:\n')
+            credentialsfile.write('    email: ' + email + '\n')
+            credentialsfile.write('    password: ' + password + '\n')
+            credentialsfile.close()
+        #if you can't open the file for editing, bail
+        except IOError:
+            sys.stederr.write('Unalbe to open credentials.yaml to write out' +
+                ' credentials. Either create credentials.yaml manually or' +
+                ' ensure the test process has permission to create the file.\n')
+            exit(1)
 
-    # TODO move the run_everywhere list into a config file?
+    # 5.5 determine the browsers to use
+    # if the person is working for mozilla and doesn't have firefox installed, something is wrong
+    browsers = [('--driver=firefox ', 'local_firefox')]
     if options.run_everywhere:
-        browsers = ['--platform=LINUX --browsername=firefox --browserver=13 ',
-            '--platform=LINUX --browsername=opera   --browserver=12 ',
-            '--platform=MAC   --browsername=firefox --browserver=14 ',
-            '--platform=VISTA --browsername=chrome ',
-            '--platform=VISTA --browsername=firefox --browserver=13 ',
-            '--platform=VISTA --browsername="internet explorer" --browserver=9 ',
-            '--platform=XP    --browsername="internet explorer" --browserver=8 ']
-        sauce = '--saucelabs=sauce.yaml '
-    else:
-        browsers = ['--driver=firefox ']
-        sauce = ''
-
+        # Chrome
+        if not which('chromedriver'):
+            sys.stderr.write('In order to run tests with chrome, you must download the driver from' +
+                ' https://code.google.com/p/chromedriver/downloads/list' +
+                ' and put it on the PATH.')
+            exit(1)
+        browsers.append(('--driver=chrome ', 'local_chrome'))
+        # XXX IEDriver does not provide a clean environment for tests when run on a non-VM
+        # XXX Opera does not have a WebDriver implementation, can only be run
+        # via a selenium server
+                
+    # 6. run the tests
     for browser in browsers:
-        if options.run_everywhere or options.run_all:
-            subprocess.call(env_py + ' -m py.test --destructive ' +
-                '--credentials=credentials.yaml ' + sauce + browser + 
-                ' --webqatimeout=90 -m travis' +
-                ' --baseurl=http://' + host + '.123done.org -q browserid', shell=True)
-            subprocess.call(env_py + ' -m py.test --destructive ' +
-                '--credentials=credentials.yaml ' + sauce + browser + 
-                ' --webqatimeout=90' +
-                ' --baseurl=http://' + host + '.123done.org -q 123done', shell=True)
-            subprocess.call(env_py + ' -m py.test --destructive ' +
-                '--credentials=credentials.yaml ' + sauce + browser + 
-                ' --webqatimeout=90' +
-                ' --baseurl=http://' + host + '.myfavoritebeer.org -q myfavoritebeer', shell=True)
+        no_proxy_json = '--capabilities={\"avoid-proxy\":true}'
+        if options.run_all:
+            subprocess.call(env_py + ' -m py.test --destructive' +
+                ' --credentials=credentials.yaml ' + browser[0] + 
+                ' --webqatimeout=90 -m travis ' + no_proxy_json +
+                ' --webqareport=results/browserid/' + browser[1] + '.html' +
+                ' --baseurl=http://%s.123done.org -q browserid' % host, shell=True)
+            subprocess.call(env_py + ' -m py.test --destructive' +
+                ' --credentials=credentials.yaml ' + browser[0] + 
+                ' --webqatimeout=90 ' + no_proxy_json +
+                ' --webqareport=results/123done/' + browser[1] + '.html' +
+                ' --baseurl=http://%s.123done.org -q 123done' % host, shell=True)
+            subprocess.call(env_py + ' -m py.test --destructive' +
+                ' --credentials=credentials.yaml ' + browser[0] + 
+                ' --webqatimeout=90 ' + no_proxy_json +
+                ' --webqareport=results/myfavoritebeer/' + browser[1] + '.html' +
+                ' --baseurl=http://%s.myfavoritebeer.org -q myfavoritebeer' % host, shell=True)
         # only run one test in the default case
         else:
-            subprocess.call(env_py + ' -m py.test --destructive ' +
-                '--credentials=credentials.yaml ' + sauce + browser +
-                ' --baseurl=http://' + host + '.123done.org ' +
-                '-q 123done/tests/test_new_user.py', shell=True)
+            subprocess.call(env_py + ' -m py.test --destructive' +
+                ' --credentials=credentials.yaml ' + browser[0] +
+                ' --webqatimeout=90 ' + no_proxy_json +
+                ' --baseurl=http://%s.123done.org' % host +
+                ' --webqareport=results/test_new_user/' + browser[1] + '.html' +
+                ' -q 123done/tests/test_new_user.py', 
+                shell=True)
 
     # 7. TODO deactivate/destroy virtualenv?? maybe '--cleanup' argument?
+      # clean up credentials.yaml
 
 
 if __name__ == '__main__':