mirror of
https://github.com/cypress-io/cypress.git
synced 2026-05-03 05:20:38 -05:00
chore: add docsUrl to intercept, task errors (#15711)
This commit is contained in:
Vendored
+1
-1
@@ -1784,7 +1784,7 @@ declare namespace Cypress {
|
||||
/**
|
||||
* Run a task in Node via the plugins file.
|
||||
*
|
||||
* @see https://on.cypress.io/task
|
||||
* @see https://on.cypress.io/api/task
|
||||
*/
|
||||
task<S = unknown>(event: string, arg?: any, options?: Partial<Loggable & Timeoutable>): Chainable<S>
|
||||
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
const testFail = (cb, expectedDocsUrl = 'https://on.cypress.io/intercept') => {
|
||||
cy.on('fail', (err) => {
|
||||
// @ts-ignore
|
||||
const docsUrl = Array.isArray(err.docsUrl) ? err.docsUrl[0] : err.docsUrl
|
||||
|
||||
expect(docsUrl).to.eq(expectedDocsUrl)
|
||||
cb(err)
|
||||
})
|
||||
}
|
||||
|
||||
describe('network stubbing', { retries: { runMode: 2, openMode: 0 } }, function () {
|
||||
const { $, _, sinon, state, Promise } = Cypress
|
||||
|
||||
@@ -436,21 +446,13 @@ describe('network stubbing', { retries: { runMode: 2, openMode: 0 } }, function
|
||||
|
||||
it('has name of route', function () {
|
||||
cy.intercept('/foo', {}).then(function () {
|
||||
let lastLog
|
||||
|
||||
lastLog = this.lastLog
|
||||
|
||||
expect(lastLog.get('name')).to.eq('route')
|
||||
expect(this.lastLog.get('name')).to.eq('route')
|
||||
})
|
||||
})
|
||||
|
||||
it('uses the wildcard URL', function () {
|
||||
cy.intercept('*', {}).then(function () {
|
||||
let lastLog
|
||||
|
||||
lastLog = this.lastLog
|
||||
|
||||
expect(lastLog.get('url')).to.eq('*')
|
||||
expect(this.lastLog.get('url')).to.eq('*')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -502,13 +504,18 @@ describe('network stubbing', { retries: { runMode: 2, openMode: 0 } }, function
|
||||
this.logs = []
|
||||
|
||||
cy.on('log:added', (attrs, log) => {
|
||||
// @ts-ignore
|
||||
if (log.get('name') !== 'intercept') {
|
||||
return
|
||||
}
|
||||
|
||||
this.lastLog = log
|
||||
this.logs.push(log)
|
||||
})
|
||||
})
|
||||
|
||||
it('url must be a string or regexp', function (done) {
|
||||
cy.on('fail', function (err) {
|
||||
testFail((err) => {
|
||||
expect(err.message).to.include('`url` must be a string or a regular expression')
|
||||
|
||||
done()
|
||||
@@ -523,7 +530,7 @@ describe('network stubbing', { retries: { runMode: 2, openMode: 0 } }, function
|
||||
|
||||
// TODO: not currently implemented
|
||||
it.skip('fails when method is invalid', function (done) {
|
||||
cy.on('fail', function (err) {
|
||||
testFail((err) => {
|
||||
expect(err.message).to.include('cy.intercept() was called with an invalid method: \'POSTS\'.')
|
||||
|
||||
done()
|
||||
@@ -533,7 +540,7 @@ describe('network stubbing', { retries: { runMode: 2, openMode: 0 } }, function
|
||||
})
|
||||
|
||||
it('requires a url when given a response', function (done) {
|
||||
cy.on('fail', function (err) {
|
||||
testFail((err) => {
|
||||
expect(err.message).to.include('The RouteMatcher does not contain any keys. You must pass something to match on.')
|
||||
|
||||
done()
|
||||
@@ -543,7 +550,7 @@ describe('network stubbing', { retries: { runMode: 2, openMode: 0 } }, function
|
||||
})
|
||||
|
||||
it('requires arguments', function (done) {
|
||||
cy.on('fail', function (err) {
|
||||
testFail((err) => {
|
||||
expect(err.message).to.include('An invalid RouteMatcher was supplied to `cy.intercept()`. The RouteMatcher does not contain any keys. You must pass something to match on.')
|
||||
|
||||
done()
|
||||
@@ -554,7 +561,7 @@ describe('network stubbing', { retries: { runMode: 2, openMode: 0 } }, function
|
||||
})
|
||||
|
||||
it('cannot merge url with url', function (done) {
|
||||
cy.on('fail', function (err) {
|
||||
testFail((err) => {
|
||||
expect(err.message).to.include('When invoking \`cy.intercept()\` with a \`RouteMatcher\` as the second parameter, \`url\` can only be specified as the first parameter')
|
||||
|
||||
done()
|
||||
@@ -565,7 +572,7 @@ describe('network stubbing', { retries: { runMode: 2, openMode: 0 } }, function
|
||||
})
|
||||
|
||||
it('cannot pass RouteMatcherOptions in 2nd arg with no handler', function (done) {
|
||||
cy.on('fail', function (err) {
|
||||
testFail((err) => {
|
||||
expect(err.message).to.include('When invoking \`cy.intercept()\` with a \`RouteMatcher\` as the second parameter, a handler (function or \`StaticResponse\`) must be specified as the third parameter.')
|
||||
|
||||
done()
|
||||
@@ -577,7 +584,7 @@ describe('network stubbing', { retries: { runMode: 2, openMode: 0 } }, function
|
||||
|
||||
context('with invalid RouteMatcher', function () {
|
||||
it('requires unique header names', function (done) {
|
||||
cy.on('fail', function (err) {
|
||||
testFail((err) => {
|
||||
expect(err.message).to.include('`FOO` was specified more than once in `headers`. Header fields can only be matched once (HTTP header field names are case-insensitive).')
|
||||
|
||||
done()
|
||||
@@ -592,7 +599,7 @@ describe('network stubbing', { retries: { runMode: 2, openMode: 0 } }, function
|
||||
})
|
||||
|
||||
it('requires StringMatcher header values', function (done) {
|
||||
cy.on('fail', function (err) {
|
||||
testFail((err) => {
|
||||
expect(err.message).to.include('`headers.wrong` must be a string or a regular expression.')
|
||||
|
||||
done()
|
||||
@@ -610,7 +617,7 @@ describe('network stubbing', { retries: { runMode: 2, openMode: 0 } }, function
|
||||
})
|
||||
|
||||
it('errors on matchUrlAgainstPath usage', function (done) {
|
||||
cy.on('fail', function (err) {
|
||||
testFail((err) => {
|
||||
expect(err.message).to.include('`matchUrlAgainstPath` was removed in Cypress 7.0.0')
|
||||
|
||||
done()
|
||||
@@ -621,7 +628,7 @@ describe('network stubbing', { retries: { runMode: 2, openMode: 0 } }, function
|
||||
})
|
||||
|
||||
it('errors on unknown prop', function (done) {
|
||||
cy.on('fail', function (err) {
|
||||
testFail((err) => {
|
||||
expect(err.message).to.include('An unknown \`RouteMatcher\` property was passed: `wrong`')
|
||||
|
||||
done()
|
||||
@@ -637,7 +644,7 @@ describe('network stubbing', { retries: { runMode: 2, openMode: 0 } }, function
|
||||
const name = String(handler)
|
||||
|
||||
it(`${name} fails`, function (done) {
|
||||
cy.on('fail', (err) => {
|
||||
testFail((err) => {
|
||||
expect(err).to.eq(this.lastLog.get('error'))
|
||||
expect(err.message).to.contain(`You passed: ${name}`)
|
||||
|
||||
@@ -669,7 +676,7 @@ describe('network stubbing', { retries: { runMode: 2, openMode: 0 } }, function
|
||||
],
|
||||
].forEach(function ([name, handler, expectedErr]) {
|
||||
it(`${name} fails`, function (done) {
|
||||
cy.on('fail', (err) => {
|
||||
testFail((err) => {
|
||||
expect(err).to.eq(this.lastLog.get('error'))
|
||||
expect(err.message).to.contain(expectedErr)
|
||||
expect(err.message).to.contain(`You passed: ${JSON.stringify(handler, null, 2)}`)
|
||||
@@ -1336,7 +1343,7 @@ describe('network stubbing', { retries: { runMode: 2, openMode: 0 } }, function
|
||||
|
||||
context('errors', function () {
|
||||
it('when unknown eventName is passed', function (done) {
|
||||
cy.on('fail', (err) => {
|
||||
testFail((err) => {
|
||||
expect(err.message).to.contain('An invalid event name was passed as the first parameter to \`req.on()\`.')
|
||||
done()
|
||||
})
|
||||
@@ -1348,7 +1355,7 @@ describe('network stubbing', { retries: { runMode: 2, openMode: 0 } }, function
|
||||
})
|
||||
|
||||
it('when no function is passed', function (done) {
|
||||
cy.on('fail', (err) => {
|
||||
testFail((err) => {
|
||||
expect(err.message).to.contain('\`req.on()\` requires the second parameter to be a function.')
|
||||
done()
|
||||
})
|
||||
@@ -1615,7 +1622,7 @@ describe('network stubbing', { retries: { runMode: 2, openMode: 0 } }, function
|
||||
|
||||
context('errors', function () {
|
||||
it('fails test if req.reply is called twice in req handler', function (done) {
|
||||
cy.on('fail', (err) => {
|
||||
testFail((err) => {
|
||||
expect(err.message).to.contain('`req.reply()` and/or `req.continue()` were called to signal request completion multiple times, but a request can only be completed once')
|
||||
done()
|
||||
})
|
||||
@@ -1628,7 +1635,7 @@ describe('network stubbing', { retries: { runMode: 2, openMode: 0 } }, function
|
||||
})
|
||||
|
||||
it('fails test if req.reply is called after req handler finishes', function (done) {
|
||||
cy.on('fail', (err) => {
|
||||
testFail((err) => {
|
||||
expect(err.message).to.contain('> `req.reply()` was called after the request handler finished executing')
|
||||
done()
|
||||
})
|
||||
@@ -1639,7 +1646,7 @@ describe('network stubbing', { retries: { runMode: 2, openMode: 0 } }, function
|
||||
})
|
||||
|
||||
it('fails test if req.reply is called after req handler resolves', function (done) {
|
||||
cy.on('fail', (err) => {
|
||||
testFail((err) => {
|
||||
expect(err.message).to.contain('> `req.reply()` was called after the request handler finished executing')
|
||||
done()
|
||||
})
|
||||
@@ -1652,7 +1659,7 @@ describe('network stubbing', { retries: { runMode: 2, openMode: 0 } }, function
|
||||
})
|
||||
|
||||
it('fails test if an exception is thrown in req handler', function (done) {
|
||||
cy.on('fail', (err2) => {
|
||||
testFail((err2) => {
|
||||
expect(err2.message).to.contain('A request callback passed to `cy.intercept()` threw an error while intercepting a request')
|
||||
.and.contain(err.message)
|
||||
|
||||
@@ -1667,7 +1674,7 @@ describe('network stubbing', { retries: { runMode: 2, openMode: 0 } }, function
|
||||
})
|
||||
|
||||
it('fails test if req.reply is called with an invalid StaticResponse', function (done) {
|
||||
cy.on('fail', (err) => {
|
||||
testFail((err) => {
|
||||
expect(err.message).to.contain('A request callback passed to `cy.intercept()` threw an error while intercepting a request')
|
||||
.and.contain('must be a number between 100 and 999 (inclusive).')
|
||||
|
||||
@@ -1680,7 +1687,7 @@ describe('network stubbing', { retries: { runMode: 2, openMode: 0 } }, function
|
||||
})
|
||||
|
||||
it('can timeout in request handler', function (done) {
|
||||
cy.on('fail', (err) => {
|
||||
testFail((err) => {
|
||||
Cypress.config('defaultCommandTimeout', 5000)
|
||||
expect(err.message).to.match(/^A request callback passed to `cy.intercept\(\)` timed out after returning a Promise that took more than the `defaultCommandTimeout` of `50ms` to resolve\./)
|
||||
|
||||
@@ -2269,7 +2276,7 @@ describe('network stubbing', { retries: { runMode: 2, openMode: 0 } }, function
|
||||
|
||||
context('errors', function () {
|
||||
it('fails test if res.send is called twice in req handler', function (done) {
|
||||
cy.on('fail', (err) => {
|
||||
testFail((err) => {
|
||||
expect(err.message).to.contain('`res.send()` was called multiple times in a response handler, but the response can only be sent once.')
|
||||
done()
|
||||
})
|
||||
@@ -2284,7 +2291,7 @@ describe('network stubbing', { retries: { runMode: 2, openMode: 0 } }, function
|
||||
})
|
||||
|
||||
it('fails test if an exception is thrown in res handler', function (done) {
|
||||
cy.on('fail', (err2) => {
|
||||
testFail((err2) => {
|
||||
expect(err2.message).to.contain('A response handler threw an error while intercepting a response')
|
||||
.and.contain(err.message)
|
||||
|
||||
@@ -2305,7 +2312,7 @@ describe('network stubbing', { retries: { runMode: 2, openMode: 0 } }, function
|
||||
})
|
||||
|
||||
it('fails test if res.send is called with an invalid StaticResponse', function (done) {
|
||||
cy.on('fail', (err) => {
|
||||
testFail((err) => {
|
||||
expect(err.message).to.contain('A response handler threw an error while intercepting a response')
|
||||
.and.contain('must be a number between 100 and 999 (inclusive).')
|
||||
|
||||
@@ -2323,7 +2330,7 @@ describe('network stubbing', { retries: { runMode: 2, openMode: 0 } }, function
|
||||
})
|
||||
|
||||
it('fails test if network error occurs retrieving response and response is intercepted', function (done) {
|
||||
cy.on('fail', (err) => {
|
||||
testFail((err) => {
|
||||
expect(err.message)
|
||||
.to.contain('A callback was provided to intercept the upstream response, but a network error occurred while making the request:')
|
||||
.and.contain('Error: connect ECONNREFUSED 127.0.0.1:3333')
|
||||
@@ -2363,7 +2370,7 @@ describe('network stubbing', { retries: { runMode: 2, openMode: 0 } }, function
|
||||
})
|
||||
|
||||
it('can timeout in req.reply handler', function (done) {
|
||||
cy.on('fail', (err) => {
|
||||
testFail((err) => {
|
||||
Cypress.config('defaultCommandTimeout', 5000)
|
||||
expect(err.message).to.match(/^A response handler timed out after returning a Promise that took more than the `defaultCommandTimeout` of `50ms` to resolve\./)
|
||||
|
||||
@@ -2400,6 +2407,8 @@ describe('network stubbing', { retries: { runMode: 2, openMode: 0 } }, function
|
||||
})
|
||||
|
||||
context('waiting and aliasing', function () {
|
||||
const testFailWaiting = (cb) => testFail(cb, 'https://on.cypress.io/wait')
|
||||
|
||||
it('can wait on a single response using "alias"', function () {
|
||||
cy.intercept('/foo*', 'bar')
|
||||
.as('foo.bar')
|
||||
@@ -2410,7 +2419,7 @@ describe('network stubbing', { retries: { runMode: 2, openMode: 0 } }, function
|
||||
})
|
||||
|
||||
it('can timeout waiting on a single response using "alias"', function (done) {
|
||||
cy.on('fail', (err) => {
|
||||
testFailWaiting((err) => {
|
||||
expect(err.message).to.contain('No response ever occurred.')
|
||||
done()
|
||||
})
|
||||
@@ -2433,7 +2442,7 @@ describe('network stubbing', { retries: { runMode: 2, openMode: 0 } }, function
|
||||
})
|
||||
|
||||
it('can timeout waiting on a single response using "alias.response"', function (done) {
|
||||
cy.on('fail', (err) => {
|
||||
testFailWaiting((err) => {
|
||||
expect(err.message).to.contain('No response ever occurred.')
|
||||
done()
|
||||
})
|
||||
@@ -2456,7 +2465,7 @@ describe('network stubbing', { retries: { runMode: 2, openMode: 0 } }, function
|
||||
})
|
||||
|
||||
it('can timeout waiting on a single request using "alias.request"', function (done) {
|
||||
cy.on('fail', (err) => {
|
||||
testFailWaiting((err) => {
|
||||
expect(err.message).to.contain('No request ever occurred.')
|
||||
done()
|
||||
})
|
||||
@@ -2480,7 +2489,7 @@ describe('network stubbing', { retries: { runMode: 2, openMode: 0 } }, function
|
||||
})
|
||||
|
||||
it('can timeout incrementally waiting on responses', function (done) {
|
||||
cy.on('fail', (err) => {
|
||||
testFailWaiting((err) => {
|
||||
expect(err.message).to.contain('for the 1st response to the route')
|
||||
done()
|
||||
})
|
||||
@@ -2511,7 +2520,7 @@ describe('network stubbing', { retries: { runMode: 2, openMode: 0 } }, function
|
||||
})
|
||||
|
||||
it('can timeout incrementally waiting on requests', function (done) {
|
||||
cy.on('fail', (err) => {
|
||||
testFailWaiting((err) => {
|
||||
expect(err.message).to.contain('for the 2nd request to the route')
|
||||
done()
|
||||
})
|
||||
@@ -2697,7 +2706,7 @@ describe('network stubbing', { retries: { runMode: 2, openMode: 0 } }, function
|
||||
})
|
||||
|
||||
it('can time out on a dynamic alias', function (done) {
|
||||
cy.on('fail', (err) => {
|
||||
testFailWaiting((err) => {
|
||||
expect(err.message).to.contain('for the 1st request to the route')
|
||||
done()
|
||||
})
|
||||
@@ -2709,7 +2718,7 @@ describe('network stubbing', { retries: { runMode: 2, openMode: 0 } }, function
|
||||
})
|
||||
|
||||
it('dynamic aliases are fulfilled before route aliases', function (done) {
|
||||
cy.on('fail', (err) => {
|
||||
testFailWaiting((err) => {
|
||||
expect(err.message).to.contain('for the 1st request to the route: `fromAs`')
|
||||
done()
|
||||
})
|
||||
|
||||
@@ -142,7 +142,7 @@ describe('src/cy/commands/task', () => {
|
||||
expect(lastLog.get('error')).to.eq(err)
|
||||
expect(lastLog.get('state')).to.eq('failed')
|
||||
expect(err.message).to.eq('`cy.task()` must be passed a non-empty string as its 1st argument. You passed: ``.')
|
||||
expect(err.docsUrl).to.eq('https://on.cypress.io/task')
|
||||
expect(err.docsUrl).to.eq('https://on.cypress.io/api/task')
|
||||
|
||||
done()
|
||||
})
|
||||
@@ -158,7 +158,7 @@ describe('src/cy/commands/task', () => {
|
||||
expect(lastLog.get('error')).to.eq(err)
|
||||
expect(lastLog.get('state')).to.eq('failed')
|
||||
expect(err.message).to.eq('`cy.task()` must be passed a non-empty string as its 1st argument. You passed: `3`.')
|
||||
expect(err.docsUrl).to.eq('https://on.cypress.io/task')
|
||||
expect(err.docsUrl).to.eq('https://on.cypress.io/api/task')
|
||||
|
||||
done()
|
||||
})
|
||||
@@ -174,7 +174,7 @@ describe('src/cy/commands/task', () => {
|
||||
expect(lastLog.get('error')).to.eq(err)
|
||||
expect(lastLog.get('state')).to.eq('failed')
|
||||
expect(err.message).to.eq('`cy.task()` must be passed a non-empty string as its 1st argument. You passed: ``.')
|
||||
expect(err.docsUrl).to.eq('https://on.cypress.io/task')
|
||||
expect(err.docsUrl).to.eq('https://on.cypress.io/api/task')
|
||||
|
||||
done()
|
||||
})
|
||||
@@ -209,7 +209,7 @@ describe('src/cy/commands/task', () => {
|
||||
expect(lastLog.get('error')).to.eq(err)
|
||||
expect(lastLog.get('state')).to.eq('failed')
|
||||
|
||||
expect(err.message).to.eq(`\`cy.task('bar')\` failed with the following error:\n\nThe task 'bar' was not handled in the plugins file. The following tasks are registered: return:arg, arg:is:undefined, wait, create:long:file\n\nFix this in your plugins file here:\n${Cypress.config('pluginsFile')}\n\nhttps://on.cypress.io/api/task`)
|
||||
expect(err.message).to.eq(`\`cy.task('bar')\` failed with the following error:\n\nThe task 'bar' was not handled in the plugins file. The following tasks are registered: return:arg, arg:is:undefined, wait, create:long:file\n\nFix this in your plugins file here:\n${Cypress.config('pluginsFile')}`)
|
||||
|
||||
done()
|
||||
})
|
||||
@@ -227,7 +227,7 @@ describe('src/cy/commands/task', () => {
|
||||
expect(lastLog.get('error')).to.eq(err)
|
||||
expect(lastLog.get('state')).to.eq('failed')
|
||||
expect(err.message).to.eq('`cy.task(\'foo\')` timed out after waiting `50ms`.')
|
||||
expect(err.docsUrl).to.eq('https://on.cypress.io/task')
|
||||
expect(err.docsUrl).to.eq('https://on.cypress.io/api/task')
|
||||
|
||||
done()
|
||||
})
|
||||
@@ -260,7 +260,7 @@ describe('src/cy/commands/task', () => {
|
||||
|
||||
cy.on('fail', (err) => {
|
||||
expect(err.message).to.include('`cy.task(\'wait\')` timed out after waiting `100ms`.')
|
||||
expect(err.docsUrl).to.eq('https://on.cypress.io/task')
|
||||
expect(err.docsUrl).to.eq('https://on.cypress.io/api/task')
|
||||
|
||||
done()
|
||||
})
|
||||
@@ -271,7 +271,7 @@ describe('src/cy/commands/task', () => {
|
||||
it('can really time out', (done) => {
|
||||
cy.on('fail', (err) => {
|
||||
expect(err.message).to.include('`cy.task(\'wait\')` timed out after waiting `100ms`.')
|
||||
expect(err.docsUrl).to.eq('https://on.cypress.io/task')
|
||||
expect(err.docsUrl).to.eq('https://on.cypress.io/api/task')
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
@@ -923,6 +923,7 @@ module.exports = {
|
||||
},
|
||||
|
||||
net_stubbing: {
|
||||
docsUrl: 'https://on.cypress.io/intercept',
|
||||
invalid_static_response: ({ cmd, message, staticResponse }) => {
|
||||
return cyStripIndent(`\
|
||||
An invalid StaticResponse was supplied to \`${cmd}()\`. ${message}
|
||||
@@ -1571,6 +1572,7 @@ module.exports = {
|
||||
},
|
||||
|
||||
task: {
|
||||
docsUrl: 'https://on.cypress.io/api/task',
|
||||
known_error: stripIndent`
|
||||
${cmd('task', '\'{{task}}\'')} failed with the following error:
|
||||
|
||||
@@ -1581,18 +1583,15 @@ module.exports = {
|
||||
> {{error}}`,
|
||||
invalid_argument: {
|
||||
message: `${cmd('task')} must be passed a non-empty string as its 1st argument. You passed: \`{{task}}\`.`,
|
||||
docsUrl: 'https://on.cypress.io/task',
|
||||
},
|
||||
timed_out: {
|
||||
message: `${cmd('task', '\'{{task}}\'')} timed out after waiting \`{{timeout}}ms\`.`,
|
||||
docsUrl: 'https://on.cypress.io/task',
|
||||
},
|
||||
server_timed_out: {
|
||||
message: stripIndent`
|
||||
${cmd('task', '\'{{task}}\'')} timed out after waiting \`{{timeout}}ms\`.
|
||||
|
||||
{{error}}`,
|
||||
docsUrl: 'https://on.cypress.io/task',
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
@@ -279,6 +279,23 @@ const replaceErrMsgTokens = (errMessage, args) => {
|
||||
return $utils.normalizeNewLines(getMsg(args), 2)
|
||||
}
|
||||
|
||||
// recursively try for a default docsUrl
|
||||
const docsUrlByParents = (msgPath) => {
|
||||
msgPath = msgPath.split('.').slice(0, -1).join('.')
|
||||
|
||||
if (!msgPath) {
|
||||
return // reached root
|
||||
}
|
||||
|
||||
const obj = _.get($errorMessages, msgPath)
|
||||
|
||||
if (obj.hasOwnProperty('docsUrl')) {
|
||||
return obj.docsUrl
|
||||
}
|
||||
|
||||
return docsUrlByParents(msgPath)
|
||||
}
|
||||
|
||||
const errByPath = (msgPath, args) => {
|
||||
let msgValue = _.get($errorMessages, msgPath)
|
||||
|
||||
@@ -298,9 +315,11 @@ const errByPath = (msgPath, args) => {
|
||||
}
|
||||
}
|
||||
|
||||
const docsUrl = (msgObj.hasOwnProperty('docsUrl') && msgObj.docsUrl) || docsUrlByParents(msgPath)
|
||||
|
||||
return cypressErr({
|
||||
message: replaceErrMsgTokens(msgObj.message, args),
|
||||
docsUrl: msgObj.docsUrl ? replaceErrMsgTokens(msgObj.docsUrl, args) : undefined,
|
||||
docsUrl: docsUrl ? replaceErrMsgTokens(docsUrl, args) : undefined,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -103,6 +103,8 @@ https://on.cypress.io/api/task
|
||||
CypressError: \`cy.task('errors')\` failed with the following error:
|
||||
|
||||
> Error thrown in task handler
|
||||
|
||||
https://on.cypress.io/api/task
|
||||
[stack trace lines]
|
||||
|
||||
From Node.js Internals:
|
||||
|
||||
@@ -3,8 +3,6 @@ const Promise = require('bluebird')
|
||||
const debug = require('debug')('cypress:server:task')
|
||||
const plugins = require('./plugins')
|
||||
|
||||
const docsUrl = 'https://on.cypress.io/api/task'
|
||||
|
||||
const throwKnownError = function (message, props = {}) {
|
||||
const err = new Error(message)
|
||||
|
||||
@@ -16,13 +14,13 @@ module.exports = {
|
||||
run (pluginsFilePath, options) {
|
||||
debug('run task', options.task, 'with arg', options.arg)
|
||||
|
||||
const fileAndDocsUrl = `\n\nFix this in your plugins file here:\n${pluginsFilePath}\n\n${docsUrl}`
|
||||
const fileText = `\n\nFix this in your plugins file here:\n${pluginsFilePath}`
|
||||
|
||||
return Promise
|
||||
.try(() => {
|
||||
if (!plugins.has('task')) {
|
||||
debug('\'task\' event is not registered')
|
||||
throwKnownError(`The 'task' event has not been registered in the plugins file. You must register it before using cy.task()${fileAndDocsUrl}`)
|
||||
throwKnownError(`The 'task' event has not been registered in the plugins file. You must register it before using cy.task()${fileText}`)
|
||||
}
|
||||
|
||||
return plugins.execute('task', options.task, options.arg)
|
||||
@@ -31,7 +29,7 @@ module.exports = {
|
||||
debug('task is unhandled')
|
||||
|
||||
return plugins.execute('_get:task:keys').then((keys) => {
|
||||
return throwKnownError(`The task '${options.task}' was not handled in the plugins file. The following tasks are registered: ${keys.join(', ')}${fileAndDocsUrl}`)
|
||||
return throwKnownError(`The task '${options.task}' was not handled in the plugins file. The following tasks are registered: ${keys.join(', ')}${fileText}`)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -41,7 +39,7 @@ module.exports = {
|
||||
return plugins.execute('_get:task:body', options.task).then((body) => {
|
||||
const handler = body ? `\n\nThe task handler was:\n\n${body}` : ''
|
||||
|
||||
return throwKnownError(`The task '${options.task}' returned undefined. You must return a value, null, or a promise that resolves to a value or null to indicate that the task was handled.${handler}${fileAndDocsUrl}`)
|
||||
return throwKnownError(`The task '${options.task}' returned undefined. You must return a value, null, or a promise that resolves to a value or null to indicate that the task was handled.${handler}${fileText}`)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -53,7 +51,7 @@ module.exports = {
|
||||
debug(`timed out after ${options.timeout}ms`)
|
||||
|
||||
return plugins.execute('_get:task:body', options.task).then((body) => {
|
||||
const err = new Error(`The task handler was:\n\n${body}${fileAndDocsUrl}`)
|
||||
const err = new Error(`The task handler was:\n\n${body}${fileText}`)
|
||||
|
||||
err.timedOut = true
|
||||
throw err
|
||||
|
||||
@@ -28,7 +28,7 @@ describe('lib/task', () => {
|
||||
plugins.has.returns(false)
|
||||
|
||||
return task.run(this.pluginsFile, { timeout: 1000 }).catch((err) => {
|
||||
expect(err.message).to.equal(`The 'task' event has not been registered in the plugins file. You must register it before using cy.task()\n\nFix this in your plugins file here:\n${this.pluginsFile}\n\nhttps://on.cypress.io/api/task`)
|
||||
expect(err.message).to.equal(`The 'task' event has not been registered in the plugins file. You must register it before using cy.task()\n\nFix this in your plugins file here:\n${this.pluginsFile}`)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -37,7 +37,7 @@ describe('lib/task', () => {
|
||||
plugins.execute.withArgs('_get:task:keys').resolves(['foo', 'bar'])
|
||||
|
||||
return task.run(this.pluginsFile, { task: 'some:task', arg: 'some:arg', timeout: 1000 }).catch((err) => {
|
||||
expect(err.message).to.equal(`The task 'some:task' was not handled in the plugins file. The following tasks are registered: foo, bar\n\nFix this in your plugins file here:\n${this.pluginsFile}\n\nhttps://on.cypress.io/api/task`)
|
||||
expect(err.message).to.equal(`The task 'some:task' was not handled in the plugins file. The following tasks are registered: foo, bar\n\nFix this in your plugins file here:\n${this.pluginsFile}`)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -46,7 +46,7 @@ describe('lib/task', () => {
|
||||
plugins.execute.withArgs('_get:task:body').resolves('function () {}')
|
||||
|
||||
return task.run(this.pluginsFile, { task: 'some:task', arg: 'some:arg', timeout: 1000 }).catch((err) => {
|
||||
expect(err.message).to.equal(`The task 'some:task' returned undefined. You must return a value, null, or a promise that resolves to a value or null to indicate that the task was handled.\n\nThe task handler was:\n\nfunction () {}\n\nFix this in your plugins file here:\n${this.pluginsFile}\n\nhttps://on.cypress.io/api/task`)
|
||||
expect(err.message).to.equal(`The task 'some:task' returned undefined. You must return a value, null, or a promise that resolves to a value or null to indicate that the task was handled.\n\nThe task handler was:\n\nfunction () {}\n\nFix this in your plugins file here:\n${this.pluginsFile}`)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -55,7 +55,7 @@ describe('lib/task', () => {
|
||||
plugins.execute.withArgs('_get:task:body').resolves('')
|
||||
|
||||
return task.run(this.pluginsFile, { task: 'some:task', arg: 'some:arg', timeout: 1000 }).catch((err) => {
|
||||
expect(err.message).to.equal(`The task 'some:task' returned undefined. You must return a value, null, or a promise that resolves to a value or null to indicate that the task was handled.\n\nFix this in your plugins file here:\n${this.pluginsFile}\n\nhttps://on.cypress.io/api/task`)
|
||||
expect(err.message).to.equal(`The task 'some:task' returned undefined. You must return a value, null, or a promise that resolves to a value or null to indicate that the task was handled.\n\nFix this in your plugins file here:\n${this.pluginsFile}`)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -64,7 +64,7 @@ describe('lib/task', () => {
|
||||
plugins.execute.withArgs('_get:task:body').resolves('function () {}')
|
||||
|
||||
return task.run(this.pluginsFile, { task: 'some:task', arg: 'some:arg', timeout: 10 }).catch((err) => {
|
||||
expect(err.message).to.equal(`The task handler was:\n\nfunction () {}\n\nFix this in your plugins file here:\n${this.pluginsFile}\n\nhttps://on.cypress.io/api/task`)
|
||||
expect(err.message).to.equal(`The task handler was:\n\nfunction () {}\n\nFix this in your plugins file here:\n${this.pluginsFile}`)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user