mirror of
https://github.com/cypress-io/cypress.git
synced 2026-05-06 23:10:22 -05:00
merge in develop to 10.0-release
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
exports['prepare-release-artifacts runs expected commands 1'] = `
|
||||
$ node ./scripts/prepare-release-artifacts.js --dry-run --sha 57d0a85108fad6f77b39db88b8a7d8a3bfdb51a2 --version 1.2.3
|
||||
🏗 Running \`move-binaries\`...
|
||||
🏗 Dry run, not executing: node ./scripts/binary.js move-binaries --sha 57d0a85108fad6f77b39db88b8a7d8a3bfdb51a2 --version 1.2.3
|
||||
🏗 Running \`create-stable-npm-package\`...
|
||||
🏗 Dry run, not executing: ./scripts/create-stable-npm-package.sh https://cdn.cypress.io/beta/npm/1.2.3/linux-x64/develop-57d0a85108fad6f77b39db88b8a7d8a3bfdb51a2/cypress.tgz
|
||||
|
||||
`
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 165 KiB |
@@ -1,4 +1,4 @@
|
||||
{
|
||||
"chrome:beta": "99.0.4844.45",
|
||||
"chrome:stable": "98.0.4758.102"
|
||||
"chrome:beta": "100.0.4896.20",
|
||||
"chrome:stable": "99.0.4844.51"
|
||||
}
|
||||
|
||||
+9
-5
@@ -29,7 +29,7 @@ mainBuildFilters: &mainBuildFilters
|
||||
only:
|
||||
- develop
|
||||
- 10.0-release
|
||||
- merge-develop-2-28-22
|
||||
- merge-develop-3-7-22
|
||||
|
||||
# usually we don't build Mac app - it takes a long time
|
||||
# but sometimes we want to really confirm we are doing the right thing
|
||||
@@ -39,7 +39,8 @@ macWorkflowFilters: &mac-workflow-filters
|
||||
or:
|
||||
- equal: [ develop, << pipeline.git.branch >> ]
|
||||
- equal: [ '10.0-release', << pipeline.git.branch >> ]
|
||||
- equal: [ merge-develop-2-28-22, << pipeline.git.branch >> ]
|
||||
- equal: [ merge-develop-3-7-22, << pipeline.git.branch >> ]
|
||||
- equal: [ fix-beta-build-caching, << pipeline.git.branch >> ]
|
||||
- matches:
|
||||
pattern: "-release$"
|
||||
value: << pipeline.git.branch >>
|
||||
@@ -49,6 +50,7 @@ windowsWorkflowFilters: &windows-workflow-filters
|
||||
or:
|
||||
- equal: [ develop, << pipeline.git.branch >> ]
|
||||
- equal: [ '10.0-release', << pipeline.git.branch >> ]
|
||||
- equal: [ fix-beta-build-caching, << pipeline.git.branch >> ]
|
||||
- matches:
|
||||
pattern: "-release$"
|
||||
value: << pipeline.git.branch >>
|
||||
@@ -81,6 +83,7 @@ executors:
|
||||
macos:
|
||||
# Executor should have Node >= required version
|
||||
xcode: "13.0.0"
|
||||
resource_class: macos.x86.medium.gen2
|
||||
environment:
|
||||
PLATFORM: mac
|
||||
|
||||
@@ -1675,7 +1678,7 @@ jobs:
|
||||
- run:
|
||||
name: Check current branch to persist artifacts
|
||||
command: |
|
||||
if [[ "$CIRCLE_BRANCH" != "develop" && "$CIRCLE_BRANCH" != "merge-develop-2-28-22" && "$CIRCLE_BRANCH" != "10.0-release" ]]; then
|
||||
if [[ "$CIRCLE_BRANCH" != "develop" && "$CIRCLE_BRANCH" != "merge-develop-3-7-22" && "$CIRCLE_BRANCH" != "10.0-release" ]]; then
|
||||
echo "Not uploading artifacts or posting install comment for this branch."
|
||||
circleci-agent step halt
|
||||
fi
|
||||
@@ -2405,12 +2408,13 @@ mac-workflow: &mac-workflow
|
||||
- node_modules_install:
|
||||
name: darwin-node-modules-install
|
||||
executor: mac
|
||||
resource_class: macos.x86.medium.gen2
|
||||
only-cache-for-root-user: true
|
||||
|
||||
- build:
|
||||
name: darwin-build
|
||||
executor: mac
|
||||
resource_class: medium
|
||||
resource_class: macos.x86.medium.gen2
|
||||
requires:
|
||||
- darwin-node-modules-install
|
||||
|
||||
@@ -2429,7 +2433,7 @@ mac-workflow: &mac-workflow
|
||||
- test-runner:upload
|
||||
- test-runner:commit-status-checks
|
||||
executor: mac
|
||||
resource_class: medium
|
||||
resource_class: macos.x86.medium.gen2
|
||||
requires:
|
||||
- darwin-build
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ exports['package.json build outputs expected properties 1'] = {
|
||||
"name": "test",
|
||||
"engines": "test engines",
|
||||
"version": "x.y.z",
|
||||
"buildInfo": "replaced by normalizePackageJson",
|
||||
"description": "Cypress.io end to end testing tool",
|
||||
"homepage": "https://github.com/cypress-io/cypress",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -43,4 +43,4 @@ https://download.cypress.io/desktop/0.20.2?platform=OS&arch=ARCH
|
||||
|
||||
exports['desktop url from template'] = `
|
||||
https://download.cypress.io/desktop/0.20.2/darwin-x64/cypress.zip
|
||||
`
|
||||
`
|
||||
|
||||
@@ -7,7 +7,7 @@ Application Data: /user/app/data/path
|
||||
Browser Profiles: /user/app/data/path/to/browsers
|
||||
Binary Caches: /user/path/to/binary/cache
|
||||
|
||||
Cypress Version: 0.0.0-development
|
||||
Cypress Version: 0.0.0-development (stable)
|
||||
System Platform: linux (Foo-OsVersion)
|
||||
System Memory: 1.2 GB free 400 MB
|
||||
|
||||
@@ -29,7 +29,7 @@ Application Data: /user/app/data/path
|
||||
Browser Profiles: /user/app/data/path/to/browsers
|
||||
Binary Caches: /user/path/to/binary/cache
|
||||
|
||||
Cypress Version: 0.0.0-development
|
||||
Cypress Version: 0.0.0-development (stable)
|
||||
System Platform: linux (Foo-OsVersion)
|
||||
System Memory: 1.2 GB free 400 MB
|
||||
|
||||
@@ -48,8 +48,46 @@ Application Data: /user/app/data/path
|
||||
Browser Profiles: /user/app/data/path/to/browsers
|
||||
Binary Caches: /user/path/to/binary/cache
|
||||
|
||||
Cypress Version: 0.0.0-development
|
||||
Cypress Version: 0.0.0-development (stable)
|
||||
System Platform: linux (Foo-OsVersion)
|
||||
System Memory: 1.2 GB free 400 MB
|
||||
|
||||
`
|
||||
|
||||
exports['logs additional info about pre-releases'] = `
|
||||
|
||||
Proxy Settings: none detected
|
||||
Environment Variables: none detected
|
||||
|
||||
Application Data: /user/app/data/path
|
||||
Browser Profiles: /user/app/data/path/to/browsers
|
||||
Binary Caches: /user/path/to/binary/cache
|
||||
|
||||
Cypress Version: 0.0.0-development (pre-release)
|
||||
System Platform: linux (Foo-OsVersion)
|
||||
System Memory: 1.2 GB free 400 MB
|
||||
|
||||
This is a pre-release build of Cypress.
|
||||
Build info:
|
||||
Commit SHA: abc123
|
||||
Commit Branch: someBranchName
|
||||
Commit Date: 2022-02-02Txx:xx:xx.000Z
|
||||
|
||||
`
|
||||
|
||||
exports['logs additional info about development'] = `
|
||||
|
||||
Proxy Settings: none detected
|
||||
Environment Variables: none detected
|
||||
|
||||
Application Data: /user/app/data/path
|
||||
Browser Profiles: /user/app/data/path/to/browsers
|
||||
Binary Caches: /user/path/to/binary/cache
|
||||
|
||||
Cypress Version: 0.0.0-development (pre-release)
|
||||
System Platform: linux (Foo-OsVersion)
|
||||
System Memory: 1.2 GB free 400 MB
|
||||
|
||||
This is the development (un-built) Cypress CLI.
|
||||
|
||||
`
|
||||
|
||||
@@ -256,4 +256,40 @@ https://on.cypress.io/guides/getting-started/installing-cypress#system-requireme
|
||||
|
||||
Platform: win32-ia32
|
||||
|
||||
`
|
||||
|
||||
exports['/lib/tasks/install .start non-stable builds logs a warning about installing a pre-release 1'] = `
|
||||
⚠ Warning: You are installing a pre-release build of Cypress.
|
||||
|
||||
Bugs may be present which do not exist in production builds.
|
||||
|
||||
This build was created from:
|
||||
* Commit SHA: abc123
|
||||
* Commit Branch: aBranchName
|
||||
* Commit Timestamp: 1996-11-27Txx:xx:xx.000Z
|
||||
|
||||
Installing Cypress (version: https://cdn.cypress.io/beta/binary/0.0.0-development/darwin-x64/aBranchName-abc123/cypress.zip)
|
||||
|
||||
|
||||
⠋ Downloaded Cypress
|
||||
✔ Downloaded Cypress
|
||||
✔ Downloaded Cypress
|
||||
⠋ Unzipped Cypress
|
||||
✔ Downloaded Cypress
|
||||
✔ Unzipped Cypress
|
||||
✔ Downloaded Cypress
|
||||
✔ Unzipped Cypress
|
||||
⠋ Finished Installation /cache/Cypress/1.2.3
|
||||
✔ Downloaded Cypress
|
||||
✔ Unzipped Cypress
|
||||
✔ Finished Installation /cache/Cypress/1.2.3
|
||||
✔ Downloaded Cypress
|
||||
✔ Unzipped Cypress
|
||||
✔ Finished Installation /cache/Cypress/1.2.3
|
||||
|
||||
You can now open Cypress by running: node_modules/.bin/cypress open
|
||||
|
||||
https://on.cypress.io/installing-cypress
|
||||
|
||||
|
||||
`
|
||||
|
||||
+54
-43
@@ -11,6 +11,7 @@ const _ = require('lodash')
|
||||
const g = chalk.green
|
||||
// color for paths
|
||||
const p = chalk.cyan
|
||||
const red = chalk.red
|
||||
// urls
|
||||
const link = chalk.blue.underline
|
||||
|
||||
@@ -43,56 +44,66 @@ const formatCypressVariables = () => {
|
||||
return maskSensitiveVariables(vars)
|
||||
}
|
||||
|
||||
methods.start = (options = {}) => {
|
||||
methods.start = async (options = {}) => {
|
||||
const args = ['--mode=info']
|
||||
|
||||
return spawn.start(args, {
|
||||
await spawn.start(args, {
|
||||
dev: options.dev,
|
||||
})
|
||||
.then(() => {
|
||||
console.log()
|
||||
const proxyVars = methods.findProxyEnvironmentVariables()
|
||||
|
||||
if (_.isEmpty(proxyVars)) {
|
||||
console.log('Proxy Settings: none detected')
|
||||
} else {
|
||||
console.log('Proxy Settings:')
|
||||
_.forEach(proxyVars, (value, key) => {
|
||||
console.log('%s: %s', key, g(value))
|
||||
})
|
||||
console.log()
|
||||
const proxyVars = methods.findProxyEnvironmentVariables()
|
||||
|
||||
console.log()
|
||||
console.log('Learn More: %s', link('https://on.cypress.io/proxy-configuration'))
|
||||
console.log()
|
||||
}
|
||||
})
|
||||
.then(() => {
|
||||
const cyVars = formatCypressVariables()
|
||||
|
||||
if (_.isEmpty(cyVars)) {
|
||||
console.log('Environment Variables: none detected')
|
||||
} else {
|
||||
console.log('Environment Variables:')
|
||||
_.forEach(cyVars, (value, key) => {
|
||||
console.log('%s: %s', key, g(value))
|
||||
})
|
||||
}
|
||||
})
|
||||
.then(() => {
|
||||
console.log()
|
||||
console.log('Application Data:', p(util.getApplicationDataFolder()))
|
||||
console.log('Browser Profiles:', p(util.getApplicationDataFolder('browsers')))
|
||||
console.log('Binary Caches: %s', p(state.getCacheDir()))
|
||||
})
|
||||
.then(() => {
|
||||
console.log()
|
||||
|
||||
return util.getOsVersionAsync().then((osVersion) => {
|
||||
console.log('Cypress Version: %s', g(util.pkgVersion()))
|
||||
console.log('System Platform: %s (%s)', g(os.platform()), g(osVersion))
|
||||
console.log('System Memory: %s free %s', g(prettyBytes(os.totalmem())), g(prettyBytes(os.freemem())))
|
||||
if (_.isEmpty(proxyVars)) {
|
||||
console.log('Proxy Settings: none detected')
|
||||
} else {
|
||||
console.log('Proxy Settings:')
|
||||
_.forEach(proxyVars, (value, key) => {
|
||||
console.log('%s: %s', key, g(value))
|
||||
})
|
||||
})
|
||||
|
||||
console.log()
|
||||
console.log('Learn More: %s', link('https://on.cypress.io/proxy-configuration'))
|
||||
console.log()
|
||||
}
|
||||
|
||||
const cyVars = formatCypressVariables()
|
||||
|
||||
if (_.isEmpty(cyVars)) {
|
||||
console.log('Environment Variables: none detected')
|
||||
} else {
|
||||
console.log('Environment Variables:')
|
||||
_.forEach(cyVars, (value, key) => {
|
||||
console.log('%s: %s', key, g(value))
|
||||
})
|
||||
}
|
||||
|
||||
console.log()
|
||||
console.log('Application Data:', p(util.getApplicationDataFolder()))
|
||||
console.log('Browser Profiles:', p(util.getApplicationDataFolder('browsers')))
|
||||
console.log('Binary Caches: %s', p(state.getCacheDir()))
|
||||
|
||||
console.log()
|
||||
|
||||
const osVersion = await util.getOsVersionAsync()
|
||||
const buildInfo = util.pkgBuildInfo()
|
||||
const isStable = buildInfo && buildInfo.stable
|
||||
|
||||
console.log('Cypress Version: %s', g(util.pkgVersion()), isStable ? g('(stable)') : red('(pre-release)'))
|
||||
console.log('System Platform: %s (%s)', g(os.platform()), g(osVersion))
|
||||
console.log('System Memory: %s free %s', g(prettyBytes(os.totalmem())), g(prettyBytes(os.freemem())))
|
||||
|
||||
if (!buildInfo) {
|
||||
console.log()
|
||||
console.log('This is the', red('development'), '(un-built) Cypress CLI.')
|
||||
} else if (!isStable) {
|
||||
console.log()
|
||||
console.log('This is a', red('pre-release'), 'build of Cypress.')
|
||||
console.log('Build info:')
|
||||
console.log(' Commit SHA:', g(buildInfo.commitSha))
|
||||
console.log(' Commit Branch:', g(buildInfo.commitBranch))
|
||||
console.log(' Commit Date:', g(buildInfo.commitDate))
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = methods
|
||||
|
||||
@@ -41,8 +41,15 @@ const getVersions = () => {
|
||||
return versions
|
||||
})
|
||||
.then((binaryVersions) => {
|
||||
const buildInfo = util.pkgBuildInfo()
|
||||
|
||||
let packageVersion = util.pkgVersion()
|
||||
|
||||
if (!buildInfo) packageVersion += ' (development)'
|
||||
else if (!buildInfo.stable) packageVersion += ' (pre-release)'
|
||||
|
||||
const versions = {
|
||||
package: util.pkgVersion(),
|
||||
package: packageVersion,
|
||||
binary: binaryVersions.binary || 'not installed',
|
||||
electronVersion: binaryVersions.electronVersion || 'not found',
|
||||
electronNodeVersion: binaryVersions.electronNodeVersion || 'not found',
|
||||
|
||||
+138
-217
@@ -1,7 +1,6 @@
|
||||
const _ = require('lodash')
|
||||
const arch = require('arch')
|
||||
const os = require('os')
|
||||
const url = require('url')
|
||||
const path = require('path')
|
||||
const chalk = require('chalk')
|
||||
const debug = require('debug')('cypress:cli')
|
||||
@@ -18,97 +17,10 @@ const logger = require('../logger')
|
||||
const { throwFormErrorText, errors } = require('../errors')
|
||||
const verbose = require('../VerboseRenderer')
|
||||
|
||||
const getNpmArgv = () => {
|
||||
const json = process.env.npm_config_argv
|
||||
const { buildInfo, version } = require('../../package.json')
|
||||
|
||||
if (!json) {
|
||||
return
|
||||
}
|
||||
|
||||
debug('found npm argv json %o', json)
|
||||
|
||||
try {
|
||||
return JSON.parse(json).original || []
|
||||
} catch (e) {
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
// attempt to discover the version specifier used to install Cypress
|
||||
// for example: "^5.0.0", "https://cdn.cypress.io/...", ...
|
||||
const getVersionSpecifier = (startDir = path.resolve(__dirname, '../..')) => {
|
||||
const argv = getNpmArgv()
|
||||
|
||||
if ((process.env.npm_package_resolved || '').endsWith('cypress.tgz')) {
|
||||
return process.env.npm_package_resolved
|
||||
}
|
||||
|
||||
if (argv) {
|
||||
const tgz = _.find(argv, (t) => t.endsWith('cypress.tgz'))
|
||||
|
||||
if (tgz) {
|
||||
return tgz
|
||||
}
|
||||
}
|
||||
|
||||
const getVersionSpecifierFromPkg = (dir) => {
|
||||
debug('looking for versionSpecifier %o', { dir })
|
||||
|
||||
const tryParent = () => {
|
||||
const parentPath = path.resolve(dir, '..')
|
||||
|
||||
if (parentPath === dir) {
|
||||
debug('reached FS root with no versionSpecifier found')
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
return getVersionSpecifierFromPkg(parentPath)
|
||||
}
|
||||
|
||||
return fs.readJSON(path.join(dir, 'package.json'))
|
||||
.catch(() => ({}))
|
||||
.then((pkg) => {
|
||||
const specifier = _.chain(['dependencies', 'devDependencies', 'optionalDependencies'])
|
||||
.map((prop) => _.get(pkg, `${prop}.cypress`))
|
||||
.compact().first().value()
|
||||
|
||||
return specifier || tryParent()
|
||||
})
|
||||
}
|
||||
|
||||
// recurse through parent directories until package.json with `cypress` is found
|
||||
return getVersionSpecifierFromPkg(startDir)
|
||||
.then((versionSpecifier) => {
|
||||
debug('finished looking for versionSpecifier', { versionSpecifier })
|
||||
|
||||
return versionSpecifier
|
||||
})
|
||||
}
|
||||
|
||||
const betaNpmUrlRe = /^\/beta\/npm\/(?<version>[0-9.]+)\/(?<platformSlug>.+?)\/(?<artifactSlug>.+?)\/cypress\.tgz$/
|
||||
|
||||
// convert a prerelease NPM package .tgz URL to the corresponding binary .zip URL
|
||||
const getBinaryUrlFromPrereleaseNpmUrl = (npmUrl) => {
|
||||
let parsed
|
||||
|
||||
try {
|
||||
parsed = url.parse(npmUrl)
|
||||
} catch (e) {
|
||||
return
|
||||
}
|
||||
|
||||
const matches = betaNpmUrlRe.exec(parsed.pathname)
|
||||
|
||||
if (parsed.hostname !== 'cdn.cypress.io' || !matches) {
|
||||
return
|
||||
}
|
||||
|
||||
const { version, artifactSlug } = matches.groups
|
||||
|
||||
parsed.pathname = `/beta/binary/${version}/${os.platform()}-${arch()}/${artifactSlug}/cypress.zip`
|
||||
|
||||
return parsed.format()
|
||||
function _getBinaryUrlFromBuildInfo ({ commitSha, commitBranch }) {
|
||||
return `https://cdn.cypress.io/beta/binary/${version}/${os.platform()}-${arch()}/${commitBranch}-${commitSha}/cypress.zip`
|
||||
}
|
||||
|
||||
const alreadyInstalledMsg = () => {
|
||||
@@ -227,43 +139,71 @@ const validateOS = () => {
|
||||
})
|
||||
}
|
||||
|
||||
const start = (options = {}) => {
|
||||
/**
|
||||
* Returns the version to install - either a string like `1.2.3` to be fetched
|
||||
* from the download server or a file path or HTTP URL.
|
||||
*/
|
||||
function getVersionOverride ({ envVarVersion, buildInfo }) {
|
||||
// let this environment variable reset the binary version we need
|
||||
if (envVarVersion) {
|
||||
return envVarVersion
|
||||
}
|
||||
|
||||
if (buildInfo && !buildInfo.stable) {
|
||||
logger.log(
|
||||
chalk.yellow(stripIndent`
|
||||
${logSymbols.warning} Warning: You are installing a pre-release build of Cypress.
|
||||
|
||||
Bugs may be present which do not exist in production builds.
|
||||
|
||||
This build was created from:
|
||||
* Commit SHA: ${buildInfo.commitSha}
|
||||
* Commit Branch: ${buildInfo.commitBranch}
|
||||
* Commit Timestamp: ${buildInfo.commitDate}
|
||||
`),
|
||||
)
|
||||
|
||||
logger.log()
|
||||
|
||||
return _getBinaryUrlFromBuildInfo(buildInfo)
|
||||
}
|
||||
}
|
||||
|
||||
function getEnvVarVersion () {
|
||||
if (!util.getEnv('CYPRESS_INSTALL_BINARY')) return
|
||||
|
||||
// because passed file paths are often double quoted
|
||||
// and might have extra whitespace around, be robust and trim the string
|
||||
const trimAndRemoveDoubleQuotes = true
|
||||
const envVarVersion = util.getEnv('CYPRESS_INSTALL_BINARY', trimAndRemoveDoubleQuotes)
|
||||
|
||||
debug('using environment variable CYPRESS_INSTALL_BINARY "%s"', envVarVersion)
|
||||
|
||||
return envVarVersion
|
||||
}
|
||||
|
||||
const start = async (options = {}) => {
|
||||
debug('installing with options %j', options)
|
||||
|
||||
const envVarVersion = getEnvVarVersion()
|
||||
|
||||
if (envVarVersion === '0') {
|
||||
debug('environment variable CYPRESS_INSTALL_BINARY = 0, skipping install')
|
||||
logger.log(
|
||||
stripIndent`
|
||||
${chalk.yellow('Note:')} Skipping binary installation: Environment variable CYPRESS_INSTALL_BINARY = 0.`,
|
||||
)
|
||||
|
||||
logger.log()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
_.defaults(options, {
|
||||
force: false,
|
||||
buildInfo,
|
||||
})
|
||||
|
||||
const pkgVersion = util.pkgVersion()
|
||||
let needVersion = pkgVersion
|
||||
let binaryUrlOverride
|
||||
|
||||
debug('version in package.json is', needVersion)
|
||||
|
||||
// let this environment variable reset the binary version we need
|
||||
if (util.getEnv('CYPRESS_INSTALL_BINARY')) {
|
||||
// because passed file paths are often double quoted
|
||||
// and might have extra whitespace around, be robust and trim the string
|
||||
const trimAndRemoveDoubleQuotes = true
|
||||
const envVarVersion = util.getEnv('CYPRESS_INSTALL_BINARY', trimAndRemoveDoubleQuotes)
|
||||
|
||||
debug('using environment variable CYPRESS_INSTALL_BINARY "%s"', envVarVersion)
|
||||
|
||||
if (envVarVersion === '0') {
|
||||
debug('environment variable CYPRESS_INSTALL_BINARY = 0, skipping install')
|
||||
logger.log(
|
||||
stripIndent`
|
||||
${chalk.yellow('Note:')} Skipping binary installation: Environment variable CYPRESS_INSTALL_BINARY = 0.`,
|
||||
)
|
||||
|
||||
logger.log()
|
||||
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
binaryUrlOverride = envVarVersion
|
||||
}
|
||||
|
||||
if (util.getEnv('CYPRESS_CACHE_FOLDER')) {
|
||||
const envCache = util.getEnv('CYPRESS_CACHE_FOLDER')
|
||||
|
||||
@@ -278,18 +218,21 @@ const start = (options = {}) => {
|
||||
logger.log()
|
||||
}
|
||||
|
||||
const installDir = state.getVersionDir(pkgVersion)
|
||||
const pkgVersion = util.pkgVersion()
|
||||
const versionOverride = getVersionOverride({ envVarVersion, buildInfo: options.buildInfo })
|
||||
const versionToInstall = versionOverride || pkgVersion
|
||||
|
||||
debug('version in package.json is %s, version to install is %s', pkgVersion, versionToInstall)
|
||||
|
||||
const installDir = state.getVersionDir(pkgVersion, options.buildInfo)
|
||||
const cacheDir = state.getCacheDir()
|
||||
const binaryDir = state.getBinaryDir(pkgVersion)
|
||||
|
||||
return validateOS().then((isValid) => {
|
||||
if (!isValid) {
|
||||
return throwFormErrorText(errors.invalidOS)()
|
||||
}
|
||||
})
|
||||
.then(() => {
|
||||
return fs.ensureDirAsync(cacheDir)
|
||||
})
|
||||
if (!(await validateOS())) {
|
||||
return throwFormErrorText(errors.invalidOS)()
|
||||
}
|
||||
|
||||
await fs.ensureDirAsync(cacheDir)
|
||||
.catch({ code: 'EACCES' }, (err) => {
|
||||
return throwFormErrorText(errors.invalidCacheDirectory)(stripIndent`
|
||||
Failed to access ${chalk.cyan(cacheDir)}:
|
||||
@@ -297,26 +240,11 @@ const start = (options = {}) => {
|
||||
${err.message}
|
||||
`)
|
||||
})
|
||||
.then(() => {
|
||||
return Promise.all([
|
||||
state.getBinaryPkgAsync(binaryDir).then(state.getBinaryPkgVersion),
|
||||
getVersionSpecifier(),
|
||||
])
|
||||
})
|
||||
.then(([binaryVersion, versionSpecifier]) => {
|
||||
if (!binaryUrlOverride && versionSpecifier) {
|
||||
const computedBinaryUrl = getBinaryUrlFromPrereleaseNpmUrl(versionSpecifier)
|
||||
|
||||
if (computedBinaryUrl) {
|
||||
debug('computed binary url from version specifier %o', { computedBinaryUrl, needVersion })
|
||||
binaryUrlOverride = computedBinaryUrl
|
||||
}
|
||||
}
|
||||
|
||||
needVersion = binaryUrlOverride || needVersion
|
||||
|
||||
debug('installed version is', binaryVersion, 'version needed is', needVersion)
|
||||
const binaryPkg = await state.getBinaryPkgAsync(binaryDir)
|
||||
const binaryVersion = await state.getBinaryPkgVersion(binaryPkg)
|
||||
|
||||
const shouldInstall = () => {
|
||||
if (!binaryVersion) {
|
||||
debug('no binary installed under cli version')
|
||||
|
||||
@@ -336,7 +264,7 @@ const start = (options = {}) => {
|
||||
return true
|
||||
}
|
||||
|
||||
if ((binaryVersion === needVersion) || !util.isSemver(needVersion)) {
|
||||
if ((binaryVersion === versionToInstall) || !util.isSemver(versionToInstall)) {
|
||||
// our version matches, tell the user this is a noop
|
||||
alreadyInstalledMsg()
|
||||
|
||||
@@ -344,96 +272,89 @@ const start = (options = {}) => {
|
||||
}
|
||||
|
||||
return true
|
||||
})
|
||||
.then((shouldInstall) => {
|
||||
// noop if we've been told not to download
|
||||
if (!shouldInstall) {
|
||||
debug('Not downloading or installing binary')
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
// noop if we've been told not to download
|
||||
if (!shouldInstall()) {
|
||||
return debug('Not downloading or installing binary')
|
||||
}
|
||||
|
||||
if (needVersion !== pkgVersion) {
|
||||
logger.log(
|
||||
chalk.yellow(stripIndent`
|
||||
${logSymbols.warning} Warning: Forcing a binary version different than the default.
|
||||
if (envVarVersion) {
|
||||
logger.log(
|
||||
chalk.yellow(stripIndent`
|
||||
${logSymbols.warning} Warning: Forcing a binary version different than the default.
|
||||
|
||||
The CLI expected to install version: ${chalk.green(pkgVersion)}
|
||||
The CLI expected to install version: ${chalk.green(pkgVersion)}
|
||||
|
||||
Instead we will install version: ${chalk.green(needVersion)}
|
||||
Instead we will install version: ${chalk.green(versionToInstall)}
|
||||
|
||||
These versions may not work properly together.
|
||||
`),
|
||||
)
|
||||
These versions may not work properly together.
|
||||
`),
|
||||
)
|
||||
|
||||
logger.log()
|
||||
}
|
||||
logger.log()
|
||||
}
|
||||
|
||||
const getLocalFilePath = async () => {
|
||||
// see if version supplied is a path to a binary
|
||||
return fs.pathExistsAsync(needVersion)
|
||||
.then((exists) => {
|
||||
if (exists) {
|
||||
return path.extname(needVersion) === '.zip' ? needVersion : false
|
||||
}
|
||||
if (await fs.pathExistsAsync(versionToInstall)) {
|
||||
return path.extname(versionToInstall) === '.zip' ? versionToInstall : false
|
||||
}
|
||||
|
||||
const possibleFile = util.formAbsolutePath(needVersion)
|
||||
const possibleFile = util.formAbsolutePath(versionToInstall)
|
||||
|
||||
debug('checking local file', possibleFile, 'cwd', process.cwd())
|
||||
debug('checking local file', possibleFile, 'cwd', process.cwd())
|
||||
|
||||
return fs.pathExistsAsync(possibleFile)
|
||||
.then((exists) => {
|
||||
// if this exists return the path to it
|
||||
// else false
|
||||
if (exists && path.extname(possibleFile) === '.zip') {
|
||||
return possibleFile
|
||||
}
|
||||
// if this exists return the path to it
|
||||
// else false
|
||||
if ((await fs.pathExistsAsync(possibleFile)) && path.extname(possibleFile) === '.zip') {
|
||||
return possibleFile
|
||||
}
|
||||
|
||||
return false
|
||||
})
|
||||
})
|
||||
.then((pathToLocalFile) => {
|
||||
if (pathToLocalFile) {
|
||||
const absolutePath = path.resolve(needVersion)
|
||||
return false
|
||||
}
|
||||
|
||||
debug('found local file at', absolutePath)
|
||||
debug('skipping download')
|
||||
const pathToLocalFile = await getLocalFilePath()
|
||||
|
||||
const rendererOptions = getRendererOptions()
|
||||
if (pathToLocalFile) {
|
||||
const absolutePath = path.resolve(versionToInstall)
|
||||
|
||||
return new Listr([unzipTask({
|
||||
progress: {
|
||||
throttle: 100,
|
||||
onProgress: null,
|
||||
},
|
||||
zipFilePath: absolutePath,
|
||||
installDir,
|
||||
rendererOptions,
|
||||
})], { rendererOptions }).run()
|
||||
}
|
||||
debug('found local file at', absolutePath)
|
||||
debug('skipping download')
|
||||
|
||||
if (options.force) {
|
||||
debug('Cypress already installed at', installDir)
|
||||
debug('but the installation was forced')
|
||||
}
|
||||
const rendererOptions = getRendererOptions()
|
||||
|
||||
debug('preparing to download and unzip version ', needVersion, 'to path', installDir)
|
||||
return new Listr([unzipTask({
|
||||
progress: {
|
||||
throttle: 100,
|
||||
onProgress: null,
|
||||
},
|
||||
zipFilePath: absolutePath,
|
||||
installDir,
|
||||
rendererOptions,
|
||||
})], { rendererOptions }).run()
|
||||
}
|
||||
|
||||
const downloadDir = os.tmpdir()
|
||||
if (options.force) {
|
||||
debug('Cypress already installed at', installDir)
|
||||
debug('but the installation was forced')
|
||||
}
|
||||
|
||||
return downloadAndUnzip({ version: needVersion, installDir, downloadDir })
|
||||
})
|
||||
// delay 1 sec for UX, unless we are testing
|
||||
.then(() => {
|
||||
return Promise.delay(1000)
|
||||
})
|
||||
.then(displayCompletionMsg)
|
||||
})
|
||||
debug('preparing to download and unzip version ', versionToInstall, 'to path', installDir)
|
||||
|
||||
const downloadDir = os.tmpdir()
|
||||
|
||||
await downloadAndUnzip({ version: versionToInstall, installDir, downloadDir })
|
||||
|
||||
// delay 1 sec for UX, unless we are testing
|
||||
await Promise.delay(1000)
|
||||
|
||||
displayCompletionMsg()
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
start,
|
||||
_getVersionSpecifier: getVersionSpecifier,
|
||||
_getBinaryUrlFromPrereleaseNpmUrl: getBinaryUrlFromPrereleaseNpmUrl,
|
||||
_getBinaryUrlFromBuildInfo,
|
||||
}
|
||||
|
||||
const unzipTask = ({ zipFilePath, installDir, progress, rendererOptions }) => {
|
||||
|
||||
@@ -50,7 +50,11 @@ const getBinaryDir = (version = util.pkgVersion()) => {
|
||||
return path.join(getVersionDir(version), getPlatFormBinaryFolder())
|
||||
}
|
||||
|
||||
const getVersionDir = (version = util.pkgVersion()) => {
|
||||
const getVersionDir = (version = util.pkgVersion(), buildInfo = util.pkgBuildInfo()) => {
|
||||
if (buildInfo && !buildInfo.stable) {
|
||||
version = ['beta', version, buildInfo.commitBranch, buildInfo.commitSha].join('-')
|
||||
}
|
||||
|
||||
return path.join(getCacheDir(), version)
|
||||
}
|
||||
|
||||
|
||||
@@ -365,6 +365,10 @@ const util = {
|
||||
return process.cwd()
|
||||
},
|
||||
|
||||
pkgBuildInfo () {
|
||||
return pkg.buildInfo
|
||||
},
|
||||
|
||||
pkgVersion () {
|
||||
return pkg.version
|
||||
},
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
const _ = require('lodash')
|
||||
const path = require('path')
|
||||
const shell = require('shelljs')
|
||||
|
||||
const fs = require('../lib/fs')
|
||||
|
||||
@@ -19,6 +20,10 @@ const {
|
||||
const packageJsonSrc = path.join('package.json')
|
||||
const packageJsonDest = path.join('build', 'package.json')
|
||||
|
||||
function getStdout (cmd) {
|
||||
return shell.exec(cmd).trim()
|
||||
}
|
||||
|
||||
function preparePackageForNpmRelease (json) {
|
||||
// modify the existing package.json
|
||||
// to prepare it for releasing to npm
|
||||
@@ -29,6 +34,12 @@ function preparePackageForNpmRelease (json) {
|
||||
|
||||
_.extend(json, {
|
||||
version,
|
||||
buildInfo: {
|
||||
commitBranch: process.env.CIRCLE_BRANCH || getStdout('git branch --show-current'),
|
||||
commitSha: getStdout('git rev-parse HEAD'),
|
||||
commitDate: new Date(getStdout('git show -s --format=%ci')).toISOString(),
|
||||
stable: false,
|
||||
},
|
||||
description,
|
||||
homepage,
|
||||
license,
|
||||
|
||||
@@ -10,7 +10,17 @@ const hasVersion = (json) => {
|
||||
return la(is.semver(json.version), 'cannot find version', json)
|
||||
}
|
||||
|
||||
const changeVersion = (o) => ({ ...o, version: 'x.y.z' })
|
||||
const normalizePackageJson = (o) => {
|
||||
expect(o.buildInfo).to.include({ stable: false })
|
||||
expect(o.buildInfo.commitBranch).to.match(/.+/)
|
||||
expect(o.buildInfo.commitSha).to.match(/[a-f0-9]+/)
|
||||
|
||||
return {
|
||||
...o,
|
||||
version: 'x.y.z',
|
||||
buildInfo: 'replaced by normalizePackageJson',
|
||||
}
|
||||
}
|
||||
|
||||
describe('package.json build', () => {
|
||||
beforeEach(function () {
|
||||
@@ -32,7 +42,7 @@ describe('package.json build', () => {
|
||||
|
||||
it('outputs expected properties', () => {
|
||||
return makeUserPackageFile()
|
||||
.then(changeVersion)
|
||||
.then(normalizePackageJson)
|
||||
.then(snapshot)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -28,6 +28,7 @@ describe('cli', () => {
|
||||
os.platform.returns('darwin')
|
||||
// sinon.stub(util, 'exit')
|
||||
sinon.stub(util, 'logErrorExit1')
|
||||
sinon.stub(util, 'pkgBuildInfo').returns({ stable: true })
|
||||
this.exec = (args) => {
|
||||
const cliArgs = `node test ${args}`.split(' ')
|
||||
|
||||
|
||||
@@ -25,6 +25,10 @@ describe('exec info', function () {
|
||||
.withArgs('browsers').returns('/user/app/data/path/to/browsers')
|
||||
.withArgs().returns('/user/app/data/path')
|
||||
|
||||
sinon.stub(util, 'pkgBuildInfo').returns({
|
||||
stable: true,
|
||||
})
|
||||
|
||||
sinon.stub(state, 'getCacheDir').returns('/user/path/to/binary/cache')
|
||||
})
|
||||
|
||||
@@ -68,4 +72,21 @@ describe('exec info', function () {
|
||||
|
||||
await startInfoAndSnapshot('cypress redacts sensitive vars')
|
||||
})
|
||||
|
||||
it('logs additional info about pre-releases', async () => {
|
||||
util.pkgBuildInfo.returns({
|
||||
stable: false,
|
||||
commitSha: 'abc123',
|
||||
commitBranch: 'someBranchName',
|
||||
commitDate: new Date('02-02-2022').toISOString(),
|
||||
})
|
||||
|
||||
await startInfoAndSnapshot('logs additional info about pre-releases')
|
||||
})
|
||||
|
||||
it('logs if unbuilt development', async () => {
|
||||
util.pkgBuildInfo.returns(undefined)
|
||||
|
||||
await startInfoAndSnapshot('logs additional info about development')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -18,6 +18,7 @@ describe('lib/exec/versions', function () {
|
||||
})
|
||||
|
||||
sinon.stub(util, 'pkgVersion').returns('4.5.6')
|
||||
sinon.stub(util, 'pkgBuildInfo').returns({ stable: true })
|
||||
})
|
||||
|
||||
describe('.getVersions', function () {
|
||||
@@ -50,6 +51,22 @@ describe('lib/exec/versions', function () {
|
||||
})
|
||||
})
|
||||
|
||||
it('appends pre-release if not stable', async function () {
|
||||
util.pkgBuildInfo.returns({ stable: false })
|
||||
|
||||
const v = await versions.getVersions()
|
||||
|
||||
expect(v.package).to.eql('4.5.6 (pre-release)')
|
||||
})
|
||||
|
||||
it('appends development if missing buildInfo', async function () {
|
||||
util.pkgBuildInfo.returns(undefined)
|
||||
|
||||
const v = await versions.getVersions()
|
||||
|
||||
expect(v.package).to.eql('4.5.6 (development)')
|
||||
})
|
||||
|
||||
it('reports default versions if not found', function () {
|
||||
// imagine package.json only has version there
|
||||
state.getBinaryPkgAsync.withArgs(binaryDir).resolves({
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
require('../../spec_helper')
|
||||
const _ = require('lodash')
|
||||
const os = require('os')
|
||||
const path = require('path')
|
||||
const chalk = require('chalk')
|
||||
const Promise = require('bluebird')
|
||||
const mockfs = require('mock-fs')
|
||||
const mockedEnv = require('mocked-env')
|
||||
const snapshot = require('../../support/snapshot')
|
||||
|
||||
const stdout = require('../../support/stdout')
|
||||
@@ -75,6 +73,32 @@ describe('/lib/tasks/install', function () {
|
||||
})
|
||||
})
|
||||
|
||||
describe('non-stable builds', () => {
|
||||
function runInstall () {
|
||||
return install.start({
|
||||
buildInfo: {
|
||||
stable: false,
|
||||
commitSha: 'abc123',
|
||||
commitBranch: 'aBranchName',
|
||||
commitDate: new Date('11-27-1996').toISOString(),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
it('install from a constructed CDN URL', async function () {
|
||||
await runInstall()
|
||||
|
||||
expect(download.start).to.be.calledWithMatch({
|
||||
version: 'https://cdn.cypress.io/beta/binary/0.0.0-development/darwin-x64/aBranchName-abc123/cypress.zip',
|
||||
})
|
||||
})
|
||||
|
||||
it('logs a warning about installing a pre-release', async function () {
|
||||
await runInstall()
|
||||
snapshot(normalize(this.stdout.toString()))
|
||||
})
|
||||
})
|
||||
|
||||
describe('override version', function () {
|
||||
it('warns when specifying cypress version in env', function () {
|
||||
const version = '0.12.1'
|
||||
@@ -460,145 +484,18 @@ describe('/lib/tasks/install', function () {
|
||||
})
|
||||
})
|
||||
|
||||
context('._getBinaryUrlFromPrereleaseNpmUrl', function () {
|
||||
beforeEach(() => {
|
||||
context('._getBinaryUrlFromBuildInfo', function () {
|
||||
const buildInfo = {
|
||||
commitSha: 'abc123',
|
||||
commitBranch: 'aBranchName',
|
||||
}
|
||||
|
||||
it('generates the expected URL', () => {
|
||||
os.platform.returns('linux')
|
||||
sinon.stub(os, 'arch').returns('x64')
|
||||
})
|
||||
|
||||
it('returns binary url for prerelease npm url', function () {
|
||||
expect(install._getBinaryUrlFromPrereleaseNpmUrl('https://cdn.cypress.io/beta/npm/5.1.1/linux-x64/ciprovider-branchname-sha/cypress.tgz'))
|
||||
.to.eq('https://cdn.cypress.io/beta/binary/5.1.1/linux-x64/ciprovider-branchname-sha/cypress.zip')
|
||||
|
||||
expect(install._getBinaryUrlFromPrereleaseNpmUrl('https://cdn.cypress.io/beta/npm/5.1.1/inux-x64/circle-develop-3fdfc3b453eb38ad3c0b079531e4dde6668e3dd0-436710/cypress.tgz'))
|
||||
.to.eq('https://cdn.cypress.io/beta/binary/5.1.1/linux-x64/circle-develop-3fdfc3b453eb38ad3c0b079531e4dde6668e3dd0-436710/cypress.zip')
|
||||
|
||||
expect(install._getBinaryUrlFromPrereleaseNpmUrl('https://cdn.cypress.io/beta/npm/5.1.1/inux-x64/circle-develop/some/branch-3fdfc3b453eb38ad3c0b079531e4dde6668e3dd0-436710/cypress.tgz'))
|
||||
.to.eq('https://cdn.cypress.io/beta/binary/5.1.1/linux-x64/circle-develop/some/branch-3fdfc3b453eb38ad3c0b079531e4dde6668e3dd0-436710/cypress.zip')
|
||||
})
|
||||
|
||||
it('returns nothing for an invalid url', function () {
|
||||
expect(install._getBinaryUrlFromPrereleaseNpmUrl('1.2.3')).to.be.undefined
|
||||
expect(install._getBinaryUrlFromPrereleaseNpmUrl(null)).to.be.undefined
|
||||
})
|
||||
})
|
||||
|
||||
context('._getVersionSpecifier', function () {
|
||||
let restoreEnv
|
||||
|
||||
beforeEach(function () {
|
||||
sinon.stub(fs, 'readJSON').rejects()
|
||||
restoreEnv && restoreEnv()
|
||||
})
|
||||
|
||||
it('resolves undefined if no versionSpecifier found', async function () {
|
||||
expect(await install._getVersionSpecifier('/foo/bar/baz')).to.be.undefined
|
||||
})
|
||||
|
||||
it('resolves with cypress.tgz URL if specified in npm argv', async function () {
|
||||
restoreEnv = mockedEnv({
|
||||
npm_config_argv: JSON.stringify({
|
||||
original: ['npm', 'i', 'https://foo.com/cypress.tgz'],
|
||||
}),
|
||||
})
|
||||
|
||||
expect(await install._getVersionSpecifier('/foo/bar/baz')).to.eq('https://foo.com/cypress.tgz')
|
||||
})
|
||||
|
||||
it('resolves with cypress.tgz URL if specified in npm env npm_package_resolved', async function () {
|
||||
restoreEnv = mockedEnv({
|
||||
npm_package_resolved: 'https://foo.com/cypress.tgz',
|
||||
})
|
||||
|
||||
expect(await install._getVersionSpecifier('/foo/bar/baz')).to.eq('https://foo.com/cypress.tgz')
|
||||
})
|
||||
|
||||
it('resolves with versionSpecifier from parent pkg.json', async function () {
|
||||
fs.readJSON.withArgs('/foo/bar/baz/package.json').resolves({
|
||||
dependencies: {
|
||||
'cypress': '1.2.3',
|
||||
},
|
||||
})
|
||||
|
||||
fs.readJSON.withArgs('/foo/bar/package.json').resolves({
|
||||
dependencies: {
|
||||
'cypress': 'wrong',
|
||||
},
|
||||
})
|
||||
|
||||
expect(await install._getVersionSpecifier('/foo/bar/baz')).to.eq('1.2.3')
|
||||
})
|
||||
|
||||
it('resolves with devDependencies too', async function () {
|
||||
fs.readJSON.withArgs('/foo/bar/baz/package.json').resolves({
|
||||
devDependencies: {
|
||||
'cypress': '4.5.6',
|
||||
},
|
||||
})
|
||||
|
||||
expect(await install._getVersionSpecifier('/foo/bar/baz')).to.eq('4.5.6')
|
||||
})
|
||||
|
||||
it('resolves with optionalDependencies too', async function () {
|
||||
fs.readJSON.withArgs('/foo/bar/baz/package.json').resolves({
|
||||
optionalDependencies: {
|
||||
'cypress': '6.7.8',
|
||||
},
|
||||
})
|
||||
|
||||
expect(await install._getVersionSpecifier('/foo/bar/baz')).to.eq('6.7.8')
|
||||
})
|
||||
|
||||
context('with win32 path functions and paths', async function () {
|
||||
const oldPath = _.clone(path)
|
||||
|
||||
beforeEach(() => {
|
||||
_.assign(path, path.win32)
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
_.assign(path, oldPath)
|
||||
})
|
||||
|
||||
it('resolves undefined if no versionSpecifier found', async function () {
|
||||
expect(await install._getVersionSpecifier('C:\\foo\\bar\\baz')).to.be.undefined
|
||||
})
|
||||
|
||||
it('resolves with versionSpecifier from parent pkg.json', async function () {
|
||||
fs.readJSON.withArgs('C:\\foo\\bar\\baz\\package.json').resolves({
|
||||
dependencies: {
|
||||
'cypress': '1.2.3',
|
||||
},
|
||||
})
|
||||
|
||||
fs.readJSON.withArgs('C:\\foo\\bar\\package.json').resolves({
|
||||
dependencies: {
|
||||
'cypress': 'wrong',
|
||||
},
|
||||
})
|
||||
|
||||
expect(await install._getVersionSpecifier('C:\\foo\\bar\\baz')).to.eq('1.2.3')
|
||||
})
|
||||
|
||||
it('resolves with devDependencies too', async function () {
|
||||
fs.readJSON.withArgs('C:\\foo\\bar\\baz\\package.json').resolves({
|
||||
devDependencies: {
|
||||
'cypress': '4.5.6',
|
||||
},
|
||||
})
|
||||
|
||||
expect(await install._getVersionSpecifier('C:\\foo\\bar\\baz')).to.eq('4.5.6')
|
||||
})
|
||||
|
||||
it('resolves with optionalDependencies too', async function () {
|
||||
fs.readJSON.withArgs('C:\\foo\\bar\\baz\\package.json').resolves({
|
||||
optionalDependencies: {
|
||||
'cypress': '6.7.8',
|
||||
},
|
||||
})
|
||||
|
||||
expect(await install._getVersionSpecifier('C:\\foo\\bar\\baz')).to.eq('6.7.8')
|
||||
})
|
||||
expect(install._getBinaryUrlFromBuildInfo(buildInfo))
|
||||
.to.eq(`https://cdn.cypress.io/beta/binary/0.0.0-development/linux-x64/aBranchName-abc123/cypress.zip`)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
+58
-73
@@ -11,45 +11,30 @@ The `@cypress/`-namespaced NPM packages that live inside the [`/npm`](../npm) di
|
||||
### Prerequisites
|
||||
|
||||
- Ensure you have the following permissions set up:
|
||||
- An AWS account with permission to create AWS access keys for the Cypress CDN.
|
||||
- An AWS account with permission to access and write to the AWS S3, i.e. the Cypress CDN.
|
||||
- Permissions for your npm account to publish the `cypress` package.
|
||||
- Permissions to update releases in ZenHub.
|
||||
|
||||
- Set up the following environment variables:
|
||||
- Cypress AWS access key and secret in `aws_credentials_json`, which looks like this:
|
||||
|
||||
- For the `release-automations` steps, you will need setup the following envs:
|
||||
- GitHub token - generated yourself in github.
|
||||
- [ZenHub API token](https://app.zenhub.com/dashboard/tokens) to interact with Zenhub. Found in 1Password.
|
||||
- The `cypress-bot` GitHub app credentials. Found in 1Password.
|
||||
```text
|
||||
aws_credentials_json='{"bucket":"cdn.cypress.io","folder":"desktop","key":"...","secret":"..."}'
|
||||
GITHUB_TOKEN="..."
|
||||
ZENHUB_API_TOKEN="..."
|
||||
GITHUB_APP_CYPRESS_INSTALLATION_ID=
|
||||
GITHUB_APP_ID=
|
||||
GITHUB_PRIVATE_KEY=
|
||||
```
|
||||
|
||||
- A [GitHub token](https://github.com/settings/tokens) and a [CircleCI token](https://circleci.com/account/api) in `ci_json`:
|
||||
|
||||
```text
|
||||
ci_json='{"githubToken":"...","circleToken":"..."}'
|
||||
```
|
||||
|
||||
- You'll also need to put the GitHub token under its own variable and get a [ZenHub API token](https://app.zenhub.com/dashboard/tokens) for the `release-automations` step.
|
||||
|
||||
```text
|
||||
GITHUB_TOKEN="..."
|
||||
ZENHUB_API_TOKEN="..."
|
||||
```
|
||||
|
||||
- The `cypress-bot` GitHub app credentials are also needed. Ask another team member who has done a deploy for those.
|
||||
|
||||
```text
|
||||
GITHUB_APP_CYPRESS_INSTALLATION_ID=
|
||||
GITHUB_APP_ID=
|
||||
GITHUB_PRIVATE_KEY=
|
||||
```
|
||||
|
||||
- For purging the Cloudflare cache (part of the `move-binaries` step), you'll need `CF_ZONEID` and `CF_TOKEN` set. These can be found in 1Password. If you don't have access, ask a team member who has done a deploy.
|
||||
|
||||
- For purging the Cloudflare cache (part of the `move-binaries` step), you'll need `CF_ZONEID` and `CF_TOKEN` set. These can be found in 1Password.
|
||||
```text
|
||||
CF_ZONEID="..."
|
||||
CF_TOKEN="..."
|
||||
```
|
||||
|
||||
- If you don't have access to 1Password, ask a team member who has done a deploy.
|
||||
- Tip: Use [as-a](https://github.com/bahmutov/as-a) to manage environment variables for different situations.
|
||||
|
||||
### Before Publishing a New Version
|
||||
@@ -67,44 +52,59 @@ of Cypress. You can see the progress of the test projects by opening the status
|
||||
|
||||

|
||||
|
||||
Once the `develop` branch for all test projects are reliably passing with the new changes and the `linux-x64` binary is present at `https://cdn.cypress.io/beta/binary/X.Y.Z/linux-x64/<sha>/cypress.zip`, and the `linux-x64` cypress npm package is present at `https://cdn.cypress.io/beta/binary/X.Y.Z/linux-x64/<sha>/cypress.tgz`, publishing can proceed.
|
||||
|
||||
### Steps to Publish a New Version
|
||||
|
||||
In the following instructions, "X.Y.Z" is used to denote the [next version of Cypress being published](./next-version.md).
|
||||
|
||||
1. `develop` should contain all of the changes made in `master`. However, this occasionally may not be the case. Ensure that `master` does not have any additional commits that are not on `develop` and all auto-generated pull requests designed to merge master into develop have been successfully merged.
|
||||
1. Confirm that every issue labeled [stage: pending release](https://github.com/cypress-io/cypress/issues?q=label%3A%22stage%3A+pending+release%22+is%3Aclosed) has a ZenHub release set. **Tip:** there is a command in [`release-automations`](https://github.com/cypress-io/release-automations)'s `issues-in-release` tool to list and check such issues. Without a ZenHub release issues will not be included in the right changelog.
|
||||
|
||||
2. If there is a new [`cypress-example-kitchensink`](https://github.com/cypress-io/cypress-example-kitchensink/releases) version, update the corresponding dependency in [`packages/example`](../packages/example) to that new version.
|
||||
2. Create or review the release-specific documentation and changelog in [cypress-documentation](https://github.com/cypress-io/cypress-documentation). If there is not already a release-specific PR open, create one.
|
||||
- Use [`release-automations`](https://github.com/cypress-io/release-automations)'s `issues-in-release` tool to generate a starting point for the changelog, based off of ZenHub:
|
||||
```shell
|
||||
cd packages/issues-in-release
|
||||
yarn do:changelog --release <release label>
|
||||
```
|
||||
- Ensure the changelog is up-to-date and has the correct date.
|
||||
- Merge any release-specific documentation changes into the main release PR.
|
||||
- You can view the doc's [branch deploy preview](https://github.com/cypress-io/cypress-documentation/blob/master/CONTRIBUTING.md#pull-requests) by clicking 'Details' on the PR's `netlify-cypress-docs/deploy-preview` GitHub status check.
|
||||
|
||||
3. Use the `move-binaries` script to move the binaries for `<commit sha>` from `beta` to the `desktop` folder for `<new target version>`. This also purges the cloudflare cache for this version.
|
||||
3. `develop` should contain all of the changes made in `master`. However, this occasionally may not be the case.
|
||||
- Ensure that `master` does not have any additional commits that are not on `develop`.
|
||||
- Ensure all auto-generated pull requests designed to merge master into develop have been successfully merged.
|
||||
|
||||
4. If there is a new [`cypress-example-kitchensink`](https://github.com/cypress-io/cypress-example-kitchensink/releases) version, update the corresponding dependency in [`packages/example`](../packages/example) to that new version.
|
||||
|
||||
5. Once the `develop` branch is passing for all test projects with the new changes and the `linux-x64` binary is present at `https://cdn.cypress.io/beta/binary/X.Y.Z/linux-x64/<sha>/cypress.zip`, and the `linux-x64` cypress npm package is present at `https://cdn.cypress.io/beta/binary/X.Y.Z/linux-x64/<sha>/cypress.tgz`, publishing can proceed.
|
||||
|
||||
6. Log into AWS SSO with `aws sso login --profile <name_of_profile>`. The release scripts assumes you are using the `production` profile. If you have setup your credentials under a different profile, be sure to set the `AWS_PROFILE` environment variable.
|
||||
|
||||
7. Use the `prepare-release-artifacts` script (Mac/Linux only) to prepare the latest commit to a stable release. When you run this script, the following happens:
|
||||
* the binaries for `<commit sha>` are moved from `beta` to the `desktop` folder for `<new target version>` in S3
|
||||
* the Cloudflare cache for this version is purged
|
||||
* the pre-prod `cypress.tgz` NPM package is converted to a stable NPM package ready for release
|
||||
|
||||
```shell
|
||||
yarn move-binaries --sha <commit sha> --version <new target version>
|
||||
yarn prepare-release-artifacts --sha <commit sha> --version <new target version>
|
||||
```
|
||||
|
||||
4. Publish the new npm package under the `dev` tag, using your personal npm account.
|
||||
- To find the link to the package file `cypress.tgz`:
|
||||
1. In GitHub, go to the latest commit (the one whose sha you used in the last step).
|
||||

|
||||
2. Scroll down past the changes to the comments. The first comment should be a `cypress-bot` comment that includes a line beginning `npm install ...`. Grab the `https://cdn.../npm/X.Y.Z/<platform>/<long sha>/cypress.tgz` link.
|
||||

|
||||
- Make sure the `linux-x64` binary and npm package are present at the commented locations. See [Before Publishing a New Version](#before-publishing-a-new-version).
|
||||
- Publish the `linux-x64` distribution to the npm registry straight from the URL:
|
||||
You can pass `--dry-run` to see the commands this would run under the hood.
|
||||
|
||||
```shell
|
||||
npm publish https://cdn.cypress.io/beta/npm/X.Y.Z/<long sha>/cypress.tgz --tag dev
|
||||
```
|
||||
:bangbang: Important :bangbang: Be sure to release the `linux-x64` distribution.
|
||||
8. Validate you are logged in to `npm` with `npm whoami`. Otherwise log in with `npm login`.
|
||||
|
||||
5. Double-check that the new version has been published under the `dev` tag using `npm info cypress` or [available-versions](https://github.com/bahmutov/available-versions). `latest` should still point to the previous version. Example output:
|
||||
9. Publish the generated npm package under the `dev` tag, using your personal npm account.
|
||||
|
||||
```shell
|
||||
npm publish /tmp/cypress-prod.tgz --tag dev
|
||||
```
|
||||
|
||||
10. Double-check that the new version has been published under the `dev` tag using `npm info cypress` or [available-versions](https://github.com/bahmutov/available-versions). `latest` should still point to the previous version. Example output:
|
||||
|
||||
```shell
|
||||
dist-tags:
|
||||
dev: 3.4.0 latest: 3.3.2
|
||||
```
|
||||
|
||||
6. Test `cypress@X.Y.Z` to make sure everything is working.
|
||||
11. Test `cypress@X.Y.Z` to make sure everything is working.
|
||||
- Install the new version: `npm install -g cypress@X.Y.Z`
|
||||
- Run a quick, manual smoke test:
|
||||
- `cypress open`
|
||||
@@ -113,43 +113,28 @@ In the following instructions, "X.Y.Z" is used to denote the [next version of Cy
|
||||
- [cypress-realworld-app](https://github.com/cypress-io/cypress-realworld-app) uses yarn and represents a typical consumer implementation.
|
||||
- Optionally, do more thorough tests, for example test the new version of Cypress against the Cypress dashboard repo.
|
||||
|
||||
7. Confirm that every issue labeled [stage: pending release](https://github.com/cypress-io/cypress/issues?q=label%3A%22stage%3A+pending+release%22+is%3Aclosed) has a ZenHub release set. **Tip:** there is a command in [`release-automations`](https://github.com/cypress-io/release-automations)'s `issues-in-release` tool to list and check such issues. Without a ZenHub release issues will not be included in the right changelog.
|
||||
|
||||
8. Deploy the release-specific documentation and changelog in [cypress-documentation](https://github.com/cypress-io/cypress-documentation).
|
||||
- If there is not already a release-specific PR open, create one. You can use [`release-automations`](https://github.com/cypress-io/release-automations)'s `issues-in-release` tool to generate a starting point for the changelog, based off of ZenHub:
|
||||
|
||||
```shell
|
||||
cd packages/issues-in-release
|
||||
yarn do:changelog --release <release label>
|
||||
```
|
||||
|
||||
- Ensure the changelog is up-to-date and has the correct date.
|
||||
- Merge any release-specific documentation changes into the main release PR.
|
||||
- You can view the doc's [branch deploy preview](https://github.com/cypress-io/cypress-documentation/blob/master/CONTRIBUTING.md#pull-requests) by clicking 'Details' on the PR's `netlify-cypress-docs/deploy-preview` GitHub status check.
|
||||
- Merge this PR into `master` to deploy it to production.
|
||||
|
||||
9. Make the new npm version the "latest" version by updating the dist-tag `latest` to point to the new version:
|
||||
12. Make the new npm version the "latest" version by updating the dist-tag `latest` to point to the new version:
|
||||
|
||||
```shell
|
||||
npm dist-tag add cypress@X.Y.Z
|
||||
```
|
||||
|
||||
10. Run `binary-release` to update the [download server's manifest](https://download.cypress.io/desktop.json). This will also ensure the binary for the version is downloadable for each system.
|
||||
13. Run `binary-release` to update the [download server's manifest](https://download.cypress.io/desktop.json). This will also ensure the binary for the version is downloadable for each system.
|
||||
|
||||
```shell
|
||||
yarn binary-release --version X.Y.Z
|
||||
```
|
||||
|
||||
11. If needed, push out any updated changes to the links manifest to [`on.cypress.io`](https://github.com/cypress-io/cypress-services/tree/develop/packages/on).
|
||||
14. If needed, push out any updated changes to the links manifest to [`on.cypress.io`](https://github.com/cypress-io/cypress-services/tree/develop/packages/on).
|
||||
|
||||
12. If needed, deploy the updated [`cypress-example-kitchensink`][cypress-example-kitchensink] to `example.cypress.io` by following [these instructions under "Deployment"](../packages/example/README.md).
|
||||
15. If needed, deploy the updated [`cypress-example-kitchensink`][cypress-example-kitchensink] to `example.cypress.io` by following [these instructions under "Deployment"](../packages/example/README.md).
|
||||
|
||||
13. Update the releases in [ZenHub](https://app.zenhub.com/workspaces/test-runner-5c3ea3baeb1e75374f7b0708/reports/release):
|
||||
16. Update the releases in [ZenHub](https://app.zenhub.com/workspaces/test-runner-5c3ea3baeb1e75374f7b0708/reports/release):
|
||||
- Close the current release in ZenHub.
|
||||
- Create a new patch release (and a new minor release, if this is a minor release) in ZenHub, and schedule them both to be completed 2 weeks from the current date.
|
||||
- Move all issues that are still open from the current release to the appropriate future release.
|
||||
|
||||
14. Bump `version` in [`package.json`](package.json), commit it to `develop`, tag it with the version, and push the tag up:
|
||||
17. Bump `version` in [`package.json`](package.json), commit it to `develop`, tag it with the version, and push the tag up:
|
||||
|
||||
```shell
|
||||
git commit -am "release X.Y.Z [skip ci]"
|
||||
@@ -159,7 +144,7 @@ In the following instructions, "X.Y.Z" is used to denote the [next version of Cy
|
||||
git push origin vX.Y.Z
|
||||
```
|
||||
|
||||
15. Merge `develop` into `master` and push both branches up. Note: pushing to `master` will automatically publish any independent npm packages that have not yet been published.
|
||||
18. Merge `develop` into `master` and push both branches up. Note: pushing to `master` will automatically publish any independent npm packages that have not yet been published.
|
||||
|
||||
```shell
|
||||
git push origin develop
|
||||
@@ -168,7 +153,7 @@ In the following instructions, "X.Y.Z" is used to denote the [next version of Cy
|
||||
git push origin master
|
||||
```
|
||||
|
||||
16. Inside of [cypress-io/release-automations][release-automations]:
|
||||
19. Inside of [cypress-io/release-automations][release-automations]:
|
||||
- Publish GitHub release to [cypress-io/cypress/releases](https://github.com/cypress-io/cypress/releases) using package `set-releases`:
|
||||
|
||||
```shell
|
||||
@@ -183,9 +168,9 @@ In the following instructions, "X.Y.Z" is used to denote the [next version of Cy
|
||||
|
||||
- Confirm there are no issues with the label [stage: pending release](https://github.com/cypress-io/cypress/issues?q=label%3A%22stage%3A+pending+release%22+is%3Aclosed) left
|
||||
|
||||
17. Publish a new docker image in [`cypress-docker-images`](https://github.com/cypress-io/cypress-docker-images) under `included` for the new cypress version. Note: we use the base image with the Node version matching the bundled Node version. Instructions for updating `cypress-docker-images` can be found [here](https://github.com/cypress-io/cypress-docker-images/blob/master/CONTRIBUTING.md#add-new-included-image).
|
||||
20. Publish a new docker image in [`cypress-docker-images`](https://github.com/cypress-io/cypress-docker-images) under `included` for the new cypress version. Note: we use the base image with the Node version matching the bundled Node version. Instructions for updating `cypress-docker-images` can be found [here](https://github.com/cypress-io/cypress-docker-images/blob/master/CONTRIBUTING.md#add-new-included-image).
|
||||
|
||||
18. Update example projects to the new version. For most projects, you can go to the Renovate dependency issue and check the box next to `Update dependency cypress to X.Y.Z`. It will automatically create a PR. Once it passes, you can merge it. Try updating at least the following projects:
|
||||
21. Update example projects to the new version. For most projects, you can go to the Renovate dependency issue and check the box next to `Update dependency cypress to X.Y.Z`. It will automatically create a PR. Once it passes, you can merge it. Try updating at least the following projects:
|
||||
- [cypress-example-todomvc](https://github.com/cypress-io/cypress-example-todomvc/issues/99)
|
||||
- [cypress-example-todomvc-redux](https://github.com/cypress-io/cypress-example-todomvc-redux/issues/1)
|
||||
- [cypress-example-realworld](https://github.com/cypress-io/cypress-example-realworld/issues/2)
|
||||
@@ -195,7 +180,7 @@ In the following instructions, "X.Y.Z" is used to denote the [next version of Cy
|
||||
- [cypress-documentation](https://github.com/cypress-io/cypress-documentation/issues/1313)
|
||||
- [cypress-example-docker-compose](https://github.com/cypress-io/cypress-example-docker-compose) - Doesn't have a Renovate issue, but will auto-create and auto-merge non-major Cypress updates as long as the tests pass.
|
||||
|
||||
19. Check if any test or example repositories have a branch for testing the features or fixes from the newly published version `x.y.z`. The branch should also be named `x.y.z`. Check all `cypress-test-*` and `cypress-example-*` repositories, and if there is a branch named `x.y.z`, merge it into `master`.
|
||||
22. Check if any test or example repositories have a branch for testing the features or fixes from the newly published version `x.y.z`. The branch should also be named `x.y.z`. Check all `cypress-test-*` and `cypress-example-*` repositories, and if there is a branch named `x.y.z`, merge it into `master`.
|
||||
|
||||
**Test Repos**
|
||||
|
||||
|
||||
@@ -187,3 +187,4 @@ describe('#startDevServer', () => {
|
||||
})
|
||||
})
|
||||
})
|
||||
.timeout(5000)
|
||||
|
||||
+4
-3
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cypress",
|
||||
"version": "9.5.0",
|
||||
"version": "9.5.1",
|
||||
"description": "Cypress.io end to end testing tool",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
@@ -44,7 +44,7 @@
|
||||
"jscodeshift": "jscodeshift -t ./node_modules/js-codemod/transforms/arrow-function-arguments.js",
|
||||
"lint": "eslint --ext .js,.jsx,.ts,.tsx,.json,.vue .",
|
||||
"lint-changed": "lint-changed",
|
||||
"move-binaries": "node ./scripts/binary.js move-binaries",
|
||||
"prepare-release-artifacts": "node ./scripts/prepare-release-artifacts.js",
|
||||
"npm-release": "node scripts/npm-release.js",
|
||||
"prestart": "yarn ensure-deps",
|
||||
"start": "cypress open --dev --global",
|
||||
@@ -66,7 +66,7 @@
|
||||
"test-unit": "lerna exec yarn test-unit --ignore \"'{@packages/{driver,root,static,web-config,net-stubbing,rewriter,ui-components},@cypress/{webpack-dev-server,eslint-plugin-dev}}'\"",
|
||||
"pretest-watch": "yarn ensure-deps",
|
||||
"test-watch": "lerna exec yarn test-watch --ignore \"'@packages/{driver,root,static,web-config}'\"",
|
||||
"type-check": "node scripts/type_check",
|
||||
"type-check": "yarn lerna exec yarn type-check --scope @tooling/system-tests && node scripts/type_check",
|
||||
"verify:mocha:results": "node ./scripts/verify_mocha_results",
|
||||
"watch": "yarn gulp dev:watch",
|
||||
"prepare": "husky install"
|
||||
@@ -75,6 +75,7 @@
|
||||
"nvm": "0.0.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@aws-sdk/credential-providers": "3.53.0",
|
||||
"@cypress/commit-message-install": "3.1.3",
|
||||
"@cypress/env-or-json-file": "2.0.0",
|
||||
"@cypress/github-commit-status-check": "1.5.0",
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
const stripAnsi = require('strip-ansi')
|
||||
|
||||
const { assertLogLength } = require('../../support/utils')
|
||||
const { Promise } = Cypress
|
||||
|
||||
@@ -130,6 +132,10 @@ describe('src/cy/commands/fixtures', () => {
|
||||
expect(err.message).to.include('A fixture file could not be found')
|
||||
expect(err.message).to.include('cypress/fixtures/err')
|
||||
|
||||
// ensure ansi color codes are not embedded in the error msg
|
||||
// https://github.com/cypress-io/cypress/issues/20208
|
||||
expect(err.message).to.eq(stripAnsi(err.message))
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -243,7 +243,7 @@ describe('per-test config', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('in mulitple nested suites', {
|
||||
describe('in multiple nested suites', {
|
||||
foo: false,
|
||||
}, () => {
|
||||
describe('config in suite', {
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
"text-mask-addons": "3.8.0",
|
||||
"underscore.string": "3.3.5",
|
||||
"unfetch": "4.1.0",
|
||||
"url-parse": "1.5.6",
|
||||
"url-parse": "1.5.8",
|
||||
"vanilla-text-mask": "5.1.1",
|
||||
"vite": "2.5.0",
|
||||
"webpack": "^4.44.2",
|
||||
|
||||
@@ -251,7 +251,7 @@ class $Cypress {
|
||||
// and those leak out into the stdout formatting.
|
||||
const errMsg = _.isString(errResult)
|
||||
? errResult
|
||||
: `Expected ${format(errResult.key)} to be ${errResult.type}.\n\nInstead the value was: ${stringify(errResult.value)}\``
|
||||
: `Expected ${format(errResult.key)} to be ${errResult.type}.\n\nInstead the value was: ${stringify(errResult.value)}`
|
||||
|
||||
throw new this.state('specWindow').Error(errMsg)
|
||||
})
|
||||
|
||||
@@ -262,6 +262,17 @@ const SetInjectionLevel: ResponseMiddleware = function () {
|
||||
this.res.wantsInjection = getInjectionLevel()
|
||||
}
|
||||
|
||||
if (this.res.wantsInjection) {
|
||||
// Chrome plans to make document.domain immutable in Chrome 106, with the default value
|
||||
// of the Origin-Agent-Cluster header becoming 'true'. We explicitly disable this header
|
||||
// so that we can continue to support tests that visit multiple subdomains in a single spec.
|
||||
// https://github.com/cypress-io/cypress/issues/20147
|
||||
//
|
||||
// We set the header here only for proxied requests that have scripts injected that set the domain.
|
||||
// Other proxied requests are ignored.
|
||||
this.res.setHeader('Origin-Agent-Cluster', '?0')
|
||||
}
|
||||
|
||||
this.res.wantsSecurityRemoved = this.config.modifyObstructiveCode && isReqMatchOriginPolicy && (
|
||||
(this.res.wantsInjection === 'full')
|
||||
|| resContentTypeIsJavaScript(this.incomingRes)
|
||||
|
||||
@@ -127,4 +127,66 @@ describe('http/response-middleware', function () {
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
describe('SetInjectionLevel', function () {
|
||||
const { SetInjectionLevel } = ResponseMiddleware
|
||||
|
||||
let ctx
|
||||
|
||||
beforeEach(function () {
|
||||
ctx = {
|
||||
req: {
|
||||
proxiedUrl: 'http://proxy.com',
|
||||
cookies: {
|
||||
'__cypress.initial': true,
|
||||
},
|
||||
headers: {
|
||||
accept: ['text/html', 'application/xhtml+xml'],
|
||||
},
|
||||
},
|
||||
res: {
|
||||
setHeader: sinon.stub(),
|
||||
},
|
||||
getRemoteState: () => {
|
||||
return {
|
||||
strategy: 'http',
|
||||
props: {
|
||||
domain: 'proxy',
|
||||
port: '80',
|
||||
tld: 'com',
|
||||
},
|
||||
}
|
||||
},
|
||||
getRenderedHTMLOrigins: () => {
|
||||
return {}
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
it('does not set Origin-Agent-Cluster header to false when injection is not expected', function () {
|
||||
ctx.incomingRes = {
|
||||
headers: {
|
||||
'content-type': 'foo/bar',
|
||||
},
|
||||
}
|
||||
|
||||
return testMiddleware([SetInjectionLevel], ctx)
|
||||
.then(() => {
|
||||
expect(ctx.res.setHeader).not.to.be.calledWith('Origin-Agent-Cluster', '?0')
|
||||
})
|
||||
})
|
||||
|
||||
it('sets Origin-Agent-Cluster header to false when injection is expected', function () {
|
||||
ctx.incomingRes = {
|
||||
headers: {
|
||||
'content-type': 'text/html',
|
||||
},
|
||||
}
|
||||
|
||||
return testMiddleware([SetInjectionLevel], ctx)
|
||||
.then(() => {
|
||||
expect(ctx.res.setHeader).to.be.calledWith('Origin-Agent-Cluster', '?0')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -31,6 +31,12 @@ export const iframesController = {
|
||||
extraOptions,
|
||||
})
|
||||
|
||||
// Chrome plans to make document.domain immutable in Chrome 106, with the default value
|
||||
// of the Origin-Agent-Cluster header becoming 'true'. We explicitly disable this header
|
||||
// so that we can continue to support tests that visit multiple subdomains in a single spec.
|
||||
// https://github.com/cypress-io/cypress/issues/20147
|
||||
res.setHeader('Origin-Agent-Cluster', '?0')
|
||||
|
||||
files.handleIframe(req, res, config, getRemoteState, extraOptions)
|
||||
},
|
||||
|
||||
|
||||
@@ -33,6 +33,12 @@ export const serveRunner = (runnerPkg: RunnerPkg, config: Cfg, res: Response) =>
|
||||
|
||||
const runnerPath = process.env.CYPRESS_INTERNAL_RUNNER_PATH || getPathToIndex(runnerPkg)
|
||||
|
||||
// Chrome plans to make document.domain immutable in Chrome 106, with the default value
|
||||
// of the Origin-Agent-Cluster header becoming 'true'. We explicitly disable this header
|
||||
// so that we can continue to support tests that visit multiple subdomains in a single spec.
|
||||
// https://github.com/cypress-io/cypress/issues/20147
|
||||
res.setHeader('Origin-Agent-Cluster', '?0')
|
||||
|
||||
return res.render(runnerPath, {
|
||||
base64Config,
|
||||
projectName: config.projectName,
|
||||
|
||||
@@ -4,6 +4,8 @@ const debug = require('debug')('cypress:server:fixture')
|
||||
const coffee = require('coffeescript')
|
||||
const Promise = require('bluebird')
|
||||
const jsonlint = require('jsonlint')
|
||||
const stripAnsi = require('strip-ansi')
|
||||
|
||||
const errors = require('./errors')
|
||||
const { fs } = require('./util/fs')
|
||||
const glob = require('./util/glob')
|
||||
@@ -60,7 +62,14 @@ module.exports = {
|
||||
if (matches.length === 0) {
|
||||
const relativePath = path.relative('.', p)
|
||||
|
||||
errors.throwErr('FIXTURE_NOT_FOUND', relativePath, extensions)
|
||||
// TODO: there's no reason this error should be in
|
||||
// the @packages/error list, it should be written in
|
||||
// the driver since this error can only occur within
|
||||
// driver commands and not outside of the test runner
|
||||
const err = errors.get('FIXTURE_NOT_FOUND', relativePath, extensions)
|
||||
|
||||
err.message = stripAnsi(err.message)
|
||||
throw err
|
||||
}
|
||||
|
||||
debug('fixture matches found, using the first', matches)
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
"data-uri-to-buffer": "2.0.1",
|
||||
"dayjs": "^1.9.3",
|
||||
"debug": "^4.3.2",
|
||||
"dependency-tree": "8.1.2",
|
||||
"duplexify": "4.1.1",
|
||||
"electron-context-menu": "3.1.1",
|
||||
"errorhandler": "1.5.1",
|
||||
@@ -119,7 +120,7 @@
|
||||
"ts-node": "^10.2.1",
|
||||
"tslib": "2.3.1",
|
||||
"underscore.string": "3.3.5",
|
||||
"url-parse": "1.5.6",
|
||||
"url-parse": "1.5.8",
|
||||
"uuid": "8.3.2",
|
||||
"which": "2.0.2",
|
||||
"widest-line": "3.1.0"
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
require('../spec_helper')
|
||||
|
||||
const { iframesController } = require(`${root}/lib/controllers/iframes`)
|
||||
const files = require(`${root}/lib/controllers/files`)
|
||||
|
||||
describe('controllers/iframes', () => {
|
||||
describe('e2e', () => {
|
||||
it('sets Origin-Agent-Cluster response header to false', () => {
|
||||
sinon.stub(files, 'handleIframe')
|
||||
|
||||
const mockReq = {}
|
||||
const mockRes = {
|
||||
setHeader: sinon.stub(),
|
||||
}
|
||||
|
||||
const controllerOptions = {
|
||||
getSpec: sinon.stub(),
|
||||
getRemoteState: sinon.stub(),
|
||||
config: {},
|
||||
}
|
||||
|
||||
iframesController.e2e(controllerOptions, mockReq, mockRes)
|
||||
|
||||
expect(mockRes.setHeader).to.have.been.calledWith('Origin-Agent-Cluster', '?0')
|
||||
expect(files.handleIframe).to.have.been.calledWith(
|
||||
mockReq, mockRes, controllerOptions.config, controllerOptions.getRemoteState, sinon.match({
|
||||
specFilter: undefined, specType: 'integration',
|
||||
}),
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,19 @@
|
||||
require('../spec_helper')
|
||||
|
||||
const { serveRunner } = require(`${root}/lib/controllers/runner`)
|
||||
|
||||
describe('controllers/runner', () => {
|
||||
describe('serveRunner', () => {
|
||||
it('sets Origin-Agent-Cluster response header to false', () => {
|
||||
const mockRes = {
|
||||
setHeader: sinon.stub(),
|
||||
render: sinon.stub(),
|
||||
}
|
||||
|
||||
serveRunner('runner', {}, mockRes)
|
||||
|
||||
expect(mockRes.setHeader).to.have.been.calledWith('Origin-Agent-Cluster', '?0')
|
||||
expect(mockRes.render).to.have.been.called
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -114,6 +114,7 @@ export async function buildCypressApp (options: BuildCypressAppOpts) {
|
||||
meta.distDir('**', 'esprima', 'test'),
|
||||
meta.distDir('**', 'bmp-js', 'test'),
|
||||
meta.distDir('**', 'exif-parser', 'test'),
|
||||
meta.distDir('**', 'app-module-path', 'test'),
|
||||
], { force: true })
|
||||
|
||||
console.log('Deleted excess directories')
|
||||
|
||||
@@ -113,6 +113,8 @@ export const prompts = {
|
||||
export const moveBinaries = async (args = []) => {
|
||||
debug('moveBinaries with args %o', args)
|
||||
const options = arg({
|
||||
'--s3bucket': String,
|
||||
'--s3folder': String,
|
||||
'--commit': String,
|
||||
'--version': String,
|
||||
// optional, if passed, only the binary for that platform will be moved
|
||||
@@ -136,8 +138,13 @@ export const moveBinaries = async (args = []) => {
|
||||
version: options['--version'],
|
||||
}
|
||||
|
||||
const aws = uploadUtils.getS3Credentials()
|
||||
const s3 = s3helpers.makeS3(aws)
|
||||
const credentials = await uploadUtils.getS3Credentials()
|
||||
const aws = {
|
||||
'bucket': options['--s3bucket'] || uploadUtils.S3Configuration.bucket,
|
||||
'folder': options['--s3folder'] || uploadUtils.S3Configuration.releaseFolder,
|
||||
}
|
||||
|
||||
const s3 = s3helpers.makeS3(credentials)
|
||||
|
||||
// found s3 paths with last build for same commit for all platforms
|
||||
const lastBuilds: Desktop[] = []
|
||||
@@ -164,12 +171,12 @@ export const moveBinaries = async (args = []) => {
|
||||
platformArch,
|
||||
})
|
||||
|
||||
console.log('finding binary for %s in %s', platformArch, uploadDir)
|
||||
console.log('finding binary in %s for %s in %s', aws.bucket, platformArch, uploadDir)
|
||||
|
||||
const list: string[] = await s3helpers.listS3Objects(uploadDir, aws.bucket, s3)
|
||||
|
||||
if (debug.enabled) {
|
||||
console.log('all found subfolders')
|
||||
console.log('all found sub-folders')
|
||||
console.log(list.join('\n'))
|
||||
}
|
||||
|
||||
|
||||
@@ -13,12 +13,18 @@ export const hasOnlyStringValues = (o) => {
|
||||
*/
|
||||
export const s3helpers = {
|
||||
makeS3 (aws) {
|
||||
la(is.unemptyString(aws.key), 'missing aws key')
|
||||
la(is.unemptyString(aws.secret), 'missing aws secret')
|
||||
la(is.unemptyString(aws.accessKeyId), 'missing aws accessKeyId')
|
||||
la(is.unemptyString(aws.secretAccessKey), 'missing aws secretAccessKey')
|
||||
|
||||
if (!process.env.CIRCLECI) {
|
||||
// sso is not required for CirceCI
|
||||
la(is.unemptyString(aws.sessionToken), 'missing aws sessionToken')
|
||||
}
|
||||
|
||||
return new S3({
|
||||
accessKeyId: aws.key,
|
||||
secretAccessKey: aws.secret,
|
||||
accessKeyId: aws.accessKeyId,
|
||||
secretAccessKey: aws.secretAccessKey,
|
||||
sessionToken: aws.sessionToken,
|
||||
})
|
||||
},
|
||||
|
||||
@@ -40,7 +46,7 @@ export const s3helpers = {
|
||||
|
||||
debug('s3 data for %s', zipFile)
|
||||
debug(data)
|
||||
resolve()
|
||||
resolve(null)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
@@ -9,16 +9,7 @@ const upload = require('./upload')
|
||||
const uploadUtils = require('./util/upload')
|
||||
const { s3helpers } = require('./s3-api')
|
||||
|
||||
const uploadTypes = {
|
||||
binary: {
|
||||
uploadFolder: 'binary',
|
||||
uploadFileName: 'cypress.zip',
|
||||
},
|
||||
'npm-package': {
|
||||
uploadFolder: 'npm',
|
||||
uploadFileName: 'cypress.tgz',
|
||||
},
|
||||
}
|
||||
const uploadTypes = uploadUtils.S3Configuration.betaUploadTypes
|
||||
|
||||
const getCDN = function (uploadPath) {
|
||||
return [uploadUtils.getUploadUrl(), uploadPath].join('/')
|
||||
@@ -32,16 +23,16 @@ const getUploadDirForPlatform = function (options) {
|
||||
// the artifact will be uploaded for every platform and uploaded into under a unique folder
|
||||
// https://cdn.cypress.io/beta/(binary|npm)/<version>/<platform>/<some unique version info>/cypress.zip
|
||||
// For binary:
|
||||
// beta/binary/9.4.2/win32-x64/circle-develop-219138ca4e952edc4af831f2ae16ce659ebdb50b/cypress.zip
|
||||
// beta/binary/9.4.2/win32-x64/develop-219138ca4e952edc4af831f2ae16ce659ebdb50b/cypress.zip
|
||||
// For NPM package:
|
||||
// beta/npm/9.4.2/circle-develop-219138ca4e952edc4af831f2ae16ce659ebdb50b/cypress.tgz
|
||||
// beta/npm/9.4.2/develop-219138ca4e952edc4af831f2ae16ce659ebdb50b/cypress.tgz
|
||||
const getUploadPath = function (options) {
|
||||
const { hash, uploadFileName } = options
|
||||
|
||||
return [getUploadDirForPlatform(options), hash, uploadFileName].join('/')
|
||||
}
|
||||
|
||||
const setChecksum = (filename, key) => {
|
||||
const setChecksum = async (filename, key) => {
|
||||
console.log('setting checksum for file %s', filename)
|
||||
console.log('on s3 object %s', key)
|
||||
|
||||
@@ -56,7 +47,7 @@ const setChecksum = (filename, key) => {
|
||||
console.log('SHA256 checksum %s', checksum)
|
||||
console.log('size', size)
|
||||
|
||||
const aws = uploadUtils.getS3Credentials()
|
||||
const aws = await uploadUtils.getS3Credentials()
|
||||
const s3 = s3helpers.makeS3(aws)
|
||||
// S3 object metadata can only have string values
|
||||
const metadata = {
|
||||
@@ -66,7 +57,7 @@ const setChecksum = (filename, key) => {
|
||||
|
||||
// by default s3.copyObject does not preserve ACL when copying
|
||||
// thus we need to reset it for our public files
|
||||
return s3helpers.setUserMetadata(aws.bucket, key, metadata,
|
||||
return s3helpers.setUserMetadata(uploadUtils.S3Configuration.bucket, key, metadata,
|
||||
'application/zip', 'public-read', s3)
|
||||
}
|
||||
|
||||
@@ -128,7 +119,7 @@ const uploadArtifactToS3 = function (args = []) {
|
||||
.then(uploadUtils.saveUrl(`${options.type}-url.json`))
|
||||
.catch((e) => {
|
||||
console.error('There was an issue uploading the artifact.')
|
||||
console.error(e)
|
||||
throw e
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
+46
-49
@@ -15,17 +15,13 @@ fs = Promise.promisifyAll(fs)
|
||||
// TODO: refactor this
|
||||
// system expects desktop application to be inside a file
|
||||
// with this name
|
||||
const zipName = 'cypress.zip'
|
||||
const zipName = uploadUtils.S3Configuration.binaryZipName
|
||||
|
||||
module.exports = {
|
||||
zipName,
|
||||
|
||||
getPublisher () {
|
||||
return uploadUtils.getPublisher(this.getAwsObj)
|
||||
},
|
||||
|
||||
getAwsObj () {
|
||||
return uploadUtils.getS3Credentials()
|
||||
async getPublisher () {
|
||||
return uploadUtils.getPublisher()
|
||||
},
|
||||
|
||||
// returns desktop folder for a given folder without platform
|
||||
@@ -43,7 +39,7 @@ module.exports = {
|
||||
let { folder, version, platformArch, name } = options
|
||||
|
||||
if (!folder) {
|
||||
folder = this.getAwsObj().folder
|
||||
folder = uploadUtils.S3Configuration.releaseFolder
|
||||
}
|
||||
|
||||
la(check.unemptyString(folder), 'missing folder', options)
|
||||
@@ -104,34 +100,34 @@ module.exports = {
|
||||
},
|
||||
|
||||
s3Manifest (version) {
|
||||
const publisher = this.getPublisher()
|
||||
return this.getPublisher()
|
||||
.then((publisher) => {
|
||||
const { releaseFolder } = uploadUtils.S3Configuration
|
||||
|
||||
const aws = this.getAwsObj()
|
||||
const headers = {
|
||||
'Cache-Control': 'no-cache',
|
||||
}
|
||||
let manifest = null
|
||||
|
||||
const headers = {}
|
||||
return new Promise((resolve, reject) => {
|
||||
return this.createRemoteManifest(releaseFolder, version)
|
||||
.then((src) => {
|
||||
manifest = src
|
||||
|
||||
headers['Cache-Control'] = 'no-cache'
|
||||
return gulp.src(src)
|
||||
.pipe(rename((p) => {
|
||||
p.dirname = `${releaseFolder}/${p.dirname}`
|
||||
|
||||
let manifest = null
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
return this.createRemoteManifest(aws.folder, version)
|
||||
.then((src) => {
|
||||
manifest = src
|
||||
|
||||
return gulp.src(src)
|
||||
.pipe(rename((p) => {
|
||||
p.dirname = `${aws.folder}/${p.dirname}`
|
||||
|
||||
return p
|
||||
})).pipe(gulpDebug())
|
||||
.pipe(publisher.publish(headers))
|
||||
.pipe(awspublish.reporter())
|
||||
.on('error', reject)
|
||||
.on('end', resolve)
|
||||
return p
|
||||
})).pipe(gulpDebug())
|
||||
.pipe(publisher.publish(headers))
|
||||
.pipe(awspublish.reporter())
|
||||
.on('error', reject)
|
||||
.on('end', resolve)
|
||||
})
|
||||
}).finally(() => {
|
||||
return fs.removeAsync(manifest)
|
||||
})
|
||||
}).finally(() => {
|
||||
return fs.removeAsync(manifest)
|
||||
})
|
||||
},
|
||||
|
||||
@@ -144,26 +140,27 @@ module.exports = {
|
||||
la(check.extension(path.extname(uploadPath))(file),
|
||||
'invalid file to upload extension', file)
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const publisher = this.getPublisher()
|
||||
return this.getPublisher()
|
||||
.then((publisher) => {
|
||||
const headers = {
|
||||
'Cache-Control': 'no-cache',
|
||||
}
|
||||
|
||||
const headers = {}
|
||||
return new Promise((resolve, reject) => {
|
||||
return gulp.src(file)
|
||||
.pipe(rename((p) => {
|
||||
// rename to standard filename for upload
|
||||
p.basename = path.basename(uploadPath, path.extname(uploadPath))
|
||||
p.dirname = path.dirname(uploadPath)
|
||||
|
||||
headers['Cache-Control'] = 'no-cache'
|
||||
|
||||
return gulp.src(file)
|
||||
.pipe(rename((p) => {
|
||||
// rename to standard filename for upload
|
||||
p.basename = path.basename(uploadPath, path.extname(uploadPath))
|
||||
p.dirname = path.dirname(uploadPath)
|
||||
|
||||
return p
|
||||
}))
|
||||
.pipe(gulpDebug())
|
||||
.pipe(publisher.publish(headers))
|
||||
.pipe(awspublish.reporter())
|
||||
.on('error', reject)
|
||||
.on('end', resolve)
|
||||
return p
|
||||
}))
|
||||
.pipe(gulpDebug())
|
||||
.pipe(publisher.publish(headers))
|
||||
.pipe(awspublish.reporter())
|
||||
.on('error', reject)
|
||||
.on('end', resolve)
|
||||
})
|
||||
})
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
const _ = require('lodash')
|
||||
const path = require('path')
|
||||
const awspublish = require('gulp-awspublish')
|
||||
const human = require('human-interval')
|
||||
const la = require('lazy-ass')
|
||||
@@ -7,7 +6,8 @@ const check = require('check-more-types')
|
||||
const fse = require('fs-extra')
|
||||
const os = require('os')
|
||||
const Promise = require('bluebird')
|
||||
const { configFromEnvOrJsonFile, filenameToShellVariable } = require('@cypress/env-or-json-file')
|
||||
const { fromSSO, fromEnv } = require('@aws-sdk/credential-providers')
|
||||
|
||||
const konfig = require('../get-config')()
|
||||
const { purgeCloudflareCache } = require('./purge-cloudflare-cache')
|
||||
|
||||
@@ -25,47 +25,50 @@ const formHashFromEnvironment = function () {
|
||||
} = process
|
||||
|
||||
if (env.CIRCLECI) {
|
||||
return `circle-${env.CIRCLE_BRANCH}-${env.CIRCLE_SHA1}`
|
||||
return `${env.CIRCLE_BRANCH}-${env.CIRCLE_SHA1}`
|
||||
}
|
||||
|
||||
throw new Error('Do not know how to form unique build hash on this CI')
|
||||
}
|
||||
|
||||
const getS3Credentials = function () {
|
||||
const key = path.join('scripts', 'support', 'aws-credentials.json')
|
||||
const config = configFromEnvOrJsonFile(key)
|
||||
|
||||
if (!config) {
|
||||
console.error('⛔️ Cannot find AWS credentials')
|
||||
console.error('Using @cypress/env-or-json-file module')
|
||||
console.error('and filename', key)
|
||||
console.error('which is environment variable', filenameToShellVariable(key))
|
||||
console.error('available environment variable keys')
|
||||
console.error(Object.keys(process.env))
|
||||
throw new Error('AWS config not found')
|
||||
}
|
||||
|
||||
la(check.unemptyString(config.bucket), 'missing AWS config bucket')
|
||||
la(check.unemptyString(config.folder), 'missing AWS config folder')
|
||||
la(check.unemptyString(config.key), 'missing AWS key')
|
||||
la(check.unemptyString(config.secret), 'missing AWS secret key')
|
||||
|
||||
return config
|
||||
const S3Configuration = {
|
||||
bucket: 'cdn.cypress.io',
|
||||
releaseFolder: 'desktop',
|
||||
binaryZipName: 'cypress.zip',
|
||||
betaUploadTypes: {
|
||||
binary: {
|
||||
uploadFolder: 'binary',
|
||||
uploadFileName: 'cypress.zip',
|
||||
},
|
||||
'npm-package': {
|
||||
uploadFolder: 'npm',
|
||||
uploadFileName: 'cypress.tgz',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
const getPublisher = function (getAwsObj = getS3Credentials) {
|
||||
const aws = getAwsObj()
|
||||
const getS3Credentials = async function () {
|
||||
// sso is not required for CirceCI
|
||||
if (process.env.CIRCLECI) {
|
||||
return fromEnv()()
|
||||
}
|
||||
|
||||
return fromSSO({ profile: process.env.AWS_PROFILE || 'production' })()
|
||||
}
|
||||
|
||||
const getPublisher = async function () {
|
||||
const aws = await getS3Credentials()
|
||||
|
||||
// console.log("aws.bucket", aws.bucket)
|
||||
return awspublish.create({
|
||||
httpOptions: {
|
||||
timeout: human('10 minutes'),
|
||||
},
|
||||
params: {
|
||||
Bucket: aws.bucket,
|
||||
Bucket: S3Configuration.bucket,
|
||||
},
|
||||
accessKeyId: aws.key,
|
||||
secretAccessKey: aws.secret,
|
||||
accessKeyId: aws.accessKeyId,
|
||||
secretAccessKey: aws.secretAccessKey,
|
||||
sessionToken: aws.sessionToken,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -156,6 +159,7 @@ const saveUrl = (filename) => {
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
S3Configuration,
|
||||
getS3Credentials,
|
||||
getPublisher,
|
||||
purgeDesktopAppFromCache,
|
||||
|
||||
Executable
+57
@@ -0,0 +1,57 @@
|
||||
#!/bin/bash
|
||||
set -e # exit on error
|
||||
|
||||
PLATFORM=$(node -p 'process.platform')
|
||||
if [[ $PLATFORM != "linux" && $PLATFORM != "darwin" ]]; then
|
||||
echo "Currently, create-stable-npm-package is only supported on Linux and MacOS."
|
||||
echo "See https://github.com/cypress-io/cypress/pull/20296#discussion_r817115583"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! $1 ]]; then
|
||||
echo "publish-npm-package takes the .tgz URL as the first argument"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ $1 != *"linux-x64"* ]]; then
|
||||
echo "Only publish the 'linux-x64' .tgz. A non-linux-x64 .tgz was passed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set -x # log commands
|
||||
|
||||
TGZ_URL=$1
|
||||
PREPROD_TGZ_PATH=/tmp/cypress-preprod.tgz
|
||||
UNPACKED_PATH=/tmp/unpacked-cypress
|
||||
PROD_TGZ_PATH=/tmp/cypress-prod.tgz
|
||||
|
||||
echo "Downloading tgz from TGZ_URL=$TGZ_URL"
|
||||
curl $TGZ_URL -o $PREPROD_TGZ_PATH
|
||||
|
||||
echo "Untarring PREPROD_TGZ_PATH=$PREPROD_TGZ_PATH"
|
||||
rm -rf $UNPACKED_PATH || true
|
||||
mkdir $UNPACKED_PATH
|
||||
tar -xzvf $PREPROD_TGZ_PATH -C $UNPACKED_PATH
|
||||
|
||||
export PKG_JSON_PATH=$UNPACKED_PATH/package/package.json
|
||||
|
||||
echo "Patching stable: true to package.json"
|
||||
node <<EOF
|
||||
const fs = require('fs')
|
||||
const pkg = require("$PKG_JSON_PATH")
|
||||
pkg.buildInfo.stable = true
|
||||
const json = JSON.stringify(pkg, null, 2)
|
||||
fs.writeFileSync("$PKG_JSON_PATH", json)
|
||||
EOF
|
||||
|
||||
echo "New package.json:"
|
||||
cat $UNPACKED_PATH/package/package.json
|
||||
|
||||
echo "Tarring..."
|
||||
cd $UNPACKED_PATH
|
||||
tar -czvf $PROD_TGZ_PATH *
|
||||
|
||||
set +x
|
||||
|
||||
echo "Prod NPM package built at:"
|
||||
echo " $PROD_TGZ_PATH"
|
||||
@@ -0,0 +1,27 @@
|
||||
const minimist = require('minimist')
|
||||
const shelljs = require('shelljs')
|
||||
|
||||
const args = minimist(process.argv.slice(2))
|
||||
|
||||
if (!/^[a-z0-9]{40}$/.test(args.sha)) {
|
||||
throw new Error('A valid (40 character) commit SHA must be passed in `--sha`.')
|
||||
}
|
||||
|
||||
if (!/^\d+\.\d+\.\d+$/.test(args.version)) {
|
||||
throw new Error('A valid semantic version (X.Y.Z) must be passed in `--version`.')
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-console
|
||||
const log = (...args) => console.log('🏗', ...args)
|
||||
|
||||
const exec = args['dry-run'] ?
|
||||
(...args) => log('Dry run, not executing:', ...args)
|
||||
: (...args) => shelljs.exec(...args)
|
||||
|
||||
log('Running `move-binaries`...')
|
||||
exec(`node ./scripts/binary.js move-binaries --sha ${args.sha} --version ${args.version}`)
|
||||
|
||||
const prereleaseNpmUrl = `https://cdn.cypress.io/beta/npm/${args.version}/linux-x64/develop-${args.sha}/cypress.tgz`
|
||||
|
||||
log('Running `create-stable-npm-package`...')
|
||||
exec(`./scripts/create-stable-npm-package.sh ${prereleaseNpmUrl}`)
|
||||
@@ -0,0 +1,10 @@
|
||||
const shelljs = require('shelljs')
|
||||
const snapshot = require('snap-shot-it')
|
||||
|
||||
describe('prepare-release-artifacts', () => {
|
||||
it('runs expected commands', () => {
|
||||
const stdout = shelljs.exec('yarn prepare-release-artifacts --dry-run --sha 57d0a85108fad6f77b39db88b8a7d8a3bfdb51a2 --version 1.2.3')
|
||||
|
||||
snapshot(stdout)
|
||||
})
|
||||
})
|
||||
@@ -182,13 +182,13 @@ exports['testConfigOverrides / fails when passing invalid config values - [chrom
|
||||
1) inline test config override throws error:
|
||||
Error: Expected \`baseUrl\` to be a fully qualified URL (starting with \`http://\` or \`https://\`).
|
||||
|
||||
Instead the value was: \`""\`\`
|
||||
Instead the value was: \`""\`
|
||||
[stack trace lines]
|
||||
|
||||
2) inline test config override throws error when executed within cy cmd:
|
||||
Error: Expected \`baseUrl\` to be a fully qualified URL (starting with \`http://\` or \`https://\`).
|
||||
|
||||
Instead the value was: \`"null"\`\`
|
||||
Instead the value was: \`"null"\`
|
||||
[stack trace lines]
|
||||
|
||||
3) context config overrides throws error
|
||||
@@ -197,7 +197,7 @@ Instead the value was: \`"null"\`\`
|
||||
|
||||
Expected \`retries\` to be a positive number or null or an object with keys "openMode" and "runMode" with values of numbers or nulls.
|
||||
|
||||
Instead the value was: \`"1"\`\`
|
||||
Instead the value was: \`"1"\`
|
||||
|
||||
https://on.cypress.io/config
|
||||
Error
|
||||
@@ -209,7 +209,7 @@ https://on.cypress.io/config
|
||||
|
||||
Expected \`defaultCommandTimeout\` to be a number.
|
||||
|
||||
Instead the value was: \`"500"\`\`
|
||||
Instead the value was: \`"500"\`
|
||||
|
||||
https://on.cypress.io/config
|
||||
Error
|
||||
@@ -221,7 +221,7 @@ https://on.cypress.io/config
|
||||
|
||||
Expected \`defaultCommandTimeout\` to be a number.
|
||||
|
||||
Instead the value was: \`"500"\`\`
|
||||
Instead the value was: \`"500"\`
|
||||
|
||||
https://on.cypress.io/config
|
||||
Error
|
||||
@@ -234,7 +234,7 @@ https://on.cypress.io/config
|
||||
|
||||
Expected \`baseUrl\` to be a fully qualified URL (starting with \`http://\` or \`https://\`).
|
||||
|
||||
Instead the value was: \`"not_an_http_url"\`\`
|
||||
Instead the value was: \`"not_an_http_url"\`
|
||||
|
||||
https://on.cypress.io/config
|
||||
Error
|
||||
@@ -246,7 +246,7 @@ https://on.cypress.io/config
|
||||
|
||||
Expected \`retries\` to be a positive number or null or an object with keys "openMode" and "runMode" with values of numbers or nulls.
|
||||
|
||||
Instead the value was: \`"1"\`\`
|
||||
Instead the value was: \`"1"\`
|
||||
|
||||
https://on.cypress.io/config
|
||||
|
||||
@@ -260,7 +260,7 @@ Because this error occurred during a \`before all\` hook we are skipping the rem
|
||||
|
||||
Expected \`retries\` to be a positive number or null or an object with keys "openMode" and "runMode" with values of numbers or nulls.
|
||||
|
||||
Instead the value was: \`"1"\`\`
|
||||
Instead the value was: \`"1"\`
|
||||
|
||||
https://on.cypress.io/config
|
||||
Error
|
||||
@@ -350,14 +350,14 @@ exports['testConfigOverrides / fails when passing invalid config values with bef
|
||||
inline test config override throws error:
|
||||
Error: Expected \`baseUrl\` to be a fully qualified URL (starting with \`http://\` or \`https://\`).
|
||||
|
||||
Instead the value was: \`""\`\`
|
||||
Instead the value was: \`""\`
|
||||
[stack trace lines]
|
||||
|
||||
2) runs all tests
|
||||
inline test config override throws error when executed within cy cmd:
|
||||
Error: Expected \`baseUrl\` to be a fully qualified URL (starting with \`http://\` or \`https://\`).
|
||||
|
||||
Instead the value was: \`"null"\`\`
|
||||
Instead the value was: \`"null"\`
|
||||
[stack trace lines]
|
||||
|
||||
3) runs all tests
|
||||
@@ -367,7 +367,7 @@ Instead the value was: \`"null"\`\`
|
||||
|
||||
Expected \`retries\` to be a positive number or null or an object with keys "openMode" and "runMode" with values of numbers or nulls.
|
||||
|
||||
Instead the value was: \`"1"\`\`
|
||||
Instead the value was: \`"1"\`
|
||||
|
||||
https://on.cypress.io/config
|
||||
Error
|
||||
@@ -380,7 +380,7 @@ https://on.cypress.io/config
|
||||
|
||||
Expected \`defaultCommandTimeout\` to be a number.
|
||||
|
||||
Instead the value was: \`"500"\`\`
|
||||
Instead the value was: \`"500"\`
|
||||
|
||||
https://on.cypress.io/config
|
||||
Error
|
||||
@@ -393,7 +393,7 @@ https://on.cypress.io/config
|
||||
|
||||
Expected \`defaultCommandTimeout\` to be a number.
|
||||
|
||||
Instead the value was: \`"500"\`\`
|
||||
Instead the value was: \`"500"\`
|
||||
|
||||
https://on.cypress.io/config
|
||||
Error
|
||||
@@ -407,7 +407,7 @@ https://on.cypress.io/config
|
||||
|
||||
Expected \`baseUrl\` to be a fully qualified URL (starting with \`http://\` or \`https://\`).
|
||||
|
||||
Instead the value was: \`"not_an_http_url"\`\`
|
||||
Instead the value was: \`"not_an_http_url"\`
|
||||
|
||||
https://on.cypress.io/config
|
||||
Error
|
||||
@@ -420,7 +420,7 @@ https://on.cypress.io/config
|
||||
|
||||
Expected \`retries\` to be a positive number or null or an object with keys "openMode" and "runMode" with values of numbers or nulls.
|
||||
|
||||
Instead the value was: \`"1"\`\`
|
||||
Instead the value was: \`"1"\`
|
||||
|
||||
https://on.cypress.io/config
|
||||
|
||||
@@ -435,7 +435,7 @@ Because this error occurred during a \`before all\` hook we are skipping the rem
|
||||
|
||||
Expected \`retries\` to be a positive number or null or an object with keys "openMode" and "runMode" with values of numbers or nulls.
|
||||
|
||||
Instead the value was: \`"1"\`\`
|
||||
Instead the value was: \`"1"\`
|
||||
|
||||
https://on.cypress.io/config
|
||||
Error
|
||||
@@ -517,7 +517,7 @@ exports['testConfigOverrides / correctly fails when invalid config values for it
|
||||
|
||||
Expected \`retries\` to be a positive number or null or an object with keys "openMode" and "runMode" with values of numbers or nulls.
|
||||
|
||||
Instead the value was: \`"1"\`\`
|
||||
Instead the value was: \`"1"\`
|
||||
|
||||
https://on.cypress.io/config
|
||||
Error
|
||||
@@ -601,13 +601,13 @@ exports['testConfigOverrides / fails when passing invalid config values - [firef
|
||||
1) inline test config override throws error:
|
||||
Error: Expected \`baseUrl\` to be a fully qualified URL (starting with \`http://\` or \`https://\`).
|
||||
|
||||
Instead the value was: \`""\`\`
|
||||
Instead the value was: \`""\`
|
||||
[stack trace lines]
|
||||
|
||||
2) inline test config override throws error when executed within cy cmd:
|
||||
Error: Expected \`baseUrl\` to be a fully qualified URL (starting with \`http://\` or \`https://\`).
|
||||
|
||||
Instead the value was: \`"null"\`\`
|
||||
Instead the value was: \`"null"\`
|
||||
[stack trace lines]
|
||||
|
||||
3) context config overrides throws error
|
||||
@@ -616,7 +616,7 @@ Instead the value was: \`"null"\`\`
|
||||
|
||||
Expected \`retries\` to be a positive number or null or an object with keys "openMode" and "runMode" with values of numbers or nulls.
|
||||
|
||||
Instead the value was: \`"1"\`\`
|
||||
Instead the value was: \`"1"\`
|
||||
|
||||
https://on.cypress.io/config
|
||||
[stack trace lines]
|
||||
@@ -627,7 +627,7 @@ https://on.cypress.io/config
|
||||
|
||||
Expected \`defaultCommandTimeout\` to be a number.
|
||||
|
||||
Instead the value was: \`"500"\`\`
|
||||
Instead the value was: \`"500"\`
|
||||
|
||||
https://on.cypress.io/config
|
||||
[stack trace lines]
|
||||
@@ -638,7 +638,7 @@ https://on.cypress.io/config
|
||||
|
||||
Expected \`defaultCommandTimeout\` to be a number.
|
||||
|
||||
Instead the value was: \`"500"\`\`
|
||||
Instead the value was: \`"500"\`
|
||||
|
||||
https://on.cypress.io/config
|
||||
[stack trace lines]
|
||||
@@ -650,7 +650,7 @@ https://on.cypress.io/config
|
||||
|
||||
Expected \`baseUrl\` to be a fully qualified URL (starting with \`http://\` or \`https://\`).
|
||||
|
||||
Instead the value was: \`"not_an_http_url"\`\`
|
||||
Instead the value was: \`"not_an_http_url"\`
|
||||
|
||||
https://on.cypress.io/config
|
||||
[stack trace lines]
|
||||
@@ -661,7 +661,7 @@ https://on.cypress.io/config
|
||||
|
||||
Expected \`retries\` to be a positive number or null or an object with keys "openMode" and "runMode" with values of numbers or nulls.
|
||||
|
||||
Instead the value was: \`"1"\`\`
|
||||
Instead the value was: \`"1"\`
|
||||
|
||||
https://on.cypress.io/config
|
||||
|
||||
@@ -674,7 +674,7 @@ Because this error occurred during a \`before all\` hook we are skipping the rem
|
||||
|
||||
Expected \`retries\` to be a positive number or null or an object with keys "openMode" and "runMode" with values of numbers or nulls.
|
||||
|
||||
Instead the value was: \`"1"\`\`
|
||||
Instead the value was: \`"1"\`
|
||||
|
||||
https://on.cypress.io/config
|
||||
[stack trace lines]
|
||||
@@ -763,14 +763,14 @@ exports['testConfigOverrides / fails when passing invalid config values with bef
|
||||
inline test config override throws error:
|
||||
Error: Expected \`baseUrl\` to be a fully qualified URL (starting with \`http://\` or \`https://\`).
|
||||
|
||||
Instead the value was: \`""\`\`
|
||||
Instead the value was: \`""\`
|
||||
[stack trace lines]
|
||||
|
||||
2) runs all tests
|
||||
inline test config override throws error when executed within cy cmd:
|
||||
Error: Expected \`baseUrl\` to be a fully qualified URL (starting with \`http://\` or \`https://\`).
|
||||
|
||||
Instead the value was: \`"null"\`\`
|
||||
Instead the value was: \`"null"\`
|
||||
[stack trace lines]
|
||||
|
||||
3) runs all tests
|
||||
@@ -780,7 +780,7 @@ Instead the value was: \`"null"\`\`
|
||||
|
||||
Expected \`retries\` to be a positive number or null or an object with keys "openMode" and "runMode" with values of numbers or nulls.
|
||||
|
||||
Instead the value was: \`"1"\`\`
|
||||
Instead the value was: \`"1"\`
|
||||
|
||||
https://on.cypress.io/config
|
||||
[stack trace lines]
|
||||
@@ -792,7 +792,7 @@ https://on.cypress.io/config
|
||||
|
||||
Expected \`defaultCommandTimeout\` to be a number.
|
||||
|
||||
Instead the value was: \`"500"\`\`
|
||||
Instead the value was: \`"500"\`
|
||||
|
||||
https://on.cypress.io/config
|
||||
[stack trace lines]
|
||||
@@ -804,7 +804,7 @@ https://on.cypress.io/config
|
||||
|
||||
Expected \`defaultCommandTimeout\` to be a number.
|
||||
|
||||
Instead the value was: \`"500"\`\`
|
||||
Instead the value was: \`"500"\`
|
||||
|
||||
https://on.cypress.io/config
|
||||
[stack trace lines]
|
||||
@@ -817,7 +817,7 @@ https://on.cypress.io/config
|
||||
|
||||
Expected \`baseUrl\` to be a fully qualified URL (starting with \`http://\` or \`https://\`).
|
||||
|
||||
Instead the value was: \`"not_an_http_url"\`\`
|
||||
Instead the value was: \`"not_an_http_url"\`
|
||||
|
||||
https://on.cypress.io/config
|
||||
[stack trace lines]
|
||||
@@ -829,7 +829,7 @@ https://on.cypress.io/config
|
||||
|
||||
Expected \`retries\` to be a positive number or null or an object with keys "openMode" and "runMode" with values of numbers or nulls.
|
||||
|
||||
Instead the value was: \`"1"\`\`
|
||||
Instead the value was: \`"1"\`
|
||||
|
||||
https://on.cypress.io/config
|
||||
|
||||
@@ -843,7 +843,7 @@ Because this error occurred during a \`before all\` hook we are skipping the rem
|
||||
|
||||
Expected \`retries\` to be a positive number or null or an object with keys "openMode" and "runMode" with values of numbers or nulls.
|
||||
|
||||
Instead the value was: \`"1"\`\`
|
||||
Instead the value was: \`"1"\`
|
||||
|
||||
https://on.cypress.io/config
|
||||
[stack trace lines]
|
||||
@@ -924,7 +924,7 @@ exports['testConfigOverrides / correctly fails when invalid config values for it
|
||||
|
||||
Expected \`retries\` to be a positive number or null or an object with keys "openMode" and "runMode" with values of numbers or nulls.
|
||||
|
||||
Instead the value was: \`"1"\`\`
|
||||
Instead the value was: \`"1"\`
|
||||
|
||||
https://on.cypress.io/config
|
||||
[stack trace lines]
|
||||
|
||||
Vendored
+8
@@ -0,0 +1,8 @@
|
||||
import { expect as _expect } from 'chai'
|
||||
import _sinon from 'sinon'
|
||||
|
||||
declare global {
|
||||
// these are made global in `spec_helper`
|
||||
const expect: typeof _expect
|
||||
const sinon: typeof _sinon
|
||||
}
|
||||
@@ -351,8 +351,8 @@ export function removeProject (name) {
|
||||
|
||||
// returns the path to project fixture
|
||||
// in the cyTmpDir
|
||||
export function project (...args) {
|
||||
return this.projectPath.apply(this, args)
|
||||
export function project (name) {
|
||||
return projectPath(name)
|
||||
}
|
||||
|
||||
export function projectPath (name) {
|
||||
|
||||
@@ -2,8 +2,6 @@ import systemTests from './system-tests'
|
||||
import dayjs from 'dayjs'
|
||||
import _ from 'lodash'
|
||||
|
||||
const expect = global.expect as unknown as Chai.ExpectStatic
|
||||
|
||||
const STATIC_DATE = '2018-02-01T20:14:19.323Z'
|
||||
|
||||
const expectDurationWithin = function (obj, duration, low, high, reset) {
|
||||
|
||||
@@ -166,7 +166,7 @@ const getResponse = function (responseSchema) {
|
||||
}
|
||||
|
||||
const sendResponse = function (req, res, responseBody) {
|
||||
return new Promise((resolve) => {
|
||||
return new Promise<void>((resolve) => {
|
||||
const _writeRaw = res._writeRaw
|
||||
|
||||
res._writeRaw = function () {
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
const snapshot = require('snap-shot-it')
|
||||
|
||||
import { SpawnOptions } from 'child_process'
|
||||
import type { SpawnOptions } from 'child_process'
|
||||
import stream from 'stream'
|
||||
import { expect } from './spec_helper'
|
||||
import { dockerSpawner } from './docker'
|
||||
import Express from 'express'
|
||||
|
||||
const isCi = require('is-ci')
|
||||
|
||||
@@ -15,7 +16,6 @@ const path = require('path')
|
||||
const http = require('http')
|
||||
const human = require('human-interval')
|
||||
const morgan = require('morgan')
|
||||
const express = require('express')
|
||||
const Bluebird = require('bluebird')
|
||||
const debug = require('debug')('cypress:system-tests')
|
||||
const httpsProxy = require('@packages/https-proxy')
|
||||
@@ -32,7 +32,8 @@ require(`@packages/server/lib/project-base`)
|
||||
|
||||
type CypressConfig = { [key: string]: any }
|
||||
|
||||
type BrowserName = 'electron' | 'firefox' | 'chrome'
|
||||
export type BrowserName = 'electron' | 'firefox' | 'chrome'
|
||||
| '!electron' | '!chrome' | '!firefox'
|
||||
|
||||
type ExecResult = {
|
||||
code: number
|
||||
@@ -503,7 +504,7 @@ const startServer = function (obj) {
|
||||
|
||||
ensurePort(port)
|
||||
|
||||
const app = express()
|
||||
const app = Express()
|
||||
|
||||
const srv = https ? httpsProxy.httpsServer(app) : new http.Server(app)
|
||||
|
||||
@@ -516,7 +517,7 @@ const startServer = function (obj) {
|
||||
}
|
||||
|
||||
if (obj.static) {
|
||||
app.use(express.static(path.join(__dirname, '../projects/e2e'), {}))
|
||||
app.use(Express.static(path.join(__dirname, '../projects/e2e'), {}) as Express.RequestHandler)
|
||||
}
|
||||
|
||||
return new Bluebird((resolve) => {
|
||||
@@ -705,6 +706,7 @@ const systemTests = {
|
||||
args = _.compact(args)
|
||||
|
||||
// avoid snapshot cwd issue - see /patches/snap-shot* for more information
|
||||
// @ts-ignore
|
||||
global.CACHED_CWD_FOR_SNAP_SHOT_IT = path.join(__dirname, '..')
|
||||
|
||||
return snapshot.apply(null, args)
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
"private": true,
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"type-check": "tsc --project .",
|
||||
"projects:yarn:install": "node ./scripts/projects-yarn-install.js",
|
||||
"test": "node ./scripts/run.js --glob-in-dir='{test,test-binary}'",
|
||||
"test:ci": "node ./scripts/run.js"
|
||||
@@ -28,6 +29,8 @@
|
||||
"@packages/socket": "0.0.0-development",
|
||||
"@packages/ts": "0.0.0-development",
|
||||
"@storybook/testing-vue3": "0.0.1",
|
||||
"@types/chai": "4.2.15",
|
||||
"@types/mocha": "9.1.0",
|
||||
"babel-loader": "8.1.0",
|
||||
"bluebird": "3.7.2",
|
||||
"body-parser": "1.19.0",
|
||||
@@ -45,7 +48,7 @@
|
||||
"dayjs": "^1.9.3",
|
||||
"debug": "^4.3.2",
|
||||
"dockerode": "3.3.1",
|
||||
"execa": "1.0.0",
|
||||
"execa": "4",
|
||||
"express": "4.17.1",
|
||||
"express-session": "1.16.1",
|
||||
"express-useragent": "1.0.15",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
const _ = require('lodash')
|
||||
const execa = require('execa')
|
||||
const { execa } = require('execa')
|
||||
const util = require('util')
|
||||
const si = require('systeminformation')
|
||||
|
||||
|
||||
@@ -2,6 +2,18 @@ import systemTests from '../lib/system-tests'
|
||||
|
||||
const beforeBrowserLaunchProject = 'plugin-before-browser-launch-deprecation'
|
||||
|
||||
const includesString = (s: string) => {
|
||||
return (stdout: string) => {
|
||||
expect(stdout).to.include(s)
|
||||
}
|
||||
}
|
||||
|
||||
const excludesString = (s: string) => {
|
||||
return (stdout: string) => {
|
||||
expect(stdout).to.not.include(s)
|
||||
}
|
||||
}
|
||||
|
||||
describe('deprecated before:browser:launch args', () => {
|
||||
systemTests.setup()
|
||||
|
||||
@@ -28,8 +40,7 @@ describe('deprecated before:browser:launch args', () => {
|
||||
project: beforeBrowserLaunchProject,
|
||||
spec: 'app.cy.js',
|
||||
snapshot: true,
|
||||
stdoutInclude: 'Deprecation Warning:',
|
||||
psInclude: ['--foo', '--bar'],
|
||||
onStdout: includesString('Deprecation Warning:'),
|
||||
})
|
||||
|
||||
systemTests.it('using non-deprecated API - no warning', {
|
||||
@@ -46,8 +57,7 @@ describe('deprecated before:browser:launch args', () => {
|
||||
project: beforeBrowserLaunchProject,
|
||||
spec: 'app.cy.js',
|
||||
snapshot: true,
|
||||
stdoutExclude: 'Deprecation Warning:',
|
||||
psInclude: ['--foo', '--bar'],
|
||||
onStdout: excludesString('Deprecation Warning:'),
|
||||
})
|
||||
|
||||
systemTests.it('concat return returns once', {
|
||||
@@ -71,10 +81,12 @@ describe('deprecated before:browser:launch args', () => {
|
||||
|
||||
return exec({ originalTitle: `deprecated before:browser:launch args / concat return returns once per test run - [firefox,chromium]` })
|
||||
},
|
||||
stdoutInclude: 'Deprecation Warning:',
|
||||
onStdout: includesString('Deprecation Warning:'),
|
||||
})
|
||||
|
||||
systemTests.it('no mutate return', {
|
||||
// TODO: fix/remove this test, it should be warning but is not
|
||||
// https://github.com/cypress-io/cypress/issues/20436
|
||||
systemTests.it.skip('no mutate return', {
|
||||
// TODO: implement webPreferences.additionalArgs here
|
||||
// once we decide if/what we're going to make the implemenation
|
||||
// SUGGESTION: add this to Cypress.browser.args which will capture
|
||||
@@ -88,8 +100,7 @@ describe('deprecated before:browser:launch args', () => {
|
||||
project: beforeBrowserLaunchProject,
|
||||
spec: 'app.cy.js',
|
||||
snapshot: true,
|
||||
stdoutInclude: 'Deprecation Warning:',
|
||||
psInclude: '--foo',
|
||||
onStdout: includesString('Deprecation Warning:'),
|
||||
})
|
||||
|
||||
// TODO: these errors could be greatly improved by the code frame
|
||||
|
||||
@@ -25,7 +25,6 @@ describe('e2e firefox', function () {
|
||||
config: {
|
||||
video: false,
|
||||
},
|
||||
exit: false,
|
||||
onRun: (exec) => {
|
||||
return exec()
|
||||
.then(() => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import systemTests from '../lib/system-tests'
|
||||
import systemTests, { BrowserName } from '../lib/system-tests'
|
||||
|
||||
describe('e2e headless', function () {
|
||||
systemTests.setup()
|
||||
@@ -25,7 +25,7 @@ describe('e2e headless', function () {
|
||||
|
||||
systemTests.it('pass for browsers that do not need xvfb', {
|
||||
...baseSpec,
|
||||
browser: ['chrome', 'chrome-beta', 'firefox'],
|
||||
browser: ['chrome', 'firefox'],
|
||||
expectedExitCode: 0,
|
||||
onRun (exec) {
|
||||
return exec().then(({ stderr }) => {
|
||||
@@ -60,10 +60,10 @@ describe('e2e headless', function () {
|
||||
// "can not record video in headed mode" error
|
||||
// this trick allows us to have 1 snapshot for electron
|
||||
// and 1 for every other browser
|
||||
;[
|
||||
;([
|
||||
'electron',
|
||||
'!electron',
|
||||
].map((b) => {
|
||||
] as BrowserName[]).map((b) => {
|
||||
systemTests.it(`tests in headed mode pass in ${b}`, {
|
||||
spec: 'headless.cy.js',
|
||||
config: {
|
||||
|
||||
@@ -2,7 +2,7 @@ import bodyParser from 'body-parser'
|
||||
import cookieParser from 'cookie-parser'
|
||||
import systemTests from '../lib/system-tests'
|
||||
|
||||
let counts = null
|
||||
let counts: Record<string, number> | null = null
|
||||
|
||||
const urlencodedParser = bodyParser.urlencoded({ extended: false })
|
||||
const jsonParser = bodyParser.json()
|
||||
|
||||
@@ -90,7 +90,9 @@ describe('e2e screenshots', () => {
|
||||
fs.statAsync(screenshot4).get('size'),
|
||||
fs.statAsync(screenshot5).get('size'),
|
||||
fs.statAsync(screenshot6).get('size'),
|
||||
fs.statAsync(screenshot7).get('size'),
|
||||
// Ignore comparing 6 and 7 since they can sometimes be the same since we take the screenshot as close to the failure as possible and
|
||||
// the test run error may not have displayed yet. Leaving this commented in case we want to change this behavior in the future
|
||||
// fs.statAsync(screenshot7).get('size'),
|
||||
fs.statAsync(screenshot8).get('size'),
|
||||
fs.statAsync(screenshot9).get('size'),
|
||||
])
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import fs from 'fs-extra'
|
||||
import path from 'path'
|
||||
import systemTests, { expect } from '../lib/system-tests'
|
||||
import systemTests, { expect, BrowserName } from '../lib/system-tests'
|
||||
import Fixtures from '../lib/fixtures'
|
||||
|
||||
const e2ePath = Fixtures.projectPath('e2e')
|
||||
@@ -35,7 +35,7 @@ describe('testConfigOverrides', () => {
|
||||
|
||||
// window.Error throws differently for firefox. break into
|
||||
// browser permutations for snapshot comparisons
|
||||
const permutations = [
|
||||
const permutations: BrowserName[][] = [
|
||||
['chrome', 'electron'],
|
||||
['firefox'],
|
||||
]
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"extends": "../packages/ts/tsconfig.json",
|
||||
"include": [
|
||||
"test",
|
||||
"lib",
|
||||
],
|
||||
"files": [
|
||||
"../packages/ts/index.d.ts",
|
||||
"./globals.d.ts"
|
||||
],
|
||||
"compilerOptions": {
|
||||
"types": [
|
||||
"mocha",
|
||||
"node",
|
||||
"chai"
|
||||
],
|
||||
"noEmit": true,
|
||||
"lib": ["esnext"],
|
||||
"skipLibCheck": true,
|
||||
"noImplicitReturns": false,
|
||||
"strictNullChecks": false
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user