mirror of
https://github.com/cypress-io/cypress.git
synced 2026-04-19 21:51:37 -05:00
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:
13
cli/types/index.d.ts
vendored
13
cli/types/index.d.ts
vendored
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"}\`
|
||||
|
||||
`
|
||||
@@ -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"\`
|
||||
|
||||
`
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
},
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
{}
|
||||
@@ -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'))
|
||||
})
|
||||
})
|
||||
@@ -151,5 +151,9 @@ module.exports = (on, config) => {
|
||||
'get:browser:args' () {
|
||||
return browserArgs
|
||||
},
|
||||
|
||||
'get:config:value' (key) {
|
||||
return config[key]
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -573,6 +573,10 @@ const e2e = {
|
||||
args.push(`--tag=${options.tag}`)
|
||||
}
|
||||
|
||||
if (options.configFile) {
|
||||
args.push(`--config-file=${options.configFile}`)
|
||||
}
|
||||
|
||||
return args
|
||||
},
|
||||
|
||||
|
||||
@@ -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([
|
||||
|
||||
@@ -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)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user