Files
cypress/packages/server/lib/modes/info.js
Gleb Bahmutov 070fceff20 add "cypress info" command (#6372)
* WIP: add cli info command to list detected browsers

* print found browsers

* change to list

* start work on info command calling into binary

* move info command into binary

* print OS info during cypress info command

* add binary cache path to info command

* add browser profile path

* add memory

* get browser profile path without partition

* pick real browsers as examples

* output same info as desired

* better names

* changed colors

* add list of cached binary versions

* do not put stable into name

* add underlined link

* conditionally show profile path, only if the folder exists

* do not list cached binaries

* human-friendly memory print

* print env proxy vars

* print CYPRESS_ env variables

* use _.sample

* update order

* store cypress info output on CI as HTML page artifact

* add percy CLI screenshots

* sanitize cypress info command

* store CLI snapshots in cli/visual-snapshots folder

* update cli unit snapshot

* add cli unit test

* start e2e testing for cypress info

* add test with proxy and cypress vars

* make sure we call the binary

* stricter start check

* start unit testing modes info

* test info mode browser print

* add test for profile path

* add cypress info command to test binary Circle job

* add cypress info to test-binary-as-specific-user circle

* print cypress info --dev on circle and on appveyor

* update .gitignore

* move error in environment load to debug
2020-02-20 10:54:25 -05:00

140 lines
3.7 KiB
JavaScript

/* eslint-disable no-console */
const debug = require('debug')('cypress:server:info')
const launcher = require('@packages/launcher')
const pluralize = require('pluralize')
const { stripIndent } = require('common-tags')
const { sortWith, ascend, prop } = require('ramda')
const browserUtils = require('../browsers/utils')
const _ = require('lodash')
const chalk = require('chalk')
const fs = require('../util/fs')
// color for numbers and short values
const n = chalk.green
// color for paths
const p = chalk.cyan
// color for accents and examples
const a = chalk.yellow
// urls
const link = chalk.blue.underline
/**
* If the list has at least 1 item, picks a random item
* and returns it AND the remaining items.
*/
const pickRandomItem = (list) => {
if (!list.length) {
return {
item: null,
remaining: list,
}
}
const item = _.sample(list)
const remaining = _.without(list, item)
return {
item, remaining,
}
}
// Usually the full browser name to pass via --browser
// is <name>:<channel>. If the channel is stable, you
// can just do "--browser <name>"
const formBrowserName = (browser) => {
if (browser.channel === 'stable') {
return browser.name
}
return `${browser.name}:${browser.channel}`
}
// for each browser computes the profile folder
// and checks if the folder exists. If exists,
// adds it to the browser object as a property
const addProfilePath = async (browsers = []) => {
for (const browser of browsers) {
const profilePath = browserUtils.getBrowserPath(browser)
debug('checking profile path %s for browser %s:%s', profilePath, browser.name, browser.channel)
try {
const profileExists = await fs.statAsync(profilePath)
if (profileExists && profileExists.isDirectory()) {
debug('profile folder exists %s', profilePath)
browser.profilePath = profilePath
}
} catch (e) {
debug('problem checking profile folder %s %s', profilePath, e.message)
}
}
return browsers
}
const print = (browsers = []) => {
console.log('Displaying Cypress info...')
console.log('')
if (browsers.length) {
console.log('Detected %s %s installed:', n(browsers.length), pluralize('browser', browsers.length))
} else {
console.log('Detected no known browsers installed')
}
console.log('')
const sortByNameAndMajor = sortWith([
ascend(prop('name')),
ascend(prop('majorVersion')),
])
const sortedByNameAndMajorVersion = sortByNameAndMajor(browsers)
sortedByNameAndMajorVersion.forEach((browser, k) => {
const text = stripIndent`
${k + 1}. ${a(browser.displayName)}
- Name: ${browser.name}
- Channel: ${browser.channel}
- Version: ${n(browser.version)}
- Executable: ${p(browser.path)}
${browser.profilePath ? `- Profile: ${browser.profilePath}` : ''}
`
console.log(text)
console.log('')
})
// randomly a few detected browsers to use as examples
if (browsers.length) {
const highlightedBrowser = a('--browser')
console.log('Note: to run these browsers, pass <name>:<channel> to the \'%s\' field',
highlightedBrowser)
console.log('')
const firstDraw = pickRandomItem(browsers)
if (firstDraw.item) {
console.log('Examples:')
console.log(a(`- cypress run --browser ${formBrowserName(firstDraw.item)}`))
const secondDraw = pickRandomItem(firstDraw.remaining)
if (secondDraw.item) {
console.log(a(`- cypress run --browser ${formBrowserName(secondDraw.item)}`))
}
}
console.log('')
console.log('Learn More: %s', link('https://on.cypress.io/launching-browsers'))
}
}
const info = () => {
return launcher.detect()
.then(addProfilePath)
.then(print)
}
module.exports = info