Skip to content

Commit

Permalink
Merge branch 'develop' into tgriesser/fix/1244-redirect-bug
Browse files Browse the repository at this point in the history
* develop:
  remove unused deps from webpack-preprocessor (#16384)
  feat: exclude html pwa plugin in webpack dev server (#16388)
  fix(ui): display duplicate aliases in command log (#16382)
  fix(ui): show req stub/fn when a handler is supplied (#16383)
  feat(component-testing): Expose CT through CLI module API (#16368)
  • Loading branch information
tgriesser committed May 10, 2021
2 parents 43db8be + 61fd6c4 commit 3963773
Show file tree
Hide file tree
Showing 21 changed files with 324 additions and 882 deletions.
22 changes: 22 additions & 0 deletions cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,25 @@ yarn add ~/{your-dirs}/cypress/cli/build/cypress-3.3.1.tgz --ignore-scripts
```

Which installs the `tgz` file we have just built from folder `Users/jane-lane/{your-dirs}/cypress/cli/build`.

#### Module API

The module API can be tested locally using something like:

```typescript
/* @ts-ignore */
import cypress from '../../cli/lib/cypress'

const run = cypress.run as (options?: Partial<CypressCommandLine.CypressRunOptions>) => Promise<CypressCommandLine.CypressRunResult | CypressCommandLine.CypressFailedRunResult>

run({
spec: './cypress/component/advanced/framer-motion/Motion.spec.tsx',
testingType: 'component',
/* @ts-ignore */
dev: true,
}).then(results => {
console.log(results)
})
```

Note that the `dev` flag is required for local testing, as otherwise the command will fail with a binary error.
1 change: 1 addition & 0 deletions cli/__snapshots__/errors_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ exports['errors individual has the following errors 1'] = [
"invalidCypressEnv",
"invalidRunProjectPath",
"invalidSmokeTestDisplayError",
"invalidTestingType",
"missingApp",
"missingDependency",
"missingXvfb",
Expand Down
5 changes: 5 additions & 0 deletions cli/__snapshots__/run_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,8 @@ exports['exec run .processRunOptions passes --config-file false option 1'] = [
"--config-file",
false
]

exports['exec run .processRunOptions defaults to e2e testingType 1'] = [
"--run-project",
null
]
4 changes: 2 additions & 2 deletions cli/lib/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,7 @@ module.exports = {
.action((opts) => {
debug('opening Cypress')
require('./exec/open')
.start(util.parseOpts(opts), { isComponentTesting: true })
.start({ ...util.parseOpts(opts), testingType: 'component' })
.catch(util.logErrorExit1)
})

Expand Down Expand Up @@ -456,7 +456,7 @@ module.exports = {
.action((opts) => {
debug('running Cypress run-ct')
require('./exec/run')
.start(util.parseOpts(opts), { isComponentTesting: true })
.start({ ...util.parseOpts(opts), testingType: 'component' })
.then(util.exit)
.catch(util.logErrorExit1)
})
Expand Down
6 changes: 6 additions & 0 deletions cli/lib/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,11 @@ const invalidCypressEnv = {
exitCode: 11,
}

const invalidTestingType = {
description: 'Invalid testingType',
solution: `Please provide a valid testingType. Valid test types are ${chalk.cyan('\'e2e\'')} and ${chalk.cyan('\'component\'')}.`,
}

/**
* This error happens when CLI detects that the child Test Runner process
* was killed with a signal, like SIGBUS
Expand Down Expand Up @@ -407,5 +412,6 @@ module.exports = {
childProcessKilled,
incompatibleHeadlessFlags,
invalidRunProjectPath,
invalidTestingType,
},
}
7 changes: 3 additions & 4 deletions cli/lib/exec/open.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ const debug = require('debug')('cypress:cli')
const util = require('../util')
const spawn = require('./spawn')
const verify = require('../tasks/verify')
const { processTestingType } = require('./shared')

module.exports = {
start (options = {}, { isComponentTesting } = { isComponentTesting: false }) {
start (options = {}) {
if (!util.isInstalledGlobally() && !options.global && !options.project) {
options.project = process.cwd()
}
Expand Down Expand Up @@ -35,9 +36,7 @@ module.exports = {
args.push('--project', options.project)
}

if (isComponentTesting) {
args.push('--testing-type', 'component')
}
args.push(...processTestingType(options.testingType))

debug('opening from options %j', options)
debug('command line arguments %j', args)
Expand Down
27 changes: 4 additions & 23 deletions cli/lib/exec/run.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,7 @@ const util = require('../util')
const spawn = require('./spawn')
const verify = require('../tasks/verify')
const { exitWithError, errors } = require('../errors')

/**
* Throws an error with "details" property from
* "errors" object.
* @param {Object} details - Error details
*/
const throwInvalidOptionError = (details) => {
if (!details) {
details = errors.unknownError
}

// throw this error synchronously, it will be caught later on and
// the details will be propagated to the promise chain
const err = new Error()

err.details = details
throw err
}
const { processTestingType, throwInvalidOptionError } = require('./shared')

/**
* Typically a user passes a string path to the project.
Expand Down Expand Up @@ -154,14 +137,16 @@ const processRunOptions = (options = {}) => {
args.push('--tag', options.tag)
}

args.push(...processTestingType(options.testingType))

return args
}

module.exports = {
processRunOptions,
isValidProject,
// resolves with the number of failed tests
start (options = {}, { isComponentTesting } = { isComponentTesting: false }) {
start (options = {}) {
_.defaults(options, {
key: null,
spec: null,
Expand All @@ -183,10 +168,6 @@ module.exports = {
throw err
}

if (isComponentTesting) {
args.push('--testing-type', 'component')
}

debug('run to spawn.start args %j', args)

return spawn.start(args, {
Expand Down
45 changes: 45 additions & 0 deletions cli/lib/exec/shared.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
const { errors } = require('../errors')

/**
* Throws an error with "details" property from
* "errors" object.
* @param {Object} details - Error details
*/
const throwInvalidOptionError = (details) => {
if (!details) {
details = errors.unknownError
}

// throw this error synchronously, it will be caught later on and
// the details will be propagated to the promise chain
const err = new Error()

err.details = details
throw err
}

/**
* Selects exec args based on the configured `testingType`
* @param {string} testingType The type of tests being executed
* @returns {string[]} The array of new exec arguments
*/
const processTestingType = (testingType) => {
if (testingType) {
if (testingType === 'e2e') {
return ['--testing-type', 'e2e']
}

if (testingType === 'component') {
return ['--testing-type', 'component']
}

return throwInvalidOptionError(errors.invalidTestingType)
}

return []
}

module.exports = {
throwInvalidOptionError,
processTestingType,
}
22 changes: 22 additions & 0 deletions cli/test/lib/exec/open_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,5 +122,27 @@ describe('exec open', function () {
expect(spawn.start).to.be.calledWith([])
})
})

it('spawns without --testing-type when not specified', () => {
return open.start().then(() => {
expect(spawn.start).to.be.calledWith([])
})
})

it('spawns with --testing-type e2e', () => {
return open.start({ testingType: 'e2e' }).then(() => {
expect(spawn.start).to.be.calledWith(['--testing-type', 'e2e'])
})
})

it('spawns with --testing-type component', () => {
return open.start({ testingType: 'component' }).then(() => {
expect(spawn.start).to.be.calledWith(['--testing-type', 'component'])
})
})

it('throws if --testing-type is invalid', () => {
expect(() => open.start({ testingType: 'randomTestingType' })).to.throw()
})
})
})
22 changes: 22 additions & 0 deletions cli/test/lib/exec/run_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,28 @@ describe('exec run', function () {

snapshot(args)
})

it('defaults to e2e testingType', () => {
const args = run.processRunOptions()

snapshot(args)
})

it('passes e2e testingType', () => {
expect(run.processRunOptions({ testingType: 'e2e' })).to.deep.eq([
'--run-project', undefined, '--testing-type', 'e2e',
])
})

it('passes component testingType', () => {
expect(run.processRunOptions({ testingType: 'component' })).to.deep.eq([
'--run-project', undefined, '--testing-type', 'component',
])
})

it('throws if testingType is invalid', () => {
expect(() => run.processRunOptions({ testingType: 'randomTestingType' })).to.throw()
})
})

context('.start', function () {
Expand Down
5 changes: 5 additions & 0 deletions cli/types/cypress-npm-api.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,11 @@ declare namespace CypressCommandLine {
* Path to a specific project
*/
project: string
/**
* Specify the type of tests to execute.
* @default "e2e"
*/
testingType: 'e2e' | 'component'
}

// small utility types to better express meaning of other types
Expand Down
2 changes: 1 addition & 1 deletion npm/webpack-dev-server/src/makeWebpackConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import CypressCTOptionsPlugin, { CypressCTOptionsPluginOptions } from './plugin'

const debug = debugFn('cypress:webpack-dev-server:makeWebpackConfig')

const removeList = ['HtmlWebpackPlugin', 'PreloadPlugin']
const removeList = ['HtmlWebpackPlugin', 'PreloadPlugin', 'HtmlPwaPlugin']

export interface UserWebpackDevServerOptions {
/**
Expand Down
6 changes: 0 additions & 6 deletions npm/webpack-preprocessor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,9 @@
"private": false,
"main": "dist",
"scripts": {
"ban": "ban",
"build": "shx rm -rf dist && tsc",
"build-prod": "yarn build",
"deps": "deps-ok && dependency-check --no-dev .",
"license": "license-checker --production --onlyunknown --csv",
"secure": "nsp check",
"semantic-release": "semantic-release",
"size": "npm pack --dry",
Expand All @@ -35,7 +33,6 @@
"@typescript-eslint/eslint-plugin": "^4.18.0",
"@typescript-eslint/parser": "^4.18.0",
"babel-loader": "^8.0.2",
"ban-sensitive-files": "1.9.0",
"chai": "4.1.2",
"chalk": "3.0.0",
"chokidar-cli": "1.2.0",
Expand All @@ -49,10 +46,8 @@
"fast-glob": "3.1.1",
"find-webpack": "1.5.0",
"fs-extra": "8.1.0",
"license-checker": "13.0.3",
"mocha": "^7.1.0",
"mockery": "2.1.0",
"prettier-eslint-cli": "4.4.0",
"proxyquire": "2.1.3",
"react": "16.13.1",
"react-dom": "16.13.1",
Expand All @@ -62,7 +57,6 @@
"sinon": "^9.0.0",
"sinon-chai": "^3.5.0",
"snap-shot-it": "7.9.2",
"start-server-and-test": "1.10.11",
"ts-node": "8.10.1",
"webpack": "^4.18.1"
},
Expand Down
39 changes: 39 additions & 0 deletions packages/driver/cypress/integration/commands/net_stubbing_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,45 @@ describe('network stubbing', { retries: { runMode: 2, openMode: 0 } }, function
})
})

it('has displayName req for spies', function () {
cy.intercept('/foo*').as('getFoo')
.then(() => {
$.get('/foo')
})
.wait('@getFoo')
.then(() => {
const log = _.last(cy.queue.logs()) as any

expect(log.get('displayName')).to.eq('req')
})
})

it('has displayName req stub for stubs', function () {
cy.intercept('/foo*', { body: 'foo' }).as('getFoo')
.then(() => {
$.get('/foo')
})
.wait('@getFoo')
.then(() => {
const log = _.last(cy.queue.logs()) as any

expect(log.get('displayName')).to.eq('req stub')
})
})

it('has displayName req fn for request handlers', function () {
cy.intercept('/foo*', () => {}).as('getFoo')
.then(() => {
$.get('/foo')
})
.wait('@getFoo')
.then(() => {
const log = _.last(cy.queue.logs()) as any

expect(log.get('displayName')).to.eq('req fn')
})
})

// TODO: implement log niceties
it.skip('#consoleProps', function () {
cy.intercept('*', {
Expand Down
Loading

0 comments on commit 3963773

Please sign in to comment.