| Index: test_runner.js | 
| =================================================================== | 
| --- a/test_runner.js | 
| +++ b/test_runner.js | 
| @@ -21,21 +21,46 @@ | 
|  | 
| const fs = require("fs"); | 
| const path = require("path"); | 
|  | 
| const MemoryFS = require("memory-fs"); | 
| const nodeunit = require("nodeunit"); | 
| const webpack = require("webpack"); | 
|  | 
| -const chromiumProcess = require("./chromium_process"); | 
| +const chromiumProcess = require("./test/runners/chromium_process"); | 
| +const chromiumWdProcess = require("./test/runners/chromiumwd_process"); | 
| +const firefoxProcess = require("./test/runners/firefox_process"); | 
|  | 
| let unitFiles = []; | 
| let browserFiles = []; | 
|  | 
| +let runnerDefinitions = { | 
| +  // Chromium with chrome-remote-interface | 
| +  chromium_remote: chromiumProcess, | 
| +  // Chromium with WebDriver ( >= 63.0.3239) | 
| +  chromium: chromiumWdProcess, | 
| +  firefox: firefoxProcess | 
| +}; | 
| + | 
| +function configureRunners() | 
| +{ | 
| +  let runners = "BROWSER_TEST_RUNNERS" in process.env ? | 
| +      process.env.BROWSER_TEST_RUNNERS.split(",") : []; | 
| + | 
| +  if (runners.length == 0) | 
| +    return ["chromium", "firefox"]; | 
| + | 
| +  runners.filter(runner => runnerDefinitions.hasOwnProperty(runner)); | 
| + | 
| +  return runners; | 
| +} | 
| + | 
| +let runnerProcesses = configureRunners(); | 
| + | 
| function addTestPaths(testPaths, recurse) | 
| { | 
| for (let testPath of testPaths) | 
| { | 
| let stat = fs.statSync(testPath); | 
| if (stat.isDirectory()) | 
| { | 
| if (recurse) | 
| @@ -88,17 +113,17 @@ | 
| let bundle = memoryFS.readFileSync("/" + bundleFilename, "utf-8"); | 
| memoryFS.unlinkSync("/" + bundleFilename); | 
| resolve(bundle); | 
| } | 
| }); | 
| }); | 
| } | 
|  | 
| -function runBrowserTests() | 
| +function runBrowserTests(processes) | 
| { | 
| if (!browserFiles.length) | 
| return; | 
|  | 
| let nodeunitPath = path.join(__dirname, "node_modules", "nodeunit", | 
| "examples", "browser", "nodeunit.js"); | 
| let bundleFilename = "bundle.js"; | 
|  | 
| @@ -117,38 +142,41 @@ | 
| }, | 
| resolve: { | 
| alias: { | 
| nodeunit$: nodeunitPath | 
| }, | 
| modules: [path.resolve(__dirname, "lib")] | 
| } | 
| }).then(bundle => | 
| -  { | 
| -    return chromiumProcess( | 
| -      bundle, bundleFilename, | 
| -      browserFiles.map( | 
| -        file => path.relative(path.join(__dirname, "test", "browser"), | 
| -                              file).replace(/\.js$/, "") | 
| +    Promise.all( | 
| +      processes.map(currentProcess => | 
| +        runnerDefinitions[currentProcess]( | 
| +          bundle, bundleFilename, | 
| +          browserFiles.map( | 
| +            file => path.relative(path.join(__dirname, "test", "browser"), | 
| +                                  file).replace(/\.js$/, "") | 
| +          ) | 
| +        ) | 
| ) | 
| -    ); | 
| -  }); | 
| +    ) | 
| +  ); | 
| } | 
|  | 
| if (process.argv.length > 2) | 
| addTestPaths(process.argv.slice(2), true); | 
| else | 
| { | 
| addTestPaths( | 
| [path.join(__dirname, "test"), path.join(__dirname, "test", "browser")], | 
| true | 
| ); | 
| } | 
|  | 
| -Promise.resolve(runBrowserTests()).catch(error => | 
| +Promise.resolve(runBrowserTests(runnerProcesses)).catch(error => | 
| { | 
| console.error("Failed running browser tests"); | 
| console.error(error); | 
| }).then(() => | 
| { | 
| if (unitFiles.length) | 
| nodeunit.reporters.default.run(unitFiles); | 
| }); | 
|  |