Pass projectRoot and configFile to plugins file through config (#6317)

* decaffeinate: Rename index.coffee from .coffee to .js

* decaffeinate: Convert index.coffee to JS

* decaffeinate: Run post-processing cleanups on index.coffee

* refactor decaffeinated plugins/index.js

* decaffeinate: Rename 3_plugins_spec.coffee from .coffee to .js

* decaffeinate: Convert 3_plugins_spec.coffee to JS

* decaffeinate: Run post-processing cleanups on 3_plugins_spec.coffee

* fix wrongly removed return

* refactor e2e plugins spec, update snapshot

* pass env argument to plugins file

* decaffeinate: Rename index_spec.coffee from .coffee to .js

* decaffeinate: Convert index_spec.coffee to JS

* decaffeinate: Run post-processing cleanups on index_spec.coffee

* update plugins tests

* update scaffold snapshot

* add back server test script and document running individual tests

* add projectRoot and configFile directly to config

* normalize browsers in snapshot

* add types for configFile and projectRoot

* fix linting issues

* return return

* Merge

* remove file

* remove unnecessary returns
This commit is contained in:
Chris Breiding
2020-02-28 14:13:36 -05:00
committed by GitHub
parent e2ea5bf663
commit 778321786f
13 changed files with 200 additions and 495 deletions

13
cli/types/index.d.ts vendored
View File

@@ -52,7 +52,7 @@ declare namespace Cypress {
type RequestBody = string | object
type ViewportOrientation = "portrait" | "landscape"
type PrevSubject = "optional" | "element" | "document" | "window"
type PluginConfig = (on: PluginEvents, config: ConfigOptions) => void | Partial<ConfigOptions> | Promise<Partial<ConfigOptions>>
type PluginConfig = (on: PluginEvents, config: PluginConfigOptions) => void | Partial<ConfigOptions> | Promise<Partial<ConfigOptions>>
interface CommandOptions {
prevSubject: boolean | PrevSubject | PrevSubject[]
@@ -2282,6 +2282,17 @@ declare namespace Cypress {
firefoxGcInterval: Nullable<number | { runMode: Nullable<number>, openMode: Nullable<number> }>
}
interface PluginConfigOptions extends ConfigOptions {
/**
* Absolute path to the config file (default: <projectRoot>/cypress.json) or false
*/
configFile: string | false
/**
* Absolute path to the root of the project
*/
projectRoot: string
}
interface DebugOptions {
verbose: boolean
}

View File

@@ -5,8 +5,10 @@ const pluginConfig: Cypress.PluginConfig = (on, config) => {}
// allows synchronous returns
const pluginConfig2: Cypress.PluginConfig = (on, config) => {
config // $ExpectType ConfigOptions
config // $ExpectType PluginConfigOptions
config.baseUrl // $ExpectType: string
config.configFile // $ExpectType: string | false
config.projectRoot // $ExpectType: string
on('before:browser:launch', (browser, options) => {
browser.displayName // $ExpectType string

View File

@@ -1,404 +0,0 @@
exports['e2e plugins fails 1'] = `
====================================================================================================
(Run Starting)
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Cypress: 1.2.3 │
│ Browser: FooBrowser 88 │
│ Specs: 1 found (app_spec.coffee) │
│ Searched: cypress/integration/app_spec.coffee │
└────────────────────────────────────────────────────────────────────────────────────────────────┘
────────────────────────────────────────────────────────────────────────────────────────────────────
Running: app_spec.coffee (1 of 1)
The following error was thrown by a plugin. We've stopped running your tests because a plugin crashed.
Error: Async error from plugins file
[stack trace lines]
(Results)
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Tests: 0 │
│ Passing: 0 │
│ Failing: 1 │
│ Pending: 0 │
│ Skipped: 0 │
│ Screenshots: 0 │
│ Video: true │
│ Duration: X seconds │
│ Spec Ran: app_spec.coffee │
└────────────────────────────────────────────────────────────────────────────────────────────────┘
(Video)
- Started processing: Compressing to 32 CRF
- Finished processing: /XXX/XXX/XXX/cypress/videos/app_spec.coffee.mp4 (X second)
====================================================================================================
(Run Finished)
Spec Tests Passing Failing Pending Skipped
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
│ ✖ app_spec.coffee XX:XX - - 1 - - │
└────────────────────────────────────────────────────────────────────────────────────────────────┘
✖ 1 of 1 failed (100%) XX:XX - - 1 - -
`
exports['e2e plugins passes 1'] = `
====================================================================================================
(Run Starting)
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Cypress: 1.2.3 │
│ Browser: FooBrowser 88 │
│ Specs: 1 found (app_spec.coffee) │
│ Searched: cypress/integration/app_spec.coffee │
└────────────────────────────────────────────────────────────────────────────────────────────────┘
────────────────────────────────────────────────────────────────────────────────────────────────────
Running: app_spec.coffee (1 of 1)
✓ is another spec
✓ is another spec
2 passing
(Results)
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Tests: 2 │
│ Passing: 2 │
│ Failing: 0 │
│ Pending: 0 │
│ Skipped: 0 │
│ Screenshots: 0 │
│ Video: true │
│ Duration: X seconds │
│ Spec Ran: app_spec.coffee │
└────────────────────────────────────────────────────────────────────────────────────────────────┘
(Video)
- Started processing: Compressing to 32 CRF
- Finished processing: /XXX/XXX/XXX/cypress/videos/app_spec.coffee.mp4 (X second)
====================================================================================================
(Run Finished)
Spec Tests Passing Failing Pending Skipped
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
│ ✔ app_spec.coffee XX:XX 2 2 - - - │
└────────────────────────────────────────────────────────────────────────────────────────────────┘
✔ All specs passed! XX:XX 2 2 - - -
`
exports['e2e plugins can modify config from plugins 1'] = `
====================================================================================================
(Run Starting)
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Cypress: 1.2.3 │
│ Browser: FooBrowser 88 │
│ Specs: 1 found (app_spec.coffee) │
│ Searched: cypress/integration/app_spec.coffee │
└────────────────────────────────────────────────────────────────────────────────────────────────┘
────────────────────────────────────────────────────────────────────────────────────────────────────
Running: app_spec.coffee (1 of 1)
✓ overrides config
✓ overrides env
2 passing
(Results)
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Tests: 2 │
│ Passing: 2 │
│ Failing: 0 │
│ Pending: 0 │
│ Skipped: 0 │
│ Screenshots: 0 │
│ Video: true │
│ Duration: X seconds │
│ Spec Ran: app_spec.coffee │
└────────────────────────────────────────────────────────────────────────────────────────────────┘
(Video)
- Started processing: Compressing to 20 CRF
- Finished processing: /XXX/XXX/XXX/cypress/videos/app_spec.coffee.mp4 (X second)
====================================================================================================
(Run Finished)
Spec Tests Passing Failing Pending Skipped
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
│ ✔ app_spec.coffee XX:XX 2 2 - - - │
└────────────────────────────────────────────────────────────────────────────────────────────────┘
✔ All specs passed! XX:XX 2 2 - - -
`
exports['e2e plugins / works with user extensions'] = `
====================================================================================================
(Run Starting)
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Cypress: 1.2.3 │
│ Browser: FooBrowser 88 │
│ Specs: 1 found (app_spec.coffee) │
│ Searched: cypress/integration/app_spec.coffee │
└────────────────────────────────────────────────────────────────────────────────────────────────┘
────────────────────────────────────────────────────────────────────────────────────────────────────
Running: app_spec.coffee (1 of 1)
✓ can inject text from an extension
1 passing
(Results)
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Tests: 1 │
│ Passing: 1 │
│ Failing: 0 │
│ Pending: 0 │
│ Skipped: 0 │
│ Screenshots: 0 │
│ Video: true │
│ Duration: X seconds │
│ Spec Ran: app_spec.coffee │
└────────────────────────────────────────────────────────────────────────────────────────────────┘
(Video)
- Started processing: Compressing to 32 CRF
- Finished processing: /XXX/XXX/XXX/cypress/videos/app_spec.coffee.mp4 (X second)
====================================================================================================
(Run Finished)
Spec Tests Passing Failing Pending Skipped
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
│ ✔ app_spec.coffee XX:XX 1 1 - - - │
└────────────────────────────────────────────────────────────────────────────────────────────────┘
✔ All specs passed! XX:XX 1 1 - - -
`
exports['e2e plugins handles absolute path to pluginsFile 1'] = `
====================================================================================================
(Run Starting)
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Cypress: 1.2.3 │
│ Browser: FooBrowser 88 │
│ Specs: 1 found (absolute_spec.coffee) │
│ Searched: cypress/integration/absolute_spec.coffee │
└────────────────────────────────────────────────────────────────────────────────────────────────┘
────────────────────────────────────────────────────────────────────────────────────────────────────
Running: absolute_spec.coffee (1 of 1)
✓ uses the plugins file
1 passing
(Results)
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Tests: 1 │
│ Passing: 1 │
│ Failing: 0 │
│ Pending: 0 │
│ Skipped: 0 │
│ Screenshots: 0 │
│ Video: true │
│ Duration: X seconds │
│ Spec Ran: absolute_spec.coffee │
└────────────────────────────────────────────────────────────────────────────────────────────────┘
(Video)
- Started processing: Compressing to 32 CRF
- Finished processing: /XXX/XXX/XXX/cypress/videos/absolute_spec.coffee.mp4 (X second)
====================================================================================================
(Run Finished)
Spec Tests Passing Failing Pending Skipped
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
│ ✔ absolute_spec.coffee XX:XX 1 1 - - - │
└────────────────────────────────────────────────────────────────────────────────────────────────┘
✔ All specs passed! XX:XX 1 1 - - -
`
exports['e2e plugins calls after:screenshot for cy.screenshot() and failure screenshots 1'] = `
====================================================================================================
(Run Starting)
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Cypress: 1.2.3 │
│ Browser: FooBrowser 88 │
│ Specs: 1 found (after_screenshot_spec.coffee) │
│ Searched: cypress/integration/after_screenshot_spec.coffee │
└────────────────────────────────────────────────────────────────────────────────────────────────┘
────────────────────────────────────────────────────────────────────────────────────────────────────
Running: after_screenshot_spec.coffee (1 of 1)
✓ cy.screenshot() - replacement
✓ cy.screenshot() - ignored values
✓ cy.screenshot() - invalid return
1) failure screenshot - rename
3 passing
1 failing
1) failure screenshot - rename:
Error: test error
[stack trace lines]
(Results)
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Tests: 4 │
│ Passing: 3 │
│ Failing: 1 │
│ Pending: 0 │
│ Skipped: 0 │
│ Screenshots: 4 │
│ Video: true │
│ Duration: X seconds │
│ Spec Ran: after_screenshot_spec.coffee │
└────────────────────────────────────────────────────────────────────────────────────────────────┘
(Screenshots)
- /XXX/XXX/XXX/screenshot-replacement.png (YxX)
- /XXX/XXX/XXX/cypress/screenshots/after_screenshot_spec.coffee/ignored-values.png (YxX)
- /XXX/XXX/XXX/cypress/screenshots/after_screenshot_spec.coffee/invalid-return.png (YxX)
- /XXX/XXX/XXX/screenshot-replacement.png (YxX)
(Video)
- Started processing: Compressing to 32 CRF
- Finished processing: /XXX/XXX/XXX/cypress/videos/after_screenshot_spec.coffee.mp (X second)
4
====================================================================================================
(Run Finished)
Spec Tests Passing Failing Pending Skipped
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
│ ✖ after_screenshot_spec.coffee XX:XX 4 3 1 - - │
└────────────────────────────────────────────────────────────────────────────────────────────────┘
✖ 1 of 1 failed (100%) XX:XX 4 3 1 - -
`
exports['e2e plugins can filter browsers from config 1'] = `
Can't run because you've entered an invalid browser name.
Browser: 'chrome' was not found on your system.
Available browsers found are: electron
`
exports['e2e plugins catches invalid viewportWidth returned from plugins 1'] = `
An invalid configuration value returned from the plugins file: \`cypress/plugins/index.coffee\`
Expected \`viewportWidth\` to be a number. Instead the value was: \`"foo"\`
`
exports['e2e plugins catches invalid browsers list returned from plugins 1'] = `
An invalid configuration value returned from the plugins file: \`cypress/plugins/index.coffee\`
Expected at least one browser
`
exports['e2e plugins catches invalid browser returned from plugins 1'] = `
An invalid configuration value returned from the plugins file: \`cypress/plugins/index.coffee\`
Found an error while validating the \`browsers\` list. Expected \`displayName\` to be a non-empty string. Instead the value was: \`{"name":"browser name","family":"chromium"}\`
`

View File

@@ -1,4 +1,4 @@
exports['e2e plugins passes 1'] = `
exports['e2e plugins passes with working preprocessor 1'] = `
====================================================================================================
@@ -58,7 +58,7 @@ exports['e2e plugins passes 1'] = `
`
exports['e2e plugins fails 1'] = `
exports['e2e plugins fails with async error 1'] = `
====================================================================================================
@@ -175,13 +175,6 @@ exports['e2e plugins can modify config from plugins 1'] = `
✔ All specs passed! XX:XX 2 2 - - -
`
exports['e2e plugins catches invalid viewportWidth returned from plugins 1'] = `
An invalid configuration value returned from the plugins file: \`cypress/plugins/index.coffee\`
Expected \`viewportWidth\` to be a number. Instead the value was: \`"foo"\`
`
exports['e2e plugins catches invalid browsers list returned from plugins 1'] = `
@@ -402,3 +395,10 @@ exports['e2e plugins calls after:screenshot for cy.screenshot() and failure scre
`
exports['e2e plugins catches invalid viewportWidth returned from plugins 1'] = `
An invalid configuration value returned from the plugins file: \`cypress/plugins/index.coffee\`
Expected \`viewportWidth\` to be a number. Instead the value was: \`"foo"\`
`

View File

@@ -68,9 +68,16 @@ const init = (config, options) => {
handler(ipc)
}
_.extend(config, {
projectRoot: options.projectRoot,
configFile: options.configFile,
})
ipc.send('load', config)
ipc.on('loaded', (newCfg, registrations) => {
_.omit(config, 'projectRoot', 'configFile')
_.each(registrations, (registration) => {
debug('register plugins process event', registration.event, 'with id', registration.eventId)
@@ -105,9 +112,7 @@ const init = (config, options) => {
const handleError = (err) => {
debug('plugins process error:', err.stack)
if (!pluginsProcess) {
return // prevent repeating this in case of multiple errors
}
if (!pluginsProcess) return // prevent repeating this in case of multiple errors
killPluginsProcess()
err = errors.get('PLUGINS_ERROR', err.annotated || err.stack || err.message)
@@ -116,11 +121,9 @@ const init = (config, options) => {
return options.onError(err)
}
const handleWarning = function (warningErr) {
const handleWarning = (warningErr) => {
debug('plugins process warning:', warningErr.stack)
if (!pluginsProcess) {
return // prevent repeating this in case of multiple warnings
}
if (!pluginsProcess) return // prevent repeating this in case of multiple warnings
return options.onWarning(warningErr)
}

View File

@@ -159,6 +159,8 @@ class Project extends EE {
cfg = config.whitelist(cfg)
return plugins.init(cfg, {
projectRoot: this.projectRoot,
configFile: settings.pathToConfigFile(this.projectRoot, options),
onError (err) {
debug('got plugins error', err.stack)

View File

@@ -3,6 +3,7 @@ const path = require('path')
const e2e = require('../support/helpers/e2e')
const Fixtures = require('../support/helpers/fixtures')
const e2eProject = Fixtures.projectPath('e2e')
const pluginExtension = Fixtures.projectPath('plugin-extension')
const pluginConfig = Fixtures.projectPath('plugin-config')
const pluginFilterBrowsers = Fixtures.projectPath('plugin-filter-browsers')
@@ -14,10 +15,10 @@ const pluginReturnsBadConfig = Fixtures.projectPath('plugin-returns-bad-config')
const pluginReturnsEmptyBrowsersList = Fixtures.projectPath('plugin-returns-empty-browsers-list')
const pluginReturnsInvalidBrowser = Fixtures.projectPath('plugin-returns-invalid-browser')
describe('e2e plugins', () => {
describe('e2e plugins', function () {
e2e.setup()
it('passes', function () {
it('passes with working preprocessor', function () {
return e2e.exec(this, {
spec: 'app_spec.coffee',
project: workingPreprocessor,
@@ -26,7 +27,7 @@ describe('e2e plugins', () => {
})
})
it('fails', function () {
it('fails with async error', function () {
return e2e.exec(this, {
spec: 'app_spec.coffee',
project: pluginsAsyncError,
@@ -121,4 +122,44 @@ describe('e2e plugins', () => {
expectedExitCode: 1,
})
})
describe('projectRoot and configFile', function () {
it('passes projectRoot and default configFile to plugins function', function () {
return e2e.exec(this, {
spec: 'plugins_config_extras_spec.js',
config: {
env: {
projectRoot: e2eProject,
configFile: path.join(e2eProject, 'cypress.json'),
},
},
})
})
it('passes custom configFile to plugins function', function () {
return e2e.exec(this, {
spec: 'plugins_config_extras_spec.js',
configFile: 'cypress-alt.json',
config: {
env: {
projectRoot: e2eProject,
configFile: path.join(e2eProject, 'cypress-alt.json'),
},
},
})
})
it('passes false configFile to plugins function', function () {
return e2e.exec(this, {
spec: 'plugins_config_extras_spec.js',
configFile: 'false',
config: {
env: {
projectRoot: e2eProject,
configFile: false,
},
},
})
})
})
})

View File

@@ -0,0 +1,13 @@
describe('plugins config extras', () => {
it('has correct projectRoot', () => {
cy.task('get:config:value', 'projectRoot')
.should('not.be.undefined')
.and('equal', Cypress.env('projectRoot'))
})
it('has correct configFile', () => {
cy.task('get:config:value', 'configFile')
.should('not.be.undefined')
.and('equal', Cypress.env('configFile'))
})
})

View File

@@ -151,5 +151,9 @@ module.exports = (on, config) => {
'get:browser:args' () {
return browserArgs
},
'get:config:value' (key) {
return config[key]
},
})
}

View File

@@ -573,6 +573,10 @@ const e2e = {
args.push(`--tag=${options.tag}`)
}
if (options.configFile) {
args.push(`--config-file=${options.configFile}`)
}
return args
},

View File

@@ -6,6 +6,9 @@ browsers = require("#{root}../lib/browsers")
utils = require("#{root}../lib/browsers/utils")
snapshot = require('snap-shot-it')
normalizeBrowsers = (message) ->
message.replace(/(found are: ).*/, "$1chrome, firefox, electron")
describe "lib/browsers/index", ->
context ".getBrowserInstance", ->
it "returns instance", ->
@@ -40,7 +43,7 @@ describe "lib/browsers/index", ->
expect(browsers.ensureAndGetByNameOrPath("browserNotGonnaBeFound"))
.to.be.rejectedWith({ type: 'BROWSER_NOT_FOUND_BY_NAME' })
.then (err) ->
snapshot(err.message)
snapshot(normalizeBrowsers(err.message))
it "throws a special error when canary is passed", ->
sinon.stub(utils, "getBrowsers").resolves([

View File

@@ -8,36 +8,53 @@ const plugins = require(`${root}../lib/plugins`)
const PLUGIN_PID = 77777
describe('lib/plugins/index', () => {
beforeEach(function () {
let pluginsProcess
let ipc
let configExtras
let getOptions
beforeEach(() => {
plugins._reset()
this.pluginsProcess = {
configExtras = {
projectRoot: '/path/to/project/root',
configFile: '/path/to/project/root/cypress.json',
}
getOptions = (overrides = {}) => {
return {
...configExtras,
...overrides,
}
}
pluginsProcess = {
send: sinon.spy(),
on: sinon.stub(),
kill: sinon.spy(),
pid: PLUGIN_PID,
}
sinon.stub(cp, 'fork').returns(this.pluginsProcess)
sinon.stub(cp, 'fork').returns(pluginsProcess)
this.ipc = {
ipc = {
send: sinon.spy(),
on: sinon.stub(),
}
sinon.stub(util, 'wrapIpc').returns(this.ipc)
sinon.stub(util, 'wrapIpc').returns(ipc)
})
context('#init', () => {
it('is noop if no pluginsFile', () => {
return plugins.init({}) // doesn't reject or time out
return plugins.init({}, getOptions()) // doesn't reject or time out
})
it('forks child process', function () {
// have to fire 'loaded' message, otherwise plugins.init promise never resolves
this.ipc.on.withArgs('loaded').yields([])
it('forks child process', () => {
// have to fire "loaded" message, otherwise plugins.init promise never resolves
ipc.on.withArgs('loaded').yields([])
return plugins.init({ pluginsFile: 'cypress-plugin' })
return plugins.init({ pluginsFile: 'cypress-plugin' }, getOptions())
.then(() => {
expect(cp.fork).to.be.called
expect(cp.fork.lastCall.args[0]).to.contain('plugins/child/index.js')
@@ -46,8 +63,8 @@ describe('lib/plugins/index', () => {
})
})
it('uses system Node when available', function () {
this.ipc.on.withArgs('loaded').yields([])
it('uses system Node when available', () => {
ipc.on.withArgs('loaded').yields([])
const systemNode = '/my/path/to/system/node'
const config = {
pluginsFile: 'cypress-plugin',
@@ -56,7 +73,7 @@ describe('lib/plugins/index', () => {
resolvedNodePath: systemNode,
}
return plugins.init(config)
return plugins.init(config, getOptions())
.then(() => {
const options = {
stdio: 'inherit',
@@ -67,15 +84,15 @@ describe('lib/plugins/index', () => {
})
})
it('uses bundled Node when cannot find system Node', function () {
this.ipc.on.withArgs('loaded').yields([])
it('uses bundled Node when cannot find system Node', () => {
ipc.on.withArgs('loaded').yields([])
const config = {
pluginsFile: 'cypress-plugin',
nodeVersion: 'system',
resolvedNodeVersion: 'v1.2.3',
}
return plugins.init(config)
return plugins.init(config, getOptions())
.then(() => {
const options = {
stdio: 'inherit',
@@ -85,13 +102,13 @@ describe('lib/plugins/index', () => {
})
})
it('calls any handlers registered with the wrapped ipc', function () {
this.ipc.on.withArgs('loaded').yields([])
it('calls any handlers registered with the wrapped ipc', () => {
ipc.on.withArgs('loaded').yields([])
const handler = sinon.spy()
plugins.registerHandler(handler)
return plugins.init({ pluginsFile: 'cypress-plugin' })
return plugins.init({ pluginsFile: 'cypress-plugin' }, getOptions())
.then(() => {
expect(handler).to.be.called
expect(handler.lastCall.args[0].send).to.be.a('function')
@@ -100,51 +117,56 @@ describe('lib/plugins/index', () => {
})
})
it('sends config via ipc', function () {
this.ipc.on.withArgs('loaded').yields([])
it('sends \'load\' event with config via ipc', () => {
ipc.on.withArgs('loaded').yields([])
const config = { pluginsFile: 'cypress-plugin' }
return plugins.init(config).then(() => {
expect(this.ipc.send).to.be.calledWith('load', config)
return plugins.init(config, getOptions()).then(() => {
expect(ipc.send).to.be.calledWith('load', {
...config,
...configExtras,
})
})
})
it('resolves once it receives \'loaded\' message', function () {
this.ipc.on.withArgs('loaded').yields([])
it('resolves once it receives \'loaded\' message', () => {
ipc.on.withArgs('loaded').yields([])
// should resolve and not time out
return plugins.init({ pluginsFile: 'cypress-plugin' })
return plugins.init({ pluginsFile: 'cypress-plugin' }, getOptions())
})
it('kills child process if it already exists', function () {
this.ipc.on.withArgs('loaded').yields([])
it('kills child process if it already exists', () => {
ipc.on.withArgs('loaded').yields([])
return plugins.init({ pluginsFile: 'cypress-plugin' })
return plugins.init({ pluginsFile: 'cypress-plugin' }, getOptions())
.then(() => {
return plugins.init({ pluginsFile: 'cypress-plugin' })
return plugins.init({ pluginsFile: 'cypress-plugin' }, getOptions())
}).then(() => {
expect(this.pluginsProcess.kill).to.be.calledOnce
expect(pluginsProcess.kill).to.be.calledOnce
})
})
describe('loaded message', () => {
beforeEach(function () {
this.config = {}
let config
this.ipc.on.withArgs('loaded').yields(this.config, [{
beforeEach(() => {
config = {}
ipc.on.withArgs('loaded').yields(config, [{
event: 'some:event',
eventId: 0,
}])
return plugins.init({ pluginsFile: 'cypress-plugin' })
return plugins.init({ pluginsFile: 'cypress-plugin' }, getOptions())
})
it('sends \'execute\' message when event is executed, wrapped in promise', function () {
it('sends \'execute\' message when event is executed, wrapped in promise', () => {
sinon.stub(util, 'wrapParentPromise').resolves('value').yields('00')
return plugins.execute('some:event', 'foo', 'bar').then((value) => {
expect(util.wrapParentPromise).to.be.called
expect(this.ipc.send).to.be.calledWith(
expect(ipc.send).to.be.calledWith(
'execute',
'some:event',
{ eventId: 0, invocationId: '00' },
@@ -158,12 +180,12 @@ describe('lib/plugins/index', () => {
describe('load:error message', () => {
context('PLUGINS_FILE_ERROR', () => {
beforeEach(function () {
this.ipc.on.withArgs('load:error').yields('PLUGINS_FILE_ERROR', 'path/to/pluginsFile.js', 'error message stack')
beforeEach(() => {
ipc.on.withArgs('load:error').yields('PLUGINS_FILE_ERROR', 'path/to/pluginsFile.js', 'error message stack')
})
it('rejects plugins.init', () => {
return plugins.init({ pluginsFile: 'cypress-plugin' })
return plugins.init({ pluginsFile: 'cypress-plugin' }, getOptions())
.catch((err) => {
expect(err.message).to.contain('The plugins file is missing or invalid')
expect(err.message).to.contain('path/to/pluginsFile.js')
@@ -174,12 +196,12 @@ describe('lib/plugins/index', () => {
})
context('PLUGINS_FUNCTION_ERROR', () => {
beforeEach(function () {
this.ipc.on.withArgs('load:error').yields('PLUGINS_FUNCTION_ERROR', 'path/to/pluginsFile.js', 'error message stack')
beforeEach(() => {
ipc.on.withArgs('load:error').yields('PLUGINS_FUNCTION_ERROR', 'path/to/pluginsFile.js', 'error message stack')
})
it('rejects plugins.init', () => {
return plugins.init({ pluginsFile: 'cypress-plugin' })
return plugins.init({ pluginsFile: 'cypress-plugin' }, getOptions())
.catch((err) => {
expect(err.message).to.contain('The function exported by the plugins file threw an error.')
expect(err.message).to.contain('path/to/pluginsFile.js')
@@ -191,46 +213,49 @@ describe('lib/plugins/index', () => {
})
describe('error message', () => {
beforeEach(function () {
this.err = {
let err
let onError
beforeEach(() => {
err = {
name: 'error name',
message: 'error message',
}
this.onError = sinon.spy()
this.ipc.on.withArgs('loaded').yields([])
onError = sinon.spy()
ipc.on.withArgs('loaded').yields([])
return plugins.init({ pluginsFile: 'cypress-plugin' }, { onError: this.onError })
return plugins.init({ pluginsFile: 'cypress-plugin' }, getOptions({ onError }))
})
it('kills the plugins process when plugins process errors', function () {
this.pluginsProcess.on.withArgs('error').yield(this.err)
it('kills the plugins process when plugins process errors', () => {
pluginsProcess.on.withArgs('error').yield(err)
expect(this.pluginsProcess.kill).to.be.called
expect(pluginsProcess.kill).to.be.called
})
it('kills the plugins process when ipc sends error', function () {
this.ipc.on.withArgs('error').yield(this.err)
it('kills the plugins process when ipc sends error', () => {
ipc.on.withArgs('error').yield(err)
expect(this.pluginsProcess.kill).to.be.called
expect(pluginsProcess.kill).to.be.called
})
it('calls onError when plugins process errors', function () {
this.pluginsProcess.on.withArgs('error').yield(this.err)
expect(this.onError).to.be.called
expect(this.onError.lastCall.args[0].title).to.equal('Error running plugin')
expect(this.onError.lastCall.args[0].stack).to.include('The following error was thrown by a plugin')
it('calls onError when plugins process errors', () => {
pluginsProcess.on.withArgs('error').yield(err)
expect(onError).to.be.called
expect(onError.lastCall.args[0].title).to.equal('Error running plugin')
expect(onError.lastCall.args[0].stack).to.include('The following error was thrown by a plugin')
expect(this.onError.lastCall.args[0].details).to.include(this.err.message)
expect(onError.lastCall.args[0].details).to.include(err.message)
})
it('calls onError when ipc sends error', function () {
this.ipc.on.withArgs('error').yield(this.err)
expect(this.onError).to.be.called
expect(this.onError.lastCall.args[0].title).to.equal('Error running plugin')
expect(this.onError.lastCall.args[0].stack).to.include('The following error was thrown by a plugin')
it('calls onError when ipc sends error', () => {
ipc.on.withArgs('error').yield(err)
expect(onError).to.be.called
expect(onError.lastCall.args[0].title).to.equal('Error running plugin')
expect(onError.lastCall.args[0].stack).to.include('The following error was thrown by a plugin')
expect(this.onError.lastCall.args[0].details).to.include(this.err.message)
expect(onError.lastCall.args[0].details).to.include(err.message)
})
})
})
@@ -286,10 +311,10 @@ describe('lib/plugins/index', () => {
plugins._setPluginsProcess(null)
})
it('returns the pid if there is a plugins process', function () {
this.ipc.on.withArgs('loaded').yields([])
it('returns the pid if there is a plugins process', () => {
ipc.on.withArgs('loaded').yields([])
return plugins.init({ pluginsFile: 'cypress-plugin' })
return plugins.init({ pluginsFile: 'cypress-plugin' }, getOptions())
.then(() => {
expect(plugins.getPluginPid()).to.eq(PLUGIN_PID)
})