diff --git a/.vscode/terminals.json b/.vscode/terminals.json index 641f0e208c..c3f9b569c9 100644 --- a/.vscode/terminals.json +++ b/.vscode/terminals.json @@ -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", diff --git a/circle.yml b/circle.yml index 17e8538e7c..de242a264e 100644 --- a/circle.yml +++ b/circle.yml @@ -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 diff --git a/packages/server/README.md b/packages/server/README.md index 1ec15bbd8f..591467b4c9 100644 --- a/packages/server/README.md +++ b/packages/server/README.md @@ -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 +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 +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 +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 +``` diff --git a/packages/server/__snapshots__/3_issue_1669_spec.coffee.js b/packages/server/__snapshots__/3_issue_1669_spec.coffee.js index 72836df372..7fefc672ee 100644 --- a/packages/server/__snapshots__/3_issue_1669_spec.coffee.js +++ b/packages/server/__snapshots__/3_issue_1669_spec.coffee.js @@ -1,4 +1,4 @@ -exports['e2e issue 2891 passes 1'] = ` +exports['e2e issue 1669 passes 1'] = ` ==================================================================================================== diff --git a/packages/server/package.json b/packages/server/package.json index 13e1db1099..e9b282bc35 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -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", diff --git a/packages/server/test/e2e/3_issue_1669_spec.coffee b/packages/server/test/e2e/3_issue_1669_spec.coffee index 0666dc0ef7..25499e2296 100644 --- a/packages/server/test/e2e/3_issue_1669_spec.coffee +++ b/packages/server/test/e2e/3_issue_1669_spec.coffee @@ -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(@, { diff --git a/packages/server/test/scripts/e2e.js b/packages/server/test/scripts/e2e.js deleted file mode 100644 index 20e7737760..0000000000 --- a/packages/server/test/scripts/e2e.js +++ /dev/null @@ -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) -}) diff --git a/packages/server/test/scripts/rename.js b/packages/server/test/scripts/rename.js deleted file mode 100644 index 9c25877722..0000000000 --- a/packages/server/test/scripts/rename.js +++ /dev/null @@ -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)) - }) -}) diff --git a/packages/server/test/scripts/run.js b/packages/server/test/scripts/run.js index f81040f9a8..53fabc561c 100644 --- a/packages/server/test/scripts/run.js +++ b/packages/server/test/scripts/run.js @@ -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) diff --git a/packages/server/test/support/watch b/packages/server/test/support/watch index 298a4aa547..f759dbc758 100755 --- a/packages/server/test/support/watch +++ b/packages/server/test/support/watch @@ -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