mirror of
https://github.com/cypress-io/cypress.git
synced 2026-02-22 15:11:00 -06:00
Improve server test scripts (#6567)
* clean up server test commands this mostly restores the pre-yarn behavior: - passing a file path to a test command runs that file, not all tests - there is only one test-watch - there is a "test" command which accepts a pathx * allow run.js to specify multiple specfiles * simplify e2e test setup by using globbing * fix e2e test that has been broken for eternity * still let users use `test-e2e --spec` syntax * update server README
This commit is contained in:
4
.vscode/terminals.json
vendored
4
.vscode/terminals.json
vendored
@@ -24,12 +24,12 @@
|
||||
"command": "yarn test-watch [file]"
|
||||
},
|
||||
{
|
||||
"name": "packages/server test-e2e",
|
||||
"name": "packages/server test",
|
||||
"focus": true,
|
||||
"onlySingle": true,
|
||||
"execute": false,
|
||||
"cwd": "[cwd]/packages/server",
|
||||
"command": "yarn test-e2e --spec [fileBasename]"
|
||||
"command": "yarn test [file]"
|
||||
},
|
||||
{
|
||||
"name": "packages/runner watch",
|
||||
|
||||
@@ -97,7 +97,7 @@ commands:
|
||||
- attach_workspace:
|
||||
at: ~/
|
||||
- run:
|
||||
command: yarn lerna exec --scope @packages/server "yarn test-e2e --chunk << parameters.chunk >> --browser << parameters.browser >>"
|
||||
command: yarn lerna exec --scope @packages/server "yarn test ./test/e2e/<< parameters.chunk >>*spec* --browser << parameters.browser >>"
|
||||
- verify-mocha-results
|
||||
- store_test_results:
|
||||
path: /tmp/cypress
|
||||
|
||||
@@ -17,11 +17,11 @@ The [driver](../driver) and the server are the two most complex packages of Cypr
|
||||
|
||||
## Developing
|
||||
|
||||
To run Cypress:
|
||||
To run the Cypress server:
|
||||
|
||||
```bash
|
||||
## boots the entire Cypress application
|
||||
yarn lerna run start --scope @packages/server --stream
|
||||
yarn start
|
||||
```
|
||||
|
||||
Since the server controls nearly every aspect of Cypress, after making changes you'll need to manually restart Cypress.
|
||||
@@ -36,19 +36,52 @@ Note: you should not ever need to build the .js files manually. `@packages/ts` p
|
||||
yarn lerna run build-prod --scope @packages/server --stream
|
||||
```
|
||||
|
||||
## Testing
|
||||
* `yarn test-unit` executes unit tests in [`test/unit`](./test/unit)
|
||||
* `yarn test-integration` executes integration tests in [`test/integration`](./test/integration)
|
||||
* `yarn test-performance` executes performance tests in [`test/performance`](./test/performance)
|
||||
* `yarn test-e2e` executes the large (slow) end to end tests in [`test/e2e`](./test/e2e)
|
||||
|
||||
* `yarn lerna run test-unit --scope @packages/server --stream` executes unit tests in [`test/unit`](./test/unit)
|
||||
* `yarn lerna run test-integration --scope @packages/server --stream` executes integration tests in [`test/integration`](./test/integration)
|
||||
* `yarn lerna run test-performance --scope @packages/server --stream` executes performance tests in [`test/performance`](./test/performance)
|
||||
* `yarn lerna run test-e2e --scope @packages/server --stream` executes the large (slow) end to end tests in [`test/e2e`](./test/e2e)
|
||||
|
||||
Each of these tasks can run in "watch" mode by appending `-watch` to the task:
|
||||
You can also use the `test-watch` command to rerun a test file whenever there is a change:
|
||||
|
||||
```bash
|
||||
yarn lerna run test-unit-watch --scope @packages/server --stream
|
||||
yarn test-watch /test/path/to/spec.js
|
||||
```
|
||||
|
||||
When running e2e tests, some test projects output verbose logs. To see them run the test with `DEBUG=cypress:e2e` environment variable.
|
||||
|
||||
To update snapshots, see `snap-shot-it` instructions: https://github.com/bahmutov/snap-shot-it#advanced-use
|
||||
### Running individual unit tests
|
||||
|
||||
```bashtest-kitchensink
|
||||
yarn test <path/to/test>
|
||||
yarn test test/unit/api_spec.coffee
|
||||
## or
|
||||
yarn test-unit api_spec ## shorthand, uses globbing to find spec
|
||||
```
|
||||
|
||||
### Running individual integration tests
|
||||
|
||||
```bash
|
||||
yarn test <path/to/test>
|
||||
yarn test test/integration/cli_spec.coffee
|
||||
## or
|
||||
yarn test-integration cli_spec ## shorthand, uses globbing to find spec
|
||||
```
|
||||
|
||||
### Running individual e2e tests
|
||||
|
||||
```bash
|
||||
yarn test <path/to/test>
|
||||
yarn test test/e2e/1_async_timeouts_spec.coffee
|
||||
## or
|
||||
yarn test-e2e 1_async ## shorthand, uses globbing to find spec
|
||||
```
|
||||
|
||||
### Updating snaphots
|
||||
|
||||
Prepend `SNAPSHOT_UPDATE=1` to any test command. See [`snap-shot-it` instructions](https://github.com/bahmutov/snap-shot-it#advanced-use) for more info.
|
||||
|
||||
```bash
|
||||
SNAPSHOT_UPDATE=1 yarn test test/unit/api_spec.coffee
|
||||
SNAPSHOT_UPDATE=1 yarn test test/integration/cli_spec.coffee
|
||||
SNAPSHOT_UPDATE=1 yarn test-e2e 1_async
|
||||
```
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
exports['e2e issue 2891 passes 1'] = `
|
||||
exports['e2e issue 1669 passes 1'] = `
|
||||
|
||||
====================================================================================================
|
||||
|
||||
|
||||
@@ -11,17 +11,14 @@
|
||||
"lint-coffee": "coffeelint test/*.coffee test/unit/*.coffee test/integration/*.coffee",
|
||||
"repl": "node repl.js",
|
||||
"start": "node ../../scripts/cypress open --dev --global",
|
||||
"test": "node ./test/scripts/run.js",
|
||||
"test-cov": "cross-env NODE_COVERAGE=true NODE_ENV=test CYPRESS_ENV=test BLUEBIRD_DEBUG=1 xvfb-maybe istanbul cover node_modules/.bin/_mocha -- --opts ./test/support/mocha.opts",
|
||||
"test-cov-process": "cross-env NODE_COVERAGE=true NODE_ENV=test CYPRESS_ENV=test BLUEBIRD_DEBUG=1 istanbul cover --include-pid",
|
||||
"test-debug": "yarn test-unit --inspect-brk=5566",
|
||||
"test-e2e": "node ./test/scripts/e2e.js",
|
||||
"test-e2e-chrome": "node ./test/scripts/run.js test/e2e chrome",
|
||||
"test-integration": "node ./test/scripts/run.js test/integration",
|
||||
"test-integration-watch": "./test/support/watch test-integration",
|
||||
"test-performance": "node ./test/scripts/run.js test/performance",
|
||||
"test-unit": "node ./test/scripts/run.js test/unit",
|
||||
"test-unit-watch": "./test/support/watch test/unit",
|
||||
"test-watch": "./test/support/watch test-unit"
|
||||
"test-e2e": "node ./test/scripts/run.js --glob-in-dir=test/e2e",
|
||||
"test-integration": "node ./test/scripts/run.js --glob-in-dir=test/integration",
|
||||
"test-performance": "node ./test/scripts/run.js --glob-in-dir=test/performance",
|
||||
"test-unit": "node ./test/scripts/run.js --glob-in-dir=test/unit",
|
||||
"test-watch": "./test/support/watch test"
|
||||
},
|
||||
"dependencies": {
|
||||
"@benmalka/foxdriver": "0.2.3",
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
e2e = require("../support/helpers/e2e")
|
||||
Fixtures = require("../support/helpers/fixtures")
|
||||
|
||||
describe "e2e issue 2891", ->
|
||||
describe "e2e issue 1669", ->
|
||||
e2e.setup()
|
||||
|
||||
## https://github.com/cypress-io/cypress/issues/2891
|
||||
## https://github.com/cypress-io/cypress/issues/1669
|
||||
|
||||
it "passes", ->
|
||||
e2e.exec(@, {
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
/* eslint-disable no-console */
|
||||
|
||||
require('@packages/coffee/register')
|
||||
|
||||
const _ = require('lodash')
|
||||
const cp = require('child_process')
|
||||
const path = require('path')
|
||||
const minimist = require('minimist')
|
||||
const Promise = require('bluebird')
|
||||
const terminalBanner = require('terminal-banner').terminalBanner
|
||||
const glob = require('../../lib/util/glob')
|
||||
const humanTime = require('../../lib/util/human_time')
|
||||
|
||||
const options = minimist(process.argv.slice(2))
|
||||
|
||||
if (options.browser) {
|
||||
process.env.BROWSER = options.browser
|
||||
}
|
||||
|
||||
const started = new Date()
|
||||
|
||||
let numFailed = 0
|
||||
|
||||
function isLoadBalanced (options) {
|
||||
return _.isNumber(options.chunk)
|
||||
}
|
||||
|
||||
function spawn (cmd, args, opts) {
|
||||
return new Promise((resolve, reject) => {
|
||||
cp.spawn(cmd, args, opts)
|
||||
.on('exit', resolve)
|
||||
.on('error', reject)
|
||||
})
|
||||
}
|
||||
|
||||
glob('test/e2e/**/*')
|
||||
.then((specs = []) => {
|
||||
if (options.spec) {
|
||||
return _.filter(specs, (spec) => {
|
||||
return _.some(options.spec.split(','), (specPart) => {
|
||||
return spec.includes(specPart)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
if (isLoadBalanced(options)) {
|
||||
return _.filter(specs, (spec) => {
|
||||
return path.basename(spec).startsWith(options.chunk)
|
||||
})
|
||||
}
|
||||
|
||||
return specs
|
||||
})
|
||||
.tap(console.log)
|
||||
.each((spec = []) => {
|
||||
terminalBanner(`Running spec ${spec}`, '*')
|
||||
|
||||
const args = [
|
||||
'./test/scripts/run.js',
|
||||
spec,
|
||||
]
|
||||
|
||||
if (options['inspect-brk']) {
|
||||
args.push('--inspect-brk')
|
||||
}
|
||||
|
||||
return spawn('node', args, { stdio: 'inherit' })
|
||||
.then((code) => {
|
||||
console.log(`${spec} exited with code`, code)
|
||||
|
||||
numFailed += code
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err)
|
||||
throw err
|
||||
})
|
||||
})
|
||||
.then(() => {
|
||||
const duration = new Date() - started
|
||||
|
||||
console.log('Total duration:', humanTime.long(duration))
|
||||
console.log('Exiting with final code:', numFailed)
|
||||
|
||||
process.exit(numFailed)
|
||||
})
|
||||
@@ -1,80 +0,0 @@
|
||||
/* eslint-disable no-console */
|
||||
|
||||
require('@packages/coffee/register')
|
||||
|
||||
const _ = require('lodash')
|
||||
const path = require('path')
|
||||
const Promise = require('bluebird')
|
||||
const minimist = require('minimist')
|
||||
const fs = require('../../lib/util/fs')
|
||||
const glob = require('../../lib/util/glob')
|
||||
|
||||
const options = minimist(process.argv.slice(2))
|
||||
|
||||
const { size, reset, snapshots } = options
|
||||
|
||||
const removeChunkPrefixes = () => {
|
||||
const forwardSlashNumUnderscoreRe = /(\/\d_)/
|
||||
|
||||
const renameFiles = (pattern) => {
|
||||
return glob(pattern)
|
||||
.map((spec) => {
|
||||
return fs.renameAsync(spec, spec.replace(forwardSlashNumUnderscoreRe, '/'))
|
||||
})
|
||||
}
|
||||
|
||||
return Promise.join(
|
||||
renameFiles('test/e2e/**/*'),
|
||||
renameFiles('__snapshots__/**/*'),
|
||||
)
|
||||
}
|
||||
|
||||
const renameSnapshotsToMatchSpecs = () => {
|
||||
glob('test/e2e/**/*')
|
||||
.map((spec) => {
|
||||
spec += '.js'
|
||||
|
||||
const specName = path.basename(spec)
|
||||
|
||||
const pathToSnapshot = path.resolve(
|
||||
__dirname, '..', '..', '__snapshots__', specName.slice(2),
|
||||
)
|
||||
|
||||
const pathToRenamedSnapshot = path.join(
|
||||
path.dirname(pathToSnapshot),
|
||||
specName,
|
||||
)
|
||||
|
||||
return fs.renameAsync(pathToSnapshot, pathToRenamedSnapshot)
|
||||
})
|
||||
.catchReturn({ code: 'ENOENT' }, null)
|
||||
}
|
||||
|
||||
if (reset) {
|
||||
return removeChunkPrefixes()
|
||||
}
|
||||
|
||||
if (snapshots) {
|
||||
return renameSnapshotsToMatchSpecs()
|
||||
}
|
||||
|
||||
glob('test/e2e/**/*')
|
||||
.then((specs) => {
|
||||
if (!size) {
|
||||
console.error('must include --size for calculating chunk size')
|
||||
}
|
||||
|
||||
return _.chunk(specs, size)
|
||||
})
|
||||
.map((chunks, index) => {
|
||||
index += 1
|
||||
|
||||
return Promise
|
||||
.map(chunks, (spec) => {
|
||||
const folder = path.dirname(spec)
|
||||
const specName = path.basename(spec)
|
||||
const renamedSpec = `${index}_${specName}`
|
||||
|
||||
return fs.renameAsync(spec, path.join(folder, renamedSpec))
|
||||
})
|
||||
})
|
||||
@@ -4,14 +4,28 @@ const _ = require('lodash')
|
||||
const chalk = require('chalk')
|
||||
const minimist = require('minimist')
|
||||
const execa = require('execa')
|
||||
const path = require('path')
|
||||
const os = require('os')
|
||||
|
||||
const options = minimist(process.argv.slice(2))
|
||||
|
||||
let run = options._[0]
|
||||
let run = options._
|
||||
|
||||
if (run && run.includes('--inspect-brk')) {
|
||||
run = options._[1]
|
||||
if (options['spec']) {
|
||||
console.error('NOTE: It is no longer necessary to pass `--spec` to server test commands. Try passing the path directly instead.')
|
||||
run = [options.spec]
|
||||
}
|
||||
|
||||
if (run[0] && run[0].includes('--inspect-brk')) {
|
||||
run = run.slice(1)
|
||||
}
|
||||
|
||||
if (options['glob-in-dir']) {
|
||||
if (run[0]) {
|
||||
run = [path.join(options['glob-in-dir'], '**', `*${run[0]}*`)]
|
||||
} else {
|
||||
run = [options['glob-in-dir']]
|
||||
}
|
||||
}
|
||||
|
||||
function exitErr (msg) {
|
||||
@@ -28,19 +42,19 @@ const isGteNode12 = () => {
|
||||
return Number(process.versions.node.split('.')[0]) >= 12
|
||||
}
|
||||
|
||||
if (!run) {
|
||||
if (!run || !run.length) {
|
||||
return exitErr(`
|
||||
Error: A path to a spec file must be specified!
|
||||
|
||||
It should look something like this:
|
||||
|
||||
$ npm test ./test/unit/api_spec.coffee
|
||||
$ yarn test ./test/unit/api_spec.coffee
|
||||
|
||||
If you want to run all a specific group of tests:
|
||||
|
||||
$ npm run test-unit
|
||||
$ npm run test-integration
|
||||
$ npm run test-e2e
|
||||
$ yarn test-unit
|
||||
$ yarn test-integration
|
||||
$ yarn test-e2e
|
||||
`)
|
||||
}
|
||||
|
||||
@@ -51,7 +65,7 @@ const commandAndArguments = {
|
||||
|
||||
if (isWindows()) {
|
||||
commandAndArguments.command = 'mocha'
|
||||
commandAndArguments.args = [run]
|
||||
commandAndArguments.args = run.slice()
|
||||
} else {
|
||||
commandAndArguments.command = 'xvfb-maybe'
|
||||
commandAndArguments.args = [
|
||||
@@ -79,8 +93,9 @@ if (isGteNode12()) {
|
||||
if (!isWindows()) {
|
||||
commandAndArguments.args.push(
|
||||
'node_modules/.bin/_mocha',
|
||||
run,
|
||||
)
|
||||
|
||||
commandAndArguments.args = commandAndArguments.args.concat(run)
|
||||
}
|
||||
|
||||
if (options.fgrep) {
|
||||
@@ -132,6 +147,7 @@ if (options.browser) {
|
||||
const cmd = `${commandAndArguments.command} ${
|
||||
commandAndArguments.args.join(' ')}`
|
||||
|
||||
console.log('specfiles:', run)
|
||||
console.log('test command:')
|
||||
console.log(cmd)
|
||||
|
||||
|
||||
@@ -5,6 +5,6 @@ ARGS="$2"
|
||||
|
||||
npm run --silent $CMD $ARGS & \
|
||||
chokidar 'test/**/*' 'lib/**/*' \
|
||||
-c "npm run --silent $CMD $ARGS" \
|
||||
-c "yarn --silent $CMD $ARGS" \
|
||||
--polling \
|
||||
--poll-interval=250
|
||||
|
||||
Reference in New Issue
Block a user