function start()

in lib/cmds/start.ts [69:267]


function start(options: Options) {
  if (options[Opt.DETACH].getBoolean()) {
    return detachedRun(options);
  }

  let osType = Config.osType();
  let stdio = options[Opt.QUIET].getBoolean() ? 'pipe' : 'inherit';
  let binaries = FileManager.setupBinaries();
  let seleniumPort = options[Opt.SELENIUM_PORT].getString();
  let appiumPort = options[Opt.APPIUM_PORT].getString();
  let avdPort = options[Opt.AVD_PORT].getNumber();
  let android = options[Opt.ANDROID].getBoolean();
  let outputDir = Config.getSeleniumDir();
  if (options[Opt.OUT_DIR].getString()) {
    if (path.isAbsolute(options[Opt.OUT_DIR].getString())) {
      outputDir = options[Opt.OUT_DIR].getString();
    } else {
      outputDir = path.resolve(Config.getBaseDir(), options[Opt.OUT_DIR].getString());
    }
  }

  try {
    // check if folder exists
    fs.statSync(outputDir).isDirectory();
  } catch (e) {
    // if the folder does not exist, quit early.
    logger.warn('the out_dir path ' + outputDir + ' does not exist, run webdriver-manager update');
    return;
  }

  let chromeLogs: string = null;
  let loggingFile: string = null;
  if (options[Opt.CHROME_LOGS].getString()) {
    if (path.isAbsolute(options[Opt.CHROME_LOGS].getString())) {
      chromeLogs = options[Opt.CHROME_LOGS].getString();
    } else {
      chromeLogs = path.resolve(Config.getBaseDir(), options[Opt.CHROME_LOGS].getString());
    }
  }
  binaries[Standalone.id].versionCustom = options[Opt.VERSIONS_STANDALONE].getString();
  binaries[ChromeDriver.id].versionCustom = options[Opt.VERSIONS_CHROME].getString();
  binaries[GeckoDriver.id].versionCustom = options[Opt.VERSIONS_GECKO].getString();
  if (options[Opt.VERSIONS_IE]) {
    binaries[IEDriver.id].versionCustom = options[Opt.VERSIONS_IE].getString();
  }
  binaries[AndroidSDK.id].versionCustom = options[Opt.VERSIONS_ANDROID].getString();
  binaries[Appium.id].versionCustom = options[Opt.VERSIONS_APPIUM].getString();
  let downloadedBinaries = FileManager.downloadedBinaries(outputDir);

  if (downloadedBinaries[Standalone.id] == null) {
    logger.error(
        'Selenium Standalone is not present. Install with ' +
        'webdriver-manager update --standalone');
    process.exit(1);
  }
  let promises: q.IPromise<any>[] = [];
  let args: string[] = [];
  if (osType === 'Linux') {
    // selenium server may take a long time to start because /dev/random is BLOCKING if there is not
    // enough entropy the solution is to use /dev/urandom, which is NON-BLOCKING (use /dev/./urandom
    // because of a java bug)
    // https://github.com/seleniumhq/selenium-google-code-issue-archive/issues/1301
    // https://bugs.openjdk.java.net/browse/JDK-6202721
    promises.push(Promise.resolve(args.push('-Djava.security.egd=file:///dev/./urandom')));
  }
  if (options[Opt.LOGGING].getString()) {
    if (path.isAbsolute(options[Opt.LOGGING].getString())) {
      loggingFile = options[Opt.LOGGING].getString();
    } else {
      loggingFile = path.resolve(Config.getBaseDir(), options[Opt.LOGGING].getString());
    }
    promises.push(Promise.resolve(args.push('-Djava.util.logging.config.file=' + loggingFile)));
  }

  if (downloadedBinaries[ChromeDriver.id] != null) {
    let chrome: ChromeDriver = binaries[ChromeDriver.id];
    promises.push(
        chrome.getUrl(chrome.versionCustom)
            .then(() => {
              args.push(
                  '-Dwebdriver.chrome.driver=' +
                  path.resolve(outputDir, binaries[ChromeDriver.id].executableFilename()));
              if (chromeLogs != null) {
                args.push('-Dwebdriver.chrome.logfile=' + chromeLogs);
              }
            })
            .catch(err => {
              console.log(err);
            }));
  }
  if (downloadedBinaries[GeckoDriver.id] != null) {
    let gecko: GeckoDriver = binaries[GeckoDriver.id];
    promises.push(gecko.getUrl(gecko.versionCustom)
                      .then(() => {
                        args.push(
                            '-Dwebdriver.gecko.driver=' +
                            path.resolve(outputDir, binaries[GeckoDriver.id].executableFilename()));
                      })
                      .catch(err => {
                        console.log(err);
                      }));
  }
  if (downloadedBinaries[IEDriver.id] != null) {
    let ie: IEDriver = binaries[IEDriver.id];
    promises.push(ie.getUrl(ie.versionCustom)
                      .then(() => {
                        binaries[IEDriver.id].osarch = 'Win32';  // use Win 32 by default
                        if (options[Opt.IE64].getBoolean()) {
                          binaries[IEDriver.id].osarch =
                              Config.osArch();  // use the system architecture
                        }
                        args.push(
                            '-Dwebdriver.ie.driver=' +
                            path.resolve(outputDir, binaries[IEDriver.id].executableFilename()));
                      })
                      .catch(err => {
                        console.log(err);
                      }));
  }
  if (options[Opt.EDGE] && options[Opt.EDGE].getString()) {
    // validate that the file exists prior to adding it to args
    try {
      let edgeFile = options[Opt.EDGE].getString();
      if (fs.statSync(edgeFile).isFile()) {
        promises.push(
            Promise.resolve(args.push('-Dwebdriver.edge.driver=' + options[Opt.EDGE].getString())));
      }
    } catch (err) {
      // Either the default file or user specified location of the edge
      // driver does not exist.
    }
  }

  Promise.all(promises).then(() => {
    let standalone: Standalone = binaries[Standalone.id];
    standalone.getUrl(standalone.versionCustom)
        .then(() => {
          // starting android
          if (android) {
            if (downloadedBinaries[AndroidSDK.id] != null) {
              let avds = options[Opt.AVDS].getString();
              startAndroid(
                  outputDir, binaries[AndroidSDK.id], avds.split(','),
                  options[Opt.AVD_USE_SNAPSHOTS].getBoolean(), avdPort, stdio);
            } else {
              logger.warn('Not starting android because it is not installed');
            }
          }
          if (downloadedBinaries[Appium.id] != null) {
            startAppium(outputDir, binaries[Appium.id], binaries[AndroidSDK.id], appiumPort, stdio);
          }

          args.push('-jar');
          args.push(path.resolve(outputDir, binaries[Standalone.id].filename()));
        })
        .catch(err => {
          console.log(err);
        })
        .then(() => {
          // Add the port parameter, has to declared after the jar file
          if (seleniumPort) {
            args.push('-port', seleniumPort);
          }

          let argsToString = '';
          for (let arg in args) {
            argsToString += ' ' + args[arg];
          }
          logger.info('java' + argsToString);

          let seleniumProcess = spawn('java', args, stdio);
          if (options[Opt.STARTED_SIGNIFIER].getString()) {
            signalWhenReady(
                options[Opt.STARTED_SIGNIFIER].getString(),
                options[Opt.SIGNAL_VIA_IPC].getBoolean(), outputDir, seleniumPort,
                downloadedBinaries[Appium.id] ? appiumPort : '', binaries[AndroidSDK.id], avdPort,
                androidActiveAVDs);
          }
          logger.info('seleniumProcess.pid: ' + seleniumProcess.pid);
          seleniumProcess.on('exit', (code: number) => {
            logger.info('Selenium Standalone has exited with code ' + code);
            shutdownEverything();
            process.exit(process.exitCode || code);
          });
          seleniumProcess.on('error', (error: Error) => {
            logger.warn('Selenium Standalone server encountered an error: ' + error);
          });
          process.stdin.resume();
          process.stdin.on('data', (chunk: Buffer) => {
            logger.info('Attempting to shut down selenium nicely');
            shutdownEverything(seleniumPort);
          });
          process.on('SIGINT', () => {
            logger.info('Staying alive until the Selenium Standalone process exits');
            shutdownEverything(seleniumPort);
          });
        });
  });
}