TheBrainFamily/chimpy

View on GitHub
src/lib/versions.js

Summary

Maintainability
D
2 days
Test Coverage
const _ = require('underscore'),
  fs = require('fs'),
  os = require('os'),
  log = require('./log'),
  async = require('async'),
  request = require('request'),
  spawnSync = require('child_process').spawnSync,
  selenium = require('selenium-standalone'),
  chromedriver = require('chromedriver'),
  booleanHelper = require('./boolean-helper'),
  processHelper = require('./process-helper.js');

function Versions(options) {
  this.options = options;

  this.appDir = '../..';
  this.chromeDriverExec = chromedriver.path;

  this.show = (callback) => {
    console.log('Chimp version: ', this.getChimpVersion());
    console.log('ChromeDriver version: ', this.getChromeDriverVersion());
    console.log('Java version: ', this.getJavaVersion());
    console.log('Selenium version: ', this.getSeleniumVersion());
    console.log('Selenium drivers version: ', this.getSeleniumDriversVersion());
    console.log('OS version: ', this.getOsVersion());
    console.log('Node version: ', this.getNodeVersion());
    this.getCurrentBrowserVersion((browserVersion) => {
      const currentBrowser = this.options.browser || 'chrome';
      console.log('Browser version: ', currentBrowser, browserVersion);
      if (callback) {
        callback();
      }
    });
  };

  this.getChimpVersion = () => {
    const packageJson = require(`${this.appDir}/package.json`);
    return packageJson.version;
  };

  this.getChromeDriverVersion = () => {
    if (booleanHelper.isFalsey(this.options.host)) {
      if (booleanHelper.isTruthy(this.options.browser)) {
        return 'Unknown. Chromedriver not used directly.';
      }

      return this._spawnSync(`${this.chromeDriverExec} -v`);
    }

    return 'Unknown. Selenium host provided.';
  };

  this.getJavaVersion = () => this._spawnSync('java -version');

  this.getSeleniumVersion = () => {
    if (this.options.seleniumStandaloneOptions) {
      return this.options.seleniumStandaloneOptions.version;
    }
    return 'Unknown.';
  };

  this.getSeleniumDriversVersion = () => {
    if (this.options.seleniumStandaloneOptions) {
      const driversVersion = [];
      const drivers = this.options.seleniumStandaloneOptions.drivers;
      _.each(_.keys(drivers), (driverName) => {
        driversVersion.push(`${driverName}: ${drivers[driverName].version}`);
      });
      return driversVersion.toString().replace(/,/g, ', ');
    }
    return 'Unknown.';
  };

  this.getOsVersion = () => `${os.type()} ${os.release()}`;

  this.getNodeVersion = () => process.version;

  this.getCurrentBrowserVersion = (callback) => {
    if (booleanHelper.isTruthy(this.options.browser)) {
      const seleniumOptions = _.clone(this.options.seleniumStandaloneOptions);
      seleniumOptions.port = 1;

      async.series([
        (cb) => {
          selenium.install(
                            seleniumOptions
                            , (err, seleniumInstallPaths) => {
                              cb(err, seleniumInstallPaths);
                            });
        },
      ],
                (err, seleniumInstallPaths) => {
                  const selectedBrowserDriver = seleniumInstallPaths[0][this.options.browser];
                  if (selectedBrowserDriver) {
                    const startBrowserOptions = {
                      path: selectedBrowserDriver.installPath,
                      port: this.options.port,
                    };
                    this._startBrowserDriver(startBrowserOptions, () => {
                      this._getBrowserVersion(startBrowserOptions, (err, browserVersion) => {
                        this._stopBrowserDriver((err) => {
                          if (err) {
                            log.warn(err);
                          }
                          callback(browserVersion);
                        });
                      });
                    });
                  } else {
                    callback(`Driver for selected browser(${this.options.browser}) not found.`);
                  }
                },
            );
    } else if (fs.existsSync(this.chromeDriverExec)) {
      const startBrowserOptions = {
        path: this.chromeDriverExec,
        port: this.options.port,
      };
      this._startBrowserDriver(startBrowserOptions, () => {
        this._getBrowserVersion(startBrowserOptions, (err, browserVersion) => {
          this._stopBrowserDriver((err) => {
            if (err) {
              log.warn(err);
            }
            callback(browserVersion);
          });
        });
      });
    } else {
      callback('Driver for selected browser not found.');
    }
  };

    // -------------------------------------------------------------------------------------

  this._startBrowserDriver = (options, callback) => {
    const waitMessage = new RegExp(`${options.port}`);
    this.child = processHelper.start({
      bin: options.path,
      prefix: 'browserdriver',
      args: [`--port=${options.port}`],
      waitForMessage: waitMessage,
      errorMessage: /Error/,
    }, callback);
  };

  this._getBrowserVersion = (options, callback) => {
    const url = `http://localhost:${options.port}/session`;
    const data = {desiredCapabilities: {}};

    request.post(
      {
        url,
        json: true,
        body: data,
      },
            (error, response, body) => {
              const data = {};
              if (!error && response.statusCode === 200) {
                data.sessionId = body.sessionId;
                data.browserVersion = body.value.version;
                request.delete(`${url}/${data.sessionId}`,
                        () => {
                          callback(null, data.browserVersion);
                        },
                    );
              } else {
                error = 'Error connecting to browser driver.';
                callback(error);
              }
            },
        );
  };

  this._stopBrowserDriver = (callback) => {
    if (this.child) {
      const options = {
        child: this.child,
        prefix: 'browserdriver',
      };

      processHelper.kill(options, (err, res) => {
        this.child = null;
        callback(err, res);
      });
    } else {
      callback(null);
    }
  };

  this._spawnSync = (commandToRun) => {
    const endLine = new RegExp(`${os.EOL}`, 'g');
    const commandOptions = commandToRun.split(' ');
    const command = commandOptions.shift();
    const commandResult = spawnSync(command, commandOptions);
    if (commandResult.status !== 0 && commandResult.error) {
      if (commandResult.error.code === 'ENOENT') {
        return 'No such file or directory';
      }

      return `Error ${commandResult.error.code}`;
    }

    let commandToReturn = '';
    _.each(commandResult.output, (output) => {
      if (output && output.length) {
        commandToReturn += output.toString().trim();
      }
    });
    return commandToReturn.replace(endLine, ', ');
  };
}

module.exports = Versions;