mirror of
https://github.com/cypress-io/cypress.git
synced 2026-01-30 11:00:35 -06:00
* https-proxy: unused file * server: wrap all https requests that use a proxy * server: use request lib in ensureUrl if proxy is in use. this makes runs tab work behind a proxy * electron: pass --proxy-server to app itself, so the embedded github login page works * cli: first attempt at env vars from windows registry * cli: api cleanup * cli: lint * cli: fix crash on no proxy, add tests * add desktop-gui watch to terminals.json * cli: pass along --proxy-source * electron: pass --proxy-bypass-list too * server: whitelist proxy* args * cli: better wording * desktop-gui: display proxy settings * extension: force proxy [wip] * extension: finally, i am victorious over coffeescript * extension: add -loopback to bypasslist * extension: revert changes Revert "extension: force proxy [wip]" This reverts commit 3ab6ba42a763f25ee65f12eb8b79eb597efc9b11. * desktop-gui: skip proxysettings if there aren't any * https-proxy, server: proxy directConnections using https-proxy-agent * https-agent: pool httpsAgents * https-proxy: work when they're not on a proxy * https-proxy: ci - use agent 1.0 * https-proxy: tests * desktop-gui: hide proxy settings when not using proxy * https-proxy: pass req through to https-proxy-agent callback * cli: use get-windows-proxy * desktop-gui: always show proxy settings * server: use get-windows-proxy * electron, server: supply electron proxy config when window launched * server: fix * https-proxy: cleanup * server: clean up ensureUrl * https-proxy: cleanup * cli: fix * cli: fix destructuring * server: enable ForeverAgent to pool HTTPS/HTTP connections #3192 * server: updating snapshot * https-proxy: don't crash, do error if proxy unreachable * https-proxy: * get-windows-proxy@1.0.0 * https-proxy: use proxy-from-env to decide on a proxy for a url * server: fallback to HTTP_PROXY globally if HTTPS_PROXY not set * server: proxy args test * cli: add proxy tests * cli: add test that loadSystemProxySettings is called during download * cli, server: account for the fact that CI has some proxy vars set * https-proxy: "" * cli, https-proxy, server: "" * desktop-gui: update settings gui * desktop-gui: cypress tests for proxy settings * server: strict undefined check * cli, server: move get-windows-proxy to scope, optionalDeps * server, cli: use new and improved get-windows-proxy * cli, server: 1.5.0 * server: re-check for proxy since cli may have failed to load the lib * server, cli: 1.5.1 * server: NO_PROXY=localhost by default, clean up * https-proxy: disable Nagle's on proxy sockets \#3192 * https-proxy: use setNoDelay on upstream, cache https agent * https-proxy: test basic auth * https-proxy: add todo: remove this * server: add custom HTTP(s) Agent implementation w keepalive, tunneling * server: typescript for agent * add ts to zunder * server: more ts * ts: add missing Agent type declaration * server: create CombinedAgent * server: use agent in more places * ts: more declarations * server: make script work even if debug port not supplied * server: begin some testing * server, ts: agent, tests * server: test * server: agent works with websockets now * server: update snapshot * server: work out some more bugs with websockets * server: more websockets * server: add net_profiler * https-proxy: fix dangling socket on direct connection * server: fix potential 'headers have already been sent' * https-proxy: nab another dangler * server: update test to expect agent * https-proxy: fix failing test * desktop-gui: change on-link * server: add tests for empty response case * server: tests * server: send keep-alive with requests * server: make net profiler hook on socket.connect * server: only hook profiler once * server: update tests, add keep-alive test * server: only regen headers if needed * server: move http_overrides into CombinedAgent, make it proxy-proof for #112 * server: update snapshot * server: undo * server: avoid circular dependency * https-proxy, server: use our Agent instead of https-proxy-agent * server: add dependency back * cli: actually use proxy for download * server, launcher, ts: typescript * Revert "server, launcher, ts: typescript" This reverts commitd3f8b8bbb6. * Revert "Revert "server, launcher, ts: typescript"" This reverts commit818dfdfd00. * ts, server: respond to PR * server, ts: types * ts: really fix types * https-proxy, server: export CA from https-proxy * agent, server, https-proxy: move agent to own package * agent => networking, move connect into networking * fix tests * fix test * networking: respond to PR changes, add more unit tests * rename ctx * networking, ts: add more tests * server: add ensureUrl tests * https-proxy: remove https-proxy-agent * server: use CombinedAgent for API * server: updates * add proxy performance tests * add perf tests to workflow * circle * run perf tests with --no-sandbox * networking, ts: ch-ch-ch-ch-changes * server, networking: pr changes * run networking tests in circle * server: fix performance test * https-proxy: test that sockets are being closed * https-proxy: write, not emit * networking: fix test * networking: bubble err in connect * networking: style * networking: clean p connect error handling * networking => network * server: make perf tests really work * server: really report * server: use args from browser * server: use AI to determine max run time * server: load electron only when needed Co-authored-by: Brian Mann <brian@cypress.io>
274 lines
6.1 KiB
JavaScript
274 lines
6.1 KiB
JavaScript
const _ = require('lodash')
|
|
const R = require('ramda')
|
|
const os = require('os')
|
|
const tty = require('tty')
|
|
const path = require('path')
|
|
const isCi = require('is-ci')
|
|
const execa = require('execa')
|
|
const getos = require('getos')
|
|
const chalk = require('chalk')
|
|
const Promise = require('bluebird')
|
|
const cachedir = require('cachedir')
|
|
const getWindowsProxy = require('@cypress/get-windows-proxy')
|
|
const executable = require('executable')
|
|
const supportsColor = require('supports-color')
|
|
const isInstalledGlobally = require('is-installed-globally')
|
|
const pkg = require(path.join(__dirname, '..', 'package.json'))
|
|
const logger = require('./logger')
|
|
const debug = require('debug')('cypress:cli')
|
|
|
|
const getosAsync = Promise.promisify(getos)
|
|
|
|
const stringify = (val) => {
|
|
return _.isObject(val) ? JSON.stringify(val) : val
|
|
}
|
|
|
|
function normalizeModuleOptions (options = {}) {
|
|
return _.mapValues(options, stringify)
|
|
}
|
|
|
|
function stdoutLineMatches (expectedLine, stdout) {
|
|
const lines = stdout.split('\n').map(R.trim)
|
|
const lineMatches = R.equals(expectedLine)
|
|
|
|
return lines.some(lineMatches)
|
|
}
|
|
|
|
/**
|
|
* Prints NODE_OPTIONS using debug() module, but only
|
|
* if DEBUG=cypress... is set
|
|
*/
|
|
function printNodeOptions (log = debug) {
|
|
if (!log.enabled) {
|
|
return
|
|
}
|
|
|
|
if (process.env.NODE_OPTIONS) {
|
|
log('NODE_OPTIONS=%s', process.env.NODE_OPTIONS)
|
|
} else {
|
|
log('NODE_OPTIONS is not set')
|
|
}
|
|
}
|
|
|
|
const util = {
|
|
normalizeModuleOptions,
|
|
|
|
printNodeOptions,
|
|
|
|
isCi () {
|
|
return isCi
|
|
},
|
|
|
|
getEnvOverrides () {
|
|
return _
|
|
.chain({})
|
|
.extend(util.getEnvColors())
|
|
.extend(util.getForceTty())
|
|
.omitBy(_.isUndefined) // remove undefined values
|
|
.mapValues((value) => { // stringify to 1 or 0
|
|
return value ? '1' : '0'
|
|
})
|
|
.value()
|
|
},
|
|
|
|
getForceTty () {
|
|
return {
|
|
FORCE_STDIN_TTY: util.isTty(process.stdin.fd),
|
|
FORCE_STDOUT_TTY: util.isTty(process.stdout.fd),
|
|
FORCE_STDERR_TTY: util.isTty(process.stderr.fd),
|
|
}
|
|
},
|
|
|
|
getEnvColors () {
|
|
const sc = util.supportsColor()
|
|
|
|
return {
|
|
FORCE_COLOR: sc,
|
|
DEBUG_COLORS: sc,
|
|
MOCHA_COLORS: sc ? true : undefined,
|
|
}
|
|
},
|
|
|
|
_getWindowsProxy () {
|
|
return getWindowsProxy()
|
|
},
|
|
|
|
loadSystemProxySettings () {
|
|
// load user's OS-specific proxy settings in to environment vars
|
|
if (!_.isUndefined(process.env.HTTP_PROXY)) {
|
|
// user has set proxy explicitly in environment vars, don't mess with it
|
|
return
|
|
}
|
|
|
|
if (os.platform() === 'win32') {
|
|
const proxy = this._getWindowsProxy()
|
|
|
|
if (proxy) {
|
|
// environment variables are the only way to make request lib use NO_PROXY
|
|
process.env.HTTP_PROXY = process.env.HTTPS_PROXY = proxy.httpProxy
|
|
process.env.NO_PROXY = process.env.NO_PROXY || proxy.noProxy
|
|
}
|
|
|
|
return 'win32'
|
|
}
|
|
},
|
|
|
|
isTty (fd) {
|
|
return tty.isatty(fd)
|
|
},
|
|
|
|
supportsColor () {
|
|
// if we've been explictly told not to support
|
|
// color then turn this off
|
|
if (process.env.NO_COLOR) {
|
|
return false
|
|
}
|
|
|
|
// https://github.com/cypress-io/cypress/issues/1747
|
|
// always return true in CI providers
|
|
if (process.env.CI) {
|
|
return true
|
|
}
|
|
|
|
// ensure that both stdout and stderr support color
|
|
return Boolean(supportsColor.stdout) && Boolean(supportsColor.stderr)
|
|
},
|
|
|
|
cwd () {
|
|
return process.cwd()
|
|
},
|
|
|
|
pkgVersion () {
|
|
return pkg.version
|
|
},
|
|
|
|
exit (code) {
|
|
process.exit(code)
|
|
},
|
|
|
|
logErrorExit1 (err) {
|
|
logger.error(err.message)
|
|
|
|
process.exit(1)
|
|
},
|
|
|
|
titleize (...args) {
|
|
// prepend first arg with space
|
|
// and pad so that all messages line up
|
|
args[0] = _.padEnd(` ${args[0]}`, 24)
|
|
|
|
// get rid of any falsy values
|
|
args = _.compact(args)
|
|
|
|
return chalk.blue(...args)
|
|
},
|
|
|
|
calculateEta (percent, elapsed) {
|
|
// returns the number of seconds remaining
|
|
|
|
// if we're at 100 already just return 0
|
|
if (percent === 100) {
|
|
return 0
|
|
}
|
|
|
|
// take the percentage and divide by one
|
|
// and multiple that against elapsed
|
|
// subtracting what's already elapsed
|
|
return elapsed * (1 / (percent / 100)) - elapsed
|
|
},
|
|
|
|
secsRemaining (eta) {
|
|
// calculate the seconds reminaing with no decimal places
|
|
return (_.isFinite(eta) ? (eta / 1000) : 0).toFixed(0)
|
|
},
|
|
|
|
setTaskTitle (task, title, renderer) {
|
|
// only update the renderer title when not running in CI
|
|
if (renderer === 'default' && task.title !== title) {
|
|
task.title = title
|
|
}
|
|
},
|
|
|
|
isInstalledGlobally () {
|
|
return isInstalledGlobally
|
|
},
|
|
|
|
isSemver (str) {
|
|
return /^(\d+\.)?(\d+\.)?(\*|\d+)$/.test(str)
|
|
},
|
|
|
|
isExecutableAsync (filePath) {
|
|
return Promise.resolve(executable(filePath))
|
|
},
|
|
|
|
getOsVersionAsync () {
|
|
return Promise.try(() => {
|
|
if (os.platform() === 'linux') {
|
|
return getosAsync()
|
|
.then((osInfo) => {
|
|
return [osInfo.dist, osInfo.release].join(' - ')
|
|
})
|
|
.catch(() => {
|
|
return os.release()
|
|
})
|
|
}
|
|
|
|
return os.release()
|
|
|
|
})
|
|
},
|
|
|
|
// attention:
|
|
// when passing relative path to NPM post install hook, the current working
|
|
// directory is set to the `node_modules/cypress` folder
|
|
// the user is probably passing relative path with respect to root package folder
|
|
formAbsolutePath (filename) {
|
|
if (path.isAbsolute(filename)) {
|
|
return filename
|
|
}
|
|
|
|
return path.join(process.cwd(), '..', '..', filename)
|
|
},
|
|
|
|
getEnv (varName) {
|
|
const envVar = process.env[varName]
|
|
const configVar = process.env[`npm_config_${varName}`]
|
|
const packageConfigVar = process.env[`npm_package_config_${varName}`]
|
|
|
|
if (envVar) {
|
|
debug(`Using ${varName} from environment variable`)
|
|
|
|
return envVar
|
|
}
|
|
|
|
if (configVar) {
|
|
debug(`Using ${varName} from npm config`)
|
|
|
|
return configVar
|
|
}
|
|
|
|
if (packageConfigVar) {
|
|
debug(`Using ${varName} from package.json config`)
|
|
|
|
return packageConfigVar
|
|
}
|
|
|
|
return undefined
|
|
|
|
},
|
|
|
|
getCacheDir () {
|
|
return cachedir('Cypress')
|
|
},
|
|
|
|
isPostInstall () {
|
|
return process.env.npm_lifecycle_event === 'postinstall'
|
|
},
|
|
|
|
exec: execa,
|
|
|
|
stdoutLineMatches,
|
|
}
|
|
|
|
module.exports = util
|