mirror of
https://github.com/cypress-io/cypress.git
synced 2026-04-24 07:59:12 -05:00
Merge branch 'develop' into feature-multidomain
This commit is contained in:
+32
@@ -13,18 +13,35 @@ cypress.zip
|
||||
Cached Theme.pak
|
||||
Cached Theme Material Design.pak
|
||||
|
||||
# from data-context, compiled .js files
|
||||
packages/data-context/src/**/*.js
|
||||
|
||||
# from desktop-gui
|
||||
packages/desktop-gui/cypress/videos
|
||||
packages/desktop-gui/src/jsconfig.json
|
||||
|
||||
|
||||
# from driver
|
||||
packages/driver/cypress/videos
|
||||
packages/driver/cypress/screenshots
|
||||
|
||||
# from launcher, compiled .js files
|
||||
packages/launcher/index.js
|
||||
packages/launcher/lib/**/*.js
|
||||
|
||||
# from network, compiled .js files
|
||||
packages/network/lib/**/*.js
|
||||
|
||||
# from net-stubbing, compiled .js files
|
||||
packages/net-stubbing/lib/**/*.js
|
||||
|
||||
# from runner
|
||||
packages/runner/cypress/videos
|
||||
packages/runner/cypress/screenshots
|
||||
|
||||
# from proxy, compiled .js files
|
||||
packages/proxy/lib/**/*.js
|
||||
|
||||
# npm packages
|
||||
npm/**/cypress/screenshots
|
||||
|
||||
@@ -33,6 +50,10 @@ packages/example/app
|
||||
packages/example/build
|
||||
packages/example/cypress/integration
|
||||
|
||||
# from frontend-shared
|
||||
packages/frontend-shared/cypress/e2e/.projects
|
||||
packages/frontend-shared/src/public/shiki/themes/cypress.theme.json
|
||||
|
||||
# from server
|
||||
packages/server/.cy
|
||||
packages/server/.projects
|
||||
@@ -40,6 +61,9 @@ packages/server/support
|
||||
packages/server/test/support/fixtures/server/imgs
|
||||
packages/server/test/support/fixtures/server/libs
|
||||
|
||||
# from socket, dist built files
|
||||
packages/socket/lib/*.js
|
||||
|
||||
# from system-tests
|
||||
system-tests/.projects
|
||||
system-tests/fixtures/large-img
|
||||
@@ -57,6 +81,10 @@ system-tests/fixtures/large-img
|
||||
# from runner-ct
|
||||
/packages/runner-ct/cypress/screenshots
|
||||
|
||||
# graphql, auto-generated
|
||||
/packages/launchpad/src/generated
|
||||
/packages/app/src/generated
|
||||
|
||||
# from npm/create-cypress-tests
|
||||
/npm/create-cypress-tests/initial-template
|
||||
/npm/create-cypress-tests/src/test-output
|
||||
@@ -343,3 +371,7 @@ $RECYCLE.BIN/
|
||||
|
||||
# Circle cache artifacts
|
||||
globbed_node_modules
|
||||
|
||||
# Autogenerated files, typically from graphql-code-generator
|
||||
*.gen.ts
|
||||
*.gen.json
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{
|
||||
"chrome:beta": "95.0.4638.49",
|
||||
"chrome:stable": "94.0.4606.81"
|
||||
"chrome:beta": "96.0.4664.27",
|
||||
"chrome:stable": "95.0.4638.69"
|
||||
}
|
||||
|
||||
+5
-5
@@ -960,7 +960,7 @@ jobs:
|
||||
fi
|
||||
- wait-on-circle-jobs:
|
||||
job-names: >
|
||||
desktop-gui-integration-tests-2x,
|
||||
desktop-gui-integration-tests-7x,
|
||||
desktop-gui-component-tests,
|
||||
cli-visual-tests,
|
||||
runner-integration-tests-chrome,
|
||||
@@ -1189,9 +1189,9 @@ jobs:
|
||||
- run-driver-integration-tests:
|
||||
browser: electron
|
||||
|
||||
desktop-gui-integration-tests-2x:
|
||||
desktop-gui-integration-tests-7x:
|
||||
<<: *defaults
|
||||
parallelism: 2
|
||||
parallelism: 7
|
||||
steps:
|
||||
- restore_cached_workspace
|
||||
- run:
|
||||
@@ -2049,7 +2049,7 @@ linux-workflow: &linux-workflow
|
||||
requires:
|
||||
- build
|
||||
|
||||
- desktop-gui-integration-tests-2x:
|
||||
- desktop-gui-integration-tests-7x:
|
||||
requires:
|
||||
- build
|
||||
- desktop-gui-component-tests:
|
||||
@@ -2119,7 +2119,7 @@ linux-workflow: &linux-workflow
|
||||
- reporter-integration-tests
|
||||
- Linux lint
|
||||
- desktop-gui-component-tests
|
||||
- desktop-gui-integration-tests-2x
|
||||
- desktop-gui-integration-tests-7x
|
||||
- runner-ct-integration-tests-chrome
|
||||
- runner-integration-tests-firefox
|
||||
- runner-integration-tests-chrome
|
||||
|
||||
+10
-6
@@ -1,6 +1,5 @@
|
||||
// @ts-check
|
||||
const _ = require('lodash')
|
||||
const R = require('ramda')
|
||||
const commander = require('commander')
|
||||
const { stripIndent } = require('common-tags')
|
||||
const logSymbols = require('log-symbols')
|
||||
@@ -279,12 +278,17 @@ const castCypressRunOptions = (opts) => {
|
||||
// only properties that have type "string | false" in our TS definition
|
||||
// require special handling, because CLI parsing takes care of purely
|
||||
// boolean arguments
|
||||
const result = R.evolve({
|
||||
port: coerceAnyStringToInt,
|
||||
configFile: coerceFalseOrString,
|
||||
})(opts)
|
||||
const castOpts = { ...opts }
|
||||
|
||||
return result
|
||||
if (_.has(opts, 'port')) {
|
||||
castOpts.port = coerceAnyStringToInt(opts.port)
|
||||
}
|
||||
|
||||
if (_.has(opts, 'configFile')) {
|
||||
castOpts.configFile = coerceFalseOrString(opts.configFile)
|
||||
}
|
||||
|
||||
return castOpts
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
||||
+1
-2
@@ -1,6 +1,5 @@
|
||||
const chalk = require('chalk')
|
||||
const { stripIndent, stripIndents } = require('common-tags')
|
||||
const { merge } = require('ramda')
|
||||
const la = require('lazy-ass')
|
||||
const is = require('check-more-types')
|
||||
|
||||
@@ -241,7 +240,7 @@ const CYPRESS_RUN_BINARY = {
|
||||
|
||||
function addPlatformInformation (info) {
|
||||
return util.getPlatformInfo().then((platform) => {
|
||||
return merge(info, { platform })
|
||||
return { ...info, platform }
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
+10
-5
@@ -6,7 +6,6 @@ const os = require('os')
|
||||
const chalk = require('chalk')
|
||||
const prettyBytes = require('pretty-bytes')
|
||||
const _ = require('lodash')
|
||||
const R = require('ramda')
|
||||
|
||||
// color for numbers and show values
|
||||
const g = chalk.green
|
||||
@@ -22,14 +21,20 @@ methods.findProxyEnvironmentVariables = () => {
|
||||
return _.pick(process.env, ['HTTP_PROXY', 'HTTPS_PROXY', 'NO_PROXY'])
|
||||
}
|
||||
|
||||
const maskSensitiveVariables = R.evolve({
|
||||
CYPRESS_RECORD_KEY: R.always('<redacted>'),
|
||||
})
|
||||
const maskSensitiveVariables = (obj) => {
|
||||
const masked = { ...obj }
|
||||
|
||||
if (masked.CYPRESS_RECORD_KEY) {
|
||||
masked.CYPRESS_RECORD_KEY = '<redacted>'
|
||||
}
|
||||
|
||||
return masked
|
||||
}
|
||||
|
||||
methods.findCypressEnvironmentVariables = () => {
|
||||
const isCyVariable = (val, key) => key.startsWith('CYPRESS_')
|
||||
|
||||
return R.pickBy(isCyVariable)(process.env)
|
||||
return _.pickBy(process.env, isCyVariable)
|
||||
}
|
||||
|
||||
const formatCypressVariables = () => {
|
||||
|
||||
+3
-2
@@ -1,4 +1,3 @@
|
||||
const R = require('ramda')
|
||||
const chalk = require('chalk')
|
||||
|
||||
let logs = []
|
||||
@@ -36,7 +35,9 @@ const always = (...messages) => {
|
||||
const logLines = (text) => {
|
||||
const lines = text.split('\n')
|
||||
|
||||
R.forEach(log, lines)
|
||||
for (const line of lines) {
|
||||
log(line)
|
||||
}
|
||||
}
|
||||
|
||||
const print = () => {
|
||||
|
||||
@@ -2,7 +2,6 @@ const _ = require('lodash')
|
||||
const os = require('os')
|
||||
const path = require('path')
|
||||
const untildify = require('untildify')
|
||||
const R = require('ramda')
|
||||
const debug = require('debug')('cypress:cli')
|
||||
|
||||
const fs = require('../fs')
|
||||
@@ -179,9 +178,9 @@ const getBinaryPkgAsync = (binaryDir) => {
|
||||
})
|
||||
}
|
||||
|
||||
const getBinaryPkgVersion = R.propOr(null, 'version')
|
||||
const getBinaryElectronVersion = R.propOr(null, 'electronVersion')
|
||||
const getBinaryElectronNodeVersion = R.propOr(null, 'electronNodeVersion')
|
||||
const getBinaryPkgVersion = (o) => _.get(o, 'version', null)
|
||||
const getBinaryElectronVersion = (o) => _.get(o, 'electronVersion', null)
|
||||
const getBinaryElectronNodeVersion = (o) => _.get(o, 'electronNodeVersion', null)
|
||||
|
||||
module.exports = {
|
||||
getPathToExecutable,
|
||||
|
||||
+9
-8
@@ -1,5 +1,4 @@
|
||||
const _ = require('lodash')
|
||||
const R = require('ramda')
|
||||
const os = require('os')
|
||||
const ospath = require('ospath')
|
||||
const crypto = require('crypto')
|
||||
@@ -114,10 +113,9 @@ const logBrokenGtkDisplayWarning = () => {
|
||||
}
|
||||
|
||||
function stdoutLineMatches (expectedLine, stdout) {
|
||||
const lines = stdout.split('\n').map(R.trim)
|
||||
const lineMatches = R.equals(expectedLine)
|
||||
const lines = stdout.split('\n').map((val) => val.trim())
|
||||
|
||||
return lines.some(lineMatches)
|
||||
return lines.some((line) => line === expectedLine)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -229,11 +227,14 @@ const parseOpts = (opts) => {
|
||||
|
||||
// some options might be quoted - which leads to unexpected results
|
||||
// remove double quotes from certain options
|
||||
const removeQuotes = {
|
||||
group: dequote,
|
||||
ciBuildId: dequote,
|
||||
const cleanOpts = { ...opts }
|
||||
const toDequote = ['group', 'ciBuildId']
|
||||
|
||||
for (const prop of toDequote) {
|
||||
if (_.has(opts, prop)) {
|
||||
cleanOpts[prop] = dequote(opts[prop])
|
||||
}
|
||||
}
|
||||
const cleanOpts = R.evolve(removeQuotes, opts)
|
||||
|
||||
debug('parsed cli options %o', cleanOpts)
|
||||
|
||||
|
||||
@@ -55,7 +55,6 @@
|
||||
"ospath": "^1.2.2",
|
||||
"pretty-bytes": "^5.6.0",
|
||||
"proxy-from-env": "1.0.0",
|
||||
"ramda": "~0.27.1",
|
||||
"request-progress": "^3.0.0",
|
||||
"supports-color": "^8.1.1",
|
||||
"tmp": "~0.2.1",
|
||||
|
||||
@@ -44,6 +44,11 @@
|
||||
"default": null,
|
||||
"description": "The reporter options used. Supported options depend on the reporter. See https://on.cypress.io/reporters#Reporter-Options"
|
||||
},
|
||||
"slowTestThreshold": {
|
||||
"type": "number",
|
||||
"default": 10000,
|
||||
"description": "Slow test threshold in milliseconds. Only affects the visual output of some reporters. For example, the spec reporter will display the test time in yellow if over the threshold. See https://on.cypress.io/configuration#Timeouts"
|
||||
},
|
||||
"testFiles": {
|
||||
"type": [
|
||||
"string",
|
||||
|
||||
@@ -5,13 +5,12 @@ const makeUserPackageFile = require('../../scripts/build')
|
||||
const snapshot = require('../support/snapshot')
|
||||
const la = require('lazy-ass')
|
||||
const is = require('check-more-types')
|
||||
const R = require('ramda')
|
||||
|
||||
const hasVersion = (json) => {
|
||||
return la(is.semver(json.version), 'cannot find version', json)
|
||||
}
|
||||
|
||||
const changeVersion = R.assoc('version', 'x.y.z')
|
||||
const changeVersion = (o) => ({ ...o, version: 'x.y.z' })
|
||||
|
||||
describe('package.json build', () => {
|
||||
beforeEach(function () {
|
||||
|
||||
@@ -2,7 +2,7 @@ require('../spec_helper')
|
||||
|
||||
const os = require('os')
|
||||
const path = require('path')
|
||||
const R = require('ramda')
|
||||
const _ = require('lodash')
|
||||
const snapshot = require('../support/snapshot')
|
||||
const Promise = require('bluebird')
|
||||
const tmp = Promise.promisifyAll(require('tmp'))
|
||||
@@ -27,11 +27,10 @@ describe('cypress', function () {
|
||||
sinon.stub(open, 'start').resolves()
|
||||
})
|
||||
|
||||
const getCallArgs = R.path(['lastCall', 'args', 0])
|
||||
const getStartArgs = () => {
|
||||
expect(open.start).to.be.called
|
||||
|
||||
return getCallArgs(open.start)
|
||||
return _.get(open.start, ['lastCall', 'args', 0])
|
||||
}
|
||||
|
||||
it('calls open#start, passing in options', function () {
|
||||
@@ -100,7 +99,6 @@ describe('cypress', function () {
|
||||
})
|
||||
})
|
||||
|
||||
const getCallArgs = R.path(['lastCall', 'args', 0])
|
||||
const normalizeCallArgs = (args) => {
|
||||
expect(args.outputPath).to.equal(outputPath)
|
||||
delete args.outputPath
|
||||
@@ -110,7 +108,7 @@ describe('cypress', function () {
|
||||
const getStartArgs = () => {
|
||||
expect(run.start).to.be.called
|
||||
|
||||
return normalizeCallArgs(getCallArgs(run.start))
|
||||
return normalizeCallArgs(_.get(run.start, ['lastCall', 'args', 0]))
|
||||
}
|
||||
|
||||
it('calls run#start, passing in options', () => {
|
||||
|
||||
Vendored
+4
@@ -91,6 +91,10 @@ declare namespace CypressCommandLine {
|
||||
* Specify mocha reporter options
|
||||
*/
|
||||
reporterOptions: any
|
||||
/**
|
||||
* Slow test threshold in milliseconds. Only affects the visual output of some reporters. For example, the spec reporter will display the test time in yellow if over the threshold.
|
||||
*/
|
||||
slowTestThreshold: number
|
||||
/**
|
||||
* Specify the specs to run
|
||||
*/
|
||||
|
||||
Vendored
+6
-1
@@ -2577,6 +2577,11 @@ declare namespace Cypress {
|
||||
* @default "spec"
|
||||
*/
|
||||
reporterOptions: { [key: string]: any }
|
||||
/**
|
||||
* Slow test threshold in milliseconds. Only affects the visual output of some reporters. For example, the spec reporter will display the test time in yellow if over the threshold.
|
||||
* @default 10000
|
||||
*/
|
||||
slowTestThreshold: number
|
||||
/**
|
||||
* Whether Cypress will watch and restart tests on test file changes
|
||||
* @default true
|
||||
@@ -5675,7 +5680,7 @@ declare namespace Cypress {
|
||||
xhr: XMLHttpRequest
|
||||
}
|
||||
|
||||
type Encodings = 'ascii' | 'base64' | 'binary' | 'hex' | 'latin1' | 'utf8' | 'utf-8' | 'ucs2' | 'ucs-2' | 'utf16le' | 'utf-16le'
|
||||
type Encodings = 'ascii' | 'base64' | 'binary' | 'hex' | 'latin1' | 'utf8' | 'utf-8' | 'ucs2' | 'ucs-2' | 'utf16le' | 'utf-16le' | null
|
||||
type PositionType = 'topLeft' | 'top' | 'topRight' | 'left' | 'center' | 'right' | 'bottomLeft' | 'bottom' | 'bottomRight'
|
||||
type ViewportPreset = 'macbook-16' | 'macbook-15' | 'macbook-13' | 'macbook-11' | 'ipad-2' | 'ipad-mini' | 'iphone-xr' | 'iphone-x' | 'iphone-6+' | 'iphone-se2' | 'iphone-8' | 'iphone-7' | 'iphone-6' | 'iphone-5' | 'iphone-4' | 'iphone-3' | 'samsung-s10' | 'samsung-note9'
|
||||
interface Offset {
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
# [create-cypress-tests-v1.1.3](https://github.com/cypress-io/cypress/compare/create-cypress-tests-v1.1.2...create-cypress-tests-v1.1.3) (2021-10-29)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* revive type checker ([#18172](https://github.com/cypress-io/cypress/issues/18172)) ([af472b6](https://github.com/cypress-io/cypress/commit/af472b6419ecb2aec1abdb09df99b2fa5f56e033))
|
||||
|
||||
# [create-cypress-tests-v1.1.2](https://github.com/cypress-io/cypress/compare/create-cypress-tests-v1.1.1...create-cypress-tests-v1.1.2) (2021-06-17)
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
# [@cypress/schematic-v1.5.2](https://github.com/cypress-io/cypress/compare/@cypress/schematic-v1.5.1...@cypress/schematic-v1.5.2) (2021-10-29)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* revive type checker ([#18172](https://github.com/cypress-io/cypress/issues/18172)) ([af472b6](https://github.com/cypress-io/cypress/commit/af472b6419ecb2aec1abdb09df99b2fa5f56e033))
|
||||
|
||||
# [@cypress/schematic-v1.5.1](https://github.com/cypress-io/cypress/compare/@cypress/schematic-v1.5.0...@cypress/schematic-v1.5.1) (2021-09-10)
|
||||
|
||||
|
||||
|
||||
@@ -50,8 +50,7 @@
|
||||
"testing"
|
||||
],
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"registry": "http://registry.npmjs.org/"
|
||||
"access": "public"
|
||||
},
|
||||
"builders": "./src/builders/builders.json",
|
||||
"ng-add": {
|
||||
|
||||
@@ -178,8 +178,7 @@
|
||||
}
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"registry": "http://registry.npmjs.org/"
|
||||
"access": "public"
|
||||
},
|
||||
"standard": {
|
||||
"globals": [
|
||||
|
||||
@@ -3,6 +3,8 @@ const { createWebpackDevConfig } = require('@craco/craco')
|
||||
const { getLegacyDevServer } = require('../utils/legacy-setup-dev-server')
|
||||
|
||||
function devServer (cypressDevServerConfig, cracoConfig) {
|
||||
process.env.FAST_REFRESH = 'false'
|
||||
|
||||
return startDevServer({
|
||||
options: cypressDevServerConfig,
|
||||
webpackConfig: createWebpackDevConfig(cracoConfig),
|
||||
|
||||
@@ -3,13 +3,21 @@ import type { Span } from 'next/dist/telemetry/trace/trace'
|
||||
// Starting with v11.1.1, a trace is required.
|
||||
// 'next/dist/telemetry/trace/trace' only exists since v10.0.9
|
||||
// and our peerDeps support back to v8 so try-catch this import
|
||||
// Starting from 12.0 trace is now located in 'next/dist/trace/trace'
|
||||
export async function getRunWebpackSpan (): Promise<{ runWebpackSpan?: Span }> {
|
||||
let trace: (name: string) => Span
|
||||
|
||||
try {
|
||||
trace = await import('next/dist/telemetry/trace/trace').then((m) => m.trace)
|
||||
try {
|
||||
trace = await import('next/dist/telemetry/trace/trace').then((m) => m.trace)
|
||||
|
||||
return { runWebpackSpan: trace('cypress') }
|
||||
return { runWebpackSpan: trace('cypress') }
|
||||
} catch (_) {
|
||||
// @ts-ignore
|
||||
trace = await import('next/dist/trace/trace').then((m) => m.trace)
|
||||
|
||||
return { runWebpackSpan: trace('cypress') }
|
||||
}
|
||||
} catch (_) {
|
||||
return {}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
# [@cypress/vite-dev-server-v2.2.0](https://github.com/cypress-io/cypress/compare/@cypress/vite-dev-server-v2.1.1...@cypress/vite-dev-server-v2.2.0) (2021-10-15)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* normalized signatures webpack & vite servers ([#18379](https://github.com/cypress-io/cypress/issues/18379)) ([8f5308f](https://github.com/cypress-io/cypress/commit/8f5308f7068b80fb877da539ce34fb67ba497c4f))
|
||||
|
||||
# [@cypress/vite-dev-server-v2.1.1](https://github.com/cypress-io/cypress/compare/@cypress/vite-dev-server-v2.1.0...@cypress/vite-dev-server-v2.1.1) (2021-10-04)
|
||||
|
||||
|
||||
|
||||
@@ -102,7 +102,6 @@
|
||||
}
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"registry": "http://registry.npmjs.org/"
|
||||
"access": "public"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
# [@cypress/webpack-dev-server-v1.7.0](https://github.com/cypress-io/cypress/compare/@cypress/webpack-dev-server-v1.6.0...@cypress/webpack-dev-server-v1.7.0) (2021-10-15)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* normalized signatures webpack & vite servers ([#18379](https://github.com/cypress-io/cypress/issues/18379)) ([8f5308f](https://github.com/cypress-io/cypress/commit/8f5308f7068b80fb877da539ce34fb67ba497c4f))
|
||||
|
||||
# [@cypress/webpack-dev-server-v1.6.0](https://github.com/cypress-io/cypress/compare/@cypress/webpack-dev-server-v1.5.0...@cypress/webpack-dev-server-v1.6.0) (2021-09-10)
|
||||
|
||||
|
||||
|
||||
+2
-3
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cypress",
|
||||
"version": "8.6.0",
|
||||
"version": "8.7.0",
|
||||
"description": "Cypress.io end to end testing tool",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
@@ -94,7 +94,6 @@
|
||||
"@types/mocha": "8.0.3",
|
||||
"@types/node": "14.14.31",
|
||||
"@types/prismjs": "1.16.0",
|
||||
"@types/ramda": "0.25.47",
|
||||
"@types/react": "16.9.50",
|
||||
"@types/react-dom": "16.9.8",
|
||||
"@types/request-promise": "4.1.45",
|
||||
@@ -173,7 +172,6 @@
|
||||
"pretty-ms": "7.0.0",
|
||||
"print-arch": "1.0.0",
|
||||
"proxyquire": "2.1.3",
|
||||
"ramda": "0.27.1",
|
||||
"semantic-release": "17.2.3",
|
||||
"semantic-release-monorepo": "7.0.3",
|
||||
"semver": "7.3.2",
|
||||
@@ -247,6 +245,7 @@
|
||||
"**/jquery": "3.1.1",
|
||||
"**/pretty-format": "26.4.0",
|
||||
"**/socket.io-parser": "4.0.4",
|
||||
"**/ua-parser-js": "0.7.24",
|
||||
"vue-template-compiler": "2.6.12"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +37,22 @@ describe('src/cy/commands/files', () => {
|
||||
})
|
||||
})
|
||||
|
||||
// https://github.com/cypress-io/cypress/issues/1558
|
||||
it('passes explicit null encoding through to server and decodes response', () => {
|
||||
Cypress.backend.resolves({
|
||||
contents: Buffer.from('\n'),
|
||||
filePath: '/path/to/foo.json',
|
||||
})
|
||||
|
||||
cy.readFile('foo.json', null).then(() => {
|
||||
expect(Cypress.backend).to.be.calledWith(
|
||||
'read:file',
|
||||
'foo.json',
|
||||
{ encoding: null },
|
||||
)
|
||||
}).should('eql', Buffer.from('\n'))
|
||||
})
|
||||
|
||||
it('sets the contents as the subject', () => {
|
||||
Cypress.backend.resolves(okResponse)
|
||||
|
||||
@@ -340,6 +356,23 @@ describe('src/cy/commands/files', () => {
|
||||
})
|
||||
})
|
||||
|
||||
// https://github.com/cypress-io/cypress/issues/1558
|
||||
it('explicit null encoding is sent to server as Buffer', () => {
|
||||
Cypress.backend.resolves(okResponse)
|
||||
|
||||
cy.writeFile('foo.txt', Buffer.from([0, 0, 54, 255]), null).then(() => {
|
||||
expect(Cypress.backend).to.be.calledWith(
|
||||
'write:file',
|
||||
'foo.txt',
|
||||
Buffer.from([0, 0, 54, 255]),
|
||||
{
|
||||
encoding: null,
|
||||
flag: 'w',
|
||||
},
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
it('can take encoding as part of options', () => {
|
||||
Cypress.backend.resolves(okResponse)
|
||||
|
||||
|
||||
@@ -35,6 +35,17 @@ describe('src/cy/commands/fixtures', () => {
|
||||
})
|
||||
})
|
||||
|
||||
// https://github.com/cypress-io/cypress/issues/1558
|
||||
it('passes explicit null encoding through to server and decodes response', () => {
|
||||
Cypress.backend.withArgs('get:fixture').resolves(Buffer.from('\n'))
|
||||
|
||||
cy.fixture('foo', null).then((obj) => {
|
||||
expect(Cypress.backend).to.be.calledWith('get:fixture', 'foo', {
|
||||
encoding: null,
|
||||
})
|
||||
}).should('eql', Buffer.from('\n'))
|
||||
})
|
||||
|
||||
it('can have encoding as second argument and options as third argument', () => {
|
||||
Cypress.backend.withArgs('get:fixture').resolves({ foo: 'bar' })
|
||||
|
||||
|
||||
@@ -23,11 +23,50 @@ describe('src/cypress/selector_playground', () => {
|
||||
})
|
||||
|
||||
it('sets selector:playground:priority if selectorPriority specified', () => {
|
||||
const selectorPriority = [
|
||||
'data-1',
|
||||
'data-2',
|
||||
'id',
|
||||
'class',
|
||||
'tag',
|
||||
'attributes',
|
||||
'nth-child',
|
||||
]
|
||||
|
||||
SelectorPlayground.defaults({
|
||||
selectorPriority: ['foo'],
|
||||
selectorPriority,
|
||||
})
|
||||
|
||||
expect(SelectorPlayground.getSelectorPriority()).to.eql(['foo'])
|
||||
expect(SelectorPlayground.getSelectorPriority()).to.eql(selectorPriority)
|
||||
})
|
||||
|
||||
it('throws if selectorPriority contains an unsupported priority', () => {
|
||||
const fn = () => {
|
||||
SelectorPlayground.defaults({
|
||||
selectorPriority: [
|
||||
'id',
|
||||
'name',
|
||||
],
|
||||
})
|
||||
}
|
||||
|
||||
expect(fn).to.throw()
|
||||
.with.property('message')
|
||||
.and.include('`Cypress.SelectorPlayground.defaults()` called with invalid `selectorPriority` property. It must be one of: `data-*`, `id`, `class`, `tag`, `attributes`, `nth-child`. You passed: `name`')
|
||||
})
|
||||
|
||||
it('throws if selectorPriority has an unsupported priority that contains a substring of a valid priority', () => {
|
||||
const fn = () => {
|
||||
SelectorPlayground.defaults({
|
||||
selectorPriority: [
|
||||
'idIsNotValid',
|
||||
],
|
||||
})
|
||||
}
|
||||
|
||||
expect(fn).to.throw()
|
||||
.with.property('message')
|
||||
.and.include('`Cypress.SelectorPlayground.defaults()` called with invalid `selectorPriority` property. It must be one of: `data-*`, `id`, `class`, `tag`, `attributes`, `nth-child`. You passed: `idIsNotValid`')
|
||||
})
|
||||
|
||||
it('sets selector:playground:on:element if onElement specified', () => {
|
||||
|
||||
@@ -11,11 +11,16 @@ export default (Commands, Cypress, cy) => {
|
||||
|
||||
if (_.isObject(encoding)) {
|
||||
userOptions = encoding
|
||||
encoding = null
|
||||
encoding = undefined
|
||||
}
|
||||
|
||||
options = _.defaults({}, userOptions, {
|
||||
encoding: encoding != null ? encoding : 'utf8',
|
||||
// https://github.com/cypress-io/cypress/issues/1558
|
||||
// If no encoding is specified, then Cypress has historically defaulted
|
||||
// to `utf8`, because of it's focus on text files. This is in contrast to
|
||||
// NodeJs, which defaults to binary. We allow users to pass in `null`
|
||||
// to restore the default node behavior.
|
||||
encoding: encoding === undefined ? 'utf8' : encoding,
|
||||
log: true,
|
||||
})
|
||||
|
||||
@@ -53,6 +58,14 @@ export default (Commands, Cypress, cy) => {
|
||||
args: { cmd: 'readFile', action: 'read', file, filePath: err.filePath, error: err.message },
|
||||
})
|
||||
}).then(({ contents, filePath }) => {
|
||||
// https://github.com/cypress-io/cypress/issues/1558
|
||||
// We invoke Buffer.from() in order to transform this from an ArrayBuffer -
|
||||
// which socket.io uses to transfer the file over the websocket - into a
|
||||
// `Buffer`, which webpack polyfills in the browser.
|
||||
if (options.encoding === null) {
|
||||
contents = Buffer.from(contents)
|
||||
}
|
||||
|
||||
consoleProps['File Path'] = filePath
|
||||
consoleProps['Contents'] = contents
|
||||
|
||||
@@ -85,11 +98,16 @@ export default (Commands, Cypress, cy) => {
|
||||
|
||||
if (_.isObject(encoding)) {
|
||||
userOptions = encoding
|
||||
encoding = null
|
||||
encoding = undefined
|
||||
}
|
||||
|
||||
options = _.defaults({}, userOptions, {
|
||||
encoding: encoding ? encoding : 'utf8',
|
||||
// https://github.com/cypress-io/cypress/issues/1558
|
||||
// If no encoding is specified, then Cypress has historically defaulted
|
||||
// to `utf8`, because of it's focus on text files. This is in contrast to
|
||||
// NodeJs, which defaults to binary. We allow users to pass in `null`
|
||||
// to restore the default node behavior.
|
||||
encoding: encoding === undefined ? 'utf8' : encoding,
|
||||
flag: userOptions.flag ? userOptions.flag : 'w',
|
||||
log: true,
|
||||
})
|
||||
@@ -120,7 +138,7 @@ export default (Commands, Cypress, cy) => {
|
||||
})
|
||||
}
|
||||
|
||||
if (_.isObject(contents)) {
|
||||
if (_.isObject(contents) && !Buffer.isBuffer(contents)) {
|
||||
contents = JSON.stringify(contents, null, 2)
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,10 @@ import Promise from 'bluebird'
|
||||
import $errUtils from '../../cypress/error_utils'
|
||||
|
||||
const clone = (obj) => {
|
||||
if (Buffer.isBuffer(obj)) {
|
||||
return Buffer.from(obj)
|
||||
}
|
||||
|
||||
return JSON.parse(JSON.stringify(obj))
|
||||
}
|
||||
|
||||
@@ -47,7 +51,7 @@ export default (Commands, Cypress, cy, state, config) => {
|
||||
options = args[1]
|
||||
}
|
||||
|
||||
if (_.isString(args[0])) {
|
||||
if (_.isString(args[0]) || args[0] === null) {
|
||||
options.encoding = args[0]
|
||||
}
|
||||
|
||||
@@ -64,6 +68,18 @@ export default (Commands, Cypress, cy, state, config) => {
|
||||
return $errUtils.throwErr(response.__error)
|
||||
}
|
||||
|
||||
// https://github.com/cypress-io/cypress/issues/1558
|
||||
// We invoke Buffer.from() in order to transform this from an ArrayBuffer -
|
||||
// which socket.io uses to transfer the file over the websocket - into a
|
||||
// `Buffer`, which webpack polyfills in the browser.
|
||||
if (options.encoding === null) {
|
||||
response = Buffer.from(response)
|
||||
} else if (response instanceof ArrayBuffer) {
|
||||
// Cypress' behavior is to base64 encode binary files if the user
|
||||
// doesn't explicitly pass `null` as the encoding.
|
||||
response = Buffer.from(response).toString('base64')
|
||||
}
|
||||
|
||||
// add the fixture to the cache
|
||||
// so it can just be returned next time
|
||||
cache[fixture] = response
|
||||
|
||||
@@ -1428,10 +1428,14 @@ export default {
|
||||
message: '`Cypress.SelectorPlayground.defaults()` must be called with an object. You passed: `{{arg}}`',
|
||||
docsUrl: 'https://on.cypress.io/selector-playground-api',
|
||||
},
|
||||
defaults_invalid_priority: {
|
||||
defaults_invalid_priority_type: {
|
||||
message: '`Cypress.SelectorPlayground.defaults()` called with invalid `selectorPriority` property. It must be an array. You passed: `{{arg}}`',
|
||||
docsUrl: 'https://on.cypress.io/selector-playground-api',
|
||||
},
|
||||
defaults_invalid_priority: {
|
||||
message: '`Cypress.SelectorPlayground.defaults()` called with invalid `selectorPriority` property. It must be one of: `data-*`, `id`, `class`, `tag`, `attributes`, `nth-child`. You passed: `{{arg}}`. Consider using the `onElement` property if a specific selector is desired.',
|
||||
docsUrl: 'https://on.cypress.io/selector-playground-api',
|
||||
},
|
||||
defaults_invalid_on_element: {
|
||||
message: '`Cypress.SelectorPlayground.defaults()` called with invalid `onElement` property. It must be a function. You passed: `{{arg}}`',
|
||||
docsUrl: 'https://on.cypress.io/selector-playground-api',
|
||||
|
||||
@@ -500,6 +500,8 @@ const create = (specWindow, Cypress, config) => {
|
||||
|
||||
const _mocha = createMocha(specWindow)
|
||||
|
||||
_mocha.slow(config('slowTestThreshold'))
|
||||
|
||||
const _runner = getRunner(_mocha)
|
||||
|
||||
_mocha.suite.file = Cypress.spec.relative
|
||||
|
||||
@@ -21,7 +21,7 @@ const TEST_BEFORE_RUN_EVENT = 'runner:test:before:run'
|
||||
const TEST_AFTER_RUN_EVENT = 'runner:test:after:run'
|
||||
|
||||
const RUNNABLE_LOGS = 'routes agents commands hooks'.split(' ')
|
||||
const RUNNABLE_PROPS = '_testConfig id order title _titlePath root hookName hookId err state failedFromHookId body speed type duration wallClockStartedAt wallClockDuration timings file originalTitle invocationDetails final currentRetry retries'.split(' ')
|
||||
const RUNNABLE_PROPS = '_testConfig id order title _titlePath root hookName hookId err state failedFromHookId body speed type duration wallClockStartedAt wallClockDuration timings file originalTitle invocationDetails final currentRetry retries _slow'.split(' ')
|
||||
|
||||
const debug = debugFn('cypress:driver:runner')
|
||||
const debugErrors = debugFn('cypress:driver:errors')
|
||||
@@ -581,6 +581,10 @@ const normalize = (runnable, tests, initialTests, onRunnable, onLogsById, getRun
|
||||
wrappedRunnable._testConfig = cfg
|
||||
}
|
||||
|
||||
if (cfg.slowTestThreshold) {
|
||||
runnable.slow(cfg.slowTestThreshold)
|
||||
}
|
||||
|
||||
wrappedRunnable._titlePath = runnable.titlePath()
|
||||
}
|
||||
|
||||
|
||||
@@ -58,16 +58,25 @@ export default {
|
||||
})
|
||||
}
|
||||
|
||||
const { selectorPriority: priority, onElement } = props
|
||||
const { selectorPriority, onElement } = props
|
||||
|
||||
if (priority) {
|
||||
if (!_.isArray(priority)) {
|
||||
$errUtils.throwErrByPath('selector_playground.defaults_invalid_priority', {
|
||||
args: { arg: $utils.stringify(priority) },
|
||||
if (selectorPriority) {
|
||||
if (!_.isArray(selectorPriority)) {
|
||||
$errUtils.throwErrByPath('selector_playground.defaults_invalid_priority_type', {
|
||||
args: { arg: $utils.stringify(selectorPriority) },
|
||||
})
|
||||
}
|
||||
// Validate that the priority is one of: "data-*", "id", "class", "tag", "attributes", "nth-child"
|
||||
|
||||
defaults.selectorPriority = priority
|
||||
selectorPriority.forEach((priority) => {
|
||||
if (!/^(data\-.*|id|class|tag|attributes|nth\-child)$/.test(priority)) {
|
||||
$errUtils.throwErrByPath('selector_playground.defaults_invalid_priority', {
|
||||
args: { arg: priority },
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
defaults.selectorPriority = selectorPriority
|
||||
}
|
||||
|
||||
if (onElement) {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Electron
|
||||
# @packages/electron
|
||||
|
||||
This is the lib responsible for installing + building Electron. This enables us to develop with the Electron shell that will match how the final compiled Cypress binary looks 1:1.
|
||||
|
||||
It does this by using `symlinks` while in development.
|
||||
It does this by using symlinks while in development.
|
||||
|
||||
## Building
|
||||
|
||||
@@ -19,3 +19,33 @@ yarn workspace @packages/electron test
|
||||
yarn workspace @packages/electron test-debug
|
||||
yarn workspace @packages/electron test-watch
|
||||
```
|
||||
|
||||
## Upgrading Electron
|
||||
|
||||
The version of `electron` that is bundled with Cypress should be kept as up-to-date as possible with the [stable Electron releases](https://www.electronjs.org/releases/stable). Many users expect the bundled Chromium and Node.js to be relatively recent. Also, historically, it has been extremely difficult to upgrade over multiple major versions of Electron at once, because of all the breaking changes in Electron and Node.js that impact Cypress.
|
||||
|
||||
|
||||
Upgrading `electron` involves more than just bumping this package's `package.json`. Here are additional tasks to check off when upgrading Electron:
|
||||
|
||||
- [ ] **Write accurate changelog items.** The "User-facing changelog" for an Electron upgrade should mention the new Node.js and Chromium versions bundled.
|
||||
- For example:
|
||||
- Upgraded `electron` from `12.0.0-beta.14` to `13.1.7`.
|
||||
- Upgraded bundled Node.js version from `14.6.0` to `14.17.0`.
|
||||
- Upgraded bundled Chromium version from 89.0.0.1234 to 91.0.0.2345.
|
||||
- [ ] **Determine if the Electron upgrade is a breaking change.** Electron upgrades constitute "breaking changes" in Cypress if:
|
||||
- the major version number of Node.js changes, since users rely on the bundled Node.js to load plugins and `.js` fixtures, or
|
||||
- there are changes to Electron that require new shared libraries to be installed on Linux, breaking existing CI setups, or
|
||||
- there is some other change that would break existing usage of Cypress (for example, a Web API feature being removed/added to the bundled Chromium)
|
||||
- [ ] **Create and publish Docker `base` and `browsers` family images matching the Node.js and Chromium versions in Electron.** The `browsers` image will be used for CI and the `base` will be used for any new `included` family images.
|
||||
- See [`cypress-docker-images`](https://github.com/cypress-io/cypress-docker-images/).
|
||||
- [ ] **Ensure that a matching Node.js version is enforced in the monorepo for local development and CI.** When Electron is upgraded, oftentimes, the bundled Node.js version that comes with Electron is updated as well. Because all unit and integration tests run in normal Node.js (not Electron's Node.js), it's important for this Node.js version to be synced with the monorepo. There are a few places where this needs to be done:
|
||||
- [ ] [`/.node-version`](../../.node-version) - used by `nvm` and other Node version managers
|
||||
- [ ] [`/appveyor.yml`](../../appveyor.yml) - update the `nodejs_version`
|
||||
- [ ] [`/package.json`](../../package.json) - update `engines`
|
||||
- [ ] [`/scripts/run-docker-local.sh`](../../scripts/run-docker-local.sh) - update Docker image to the new matching `browsers` image
|
||||
- [ ] [`/circle.yml`](../../circle.yml)
|
||||
- Update the Docker `image`s to the new matching `browsers` image.
|
||||
- Update the `xcode` version to one with the same major Node.js version bundled. There is usually not an exact match, this is ok as long as the major version number as the same.
|
||||
- [ ] Do a global search for the old Node.js version to identify any new areas that may need updating/unification, and update those locations (and this document!)
|
||||
- [ ] **Manually smoke test `cypress open`.** Upgrading Electron can break the `desktop-gui` in unexpected ways. Since testing in this area is weak, double-check that things like launching `cypress open`, signing into the Dashboard, and launching Electron tests still work.
|
||||
- [ ] **Fix failing tests.** Usually, these are due to breaking changes in either Node.js or Electron. Check the changelogs of both to find relevant changes.
|
||||
@@ -2,7 +2,6 @@ import { findApp, FindAppParams } from './util'
|
||||
import type { Browser, DetectedBrowser } from '../types'
|
||||
import * as linuxHelper from '../linux'
|
||||
import { log } from '../log'
|
||||
import { merge } from 'ramda'
|
||||
import { get } from 'lodash'
|
||||
|
||||
type Detectors = {
|
||||
@@ -105,7 +104,7 @@ export function detect (browser: Browser): Promise<DetectedBrowser> {
|
||||
}
|
||||
|
||||
return findApp(findAppParams)
|
||||
.then(merge({ name: browser.name }))
|
||||
.then((val) => ({ name: browser.name, ...val }))
|
||||
.catch(() => {
|
||||
log('could not detect %s using traditional Mac methods', browser.name)
|
||||
log('trying linux search')
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { log } from '../log'
|
||||
import { notInstalledErr } from '../errors'
|
||||
import { prop, tap } from 'ramda'
|
||||
import { utils } from '../utils'
|
||||
import * as fs from 'fs-extra'
|
||||
import * as os from 'os'
|
||||
@@ -27,7 +26,7 @@ export function parsePlist (p: string, property: string): Promise<string> {
|
||||
return fs
|
||||
.readFile(pl, 'utf8')
|
||||
.then(plist.parse)
|
||||
.then(prop(property))
|
||||
.then((val) => val[property])
|
||||
.then(String) // explicitly convert value to String type
|
||||
.catch(failed) // to make TS compiler happy
|
||||
}
|
||||
@@ -50,8 +49,14 @@ export function mdfind (id: string): Promise<string> {
|
||||
}
|
||||
|
||||
return utils.execa(cmd)
|
||||
.then(prop('stdout'))
|
||||
.then(tap(logFound))
|
||||
.then((val) => {
|
||||
return val.stdout
|
||||
})
|
||||
.then((val) => {
|
||||
logFound(val)
|
||||
|
||||
return val
|
||||
})
|
||||
.catch(failedToFind)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import Bluebird from 'bluebird'
|
||||
import { compact, extend, find } from 'lodash'
|
||||
import _, { compact, extend, find } from 'lodash'
|
||||
import os from 'os'
|
||||
import { flatten, merge, pick, props, tap, uniqBy } from 'ramda'
|
||||
import { browsers } from './browsers'
|
||||
import * as darwinHelper from './darwin'
|
||||
import { needsDarwinWorkaround, darwinDetectionWorkaround } from './darwin/util'
|
||||
@@ -17,7 +16,7 @@ import type {
|
||||
} from './types'
|
||||
import * as windowsHelper from './windows'
|
||||
|
||||
type HasVersion = Partial<FoundBrowser> & {
|
||||
type HasVersion = Omit<Partial<FoundBrowser>, 'version' | 'name'> & {
|
||||
version: string
|
||||
name: string
|
||||
}
|
||||
@@ -85,7 +84,7 @@ function lookup (
|
||||
* one for each binary. If Windows is detected, only one `checkOneBrowser` will be called, because
|
||||
* we don't use the `binary` field on Windows.
|
||||
*/
|
||||
function checkBrowser (browser: Browser): Bluebird<(boolean | FoundBrowser)[]> {
|
||||
function checkBrowser (browser: Browser): Bluebird<(boolean | HasVersion)[]> {
|
||||
if (Array.isArray(browser.binary) && os.platform() !== 'win32') {
|
||||
return Bluebird.map(browser.binary, (binary: string) => {
|
||||
return checkOneBrowser(extend({}, browser, { binary }))
|
||||
@@ -95,9 +94,9 @@ function checkBrowser (browser: Browser): Bluebird<(boolean | FoundBrowser)[]> {
|
||||
return Bluebird.map([browser], checkOneBrowser)
|
||||
}
|
||||
|
||||
function checkOneBrowser (browser: Browser): Promise<boolean | FoundBrowser> {
|
||||
function checkOneBrowser (browser: Browser): Promise<boolean | HasVersion> {
|
||||
const platform = os.platform()
|
||||
const pickBrowserProps = pick([
|
||||
const pickBrowserProps = [
|
||||
'name',
|
||||
'family',
|
||||
'channel',
|
||||
@@ -111,7 +110,7 @@ function checkOneBrowser (browser: Browser): Promise<boolean | FoundBrowser> {
|
||||
'info',
|
||||
'minSupportedVersion',
|
||||
'unsupportedVersion',
|
||||
])
|
||||
] as const
|
||||
|
||||
const logBrowser = (props: any) => {
|
||||
log('setting major version for %j', props)
|
||||
@@ -130,9 +129,13 @@ function checkOneBrowser (browser: Browser): Promise<boolean | FoundBrowser> {
|
||||
log('checking one browser %s', browser.name)
|
||||
|
||||
return lookup(platform, browser)
|
||||
.then(merge(browser))
|
||||
.then(pickBrowserProps)
|
||||
.then(tap(logBrowser))
|
||||
.then((val) => ({ ...browser, ...val }))
|
||||
.then((val) => _.pick(val, pickBrowserProps) as HasVersion)
|
||||
.then((val) => {
|
||||
logBrowser(val)
|
||||
|
||||
return val
|
||||
})
|
||||
.then((browser) => setMajorVersion(browser))
|
||||
.catch(failed)
|
||||
}
|
||||
@@ -176,9 +179,11 @@ export const detect = (goalBrowsers?: Browser[], useDarwinWorkaround = true): Bl
|
||||
})
|
||||
}
|
||||
|
||||
const removeDuplicates = uniqBy((browser: FoundBrowser) => {
|
||||
return props(['name', 'version'], browser)
|
||||
})
|
||||
const removeDuplicates = (val) => {
|
||||
return _.uniqBy(val, (browser: FoundBrowser) => {
|
||||
return `${browser.name}-${browser.version}`
|
||||
})
|
||||
}
|
||||
const compactFalse = (browsers: any[]) => {
|
||||
return compact(browsers) as FoundBrowser[]
|
||||
}
|
||||
@@ -186,7 +191,7 @@ export const detect = (goalBrowsers?: Browser[], useDarwinWorkaround = true): Bl
|
||||
log('detecting if the following browsers are present %o', goalBrowsers)
|
||||
|
||||
return Bluebird.mapSeries(goalBrowsers, checkBrowser)
|
||||
.then(flatten)
|
||||
.then((val) => _.flatten(val))
|
||||
.then(compactFalse)
|
||||
.then(removeDuplicates)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { log } from '../log'
|
||||
import { partial, trim, tap, prop } from 'ramda'
|
||||
import type { FoundBrowser, Browser, PathData } from '../types'
|
||||
import { notInstalledErr } from '../errors'
|
||||
import { utils } from '../utils'
|
||||
@@ -68,9 +67,13 @@ export function getVersionString (path: string) {
|
||||
|
||||
return Bluebird.resolve(utils.getOutput(path, ['--version']))
|
||||
.timeout(30000, `Timed out after 30 seconds getting browser version for ${path}`)
|
||||
.then(prop('stdout'))
|
||||
.then(trim)
|
||||
.then(tap(partial(log, ['stdout: "%s"'])))
|
||||
.then((val) => val.stdout)
|
||||
.then((val) => val.trim())
|
||||
.then((val) => {
|
||||
log('stdout: %s', val)
|
||||
|
||||
return val
|
||||
})
|
||||
}
|
||||
|
||||
export function getVersionNumber (version: string, browser: Browser) {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import * as fse from 'fs-extra'
|
||||
import os from 'os'
|
||||
import { join, normalize, win32 } from 'path'
|
||||
import { tap, trim, prop } from 'ramda'
|
||||
import { get } from 'lodash'
|
||||
import { notInstalledErr } from '../errors'
|
||||
import { log } from '../log'
|
||||
@@ -151,7 +150,11 @@ function getWindowsBrowser (browser: Browser): Promise<FoundBrowser> {
|
||||
}
|
||||
|
||||
return getVersionString(path)
|
||||
.then(tap(log))
|
||||
.then((val) => {
|
||||
log(val)
|
||||
|
||||
return val
|
||||
})
|
||||
.then(getVersion)
|
||||
.then((version: string) => {
|
||||
log('browser %s at \'%s\' version %s', browser.name, exePath, version)
|
||||
@@ -193,8 +196,8 @@ export function getVersionString (path: string) {
|
||||
]
|
||||
|
||||
return utils.execa('wmic', args)
|
||||
.then(prop('stdout'))
|
||||
.then(trim)
|
||||
.then((val) => val.stdout)
|
||||
.then((val) => val.trim())
|
||||
}
|
||||
|
||||
export function getVersionNumber (version: string) {
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
"fs-extra": "8.1.0",
|
||||
"lodash": "4.17.21",
|
||||
"plist": "3.0.1",
|
||||
"ramda": "0.27.1",
|
||||
"semver": "7.3.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
require('../spec_helper')
|
||||
import _ from 'lodash'
|
||||
import { detect, detectByPath, setMajorVersion } from '../../lib/detect'
|
||||
import { goalBrowsers } from '../fixtures'
|
||||
import { expect } from 'chai'
|
||||
@@ -6,7 +7,6 @@ import { utils } from '../../lib/utils'
|
||||
import sinon, { SinonStub } from 'sinon'
|
||||
import os from 'os'
|
||||
import { log } from '../log'
|
||||
import { project } from 'ramda'
|
||||
import * as darwinUtil from '../../lib/darwin/util'
|
||||
|
||||
const isWindows = () => {
|
||||
@@ -20,7 +20,7 @@ describe('browser detection', () => {
|
||||
log('detected browsers %j', browsers)
|
||||
expect(browsers).to.be.an('array')
|
||||
|
||||
const mainProps = project(['name', 'version'], browsers)
|
||||
const mainProps = browsers.map((val) => _.pick(val, ['name', 'version']))
|
||||
|
||||
log('%d browsers\n%j', browsers.length, mainProps)
|
||||
|
||||
|
||||
@@ -120,7 +120,7 @@ export async function setResponseFromFixture (getFixtureFn: GetFixtureFn, static
|
||||
return
|
||||
}
|
||||
|
||||
const data = await getFixtureFn(fixture.filePath, { encoding: fixture.encoding || null })
|
||||
const data = await getFixtureFn(fixture.filePath, { encoding: fixture.encoding })
|
||||
|
||||
const { headers } = staticResponse
|
||||
|
||||
|
||||
@@ -20,8 +20,10 @@ interface Overrides {
|
||||
const noop = () => {}
|
||||
|
||||
class FakeEventManager {
|
||||
reporterBus: { on: () => void }
|
||||
constructor (overrides: Overrides = {}) {
|
||||
this.saveState = overrides.saveState || noop
|
||||
this.reporterBus = { on: noop }
|
||||
}
|
||||
|
||||
start = noop
|
||||
@@ -132,4 +134,29 @@ describe('RunnerCt', () => {
|
||||
cy.get(selectors.noSpecSelectedReporter).should('exist')
|
||||
})
|
||||
})
|
||||
|
||||
context('current spec is deleted', () => {
|
||||
it('removes selection', () => {
|
||||
const state = makeState({
|
||||
spec: { relative: '/test.js', absolute: 'root/test.js', name: 'test.js' },
|
||||
specs: [
|
||||
{ relative: '/test2.js', absolute: 'root/test2.js', name: 'test2.js' },
|
||||
{ relative: '/test.js', absolute: 'root/test.js', name: 'test.js' },
|
||||
],
|
||||
})
|
||||
|
||||
mount(<RunnerCt
|
||||
state={state}
|
||||
// @ts-ignore - this is difficult to stub. Real one breaks things.
|
||||
eventManager={new FakeEventManager()}
|
||||
config={fakeConfig}
|
||||
/>)
|
||||
|
||||
cy.contains('Your tests are loading').then(() => {
|
||||
state.setSpecs([{ relative: '/test2.js', absolute: 'root/test2.js', name: 'test2.js' }])
|
||||
})
|
||||
|
||||
cy.contains('No spec selected')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -25,7 +25,19 @@ export abstract class BaseStore {
|
||||
this.specRunId = nanoid()
|
||||
}
|
||||
|
||||
@action checkCurrentSpecStillExists (specs: Cypress.Cypress['spec'][]) {
|
||||
const newSpecsAbsolutes = new Set(specs.map((spec) => spec.absolute))
|
||||
|
||||
this.specs.forEach((oldSpec) => {
|
||||
if (!newSpecsAbsolutes.has(oldSpec.absolute) && this.spec?.absolute === oldSpec.absolute) {
|
||||
this.spec = undefined
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@action setSpecs (specs: Cypress.Cypress['spec'][]) {
|
||||
this.checkCurrentSpecStillExists(specs)
|
||||
|
||||
this.specs = specs
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,4 @@
|
||||
import _ from 'lodash'
|
||||
import R from 'ramda'
|
||||
import path from 'path'
|
||||
import Promise from 'bluebird'
|
||||
import deepDiff from 'return-deep-diff'
|
||||
@@ -17,7 +16,7 @@ import findSystemNode from './util/find_system_node'
|
||||
const debug = Debug('cypress:server:config')
|
||||
|
||||
import { options, breakingOptions } from './config_options'
|
||||
import { getProcessEnvVars } from './util/config'
|
||||
import { getProcessEnvVars, CYPRESS_SPECIAL_ENV_VARS } from './util/config'
|
||||
|
||||
export const RESOLVED_FROM = ['plugin', 'env', 'default', 'runtime', 'config'] as const
|
||||
|
||||
@@ -32,18 +31,6 @@ export type ResolvedConfigurationOptions = Partial<{
|
||||
[x in keyof Cypress.ResolvedConfigOptions]: ResolvedFromConfig
|
||||
}>
|
||||
|
||||
export const CYPRESS_ENV_PREFIX = 'CYPRESS_'
|
||||
|
||||
export const CYPRESS_ENV_PREFIX_LENGTH = 'CYPRESS_'.length
|
||||
|
||||
export const CYPRESS_RESERVED_ENV_VARS = [
|
||||
'CYPRESS_INTERNAL_ENV',
|
||||
]
|
||||
|
||||
export const CYPRESS_SPECIAL_ENV_VARS = [
|
||||
'RECORD_KEY',
|
||||
]
|
||||
|
||||
const dashesOrUnderscoresRe = /^(_-)+/
|
||||
|
||||
// takes an array and creates an index object of [keyKey]: [valueKey]
|
||||
@@ -269,6 +256,11 @@ export function mergeDefaults (config: Record<string, any> = {}, options: Record
|
||||
|
||||
_.defaults(config, defaultValues)
|
||||
|
||||
// Default values can be functions, in which case they are evaluated
|
||||
// at runtime - for example, slowTestThreshold where the default value
|
||||
// varies between e2e and component testing.
|
||||
config = _.mapValues(config, (value) => (typeof value === 'function' ? value(options) : value))
|
||||
|
||||
// split out our own app wide env from user env variables
|
||||
// and delete envFile
|
||||
config.env = parseEnv(config, options.env, resolved)
|
||||
@@ -291,7 +283,7 @@ export function mergeDefaults (config: Record<string, any> = {}, options: Record
|
||||
config.numTestsKeptInMemory = 0
|
||||
}
|
||||
|
||||
config = setResolvedConfigValues(config, defaultValues, resolved)
|
||||
config = setResolvedConfigValues(config, defaultValues, resolved, options)
|
||||
|
||||
if (config.port) {
|
||||
config = setUrls(config)
|
||||
@@ -316,10 +308,10 @@ export function mergeDefaults (config: Record<string, any> = {}, options: Record
|
||||
.then(_.partialRight(setNodeBinary, options.onWarning))
|
||||
}
|
||||
|
||||
export function setResolvedConfigValues (config, defaults, resolved) {
|
||||
export function setResolvedConfigValues (config, defaults, resolved, options) {
|
||||
const obj = _.clone(config)
|
||||
|
||||
obj.resolved = resolveConfigValues(config, defaults, resolved)
|
||||
obj.resolved = resolveConfigValues(config, defaults, resolved, options)
|
||||
debug('resolved config is %o', obj.resolved.browsers)
|
||||
|
||||
return obj
|
||||
@@ -364,7 +356,7 @@ export function updateWithPluginValues (cfg, overrides) {
|
||||
return errors.throw('CONFIG_VALIDATION_ERROR', errMsg)
|
||||
})
|
||||
|
||||
let originalResolvedBrowsers = cfg && cfg.resolved && cfg.resolved.browsers && R.clone(cfg.resolved.browsers)
|
||||
let originalResolvedBrowsers = cfg && cfg.resolved && cfg.resolved.browsers && _.cloneDeep(cfg.resolved.browsers)
|
||||
|
||||
if (!originalResolvedBrowsers) {
|
||||
// have something to resolve with if plugins return nothing
|
||||
@@ -378,7 +370,7 @@ export function updateWithPluginValues (cfg, overrides) {
|
||||
|
||||
debug('config diffs %o', diffs)
|
||||
|
||||
const userBrowserList = diffs && diffs.browsers && R.clone(diffs.browsers)
|
||||
const userBrowserList = diffs && diffs.browsers && _.cloneDeep(diffs.browsers)
|
||||
|
||||
if (userBrowserList) {
|
||||
debug('user browser list %o', userBrowserList)
|
||||
@@ -424,7 +416,7 @@ export function updateWithPluginValues (cfg, overrides) {
|
||||
// combines the default configuration object with values specified in the
|
||||
// configuration file like "cypress.json". Values in configuration file
|
||||
// overwrite the defaults.
|
||||
export function resolveConfigValues (config, defaults, resolved = {}) {
|
||||
export function resolveConfigValues (config, defaults, resolved = {}, options = {}) {
|
||||
// pick out only known configuration keys
|
||||
return _
|
||||
.chain(config)
|
||||
@@ -448,7 +440,9 @@ export function resolveConfigValues (config, defaults, resolved = {}) {
|
||||
return source(r)
|
||||
}
|
||||
|
||||
if (!(!_.isEqual(config[key], defaults[key]) && key !== 'browsers')) {
|
||||
const defaultValue = typeof defaults[key] === 'function' ? defaults[key](options) : defaults[key]
|
||||
|
||||
if (!(!_.isEqual(config[key], defaultValue) && key !== 'browsers')) {
|
||||
// "browsers" list is special, since it is dynamic by default
|
||||
// and can only be ovewritten via plugins file
|
||||
return source('default')
|
||||
|
||||
@@ -216,6 +216,10 @@ export const options = [
|
||||
defaultValue: 'cypress/screenshots',
|
||||
validation: v.isStringOrFalse,
|
||||
isFolder: true,
|
||||
}, {
|
||||
name: 'slowTestThreshold',
|
||||
defaultValue: (options: Record<string, any>) => options.testingType === 'component' ? 250 : 10000,
|
||||
validation: v.isNumber,
|
||||
}, {
|
||||
name: 'socketId',
|
||||
defaultValue: null,
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
const _ = require('lodash')
|
||||
const R = require('ramda')
|
||||
const path = require('path')
|
||||
const Promise = require('bluebird')
|
||||
const cwd = require('../cwd')
|
||||
@@ -89,7 +88,7 @@ module.exports = {
|
||||
// desktop-gui/src/specs/specs-store.js
|
||||
return spec.relative.toLowerCase().includes(specFilter.toLowerCase())
|
||||
}
|
||||
const specFilterFn = specFilter ? specFilterContains : R.T
|
||||
const specFilterFn = specFilter ? specFilterContains : () => true
|
||||
|
||||
const getSpecsHelper = () => {
|
||||
// grab all of the specs if this is ci
|
||||
@@ -99,17 +98,21 @@ module.exports = {
|
||||
debug('returning all specs')
|
||||
|
||||
return specsUtil.default.findSpecs(config)
|
||||
.then(R.tap((specs) => {
|
||||
return debug('found __all specs %o', specs)
|
||||
}))
|
||||
.then((specs) => {
|
||||
debug('found __all specs %o', specs)
|
||||
|
||||
return specs
|
||||
})
|
||||
.filter(specFilterFn)
|
||||
.filter((foundSpec) => {
|
||||
return componentTestingEnabled
|
||||
? foundSpec.specType === 'component'
|
||||
: foundSpec.specType === 'integration'
|
||||
}).then(R.tap((specs) => {
|
||||
return debug('filtered __all specs %o', specs)
|
||||
})).map((spec) => {
|
||||
}).then((specs) => {
|
||||
debug('filtered __all specs %o', specs)
|
||||
|
||||
return specs
|
||||
}).map((spec) => {
|
||||
// grab the name of each
|
||||
return spec.absolute
|
||||
}).map(convertSpecPath)
|
||||
|
||||
@@ -9,7 +9,6 @@ require('./environment')
|
||||
// essentially do it all again when we boot the correct
|
||||
// mode.
|
||||
|
||||
const R = require('ramda')
|
||||
const Promise = require('bluebird')
|
||||
const debug = require('debug')('cypress:server:cypress')
|
||||
const argsUtils = require('./util/args')
|
||||
@@ -123,7 +122,7 @@ module.exports = {
|
||||
|
||||
// if the CLI passed "--" somewhere, we need to remove it
|
||||
// for https://github.com/cypress-io/cypress/issues/5466
|
||||
argv = R.without('--', argv)
|
||||
argv = argv.filter((val) => val !== '--')
|
||||
|
||||
let options
|
||||
|
||||
|
||||
@@ -1,18 +1,25 @@
|
||||
const Promise = require('bluebird')
|
||||
const execa = require('execa')
|
||||
const R = require('ramda')
|
||||
const shellEnv = require('shell-env')
|
||||
const _ = require('lodash')
|
||||
const log = require('./log')
|
||||
const utils = require('./util/shell')
|
||||
|
||||
const pickMainProps = R.pick(['stdout', 'stderr', 'code'])
|
||||
const pickMainProps = (val) => _.pick(val, ['stdout', 'stderr', 'code'])
|
||||
|
||||
const trimStdio = R.evolve({
|
||||
stdout: R.trim,
|
||||
stderr: R.trim,
|
||||
})
|
||||
const trimStdio = (val) => {
|
||||
const result = { ...val }
|
||||
|
||||
const loadShellVars = R.memoizeWith(R.toString, shellEnv)
|
||||
if (_.isString(val.stdout)) {
|
||||
result.stdout = val.stdout.trim()
|
||||
}
|
||||
|
||||
if (_.isString(val.stderr)) {
|
||||
result.stderr = val.stderr.trim()
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
run (projectRoot, options) {
|
||||
@@ -38,9 +45,9 @@ module.exports = {
|
||||
}
|
||||
|
||||
const run = () => {
|
||||
return loadShellVars()
|
||||
return shellEnv()
|
||||
.then((shellVariables) => {
|
||||
const env = R.mergeAll([{}, shellVariables, process.env, options.env])
|
||||
const env = _.merge({}, shellVariables, process.env, options.env)
|
||||
|
||||
return utils.getShell(env.SHELL)
|
||||
.then((shell) => {
|
||||
|
||||
@@ -4,9 +4,14 @@ const { fs } = require('./util/fs')
|
||||
module.exports = {
|
||||
readFile (projectRoot, file, options = {}) {
|
||||
const filePath = path.resolve(projectRoot, file)
|
||||
const readFn = path.extname(filePath) === '.json' ? fs.readJsonAsync : fs.readFileAsync
|
||||
const readFn = (path.extname(filePath) === '.json' && options.encoding !== null) ? fs.readJsonAsync : fs.readFileAsync
|
||||
|
||||
return readFn(filePath, options.encoding || 'utf8')
|
||||
// https://github.com/cypress-io/cypress/issues/1558
|
||||
// If no encoding is specified, then Cypress has historically defaulted
|
||||
// to `utf8`, because of it's focus on text files. This is in contrast to
|
||||
// NodeJs, which defaults to binary. We allow users to pass in `null`
|
||||
// to restore the default node behavior.
|
||||
return readFn(filePath, options.encoding === undefined ? 'utf8' : options.encoding)
|
||||
.then((contents) => {
|
||||
return {
|
||||
contents,
|
||||
@@ -22,7 +27,7 @@ module.exports = {
|
||||
writeFile (projectRoot, file, contents, options = {}) {
|
||||
const filePath = path.resolve(projectRoot, file)
|
||||
const writeOptions = {
|
||||
encoding: options.encoding || 'utf8',
|
||||
encoding: options.encoding === undefined ? 'utf8' : options.encoding,
|
||||
flag: options.flag || 'w',
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
const _ = require('lodash')
|
||||
const path = require('path')
|
||||
const check = require('syntax-error')
|
||||
const debug = require('debug')('cypress:server:fixture')
|
||||
@@ -116,15 +115,24 @@ module.exports = {
|
||||
},
|
||||
|
||||
parseFileByExtension (p, fixture, ext, options = {}) {
|
||||
// https://github.com/cypress-io/cypress/issues/1558
|
||||
// If the user explicitly specifies `null` as the encoding, we treat the
|
||||
// file as binary regardless of extension. We base64 encode them for
|
||||
// transmission over the websocket. There is a matching Buffer.from()
|
||||
// in packages/driver/src/cy/commands/fixtures.ts
|
||||
if (options.encoding === null) {
|
||||
return this.parse(p, fixture)
|
||||
}
|
||||
|
||||
switch (ext) {
|
||||
case '.json': return this.parseJson(p, fixture)
|
||||
case '.js': return this.parseJs(p, fixture)
|
||||
case '.coffee': return this.parseCoffee(p, fixture)
|
||||
case '.html': return this.parseHtml(p, fixture)
|
||||
case '.png': case '.jpg': case '.jpeg': case '.gif': case '.tif': case '.tiff': case '.zip':
|
||||
return this.parse(p, fixture, _.isNull(options.encoding) ? null : (options.encoding || 'base64'))
|
||||
return this.parse(p, fixture, options.encoding)
|
||||
default:
|
||||
return this.parse(p, fixture, _.isNull(options.encoding) ? null : options.encoding)
|
||||
return this.parse(p, fixture, options.encoding || 'utf8')
|
||||
}
|
||||
},
|
||||
|
||||
@@ -184,7 +192,7 @@ module.exports = {
|
||||
.bind(this)
|
||||
},
|
||||
|
||||
parse (p, fixture, encoding = 'utf8') {
|
||||
parse (p, fixture, encoding) {
|
||||
return fs.readFileAsync(p, encoding)
|
||||
.bind(this)
|
||||
},
|
||||
|
||||
@@ -3,7 +3,6 @@ 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')
|
||||
@@ -83,11 +82,7 @@ const print = (browsers = []) => {
|
||||
|
||||
console.log('')
|
||||
|
||||
const sortByNameAndMajor = sortWith([
|
||||
ascend(prop('name')),
|
||||
ascend(prop('majorVersion')),
|
||||
])
|
||||
const sortedByNameAndMajorVersion = sortByNameAndMajor(browsers)
|
||||
const sortedByNameAndMajorVersion = _.sortBy(browsers, ['name', 'majorVersion'])
|
||||
|
||||
sortedByNameAndMajorVersion.forEach((browser, k) => {
|
||||
const text = stripIndent`
|
||||
|
||||
@@ -8,6 +8,7 @@ const Mocha = require('mocha-7.0.1')
|
||||
const mochaReporters = require('mocha-7.0.1/lib/reporters')
|
||||
const mochaCreateStatsCollector = require('mocha-7.0.1/lib/stats-collector')
|
||||
const mochaColor = mochaReporters.Base.color
|
||||
const mochaSymbols = mochaReporters.Base.symbols
|
||||
|
||||
const debug = require('debug')('cypress:server:reporter')
|
||||
const Promise = require('bluebird')
|
||||
@@ -293,6 +294,34 @@ class Reporter {
|
||||
reporterOptions: this.reporterOptions,
|
||||
})
|
||||
|
||||
if (this.reporterName === 'spec') {
|
||||
// Unfortunately the reporter doesn't expose its indentation logic, so we have to replicate it here
|
||||
let indents = 0
|
||||
|
||||
this.runner.on('suite', function (suite) {
|
||||
++indents
|
||||
})
|
||||
|
||||
this.runner.on('suite end', function () {
|
||||
--indents
|
||||
})
|
||||
|
||||
// Override the default reporter to always show test timing even for fast tests
|
||||
// and display slow ones in yellow rather than red
|
||||
this.runner._events.pass[2] = function (test) {
|
||||
const durationColor = test.speed === 'slow' ? 'medium' : 'fast'
|
||||
const fmt =
|
||||
Array(indents).join(' ') +
|
||||
mochaColor('checkmark', ` ${ mochaSymbols.ok}`) +
|
||||
mochaColor('pass', ' %s') +
|
||||
mochaColor(durationColor, ' (%dms)')
|
||||
|
||||
// Log: `✓ test title (300ms)` when a test passes
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(fmt, test.title, test.duration)
|
||||
}
|
||||
}
|
||||
|
||||
this.runner.ignoreLeaks = true
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@ const glob = require('./util/glob')
|
||||
const cwd = require('./cwd')
|
||||
const debug = require('debug')('cypress:server:scaffold')
|
||||
const errors = require('./errors')
|
||||
const { isEmpty } = require('ramda')
|
||||
const { isDefault } = require('./util/config')
|
||||
|
||||
const getExampleSpecsFullPaths = cypressEx.getPathToExamples()
|
||||
@@ -116,8 +115,8 @@ const isNewProject = (config) => {
|
||||
debug('determine if we should scaffold:')
|
||||
|
||||
// TODO: add tests for this
|
||||
debug('- empty?', isEmpty(files))
|
||||
if (isEmpty(files)) {
|
||||
debug('- empty?', _.isEmpty(files))
|
||||
if (_.isEmpty(files)) {
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,18 @@
|
||||
import _ from 'lodash'
|
||||
import {
|
||||
CYPRESS_ENV_PREFIX,
|
||||
CYPRESS_ENV_PREFIX_LENGTH,
|
||||
CYPRESS_RESERVED_ENV_VARS,
|
||||
} from '../config'
|
||||
import { coerce } from './coerce'
|
||||
|
||||
export const CYPRESS_ENV_PREFIX = 'CYPRESS_'
|
||||
|
||||
export const CYPRESS_ENV_PREFIX_LENGTH = 'CYPRESS_'.length
|
||||
|
||||
export const CYPRESS_RESERVED_ENV_VARS = [
|
||||
'CYPRESS_INTERNAL_ENV',
|
||||
]
|
||||
|
||||
export const CYPRESS_SPECIAL_ENV_VARS = [
|
||||
'RECORD_KEY',
|
||||
]
|
||||
|
||||
export const isDefault = (config: Record<string, any>, prop: string) => {
|
||||
return config.resolved[prop].from === 'default'
|
||||
}
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
const R = require('ramda')
|
||||
|
||||
const addNewlineAtEveryNChar = (str, n) => {
|
||||
// Add a newline char after every 'n' char
|
||||
if (str) {
|
||||
return R.splitEvery(n, str).join('\n')
|
||||
if (!str) {
|
||||
return str
|
||||
}
|
||||
|
||||
let result = []
|
||||
let idx = 0
|
||||
|
||||
while (idx < str.length) {
|
||||
result.push(str.slice(idx, idx += n))
|
||||
}
|
||||
|
||||
return result.join('\n')
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
const _ = require('lodash')
|
||||
const Promise = require('bluebird')
|
||||
const execa = require('execa')
|
||||
const R = require('ramda')
|
||||
const os = require('os')
|
||||
const commandExistsModule = require('command-exists')
|
||||
const log = require('../log')
|
||||
@@ -71,7 +70,7 @@ const sourceShellCommand = function (cmd, shell) {
|
||||
|
||||
const findBash = () => {
|
||||
return execa.shell('which bash')
|
||||
.then(R.prop('stdout'))
|
||||
.then((val) => val.stdout)
|
||||
}
|
||||
|
||||
const getShell = function (shell) {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import _ from 'lodash'
|
||||
import R from 'ramda'
|
||||
import la from 'lazy-ass'
|
||||
import path from 'path'
|
||||
import check from 'check-more-types'
|
||||
@@ -171,15 +170,13 @@ function findSpecsOfType (searchFolder: string, commonSearchOptions: CommonSearc
|
||||
return Bluebird.mapSeries(testFilesPatterns, findOnePattern).then(_.flatten)
|
||||
}
|
||||
|
||||
const setTestType = (testType: Cypress.CypressSpecType) => R.map(R.set(R.lensProp('specType'), testType))
|
||||
|
||||
const findIntegrationSpecs = (searchFolder: string | undefined, commonSearchOptions: CommonSearchOptions, specPattern: string | undefined) => {
|
||||
if (!searchFolder) {
|
||||
return []
|
||||
}
|
||||
|
||||
return findSpecsOfType(searchFolder, commonSearchOptions, specPattern)
|
||||
.then(setTestType(SPEC_TYPES.INTEGRATION))
|
||||
.then((val) => val.map((s) => ({ ...s, specType: SPEC_TYPES.INTEGRATION })))
|
||||
}
|
||||
|
||||
const findComponentSpecs = (searchFolder: string | undefined | false, commonSearchOptions: CommonSearchOptions, specPattern: string | undefined) => {
|
||||
@@ -188,7 +185,7 @@ const findComponentSpecs = (searchFolder: string | undefined | false, commonSear
|
||||
}
|
||||
|
||||
return findSpecsOfType(searchFolder, commonSearchOptions, specPattern)
|
||||
.then(setTestType(SPEC_TYPES.COMPONENT))
|
||||
.then((val) => val.map((s) => ({ ...s, specType: SPEC_TYPES.COMPONENT })))
|
||||
}
|
||||
|
||||
const printFoundSpecs = (foundSpecs: Cypress.Spec[]) => {
|
||||
|
||||
@@ -297,6 +297,7 @@ export async function process (name, cname, videoCompression, ffmpegchaptersConf
|
||||
const outputOptions = [
|
||||
'-preset fast',
|
||||
`-crf ${videoCompression}`,
|
||||
'-pix_fmt yuv420p',
|
||||
]
|
||||
|
||||
if (addChaptersMeta) {
|
||||
|
||||
@@ -94,7 +94,6 @@
|
||||
"ospath": "1.2.2",
|
||||
"p-queue": "6.1.0",
|
||||
"pluralize": "8.0.0",
|
||||
"ramda": "0.27.1",
|
||||
"randomstring": "1.1.5",
|
||||
"recast": "0.20.4",
|
||||
"resolve": "1.17.0",
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
require('../spec_helper')
|
||||
|
||||
const _ = require('lodash')
|
||||
const R = require('ramda')
|
||||
const cp = require('child_process')
|
||||
const pkg = require('../../package.json')
|
||||
const execa = require('execa')
|
||||
@@ -102,7 +101,7 @@ describe('CLI Interface', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
return execa('npm', ['-version'])
|
||||
.then(R.prop('stdout'))
|
||||
.then((val) => val.stdout)
|
||||
.then((version) => {
|
||||
npmVersion = version
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/* eslint-disable no-restricted-properties */
|
||||
require('../spec_helper')
|
||||
|
||||
const R = require('ramda')
|
||||
const _ = require('lodash')
|
||||
const path = require('path')
|
||||
const EE = require('events')
|
||||
@@ -1054,7 +1053,7 @@ describe('lib/cypress', () => {
|
||||
|
||||
// when we work with the browsers we set a few extra flags
|
||||
const chrome = _.find(TYPICAL_BROWSERS, { name: 'chrome' })
|
||||
const launchedChrome = R.merge(chrome, {
|
||||
const launchedChrome = _.defaults({}, chrome, {
|
||||
isHeadless: true,
|
||||
isHeaded: false,
|
||||
})
|
||||
|
||||
@@ -5,7 +5,7 @@ const utils = require(`${root}../lib/browsers/utils`)
|
||||
const snapshot = require('snap-shot-it')
|
||||
|
||||
const normalizeBrowsers = (message) => {
|
||||
return message.replace(/(found are: ).*/, '$1chrome, firefox, electron')
|
||||
return message.replace(/(found on your system are:)(?:\n- .*)*/, '$1\n- chrome\n- firefox\n- electron')
|
||||
}
|
||||
|
||||
// When we added component testing mode, we added the option for electron to be omitted
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
require('../spec_helper')
|
||||
|
||||
const _ = require('lodash')
|
||||
const R = require('ramda')
|
||||
const debug = require('debug')('test')
|
||||
const config = require(`${root}lib/config`)
|
||||
const errors = require(`${root}lib/errors`)
|
||||
@@ -1072,13 +1071,21 @@ describe('lib/config', () => {
|
||||
cfg.projectRoot = '/foo/bar/'
|
||||
|
||||
return config.mergeDefaults(cfg, options)
|
||||
.then(R.prop(prop))
|
||||
.then((val) => val[prop])
|
||||
.then((result) => {
|
||||
expect(result).to.deep.eq(value)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
it('slowTestThreshold=10000 for e2e', function () {
|
||||
return this.defaults('slowTestThreshold', 10000, {}, { testingType: 'e2e' })
|
||||
})
|
||||
|
||||
it('slowTestThreshold=250 for component', function () {
|
||||
return this.defaults('slowTestThreshold', 250, {}, { testingType: 'component' })
|
||||
})
|
||||
|
||||
it('port=null', function () {
|
||||
return this.defaults('port', null)
|
||||
})
|
||||
@@ -1462,6 +1469,7 @@ describe('lib/config', () => {
|
||||
retries: { value: { runMode: 0, openMode: 0 }, from: 'default' },
|
||||
screenshotOnRunFailure: { value: true, from: 'default' },
|
||||
screenshotsFolder: { value: 'cypress/screenshots', from: 'default' },
|
||||
slowTestThreshold: { value: 10000, from: 'default' },
|
||||
supportFile: { value: 'cypress/support', from: 'default' },
|
||||
taskTimeout: { value: 60000, from: 'default' },
|
||||
testFiles: { value: '**/*.*', from: 'default' },
|
||||
@@ -1568,6 +1576,7 @@ describe('lib/config', () => {
|
||||
retries: { value: { runMode: 0, openMode: 0 }, from: 'default' },
|
||||
screenshotOnRunFailure: { value: true, from: 'default' },
|
||||
screenshotsFolder: { value: 'cypress/screenshots', from: 'default' },
|
||||
slowTestThreshold: { value: 10000, from: 'default' },
|
||||
supportFile: { value: 'cypress/support', from: 'default' },
|
||||
taskTimeout: { value: 60000, from: 'default' },
|
||||
testFiles: { value: '**/*.*', from: 'default' },
|
||||
@@ -2412,25 +2421,3 @@ describe('lib/config', () => {
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('lib/util/config', () => {
|
||||
context('.isDefault', () => {
|
||||
it('returns true if value is default value', () => {
|
||||
settings = { baseUrl: null }
|
||||
const defaults = { baseUrl: null }
|
||||
const resolved = {}
|
||||
const merged = config.setResolvedConfigValues(settings, defaults, resolved)
|
||||
|
||||
expect(configUtil.isDefault(merged, 'baseUrl')).to.be.true
|
||||
})
|
||||
|
||||
it('returns false if value is not default value', () => {
|
||||
settings = { baseUrl: null }
|
||||
const defaults = { baseUrl: 'http://localhost:8080' }
|
||||
const resolved = {}
|
||||
const merged = config.setResolvedConfigValues(settings, defaults, resolved)
|
||||
|
||||
expect(configUtil.isDefault(merged, 'baseUrl')).to.be.false
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -41,6 +41,13 @@ describe('lib/files', () => {
|
||||
})
|
||||
})
|
||||
|
||||
// https://github.com/cypress-io/cypress/issues/1558
|
||||
it('explicit null encoding is sent to driver as a Buffer', function () {
|
||||
return files.readFile(this.projectRoot, 'tests/_fixtures/ascii.foo', { encoding: null }).then(({ contents }) => {
|
||||
expect(contents).to.eql(Buffer.from('\n'))
|
||||
})
|
||||
})
|
||||
|
||||
it('parses json to valid JS object', function () {
|
||||
return files.readFile(this.projectRoot, 'tests/_fixtures/users.json').then(({ contents }) => {
|
||||
expect(contents).to.eql([
|
||||
@@ -75,6 +82,15 @@ describe('lib/files', () => {
|
||||
})
|
||||
})
|
||||
|
||||
// https://github.com/cypress-io/cypress/issues/1558
|
||||
it('explicit null encoding is written exactly as received', function () {
|
||||
return files.writeFile(this.projectRoot, '.projects/write_file.txt', Buffer.from(''), { encoding: null }).then(() => {
|
||||
return files.readFile(this.projectRoot, '.projects/write_file.txt', { encoding: null }).then(({ contents }) => {
|
||||
expect(contents).to.eql(Buffer.from(''))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('overwrites existing file by default', function () {
|
||||
return files.writeFile(this.projectRoot, '.projects/write_file.txt', 'foo').then(() => {
|
||||
return files.readFile(this.projectRoot, '.projects/write_file.txt').then(({ contents }) => {
|
||||
|
||||
@@ -18,6 +18,9 @@ describe('lib/fixture', () => {
|
||||
FixturesHelper.scaffold()
|
||||
|
||||
this.todosPath = FixturesHelper.projectPath('todos')
|
||||
this.read = (folder, image, encoding) => {
|
||||
return fs.readFileAsync(path.join(folder, image), encoding)
|
||||
}
|
||||
|
||||
return config.get(this.todosPath).then((cfg) => {
|
||||
({ fixturesFolder: this.fixturesFolder } = cfg)
|
||||
@@ -172,8 +175,8 @@ Expecting 'EOF', '}', ':', ',', ']', got 'STRING'\
|
||||
return config.get(projectPath)
|
||||
.then((cfg) => {
|
||||
return fixture.get(cfg.fixturesFolder, 'foo')
|
||||
.then((fixture) => {
|
||||
expect(fixture).to.deep.eq({ 'bar': 'baz' })
|
||||
.then((result) => {
|
||||
expect(result).to.deep.eq({ 'bar': 'baz' })
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -325,6 +328,15 @@ John,Chef,1982
|
||||
})
|
||||
})
|
||||
|
||||
// https://github.com/cypress-io/cypress/issues/1558
|
||||
context('binary files', () => {
|
||||
it('returns file as buffer regardless of extension when passed null encoding', function () {
|
||||
return fixture.get(this.fixturesFolder, 'nested/fixture.js', { encoding: null }).then((index) => {
|
||||
expect(index).to.eql(Buffer.from('{nested: "fixture"}'))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
context('file with unknown extension and encoding specified', () => {
|
||||
it('returns text encoded as specified', function () {
|
||||
return fixture.get(this.fixturesFolder, 'ascii.foo', { encoding: 'ascii' }).then((index) => {
|
||||
@@ -334,69 +346,64 @@ John,Chef,1982
|
||||
})
|
||||
|
||||
context('image files', () => {
|
||||
beforeEach(function () {
|
||||
this.read = (folder, image, encoding) => {
|
||||
return fs.readFileAsync(path.join(folder, image), encoding)
|
||||
}
|
||||
})
|
||||
|
||||
it('returns png as string', function () {
|
||||
return this.read(this.fixturesFolder, 'images/flower.png', 'base64')
|
||||
.then((str) => {
|
||||
it('returns png as buffer', function () {
|
||||
return this.read(this.fixturesFolder, 'images/flower.png')
|
||||
.then((file) => {
|
||||
return fixture.get(this.fixturesFolder, 'images/flower.png')
|
||||
.then((base64) => {
|
||||
expect(base64).to.eq(str)
|
||||
.then((result) => {
|
||||
expect(result).to.eql(file)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('returns jpg as string', function () {
|
||||
return this.read(this.fixturesFolder, 'images/sample.jpg', 'base64')
|
||||
.then((str) => {
|
||||
it('returns jpg as buffer', function () {
|
||||
return this.read(this.fixturesFolder, 'images/sample.jpg')
|
||||
.then((file) => {
|
||||
return fixture.get(this.fixturesFolder, 'images/sample.jpg')
|
||||
.then((base64) => {
|
||||
expect(base64).to.eq(str)
|
||||
.then((result) => {
|
||||
expect(result).to.eql(file)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('returns gif as string', function () {
|
||||
return this.read(this.fixturesFolder, 'images/word.gif', 'base64')
|
||||
.then((str) => {
|
||||
it('returns gif as buffer', function () {
|
||||
return this.read(this.fixturesFolder, 'images/word.gif')
|
||||
.then((file) => {
|
||||
return fixture.get(this.fixturesFolder, 'images/word.gif')
|
||||
.then((base64) => {
|
||||
expect(base64).to.eq(str)
|
||||
.then((result) => {
|
||||
expect(result).to.eql(file)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('returns tif as string', function () {
|
||||
return this.read(this.fixturesFolder, 'images/sample.tif', 'base64')
|
||||
.then((str) => {
|
||||
it('returns tif as buffer', function () {
|
||||
return this.read(this.fixturesFolder, 'images/sample.tif')
|
||||
.then((file) => {
|
||||
return fixture.get(this.fixturesFolder, 'images/sample.tif')
|
||||
.then((base64) => {
|
||||
expect(base64).to.eq(str)
|
||||
.then((result) => {
|
||||
expect(result).to.eql(file)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('returns png as binary', function () {
|
||||
it('returns png as binary if that encoding is requested', function () {
|
||||
return this.read(this.fixturesFolder, 'images/flower.png', 'binary')
|
||||
.then((bin) => {
|
||||
.then((file) => {
|
||||
return fixture.get(this.fixturesFolder, 'images/flower.png', { encoding: 'binary' })
|
||||
.then((bin2) => {
|
||||
expect(bin).to.eq(bin2)
|
||||
.then((result) => {
|
||||
expect(result).to.eq(file)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
context('zip files', () => {
|
||||
it('returns zip as base64 string', function () {
|
||||
return fixture.get(this.fixturesFolder, 'example.zip').then((base64) => {
|
||||
const str = 'UEsDBAoAAAAAAK2zOUcAAAAAAAAAAAAAAAAEABAAemlwL1VYDAAGAwZWBgMGVvUBFABQSwMECgAAAAAAo7M5RwAAAAAAAAAAAAAAAAkAEAB6aXAvYS50eHRVWAwA8QIGVvECBlb1ARQAUEsDBAoAAAAAAKSzOUcAAAAAAAAAAAAAAAAJABAAemlwL2IudHh0VVgMAPMCBlbzAgZW9QEUAFBLAwQKAAAAAAClszlHAAAAAAAAAAAAAAAACQAQAHppcC9jLnR4dFVYDAD1AgZW9QIGVvUBFABQSwMECgAAAAAApbM5RwAAAAAAAAAAAAAAAAkAEAB6aXAvZC50eHRVWAwA9gIGVvYCBlb1ARQAUEsDBAoAAAAAAKazOUcAAAAAAAAAAAAAAAAJABAAemlwL2UudHh0VVgMAPgCBlb4AgZW9QEUAFBLAwQKAAAAAACnszlHAAAAAAAAAAAAAAAACQAQAHppcC9mLnR4dFVYDAD5AgZW+QIGVvUBFABQSwMECgAAAAAAqLM5RwAAAAAAAAAAAAAAAAkAEAB6aXAvZy50eHRVWAwA+wIGVvsCBlb1ARQAUEsDBAoAAAAAAKizOUcAAAAAAAAAAAAAAAAJABAAemlwL2gudHh0VVgMAPwCBlb8AgZW9QEUAFBLAwQKAAAAAACpszlHAAAAAAAAAAAAAAAACQAQAHppcC9pLnR4dFVYDAD9AgZW/QIGVvUBFABQSwMECgAAAAAAqrM5RwAAAAAAAAAAAAAAAAkAEAB6aXAvai50eHRVWAwA/wIGVv8CBlb1ARQAUEsDBAoAAAAAAK2zOUcAAAAAAAAAAAAAAAAJABAAemlwL2sudHh0VVgMAAYDBlYGAwZW9QEUAFBLAQIVAwoAAAAAAK2zOUcAAAAAAAAAAAAAAAAEAAwAAAAAAAAAAEDtQQAAAAB6aXAvVVgIAAYDBlYGAwZWUEsBAhUDCgAAAAAAo7M5RwAAAAAAAAAAAAAAAAkADAAAAAAAAAAAQKSBMgAAAHppcC9hLnR4dFVYCADxAgZW8QIGVlBLAQIVAwoAAAAAAKSzOUcAAAAAAAAAAAAAAAAJAAwAAAAAAAAAAECkgWkAAAB6aXAvYi50eHRVWAgA8wIGVvMCBlZQSwECFQMKAAAAAAClszlHAAAAAAAAAAAAAAAACQAMAAAAAAAAAABApIGgAAAAemlwL2MudHh0VVgIAPUCBlb1AgZWUEsBAhUDCgAAAAAApbM5RwAAAAAAAAAAAAAAAAkADAAAAAAAAAAAQKSB1wAAAHppcC9kLnR4dFVYCAD2AgZW9gIGVlBLAQIVAwoAAAAAAKazOUcAAAAAAAAAAAAAAAAJAAwAAAAAAAAAAECkgQ4BAAB6aXAvZS50eHRVWAgA+AIGVvgCBlZQSwECFQMKAAAAAACnszlHAAAAAAAAAAAAAAAACQAMAAAAAAAAAABApIFFAQAAemlwL2YudHh0VVgIAPkCBlb5AgZWUEsBAhUDCgAAAAAAqLM5RwAAAAAAAAAAAAAAAAkADAAAAAAAAAAAQKSBfAEAAHppcC9nLnR4dFVYCAD7AgZW+wIGVlBLAQIVAwoAAAAAAKizOUcAAAAAAAAAAAAAAAAJAAwAAAAAAAAAAECkgbMBAAB6aXAvaC50eHRVWAgA/AIGVvwCBlZQSwECFQMKAAAAAACpszlHAAAAAAAAAAAAAAAACQAMAAAAAAAAAABApIHqAQAAemlwL2kudHh0VVgIAP0CBlb9AgZWUEsBAhUDCgAAAAAAqrM5RwAAAAAAAAAAAAAAAAkADAAAAAAAAAAAQKSBIQIAAHppcC9qLnR4dFVYCAD/AgZW/wIGVlBLAQIVAwoAAAAAAK2zOUcAAAAAAAAAAAAAAAAJAAwAAAAAAAAAAECkgVgCAAB6aXAvay50eHRVWAgABgMGVgYDBlZQSwUGAAAAAAwADAAfAwAAjwIAAAAA'
|
||||
|
||||
expect(base64).to.eq(str)
|
||||
it('returns zip as buffer', function () {
|
||||
return this.read(this.fixturesFolder, 'example.zip')
|
||||
.then((file) => {
|
||||
return fixture.get(this.fixturesFolder, 'example.zip').then((result) => {
|
||||
expect(result).to.eql(file)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
require('../../spec_helper')
|
||||
|
||||
const _ = require('lodash')
|
||||
const Promise = require('bluebird')
|
||||
const electron = require('electron')
|
||||
const stripAnsi = require('strip-ansi')
|
||||
const snapshot = require('snap-shot-it')
|
||||
const R = require('ramda')
|
||||
const pkg = require('@packages/root')
|
||||
const { fs } = require(`${root}../lib/util/fs`)
|
||||
const user = require(`${root}../lib/user`)
|
||||
@@ -862,7 +862,7 @@ describe('lib/modes/run', () => {
|
||||
// for some reason I cannot stub property value using Sinon
|
||||
let version
|
||||
// save a copy of "true" experiments right away
|
||||
const names = R.clone(experimental.names)
|
||||
const names = _.cloneDeep(experimental.names)
|
||||
|
||||
before(() => {
|
||||
// reset experiments names before each test
|
||||
|
||||
@@ -111,7 +111,6 @@ describe('lib/reporter', () => {
|
||||
it('recursively creates suites for fullTitle', function () {
|
||||
const args = this.reporter.parseArgs('fail', [this.testObj])
|
||||
|
||||
console.log(args)
|
||||
expect(args[0]).to.eq('fail')
|
||||
|
||||
const title = 'TodoMVC - React When page is initially opened should focus on the todo input field'
|
||||
|
||||
@@ -456,6 +456,16 @@ describe('lib/socket', () => {
|
||||
|
||||
return this.client.emit('backend:request', 'get:fixture', 'does-not-exist.txt', {}, cb)
|
||||
})
|
||||
|
||||
it('passes Buffers through intact', function (done) {
|
||||
const cb = function (resp) {
|
||||
expect(resp.response).to.eql(Buffer.from('[{"json": true}]'))
|
||||
|
||||
return done()
|
||||
}
|
||||
|
||||
return this.client.emit('backend:request', 'get:fixture', 'foo', { encoding: null }, cb)
|
||||
})
|
||||
})
|
||||
|
||||
context('on(http:request)', () => {
|
||||
|
||||
+3
-3
@@ -1,12 +1,12 @@
|
||||
require('../spec_helper')
|
||||
require('../../spec_helper')
|
||||
|
||||
const path = require('path')
|
||||
const os = require('os')
|
||||
const snapshot = require('snap-shot-it')
|
||||
const stripAnsi = require('strip-ansi')
|
||||
const minimist = require('minimist')
|
||||
const argsUtil = require(`${root}lib/util/args`)
|
||||
const getWindowsProxyUtil = require(`${root}lib/util/get-windows-proxy`)
|
||||
const argsUtil = require(`${root}../lib/util/args`)
|
||||
const getWindowsProxyUtil = require(`${root}../lib/util/get-windows-proxy`)
|
||||
|
||||
const cwd = process.cwd()
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
require('../spec_helper')
|
||||
require('../../spec_helper')
|
||||
|
||||
const CacheBuster = require(`${root}lib/util/cache_buster`)
|
||||
const CacheBuster = require(`${root}../lib/util/cache_buster`)
|
||||
|
||||
describe('lib/cache_buster', () => {
|
||||
context('#get', () => {
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
require('../spec_helper')
|
||||
require('../../spec_helper')
|
||||
|
||||
const _ = require('lodash')
|
||||
const { stripIndent } = require('common-tags')
|
||||
const chromePolicyCheck = require(`${root}lib/util/chrome_policy_check`)
|
||||
const chromePolicyCheck = require(`${root}../lib/util/chrome_policy_check`)
|
||||
|
||||
describe('lib/util/chrome_policy_check', () => {
|
||||
context('.getRunner returns a function', () => {
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
const mockedEnv = require('mocked-env')
|
||||
|
||||
require('../spec_helper')
|
||||
require('../../spec_helper')
|
||||
|
||||
const ciProvider = require(`${root}lib/util/ci_provider`)
|
||||
const ciProvider = require(`${root}../lib/util/ci_provider`)
|
||||
|
||||
const expectsName = (name) => {
|
||||
expect(ciProvider.provider(), 'CI providers detected name').to.eq(name)
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
require('../spec_helper')
|
||||
require('../../spec_helper')
|
||||
|
||||
const { coerce } = require(`${root}lib/util/coerce`)
|
||||
const { getProcessEnvVars } = require(`${root}lib/util/config`)
|
||||
const { coerce } = require(`${root}../lib/util/coerce`)
|
||||
const { getProcessEnvVars } = require(`${root}../lib/util/config`)
|
||||
|
||||
describe('lib/util/coerce', () => {
|
||||
beforeEach(function () {
|
||||
@@ -0,0 +1,48 @@
|
||||
require('../../spec_helper')
|
||||
|
||||
const configUtil = require(`${root}../lib/util/config`)
|
||||
|
||||
describe('lib/util/config', () => {
|
||||
context('.isDefault', () => {
|
||||
it('returns true if value is default value', () => {
|
||||
const options = {
|
||||
resolved: {
|
||||
baseUrl: { from: 'default' },
|
||||
},
|
||||
}
|
||||
|
||||
expect(configUtil.isDefault(options, 'baseUrl')).to.be.true
|
||||
})
|
||||
|
||||
it('returns false if value is not default value', () => {
|
||||
const options = {
|
||||
resolved: {
|
||||
baseUrl: { from: 'cli' },
|
||||
},
|
||||
}
|
||||
|
||||
expect(configUtil.isDefault(options, 'baseUrl')).to.be.false
|
||||
})
|
||||
})
|
||||
|
||||
context('.getProcessEnvVars', () => {
|
||||
it('returns process envs prefixed with cypress', () => {
|
||||
const envs = {
|
||||
CYPRESS_BASE_URL: 'value',
|
||||
RANDOM_ENV: 'ignored',
|
||||
}
|
||||
|
||||
expect(configUtil.getProcessEnvVars(envs)).to.deep.eq({
|
||||
BASE_URL: 'value',
|
||||
})
|
||||
})
|
||||
|
||||
it('does not return CYPRESS_RESERVED_ENV_VARS', () => {
|
||||
const envs = {
|
||||
CYPRESS_INTERNAL_ENV: 'value',
|
||||
}
|
||||
|
||||
expect(configUtil.getProcessEnvVars(envs)).to.deep.eq({})
|
||||
})
|
||||
})
|
||||
})
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
require('../spec_helper')
|
||||
require('../../spec_helper')
|
||||
|
||||
const duration = require(`${root}lib/util/duration`)
|
||||
const duration = require(`${root}../lib/util/duration`)
|
||||
|
||||
describe('lib/util/duration', () => {
|
||||
context('.format', () => {
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
import '../spec_helper'
|
||||
import '../../spec_helper'
|
||||
|
||||
import { connect, agent } from '@packages/network'
|
||||
import { isListening } from '../../lib/util/ensure-url'
|
||||
import { isListening } from '../../../lib/util/ensure-url'
|
||||
import sinon from 'sinon'
|
||||
import nock from 'nock'
|
||||
|
||||
+5
-5
@@ -1,13 +1,13 @@
|
||||
require('../spec_helper')
|
||||
require('../../spec_helper')
|
||||
|
||||
const os = require('os')
|
||||
const path = require('path')
|
||||
const Promise = require('bluebird')
|
||||
const lockFile = Promise.promisifyAll(require('lockfile'))
|
||||
const { fs } = require(`${root}lib/util/fs`)
|
||||
const env = require(`${root}lib/util/env`)
|
||||
const exit = require(`${root}lib/util/exit`)
|
||||
const FileUtil = require(`${root}lib/util/file`)
|
||||
const { fs } = require(`${root}../lib/util/fs`)
|
||||
const env = require(`${root}../lib/util/env`)
|
||||
const exit = require(`${root}../lib/util/exit`)
|
||||
const FileUtil = require(`${root}../lib/util/file`)
|
||||
|
||||
describe('lib/util/file', () => {
|
||||
beforeEach(function () {
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
require('../spec_helper')
|
||||
require('../../spec_helper')
|
||||
|
||||
const humanInterval = require('human-interval')
|
||||
const humanTime = require(`${root}lib/util/human_time`)
|
||||
const humanTime = require(`${root}../lib/util/human_time`)
|
||||
|
||||
describe('lib/util/human_time', () => {
|
||||
context('.long', () => {
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
import '../spec_helper'
|
||||
import '../../spec_helper'
|
||||
|
||||
import newlines from '../../lib/util/newlines'
|
||||
import newlines from '../../../lib/util/newlines'
|
||||
|
||||
describe('lib/util/newlines', function () {
|
||||
it('inserts newline at each n char', function () {
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
require('../spec_helper')
|
||||
require('../../spec_helper')
|
||||
|
||||
const cp = require('child_process')
|
||||
const open = require(`${root}lib/util/open`)
|
||||
const open = require(`${root}../lib/util/open`)
|
||||
|
||||
const platform = (p) => {
|
||||
return Object.defineProperty(process, 'platform', {
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
require('../spec_helper')
|
||||
require('../../spec_helper')
|
||||
|
||||
const origin = require(`${root}lib/util/origin`)
|
||||
const origin = require(`${root}../lib/util/origin`)
|
||||
|
||||
describe('lib/util/origin', () => {
|
||||
beforeEach(function () {
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
require('../spec_helper')
|
||||
require('../../spec_helper')
|
||||
|
||||
const path_helpers = require(`${root}lib/util/path_helpers`)
|
||||
const path_helpers = require(`${root}../lib/util/path_helpers`)
|
||||
|
||||
describe('lib/util/path_helpers', () => {
|
||||
context('checkIfResolveChangedRootFolder', () => {
|
||||
+4
-4
@@ -1,10 +1,10 @@
|
||||
require('../spec_helper')
|
||||
require('../../spec_helper')
|
||||
|
||||
const os = require('os')
|
||||
const path = require('path')
|
||||
const { fs } = require(`${root}/lib/util/fs`)
|
||||
const findProcess = require(`${root}lib/util/find_process`)
|
||||
const profileCleaner = require(`${root}lib/util/profile_cleaner`)
|
||||
const { fs } = require(`${root}../lib/util/fs`)
|
||||
const findProcess = require(`${root}../lib/util/find_process`)
|
||||
const profileCleaner = require(`${root}../lib/util/profile_cleaner`)
|
||||
|
||||
const tmpDir = os.tmpdir()
|
||||
const pidProfilesFolder = path.join(tmpDir, 'pid-profiles')
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
require('../spec_helper')
|
||||
require('../../spec_helper')
|
||||
|
||||
const randomstring = require('randomstring')
|
||||
const random = require(`${root}lib/util/random`)
|
||||
const random = require(`${root}../lib/util/random`)
|
||||
|
||||
context('.id', () => {
|
||||
it('returns random.generate string with length 5 by default', () => {
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
require('../spec_helper')
|
||||
require('../../spec_helper')
|
||||
|
||||
const { apiRoutes, onRoutes } = require(`${root}/lib/util/routes`)
|
||||
const { apiRoutes, onRoutes } = require(`${root}../lib/util/routes`)
|
||||
|
||||
describe('lib/util/routes', () => {
|
||||
describe('api routes', () => {
|
||||
+6
-6
@@ -1,9 +1,9 @@
|
||||
require('../spec_helper')
|
||||
require('../../spec_helper')
|
||||
|
||||
const R = require('ramda')
|
||||
const _ = require('lodash')
|
||||
const path = require('path')
|
||||
const config = require(`${root}lib/config`)
|
||||
const specsUtil = require(`${root}lib/util/specs`).default
|
||||
const config = require(`${root}../lib/config`)
|
||||
const specsUtil = require(`${root}../lib/util/specs`).default
|
||||
const FixturesHelper = require('@tooling/system-tests/lib/fixtures')
|
||||
const debug = require('debug')('test')
|
||||
|
||||
@@ -33,7 +33,7 @@ describe('lib/util/specs', () => {
|
||||
it('returns absolute filenames', function () {
|
||||
return specsUtil
|
||||
.findSpecs(this.config)
|
||||
.then((R.forEach(checkFoundSpec)))
|
||||
.then(((specs) => specs.forEach(checkFoundSpec)))
|
||||
})
|
||||
|
||||
it('handles fixturesFolder being false', function () {
|
||||
@@ -65,7 +65,7 @@ describe('lib/util/specs', () => {
|
||||
cfg.resolved.testingType = { value: 'component' }
|
||||
|
||||
return specsUtil.findSpecs(cfg)
|
||||
}).then(R.project(['relative', 'specType']))
|
||||
}).then((val) => val.map((spec) => _.pick(spec, ['relative', 'specType'])))
|
||||
.then((files) => {
|
||||
expect(files).to.deep.equal([
|
||||
{
|
||||
+2
-2
@@ -1,11 +1,11 @@
|
||||
require('../spec_helper')
|
||||
require('../../spec_helper')
|
||||
|
||||
const _ = require('lodash')
|
||||
const fs = require('fs')
|
||||
const stream = require('stream')
|
||||
const Promise = require('bluebird')
|
||||
const { concatStream } = require('@packages/network')
|
||||
const { streamBuffer } = require('../../lib/util/stream_buffer')
|
||||
const { streamBuffer } = require('../../../lib/util/stream_buffer')
|
||||
|
||||
function drain (stream) {
|
||||
return new Promise((resolve) => {
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
import '../spec_helper'
|
||||
import '../../spec_helper'
|
||||
import { expect } from 'chai'
|
||||
import execa from 'execa'
|
||||
import proxyquire from 'proxyquire'
|
||||
@@ -6,7 +6,7 @@ import proxyquire from 'proxyquire'
|
||||
const ERROR_MESSAGE = 'Setting the NODE_TLS_REJECT_UNAUTHORIZED'
|
||||
|
||||
const TLS_CONNECT = `require('tls').connect().on('error', ()=>{});`
|
||||
const SUPPRESS_WARNING = `require('${__dirname}/../../lib/util/suppress_warnings').suppress();`
|
||||
const SUPPRESS_WARNING = `require('${__dirname}/../../../lib/util/suppress_warnings').suppress();`
|
||||
|
||||
describe('lib/util/suppress_warnings', function () {
|
||||
it('tls.connect emits warning if NODE_TLS_REJECT_UNAUTHORIZED=0 and not suppressed', function () {
|
||||
@@ -36,7 +36,7 @@ describe('lib/util/suppress_warnings', function () {
|
||||
const emitWarning = sinon.spy(process, 'emitWarning')
|
||||
|
||||
// force typescript to always be non-requireable
|
||||
const { suppress } = proxyquire('../../lib/util/suppress_warnings', {})
|
||||
const { suppress } = proxyquire('../../../lib/util/suppress_warnings', {})
|
||||
|
||||
suppress()
|
||||
|
||||
+4
-4
@@ -1,11 +1,11 @@
|
||||
require('../spec_helper')
|
||||
require('../../spec_helper')
|
||||
|
||||
const snapshot = require('snap-shot-it')
|
||||
const stripAnsi = require('strip-ansi')
|
||||
const widestLine = require('widest-line')
|
||||
const env = require(`${root}lib/util/env`)
|
||||
const terminal = require(`${root}lib/util/terminal`)
|
||||
const terminalSize = require(`${root}lib/util/terminal-size`)
|
||||
const env = require(`${root}../lib/util/env`)
|
||||
const terminal = require(`${root}../lib/util/terminal`)
|
||||
const terminalSize = require(`${root}../lib/util/terminal-size`)
|
||||
|
||||
const sanitizeSnapshot = (str) => {
|
||||
return snapshot(stripAnsi(str))
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
require('../spec_helper')
|
||||
require('../../spec_helper')
|
||||
|
||||
const fs = require('fs')
|
||||
const os = require('os')
|
||||
const path = require('path')
|
||||
const trash = require(`${root}lib/util/trash`)
|
||||
const trash = require(`${root}../lib/util/trash`)
|
||||
|
||||
const populateDirectories = function (basePath) {
|
||||
fs.mkdirSync(basePath)
|
||||
@@ -1,8 +1,8 @@
|
||||
require('../spec_helper')
|
||||
require('../../spec_helper')
|
||||
|
||||
const tty = require('tty')
|
||||
const ttyUtil = require(`${root}lib/util/tty`)
|
||||
const terminalSize = require(`${root}lib/util/terminal-size`)
|
||||
const ttyUtil = require(`${root}../lib/util/tty`)
|
||||
const terminalSize = require(`${root}../lib/util/terminal-size`)
|
||||
|
||||
const ttys = [process.stdin.isTTY, process.stdout.isTTY, process.stderr.isTTY]
|
||||
|
||||
+12
-7
@@ -10,7 +10,6 @@ const pluralize = require('pluralize')
|
||||
const execa = require('execa')
|
||||
const electron = require('@packages/electron')
|
||||
const debug = require('debug')('cypress:binary')
|
||||
const R = require('ramda')
|
||||
const la = require('lazy-ass')
|
||||
const check = require('check-more-types')
|
||||
|
||||
@@ -116,7 +115,11 @@ const buildCypressApp = function (platform, version, options = {}) {
|
||||
|
||||
return packages.runAllBuild()
|
||||
// Promise.resolve()
|
||||
.then(R.tap(logBuiltAllPackages))
|
||||
.then((val) => {
|
||||
logBuiltAllPackages(val)
|
||||
|
||||
return val
|
||||
})
|
||||
}
|
||||
|
||||
const copyPackages = function () {
|
||||
@@ -343,7 +346,7 @@ require('./packages/server')\
|
||||
console.log('in build folder %s', buildFolder)
|
||||
|
||||
return execa('ls', ['-la', buildFolder])
|
||||
.then(R.prop('stdout'))
|
||||
.then((val) => val.stdout)
|
||||
.then(console.log)
|
||||
}
|
||||
|
||||
@@ -430,14 +433,16 @@ require('./packages/server')\
|
||||
}
|
||||
|
||||
const printDiskUsage = function (sizes) {
|
||||
const bySize = R.sortBy(R.prop('1'))
|
||||
|
||||
return console.log(bySize(R.toPairs(sizes)))
|
||||
return console.log(_.sortBy(_.toPairs(sizes), 1))
|
||||
}
|
||||
|
||||
return execa('du', args)
|
||||
.then(parseDiskUsage)
|
||||
.then(R.tap(printDiskUsage))
|
||||
.then((val) => {
|
||||
printDiskUsage(val)
|
||||
|
||||
return val
|
||||
})
|
||||
.then((sizes) => {
|
||||
return performanceTracking.track('test runner size', sizes)
|
||||
})
|
||||
|
||||
+12
-22
@@ -4,7 +4,6 @@ const bumpercar = require('@cypress/bumpercar')
|
||||
const path = require('path')
|
||||
const la = require('lazy-ass')
|
||||
const check = require('check-more-types')
|
||||
const R = require('ramda')
|
||||
const { configFromEnvOrJsonFile, filenameToShellVariable } = require('@cypress/env-or-json-file')
|
||||
const makeEmptyGithubCommit = require('make-empty-github-commit')
|
||||
const parse = require('parse-github-repo-url')
|
||||
@@ -88,7 +87,7 @@ const getCiConfig = function () {
|
||||
return config
|
||||
}
|
||||
|
||||
const awaitEachProjectAndProvider = function (projects, fn, filter = R.identity) {
|
||||
const awaitEachProjectAndProvider = function (projects, fn, filter = (val) => val) {
|
||||
const creds = getCiConfig()
|
||||
|
||||
// configure a new Bumpercar
|
||||
@@ -119,7 +118,7 @@ const awaitEachProjectAndProvider = function (projects, fn, filter = R.identity)
|
||||
|
||||
car = bumpercar.create({ providers })
|
||||
|
||||
const filteredProjects = R.filter(filter, projects)
|
||||
const filteredProjects = projects.filter(filter)
|
||||
|
||||
if (check.empty(filteredProjects)) {
|
||||
console.log('⚠️ zero filtered projects left after filtering')
|
||||
@@ -136,26 +135,17 @@ const awaitEachProjectAndProvider = function (projects, fn, filter = R.identity)
|
||||
// do not trigger all projects if there is specific provider
|
||||
// for example appVeyor should be used for Windows testing
|
||||
const getFilterByProvider = function (providerName, platformName) {
|
||||
let platformFilter; let providerFilter
|
||||
return (val) => {
|
||||
if (providerName && val.provider !== providerName) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (providerName) {
|
||||
console.log('only allow projects for provider', providerName)
|
||||
providerFilter = R.propEq('provider', providerName)
|
||||
} else {
|
||||
providerFilter = R.identity
|
||||
if (platformName && val.platform !== platformName) {
|
||||
return false
|
||||
}
|
||||
|
||||
return val
|
||||
}
|
||||
|
||||
if (platformName) {
|
||||
console.log('only allow projects for platform', platformName)
|
||||
platformFilter = R.propEq('platform', platformName)
|
||||
} else {
|
||||
platformFilter = R.identity
|
||||
}
|
||||
|
||||
// combined filter is when both filters pass
|
||||
const projectFilter = R.allPass([providerFilter, platformFilter])
|
||||
|
||||
return projectFilter
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
@@ -199,7 +189,7 @@ module.exports = {
|
||||
}
|
||||
|
||||
return awaitEachProjectAndProvider(PROJECTS, updateProject, projectFilter)
|
||||
.then(R.always(result))
|
||||
.then(() => result)
|
||||
},
|
||||
|
||||
// triggers test projects on multiple CIs
|
||||
|
||||
@@ -12,7 +12,6 @@ const la = require('lazy-ass')
|
||||
const check = require('check-more-types')
|
||||
const debug = require('debug')('cypress:binary')
|
||||
const questionsRemain = require('@cypress/questions-remain')
|
||||
const R = require('ramda')
|
||||
const rp = require('@cypress/request-promise')
|
||||
|
||||
const zip = require('./zip')
|
||||
@@ -37,7 +36,7 @@ const fail = (str) => {
|
||||
return console.log(chalk.bgRed(` ${chalk.black(str)} `))
|
||||
}
|
||||
|
||||
const zippedFilename = R.always(upload.zipName)
|
||||
const zippedFilename = () => upload.zipName
|
||||
|
||||
// goes through the list of properties and asks relevant question
|
||||
// resolves with all relevant options set
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
const path = require('path')
|
||||
const la = require('lazy-ass')
|
||||
const check = require('check-more-types')
|
||||
const R = require('ramda')
|
||||
const os = require('os')
|
||||
const _ = require('lodash')
|
||||
|
||||
// canonical platform names
|
||||
const platforms = {
|
||||
@@ -11,11 +11,11 @@ const platforms = {
|
||||
windows: 'win32',
|
||||
}
|
||||
|
||||
const isValidPlatform = check.oneOf(R.values(platforms))
|
||||
const isValidPlatform = check.oneOf(_.values(platforms))
|
||||
|
||||
const checkPlatform = (platform) => {
|
||||
return la(isValidPlatform(platform),
|
||||
'invalid build platform', platform, 'valid choices', R.values(platforms))
|
||||
'invalid build platform', platform, 'valid choices', _.values(platforms))
|
||||
}
|
||||
|
||||
const buildRootDir = () => {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user