text: const _ = require('lodash')
  const os = require('os')
  const path = require('path')
  const sinon = require('sinon')
  const mockfs = require('mock-fs')
  const Promise = require('bluebird')
  const util = require('../lib/util')
  const { MockChildProcess } = require('spawn-mock')
  const _kill = MockChildProcess.prototype.kill
  
  const patchMockSpawn = () => {
  
    MockChildProcess.prototype.kill = function (...args) {
  
      this.emit('exit')
  
      return _kill.apply(this, args)
    }
  }
  
  patchMockSpawn()
  
  global.sinon = sinon
  global.expect = require('chai').expect
  global.lib = path.join(__dirname, '..', 'lib')
  
  require('chai')
  .use(require('@cypress/sinon-chai'))
  .use(require('chai-string'))
  .use(require('chai-as-promised'))
  
  sinon.usingPromise(Promise)
  
  delete process.env.CYPRESS_RUN_BINARY
  delete process.env.CYPRESS_INSTALL_BINARY
  delete process.env.CYPRESS_CACHE_FOLDER
  delete process.env.CYPRESS_BINARY_VERSION
  delete process.env.CYPRESS_SKIP_BINARY_INSTALL
  delete process.env.CYPRESS_DOWNLOAD_MIRROR
  delete process.env.DISPLAY
  
  // enable running specs with --silent w/out affecting logging in tests
  process.env.npm_config_loglevel = 'notice'
  
  const env = _.clone(process.env)
  
  function throwIfFnNotStubbed (stub, method) {
    const sig = `.${method}(...)`
  
    stub.callsFake(function (...args) {
      const err = new Error(`${sig} was called without being stubbed.
  
        ${sig} was called with arguments:
  
        ${args.map(JSON.stringify).join(', ')}
      `)
  
      err.stack = _
      .chain(err.stack)
      .split('\n')
      .reject((str) => {
        return _.includes(str, 'sinon')
      })
      .join('\n')
      .value()
  
      throw err
    })
  }
  
  const $stub = sinon.stub
  
  sinon.stub = function (obj, method) {
    /* eslint-disable prefer-rest-params */
    const stub = $stub.apply(this, arguments)
  
    let fns = [method]
  
    if (arguments.length === 1) {
      fns = _.functions(obj)
    }
  
    if (arguments.length === 0) {
      throwIfFnNotStubbed(stub, '[anonymous function]')
  
      return stub
    }
  
    fns.forEach((name) => {
      const fn = obj[name]
  
      if (_.isFunction(fn)) {
        throwIfFnNotStubbed(fn, name)
      }
    })
  
    return stub
  }
  
  beforeEach(function () {
    sinon.stub(os, 'platform')
    sinon.stub(os, 'release')
    sinon.stub(util, 'getOsVersionAsync').resolves('Foo-OsVersion')
  })
  
  afterEach(function () {
    mockfs.restore()
    process.env = _.clone(env)
    sinon.restore()
  })
  