runFiles = ({ files, options, modules }) =>
  waterfall([
    () => modules.reporter.start(files),
    () => mapSeries(files, file =>
      modules.director.runFile(file)
        .then(races => mapSeries(races, race => {
          if (options.traces) {
            race.saveTrace(options.output)
          }

          race.createReport()
          if (options.reports) {
            race.saveReport(options.output)
          }

          return race
        }))
    ),
    races => modules.reporter.finish(flat(races))
  ])
/*.js']
  }

  // return matching files
  return globby(baton.files).then(paths => {
    if (paths.length === 0) {
      throw new Error('No files found!')
    }
    baton.files = paths
  })
}

// TODO: check what happens if one fails, how can we cleanup the others?
const initialize = baton =>
  series([
    () => launchChrome({
      flags: baton.options.chromeFlags,
      headless: baton.options.headless
    }),
    () => startServer({
      baseDir: process.cwd(),
      port: baton.options.port,
      clientPort: baton.options.runnerPort
    }),
    () => createRunnerServer({
      port: baton.options.runnerPort
    }),
    () => createDriver({
      port: baton.options.port
    }),
    () => createReporter(DEBUG ? 'noop' : 'compact')
  ]).then(modules => {
    baton.modules = {
      chrome: modules[0],
      server: modules[1],
      runner: modules[2],
      driver: modules[3],
      reporter: modules[4]
    }

    baton.modules.director = createDirector(baton.modules, baton.options)

    /* istanbul ignore next