Index: pyenvjasmine/runner.py
===================================================================
--- pyenvjasmine/runner.py	(revision 42)
+++ pyenvjasmine/runner.py	(revision 0)
@@ -1,7 +1,4 @@
 import os
-import sys
 import subprocess
-import threading
-import signal
 
 
@@ -10,5 +7,5 @@
     Get the environment parameter, depending on OS (Win/Unix).
     """
-    if os.name == 'nt':  # not tested!
+    if os.name == 'nt': # not tested!
         environment = '--environment=WIN'
     else:
@@ -17,82 +14,5 @@
 
 
-def print_no_newline(string):
-    sys.stdout.write(str(string))
-    sys.stdout.flush()
-
-
-def run_popen_with_timeout(
-        command, timeout, input_data, stdin, stdout, stderr, env=None):
-    """
-    Run a sub-program in subprocess.Popen, pass it the input_data,
-    kill it if the specified timeout has passed.
-    returns a tuple of success, stdout, stderr
-
-    sample usage:
-
-    timeout = 60  # seconds
-    path = '/path/to/event.log'
-    command = ['/usr/bin/tail', '-30', path]
-    input_data = ''
-    success, stdout, stderr = run_popen_with_timeout(command, timeout,
-                                                     input_data)
-    if not success:
-        print('timeout on tail event.log output')
-    tail_output = stdout
-    """
-    kill_check = threading.Event()
-
-    def _kill_process_after_a_timeout(pid):
-        try:
-            os.kill(pid, signal.SIGTERM)
-        except OSError:
-            # catch a possible race condition, the process terminated normally
-            # between the timer firing and our kill
-            return
-        kill_check.set()  # tell the main routine that we had to kill
-        # use SIGKILL if hard to kill...
-        return
-
-    stdout_l = []
-
-    # don't use shell if command/options come in as list
-    use_shell = not isinstance(command, list)
-    try:
-        p = subprocess.Popen(command, bufsize=1, shell=use_shell,
-                             stdin=stdin, stdout=stdout,
-                             stderr=stderr, env=env)
-    except OSError as error_message:
-        stderr = 'OSError: ' + str(error_message)
-        return (False, '', stderr)
-    pid = p.pid
-
-    watchdog = threading.Timer(timeout, _kill_process_after_a_timeout,
-                               args=(pid, ))
-    watchdog.start()
-
-    while True:
-        output = p.stdout.readline(1).decode('utf-8')
-        if output in ['', b''] and p.poll() is not None:
-            break
-        if output == '\n':
-            print(output)
-        else:
-            print_no_newline(output)
-        stdout_l.append(output)
-
-    try:
-        (stdout, stderr) = p.communicate(input_data)
-    except OSError as error_message:
-        stdout = ''
-        stderr = 'OSError: ' + str(error_message)
-        p.returncode = -666
-
-    watchdog.cancel()  # if it's still waiting to run
-    # if it timed out, success is False
-    success = (not kill_check.isSet()) and p.returncode >= 0
-    kill_check.clear()
-    return (success, ''.join(stdout_l), stderr)
-
-class Runner(object):
+class TestRunner(object):
     """
     Setup to run envjasmine "specs" (tests).
@@ -103,5 +23,5 @@
 
     def __init__(self, rootdir=None, testdir=None, configfile=None,
-                 browser_configfile=None, testing_environment='phantomjs'):
+                    browser_configfile=None):
         """
         Set up paths, by default everything is
@@ -119,81 +39,38 @@
                     the tests in browser.
         """
-        here = os.path.dirname(__file__)
-        self.libdir = here
-        self.rootdir = rootdir or os.path.join(here, 'envjasmine')
-        self.testdir = testdir or self.rootdir
+        if rootdir is None:
+            here = os.path.dirname(__file__)
+            rootdir = os.path.join(here, 'envjasmine')
+        if testdir is None:
+            testdir = rootdir
+        self.testdir = testdir
+        self.rootdir = rootdir
         self.configfile = configfile
         self.browser_configfile = browser_configfile
-        self.runner_js = os.path.join(here, 'run-jasmine3.js')
-        self.testing_environment = testing_environment
+
+    def run(self, spec=None, capture_output=True):
+        """
+        Run the js tests with envjasmine.
+        spec: (relative) path to a spec file (run only that spec)
+        Returns the output
+        """
         environment = get_environment()
-        rhino_path = os.path.join(self.rootdir, 'lib', 'rhino', 'js.jar')
-        envjasmine_js_path = os.path.join(self.rootdir, 'lib', 'envjasmine.js')
+        rhino_path = os.path.join(self.rootdir,
+                                    'lib', 'rhino', 'js.jar')
+        envjasmine_js_path = os.path.join(self.rootdir,
+                                    'lib', 'envjasmine.js')
         rootdir_param = '--rootDir=%s' % self.rootdir
         testdir_param = '--testDir=%s' % self.testdir
-
-        # using a dictionary to parameterize the different engines
-        self.envs = {
-            'phantomjs' : {
-                'command' : [
-                    'phantomjs',
-                    '--debug=true',
-                    self.runner_js,
-                    'browser.runner.html'
-                ],
-                'runner_html' : 'runner3.html',
-                'failed_mark' : 'FAILED',
-                'success_mark' : '0 failures'
-            },
-            'rhino' : {
-                'command' : [
-                    'java',
-                    '-Duser.timezone=US/Eastern',
-                    '-Dfile.encoding=utf-8',
-                    '-jar',
-                    rhino_path,
-                    envjasmine_js_path,
-                    '--disableColor',
-                    environment,
-                    rootdir_param,
-                    testdir_param
-                ],
-                'runner_html' : 'runner.html',
-                'failed_mark' : 'FAILED',
-                'success_mark' : 'Failed: 0',
-                'command_params_func' : self.command_params_rhino
-            }
-        }
-        self.runner_html = os.path.join(here,
-                              self.envs[self.testing_environment]['runner_html'])
-
-    def command_params_rhino(self, command):
-        """
-        Function specific to Rhino to add eventual arguments to the command line.
-        The function is referenced in the dictionary "envs" with key
-        "command_params_func", and for every engine that needs the same type of
-        manipulation there will be a similar function with relative reference in
-        the dictionary
-        """
-        if self.configfile and os.path.exists(self.configfile):
-           command.append('--configFile=%s' % self.configfile)
-        return command
-
-    def run(self, spec=None, timeout=None):
-        """
-        Run the js tests with envjasmine, return success (true/false) and
-        the captured stdout data
-
-        spec: (relative) path to a spec file (run only that spec)
-        timeout: Set it to a given number of seconds and the process running
-                 the js tests will be killed passed that time
-        """
         if self.browser_configfile and os.path.exists(self.browser_configfile):
             self.write_browser_htmlfile()
-        command = self.envs[self.testing_environment]['command']
-        # Add eventual other parameters to the command by calling a
-        # function specific for the selected engine (rhino, phantomjs, etc.)
-        if 'command_params_func' in self.envs[self.testing_environment]:
-            command = self.envs[self.testing_environment]['command_params_func'](command)
+
+        command = ['java', '-Duser.timezone=US/Eastern',
+                '-Dfile.encoding=utf-8', '-jar', rhino_path,
+                envjasmine_js_path,
+                '--disableColor',
+                environment, rootdir_param, testdir_param
+                ]
+        if self.configfile and os.path.exists(self.configfile):
+            command.append('--configFile=%s' % self.configfile)
         # if we were asked to test only some of the spec files,
         # addd them to the command line:
@@ -202,46 +79,85 @@
                 spec = [spec]
             command.extend(spec)
-
-        # shell = False
-        stdin = None
-        stdout = subprocess.PIPE
-        stderr = subprocess.PIPE
-        input_data = ''
-        success, stdout, stderr = run_popen_with_timeout(
-            command, timeout, input_data, stdin, stdout, stderr
-        )
-
-        # success will be true if the subprocess did not timeout, now look
-        # for actual failures if there was not a timeout
-        if success:
-            success = self.did_test_pass(stdout)
-        return success, stdout
-
-    def did_test_pass(self, stdout):
-        if self.envs[self.testing_environment]['failed_mark'] in stdout:
-            # it can happen that a test fails because of some timing issues
-            # (timer error). In such case it may happen that the test does
-            # not appear in the "Failed" report at the end, even if it
-            # failed, because the execution is interrupted there (no more
-            # tests are even run afterwards)
-            #
-            # in such case, we consider tests failed
-            return False
-        # Otherwise, look for a "Failed: 0" status, which we consider as
-        # tests passing ok
-        for line in stdout.splitlines():
-            if self.envs[self.testing_environment]['success_mark'] in line:
-                return True
-        return False
+        shell = False
+        if capture_output:
+            stdout = subprocess.PIPE
+            stderr = subprocess.PIPE
+        else:
+            stdout = None
+            stderr = None
+        p = subprocess.Popen(command, shell=shell,
+                            stdout=stdout, stderr=stderr)
+        (res, stderr) = p.communicate()
+        return res
 
     def write_browser_htmlfile(self):
         markup = self.create_testRunnerHtml()
-        with open("browser.runner.html", 'w') as file:
+        with open("browser.runner.html",'w') as file:
             file.write(markup)
 
     def create_testRunnerHtml(self):
-        with open(self.runner_html, 'r') as runner_html:
-            html = runner_html.read()
-            return html % {"libDir": os.path.normpath(self.libdir),
-                           "testDir": os.path.normpath(self.testdir),
-                           "browser_configfile": self.browser_configfile}
+        return """
+        <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+          "http://www.w3.org/TR/html4/loose.dtd">
+        <html>
+        <head>
+          <title></title>
+          <link rel="stylesheet" type="text/css" href="file:///%(libDir)s/envjasmine/lib/jasmine/jasmine.css">
+
+          <script type="text/javascript" src="file:///%(libDir)s/envjasmine/lib/jasmine/jasmine.js"></script>
+          <script type="text/javascript" src="file:///%(libDir)s/envjasmine/lib/jasmine/jasmine-html.js"></script>
+          <script type="text/javascript" src="file:///%(libDir)s/envjasmine/lib/jasmine-ajax/mock-ajax.js"></script>
+          <script type="text/javascript" src="file:///%(libDir)s/envjasmine/lib/jasmine-ajax/spec-helper.js"></script>
+          <script type="text/javascript" src="file:///%(libDir)s/envjasmine/lib/jasmine-jquery/jasmine-jquery.js"></script>
+
+          <script type="text/javascript" src="browser.runner.js"></script>
+          <script type="text/javascript">
+              (function () {
+                  "use strict";
+                  var jasmineEnv = jasmine.getEnv();
+                  jasmineEnv.updateInterval = 1000;
+
+                  var trivialReporter = new jasmine.TrivialReporter();
+                  jasmineEnv.addReporter(trivialReporter);
+                  jasmineEnv.specFilter = function (spec) {
+                      return trivialReporter.specFilter(spec);
+                  };
+
+                  var currentWindowOnload = window.onload;
+
+                  window.onload = function () {
+                      if (currentWindowOnload) {
+                          currentWindowOnload();
+                      }
+                      execJasmine();
+                  };
+
+                  function execJasmine() {
+                      jasmineEnv.execute();
+                  }
+              })();
+              var EnvJasmine = {};
+              EnvJasmine.jsDir = "";
+              EnvJasmine.testDir = "%(testDir)s";
+              EnvJasmine.load = function (path) {
+                  appendScript(path);
+              };
+              EnvJasmine.loadGlobal = function (path) {
+                  appendScript(path);
+              };
+              function appendScript(path){
+                  var script = document.createElement('script');
+                  script.src = path;
+                  script.type ='text/javascript';
+                  document.getElementsByTagName('head')[0].appendChild(script);
+              }
+          </script>
+          <script type="text/javascript" src="%(browser_configfile)s"></script>
+        </head>
+        <body>
+        </body>
+        </html>
+        """ %{"libDir": os.path.normpath(os.path.dirname(__file__)),
+              "testDir": os.path.normpath(self.testdir),
+              "browser_configfile": self.browser_configfile}
+
