mirror of
https://github.com/cypress-io/cypress.git
synced 2026-02-19 13:41:26 -06:00
iterate through specs in parallel (#2154)
- fixes: #2153 - fixes: #1566 - fixes: #1690 - fixes: #2275 - fixes: #2276
This commit is contained in:
committed by
Brian Mann
parent
88379da700
commit
f313dd0b84
@@ -171,7 +171,9 @@ jobs:
|
||||
paths:
|
||||
- packages/ts/node_modules
|
||||
|
||||
- run: npm run stop-only
|
||||
## TODO: this needs to be reenabled when
|
||||
## we update stop-only
|
||||
# - run: npm run stop-only
|
||||
## now go build all of subpackages
|
||||
- run: npm run build
|
||||
|
||||
|
||||
@@ -67,6 +67,9 @@ exports['shows help for run --foo 1'] = `
|
||||
-c, --config <config> sets configuration values. separate multiple values with a comma. overrides any value in cypress.json.
|
||||
-b, --browser <browser-name> runs Cypress in the browser with the given name. note: using an external browser will not record a video.
|
||||
-P, --project <project-path> path to the project
|
||||
--parallel enables concurrent runs and automatic load balancing of specs across multiple machines or processes
|
||||
--group <name> a named group for recorded runs in the Cypress dashboard
|
||||
--ci-build-id <id> the unique identifier for a run on your CI provider. typically a "BUILD_ID" env var. this value is automatically detected for most CI providers
|
||||
--no-exit keep the browser open after tests finish
|
||||
--dev runs cypress in development and bypasses binary check
|
||||
-h, --help output usage information
|
||||
@@ -94,14 +97,14 @@ exports['cli help command shows help 1'] = `
|
||||
|
||||
Options:
|
||||
|
||||
-v, --version Prints Cypress version
|
||||
-v, --version prints Cypress version
|
||||
-h, --help output usage information
|
||||
|
||||
|
||||
Commands:
|
||||
|
||||
help Shows CLI help and exits
|
||||
version Prints Cypress version
|
||||
version prints Cypress version
|
||||
run [options] Runs Cypress tests from the CLI without the GUI
|
||||
open [options] Opens Cypress in the interactive GUI.
|
||||
install [options] Installs the Cypress executable matching this package's version
|
||||
@@ -131,14 +134,14 @@ exports['cli help command shows help for -h 1'] = `
|
||||
|
||||
Options:
|
||||
|
||||
-v, --version Prints Cypress version
|
||||
-v, --version prints Cypress version
|
||||
-h, --help output usage information
|
||||
|
||||
|
||||
Commands:
|
||||
|
||||
help Shows CLI help and exits
|
||||
version Prints Cypress version
|
||||
version prints Cypress version
|
||||
run [options] Runs Cypress tests from the CLI without the GUI
|
||||
open [options] Opens Cypress in the interactive GUI.
|
||||
install [options] Installs the Cypress executable matching this package's version
|
||||
@@ -168,14 +171,14 @@ exports['cli help command shows help for --help 1'] = `
|
||||
|
||||
Options:
|
||||
|
||||
-v, --version Prints Cypress version
|
||||
-v, --version prints Cypress version
|
||||
-h, --help output usage information
|
||||
|
||||
|
||||
Commands:
|
||||
|
||||
help Shows CLI help and exits
|
||||
version Prints Cypress version
|
||||
version prints Cypress version
|
||||
run [options] Runs Cypress tests from the CLI without the GUI
|
||||
open [options] Opens Cypress in the interactive GUI.
|
||||
install [options] Installs the Cypress executable matching this package's version
|
||||
@@ -207,14 +210,14 @@ exports['cli unknown command shows usage and exits 1'] = `
|
||||
|
||||
Options:
|
||||
|
||||
-v, --version Prints Cypress version
|
||||
-v, --version prints Cypress version
|
||||
-h, --help output usage information
|
||||
|
||||
|
||||
Commands:
|
||||
|
||||
help Shows CLI help and exits
|
||||
version Prints Cypress version
|
||||
version prints Cypress version
|
||||
run [options] Runs Cypress tests from the CLI without the GUI
|
||||
open [options] Opens Cypress in the interactive GUI.
|
||||
install [options] Installs the Cypress executable matching this package's version
|
||||
|
||||
@@ -28,7 +28,7 @@ const parseOpts = (opts) => {
|
||||
'project', 'spec', 'reporter', 'reporterOptions', 'path', 'destination',
|
||||
'port', 'env', 'cypressVersion', 'config', 'record', 'key',
|
||||
'browser', 'detached', 'headed', 'global', 'dev', 'force', 'exit',
|
||||
'cachePath', 'cacheList', 'cacheClear'
|
||||
'cachePath', 'cacheList', 'cacheClear', 'parallel', 'group', 'ciBuildId'
|
||||
)
|
||||
|
||||
if (opts.exit) {
|
||||
@@ -56,7 +56,7 @@ const descriptions = {
|
||||
detached: 'runs Cypress application in detached mode',
|
||||
project: 'path to the project',
|
||||
global: 'force Cypress into global mode as if its globally installed',
|
||||
version: 'Prints Cypress version',
|
||||
version: 'prints Cypress version',
|
||||
headed: 'displays the Electron browser instead of running headlessly',
|
||||
dev: 'runs cypress in development and bypasses binary check',
|
||||
forceInstall: 'force install the Cypress binary',
|
||||
@@ -64,6 +64,9 @@ const descriptions = {
|
||||
cachePath: 'print the cypress binary cache path',
|
||||
cacheList: 'list the currently cached versions',
|
||||
cacheClear: 'delete the Cypress binary cache',
|
||||
group: 'a named group for recorded runs in the Cypress dashboard',
|
||||
parallel: 'enables concurrent runs and automatic load balancing of specs across multiple machines or processes',
|
||||
ciBuildId: 'the unique identifier for a run on your CI provider. typically a "BUILD_ID" env var. this value is automatically detected for most CI providers',
|
||||
}
|
||||
|
||||
const knownCommands = ['version', 'run', 'open', 'install', 'verify', '-v', '--version', 'help', '-h', '--help', 'cache']
|
||||
@@ -134,6 +137,9 @@ module.exports = {
|
||||
.option('-c, --config <config>', text('config'))
|
||||
.option('-b, --browser <browser-name>', text('browser'))
|
||||
.option('-P, --project <project-path>', text('project'))
|
||||
.option('--parallel', text('parallel'))
|
||||
.option('--group <name>', text('group'))
|
||||
.option('--ci-build-id <id>', text('ciBuildId'))
|
||||
.option('--no-exit', text('exit'))
|
||||
.option('--dev', text('dev'), coerceFalse)
|
||||
.action((opts) => {
|
||||
|
||||
@@ -64,6 +64,18 @@ const processRunOptions = (options = {}) => {
|
||||
args.push('--record', options.record)
|
||||
}
|
||||
|
||||
if (options.parallel) {
|
||||
args.push('--parallel')
|
||||
}
|
||||
|
||||
if (options.group) {
|
||||
args.push('--group', options.group)
|
||||
}
|
||||
|
||||
if (options.ciBuildId) {
|
||||
args.push('--ci-build-id', options.ciBuildId)
|
||||
}
|
||||
|
||||
if (options.outputPath) {
|
||||
args.push('--output-path', options.outputPath)
|
||||
}
|
||||
|
||||
@@ -205,6 +205,20 @@ describe('cli', function () {
|
||||
expect(run.start).to.be.calledWith({ exit: false })
|
||||
})
|
||||
|
||||
it('calls run with --parallel', function () {
|
||||
this.exec('run --parallel')
|
||||
expect(run.start).to.be.calledWith({ parallel: true })
|
||||
})
|
||||
|
||||
it('calls runs with --ci-build-id', function () {
|
||||
this.exec('run --ci-build-id 123')
|
||||
expect(run.start).to.be.calledWith({ ciBuildId: '123' })
|
||||
})
|
||||
|
||||
it('calls runs with --group', function () {
|
||||
this.exec('run --group staging')
|
||||
expect(run.start).to.be.calledWith({ group: 'staging' })
|
||||
})
|
||||
})
|
||||
|
||||
context('cypress open', function () {
|
||||
|
||||
13
package.json
13
package.json
@@ -26,11 +26,10 @@
|
||||
"lint-coffee": "coffeelint scripts/**/*.coffee",
|
||||
"lint": "npm run lint-js && npm run lint-coffee",
|
||||
"pretest": "npm run lint && npm run all lint && npm run test-scripts",
|
||||
"precommit": "lint-staged; npm run warn-only",
|
||||
"precommit": "lint-staged",
|
||||
"precommit-lint": "eslint --fix",
|
||||
"prepush": "npm run stop-only",
|
||||
"stop-only": "stop-only packages --exclude-dir .cy --exclude-dir .projects --exclude-dir node_modules --exclude-dir dist --exclude-dir dist-test --exclude-dir fixtures --exclude-dir lib --exclude-dir bower_components",
|
||||
"warn-only": "stop-only --warn packages --exclude-dir .cy --exclude-dir .projects --exclude-dir node_modules --exclude-dir dist --exclude-dir dist-test --exclude-dir fixtures --exclude-dir lib --exclude-dir bower_components",
|
||||
"stop-only": "stop-only --folder packages --skip .cy,.publish,.projects,node_modules,dist,dist-test,fixtures,lib,bower_components,spec_helper.coffee",
|
||||
"warn-only": "stop-only --warn packages --skip .cy,.publish,.projects,node_modules,dist,dist-test,fixtures,lib,bower_components,spec_helper.coffee",
|
||||
"bump": "node ./scripts/binary.js bump",
|
||||
"set-next-ci-version": "node ./scripts/binary.js setNextVersion",
|
||||
"binary-build": "node ./scripts/binary.js build",
|
||||
@@ -80,7 +79,7 @@
|
||||
"execa": "^0.8.0",
|
||||
"execa-wrap": "^1.1.0",
|
||||
"filesize": "^3.5.10",
|
||||
"fs-extra": "^2.1.2",
|
||||
"fs-extra": "^7.0.0",
|
||||
"gift": "^0.10.0",
|
||||
"gulp": "^3.9.1",
|
||||
"gulp-awspublish": "^3.3.0",
|
||||
@@ -108,8 +107,8 @@
|
||||
"print-arch": "^1.0.0",
|
||||
"ramda": "^0.24.1",
|
||||
"shelljs": "^0.7.8",
|
||||
"snap-shot-it": "^4.0.1",
|
||||
"stop-only": "1.2.1",
|
||||
"snap-shot-it": "^5.0.1",
|
||||
"stop-only": "2.1.0",
|
||||
"terminal-banner": "^1.0.0",
|
||||
"typescript": "^2.3.4",
|
||||
"vagrant": "0.0.1",
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
exports['e2e async timeouts failing1 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -67,5 +68,5 @@ exports['e2e async timeouts failing1 1'] = `
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
1 of 1 failed (100%) XX:XX 1 - 1 - -
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
@@ -1,4 +1,5 @@
|
||||
exports['e2e baseUrl https passes 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -55,9 +56,11 @@ exports['e2e baseUrl https passes 1'] = `
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
All specs passed! XX:XX 1 1 - - -
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['e2e baseUrl http passes 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -114,5 +117,5 @@ exports['e2e baseUrl http passes 1'] = `
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
All specs passed! XX:XX 1 1 - - -
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
@@ -1,4 +1,5 @@
|
||||
exports['e2e blacklist passes 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -55,5 +56,5 @@ exports['e2e blacklist passes 1'] = `
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
All specs passed! XX:XX 1 1 - - -
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
@@ -1,4 +1,5 @@
|
||||
exports['e2e browserify, babel, es2015 passes 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -57,9 +58,11 @@ exports['e2e browserify, babel, es2015 passes 1'] = `
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
All specs passed! XX:XX 3 3 - - -
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['e2e browserify, babel, es2015 fails 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -88,7 +91,6 @@ SyntaxError: /foo/bar/.projects/e2e/lib/fail.js: Unexpected token (2:0)
|
||||
> 2 |
|
||||
| ^ while parsing file: /foo/bar/.projects/e2e/lib/fail.js
|
||||
|
||||
|
||||
This occurred while Cypress was compiling and bundling your test code. This is usually caused by:
|
||||
|
||||
- A missing file or dependency
|
||||
@@ -128,5 +130,5 @@ Fix the error in your code and re-run your tests.
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
1 of 1 failed (100%) XX:XX - - 1 - -
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
@@ -1,4 +1,5 @@
|
||||
exports['e2e busted support file passes 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -22,7 +23,6 @@ The error was:
|
||||
|
||||
Error: Cannot find module './does/not/exist' from '/foo/bar/.projects/busted-support-file/cypress/support'
|
||||
|
||||
|
||||
This occurred while Cypress was compiling and bundling your test code. This is usually caused by:
|
||||
|
||||
- A missing file or dependency
|
||||
@@ -62,5 +62,5 @@ Fix the error in your code and re-run your tests.
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
1 of 1 failed (100%) XX:XX - - 1 - -
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
@@ -1,4 +1,5 @@
|
||||
exports['e2e cache passes 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -58,5 +59,5 @@ exports['e2e cache passes 1'] = `
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
All specs passed! XX:XX 4 4 - - -
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
@@ -1,4 +1,5 @@
|
||||
exports['e2e caught and uncaught hooks errors failing1 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -111,9 +112,11 @@ Because this error occurred during a 'before all' hook we are skipping the remai
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
1 of 1 failed (100%) XX:XX 11 5 3 - 3
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['e2e caught and uncaught hooks errors failing2 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -198,9 +201,11 @@ Because this error occurred during a 'before each' hook we are skipping the rema
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
1 of 1 failed (100%) XX:XX 7 4 1 - 2
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['e2e caught and uncaught hooks errors failing3 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -277,9 +282,11 @@ Because this error occurred during a 'before each' hook we are skipping all of t
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
1 of 1 failed (100%) XX:XX 4 - 1 - 3
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['e2e caught and uncaught hooks errors failing4 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -362,5 +369,5 @@ Because this error occurred during a 'before each' hook we are skipping the rema
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
1 of 1 failed (100%) XX:XX 3 2 1 - -
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
@@ -1,4 +1,5 @@
|
||||
exports['e2e commands outside of test fails 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -87,5 +88,5 @@ We dynamically generated a new test to display this failure.
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
1 of 1 failed (100%) XX:XX 1 - 1 - -
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
@@ -1,4 +1,5 @@
|
||||
exports['e2e config passes 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -59,9 +60,11 @@ exports['e2e config passes 1'] = `
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
All specs passed! XX:XX 5 5 - - -
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['e2e config fails 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -143,5 +146,5 @@ exports['e2e config fails 1'] = `
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
1 of 1 failed (100%) XX:XX 1 - 1 - -
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
@@ -1,4 +1,5 @@
|
||||
exports['e2e plugins fails when spec does not exist 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -23,8 +24,6 @@ The error was:
|
||||
|
||||
Error: ENOENT: no such file or directory, stat '/does/not/exist.js'
|
||||
|
||||
|
||||
|
||||
This occurred while Cypress was compiling and bundling your test code. This is usually caused by:
|
||||
|
||||
- A missing file or dependency
|
||||
@@ -64,5 +63,5 @@ Fix the error in your code and re-run your tests.
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
1 of 1 failed (100%) XX:XX - - 1 - -
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
@@ -1,4 +1,5 @@
|
||||
exports['e2e cookies passes 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -60,5 +61,5 @@ exports['e2e cookies passes 1'] = `
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
All specs passed! XX:XX 6 6 - - -
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
241
packages/server/__snapshots__/cypress_spec.coffee.js
Normal file
241
packages/server/__snapshots__/cypress_spec.coffee.js
Normal file
@@ -0,0 +1,241 @@
|
||||
exports['RECORD_PARAMS_WITHOUT_RECORDING-ciBuildId 1'] = `
|
||||
You passed the --ci-build-id, --group, or --parallel flag without also passing the --record flag.
|
||||
|
||||
The --ci-build-id flag you passed was: ciBuildId123
|
||||
|
||||
These flags can only be used when recording to the Cypress Dashboard service.
|
||||
|
||||
https://on.cypress.io/record-params-without-recording
|
||||
`
|
||||
|
||||
exports['INCORRECT_CI_BUILD_ID_USAGE 1'] = `
|
||||
You passed the --ci-build-id flag but did not provide either --group or --parallel.
|
||||
|
||||
The --ci-build-id flag you passed was: ciBuildId123
|
||||
|
||||
The --ci-build-id flag is used to either group or parallelize multiple runs together.
|
||||
|
||||
https://on.cypress.io/incorrect-ci-build-id-usage
|
||||
`
|
||||
|
||||
exports['RECORD_PARAMS_WITHOUT_RECORDING-group 1'] = `
|
||||
You passed the --ci-build-id, --group, or --parallel flag without also passing the --record flag.
|
||||
|
||||
The --group flag you passed was: e2e-tests
|
||||
|
||||
These flags can only be used when recording to the Cypress Dashboard service.
|
||||
|
||||
https://on.cypress.io/record-params-without-recording
|
||||
`
|
||||
|
||||
exports['RECORD_PARAMS_WITHOUT_RECORDING-parallel 1'] = `
|
||||
You passed the --ci-build-id, --group, or --parallel flag without also passing the --record flag.
|
||||
|
||||
The --parallel flag you passed was: true
|
||||
|
||||
These flags can only be used when recording to the Cypress Dashboard service.
|
||||
|
||||
https://on.cypress.io/record-params-without-recording
|
||||
`
|
||||
|
||||
exports['RECORD_PARAMS_WITHOUT_RECORDING-group-parallel 1'] = `
|
||||
You passed the --ci-build-id, --group, or --parallel flag without also passing the --record flag.
|
||||
|
||||
The --group flag you passed was: electron-smoke-tests
|
||||
The --parallel flag you passed was: true
|
||||
|
||||
These flags can only be used when recording to the Cypress Dashboard service.
|
||||
|
||||
https://on.cypress.io/record-params-without-recording
|
||||
`
|
||||
|
||||
exports['INDETERMINATE_CI_BUILD_ID-group 1'] = `
|
||||
You passed the --group or --parallel flag but we could not automatically determine or generate a ciBuildId.
|
||||
|
||||
The --group flag you passed was: e2e-tests
|
||||
|
||||
In order to use either of these parameters a ciBuildId must be determined.
|
||||
|
||||
The ciBuildId is automatically detected if you are running Cypress in any of of the these CI providers:
|
||||
|
||||
- appveyor
|
||||
- bamboo
|
||||
- buildkite
|
||||
- circle
|
||||
- codeship
|
||||
- drone
|
||||
- gitlab
|
||||
- jenkins
|
||||
- semaphore
|
||||
- shippable
|
||||
- snap
|
||||
- teamcity
|
||||
- teamfoundation
|
||||
- travis
|
||||
- wercker
|
||||
|
||||
Because we could not automatically generate this ciBuildId, the --ci-build-id flag must be passed in manually.
|
||||
|
||||
https://on.cypress.io/indeterminate-ci-build-id
|
||||
`
|
||||
|
||||
exports['INDETERMINATE_CI_BUILD_ID-parallel 1'] = `
|
||||
You passed the --group or --parallel flag but we could not automatically determine or generate a ciBuildId.
|
||||
|
||||
The --parallel flag you passed was: true
|
||||
|
||||
In order to use either of these parameters a ciBuildId must be determined.
|
||||
|
||||
The ciBuildId is automatically detected if you are running Cypress in any of of the these CI providers:
|
||||
|
||||
- appveyor
|
||||
- bamboo
|
||||
- buildkite
|
||||
- circle
|
||||
- codeship
|
||||
- drone
|
||||
- gitlab
|
||||
- jenkins
|
||||
- semaphore
|
||||
- shippable
|
||||
- snap
|
||||
- teamcity
|
||||
- teamfoundation
|
||||
- travis
|
||||
- wercker
|
||||
|
||||
Because we could not automatically generate this ciBuildId, the --ci-build-id flag must be passed in manually.
|
||||
|
||||
https://on.cypress.io/indeterminate-ci-build-id
|
||||
`
|
||||
|
||||
exports['INDETERMINATE_CI_BUILD_ID-parallel-group 1'] = `
|
||||
You passed the --group or --parallel flag but we could not automatically determine or generate a ciBuildId.
|
||||
|
||||
The --group flag you passed was: e2e-tests-chrome
|
||||
The --parallel flag you passed was: true
|
||||
|
||||
In order to use either of these parameters a ciBuildId must be determined.
|
||||
|
||||
The ciBuildId is automatically detected if you are running Cypress in any of of the these CI providers:
|
||||
|
||||
- appveyor
|
||||
- bamboo
|
||||
- buildkite
|
||||
- circle
|
||||
- codeship
|
||||
- drone
|
||||
- gitlab
|
||||
- jenkins
|
||||
- semaphore
|
||||
- shippable
|
||||
- snap
|
||||
- teamcity
|
||||
- teamfoundation
|
||||
- travis
|
||||
- wercker
|
||||
|
||||
Because we could not automatically generate this ciBuildId, the --ci-build-id flag must be passed in manually.
|
||||
|
||||
https://on.cypress.io/indeterminate-ci-build-id
|
||||
`
|
||||
|
||||
exports['DASHBOARD_RUN_GROUP_NAME_NOT_UNIQUE 1'] = `
|
||||
You passed the --group flag, but this group name has already been used for this run.
|
||||
|
||||
The existing run is: https://dashboard.cypress.io/runs/12345
|
||||
|
||||
The --group flag you passed was: electron-smoke-tests
|
||||
The --ciBuildId flag you passed was: ciBuildId123
|
||||
|
||||
If you are trying to parallelize this run, then also pass the --parallel flag, else pass a different group name.
|
||||
|
||||
It also looks like you also passed in an explicit --ci-build-id flag.
|
||||
|
||||
This is only necessary if you are NOT running in one of our supported CI providers.
|
||||
|
||||
This flag must be unique for each new run, but must also be identical for each machine you are trying to --group or run in --parallel.
|
||||
|
||||
https://on.cypress.io/run-group-name-not-unique
|
||||
`
|
||||
|
||||
exports['DASHBOARD_PARALLEL_GROUP_PARAMS_MISMATCH 1'] = `
|
||||
You passed the --parallel flag, but this machine is sending different parameters from the first machine that started this parallel run.
|
||||
|
||||
The existing run is: https://dashboard.cypress.io/runs/12345
|
||||
|
||||
In order to run in parallel mode each machine must send the identical parameters such as:
|
||||
|
||||
- specs
|
||||
- osName
|
||||
- osVersion
|
||||
- browserName
|
||||
- browserVersion (major)
|
||||
|
||||
This machine sent the following parameters:
|
||||
|
||||
{
|
||||
"osName": "darwin",
|
||||
"osVersion": "v1",
|
||||
"browserName": "Electron",
|
||||
"browserVersion": "59.1.2.3",
|
||||
"specs": [
|
||||
"cypress/integration/app_spec.js"
|
||||
]
|
||||
}
|
||||
|
||||
https://on.cypress.io/parallel-group-params-mismatch
|
||||
`
|
||||
|
||||
exports['DASHBOARD_PARALLEL_DISALLOWED 1'] = `
|
||||
You passed the --parallel flag, but this run group was originally created without the --parallel flag.
|
||||
|
||||
The existing run is: https://dashboard.cypress.io/runs/12345
|
||||
|
||||
The --group flag you passed was: electron-smoke-tests
|
||||
The --ciBuildId flag you passed was: ciBuildId123
|
||||
|
||||
You can not use the --parallel flag with this group.
|
||||
|
||||
https://on.cypress.io/parallel-disallowed
|
||||
`
|
||||
|
||||
exports['DASHBOARD_PARALLEL_REQUIRED 1'] = `
|
||||
You dot not pass the --parallel flag, but this run group was originally created with the --parallel flag.
|
||||
|
||||
The existing run is: https://dashboard.cypress.io/runs/12345
|
||||
|
||||
The --group flag you passed was: electron-smoke-tests
|
||||
The --ciBuildId flag you passed was: ciBuildId123
|
||||
|
||||
You must use the --parallel flag with this group.
|
||||
|
||||
https://on.cypress.io/parallel-required
|
||||
`
|
||||
|
||||
exports['DASHBOARD_ALREADY_COMPLETE 1'] = `
|
||||
The run you are attempting access is already complete and will not accept new groups.
|
||||
|
||||
The existing run is: https://dashboard.cypress.io/runs/12345
|
||||
|
||||
When a run finishes all of its groups, it waits for a configurable set of time before finally completing. You must add more groups during that time period.
|
||||
|
||||
The --group flag you passed was: electron-smoke-tests
|
||||
The --ciBuildId flag you passed was: ciBuildId123
|
||||
|
||||
https://on.cypress.io/already-complete
|
||||
`
|
||||
|
||||
exports['DASHBOARD_STALE_RUN 1'] = `
|
||||
You are attempting to pass the --parallel flag to a run that was completed over 24 hours ago.
|
||||
|
||||
The existing run is: https://dashboard.cypress.io/runs/12345
|
||||
|
||||
You cannot parallelize a run that has been complete for that long.
|
||||
|
||||
The --group flag you passed was: electron-smoke-tests
|
||||
The --parallel flag you passed was: true
|
||||
The --ciBuildId flag you passed was: ciBuildId123
|
||||
|
||||
https://on.cypress.io/stale-run
|
||||
`
|
||||
@@ -1,4 +1,5 @@
|
||||
exports['e2e domain passing 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -102,5 +103,5 @@ exports['e2e domain passing 1'] = `
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
All specs passed! XX:XX 6 6 - - -
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
@@ -1,4 +1,5 @@
|
||||
exports['e2e form submissions passing 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -56,9 +57,11 @@ exports['e2e form submissions passing 1'] = `
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
All specs passed! XX:XX 2 2 - - -
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['e2e form submissions failing 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -141,5 +144,5 @@ exports['e2e form submissions failing 1'] = `
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
1 of 1 failed (100%) XX:XX 1 - 1 - -
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
@@ -1,4 +1,5 @@
|
||||
exports['e2e go passes 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -56,5 +57,5 @@ exports['e2e go passes 1'] = `
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
All specs passed! XX:XX 2 2 - - -
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
@@ -1,4 +1,5 @@
|
||||
exports['e2e iframes passes 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -62,5 +63,5 @@ exports['e2e iframes passes 1'] = `
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
All specs passed! XX:XX 8 8 - - -
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
@@ -1,4 +1,5 @@
|
||||
exports['e2e images passes 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -56,5 +57,5 @@ exports['e2e images passes 1'] = `
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
All specs passed! XX:XX 2 2 - - -
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
@@ -1,4 +1,5 @@
|
||||
exports['e2e issue 149 failing 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -66,5 +67,5 @@ exports['e2e issue 149 failing 1'] = `
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
1 of 1 failed (100%) XX:XX 2 1 1 - -
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
@@ -1,4 +1,5 @@
|
||||
exports['e2e issue 173 failing 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -79,5 +80,5 @@ exports['e2e issue 173 failing 1'] = `
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
1 of 1 failed (100%) XX:XX 2 1 1 - -
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
@@ -1,4 +1,5 @@
|
||||
exports['e2e issue 674 fails 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -77,5 +78,5 @@ Because this error occurred during a 'after each' hook we are skipping the remai
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
1 of 1 failed (100%) XX:XX 1 - 1 - -
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
@@ -1,4 +1,5 @@
|
||||
exports['e2e js error handling fails 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -143,5 +144,5 @@ https://on.cypress.io/uncaught-exception-from-application
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
1 of 1 failed (100%) XX:XX 8 3 5 - -
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
@@ -1,4 +1,5 @@
|
||||
exports['e2e new project passes 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -52,5 +53,5 @@ exports['e2e new project passes 1'] = `
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
All specs passed! XX:XX 1 1 - - -
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
@@ -1,4 +1,5 @@
|
||||
exports['e2e only spec failing 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -55,5 +56,5 @@ exports['e2e only spec failing 1'] = `
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
All specs passed! XX:XX 1 1 - - -
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
@@ -1,4 +1,5 @@
|
||||
exports['e2e page_loading passes 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -57,5 +58,5 @@ exports['e2e page_loading passes 1'] = `
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
All specs passed! XX:XX 2 2 - - -
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
@@ -1,4 +1,5 @@
|
||||
exports['e2e plugins fails 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -32,7 +33,6 @@ Error: Async error from plugins file
|
||||
at stack trace line
|
||||
at stack trace line
|
||||
at stack trace line
|
||||
at stack trace line
|
||||
|
||||
|
||||
(Results)
|
||||
@@ -67,9 +67,11 @@ Error: Async error from plugins file
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
1 of 1 failed (100%) XX:XX - - 1 - -
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['e2e plugins passes 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -125,9 +127,11 @@ exports['e2e plugins passes 1'] = `
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
All specs passed! XX:XX 2 2 - - -
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['e2e plugins can modify config from plugins 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -183,9 +187,11 @@ exports['e2e plugins can modify config from plugins 1'] = `
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
All specs passed! XX:XX 2 2 - - -
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['e2e plugins works with user extensions 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -240,9 +246,11 @@ A video will not be recorded when using this browser.
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
All specs passed! XX:XX 1 1 - - -
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['e2e plugins handles absolute path to pluginsFile 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -297,9 +305,11 @@ exports['e2e plugins handles absolute path to pluginsFile 1'] = `
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
All specs passed! XX:XX 1 1 - - -
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['e2e plugins calls after:screenshot for cy.screenshot() and failure screenshots 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -372,5 +382,5 @@ exports['e2e plugins calls after:screenshot for cy.screenshot() and failure scre
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
1 of 1 failed (100%) XX:XX 4 3 1 - -
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
@@ -1,4 +1,5 @@
|
||||
exports['e2e promises failing1 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -72,5 +73,5 @@ exports['e2e promises failing1 1'] = `
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
1 of 1 failed (100%) XX:XX 2 - 2 - -
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
@@ -1,4 +1,5 @@
|
||||
exports['e2e record passing passes 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -8,6 +9,7 @@ exports['e2e record passing passes 1'] = `
|
||||
│ Browser: FooBrowser 88 │
|
||||
│ Specs: 4 found (record_error_spec.coffee, record_fail_spec.coffee, record_pass_spec.coff… │
|
||||
│ Searched: cypress/integration/record* │
|
||||
│ Params: Group: false, Parallel: false │
|
||||
│ Run URL: https://dashboard.cypress.io/#/projects/cjvoj7/runs/12 │
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
|
||||
@@ -15,6 +17,7 @@ exports['e2e record passing passes 1'] = `
|
||||
────────────────────────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
Running: record_error_spec.coffee... (1 of 4)
|
||||
Estimated: 8 seconds
|
||||
|
||||
Oops...we found an error preparing this test file:
|
||||
|
||||
@@ -24,7 +27,6 @@ The error was:
|
||||
|
||||
Error: Cannot find module '../it/does/not/exist' from '/foo/bar/.projects/e2e/cypress/integration'
|
||||
|
||||
|
||||
This occurred while Cypress was compiling and bundling your test code. This is usually caused by:
|
||||
|
||||
- A missing file or dependency
|
||||
@@ -43,6 +45,7 @@ Fix the error in your code and re-run your tests.
|
||||
│ Screenshots: 0 │
|
||||
│ Video: true │
|
||||
│ Duration: X seconds │
|
||||
│ Estimated: 8 seconds │
|
||||
│ Spec Ran: record_error_spec.coffee │
|
||||
└────────────────────────────────────────┘
|
||||
|
||||
@@ -60,6 +63,7 @@ Fix the error in your code and re-run your tests.
|
||||
────────────────────────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
Running: record_fail_spec.coffee... (2 of 4)
|
||||
Estimated: 8 seconds
|
||||
|
||||
|
||||
record fails
|
||||
@@ -89,6 +93,7 @@ Because this error occurred during a 'before each' hook we are skipping the rema
|
||||
│ Screenshots: 1 │
|
||||
│ Video: true │
|
||||
│ Duration: X seconds │
|
||||
│ Estimated: 8 seconds │
|
||||
│ Spec Ran: record_fail_spec.coffee │
|
||||
└───────────────────────────────────────┘
|
||||
|
||||
@@ -112,6 +117,7 @@ Because this error occurred during a 'before each' hook we are skipping the rema
|
||||
────────────────────────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
Running: record_pass_spec.coffee... (3 of 4)
|
||||
Estimated: 8 seconds
|
||||
|
||||
|
||||
record pass
|
||||
@@ -134,6 +140,7 @@ Because this error occurred during a 'before each' hook we are skipping the rema
|
||||
│ Screenshots: 1 │
|
||||
│ Video: true │
|
||||
│ Duration: X seconds │
|
||||
│ Estimated: 8 seconds │
|
||||
│ Spec Ran: record_pass_spec.coffee │
|
||||
└───────────────────────────────────────┘
|
||||
|
||||
@@ -150,6 +157,7 @@ Because this error occurred during a 'before each' hook we are skipping the rema
|
||||
────────────────────────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
Running: record_uncaught_spec.coffee... (4 of 4)
|
||||
Estimated: 8 seconds
|
||||
|
||||
|
||||
1) An uncaught error was detected outside of a test
|
||||
@@ -186,6 +194,7 @@ We dynamically generated a new test to display this failure.
|
||||
│ Screenshots: 1 │
|
||||
│ Video: true │
|
||||
│ Duration: X seconds │
|
||||
│ Estimated: 8 seconds │
|
||||
│ Spec Ran: record_uncaught_spec.coffee │
|
||||
└───────────────────────────────────────────┘
|
||||
|
||||
@@ -228,20 +237,11 @@ We dynamically generated a new test to display this failure.
|
||||
|
||||
Recorded Run: https://dashboard.cypress.io/#/projects/cjvoj7/runs/12
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['e2e record api interaction errors recordKey and projectId errors and exits 1'] = `We failed trying to authenticate this project: pid123
|
||||
|
||||
Your Record Key is invalid: f858a...ee7e1
|
||||
|
||||
It may have been recently revoked by you or another user.
|
||||
|
||||
Please log into the Dashboard to see the updated token.
|
||||
|
||||
https://on.cypress.io/dashboard/projects/pid123
|
||||
`
|
||||
|
||||
exports['e2e record api interaction errors project 404 errors and exits 1'] = `We could not find a project with the ID: pid123
|
||||
exports['e2e record api interaction errors project 404 errors and exits 1'] = `
|
||||
We could not find a project with the ID: pid123
|
||||
|
||||
This projectId came from your cypress.json file or an environment variable.
|
||||
|
||||
@@ -252,9 +252,11 @@ We will list the correct projectId in the 'Settings' tab.
|
||||
Alternatively, you can create a new project using the Desktop Application.
|
||||
|
||||
https://on.cypress.io/dashboard
|
||||
|
||||
`
|
||||
|
||||
exports['e2e record api interaction errors create run warns and does not create or update instances 1'] = `Warning: We encountered an error talking to our servers.
|
||||
exports['e2e record api interaction errors create run 500 warns and does not create or update instances 1'] = `
|
||||
Warning: We encountered an error talking to our servers.
|
||||
|
||||
This run will not be recorded.
|
||||
|
||||
@@ -319,9 +321,11 @@ StatusCodeError: 500 - "Internal Server Error"
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
All specs passed! XX:XX 2 1 - 1 -
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['e2e record api interaction errors create instance does not update instance 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -331,6 +335,7 @@ exports['e2e record api interaction errors create instance does not update insta
|
||||
│ Browser: FooBrowser 88 │
|
||||
│ Specs: 1 found (record_pass_spec.coffee) │
|
||||
│ Searched: cypress/integration/record_pass* │
|
||||
│ Params: Group: false, Parallel: false │
|
||||
│ Run URL: https://dashboard.cypress.io/#/projects/cjvoj7/runs/12 │
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
|
||||
@@ -392,9 +397,11 @@ StatusCodeError: 500 - "Internal Server Error"
|
||||
|
||||
Recorded Run: https://dashboard.cypress.io/#/projects/cjvoj7/runs/12
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['e2e record api interaction errors update instance does not update instance stdout 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -404,6 +411,7 @@ exports['e2e record api interaction errors update instance does not update insta
|
||||
│ Browser: FooBrowser 88 │
|
||||
│ Specs: 1 found (record_pass_spec.coffee) │
|
||||
│ Searched: cypress/integration/record_pass* │
|
||||
│ Params: Group: false, Parallel: false │
|
||||
│ Run URL: https://dashboard.cypress.io/#/projects/cjvoj7/runs/12 │
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
|
||||
@@ -411,6 +419,7 @@ exports['e2e record api interaction errors update instance does not update insta
|
||||
────────────────────────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
Running: record_pass_spec.coffee... (1 of 1)
|
||||
Estimated: 8 seconds
|
||||
|
||||
|
||||
record pass
|
||||
@@ -433,6 +442,7 @@ exports['e2e record api interaction errors update instance does not update insta
|
||||
│ Screenshots: 1 │
|
||||
│ Video: true │
|
||||
│ Duration: X seconds │
|
||||
│ Estimated: 8 seconds │
|
||||
│ Spec Ran: record_pass_spec.coffee │
|
||||
└───────────────────────────────────────┘
|
||||
|
||||
@@ -468,9 +478,11 @@ StatusCodeError: 500 - "Internal Server Error"
|
||||
|
||||
Recorded Run: https://dashboard.cypress.io/#/projects/cjvoj7/runs/12
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['e2e record api interaction errors update instance stdout warns but proceeds 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -480,6 +492,7 @@ exports['e2e record api interaction errors update instance stdout warns but proc
|
||||
│ Browser: FooBrowser 88 │
|
||||
│ Specs: 1 found (record_pass_spec.coffee) │
|
||||
│ Searched: cypress/integration/record_pass* │
|
||||
│ Params: Group: false, Parallel: false │
|
||||
│ Run URL: https://dashboard.cypress.io/#/projects/cjvoj7/runs/12 │
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
|
||||
@@ -487,6 +500,7 @@ exports['e2e record api interaction errors update instance stdout warns but proc
|
||||
────────────────────────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
Running: record_pass_spec.coffee... (1 of 1)
|
||||
Estimated: 8 seconds
|
||||
|
||||
|
||||
record pass
|
||||
@@ -509,6 +523,7 @@ exports['e2e record api interaction errors update instance stdout warns but proc
|
||||
│ Screenshots: 1 │
|
||||
│ Video: true │
|
||||
│ Duration: X seconds │
|
||||
│ Estimated: 8 seconds │
|
||||
│ Spec Ran: record_pass_spec.coffee │
|
||||
└───────────────────────────────────────┘
|
||||
|
||||
@@ -545,22 +560,11 @@ StatusCodeError: 500 - "Internal Server Error"
|
||||
|
||||
Recorded Run: https://dashboard.cypress.io/#/projects/cjvoj7/runs/12
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['e2e record failing errors and exits without projectId 1'] = `You passed the --record flag but this project has not been setup to record.
|
||||
|
||||
This project is missing the 'projectId' inside of 'cypress.json'.
|
||||
|
||||
We cannot uniquely identify this project without this id.
|
||||
|
||||
You need to setup this project to record. This will generate a unique 'projectId'.
|
||||
|
||||
Alternatively if you omit the --record flag this project will run without recording.
|
||||
|
||||
https://on.cypress.io/recording-project-runs
|
||||
`
|
||||
|
||||
exports['e2e record recordKey errors and exits without recordKey 1'] = `You passed the --record flag but did not provide us your Record Key.
|
||||
exports['e2e record recordKey errors and exits without recordKey 1'] = `
|
||||
You passed the --record flag but did not provide us your Record Key.
|
||||
|
||||
You can pass us your Record Key like this:
|
||||
|
||||
@@ -569,9 +573,11 @@ You can pass us your Record Key like this:
|
||||
You can also set the key as an environment variable with the name CYPRESS_RECORD_KEY.
|
||||
|
||||
https://on.cypress.io/how-do-i-record-runs
|
||||
|
||||
`
|
||||
|
||||
exports['e2e record projectId errors and exits without projectId 1'] = `You passed the --record flag but this project has not been setup to record.
|
||||
exports['e2e record projectId errors and exits without projectId 1'] = `
|
||||
You passed the --record flag but this project has not been setup to record.
|
||||
|
||||
This project is missing the 'projectId' inside of 'cypress.json'.
|
||||
|
||||
@@ -582,9 +588,11 @@ You need to setup this project to record. This will generate a unique 'projectId
|
||||
Alternatively if you omit the --record flag this project will run without recording.
|
||||
|
||||
https://on.cypress.io/recording-project-runs
|
||||
|
||||
`
|
||||
|
||||
exports['e2e record api interaction errors recordKey and projectId errors and exits on 401 1'] = `We failed trying to authenticate this project: pid123
|
||||
exports['e2e record api interaction errors recordKey and projectId errors and exits on 401 1'] = `
|
||||
We failed trying to authenticate this project: pid123
|
||||
|
||||
Your Record Key is invalid: f858a...ee7e1
|
||||
|
||||
@@ -593,9 +601,11 @@ It may have been recently revoked by you or another user.
|
||||
Please log into the Dashboard to see the updated token.
|
||||
|
||||
https://on.cypress.io/dashboard/projects/pid123
|
||||
|
||||
`
|
||||
|
||||
exports['e2e record video recording does not upload when not enabled 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -605,6 +615,7 @@ exports['e2e record video recording does not upload when not enabled 1'] = `
|
||||
│ Browser: FooBrowser 88 │
|
||||
│ Specs: 1 found (record_pass_spec.coffee) │
|
||||
│ Searched: cypress/integration/record_pass* │
|
||||
│ Params: Group: false, Parallel: false │
|
||||
│ Run URL: https://dashboard.cypress.io/#/projects/cjvoj7/runs/12 │
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
|
||||
@@ -612,6 +623,7 @@ exports['e2e record video recording does not upload when not enabled 1'] = `
|
||||
────────────────────────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
Running: record_pass_spec.coffee... (1 of 1)
|
||||
Estimated: 8 seconds
|
||||
|
||||
|
||||
record pass
|
||||
@@ -634,6 +646,7 @@ exports['e2e record video recording does not upload when not enabled 1'] = `
|
||||
│ Screenshots: 1 │
|
||||
│ Video: false │
|
||||
│ Duration: X seconds │
|
||||
│ Estimated: 8 seconds │
|
||||
│ Spec Ran: record_pass_spec.coffee │
|
||||
└───────────────────────────────────────┘
|
||||
|
||||
@@ -663,9 +676,11 @@ exports['e2e record video recording does not upload when not enabled 1'] = `
|
||||
|
||||
Recorded Run: https://dashboard.cypress.io/#/projects/cjvoj7/runs/12
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['e2e record api interaction errors uploading assets warns but proceeds 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -675,6 +690,7 @@ exports['e2e record api interaction errors uploading assets warns but proceeds 1
|
||||
│ Browser: FooBrowser 88 │
|
||||
│ Specs: 1 found (record_pass_spec.coffee) │
|
||||
│ Searched: cypress/integration/record_pass* │
|
||||
│ Params: Group: false, Parallel: false │
|
||||
│ Run URL: https://dashboard.cypress.io/#/projects/cjvoj7/runs/12 │
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
|
||||
@@ -682,6 +698,7 @@ exports['e2e record api interaction errors uploading assets warns but proceeds 1
|
||||
────────────────────────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
Running: record_pass_spec.coffee... (1 of 1)
|
||||
Estimated: 8 seconds
|
||||
|
||||
|
||||
record pass
|
||||
@@ -704,6 +721,7 @@ exports['e2e record api interaction errors uploading assets warns but proceeds 1
|
||||
│ Screenshots: 1 │
|
||||
│ Video: true │
|
||||
│ Duration: X seconds │
|
||||
│ Estimated: 8 seconds │
|
||||
│ Spec Ran: record_pass_spec.coffee │
|
||||
└───────────────────────────────────────┘
|
||||
|
||||
@@ -740,23 +758,29 @@ exports['e2e record api interaction errors uploading assets warns but proceeds 1
|
||||
|
||||
Recorded Run: https://dashboard.cypress.io/#/projects/cjvoj7/runs/12
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['e2e record misconfiguration errors and exits when no browser found 1'] = `Can't run because you've entered an invalid browser.
|
||||
exports['e2e record misconfiguration errors and exits when no browser found 1'] = `
|
||||
Can't run because you've entered an invalid browser.
|
||||
|
||||
Browser: 'browserDoesNotExist' was not found on your system.
|
||||
|
||||
Available browsers found are: browser1, browser2, browser3
|
||||
|
||||
`
|
||||
|
||||
exports['e2e record misconfiguration errors and exits when no specs found 1'] = `Can't run because no spec files were found.
|
||||
exports['e2e record misconfiguration errors and exits when no specs found 1'] = `
|
||||
Can't run because no spec files were found.
|
||||
|
||||
We searched for any files matching this glob pattern:
|
||||
|
||||
cypress/integration/notfound/**
|
||||
|
||||
`
|
||||
|
||||
exports['e2e record recordKey warns but does not exit when is forked pr 1'] = `Warning: It looks like you are trying to record this run from a forked PR.
|
||||
exports['e2e record recordKey warns but does not exit when is forked pr 1'] = `
|
||||
Warning: It looks like you are trying to record this run from a forked PR.
|
||||
|
||||
The 'Record Key' is missing. Your CI provider is likely not passing private environment variables to builds from forks.
|
||||
|
||||
@@ -821,5 +845,491 @@ This error will not alter the exit code.
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
All specs passed! XX:XX 2 1 - 1 -
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['e2e record parallelization passes in parallel with group 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
|
||||
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Cypress: 1.2.3 │
|
||||
│ Browser: FooBrowser 88 │
|
||||
│ Specs: 4 found (record_error_spec.coffee, record_fail_spec.coffee, record_pass_spec.coff… │
|
||||
│ Searched: cypress/integration/record* │
|
||||
│ Params: Group: prod-e2e, Parallel: true │
|
||||
│ Run URL: https://dashboard.cypress.io/#/projects/cjvoj7/runs/12 │
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
|
||||
|
||||
────────────────────────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
Running: record_pass_spec.coffee... (1 of 4)
|
||||
Estimated: 1 second
|
||||
|
||||
|
||||
record pass
|
||||
✓ passes
|
||||
- is pending
|
||||
|
||||
|
||||
1 passing
|
||||
1 pending
|
||||
|
||||
|
||||
(Results)
|
||||
|
||||
┌───────────────────────────────────────┐
|
||||
│ Tests: 2 │
|
||||
│ Passing: 1 │
|
||||
│ Failing: 0 │
|
||||
│ Pending: 1 │
|
||||
│ Skipped: 0 │
|
||||
│ Screenshots: 1 │
|
||||
│ Video: true │
|
||||
│ Duration: X seconds │
|
||||
│ Estimated: 1 second │
|
||||
│ Spec Ran: record_pass_spec.coffee │
|
||||
└───────────────────────────────────────┘
|
||||
|
||||
|
||||
(Screenshots)
|
||||
|
||||
- /foo/bar/.projects/e2e/cypress/screenshots/record_pass_spec.coffee/yay it passes.png (202x1002)
|
||||
|
||||
|
||||
(Uploading Results)
|
||||
|
||||
- Done Uploading (1/1) /foo/bar/.projects/e2e/cypress/screenshots/record_pass_spec.coffee/yay it passes.png
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Finished)
|
||||
|
||||
|
||||
Spec Tests Passing Failing Pending Skipped
|
||||
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ ✔ record_pass_spec.coffee XX:XX 2 1 - 1 - │
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
All specs passed! XX:XX 2 1 - 1 -
|
||||
|
||||
|
||||
───────────────────────────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
Recorded Run: https://dashboard.cypress.io/#/projects/cjvoj7/runs/12
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['e2e record parallelization passes in parallel with group 2'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
|
||||
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Cypress: 1.2.3 │
|
||||
│ Browser: FooBrowser 88 │
|
||||
│ Specs: 4 found (record_error_spec.coffee, record_fail_spec.coffee, record_pass_spec.coff… │
|
||||
│ Searched: cypress/integration/record* │
|
||||
│ Params: Group: prod-e2e, Parallel: true │
|
||||
│ Run URL: https://dashboard.cypress.io/#/projects/cjvoj7/runs/12 │
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
|
||||
|
||||
────────────────────────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
Running: record_error_spec.coffee... (2 of 4)
|
||||
Estimated: 1 second
|
||||
|
||||
Oops...we found an error preparing this test file:
|
||||
|
||||
/foo/bar/.projects/e2e/cypress/integration/record_error_spec.coffee
|
||||
|
||||
The error was:
|
||||
|
||||
Error: Cannot find module '../it/does/not/exist' from '/foo/bar/.projects/e2e/cypress/integration'
|
||||
|
||||
This occurred while Cypress was compiling and bundling your test code. This is usually caused by:
|
||||
|
||||
- A missing file or dependency
|
||||
- A syntax error in the file or one of its dependencies
|
||||
|
||||
Fix the error in your code and re-run your tests.
|
||||
|
||||
(Results)
|
||||
|
||||
┌────────────────────────────────────────┐
|
||||
│ Tests: 0 │
|
||||
│ Passing: 0 │
|
||||
│ Failing: 1 │
|
||||
│ Pending: 0 │
|
||||
│ Skipped: 0 │
|
||||
│ Screenshots: 0 │
|
||||
│ Video: true │
|
||||
│ Duration: X seconds │
|
||||
│ Estimated: 1 second │
|
||||
│ Spec Ran: record_error_spec.coffee │
|
||||
└────────────────────────────────────────┘
|
||||
|
||||
|
||||
(Video)
|
||||
|
||||
- Started processing: Compressing to 32 CRF
|
||||
- Finished processing: /foo/bar/.projects/e2e/cypress/videos/abc123.mp4 (X seconds)
|
||||
|
||||
|
||||
(Uploading Results)
|
||||
|
||||
- Done Uploading (1/1) /foo/bar/.projects/e2e/cypress/videos/abc123.mp4
|
||||
|
||||
────────────────────────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
Running: record_fail_spec.coffee... (3 of 4)
|
||||
Estimated: 2 seconds
|
||||
|
||||
|
||||
record fails
|
||||
1) "before each" hook for "fails 1"
|
||||
|
||||
|
||||
0 passing
|
||||
1 failing
|
||||
|
||||
1) record fails "before each" hook for "fails 1":
|
||||
Error: foo
|
||||
|
||||
Because this error occurred during a 'before each' hook we are skipping the remaining tests in the current suite: 'record fails'
|
||||
at stack trace line
|
||||
|
||||
|
||||
|
||||
|
||||
(Results)
|
||||
|
||||
┌───────────────────────────────────────┐
|
||||
│ Tests: 2 │
|
||||
│ Passing: 0 │
|
||||
│ Failing: 1 │
|
||||
│ Pending: 0 │
|
||||
│ Skipped: 1 │
|
||||
│ Screenshots: 1 │
|
||||
│ Video: true │
|
||||
│ Duration: X seconds │
|
||||
│ Estimated: 2 seconds │
|
||||
│ Spec Ran: record_fail_spec.coffee │
|
||||
└───────────────────────────────────────┘
|
||||
|
||||
|
||||
(Screenshots)
|
||||
|
||||
- /foo/bar/.projects/e2e/cypress/screenshots/record_fail_spec.coffee/record fails -- fails 1 -- before each hook (failed).png (1280x720)
|
||||
|
||||
|
||||
(Video)
|
||||
|
||||
- Started processing: Compressing to 32 CRF
|
||||
- Finished processing: /foo/bar/.projects/e2e/cypress/videos/abc123.mp4 (X seconds)
|
||||
|
||||
|
||||
(Uploading Results)
|
||||
|
||||
- Done Uploading (1/2) /foo/bar/.projects/e2e/cypress/screenshots/record_fail_spec.coffee/record fails -- fails 1 -- before each hook (failed).png
|
||||
- Done Uploading (2/2) /foo/bar/.projects/e2e/cypress/videos/abc123.mp4
|
||||
|
||||
────────────────────────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
Running: record_uncaught_spec.coffee... (4 of 4)
|
||||
Estimated: 3 seconds
|
||||
|
||||
|
||||
1) An uncaught error was detected outside of a test
|
||||
|
||||
0 passing
|
||||
1 failing
|
||||
|
||||
1) An uncaught error was detected outside of a test:
|
||||
Uncaught Error: instantly fails
|
||||
|
||||
This error originated from your test code, not from Cypress.
|
||||
|
||||
When Cypress detects uncaught errors originating from your test code it will automatically fail the current test.
|
||||
|
||||
Cypress could not associate this error to any specific test.
|
||||
|
||||
We dynamically generated a new test to display this failure.
|
||||
at stack trace line
|
||||
at stack trace line
|
||||
at stack trace line
|
||||
at stack trace line
|
||||
|
||||
|
||||
|
||||
|
||||
(Results)
|
||||
|
||||
┌───────────────────────────────────────────┐
|
||||
│ Tests: 1 │
|
||||
│ Passing: 0 │
|
||||
│ Failing: 1 │
|
||||
│ Pending: 0 │
|
||||
│ Skipped: 0 │
|
||||
│ Screenshots: 1 │
|
||||
│ Video: true │
|
||||
│ Duration: X seconds │
|
||||
│ Estimated: 3 seconds │
|
||||
│ Spec Ran: record_uncaught_spec.coffee │
|
||||
└───────────────────────────────────────────┘
|
||||
|
||||
|
||||
(Screenshots)
|
||||
|
||||
- /foo/bar/.projects/e2e/cypress/screenshots/record_uncaught_spec.coffee/An uncaught error was detected outside of a test (failed).png (1280x720)
|
||||
|
||||
|
||||
(Video)
|
||||
|
||||
- Started processing: Compressing to 32 CRF
|
||||
- Finished processing: /foo/bar/.projects/e2e/cypress/videos/abc123.mp4 (X seconds)
|
||||
|
||||
|
||||
(Uploading Results)
|
||||
|
||||
- Done Uploading (1/2) /foo/bar/.projects/e2e/cypress/screenshots/record_uncaught_spec.coffee/An uncaught error was detected outside of a test (failed).png
|
||||
- Done Uploading (2/2) /foo/bar/.projects/e2e/cypress/videos/abc123.mp4
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Finished)
|
||||
|
||||
|
||||
Spec Tests Passing Failing Pending Skipped
|
||||
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ ✖ record_error_spec.coffee XX:XX - - 1 - - │
|
||||
├────────────────────────────────────────────────────────────────────────────────────────────────┤
|
||||
│ ✖ record_fail_spec.coffee XX:XX 2 - 1 - 1 │
|
||||
├────────────────────────────────────────────────────────────────────────────────────────────────┤
|
||||
│ ✖ record_uncaught_spec.coffee XX:XX 1 - 1 - - │
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
3 of 3 failed (100%) XX:XX 3 - 3 - 1
|
||||
|
||||
|
||||
───────────────────────────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
Recorded Run: https://dashboard.cypress.io/#/projects/cjvoj7/runs/12
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['e2e record api interaction errors create run 422 errors and exits when group name is in use 1'] = `
|
||||
You passed the --group flag, but this group name has already been used for this run.
|
||||
|
||||
The existing run is: https://dashboard.cypress.io/runs/12345
|
||||
|
||||
The --group flag you passed was: e2e-tests
|
||||
|
||||
If you are trying to parallelize this run, then also pass the --parallel flag, else pass a different group name.
|
||||
|
||||
https://on.cypress.io/run-group-name-not-unique
|
||||
|
||||
`
|
||||
|
||||
exports['e2e record api interaction errors create run unknown 422 errors and exits when there is an unknown 422 response 1'] = `
|
||||
We encountered an unexpected error talking to our servers.
|
||||
|
||||
There is likely something wrong with the request.
|
||||
|
||||
The --group flag you passed was: e2e-tests
|
||||
The --parallel flag you passed was: true
|
||||
The --ciBuildId flag you passed was: ciBuildId123
|
||||
|
||||
The server's response was:
|
||||
|
||||
StatusCodeError: 422
|
||||
|
||||
{
|
||||
"code": "SOMETHING_UNKNOWN",
|
||||
"message": "An unknown message here from the server."
|
||||
}
|
||||
|
||||
`
|
||||
|
||||
exports['e2e record api interaction errors create run 500 warns but proceeds when grouping without parallelization 1'] = `
|
||||
Warning: We encountered an error talking to our servers.
|
||||
|
||||
This run will not be recorded.
|
||||
|
||||
This error will not alter the exit code.
|
||||
|
||||
StatusCodeError: 500 - "Internal Server Error"
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
|
||||
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Cypress: 1.2.3 │
|
||||
│ Browser: FooBrowser 88 │
|
||||
│ Specs: 1 found (record_pass_spec.coffee) │
|
||||
│ Searched: cypress/integration/record_pass* │
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
|
||||
|
||||
────────────────────────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
Running: record_pass_spec.coffee... (1 of 1)
|
||||
|
||||
|
||||
record pass
|
||||
✓ passes
|
||||
- is pending
|
||||
|
||||
|
||||
1 passing
|
||||
1 pending
|
||||
|
||||
|
||||
(Results)
|
||||
|
||||
┌───────────────────────────────────────┐
|
||||
│ Tests: 2 │
|
||||
│ Passing: 1 │
|
||||
│ Failing: 0 │
|
||||
│ Pending: 1 │
|
||||
│ Skipped: 0 │
|
||||
│ Screenshots: 1 │
|
||||
│ Video: true │
|
||||
│ Duration: X seconds │
|
||||
│ Spec Ran: record_pass_spec.coffee │
|
||||
└───────────────────────────────────────┘
|
||||
|
||||
|
||||
(Screenshots)
|
||||
|
||||
- /foo/bar/.projects/e2e/cypress/screenshots/record_pass_spec.coffee/yay it passes.png (202x1002)
|
||||
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Finished)
|
||||
|
||||
|
||||
Spec Tests Passing Failing Pending Skipped
|
||||
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ ✔ record_pass_spec.coffee XX:XX 2 1 - 1 - │
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
All specs passed! XX:XX 2 1 - 1 -
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['e2e record api interaction errors create run 500 does not proceed and exits with error when parallelizing 1'] = `
|
||||
We encountered an unexpected error talking to our servers.
|
||||
|
||||
Because you passed the --parallel flag, this run cannot proceed because it requires a valid response from our servers.
|
||||
|
||||
The --group flag you passed was: foo
|
||||
The --ciBuildId flag you passed was: ciBuildId123
|
||||
|
||||
The server's response was:
|
||||
|
||||
StatusCodeError: 500 - "Internal Server Error"
|
||||
|
||||
`
|
||||
|
||||
exports['e2e record api interaction errors create instance 500 does not proceed and exits with error when parallelizing and creating instance 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
|
||||
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Cypress: 1.2.3 │
|
||||
│ Browser: FooBrowser 88 │
|
||||
│ Specs: 1 found (record_pass_spec.coffee) │
|
||||
│ Searched: cypress/integration/record_pass* │
|
||||
│ Params: Group: foo, Parallel: true │
|
||||
│ Run URL: https://dashboard.cypress.io/#/projects/cjvoj7/runs/12 │
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
|
||||
We encountered an unexpected error talking to our servers.
|
||||
|
||||
Because you passed the --parallel flag, this run cannot proceed because it requires a valid response from our servers.
|
||||
|
||||
The --group flag you passed was: foo
|
||||
The --ciBuildId flag you passed was: ciBuildId123
|
||||
|
||||
The server's response was:
|
||||
|
||||
StatusCodeError: 500 - "Internal Server Error"
|
||||
|
||||
`
|
||||
|
||||
exports['e2e record api interaction errors update instance 500 does not proceed and exits with error when parallelizing and updating instance 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
|
||||
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Cypress: 1.2.3 │
|
||||
│ Browser: FooBrowser 88 │
|
||||
│ Specs: 1 found (record_pass_spec.coffee) │
|
||||
│ Searched: cypress/integration/record_pass* │
|
||||
│ Params: Group: foo, Parallel: true │
|
||||
│ Run URL: https://dashboard.cypress.io/#/projects/cjvoj7/runs/12 │
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
|
||||
|
||||
────────────────────────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
Running: record_pass_spec.coffee... (1 of 1)
|
||||
Estimated: 5 seconds
|
||||
|
||||
|
||||
record pass
|
||||
✓ passes
|
||||
- is pending
|
||||
|
||||
|
||||
1 passing
|
||||
1 pending
|
||||
|
||||
|
||||
(Results)
|
||||
|
||||
┌───────────────────────────────────────┐
|
||||
│ Tests: 2 │
|
||||
│ Passing: 1 │
|
||||
│ Failing: 0 │
|
||||
│ Pending: 1 │
|
||||
│ Skipped: 0 │
|
||||
│ Screenshots: 1 │
|
||||
│ Video: true │
|
||||
│ Duration: X seconds │
|
||||
│ Estimated: 5 seconds │
|
||||
│ Spec Ran: record_pass_spec.coffee │
|
||||
└───────────────────────────────────────┘
|
||||
|
||||
|
||||
(Screenshots)
|
||||
|
||||
- /foo/bar/.projects/e2e/cypress/screenshots/record_pass_spec.coffee/yay it passes.png (202x1002)
|
||||
|
||||
|
||||
(Uploading Results)
|
||||
|
||||
We encountered an unexpected error talking to our servers.
|
||||
|
||||
Because you passed the --parallel flag, this run cannot proceed because it requires a valid response from our servers.
|
||||
|
||||
The --group flag you passed was: foo
|
||||
The --ciBuildId flag you passed was: ciBuildId123
|
||||
|
||||
The server's response was:
|
||||
|
||||
StatusCodeError: 500 - "Internal Server Error"
|
||||
|
||||
`
|
||||
@@ -1,4 +1,5 @@
|
||||
exports['e2e reporters reports error if cannot load reporter 1'] = `Could not load reporter by name: module-does-not-exist
|
||||
exports['e2e reporters reports error if cannot load reporter 1'] = `
|
||||
Could not load reporter by name: module-does-not-exist
|
||||
|
||||
We searched for the reporter in these paths:
|
||||
|
||||
@@ -10,9 +11,11 @@ The error we received was:
|
||||
Cannot find module '/foo/bar/.projects/e2e/node_modules/module-does-not-exist'
|
||||
|
||||
Learn more at stack trace line
|
||||
|
||||
`
|
||||
|
||||
exports['e2e reporters supports junit reporter and reporter options 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -61,9 +64,11 @@ exports['e2e reporters supports junit reporter and reporter options 1'] = `
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
All specs passed! XX:XX 1 1 - - -
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['e2e reporters supports local custom reporter 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -114,9 +119,11 @@ finished!
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
All specs passed! XX:XX 1 1 - - -
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['e2e reporters mochawesome passes with mochawesome@1.5.2 npm custom reporter 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -179,9 +186,11 @@ exports['e2e reporters mochawesome passes with mochawesome@1.5.2 npm custom repo
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
All specs passed! XX:XX 1 1 - - -
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['e2e reporters mochawesome fails with mochawesome@1.5.2 npm custom reporter 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -289,9 +298,11 @@ Because this error occurred during a 'after all' hook we are skipping the remain
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
1 of 1 failed (100%) XX:XX 6 1 3 1 1
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['e2e reporters mochawesome passes with mochawesome@2.3.1 npm custom reporter 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -352,9 +363,11 @@ exports['e2e reporters mochawesome passes with mochawesome@2.3.1 npm custom repo
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
All specs passed! XX:XX 1 1 - - -
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['e2e reporters mochawesome fails with mochawesome@2.3.1 npm custom reporter 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -460,9 +473,11 @@ Because this error occurred during a 'after all' hook we are skipping the remain
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
1 of 1 failed (100%) XX:XX 6 1 3 1 1
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['e2e reporters mochawesome passes with mochawesome@3.0.1 npm custom reporter 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -523,9 +538,11 @@ exports['e2e reporters mochawesome passes with mochawesome@3.0.1 npm custom repo
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
All specs passed! XX:XX 1 1 - - -
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['e2e reporters mochawesome fails with mochawesome@3.0.1 npm custom reporter 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -631,9 +648,11 @@ Because this error occurred during a 'after all' hook we are skipping the remain
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
1 of 1 failed (100%) XX:XX 6 1 3 1 1
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['e2e reporters reports error when thrown from reporter 1'] = `Could not load reporter by name: reporters/throws.js
|
||||
exports['e2e reporters reports error when thrown from reporter 1'] = `
|
||||
Could not load reporter by name: reporters/throws.js
|
||||
|
||||
We searched for the reporter in these paths:
|
||||
|
||||
@@ -675,7 +694,6 @@ Error: this reporter threw an error
|
||||
at stack trace line
|
||||
at stack trace line
|
||||
|
||||
|
||||
Learn more at stack trace line
|
||||
`
|
||||
|
||||
`
|
||||
@@ -1,4 +1,5 @@
|
||||
exports['e2e requests passes 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -66,9 +67,11 @@ exports['e2e requests passes 1'] = `
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
All specs passed! XX:XX 12 12 - - -
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['e2e requests fails when network immediately fails 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -194,9 +197,11 @@ RequestError: Error: connect ECONNREFUSED 127.0.0.1:16795
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
1 of 1 failed (100%) XX:XX 1 - 1 - -
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['e2e requests fails on status code 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -315,5 +320,5 @@ Body: Service Unavailable
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
1 of 1 failed (100%) XX:XX 1 - 1 - -
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
@@ -1,4 +1,5 @@
|
||||
exports['e2e return value failing1 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -131,5 +132,5 @@ https://on.cypress.io/returning-value-and-commands-in-custom-command
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
1 of 1 failed (100%) XX:XX 2 - 2 - -
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
@@ -1,4 +1,5 @@
|
||||
exports['lib/plugins/child/run_plugins sends error message if pluginsFile is missing 1'] = `Error: Cannot find module '/does/not/exist.coffee'
|
||||
exports['lib/plugins/child/run_plugins sends error message if pluginsFile is missing 1'] = `
|
||||
Error: Cannot find module '/does/not/exist.coffee'
|
||||
at Function.Module._resolveFilename <path>module.js
|
||||
at Module._load <path>module.js
|
||||
at Function.hookedLoader [as _load] <path>mockery.js
|
||||
@@ -22,9 +23,11 @@ exports['lib/plugins/child/run_plugins sends error message if pluginsFile is mis
|
||||
at runCallback <path>timers.js
|
||||
at tryOnImmediate <path>timers.js
|
||||
at processImmediate [as _immediateCallback] <path>timers.js
|
||||
|
||||
`
|
||||
|
||||
exports['lib/plugins/child/run_plugins sends error message if requiring pluginsFile errors 1'] = `Error: error thrown by pluginsFile
|
||||
exports['lib/plugins/child/run_plugins sends error message if requiring pluginsFile errors 1'] = `
|
||||
Error: error thrown by pluginsFile
|
||||
at Object.<anonymous> <path>throws_error.coffee
|
||||
at Object.<anonymous> <path>throws_error.coffee
|
||||
at Module._compile <path>module.js
|
||||
@@ -53,15 +56,15 @@ exports['lib/plugins/child/run_plugins sends error message if requiring pluginsF
|
||||
at runCallback <path>timers.js
|
||||
at tryOnImmediate <path>timers.js
|
||||
at processImmediate [as _immediateCallback] <path>timers.js
|
||||
|
||||
`
|
||||
|
||||
exports['lib/plugins/child/run_plugins sends error message if pluginsFile has syntax error 1'] = `<path>syntax_error.coffee) error: missing }
|
||||
exports['lib/plugins/child/run_plugins sends error message if pluginsFile has syntax error 1'] = `
|
||||
<path>syntax_error.coffee) error: missing }
|
||||
<color-code>{<color-code>
|
||||
<color-code>^<color-code>`
|
||||
<color-code>^<color-code>
|
||||
`
|
||||
|
||||
exports['lib/plugins/child/run_plugins sends error message if pluginsFile does not export a function 1'] = `null`
|
||||
|
||||
exports['lib/plugins/child/run_plugins on \'load\' message sends error if pluginsFile function throws an error 1'] = {
|
||||
"name": "ReferenceError",
|
||||
"message": "foo is not defined"
|
||||
}
|
||||
exports['lib/plugins/child/run_plugins sends error message if pluginsFile does not export a function 1'] = `
|
||||
null
|
||||
`
|
||||
@@ -285,7 +285,8 @@ exports['lib/scaffold .fileTree leaves out support if configured to false 1'] =
|
||||
}
|
||||
]
|
||||
|
||||
exports['lib/scaffold .support creates supportFolder and commands.js and index.js when supportFolder does not exist 1'] = `// ***********************************************
|
||||
exports['lib/scaffold .support creates supportFolder and commands.js and index.js when supportFolder does not exist 1'] = `
|
||||
// ***********************************************
|
||||
// This example commands.js shows you how to
|
||||
// create various custom commands and overwrite
|
||||
// existing commands.
|
||||
@@ -310,9 +311,11 @@ exports['lib/scaffold .support creates supportFolder and commands.js and index.j
|
||||
//
|
||||
// -- This is will overwrite an existing command --
|
||||
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
|
||||
|
||||
`
|
||||
|
||||
exports['lib/scaffold .support creates supportFolder and commands.js and index.js when supportFolder does not exist 2'] = `// ***********************************************************
|
||||
exports['lib/scaffold .support creates supportFolder and commands.js and index.js when supportFolder does not exist 2'] = `
|
||||
// ***********************************************************
|
||||
// This example support/index.js is processed and
|
||||
// loaded automatically before your test files.
|
||||
//
|
||||
@@ -332,6 +335,7 @@ import './commands'
|
||||
|
||||
// Alternatively you can use CommonJS syntax:
|
||||
// require('./commands')
|
||||
|
||||
`
|
||||
|
||||
exports['lib/scaffold .fileTree leaves out plugins if configured to false 1'] = [
|
||||
@@ -423,7 +427,8 @@ exports['lib/scaffold .fileTree leaves out plugins if configured to false 1'] =
|
||||
}
|
||||
]
|
||||
|
||||
exports['lib/scaffold .plugins creates pluginsFile when pluginsFolder does not exist 1'] = `// ***********************************************************
|
||||
exports['lib/scaffold .plugins creates pluginsFile when pluginsFolder does not exist 1'] = `
|
||||
// ***********************************************************
|
||||
// This example plugins/index.js can be used to load plugins
|
||||
//
|
||||
// You can change the location of this file or turn off loading
|
||||
@@ -440,4 +445,5 @@ module.exports = (on, config) => {
|
||||
// <backtick>on<backtick> is used to hook into various events Cypress emits
|
||||
// <backtick>config<backtick> is the resolved Cypress config
|
||||
}
|
||||
|
||||
`
|
||||
@@ -1,4 +1,5 @@
|
||||
exports['e2e screenshot element capture passes 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -68,5 +69,5 @@ exports['e2e screenshot element capture passes 1'] = `
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
All specs passed! XX:XX 1 1 - - -
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
@@ -1,4 +1,5 @@
|
||||
exports['e2e screenshot fullPage capture passes 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -68,5 +69,5 @@ exports['e2e screenshot fullPage capture passes 1'] = `
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
All specs passed! XX:XX 1 1 - - -
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
@@ -1,4 +1,5 @@
|
||||
exports['e2e screenshot in nested spec passes 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -58,5 +59,5 @@ exports['e2e screenshot in nested spec passes 1'] = `
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
All specs passed! XX:XX 1 1 - - -
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
@@ -1,4 +1,5 @@
|
||||
exports['e2e screenshot viewport capture passes 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -83,5 +84,5 @@ exports['e2e screenshot viewport capture passes 1'] = `
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
All specs passed! XX:XX 1 1 - - -
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
@@ -1,4 +1,5 @@
|
||||
exports['e2e screenshots passes 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -133,5 +134,5 @@ Because this error occurred during a 'after each' hook we are skipping the remai
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
1 of 1 failed (100%) XX:XX 19 15 4 - -
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
@@ -1,4 +1,5 @@
|
||||
exports['e2e server sent events passes 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -55,5 +56,5 @@ exports['e2e server sent events passes 1'] = `
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
All specs passed! XX:XX 1 1 - - -
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
@@ -1,14 +0,0 @@
|
||||
exports['e2e specs failing when no specs found 1'] = `Can't run because no spec files were found.
|
||||
|
||||
We searched for any files inside of this folder:
|
||||
|
||||
/foo/bar/.projects/e2e/cypress/specs
|
||||
`
|
||||
|
||||
exports['e2e specs failing when no spec pattern found 1'] = `Can't run because no spec files were found.
|
||||
|
||||
We searched for any files matching this glob pattern:
|
||||
|
||||
cypress/integration/cypress/integration/**notfound**
|
||||
`
|
||||
|
||||
17
packages/server/__snapshots__/specs_spec.coffee.js
Normal file
17
packages/server/__snapshots__/specs_spec.coffee.js
Normal file
@@ -0,0 +1,17 @@
|
||||
exports['e2e specs failing when no specs found 1'] = `
|
||||
Can't run because no spec files were found.
|
||||
|
||||
We searched for any files inside of this folder:
|
||||
|
||||
/foo/bar/.projects/e2e/cypress/specs
|
||||
|
||||
`
|
||||
|
||||
exports['e2e specs failing when no spec pattern found 1'] = `
|
||||
Can't run because no spec files were found.
|
||||
|
||||
We searched for any files matching this glob pattern:
|
||||
|
||||
cypress/integration/cypress/integration/**notfound**
|
||||
|
||||
`
|
||||
@@ -1,4 +1,5 @@
|
||||
exports['e2e stdout displays errors from failures 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -133,9 +134,11 @@ The internal Cypress web server responded with:
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
1 of 1 failed (100%) XX:XX 5 2 3 - -
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['e2e stdout displays errors from exiting early due to bundle errors 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -202,9 +205,11 @@ Fix the error in your code and re-run your tests.
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
1 of 1 failed (100%) XX:XX - - 1 - -
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['e2e stdout does not duplicate suites or tests between visits 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -272,9 +277,11 @@ exports['e2e stdout does not duplicate suites or tests between visits 1'] = `
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
All specs passed! XX:XX 8 8 - - -
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['e2e stdout logs that electron cannot be recorded in headed mode 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -329,9 +336,11 @@ A video will not be recorded when using this mode.
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
All specs passed! XX:XX 1 1 - - -
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['e2e stdout logs that chrome cannot be recorded 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -386,5 +395,5 @@ A video will not be recorded when using this browser.
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
All specs passed! XX:XX 1 1 - - -
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
@@ -1,4 +1,5 @@
|
||||
exports['e2e subdomain passes 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -64,5 +65,5 @@ exports['e2e subdomain passes 1'] = `
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
All specs passed! XX:XX 9 7 - 2 -
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
@@ -1,4 +1,5 @@
|
||||
exports['e2e task fails 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -84,5 +85,5 @@ https://on.cypress.io/api/task
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
1 of 1 failed (100%) XX:XX 1 - 1 - -
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
@@ -1,4 +1,5 @@
|
||||
exports['e2e task fails 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -126,5 +127,5 @@ https://on.cypress.io/api/task
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
1 of 1 failed (100%) XX:XX 2 - 2 - -
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
@@ -1,44 +0,0 @@
|
||||
exports['lib/util/terminal .table draws a table with 2px margin-left 1'] = `[90m [39m[90m Spec [39m[90m Skipped [39m[90m Pending [39m[90m Passing [39m[90m Failing [39m
|
||||
[90m ┌────────────────────────────────────────────────────[39m[90m────────────[39m[90m────────────[39m[90m────────────[39m[90m────────────┐[39m
|
||||
[90m │[39m foo.js 4 3 2 1 [90m│[39m
|
||||
[90m ├────────────────────────────────────────────────────[39m[90m────────────[39m[90m────────────[39m[90m────────────[39m[90m────────────┤[39m
|
||||
[90m │[39m bar.js 0 0 0 15 [90m│[39m
|
||||
[90m ├────────────────────────────────────────────────────[39m[90m────────────[39m[90m────────────[39m[90m────────────[39m[90m────────────┤[39m
|
||||
[90m │[39m fail/is/whale.js 25 5 100 3 [90m│[39m
|
||||
[90m └────────────────────────────────────────────────────[39m[90m────────────[39m[90m────────────[39m[90m────────────[39m[90m────────────┘[39m`
|
||||
|
||||
exports['lib/util/terminal .table draws two tables as summary view 1'] = `[90m [39m[90m Spec [39m[90m Skipped [39m[90m Pending [39m[90m Passing [39m[90m Failing [39m
|
||||
[90m ┌────────────────────────────────────────────────────[39m[90m────────────[39m[90m────────────[39m[90m────────────[39m[90m────────────┐[39m
|
||||
[90m │[39m foo.js 4 3 2 1 [90m│[39m
|
||||
[90m ├────────────────────────────────────────────────────[39m[90m────────────[39m[90m────────────[39m[90m────────────[39m[90m────────────┤[39m
|
||||
[90m │[39m bar.js 0 0 0 15 [90m│[39m
|
||||
[90m ├────────────────────────────────────────────────────[39m[90m────────────[39m[90m────────────[39m[90m────────────[39m[90m────────────┤[39m
|
||||
[90m │[39m fail/is/whale.js 25 5 100 3 [90m│[39m
|
||||
[90m └────────────────────────────────────────────────────[39m[90m────────────[39m[90m────────────[39m[90m────────────[39m[90m────────────┘[39m`
|
||||
|
||||
exports['lib/util/terminal .table draws multiple specs summary table 1'] = ` Spec Tests Passing Failing Pending Skipped
|
||||
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ foo.js 00:49 7 4 3 2 1 │
|
||||
├────────────────────────────────────────────────────────────────────────────────────────────────┤
|
||||
│ bar.js 796ms 0 0 0 0 15 │
|
||||
├────────────────────────────────────────────────────────────────────────────────────────────────┤
|
||||
│ fail/is/whale.js 03:28 30 25 5 100 3 │
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
2 of 3 passed (66%) 1:05:36 37 29 8 102 18 `
|
||||
|
||||
exports['lib/util/terminal .table draws single spec summary table 1'] = ` ┌──────────────────────────────┐
|
||||
│ Tests: 1 │
|
||||
│ Passing: 2 │
|
||||
│ Failing: 3 │
|
||||
│ Pending: 4 │
|
||||
│ Skipped: 5 │
|
||||
│ Duration: 6 │
|
||||
│ Screenshots: 7 │
|
||||
│ Video: true │
|
||||
│ Spec: foo/bar/baz.js │
|
||||
└──────────────────────────────┘`
|
||||
|
||||
exports['lib/util/terminal .table draws a page divider 1'] = `────────────────────────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
Running: foo/bar/baz.js... (100 of 200) `
|
||||
|
||||
31
packages/server/__snapshots__/terminal_spec.coffee.js
Normal file
31
packages/server/__snapshots__/terminal_spec.coffee.js
Normal file
@@ -0,0 +1,31 @@
|
||||
exports['lib/util/terminal .table draws multiple specs summary table 1'] = `
|
||||
Spec Tests Passing Failing Pending Skipped
|
||||
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ foo.js 00:49 7 4 3 2 1 │
|
||||
├────────────────────────────────────────────────────────────────────────────────────────────────┤
|
||||
│ bar.js 796ms 0 0 0 0 15 │
|
||||
├────────────────────────────────────────────────────────────────────────────────────────────────┤
|
||||
│ fail/is/whale.js 03:28 30 25 5 100 3 │
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
2 of 3 passed (66%) 1:05:36 37 29 8 102 18
|
||||
`
|
||||
|
||||
exports['lib/util/terminal .table draws single spec summary table 1'] = `
|
||||
┌──────────────────────────────┐
|
||||
│ Tests: 1 │
|
||||
│ Passing: 2 │
|
||||
│ Failing: 3 │
|
||||
│ Pending: 4 │
|
||||
│ Skipped: 5 │
|
||||
│ Duration: 6 │
|
||||
│ Screenshots: 7 │
|
||||
│ Video: true │
|
||||
│ Spec: foo/bar/baz.js │
|
||||
└──────────────────────────────┘
|
||||
`
|
||||
|
||||
exports['lib/util/terminal .table draws a page divider 1'] = `
|
||||
────────────────────────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
Running: foo/bar/baz.js... (100 of 200)
|
||||
`
|
||||
@@ -1,4 +1,5 @@
|
||||
exports['e2e uncaught errors failing1 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -76,9 +77,11 @@ We dynamically generated a new test to display this failure.
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
1 of 1 failed (100%) XX:XX 1 - 1 - -
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['e2e uncaught errors failing2 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -157,9 +160,11 @@ We dynamically generated a new test to display this failure.
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
1 of 1 failed (100%) XX:XX 1 - 1 - -
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['e2e uncaught errors failing3 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -232,9 +237,11 @@ When Cypress detects uncaught errors originating from your test code it will aut
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
1 of 1 failed (100%) XX:XX 1 - 1 - -
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['e2e uncaught errors failing4 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -312,9 +319,11 @@ Because this error occurred during a 'before all' hook we are skipping the remai
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
1 of 1 failed (100%) XX:XX 2 1 1 - -
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['e2e uncaught errors failing5 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -405,5 +414,5 @@ exports['e2e uncaught errors failing5 1'] = `
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
1 of 1 failed (100%) XX:XX 8 4 4 - -
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
@@ -1,4 +1,5 @@
|
||||
exports['e2e uncaught support file errors failing 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -75,5 +76,5 @@ We dynamically generated a new test to display this failure.
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
1 of 1 failed (100%) XX:XX 1 - 1 - -
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
@@ -1,4 +1,5 @@
|
||||
exports['e2e user agent passes on chrome 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -56,9 +57,11 @@ A video will not be recorded when using this browser.
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
All specs passed! XX:XX 2 2 - - -
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['e2e user agent passes on electron 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -116,5 +119,5 @@ exports['e2e user agent passes on electron 1'] = `
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
All specs passed! XX:XX 2 2 - - -
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
@@ -1,4 +1,5 @@
|
||||
exports['e2e viewport passes 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -57,5 +58,5 @@ exports['e2e viewport passes 1'] = `
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
All specs passed! XX:XX 3 3 - - -
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
@@ -1,4 +1,5 @@
|
||||
exports['e2e visit low response timeout passes 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -72,9 +73,11 @@ exports['e2e visit low response timeout passes 1'] = `
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
All specs passed! XX:XX 13 13 - - -
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['e2e visit low response timeout fails when network connection immediately fails 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -179,9 +182,11 @@ Error: connect ECONNREFUSED 127.0.0.1:16795
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
1 of 1 failed (100%) XX:XX 1 - 1 - -
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['e2e visit low response timeout fails when server responds with 500 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -274,9 +279,11 @@ If you do not want status codes to cause failures pass the option: 'failOnStatus
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
1 of 1 failed (100%) XX:XX 1 - 1 - -
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['e2e visit low response timeout fails when file server responds with 404 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -369,9 +376,11 @@ The internal Cypress web server responded with:
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
1 of 1 failed (100%) XX:XX 1 - 1 - -
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['e2e visit low response timeout fails when content type isnt html 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -466,9 +475,11 @@ cy.request() will automatically get and set cookies and enable you to parse resp
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
1 of 1 failed (100%) XX:XX 1 - 1 - -
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['e2e visit normal response timeouts fails when visit times out 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -589,5 +600,5 @@ When this 'load' event occurs, Cypress will continue running commands.
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
1 of 1 failed (100%) XX:XX 2 - 2 - -
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
@@ -1,4 +1,5 @@
|
||||
exports['e2e web security when enabled fails 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -163,9 +164,11 @@ https://on.cypress.io/cross-origin-violation
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
1 of 1 failed (100%) XX:XX 3 - 3 - -
|
||||
|
||||
|
||||
`
|
||||
|
||||
exports['e2e web security when disabled passes 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -224,5 +227,5 @@ A video will not be recorded when using this browser.
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
All specs passed! XX:XX 3 3 - - -
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
@@ -1,4 +1,5 @@
|
||||
exports['e2e websockets passes 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -55,5 +56,5 @@ exports['e2e websockets passes 1'] = `
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
All specs passed! XX:XX 1 1 - - -
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
@@ -1,4 +1,5 @@
|
||||
exports['e2e xhr passes 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
(Run Starting)
|
||||
@@ -63,5 +64,5 @@ exports['e2e xhr passes 1'] = `
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
All specs passed! XX:XX 8 8 - - -
|
||||
|
||||
`
|
||||
|
||||
`
|
||||
@@ -31,7 +31,16 @@ rp = request.defaults (params = {}, callback) ->
|
||||
|
||||
method = params.method.toLowerCase()
|
||||
|
||||
debug(
|
||||
"request to url: %s with params: %o",
|
||||
"#{params.method} #{params.url}",
|
||||
_.pick(params, "body", "headers")
|
||||
)
|
||||
|
||||
request[method](params, callback)
|
||||
.promise()
|
||||
.tap (resp) ->
|
||||
debug("response %o", resp)
|
||||
|
||||
formatResponseBody = (err) ->
|
||||
## if the body is JSON object
|
||||
@@ -57,6 +66,8 @@ isRetriableError = (err) ->
|
||||
(err instanceof Promise.TimeoutError) or (500 <= err.statusCode < 600)
|
||||
|
||||
module.exports = {
|
||||
rp
|
||||
|
||||
ping: ->
|
||||
rp.get(routes.ping())
|
||||
.catch(tagError)
|
||||
@@ -113,28 +124,25 @@ module.exports = {
|
||||
|
||||
createRun: (options = {}) ->
|
||||
body = _.pick(options, [
|
||||
"projectId"
|
||||
"recordKey"
|
||||
"ci"
|
||||
"specs",
|
||||
"commit"
|
||||
"platform"
|
||||
"specPattern"
|
||||
"group",
|
||||
"platform",
|
||||
"parallel",
|
||||
"ciBuildId",
|
||||
"projectId",
|
||||
"recordKey",
|
||||
"specPattern",
|
||||
])
|
||||
|
||||
## temporary hack to get around
|
||||
## the latest schema requirements
|
||||
body.group = null
|
||||
body.parallel = null
|
||||
body.ciBuildId = null
|
||||
|
||||
rp.post({
|
||||
body
|
||||
url: routes.runs()
|
||||
json: true
|
||||
timeout: options.timeout ? MUTATING_TIMEOUT
|
||||
headers: {
|
||||
"x-route-version": "3"
|
||||
"x-route-version": "4"
|
||||
}
|
||||
})
|
||||
.catch(errors.StatusCodeError, formatResponseBody)
|
||||
@@ -156,11 +164,9 @@ module.exports = {
|
||||
json: true
|
||||
timeout: timeout ? MUTATING_TIMEOUT
|
||||
headers: {
|
||||
"x-route-version": "4"
|
||||
"x-route-version": "5"
|
||||
}
|
||||
})
|
||||
.promise()
|
||||
.get("instanceId")
|
||||
.catch(errors.StatusCodeError, formatResponseBody)
|
||||
.catch(tagError)
|
||||
|
||||
@@ -208,7 +214,6 @@ module.exports = {
|
||||
bearer: authToken
|
||||
}
|
||||
})
|
||||
.promise()
|
||||
.timeout(timeout)
|
||||
.catch(tagError)
|
||||
|
||||
@@ -294,7 +299,6 @@ module.exports = {
|
||||
url: routes.auth(),
|
||||
json: true
|
||||
})
|
||||
.promise()
|
||||
.get("url")
|
||||
.catch(tagError)
|
||||
|
||||
@@ -310,7 +314,6 @@ module.exports = {
|
||||
"x-route-version": "2"
|
||||
}
|
||||
})
|
||||
.promise()
|
||||
.get("apiToken")
|
||||
.catch(tagError)
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
_ = require("lodash")
|
||||
os = require("os")
|
||||
path = require("path")
|
||||
Promise = require("bluebird")
|
||||
extension = require("@packages/extension")
|
||||
debug = require("debug")("cypress:server:browsers")
|
||||
@@ -64,6 +65,17 @@ defaultArgs = [
|
||||
"--disable-default-apps"
|
||||
]
|
||||
|
||||
pluginsBeforeBrowserLaunch = (browser, args) ->
|
||||
## bail if we're not registered to this event
|
||||
return args if not plugins.has("before:browser:launch")
|
||||
|
||||
plugins.execute("before:browser:launch", browser, args)
|
||||
.then (newArgs) ->
|
||||
debug("got user args for 'before:browser:launch'", newArgs)
|
||||
|
||||
## reset args if we got 'em
|
||||
return newArgs ? args
|
||||
|
||||
_normalizeArgExtensions = (dest, args) ->
|
||||
loadExtension = _.find args, (arg) ->
|
||||
arg.includes(LOAD_EXTENSION)
|
||||
@@ -80,15 +92,23 @@ _normalizeArgExtensions = (dest, args) ->
|
||||
|
||||
args
|
||||
|
||||
## we now store the extension in each browser profile
|
||||
_removeRootExtension = ->
|
||||
fs
|
||||
.removeAsync(appData.path("extensions"))
|
||||
.catchReturn(null) ## noop if doesn't exist fails for any reason
|
||||
|
||||
module.exports = {
|
||||
_normalizeArgExtensions
|
||||
|
||||
_writeExtension: (proxyUrl, socketIoRoute) ->
|
||||
_removeRootExtension
|
||||
|
||||
_writeExtension: (browserName, isTextTerminal, proxyUrl, socketIoRoute) ->
|
||||
## get the string bytes for the final extension file
|
||||
extension.setHostAndPath(proxyUrl, socketIoRoute)
|
||||
.then (str) ->
|
||||
extensionDest = appData.path("extensions", "chrome")
|
||||
extensionBg = appData.path("extensions", "chrome", "background.js")
|
||||
extensionDest = utils.getExtensionDir(browserName, isTextTerminal)
|
||||
extensionBg = path.join(extensionDest, "background.js")
|
||||
|
||||
## copy the extension src to the extension dist
|
||||
utils.copyExtension(pathToExtension, extensionDest)
|
||||
@@ -130,41 +150,43 @@ module.exports = {
|
||||
args
|
||||
|
||||
open: (browserName, url, options = {}, automation) ->
|
||||
args = @_getArgs(options)
|
||||
{ isTextTerminal } = options
|
||||
|
||||
Promise
|
||||
.try ->
|
||||
## bail if we're not registered to this event
|
||||
return if not plugins.has("before:browser:launch")
|
||||
.try =>
|
||||
args = @_getArgs(options)
|
||||
|
||||
plugins.execute("before:browser:launch", options.browser, args)
|
||||
.then (newArgs) ->
|
||||
debug("got user args for 'before:browser:launch'", newArgs)
|
||||
|
||||
## reset args if we got 'em
|
||||
if newArgs
|
||||
args = newArgs
|
||||
.then =>
|
||||
Promise.all([
|
||||
## ensure that we have a clean cache dir
|
||||
## before launching the browser every time
|
||||
utils.ensureCleanCache(browserName)
|
||||
utils.ensureCleanCache(browserName, isTextTerminal),
|
||||
|
||||
@_writeExtension(options.proxyUrl, options.socketIoRoute)
|
||||
pluginsBeforeBrowserLaunch(options.browser, args)
|
||||
])
|
||||
.spread (cacheDir, dest) ->
|
||||
## normalize the --load-extensions argument by
|
||||
## massaging what the user passed into our own
|
||||
args = _normalizeArgExtensions(dest, args)
|
||||
.spread (cacheDir, args) =>
|
||||
Promise.all([
|
||||
@_writeExtension(
|
||||
browserName,
|
||||
isTextTerminal,
|
||||
options.proxyUrl,
|
||||
options.socketIoRoute
|
||||
),
|
||||
|
||||
userDir = utils.getProfileDir(browserName)
|
||||
_removeRootExtension(),
|
||||
])
|
||||
.spread (extDest) ->
|
||||
## normalize the --load-extensions argument by
|
||||
## massaging what the user passed into our own
|
||||
args = _normalizeArgExtensions(extDest, args)
|
||||
|
||||
## this overrides any previous user-data-dir args
|
||||
## by being the last one
|
||||
args.push("--user-data-dir=#{userDir}")
|
||||
args.push("--disk-cache-dir=#{cacheDir}")
|
||||
userDir = utils.getProfileDir(browserName, isTextTerminal)
|
||||
|
||||
debug("launch in chrome: %s, %s", url, args)
|
||||
## this overrides any previous user-data-dir args
|
||||
## by being the last one
|
||||
args.push("--user-data-dir=#{userDir}")
|
||||
args.push("--disk-cache-dir=#{cacheDir}")
|
||||
|
||||
utils.launch(browserName, url, args)
|
||||
debug("launch in chrome: %s, %s", url, args)
|
||||
|
||||
utils.launch(browserName, url, args)
|
||||
}
|
||||
|
||||
@@ -2,10 +2,12 @@ _ = require("lodash")
|
||||
EE = require("events")
|
||||
Promise = require("bluebird")
|
||||
debug = require("debug")("cypress:server:browsers:electron")
|
||||
plugins = require("../plugins")
|
||||
menu = require("../gui/menu")
|
||||
Windows = require("../gui/windows")
|
||||
appData = require("../util/app_data")
|
||||
plugins = require("../plugins")
|
||||
savedState = require("../saved_state")
|
||||
profileCleaner = require("../util/profile_cleaner")
|
||||
|
||||
module.exports = {
|
||||
_defaultOptions: (projectRoot, state, options) ->
|
||||
@@ -20,6 +22,7 @@ module.exports = {
|
||||
minWidth: 100
|
||||
minHeight: 100
|
||||
contextMenu: true
|
||||
partition: @_getPartition(options)
|
||||
trackState: {
|
||||
width: "browserWidth"
|
||||
height: "browserHeight"
|
||||
@@ -89,6 +92,16 @@ module.exports = {
|
||||
win.loadURL(url)
|
||||
.return(win)
|
||||
|
||||
_getPartition: (options) ->
|
||||
if options.isTextTerminal
|
||||
## create dynamic persisted run
|
||||
## to enable parallelization
|
||||
return "persist:run-#{process.pid}"
|
||||
|
||||
## we're in interactive mode and always
|
||||
## use the same session
|
||||
return "persist:interactive"
|
||||
|
||||
_clearCache: (webContents) ->
|
||||
new Promise (resolve) ->
|
||||
webContents.session.clearCache(resolve)
|
||||
@@ -108,6 +121,7 @@ module.exports = {
|
||||
{ projectRoot, isTextTerminal } = options
|
||||
|
||||
debug("open %o", { browserName, url })
|
||||
|
||||
savedState(projectRoot, isTextTerminal)
|
||||
.then (state) ->
|
||||
debug("got saved state")
|
||||
|
||||
@@ -59,6 +59,8 @@ module.exports = {
|
||||
|
||||
throwBrowserNotFound
|
||||
|
||||
removeOldProfiles: utils.removeOldProfiles
|
||||
|
||||
get: utils.getBrowsers
|
||||
|
||||
launch: utils.launch
|
||||
|
||||
@@ -3,24 +3,72 @@ Promise = require("bluebird")
|
||||
launcher = require("@packages/launcher")
|
||||
fs = require("../util/fs")
|
||||
appData = require("../util/app_data")
|
||||
profileCleaner = require("../util/profile_cleaner")
|
||||
|
||||
profiles = appData.path("browsers")
|
||||
PATH_TO_BROWSERS = appData.path("browsers")
|
||||
|
||||
copyExtension = (src, dest) ->
|
||||
fs.copyAsync(src, dest)
|
||||
|
||||
getPartition = (isTextTerminal) ->
|
||||
if isTextTerminal
|
||||
return "run-#{process.pid}"
|
||||
|
||||
return "interactive"
|
||||
|
||||
getProfileDir = (browserName, isTextTerminal) ->
|
||||
path.join(
|
||||
PATH_TO_BROWSERS,
|
||||
browserName,
|
||||
getPartition(isTextTerminal),
|
||||
)
|
||||
|
||||
getExtensionDir = (browserName, isTextTerminal) ->
|
||||
path.join(
|
||||
getProfileDir(browserName, isTextTerminal),
|
||||
"CypressExtension"
|
||||
)
|
||||
|
||||
ensureCleanCache = (browserName, isTextTerminal) ->
|
||||
p = path.join(
|
||||
getProfileDir(browserName, isTextTerminal),
|
||||
"CypressCache"
|
||||
)
|
||||
|
||||
fs
|
||||
.removeAsync(p)
|
||||
.then ->
|
||||
fs.ensureDirAsync(p)
|
||||
.return(p)
|
||||
|
||||
removeOldProfiles = ->
|
||||
## a profile is considered old if it was used
|
||||
## in a previous run for a PID that is either
|
||||
## no longer active, or isnt a cypress related process
|
||||
pathToProfiles = path.join(PATH_TO_BROWSERS, "*")
|
||||
pathToPartitions = appData.electronPartitionsPath()
|
||||
|
||||
Promise.all([
|
||||
## we now store profiles in either interactive or run-* folders
|
||||
## so we need to remove the old root profiles that existed before
|
||||
profileCleaner.removeRootProfile(pathToProfiles, [
|
||||
path.join(pathToProfiles, "run-*")
|
||||
path.join(pathToProfiles, "interactive")
|
||||
])
|
||||
profileCleaner.removeInactiveByPid(pathToProfiles, "run-"),
|
||||
profileCleaner.removeInactiveByPid(pathToPartitions, "run-"),
|
||||
])
|
||||
|
||||
module.exports = {
|
||||
getProfileDir: (name) ->
|
||||
path.join(profiles, name)
|
||||
copyExtension
|
||||
|
||||
ensureCleanCache: (name) ->
|
||||
p = path.join(profiles, name, "CypressCache")
|
||||
getProfileDir
|
||||
|
||||
fs
|
||||
.removeAsync(p)
|
||||
.then ->
|
||||
fs.ensureDirAsync(p)
|
||||
.return(p)
|
||||
getExtensionDir
|
||||
|
||||
copyExtension: (src, dest) ->
|
||||
fs.copyAsync(src, dest)
|
||||
ensureCleanCache
|
||||
|
||||
removeOldProfiles
|
||||
|
||||
getBrowsers: ->
|
||||
## TODO: accept an options object which
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -142,6 +142,7 @@ module.exports = {
|
||||
onCrashed: ->
|
||||
onNewWindow: ->
|
||||
webPreferences: {
|
||||
partition: null
|
||||
chromeWebSecurity: true
|
||||
nodeIntegration: false
|
||||
backgroundThrottling: false
|
||||
@@ -158,6 +159,9 @@ module.exports = {
|
||||
if options.chromeWebSecurity is false
|
||||
options.webPreferences.webSecurity = false
|
||||
|
||||
if options.partition
|
||||
options.webPreferences.partition = options.partition
|
||||
|
||||
win = @_newBrowserWindow(options)
|
||||
|
||||
win.on "blur", ->
|
||||
|
||||
@@ -56,12 +56,37 @@ warnIfProjectIdButNoRecordOption = (projectId, options) ->
|
||||
## record mode
|
||||
errors.warning("PROJECT_ID_AND_KEY_BUT_MISSING_RECORD_OPTION", projectId)
|
||||
|
||||
throwIfIndeterminateCiBuildId = (ciBuildId, parallel, group) ->
|
||||
if (not ciBuildId and not ciProvider.provider()) and (parallel or group)
|
||||
errors.throw(
|
||||
"INDETERMINATE_CI_BUILD_ID",
|
||||
{
|
||||
group,
|
||||
parallel
|
||||
},
|
||||
ciProvider.list()
|
||||
)
|
||||
|
||||
throwIfRecordParamsWithoutRecording = (record, ciBuildId, parallel, group) ->
|
||||
if not record and _.some([ciBuildId, parallel, group])
|
||||
errors.throw("RECORD_PARAMS_WITHOUT_RECORDING", {
|
||||
ciBuildId,
|
||||
group,
|
||||
parallel
|
||||
})
|
||||
|
||||
throwIfIncorrectCiBuildIdUsage = (ciBuildId, parallel, group) ->
|
||||
## we've been given an explicit ciBuildId
|
||||
## but no parallel or group flag
|
||||
if ciBuildId and (not parallel and not group)
|
||||
errors.throw("INCORRECT_CI_BUILD_ID_USAGE", { ciBuildId })
|
||||
|
||||
throwIfNoProjectId = (projectId) ->
|
||||
if not projectId
|
||||
errors.throw("CANNOT_RECORD_NO_PROJECT_ID")
|
||||
|
||||
getSpecRelativePath = (spec) ->
|
||||
_.get(spec, "relative")
|
||||
_.get(spec, "relative", null)
|
||||
|
||||
uploadArtifacts = (options = {}) ->
|
||||
{ video, screenshots, videoUploadUrl, shouldUploadVideo, screenshotUploadUrls } = options
|
||||
@@ -138,7 +163,7 @@ updateInstanceStdout = (options = {}) ->
|
||||
.finally(capture.restore)
|
||||
|
||||
updateInstance = (options = {}) ->
|
||||
{ instanceId, results, captured } = options
|
||||
{ instanceId, results, captured, group, parallel, ciBuildId } = options
|
||||
{ stats, tests, hooks, video, screenshots, reporterStats, error } = results
|
||||
|
||||
video = Boolean(video)
|
||||
@@ -172,6 +197,15 @@ updateInstance = (options = {}) ->
|
||||
stack: err.stack
|
||||
})
|
||||
|
||||
if parallel
|
||||
return errors.throw("DASHBOARD_CANNOT_PROCEED_IN_PARALLEL", {
|
||||
error: err,
|
||||
flags: {
|
||||
group,
|
||||
ciBuildId,
|
||||
},
|
||||
})
|
||||
|
||||
errors.warning("DASHBOARD_CANNOT_CREATE_RUN_OR_INSTANCE", err)
|
||||
|
||||
## dont log exceptions if we have a 503 status code
|
||||
@@ -182,7 +216,13 @@ updateInstance = (options = {}) ->
|
||||
null
|
||||
|
||||
createRun = (options = {}) ->
|
||||
{ projectId, recordKey, platform, git, specPattern, specs } = options
|
||||
_.defaults(options, {
|
||||
group: null,
|
||||
parallel: null,
|
||||
ciBuildId: null,
|
||||
})
|
||||
|
||||
{ projectId, recordKey, platform, git, specPattern, specs, parallel, ciBuildId, group } = options
|
||||
|
||||
recordKey ?= env.get("CYPRESS_RECORD_KEY") or env.get("CYPRESS_CI_KEY")
|
||||
|
||||
@@ -201,15 +241,22 @@ createRun = (options = {}) ->
|
||||
if specPattern
|
||||
specPattern = specPattern.join(",")
|
||||
|
||||
if ciBuildId
|
||||
## stringify
|
||||
ciBuildId = String(ciBuildId)
|
||||
|
||||
specs = _.map(specs, getSpecRelativePath)
|
||||
|
||||
makeRequest = ->
|
||||
api.createRun({
|
||||
specPattern
|
||||
specs
|
||||
group
|
||||
parallel
|
||||
platform
|
||||
ciBuildId
|
||||
projectId
|
||||
recordKey
|
||||
platform
|
||||
specPattern
|
||||
ci: {
|
||||
params: ciProvider.ciParams()
|
||||
provider: ciProvider.provider()
|
||||
@@ -237,12 +284,83 @@ createRun = (options = {}) ->
|
||||
switch err.statusCode
|
||||
when 401
|
||||
recordKey = recordKey.slice(0, 5) + "..." + recordKey.slice(-5)
|
||||
errors.throw("RECORD_KEY_NOT_VALID", recordKey, projectId)
|
||||
errors.throw("DASHBOARD_RECORD_KEY_NOT_VALID", recordKey, projectId)
|
||||
when 404
|
||||
errors.throw("DASHBOARD_PROJECT_NOT_FOUND", projectId)
|
||||
when 412
|
||||
errors.throw("DASHBOARD_INVALID_RUN_REQUEST", err.error)
|
||||
when 422
|
||||
{ code, payload } = err.error
|
||||
|
||||
runUrl = _.get(payload, "runUrl")
|
||||
|
||||
switch code
|
||||
when "RUN_GROUP_NAME_NOT_UNIQUE"
|
||||
errors.throw("DASHBOARD_RUN_GROUP_NAME_NOT_UNIQUE", {
|
||||
group,
|
||||
runUrl,
|
||||
ciBuildId,
|
||||
})
|
||||
when "PARALLEL_GROUP_PARAMS_MISMATCH"
|
||||
{ browserName, browserVersion, osName, osVersion } = platform
|
||||
|
||||
errors.throw("DASHBOARD_PARALLEL_GROUP_PARAMS_MISMATCH", {
|
||||
group,
|
||||
runUrl,
|
||||
ciBuildId,
|
||||
parameters: {
|
||||
osName,
|
||||
osVersion,
|
||||
browserName,
|
||||
browserVersion,
|
||||
specs,
|
||||
}
|
||||
})
|
||||
when "PARALLEL_DISALLOWED"
|
||||
errors.throw("DASHBOARD_PARALLEL_DISALLOWED", {
|
||||
group,
|
||||
runUrl,
|
||||
ciBuildId,
|
||||
})
|
||||
when "PARALLEL_REQUIRED"
|
||||
errors.throw("DASHBOARD_PARALLEL_REQUIRED", {
|
||||
group,
|
||||
runUrl,
|
||||
ciBuildId,
|
||||
})
|
||||
when "ALREADY_COMPLETE"
|
||||
errors.throw("DASHBOARD_ALREADY_COMPLETE", {
|
||||
runUrl,
|
||||
group,
|
||||
parallel,
|
||||
ciBuildId,
|
||||
})
|
||||
when "STALE_RUN"
|
||||
errors.throw("DASHBOARD_STALE_RUN", {
|
||||
runUrl,
|
||||
group,
|
||||
parallel,
|
||||
ciBuildId,
|
||||
})
|
||||
else
|
||||
errors.throw("DASHBOARD_UNKNOWN_INVALID_REQUEST", {
|
||||
error: err,
|
||||
flags: {
|
||||
group,
|
||||
parallel,
|
||||
ciBuildId,
|
||||
},
|
||||
})
|
||||
else
|
||||
if parallel
|
||||
return errors.throw("DASHBOARD_CANNOT_PROCEED_IN_PARALLEL", {
|
||||
error: err,
|
||||
flags: {
|
||||
group,
|
||||
ciBuildId,
|
||||
},
|
||||
})
|
||||
|
||||
## warn the user that assets will be not recorded
|
||||
errors.warning("DASHBOARD_CANNOT_CREATE_RUN_OR_INSTANCE", err)
|
||||
|
||||
@@ -252,7 +370,7 @@ createRun = (options = {}) ->
|
||||
.return(null)
|
||||
|
||||
createInstance = (options = {}) ->
|
||||
{ runId, groupId, machineId, platform, spec } = options
|
||||
{ runId, group, groupId, parallel, machineId, ciBuildId, platform, spec } = options
|
||||
|
||||
spec = getSpecRelativePath(spec)
|
||||
|
||||
@@ -274,6 +392,15 @@ createInstance = (options = {}) ->
|
||||
stack: err.stack
|
||||
})
|
||||
|
||||
if parallel
|
||||
return errors.throw("DASHBOARD_CANNOT_PROCEED_IN_PARALLEL", {
|
||||
error: err,
|
||||
flags: {
|
||||
group,
|
||||
ciBuildId,
|
||||
},
|
||||
})
|
||||
|
||||
errors.warning("DASHBOARD_CANNOT_CREATE_RUN_OR_INSTANCE", err)
|
||||
|
||||
## dont log exceptions if we have a 503 status code
|
||||
@@ -284,7 +411,7 @@ createInstance = (options = {}) ->
|
||||
null
|
||||
|
||||
createRunAndRecordSpecs = (options = {}) ->
|
||||
{ specPattern, specs, sys, browser, projectId, projectRoot, runAllSpecs } = options
|
||||
{ specPattern, specs, sys, browser, projectId, projectRoot, runAllSpecs, parallel, ciBuildId, group } = options
|
||||
|
||||
recordKey = options.key
|
||||
|
||||
@@ -302,8 +429,11 @@ createRunAndRecordSpecs = (options = {}) ->
|
||||
createRun({
|
||||
git
|
||||
specs
|
||||
group
|
||||
parallel
|
||||
platform
|
||||
recordKey
|
||||
ciBuildId
|
||||
projectId
|
||||
specPattern
|
||||
})
|
||||
@@ -317,6 +447,8 @@ createRunAndRecordSpecs = (options = {}) ->
|
||||
instanceId = null
|
||||
|
||||
beforeSpecRun = (spec) ->
|
||||
debug("before spec run %o", { spec })
|
||||
|
||||
capture.restore()
|
||||
|
||||
captured = capture.stdout()
|
||||
@@ -324,18 +456,32 @@ createRunAndRecordSpecs = (options = {}) ->
|
||||
createInstance({
|
||||
spec
|
||||
runId
|
||||
group
|
||||
groupId
|
||||
platform
|
||||
parallel
|
||||
ciBuildId
|
||||
machineId
|
||||
})
|
||||
.then (id) ->
|
||||
instanceId = id
|
||||
.then (resp = {}) ->
|
||||
{ instanceId } = resp
|
||||
|
||||
afterSpecRun = (results, config) ->
|
||||
## pull off only what we need
|
||||
return _
|
||||
.chain(resp)
|
||||
.pick("spec", "claimedInstances", "totalInstances")
|
||||
.extend({
|
||||
estimated: resp.estimatedWallClockDuration
|
||||
})
|
||||
.value()
|
||||
|
||||
afterSpecRun = (spec, results, config) ->
|
||||
## dont do anything if we failed to
|
||||
## create the instance
|
||||
return if not instanceId
|
||||
|
||||
debug("after spec run %o", { spec })
|
||||
|
||||
console.log("")
|
||||
|
||||
terminal.header("Uploading Results", {
|
||||
@@ -345,9 +491,12 @@ createRunAndRecordSpecs = (options = {}) ->
|
||||
console.log("")
|
||||
|
||||
updateInstance({
|
||||
group
|
||||
config
|
||||
results
|
||||
captured
|
||||
parallel
|
||||
ciBuildId
|
||||
instanceId
|
||||
})
|
||||
.then (resp) ->
|
||||
@@ -388,8 +537,14 @@ module.exports = {
|
||||
|
||||
throwIfNoProjectId
|
||||
|
||||
throwIfIndeterminateCiBuildId
|
||||
|
||||
throwIfIncorrectCiBuildIdUsage
|
||||
|
||||
warnIfProjectIdButNoRecordOption
|
||||
|
||||
throwIfRecordParamsWithoutRecording
|
||||
|
||||
createRunAndRecordSpecs
|
||||
|
||||
}
|
||||
|
||||
@@ -86,6 +86,11 @@ formatSpecSummary = (name, failures) ->
|
||||
]
|
||||
.join(" ")
|
||||
|
||||
formatRecordParams = (runUrl, parallel, group) ->
|
||||
if runUrl
|
||||
group or= false
|
||||
"Group: #{group}, Parallel: #{Boolean(parallel)}"
|
||||
|
||||
formatSpecPattern = (specPattern) ->
|
||||
if specPattern
|
||||
specPattern.join(", ")
|
||||
@@ -103,7 +108,7 @@ formatSpecs = (specs) ->
|
||||
.join("")
|
||||
|
||||
displayRunStarting = (options = {}) ->
|
||||
{ specs, specPattern, browser, runUrl } = options
|
||||
{ specs, specPattern, browser, runUrl, parallel, group } = options
|
||||
|
||||
console.log("")
|
||||
|
||||
@@ -128,6 +133,7 @@ displayRunStarting = (options = {}) ->
|
||||
[gray("Browser:"), formatBrowser(browser)]
|
||||
[gray("Specs:"), formatSpecs(specs)]
|
||||
[gray("Searched:"), formatSpecPattern(specPattern)]
|
||||
[gray("Params:"), formatRecordParams(runUrl, parallel, group)]
|
||||
[gray("Run URL:"), runUrl]
|
||||
])
|
||||
.filter(_.property(1))
|
||||
@@ -139,15 +145,17 @@ displayRunStarting = (options = {}) ->
|
||||
|
||||
console.log("")
|
||||
|
||||
displaySpecHeader = (name, curr, total) ->
|
||||
displaySpecHeader = (name, curr, total, estimated) ->
|
||||
console.log("")
|
||||
|
||||
PADDING = 2
|
||||
|
||||
table = terminal.table({
|
||||
colWidths: [80, 20]
|
||||
colAligns: ["left", "right"]
|
||||
type: "pageDivider"
|
||||
style: {
|
||||
"padding-left": 2
|
||||
"padding-left": PADDING
|
||||
}
|
||||
})
|
||||
|
||||
@@ -159,7 +167,11 @@ displaySpecHeader = (name, curr, total) ->
|
||||
|
||||
console.log(table.toString())
|
||||
|
||||
collectTestResults = (obj = {}) ->
|
||||
if estimated
|
||||
estimatedLabel = " ".repeat(PADDING) + "Estimated:"
|
||||
console.log(estimatedLabel, humanTime.long(estimated))
|
||||
|
||||
collectTestResults = (obj = {}, estimated) ->
|
||||
{
|
||||
name: _.get(obj, 'spec.name')
|
||||
tests: _.get(obj, 'stats.tests')
|
||||
@@ -168,11 +180,12 @@ collectTestResults = (obj = {}) ->
|
||||
failures: _.get(obj, 'stats.failures')
|
||||
skipped: _.get(obj, 'stats.skipped' )
|
||||
duration: humanTime.long(_.get(obj, 'stats.wallClockDuration'))
|
||||
estimated: estimated and humanTime.long(estimated)
|
||||
screenshots: obj.screenshots and obj.screenshots.length
|
||||
video: Boolean(obj.video)
|
||||
}
|
||||
|
||||
renderSummaryTable = (runUrl, results) ->
|
||||
renderSummaryTable = (runUrl) -> (results) ->
|
||||
{ runs } = results
|
||||
|
||||
console.log("")
|
||||
@@ -250,6 +263,56 @@ renderSummaryTable = (runUrl, results) ->
|
||||
console.log(terminal.renderTables(table4))
|
||||
console.log("")
|
||||
|
||||
iterateThroughSpecs = (options = {}) ->
|
||||
{ specs, runEachSpec, parallel, beforeSpecRun, afterSpecRun, config } = options
|
||||
|
||||
serial = ->
|
||||
Promise.mapSeries(specs, runEachSpec)
|
||||
|
||||
serialWithRecord = ->
|
||||
Promise
|
||||
.mapSeries specs, (spec, index, length) ->
|
||||
beforeSpecRun(spec)
|
||||
.then ({ estimated }) ->
|
||||
runEachSpec(spec, index, length, estimated)
|
||||
.tap (results) ->
|
||||
afterSpecRun(spec, results, config)
|
||||
|
||||
parallelWithRecord = (runs) ->
|
||||
beforeSpecRun()
|
||||
.then ({ spec, claimedInstances, totalInstances, estimated }) ->
|
||||
## no more specs to run?
|
||||
if not spec
|
||||
## then we're done!
|
||||
return runs
|
||||
|
||||
## find the actual spec object amongst
|
||||
## our specs array since the API sends us
|
||||
## the relative name
|
||||
spec = _.find(specs, { relative: spec })
|
||||
|
||||
runEachSpec(spec, claimedInstances - 1, totalInstances, estimated)
|
||||
.tap (results) ->
|
||||
runs.push(results)
|
||||
|
||||
afterSpecRun(spec, results, config)
|
||||
.then ->
|
||||
## recurse
|
||||
parallelWithRecord(runs)
|
||||
|
||||
switch
|
||||
when parallel
|
||||
## if we are running in parallel
|
||||
## then ask the server for the next spec
|
||||
parallelWithRecord([])
|
||||
when beforeSpecRun
|
||||
## else iterate serialially and record
|
||||
## the results of each spec
|
||||
serialWithRecord()
|
||||
else
|
||||
## else iterate in serial
|
||||
serial()
|
||||
|
||||
getProjectId = (project, id) ->
|
||||
id ?= env.get("CYPRESS_PROJECT_ID")
|
||||
|
||||
@@ -288,7 +351,7 @@ openProjectCreate = (projectRoot, socketId, options) ->
|
||||
socketId
|
||||
morgan: false
|
||||
report: true
|
||||
isTextTerminal: options.isTextTerminal ? true
|
||||
isTextTerminal: options.isTextTerminal
|
||||
onError: (err) ->
|
||||
console.log("")
|
||||
console.log(err.stack)
|
||||
@@ -316,6 +379,12 @@ createAndOpenProject = (socketId, options) ->
|
||||
projectId: getProjectId(project, projectId)
|
||||
})
|
||||
|
||||
removeOldProfiles = ->
|
||||
browsers.removeOldProfiles()
|
||||
.catch (err) ->
|
||||
## dont make removing old browsers profiles break the build
|
||||
errors.warning("CANNOT_REMOVE_OLD_BROWSER_PROFILES", err.stack)
|
||||
|
||||
trashAssets = (config = {}) ->
|
||||
if config.trashAssetsBeforeRuns isnt true
|
||||
return Promise.resolve()
|
||||
@@ -375,8 +444,8 @@ module.exports = {
|
||||
|
||||
obj
|
||||
|
||||
displayResults: (obj = {}) ->
|
||||
results = collectTestResults(obj)
|
||||
displayResults: (obj = {}, estimated) ->
|
||||
results = collectTestResults(obj, estimated)
|
||||
|
||||
c = if results.failures then "red" else "green"
|
||||
|
||||
@@ -390,7 +459,7 @@ module.exports = {
|
||||
type: "outsideBorder"
|
||||
})
|
||||
|
||||
data = _.map [
|
||||
data = _.chain([
|
||||
["Tests:", results.tests]
|
||||
["Passing:", results.passes]
|
||||
["Failing:", results.failures]
|
||||
@@ -399,11 +468,15 @@ module.exports = {
|
||||
["Screenshots:", results.screenshots]
|
||||
["Video:", results.video]
|
||||
["Duration:", results.duration]
|
||||
["Estimated:", results.estimated] if estimated
|
||||
["Spec Ran:", results.name]
|
||||
], (arr) ->
|
||||
])
|
||||
.compact()
|
||||
.map (arr) ->
|
||||
[key, val] = arr
|
||||
|
||||
[color(key, "gray"), color(val, c)]
|
||||
.value()
|
||||
|
||||
table.push(data...)
|
||||
|
||||
@@ -593,7 +666,7 @@ module.exports = {
|
||||
project.on("socket:connected", fn)
|
||||
|
||||
waitForTestsToFinishRunning: (options = {}) ->
|
||||
{ project, screenshots, started, end, name, cname, videoCompression, videoUploadOnPasses, exit, spec } = options
|
||||
{ project, screenshots, started, end, name, cname, videoCompression, videoUploadOnPasses, exit, spec, estimated } = options
|
||||
|
||||
@listenForProjectEnd(project, exit)
|
||||
.then (obj) =>
|
||||
@@ -617,7 +690,7 @@ module.exports = {
|
||||
finish = ->
|
||||
return obj
|
||||
|
||||
@displayResults(obj)
|
||||
@displayResults(obj, estimated)
|
||||
|
||||
if screenshots and screenshots.length
|
||||
@displayScreenshots(screenshots)
|
||||
@@ -665,7 +738,7 @@ module.exports = {
|
||||
}
|
||||
|
||||
runSpecs: (options = {}) ->
|
||||
{ config, browser, sys, headed, outputPath, specs, specPattern, beforeSpecRun, afterSpecRun, runUrl } = options
|
||||
{ config, browser, sys, headed, outputPath, specs, specPattern, beforeSpecRun, afterSpecRun, runUrl, parallel, group } = options
|
||||
|
||||
isHeadless = browser.name is "electron" and not headed
|
||||
|
||||
@@ -694,33 +767,29 @@ module.exports = {
|
||||
|
||||
displayRunStarting({
|
||||
specs
|
||||
group
|
||||
runUrl
|
||||
browser
|
||||
parallel
|
||||
specPattern
|
||||
})
|
||||
|
||||
runEachSpec = (spec, index, length) =>
|
||||
Promise
|
||||
.try ->
|
||||
if beforeSpecRun
|
||||
debug("before spec run %o", spec)
|
||||
runEachSpec = (spec, index, length, estimated) =>
|
||||
displaySpecHeader(spec.name, index + 1, length, estimated)
|
||||
|
||||
beforeSpecRun(spec)
|
||||
.then =>
|
||||
displaySpecHeader(spec.name, index + 1, length)
|
||||
|
||||
@runSpec(spec, options)
|
||||
@runSpec(spec, options, estimated)
|
||||
.get("results")
|
||||
.tap (results) ->
|
||||
debug("spec results %o", results)
|
||||
|
||||
if afterSpecRun
|
||||
debug("after spec run %o", spec)
|
||||
|
||||
afterSpecRun(results, config)
|
||||
|
||||
Promise
|
||||
.mapSeries(specs, runEachSpec)
|
||||
iterateThroughSpecs({
|
||||
specs
|
||||
config
|
||||
parallel
|
||||
runEachSpec
|
||||
afterSpecRun
|
||||
beforeSpecRun
|
||||
})
|
||||
.then (runs = []) ->
|
||||
results.startedTestsAt = start = getRun(_.first(runs), "stats.wallClockStartedAt")
|
||||
results.endedTestsAt = end = getRun(_.last(runs), "stats.wallClockEndedAt")
|
||||
@@ -738,7 +807,7 @@ module.exports = {
|
||||
writeOutput(outputPath, results)
|
||||
.return(results)
|
||||
|
||||
runSpec: (spec = {}, options = {}) ->
|
||||
runSpec: (spec = {}, options = {}, estimated) ->
|
||||
{ project, browser, video, videosFolder } = options
|
||||
|
||||
{ isHeadless, isHeaded } = browser
|
||||
@@ -797,6 +866,7 @@ module.exports = {
|
||||
cname
|
||||
started
|
||||
project
|
||||
estimated
|
||||
screenshots
|
||||
exit: options.exit
|
||||
videoCompression: options.videoCompression
|
||||
@@ -831,12 +901,13 @@ module.exports = {
|
||||
debug("run mode ready with options %o", options)
|
||||
|
||||
_.defaults(options, {
|
||||
isTextTerminal: true
|
||||
browser: "electron"
|
||||
})
|
||||
|
||||
socketId = random.id()
|
||||
|
||||
{ projectRoot, record, key } = options
|
||||
{ projectRoot, record, key, ciBuildId, parallel, group } = options
|
||||
|
||||
browserName = options.browser
|
||||
|
||||
@@ -852,15 +923,19 @@ module.exports = {
|
||||
.then ({ project, projectId, config }) =>
|
||||
## if we have a project id and a key but record hasnt been given
|
||||
recordMode.warnIfProjectIdButNoRecordOption(projectId, options)
|
||||
recordMode.throwIfRecordParamsWithoutRecording(record, ciBuildId, parallel, group)
|
||||
|
||||
if record
|
||||
recordMode.throwIfNoProjectId(projectId)
|
||||
recordMode.throwIfIncorrectCiBuildIdUsage(ciBuildId, parallel, group)
|
||||
recordMode.throwIfIndeterminateCiBuildId(ciBuildId, parallel, group)
|
||||
|
||||
Promise.all([
|
||||
system.info(),
|
||||
browsers.ensureAndGetByName(browserName),
|
||||
@findSpecs(config, specPattern),
|
||||
trashAssets(config),
|
||||
removeOldProfiles()
|
||||
])
|
||||
.spread (sys = {}, browser = {}, specs = []) =>
|
||||
## return only what is return to the specPattern
|
||||
@@ -877,9 +952,11 @@ module.exports = {
|
||||
projectRoot
|
||||
specPattern
|
||||
socketId
|
||||
parallel
|
||||
browser
|
||||
project
|
||||
runUrl
|
||||
group
|
||||
config
|
||||
specs
|
||||
sys
|
||||
@@ -891,7 +968,7 @@ module.exports = {
|
||||
headed: options.headed
|
||||
outputPath: options.outputPath
|
||||
})
|
||||
.tap(_.partial(renderSummaryTable, runUrl))
|
||||
.tap(renderSummaryTable(runUrl))
|
||||
|
||||
if record
|
||||
{ projectName } = config
|
||||
@@ -900,7 +977,10 @@ module.exports = {
|
||||
key
|
||||
sys
|
||||
specs
|
||||
group
|
||||
browser
|
||||
parallel
|
||||
ciBuildId
|
||||
projectId
|
||||
projectRoot
|
||||
projectName
|
||||
|
||||
@@ -6,13 +6,15 @@ la = require("lazy-ass")
|
||||
check = require("check-more-types")
|
||||
log = require("debug")("cypress:server:appdata")
|
||||
pkg = require("@packages/root")
|
||||
cwd = require("../cwd")
|
||||
fs = require("../util/fs")
|
||||
cwd = require("../cwd")
|
||||
|
||||
name = pkg.productName or pkg.name
|
||||
data = ospath.data()
|
||||
PRODUCT_NAME = pkg.productName or pkg.name
|
||||
OS_DATA_PATH = ospath.data()
|
||||
|
||||
if not name
|
||||
ELECTRON_APP_DATA_PATH = path.join(OS_DATA_PATH, PRODUCT_NAME)
|
||||
|
||||
if not PRODUCT_NAME
|
||||
throw new Error("Root package is missing name")
|
||||
|
||||
getSymlinkType = ->
|
||||
@@ -52,10 +54,14 @@ module.exports = {
|
||||
path: (paths...) ->
|
||||
la(check.unemptyString(process.env.CYPRESS_ENV),
|
||||
"expected CYPRESS_ENV, found", process.env.CYPRESS_ENV)
|
||||
p = path.join(data, name, "cy", process.env.CYPRESS_ENV, paths...)
|
||||
|
||||
p = path.join(ELECTRON_APP_DATA_PATH, "cy", process.env.CYPRESS_ENV, paths...)
|
||||
log("path: %s", p)
|
||||
p
|
||||
|
||||
electronPartitionsPath: ->
|
||||
path.join(ELECTRON_APP_DATA_PATH, "Partitions")
|
||||
|
||||
projectsPath: (paths...) ->
|
||||
@path("projects", paths...)
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ nestedObjectsInCurlyBracesRe = /\{(.+?)\}/g
|
||||
nestedArraysInSquareBracketsRe = /\[(.+?)\]/g
|
||||
everythingAfterFirstEqualRe = /=(.+)/
|
||||
|
||||
whitelist = "cwd appPath execPath apiKey smokeTest getKey generateKey runProject project spec reporter reporterOptions port env ci record updating ping key logs clearLogs returnPkg version mode headed config exit exitWithCode browser runMode outputPath parallel parallelId".split(" ")
|
||||
whitelist = "cwd appPath execPath apiKey smokeTest getKey generateKey runProject project spec reporter reporterOptions port env ci record updating ping key logs clearLogs returnPkg version mode headed config exit exitWithCode browser runMode outputPath parallel ciBuildId group".split(" ")
|
||||
|
||||
# returns true if the given string has double quote character "
|
||||
# only at the last position.
|
||||
@@ -121,6 +121,7 @@ module.exports = {
|
||||
"run-project": "runProject"
|
||||
"return-pkg": "returnPkg"
|
||||
"run-mode": "isTextTerminal"
|
||||
"ci-build-id": "ciBuildId"
|
||||
"exit-with-code": "exitWithCode"
|
||||
"reporter-options": "reporterOptions"
|
||||
"output-path": "outputPath"
|
||||
|
||||
@@ -311,7 +311,12 @@ commitDefaults = (existingInfo) ->
|
||||
_.transform existingInfo, (memo, value, key) ->
|
||||
memo[key] = _.defaultTo(value ? commitParamsObj[key], null)
|
||||
|
||||
list = ->
|
||||
_.keys(CI_PROVIDERS)
|
||||
|
||||
module.exports = {
|
||||
list
|
||||
|
||||
provider
|
||||
|
||||
ciParams
|
||||
|
||||
9
packages/server/lib/util/find_process.js
Normal file
9
packages/server/lib/util/find_process.js
Normal file
@@ -0,0 +1,9 @@
|
||||
const findProcess = require('find-process')
|
||||
|
||||
const byPid = (pid) => {
|
||||
return findProcess('pid', pid)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
byPid,
|
||||
}
|
||||
90
packages/server/lib/util/profile_cleaner.js
Normal file
90
packages/server/lib/util/profile_cleaner.js
Normal file
@@ -0,0 +1,90 @@
|
||||
const _ = require('lodash')
|
||||
const path = require('path')
|
||||
const debug = require('debug')('cypress:server:profilecleaner')
|
||||
const fs = require('./fs')
|
||||
const glob = require('./glob')
|
||||
const findProcess = require('./find_process')
|
||||
|
||||
const includesCypress = (str) => {
|
||||
return _.chain(str).lowerCase().includes('cypress').value()
|
||||
}
|
||||
|
||||
const isCypressProcess = (process) => {
|
||||
debug('got process %o', process)
|
||||
|
||||
return _.some([process.cmd, process.name], includesCypress)
|
||||
}
|
||||
|
||||
const getPidFromFolder = (folder, pidPrefix) => {
|
||||
return _.toNumber(
|
||||
path.basename(folder).replace(pidPrefix, '')
|
||||
)
|
||||
}
|
||||
|
||||
const folderWithPid = (pidPrefix) => (folder) => {
|
||||
return {
|
||||
folder,
|
||||
pid: getPidFromFolder(folder, pidPrefix),
|
||||
}
|
||||
}
|
||||
|
||||
// find all the pids not associated to a cypress process
|
||||
const inactivePids = ({ pid }) => {
|
||||
debug('finding process by pid:', pid)
|
||||
if (!_.isFinite(pid)) {
|
||||
return null
|
||||
}
|
||||
|
||||
return findProcess.byPid(pid)
|
||||
.then((processes) => {
|
||||
// return true if no processes are a cypress process
|
||||
return !_.some(processes, isCypressProcess)
|
||||
})
|
||||
}
|
||||
|
||||
const removeProfile = ({ pid, folder }) => {
|
||||
debug('removing old profile %o', { pid, folder })
|
||||
|
||||
return fs.removeAsync(folder)
|
||||
}
|
||||
|
||||
const removeMatch = (match) => {
|
||||
debug('removed root profile object %o', { path: match })
|
||||
|
||||
return fs.removeAsync(match)
|
||||
}
|
||||
|
||||
const removeInactiveByPid = (pathToProfiles, pidPrefix) => {
|
||||
const pattern = path.join(pathToProfiles, `${pidPrefix}*`)
|
||||
|
||||
return glob(pattern, { absolute: true })
|
||||
.tap((folders) => {
|
||||
debug('found %d profile folders: %o', folders.length, folders)
|
||||
})
|
||||
.map(folderWithPid(pidPrefix))
|
||||
.filter(inactivePids)
|
||||
.map(removeProfile)
|
||||
}
|
||||
|
||||
const removeRootProfile = (pathToProfiles, ignore) => {
|
||||
const pattern = path.join(pathToProfiles, '*')
|
||||
|
||||
return glob(pattern, { absolute: true, dot: true, ignore })
|
||||
.tap((matches) => {
|
||||
debug('found %d root level profile matches: %o', matches.length, matches)
|
||||
})
|
||||
.map(removeMatch)
|
||||
.catchReturn(null) // swallow errors
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
inactivePids,
|
||||
|
||||
isCypressProcess,
|
||||
|
||||
getPidFromFolder,
|
||||
|
||||
removeRootProfile,
|
||||
|
||||
removeInactiveByPid,
|
||||
}
|
||||
@@ -67,7 +67,7 @@
|
||||
"react": "^15.2.1",
|
||||
"repl.history": "^0.1.3",
|
||||
"run-sequence": "^1.0.2",
|
||||
"snap-shot-it": "2.0.0",
|
||||
"snap-shot-it": "5.0.1",
|
||||
"ssestream": "^1.0.1",
|
||||
"stream-to-promise": "^1.1.0",
|
||||
"supertest": "^0.15.0",
|
||||
@@ -110,8 +110,9 @@
|
||||
"evil-dns": "^0.2.0",
|
||||
"execa": "^0.8.0",
|
||||
"express": "4.16.2",
|
||||
"find-process": "^1.1.1",
|
||||
"fluent-ffmpeg": "^2.1.0",
|
||||
"fs-extra": "4.0.1",
|
||||
"fs-extra": "4.0.3",
|
||||
"getos": "^2.8.2",
|
||||
"glob": "7.1.2",
|
||||
"graceful-fs": "^4.1.11",
|
||||
|
||||
@@ -304,6 +304,145 @@ describe "e2e record", ->
|
||||
expect(forthInstanceStdout.body.stdout).not.to.include("record_fail_spec.coffee")
|
||||
expect(forthInstanceStdout.body.stdout).not.to.include("record_pass_spec.coffee")
|
||||
|
||||
context "parallelization", ->
|
||||
allSpecs = [
|
||||
"cypress/integration/record_error_spec.coffee",
|
||||
"cypress/integration/record_fail_spec.coffee",
|
||||
"cypress/integration/record_pass_spec.coffee",
|
||||
"cypress/integration/record_uncaught_spec.coffee",
|
||||
]
|
||||
|
||||
postInstanceResponses = (specs) ->
|
||||
return _
|
||||
.chain(specs)
|
||||
.map (spec, i) ->
|
||||
return {
|
||||
spec
|
||||
instanceId
|
||||
estimatedWallClockDuration: (i + 1) * 1000
|
||||
}
|
||||
.concat({
|
||||
spec: null
|
||||
instanceId: null,
|
||||
estimatedWallClockDuration: null
|
||||
})
|
||||
.value()
|
||||
|
||||
## a1 does 3 specs, b2 does 1 spec
|
||||
a1Specs = _.without(allSpecs, "cypress/integration/record_pass_spec.coffee")
|
||||
b2Specs = _.difference(allSpecs, a1Specs)
|
||||
|
||||
firstRunResponse = false
|
||||
waitUntilSecondInstanceClaims = null
|
||||
|
||||
claimed = []
|
||||
|
||||
responses = {
|
||||
a1: postInstanceResponses(a1Specs)
|
||||
b2: postInstanceResponses(b2Specs)
|
||||
}
|
||||
|
||||
## replace the 1st + 2nd routes object
|
||||
routes = defaultRoutes.slice(0)
|
||||
routes[0] = {
|
||||
method: "post"
|
||||
url: "/runs"
|
||||
req: "postRunRequest@2.1.0",
|
||||
res: (req, res) ->
|
||||
{ group, ciBuildId } = req.body
|
||||
|
||||
expect(group).to.eq("prod-e2e")
|
||||
expect(ciBuildId).to.eq("ciBuildId123")
|
||||
|
||||
## if this is the first response
|
||||
## give machineId a1, else b2
|
||||
if not firstRunResponse
|
||||
firstRunResponse = true
|
||||
machineId = "a1ad2bcf-6398-46ed-b201-2fd90b188d5f"
|
||||
else
|
||||
machineId = "b2bd2bcf-6398-46ed-b201-2fd90b188d5f"
|
||||
|
||||
res.json(
|
||||
_.extend({}, postRunResponse, { machineId })
|
||||
)
|
||||
|
||||
}
|
||||
routes[1] = {
|
||||
method: "post"
|
||||
url: "/runs/:id/instances"
|
||||
req: "postRunInstanceRequest@2.1.0",
|
||||
res: (req, res) ->
|
||||
{ machineId, spec } = req.body
|
||||
|
||||
expect(spec).to.be.null
|
||||
|
||||
mId = machineId.slice(0, 2)
|
||||
|
||||
respond = ->
|
||||
resp = responses[mId].shift()
|
||||
|
||||
## if theres a spec to claim
|
||||
if resp.spec
|
||||
claimed.push(resp)
|
||||
|
||||
resp.claimedInstances = claimed.length
|
||||
resp.totalInstances = allSpecs.length
|
||||
|
||||
jsonSchemas.assertSchema("postRunInstanceResponse", "2.1.0")(resp)
|
||||
res.json(resp)
|
||||
|
||||
## when the 1st machine attempts to claim its FIRST spec, we
|
||||
## automatically delay it until the 2nd machine claims its FIRST
|
||||
## spec so that the request URL's are deterministic
|
||||
if mId is "a1" and claimed.length is 0
|
||||
waitUntilSecondInstanceClaims = ->
|
||||
waitUntilSecondInstanceClaims = null
|
||||
respond()
|
||||
else
|
||||
respond()
|
||||
waitUntilSecondInstanceClaims?()
|
||||
}
|
||||
|
||||
setup(routes)
|
||||
|
||||
it "passes in parallel with group", ->
|
||||
Promise.all([
|
||||
e2e.exec(@, {
|
||||
key: "f858a2bc-b469-4e48-be67-0876339ee7e1"
|
||||
spec: "record*"
|
||||
group: "prod-e2e"
|
||||
record: true
|
||||
parallel: true
|
||||
snapshot: true
|
||||
ciBuildId: "ciBuildId123"
|
||||
expectedExitCode: 3
|
||||
config: {
|
||||
trashAssetsBeforeRuns: false
|
||||
}
|
||||
})
|
||||
.get("stdout"),
|
||||
|
||||
## stagger the 2nd instance
|
||||
## starting up a bit
|
||||
Promise
|
||||
.delay(3000)
|
||||
.then =>
|
||||
e2e.exec(@, {
|
||||
key: "f858a2bc-b469-4e48-be67-0876339ee7e1"
|
||||
spec: "record*"
|
||||
group: "prod-e2e"
|
||||
record: true
|
||||
parallel: true
|
||||
snapshot: true
|
||||
ciBuildId: "ciBuildId123"
|
||||
expectedExitCode: 0
|
||||
config: {
|
||||
trashAssetsBeforeRuns: false
|
||||
}
|
||||
})
|
||||
.get("stdout")
|
||||
])
|
||||
|
||||
context "misconfiguration", ->
|
||||
setup([])
|
||||
|
||||
@@ -423,7 +562,7 @@ describe "e2e record", ->
|
||||
expectedExitCode: 1
|
||||
})
|
||||
|
||||
describe "create run", ->
|
||||
describe "create run 500", ->
|
||||
routes = [{
|
||||
method: "post"
|
||||
url: "/runs"
|
||||
@@ -450,6 +589,192 @@ describe "e2e record", ->
|
||||
"POST /runs"
|
||||
])
|
||||
|
||||
it "warns but proceeds when grouping without parallelization", ->
|
||||
process.env.DISABLE_API_RETRIES = "true"
|
||||
|
||||
e2e.exec(@, {
|
||||
key: "f858a2bc-b469-4e48-be67-0876339ee7e1"
|
||||
spec: "record_pass*"
|
||||
group: "foo"
|
||||
record: true
|
||||
snapshot: true
|
||||
ciBuildId: "ciBuildId123"
|
||||
expectedExitCode: 0
|
||||
})
|
||||
.then ->
|
||||
urls = getRequestUrls()
|
||||
|
||||
expect(urls).to.deep.eq([
|
||||
"POST /runs"
|
||||
])
|
||||
|
||||
it "does not proceed and exits with error when parallelizing", ->
|
||||
process.env.DISABLE_API_RETRIES = "true"
|
||||
|
||||
e2e.exec(@, {
|
||||
key: "f858a2bc-b469-4e48-be67-0876339ee7e1"
|
||||
spec: "record_pass*"
|
||||
group: "foo"
|
||||
record: true
|
||||
parallel: true
|
||||
snapshot: true
|
||||
ciBuildId: "ciBuildId123"
|
||||
expectedExitCode: 1
|
||||
})
|
||||
.then ->
|
||||
urls = getRequestUrls()
|
||||
|
||||
expect(urls).to.deep.eq([
|
||||
"POST /runs"
|
||||
])
|
||||
|
||||
describe "create instance 500", ->
|
||||
routes = defaultRoutes.slice(0)
|
||||
|
||||
routes[1] = {
|
||||
method: "post"
|
||||
url: "/runs/:id/instances"
|
||||
req: "postRunInstanceRequest@2.1.0",
|
||||
res: (req, res) -> res.sendStatus(500)
|
||||
}
|
||||
|
||||
setup(routes)
|
||||
|
||||
it "does not proceed and exits with error when parallelizing and creating instance", ->
|
||||
process.env.DISABLE_API_RETRIES = "true"
|
||||
|
||||
e2e.exec(@, {
|
||||
key: "f858a2bc-b469-4e48-be67-0876339ee7e1"
|
||||
spec: "record_pass*"
|
||||
group: "foo"
|
||||
record: true
|
||||
parallel: true
|
||||
snapshot: true
|
||||
ciBuildId: "ciBuildId123"
|
||||
expectedExitCode: 1
|
||||
})
|
||||
.then ->
|
||||
urls = getRequestUrls()
|
||||
|
||||
expect(urls).to.deep.eq([
|
||||
"POST /runs",
|
||||
"POST /runs/#{runId}/instances"
|
||||
])
|
||||
|
||||
describe "update instance 500", ->
|
||||
routes = defaultRoutes.slice(0)
|
||||
|
||||
routes[1] = {
|
||||
method: "post"
|
||||
url: "/runs/:id/instances"
|
||||
req: "postRunInstanceRequest@2.1.0",
|
||||
res: (req, res) ->
|
||||
res.json({
|
||||
instanceId
|
||||
spec: "cypress/integration/record_pass_spec.coffee"
|
||||
estimatedWallClockDuration: 5000
|
||||
totalInstances: 1
|
||||
claimedInstances: 1
|
||||
})
|
||||
}
|
||||
|
||||
routes[2] = {
|
||||
method: "put"
|
||||
url: "/instances/:id"
|
||||
req: "putInstanceRequest@2.0.0",
|
||||
res: (req, res) -> res.sendStatus(500)
|
||||
}
|
||||
|
||||
setup(routes)
|
||||
|
||||
it "does not proceed and exits with error when parallelizing and updating instance", ->
|
||||
process.env.DISABLE_API_RETRIES = "true"
|
||||
|
||||
e2e.exec(@, {
|
||||
key: "f858a2bc-b469-4e48-be67-0876339ee7e1"
|
||||
spec: "record_pass*"
|
||||
group: "foo"
|
||||
record: true
|
||||
parallel: true
|
||||
snapshot: true
|
||||
ciBuildId: "ciBuildId123"
|
||||
expectedExitCode: 1
|
||||
})
|
||||
.then ->
|
||||
urls = getRequestUrls()
|
||||
|
||||
expect(urls).to.deep.eq([
|
||||
"POST /runs",
|
||||
"POST /runs/#{runId}/instances"
|
||||
"PUT /instances/e9e81b5e-cc58-4026-b2ff-8ae3161435a6"
|
||||
])
|
||||
|
||||
describe "create run 422", ->
|
||||
routes = [{
|
||||
method: "post"
|
||||
url: "/runs"
|
||||
req: "postRunRequest@2.1.0",
|
||||
res: (req, res) -> res.status(422).json({
|
||||
code: "RUN_GROUP_NAME_NOT_UNIQUE"
|
||||
message: "Run group name cannot be used again without passing the parallel flag."
|
||||
payload: {
|
||||
runUrl: "https://dashboard.cypress.io/runs/12345"
|
||||
}
|
||||
})
|
||||
}]
|
||||
|
||||
setup(routes)
|
||||
|
||||
## the other 422 tests for this are in integration/cypress_spec
|
||||
it "errors and exits when group name is in use", ->
|
||||
process.env.CIRCLECI = "1"
|
||||
|
||||
e2e.exec(@, {
|
||||
key: "f858a2bc-b469-4e48-be67-0876339ee7e1"
|
||||
spec: "record_pass*"
|
||||
group: "e2e-tests"
|
||||
record: true
|
||||
snapshot: true
|
||||
expectedExitCode: 1
|
||||
})
|
||||
.then ->
|
||||
urls = getRequestUrls()
|
||||
|
||||
expect(urls).to.deep.eq([
|
||||
"POST /runs"
|
||||
])
|
||||
|
||||
describe "create run unknown 422", ->
|
||||
routes = [{
|
||||
method: "post"
|
||||
url: "/runs"
|
||||
req: "postRunRequest@2.1.0",
|
||||
res: (req, res) -> res.status(422).json({
|
||||
code: "SOMETHING_UNKNOWN"
|
||||
message: "An unknown message here from the server."
|
||||
})
|
||||
}]
|
||||
|
||||
setup(routes)
|
||||
|
||||
it "errors and exits when there is an unknown 422 response", ->
|
||||
e2e.exec(@, {
|
||||
key: "f858a2bc-b469-4e48-be67-0876339ee7e1"
|
||||
spec: "record_pass*"
|
||||
group: "e2e-tests"
|
||||
record: true
|
||||
parallel: true
|
||||
snapshot: true
|
||||
ciBuildId: "ciBuildId123"
|
||||
expectedExitCode: 1
|
||||
})
|
||||
.then ->
|
||||
urls = getRequestUrls()
|
||||
|
||||
expect(urls).to.deep.eq([
|
||||
"POST /runs"
|
||||
])
|
||||
|
||||
describe "create instance", ->
|
||||
routes = [
|
||||
{
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
e2e = require("../support/helpers/e2e")
|
||||
|
||||
describe.skip "e2e window.open", ->
|
||||
describe "e2e window.open", ->
|
||||
e2e.setup()
|
||||
|
||||
it "passes", ->
|
||||
e2e.exec(@, {
|
||||
spec: "window_open_spec.coffee"
|
||||
snapshot: true
|
||||
expectedExitCode: 0
|
||||
})
|
||||
## skipping this for now due to
|
||||
## snap-shot-it monkey patching
|
||||
## .only causing test failures
|
||||
# it "passes", ->
|
||||
# e2e.exec(@, {
|
||||
# spec: "window_open_spec.coffee"
|
||||
# snapshot: true
|
||||
# expectedExitCode: 0
|
||||
# })
|
||||
|
||||
@@ -11,6 +11,8 @@ electron = require("electron")
|
||||
commitInfo = require("@cypress/commit-info")
|
||||
isForkPr = require("is-fork-pr")
|
||||
Fixtures = require("../support/helpers/fixtures")
|
||||
snapshot = require("snap-shot-it")
|
||||
stripAnsi = require("strip-ansi")
|
||||
pkg = require("@packages/root")
|
||||
launcher = require("@packages/launcher")
|
||||
extension = require("@packages/extension")
|
||||
@@ -40,6 +42,7 @@ videoCapture = require("#{root}lib/video_capture")
|
||||
browserUtils = require("#{root}lib/browsers/utils")
|
||||
openProject = require("#{root}lib/open_project")
|
||||
env = require("#{root}lib/util/env")
|
||||
system = require("#{root}lib/util/system")
|
||||
appData = require("#{root}lib/util/app_data")
|
||||
formStatePath = require("#{root}lib/util/saved_state").formStatePath
|
||||
|
||||
@@ -62,15 +65,25 @@ TYPICAL_BROWSERS = [
|
||||
version: '62.0.3197.0',
|
||||
path: '/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary',
|
||||
majorVersion: '62'
|
||||
}, {
|
||||
name: 'electron',
|
||||
version: '',
|
||||
path: '',
|
||||
majorVersion: '',
|
||||
info: 'Electron is the default browser that comes with Cypress. This is the browser that runs in headless mode. Selecting this browser is useful when debugging. The version number indicates the underlying Chromium version that Electron uses.'
|
||||
}
|
||||
]
|
||||
|
||||
previousCwd = process.cwd()
|
||||
|
||||
snapshotConsoleLogs = (name) ->
|
||||
args = _
|
||||
.chain(console.log.args)
|
||||
.map (innerArgs) ->
|
||||
innerArgs.join(" ")
|
||||
.join("\n")
|
||||
.value()
|
||||
|
||||
## our cwd() is currently the project
|
||||
## so must switch back to original
|
||||
process.chdir(previousCwd)
|
||||
|
||||
snapshot(name, stripAnsi(args))
|
||||
|
||||
describe "lib/cypress", ->
|
||||
require("mocha-banner").register()
|
||||
|
||||
@@ -460,6 +473,17 @@ describe "lib/cypress", ->
|
||||
expect(console.log).to.be.calledWithMatch("cypress run --record")
|
||||
expect(console.log).to.be.calledWithMatch("https://on.cypress.io/recording-project-runs")
|
||||
|
||||
it "logs warning when removing old browser profiles fails", ->
|
||||
err = new Error('foo')
|
||||
|
||||
sinon.stub(browsers, 'removeOldProfiles').rejects(err)
|
||||
|
||||
cypress.start(["--run-project=#{@todosPath}"])
|
||||
.then =>
|
||||
expect(errors.warning).to.be.calledWith("CANNOT_REMOVE_OLD_BROWSER_PROFILES", err.stack)
|
||||
expect(console.log).to.be.calledWithMatch("Warning: We failed to remove old browser profiles from previous runs.")
|
||||
expect(console.log).to.be.calledWithMatch(err.message)
|
||||
|
||||
it "does not log warning when no projectId", ->
|
||||
cypress.start(["--run-project=#{@pristinePath}", "--key=asdf"])
|
||||
.then =>
|
||||
@@ -634,7 +658,9 @@ describe "lib/cypress", ->
|
||||
|
||||
describe "state", ->
|
||||
beforeEach ->
|
||||
formStatePath(@todosPath)
|
||||
appData.remove()
|
||||
.then =>
|
||||
formStatePath(@todosPath)
|
||||
.then (statePathStart) =>
|
||||
@statePath = appData.projectsPath(statePathStart)
|
||||
|
||||
@@ -924,6 +950,246 @@ describe "lib/cypress", ->
|
||||
expect(console.log).to.be.calledWithMatch("cypress run --record")
|
||||
@expectExitWith(3)
|
||||
|
||||
it "errors and exits when using --group but ciBuildId could not be generated", ->
|
||||
sinon.stub(ciProvider, "provider").returns(null)
|
||||
|
||||
cypress.start([
|
||||
"--run-project=#{@recordPath}",
|
||||
"--record"
|
||||
"--key=token-123",
|
||||
"--group=e2e-tests",
|
||||
])
|
||||
.then =>
|
||||
@expectExitWithErr("INDETERMINATE_CI_BUILD_ID")
|
||||
snapshotConsoleLogs("INDETERMINATE_CI_BUILD_ID-group")
|
||||
|
||||
it "errors and exits when using --parallel but ciBuildId could not be generated", ->
|
||||
sinon.stub(ciProvider, "provider").returns(null)
|
||||
|
||||
cypress.start([
|
||||
"--run-project=#{@recordPath}",
|
||||
"--record"
|
||||
"--key=token-123",
|
||||
"--parallel",
|
||||
])
|
||||
.then =>
|
||||
@expectExitWithErr("INDETERMINATE_CI_BUILD_ID")
|
||||
snapshotConsoleLogs("INDETERMINATE_CI_BUILD_ID-parallel")
|
||||
|
||||
it "errors and exits when using --parallel and --group but ciBuildId could not be generated", ->
|
||||
sinon.stub(ciProvider, "provider").returns(null)
|
||||
|
||||
cypress.start([
|
||||
"--run-project=#{@recordPath}",
|
||||
"--record"
|
||||
"--key=token-123",
|
||||
"--group=e2e-tests-chrome",
|
||||
"--parallel",
|
||||
])
|
||||
.then =>
|
||||
@expectExitWithErr("INDETERMINATE_CI_BUILD_ID")
|
||||
snapshotConsoleLogs("INDETERMINATE_CI_BUILD_ID-parallel-group")
|
||||
|
||||
it "errors and exits when using --ci-build-id with no group or parallelization", ->
|
||||
cypress.start([
|
||||
"--run-project=#{@recordPath}",
|
||||
"--record"
|
||||
"--key=token-123",
|
||||
"--ci-build-id=ciBuildId123",
|
||||
])
|
||||
.then =>
|
||||
@expectExitWithErr("INCORRECT_CI_BUILD_ID_USAGE")
|
||||
snapshotConsoleLogs("INCORRECT_CI_BUILD_ID_USAGE")
|
||||
|
||||
it "errors and exits when using --ci-build-id without recording", ->
|
||||
cypress.start([
|
||||
"--run-project=#{@recordPath}",
|
||||
"--ci-build-id=ciBuildId123",
|
||||
])
|
||||
.then =>
|
||||
@expectExitWithErr("RECORD_PARAMS_WITHOUT_RECORDING")
|
||||
snapshotConsoleLogs("RECORD_PARAMS_WITHOUT_RECORDING-ciBuildId")
|
||||
|
||||
it "errors and exits when using --group without recording", ->
|
||||
cypress.start([
|
||||
"--run-project=#{@recordPath}",
|
||||
"--group=e2e-tests",
|
||||
])
|
||||
.then =>
|
||||
@expectExitWithErr("RECORD_PARAMS_WITHOUT_RECORDING")
|
||||
snapshotConsoleLogs("RECORD_PARAMS_WITHOUT_RECORDING-group")
|
||||
|
||||
it "errors and exits when using --parallel without recording", ->
|
||||
cypress.start([
|
||||
"--run-project=#{@recordPath}",
|
||||
"--parallel",
|
||||
])
|
||||
.then =>
|
||||
@expectExitWithErr("RECORD_PARAMS_WITHOUT_RECORDING")
|
||||
snapshotConsoleLogs("RECORD_PARAMS_WITHOUT_RECORDING-parallel")
|
||||
|
||||
it "errors and exits when using --group and --parallel without recording", ->
|
||||
cypress.start([
|
||||
"--run-project=#{@recordPath}",
|
||||
"--group=electron-smoke-tests",
|
||||
"--parallel",
|
||||
])
|
||||
.then =>
|
||||
@expectExitWithErr("RECORD_PARAMS_WITHOUT_RECORDING")
|
||||
snapshotConsoleLogs("RECORD_PARAMS_WITHOUT_RECORDING-group-parallel")
|
||||
|
||||
it "errors and exits when group name is not unique and explicitly passed ciBuildId", ->
|
||||
err = new Error()
|
||||
err.statusCode = 422
|
||||
err.error = {
|
||||
code: "RUN_GROUP_NAME_NOT_UNIQUE"
|
||||
payload: {
|
||||
runUrl: "https://dashboard.cypress.io/runs/12345"
|
||||
}
|
||||
}
|
||||
|
||||
api.createRun.rejects(err)
|
||||
|
||||
cypress.start([
|
||||
"--run-project=#{@recordPath}",
|
||||
"--record"
|
||||
"--key=token-123",
|
||||
"--group=electron-smoke-tests",
|
||||
"--ciBuildId=ciBuildId123",
|
||||
])
|
||||
.then =>
|
||||
@expectExitWithErr("DASHBOARD_RUN_GROUP_NAME_NOT_UNIQUE")
|
||||
snapshotConsoleLogs("DASHBOARD_RUN_GROUP_NAME_NOT_UNIQUE")
|
||||
|
||||
it "errors and exits when parallel group params are different", ->
|
||||
sinon.stub(system, "info").returns({
|
||||
osName: "darwin"
|
||||
osVersion: "v1"
|
||||
})
|
||||
|
||||
sinon.stub(browsers, "ensureAndGetByName").returns({
|
||||
version: "59.1.2.3"
|
||||
displayName: "Electron"
|
||||
})
|
||||
|
||||
err = new Error()
|
||||
err.statusCode = 422
|
||||
err.error = {
|
||||
code: "PARALLEL_GROUP_PARAMS_MISMATCH"
|
||||
payload: {
|
||||
runUrl: "https://dashboard.cypress.io/runs/12345"
|
||||
}
|
||||
}
|
||||
|
||||
api.createRun.rejects(err)
|
||||
|
||||
cypress.start([
|
||||
"--run-project=#{@recordPath}",
|
||||
"--record"
|
||||
"--key=token-123",
|
||||
"--parallel"
|
||||
"--group=electron-smoke-tests",
|
||||
"--ciBuildId=ciBuildId123",
|
||||
])
|
||||
.then =>
|
||||
@expectExitWithErr("DASHBOARD_PARALLEL_GROUP_PARAMS_MISMATCH")
|
||||
snapshotConsoleLogs("DASHBOARD_PARALLEL_GROUP_PARAMS_MISMATCH")
|
||||
|
||||
it "errors and exits when parallel is not allowed", ->
|
||||
err = new Error()
|
||||
err.statusCode = 422
|
||||
err.error = {
|
||||
code: "PARALLEL_DISALLOWED"
|
||||
payload: {
|
||||
runUrl: "https://dashboard.cypress.io/runs/12345"
|
||||
}
|
||||
}
|
||||
|
||||
api.createRun.rejects(err)
|
||||
|
||||
cypress.start([
|
||||
"--run-project=#{@recordPath}",
|
||||
"--record"
|
||||
"--key=token-123",
|
||||
"--parallel"
|
||||
"--group=electron-smoke-tests",
|
||||
"--ciBuildId=ciBuildId123",
|
||||
])
|
||||
.then =>
|
||||
@expectExitWithErr("DASHBOARD_PARALLEL_DISALLOWED")
|
||||
snapshotConsoleLogs("DASHBOARD_PARALLEL_DISALLOWED")
|
||||
|
||||
it "errors and exits when parallel is required", ->
|
||||
err = new Error()
|
||||
err.statusCode = 422
|
||||
err.error = {
|
||||
code: "PARALLEL_REQUIRED"
|
||||
payload: {
|
||||
runUrl: "https://dashboard.cypress.io/runs/12345"
|
||||
}
|
||||
}
|
||||
|
||||
api.createRun.rejects(err)
|
||||
|
||||
cypress.start([
|
||||
"--run-project=#{@recordPath}",
|
||||
"--record"
|
||||
"--key=token-123",
|
||||
"--parallel"
|
||||
"--group=electron-smoke-tests",
|
||||
"--ciBuildId=ciBuildId123",
|
||||
])
|
||||
.then =>
|
||||
@expectExitWithErr("DASHBOARD_PARALLEL_REQUIRED")
|
||||
snapshotConsoleLogs("DASHBOARD_PARALLEL_REQUIRED")
|
||||
|
||||
it "errors and exits when run is already complete", ->
|
||||
err = new Error()
|
||||
err.statusCode = 422
|
||||
err.error = {
|
||||
code: "ALREADY_COMPLETE"
|
||||
payload: {
|
||||
runUrl: "https://dashboard.cypress.io/runs/12345"
|
||||
}
|
||||
}
|
||||
|
||||
api.createRun.rejects(err)
|
||||
|
||||
cypress.start([
|
||||
"--run-project=#{@recordPath}",
|
||||
"--record"
|
||||
"--key=token-123",
|
||||
"--group=electron-smoke-tests",
|
||||
"--ciBuildId=ciBuildId123",
|
||||
])
|
||||
.then =>
|
||||
@expectExitWithErr("DASHBOARD_ALREADY_COMPLETE")
|
||||
snapshotConsoleLogs("DASHBOARD_ALREADY_COMPLETE")
|
||||
|
||||
it "errors and exits when run is stale", ->
|
||||
err = new Error()
|
||||
err.statusCode = 422
|
||||
err.error = {
|
||||
code: "STALE_RUN"
|
||||
payload: {
|
||||
runUrl: "https://dashboard.cypress.io/runs/12345"
|
||||
}
|
||||
}
|
||||
|
||||
api.createRun.rejects(err)
|
||||
|
||||
cypress.start([
|
||||
"--run-project=#{@recordPath}",
|
||||
"--record"
|
||||
"--key=token-123",
|
||||
"--parallel"
|
||||
"--group=electron-smoke-tests",
|
||||
"--ciBuildId=ciBuildId123",
|
||||
])
|
||||
.then =>
|
||||
@expectExitWithErr("DASHBOARD_STALE_RUN")
|
||||
snapshotConsoleLogs("DASHBOARD_STALE_RUN")
|
||||
|
||||
context "--return-pkg", ->
|
||||
beforeEach ->
|
||||
console.log.restore()
|
||||
|
||||
@@ -18,6 +18,27 @@ require("chai")
|
||||
.use(require("@cypress/sinon-chai"))
|
||||
.use(require("chai-uuid"))
|
||||
|
||||
if process.env.UPDATE
|
||||
throw new Error("You're using UPDATE=1 which is the old way of updating snapshots.\n\nThe correct environment variable is SNAPSHOT_UPDATE=1")
|
||||
|
||||
if process.env.UPDATE_SNAPSHOT
|
||||
throw new Error("You're using UPDATE_SNAPSHOT=1\n\nThe correct environment variable is SNAPSHOT_UPDATE=1")
|
||||
|
||||
if process.env.UPDATE_SNAPSHOTS
|
||||
throw new Error("You're using UPDATE_SNAPSHOTS=1\n\nThe correct environment variable is SNAPSHOT_UPDATE=1")
|
||||
|
||||
hasOnly = false
|
||||
|
||||
## hack for older version of mocha so that
|
||||
## snap-shot-it can find suite._onlyTests
|
||||
["it", "describe", "context"].forEach (prop) ->
|
||||
backup = global[prop].only
|
||||
|
||||
global[prop].only = ->
|
||||
hasOnly = true
|
||||
|
||||
backup.apply(@, arguments)
|
||||
|
||||
env = _.clone(process.env)
|
||||
|
||||
sinon.usingPromise(Promise)
|
||||
@@ -52,6 +73,9 @@ mockery.registerSubstitute(
|
||||
mockery.registerMock("original-fs", {})
|
||||
|
||||
before ->
|
||||
if hasOnly
|
||||
@test.parent._onlyTests = [true]
|
||||
|
||||
appData.ensure()
|
||||
|
||||
beforeEach ->
|
||||
|
||||
@@ -246,6 +246,15 @@ module.exports = {
|
||||
if options.record
|
||||
args.push("--record")
|
||||
|
||||
if options.parallel
|
||||
args.push("--parallel")
|
||||
|
||||
if options.group
|
||||
args.push("--group=#{options.group}")
|
||||
|
||||
if options.ciBuildId
|
||||
args.push("--ci-build-id=#{options.ciBuildId}")
|
||||
|
||||
if options.key
|
||||
args.push("--key=#{options.key}")
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
require("../spec_helper")
|
||||
|
||||
_ = require("lodash")
|
||||
rp = require("request-promise")
|
||||
os = require("os")
|
||||
nmi = require("node-machine-id")
|
||||
pkg = require("@packages/root")
|
||||
@@ -128,7 +127,7 @@ describe "lib/api", ->
|
||||
expect(err.message).to.eq("Error: ESOCKETTIMEDOUT")
|
||||
|
||||
it "sets timeout to 10 seconds", ->
|
||||
sinon.stub(rp, "get").returns({
|
||||
sinon.stub(api.rp, "get").returns({
|
||||
catch: -> {
|
||||
catch: -> {
|
||||
then: (fn) -> fn()
|
||||
@@ -140,7 +139,7 @@ describe "lib/api", ->
|
||||
|
||||
api.getProjectRuns("id-123", "auth-token-123")
|
||||
.then (ret) ->
|
||||
expect(rp.get).to.be.calledWithMatch({timeout: 10000})
|
||||
expect(api.rp.get).to.be.calledWithMatch({timeout: 10000})
|
||||
|
||||
it "GET /projects/:id/runs failure formatting", ->
|
||||
nock("http://localhost:1234")
|
||||
@@ -234,7 +233,7 @@ describe "lib/api", ->
|
||||
|
||||
it "POST /runs + returns runId", ->
|
||||
nock("http://localhost:1234")
|
||||
.matchHeader("x-route-version", "3")
|
||||
.matchHeader("x-route-version", "4")
|
||||
.matchHeader("x-os-name", "linux")
|
||||
.matchHeader("x-cypress-version", pkg.version)
|
||||
.post("/runs", @buildProps)
|
||||
@@ -248,7 +247,7 @@ describe "lib/api", ->
|
||||
|
||||
it "POST /runs failure formatting", ->
|
||||
nock("http://localhost:1234")
|
||||
.matchHeader("x-route-version", "3")
|
||||
.matchHeader("x-route-version", "4")
|
||||
.matchHeader("x-os-name", "linux")
|
||||
.matchHeader("x-cypress-version", pkg.version)
|
||||
.post("/runs", @buildProps)
|
||||
@@ -276,7 +275,7 @@ describe "lib/api", ->
|
||||
|
||||
it "handles timeouts", ->
|
||||
nock("http://localhost:1234")
|
||||
.matchHeader("x-route-version", "3")
|
||||
.matchHeader("x-route-version", "4")
|
||||
.matchHeader("x-os-name", "linux")
|
||||
.matchHeader("x-cypress-version", pkg.version)
|
||||
.post("/runs")
|
||||
@@ -291,16 +290,16 @@ describe "lib/api", ->
|
||||
.catch (err) ->
|
||||
expect(err.message).to.eq("Error: ESOCKETTIMEDOUT")
|
||||
|
||||
it "sets timeout to 60 seconds", ->
|
||||
sinon.stub(rp, "post").resolves({runId: 'foo'})
|
||||
it "sets timeout to 10 seconds", ->
|
||||
sinon.stub(api.rp, "post").resolves({runId: 'foo'})
|
||||
|
||||
api.createRun({})
|
||||
.then ->
|
||||
expect(rp.post).to.be.calledWithMatch({timeout: 60000})
|
||||
expect(api.rp.post).to.be.calledWithMatch({timeout: 60000})
|
||||
|
||||
it "tags errors", ->
|
||||
nock("http://localhost:1234")
|
||||
.matchHeader("x-route-version", "3")
|
||||
.matchHeader("x-route-version", "4")
|
||||
.matchHeader("authorization", "Bearer auth-token-123")
|
||||
.matchHeader("accept-encoding", /gzip/)
|
||||
.post("/runs", @buildProps)
|
||||
@@ -332,7 +331,7 @@ describe "lib/api", ->
|
||||
os.platform.returns("darwin")
|
||||
|
||||
nock("http://localhost:1234")
|
||||
.matchHeader("x-route-version", "4")
|
||||
.matchHeader("x-route-version", "5")
|
||||
.matchHeader("x-os-name", "darwin")
|
||||
.matchHeader("x-cypress-version", pkg.version)
|
||||
.post("/runs/run-id-123/instances", @postProps)
|
||||
@@ -341,12 +340,13 @@ describe "lib/api", ->
|
||||
})
|
||||
|
||||
api.createInstance(@createProps)
|
||||
.get("instanceId")
|
||||
.then (instanceId) ->
|
||||
expect(instanceId).to.eq("instance-id-123")
|
||||
|
||||
it "POST /runs/:id/instances failure formatting", ->
|
||||
nock("http://localhost:1234")
|
||||
.matchHeader("x-route-version", "4")
|
||||
.matchHeader("x-route-version", "5")
|
||||
.matchHeader("x-os-name", "linux")
|
||||
.matchHeader("x-cypress-version", pkg.version)
|
||||
.post("/runs/run-id-123/instances")
|
||||
@@ -374,7 +374,7 @@ describe "lib/api", ->
|
||||
|
||||
it "handles timeouts", ->
|
||||
nock("http://localhost:1234")
|
||||
.matchHeader("x-route-version", "4")
|
||||
.matchHeader("x-route-version", "5")
|
||||
.matchHeader("x-os-name", "linux")
|
||||
.matchHeader("x-cypress-version", pkg.version)
|
||||
.post("/runs/run-id-123/instances")
|
||||
@@ -391,13 +391,13 @@ describe "lib/api", ->
|
||||
expect(err.message).to.eq("Error: ESOCKETTIMEDOUT")
|
||||
|
||||
it "sets timeout to 60 seconds", ->
|
||||
sinon.stub(rp, "post").returns({
|
||||
promise: -> Promise.resolve({ instanceId: "instanceId123" })
|
||||
sinon.stub(api.rp, "post").resolves({
|
||||
instanceId: "instanceId123"
|
||||
})
|
||||
|
||||
api.createInstance({})
|
||||
.then ->
|
||||
expect(rp.post).to.be.calledWithMatch({timeout: 60000})
|
||||
expect(api.rp.post).to.be.calledWithMatch({timeout: 60000})
|
||||
|
||||
it "tags errors", ->
|
||||
nock("http://localhost:1234")
|
||||
@@ -484,11 +484,11 @@ describe "lib/api", ->
|
||||
expect(err.message).to.eq("Error: ESOCKETTIMEDOUT")
|
||||
|
||||
it "sets timeout to 60 seconds", ->
|
||||
sinon.stub(rp, "put").resolves()
|
||||
sinon.stub(api.rp, "put").resolves()
|
||||
|
||||
api.updateInstance({})
|
||||
.then ->
|
||||
expect(rp.put).to.be.calledWithMatch({timeout: 60000})
|
||||
expect(api.rp.put).to.be.calledWithMatch({timeout: 60000})
|
||||
|
||||
it "tags errors", ->
|
||||
nock("http://localhost:1234")
|
||||
@@ -564,11 +564,11 @@ describe "lib/api", ->
|
||||
expect(err.message).to.eq("Error: ESOCKETTIMEDOUT")
|
||||
|
||||
it "sets timeout to 60 seconds", ->
|
||||
sinon.stub(rp, "put").resolves()
|
||||
sinon.stub(api.rp, "put").resolves()
|
||||
|
||||
api.updateInstanceStdout({})
|
||||
.then ->
|
||||
expect(rp.put).to.be.calledWithMatch({timeout: 60000})
|
||||
expect(api.rp.put).to.be.calledWithMatch({timeout: 60000})
|
||||
|
||||
it "tags errors", ->
|
||||
nock("http://localhost:1234")
|
||||
@@ -956,9 +956,9 @@ describe "lib/api", ->
|
||||
it "by default times outs after 3 seconds", ->
|
||||
## return our own specific promise
|
||||
## so we can spy on the timeout function
|
||||
p = Promise.resolve()
|
||||
p = Promise.resolve({})
|
||||
sinon.spy(p, "timeout")
|
||||
sinon.stub(rp.Request.prototype, "promise").returns(p)
|
||||
sinon.stub(api.rp, "post").returns(p)
|
||||
|
||||
@setup({foo: "bar"}, "auth-token-123")
|
||||
api.createRaygunException({foo: "bar"}, "auth-token-123").then ->
|
||||
|
||||
@@ -37,7 +37,9 @@ describe "lib/browsers/chrome", ->
|
||||
|
||||
it "normalizes --load-extension if provided in plugin", ->
|
||||
plugins.has.returns(true)
|
||||
plugins.execute.resolves(["--foo=bar", "--load-extension=/foo/bar/baz.js"])
|
||||
plugins.execute.resolves([
|
||||
"--foo=bar", "--load-extension=/foo/bar/baz.js"
|
||||
])
|
||||
|
||||
pathToTheme = extension.getPathToTheme()
|
||||
|
||||
|
||||
@@ -95,6 +95,9 @@ describe "lib/modes/record", ->
|
||||
projectId = "pId123"
|
||||
specPattern = ["spec/pattern1", "spec/pattern2"]
|
||||
projectRoot = "project/root"
|
||||
ciBuildId = "ciId123"
|
||||
parallel = null
|
||||
group = null
|
||||
runAllSpecs = sinon.stub()
|
||||
sys = {
|
||||
osCpus: 1
|
||||
@@ -111,7 +114,10 @@ describe "lib/modes/record", ->
|
||||
key
|
||||
sys
|
||||
specs
|
||||
group
|
||||
browser
|
||||
parallel
|
||||
ciBuildId
|
||||
projectId
|
||||
projectRoot
|
||||
specPattern
|
||||
@@ -120,6 +126,21 @@ describe "lib/modes/record", ->
|
||||
.then ->
|
||||
expect(commitInfo.commitInfo).to.be.calledWith(projectRoot)
|
||||
expect(api.createRun).to.be.calledWith({
|
||||
group
|
||||
parallel
|
||||
projectId
|
||||
ciBuildId
|
||||
recordKey: key
|
||||
specPattern: "spec/pattern1,spec/pattern2"
|
||||
specs: ["path/to/spec/a", "path/to/spec/b"]
|
||||
platform: {
|
||||
osCpus: 1
|
||||
osName: 2
|
||||
osMemory: 3
|
||||
osVersion: 4
|
||||
browserName: "chrome"
|
||||
browserVersion: "59"
|
||||
}
|
||||
ci: {
|
||||
params: {
|
||||
foo: "bar"
|
||||
|
||||
@@ -49,6 +49,7 @@ describe "lib/modes/run", ->
|
||||
options = {
|
||||
port: 8080
|
||||
env: {foo: "bar"}
|
||||
isTextTerminal: true
|
||||
projectRoot: "/_test-output/path/to/project/foo"
|
||||
}
|
||||
|
||||
|
||||
91
packages/server/test/unit/profile_cleaner_spec.coffee
Normal file
91
packages/server/test/unit/profile_cleaner_spec.coffee
Normal file
@@ -0,0 +1,91 @@
|
||||
require("../spec_helper")
|
||||
|
||||
os = require("os")
|
||||
path = require("path")
|
||||
fs = require("#{root}/lib/util/fs")
|
||||
findProcess = require("#{root}lib/util/find_process")
|
||||
profileCleaner = require("#{root}lib/util/profile_cleaner")
|
||||
|
||||
tmpDir = os.tmpdir()
|
||||
pidProfilesFolder = path.join(tmpDir, "pid-profiles")
|
||||
|
||||
describe "lib/util/profile_cleaner", ->
|
||||
context '.isCypressProcess', ->
|
||||
it 'finds cypress processes by name or cmd', ->
|
||||
isProc = (obj, bool) ->
|
||||
expect(profileCleaner.isCypressProcess(obj), JSON.stringify(obj)).to.eq(bool)
|
||||
|
||||
processes = [
|
||||
{
|
||||
name: 'CYPRESS'
|
||||
},
|
||||
{
|
||||
cmd: 'path/to/Cypress -- some args'
|
||||
},
|
||||
{
|
||||
name: 'nope',
|
||||
cmd: 'not found'
|
||||
}
|
||||
]
|
||||
|
||||
isProc(processes[0], true)
|
||||
isProc(processes[1], true)
|
||||
isProc(processes[2], false)
|
||||
|
||||
context ".removeInactiveByPid", ->
|
||||
beforeEach ->
|
||||
sinon.stub(findProcess, 'byPid')
|
||||
.withArgs(53301)
|
||||
.resolves([
|
||||
{
|
||||
pid: '53301'
|
||||
ppid: '53300',
|
||||
uid: '501',
|
||||
gid: '20',
|
||||
name: 'Cypress',
|
||||
cmd: '/Users/bmann/Library/Caches/Cypress/3.0.3/Cypress.app/Contents/MacOS/Cypress --project /Users/bmann/Dev/cypress-dashboard --cwd /Users/bmann/Dev/cypress-dashboard'
|
||||
}
|
||||
])
|
||||
.withArgs(12345)
|
||||
.resolves([
|
||||
{
|
||||
pid: '12345'
|
||||
name: 'Foo',
|
||||
cmd: 'node foo bar'
|
||||
}
|
||||
])
|
||||
.withArgs(9999)
|
||||
.resolves([])
|
||||
|
||||
createFolder = (folder) ->
|
||||
fs.ensureDirAsync(path.join(pidProfilesFolder, folder))
|
||||
|
||||
Promise.all([
|
||||
createFolder("run-9999")
|
||||
createFolder("run-12345")
|
||||
createFolder("run-53301")
|
||||
createFolder("foo-53301")
|
||||
])
|
||||
|
||||
afterEach ->
|
||||
fs.removeAsync(pidProfilesFolder)
|
||||
|
||||
it "removes profiles which are not cypress pids", ->
|
||||
expected = (folder, condition) ->
|
||||
pathToFolder = path.join(pidProfilesFolder, folder)
|
||||
|
||||
fs
|
||||
.pathExists(pathToFolder)
|
||||
.then (bool) ->
|
||||
expect(bool, "expected folder: #{pathToFolder} to exist? #{condition}").to.eq(condition)
|
||||
|
||||
profileCleaner.removeInactiveByPid(pidProfilesFolder, "run-")
|
||||
.then ->
|
||||
Promise.all([
|
||||
expected('run-9999', false),
|
||||
expected('run-12345', false),
|
||||
expected('run-53301', true),
|
||||
expected('foo-53301', true),
|
||||
])
|
||||
.finally ->
|
||||
findProcess.byPid.restore()
|
||||
26
scripts/add_newlines_to_snapshots.js
Normal file
26
scripts/add_newlines_to_snapshots.js
Normal file
@@ -0,0 +1,26 @@
|
||||
const fs = require('fs-extra')
|
||||
const glob = require('glob')
|
||||
const Promise = require('bluebird')
|
||||
|
||||
const globAsync = Promise.promisify(glob)
|
||||
|
||||
const endingNewLines = /\s+$/g
|
||||
const contentBetweenBackticksRe = /\`([\s\S]+?)\`/g
|
||||
|
||||
globAsync('packages/server/__snapshots__/*')
|
||||
.map((file) => {
|
||||
return fs.readFile(file, 'utf8')
|
||||
.then((str) => {
|
||||
return str
|
||||
.replace(
|
||||
contentBetweenBackticksRe,
|
||||
'`\n$1\n`'
|
||||
)
|
||||
.split('`\n\n\n').join('`\n\n')
|
||||
.split('\n\n\n\n`').join('\n\n\n`')
|
||||
.split(endingNewLines).join('\n')
|
||||
})
|
||||
.then((str) => {
|
||||
return fs.writeFile(file, str)
|
||||
})
|
||||
})
|
||||
15
scripts/rename_snapshots.js
Normal file
15
scripts/rename_snapshots.js
Normal file
@@ -0,0 +1,15 @@
|
||||
const fs = require('fs-extra')
|
||||
const glob = require('glob')
|
||||
const Promise = require('bluebird')
|
||||
|
||||
const globAsync = Promise.promisify(glob)
|
||||
|
||||
globAsync('packages/*/__snapshots__/*.coffee')
|
||||
.map((file) => {
|
||||
const renamed = `${file}.js`
|
||||
|
||||
/* eslint-disable no-console */
|
||||
console.log('renaming', file, '->', renamed)
|
||||
|
||||
return fs.rename(file, renamed)
|
||||
})
|
||||
Reference in New Issue
Block a user