If a Cypress command fails (as it does in this case), the all is good, we show a good error and a good stack trace.
I can click on the file link (blue) or on the error link in the stack trace and go right to the location. Nice. Very happy.
I can find the error-stack.tsx code and copy the Error object it receives to show the stack and the files linked. Here is the error object JSON (I used a breakpoint and copy(err) to copy it)
{
"name": "AssertionError",
"message": "Timed out retrying: Expected to find element: `.new-todo`, but never found it.",
"stack": "AssertionError: Timed out retrying: Expected to find element: `.new-todo`, but never found it.\n at Context.eval (http://localhost:8888/__cypress/tests?p=cypress/integration/spec.js:103:8)",
"sourceMappedStack": "AssertionError: Timed out retrying: Expected to find element: `.new-todo`, but never found it.\n at Context.eval (webpack:///cypress/integration/spec.js:6:8)",
"parsedStack": [
{
"message": "AssertionError: Timed out retrying: Expected to find element: `.new-todo`, but never found it.",
"whitespace": ""
},
{
"function": "Context.eval",
"fileUrl": "http://localhost:8888/__cypress/tests?p=cypress/integration/spec.js",
"originalFile": "webpack:///cypress/integration/spec.js",
"relativeFile": "cypress/integration/spec.js",
"absoluteFile": "/Users/gleb/git/cypress-example-todomvc/cypress/integration/spec.js",
"line": 6,
"column": 8,
"whitespace": ""
}
],
"docsUrl": "",
"templateType": "",
"codeFrame": {
"line": 6,
"column": 8,
"originalFile": "cypress/integration/spec.js",
"relativeFile": "cypress/integration/spec.js",
"absoluteFile": "/Users/gleb/git/cypress-example-todomvc/cypress/integration/spec.js",
"frame": " 4 | it('adds todos', () => {\n 5 | cy.visit('/')\n> 6 | cy.get('.new-todo').type('write code{enter}').type('write tests{enter}')\n | ^\n 7 | cy.get('.todo-list li')\n 8 | .should('have.length', 2)\n 9 | .first()",
"language": "js"
}
}
Now, let's do something else. Instead of a Cypress command failing, let the application under test throw an error. For example in the file js/utils.js let's randomly add the following code line 9. Neither a nor b exists.
a = b
We run the test again and see the application error. good.
Let's open the error stack trace. Well now it makes little sense
We see blue underlined links to js/utils.js file - but clicking on them does nothing. Let's see the error object
{
"name": "ReferenceError",
"message": "The following error originated from your application code, not from Cypress.\n\n > b is not defined\n\nWhen Cypress detects uncaught errors originating from your application it will automatically fail the current test.\n\nThis behavior is configurable, and you can choose to turn this off by listening to the `uncaught:exception` event.",
"stack": "ReferenceError: The following error originated from your application code, not from Cypress.\n\n > b is not defined\n\nWhen Cypress detects uncaught errors originating from your application it will automatically fail the current test.\n\nThis behavior is configurable, and you can choose to turn this off by listening to the `uncaught:exception` event.\n at http://localhost:8888/js/utils.js:9:3\n at http://localhost:8888/js/utils.js:60:3\nFrom previous event:\n at run (http://localhost:8888/__cypress/runner/cypress_runner.js:169474:21)\n at $Cy.cy.<computed> [as visit] (http://localhost:8888/__cypress/runner/cypress_runner.js:169931:11)\n at Context.runnable.fn (http://localhost:8888/__cypress/runner/cypress_runner.js:170155:21)\n at callFn (http://localhost:8888/__cypress/runner/cypress_runner.js:104227:21)\n at Test.../driver/node_modules/mocha/lib/runnable.js.Runnable.run (http://localhost:8888/__cypress/runner/cypress_runner.js:104214:7)\n at http://localhost:8888/__cypress/runner/cypress_runner.js:175754:28\nFrom previous event:\n at Object.onRunnableRun (http://localhost:8888/__cypress/runner/cypress_runner.js:175742:17)\n at $Cypress.action (http://localhost:8888/__cypress/runner/cypress_runner.js:166291:28)\n at Test.Runnable.run (http://localhost:8888/__cypress/runner/cypress_runner.js:174128:13)\n at Runner.../driver/node_modules/mocha/lib/runner.js.Runner.runTest (http://localhost:8888/__cypress/runner/cypress_runner.js:104886:10)\n at http://localhost:8888/__cypress/runner/cypress_runner.js:105012:12\n at next (http://localhost:8888/__cypress/runner/cypress_runner.js:104795:14)\n at http://localhost:8888/__cypress/runner/cypress_runner.js:104805:7\n at next (http://localhost:8888/__cypress/runner/cypress_runner.js:104707:14)\n at http://localhost:8888/__cypress/runner/cypress_runner.js:104773:5\n at timeslice (http://localhost:8888/__cypress/runner/cypress_runner.js:98699:27)",
"sourceMappedStack": "ReferenceError: The following error originated from your application code, not from Cypress.\n\n > b is not defined\n\nWhen Cypress detects uncaught errors originating from your application it will automatically fail the current test.\n\nThis behavior is configurable, and you can choose to turn this off by listening to the `uncaught:exception` event.\n at <unknown> (http://localhost:8888/js/utils.js:9:4)\n at <unknown> (http://localhost:8888/js/utils.js:60:4)\nFrom previous event:\n at run (http://localhost:8888/__cypress/runner/cypress_runner.js:169474:22)\n at $Cy.cy.<computed> [as visit] (http://localhost:8888/__cypress/runner/cypress_runner.js:169931:12)\n at Context.runnable.fn (http://localhost:8888/__cypress/runner/cypress_runner.js:170155:22)\n at callFn (http://localhost:8888/__cypress/runner/cypress_runner.js:104227:22)\n at Test.../driver/node_modules/mocha/lib/runnable.js.Runnable.run (http://localhost:8888/__cypress/runner/cypress_runner.js:104214:8)\n at <unknown> (http://localhost:8888/__cypress/runner/cypress_runner.js:175754:29)\nFrom previous event:\n at Object.onRunnableRun (http://localhost:8888/__cypress/runner/cypress_runner.js:175742:18)\n at $Cypress.action (http://localhost:8888/__cypress/runner/cypress_runner.js:166291:29)\n at Test.Runnable.run (http://localhost:8888/__cypress/runner/cypress_runner.js:174128:14)\n at Runner.../driver/node_modules/mocha/lib/runner.js.Runner.runTest (http://localhost:8888/__cypress/runner/cypress_runner.js:104886:11)\n at <unknown> (http://localhost:8888/__cypress/runner/cypress_runner.js:105012:13)\n at next (http://localhost:8888/__cypress/runner/cypress_runner.js:104795:15)\n at <unknown> (http://localhost:8888/__cypress/runner/cypress_runner.js:104805:8)\n at next (http://localhost:8888/__cypress/runner/cypress_runner.js:104707:15)\n at <unknown> (http://localhost:8888/__cypress/runner/cypress_runner.js:104773:6)\n at timeslice (http://localhost:8888/__cypress/runner/cypress_runner.js:98699:28)",
"parsedStack": [
{
"message": "ReferenceError: The following error originated from your application code, not from Cypress.",
"whitespace": ""
},
{
"message": "",
"whitespace": ""
},
{
"message": " > b is not defined",
"whitespace": ""
},
{
"message": "",
"whitespace": ""
},
{
"message": "When Cypress detects uncaught errors originating from your application it will automatically fail the current test.",
"whitespace": ""
},
{
"message": "",
"whitespace": ""
},
{
"message": "This behavior is configurable, and you can choose to turn this off by listening to the `uncaught:exception` event.",
"whitespace": ""
},
{
"function": "<unknown>",
"fileUrl": "http://localhost:8888/js/utils.js",
"originalFile": "http://localhost:8888/js/utils.js",
"relativeFile": "localhost:8888/js/utils.js",
"absoluteFile": "/Users/gleb/git/cypress-example-todomvc/localhost:8888/js/utils.js",
"line": 9,
"column": 4,
"whitespace": ""
},
{
"function": "<unknown>",
"fileUrl": "http://localhost:8888/js/utils.js",
"originalFile": "http://localhost:8888/js/utils.js",
"relativeFile": "localhost:8888/js/utils.js",
"absoluteFile": "/Users/gleb/git/cypress-example-todomvc/localhost:8888/js/utils.js",
"line": 60,
"column": 4,
"whitespace": ""
},
{
"message": "From previous event:",
"whitespace": ""
},
{
"function": "run",
"fileUrl": "http://localhost:8888/__cypress/runner/cypress_runner.js",
"originalFile": "http://localhost:8888/__cypress/runner/cypress_runner.js",
"relativeFile": "localhost:8888/__cypress/runner/cypress_runner.js",
"absoluteFile": "/Users/gleb/git/cypress-example-todomvc/localhost:8888/__cypress/runner/cypress_runner.js",
"line": 169474,
"column": 22,
"whitespace": ""
},
{
"function": "$Cy.cy.<computed> [as visit]",
"fileUrl": "http://localhost:8888/__cypress/runner/cypress_runner.js",
"originalFile": "http://localhost:8888/__cypress/runner/cypress_runner.js",
"relativeFile": "localhost:8888/__cypress/runner/cypress_runner.js",
"absoluteFile": "/Users/gleb/git/cypress-example-todomvc/localhost:8888/__cypress/runner/cypress_runner.js",
"line": 169931,
"column": 12,
"whitespace": ""
},
{
"function": "Context.runnable.fn",
"fileUrl": "http://localhost:8888/__cypress/runner/cypress_runner.js",
"originalFile": "http://localhost:8888/__cypress/runner/cypress_runner.js",
"relativeFile": "localhost:8888/__cypress/runner/cypress_runner.js",
"absoluteFile": "/Users/gleb/git/cypress-example-todomvc/localhost:8888/__cypress/runner/cypress_runner.js",
"line": 170155,
"column": 22,
"whitespace": ""
},
{
"function": "callFn",
"fileUrl": "http://localhost:8888/__cypress/runner/cypress_runner.js",
"originalFile": "http://localhost:8888/__cypress/runner/cypress_runner.js",
"relativeFile": "localhost:8888/__cypress/runner/cypress_runner.js",
"absoluteFile": "/Users/gleb/git/cypress-example-todomvc/localhost:8888/__cypress/runner/cypress_runner.js",
"line": 104227,
"column": 22,
"whitespace": ""
},
{
"function": "Test.../driver/node_modules/mocha/lib/runnable.js.Runnable.run",
"fileUrl": "http://localhost:8888/__cypress/runner/cypress_runner.js",
"originalFile": "http://localhost:8888/__cypress/runner/cypress_runner.js",
"relativeFile": "localhost:8888/__cypress/runner/cypress_runner.js",
"absoluteFile": "/Users/gleb/git/cypress-example-todomvc/localhost:8888/__cypress/runner/cypress_runner.js",
"line": 104214,
"column": 8,
"whitespace": ""
},
{
"function": "<unknown>",
"fileUrl": "http://localhost:8888/__cypress/runner/cypress_runner.js",
"originalFile": "http://localhost:8888/__cypress/runner/cypress_runner.js",
"relativeFile": "localhost:8888/__cypress/runner/cypress_runner.js",
"absoluteFile": "/Users/gleb/git/cypress-example-todomvc/localhost:8888/__cypress/runner/cypress_runner.js",
"line": 175754,
"column": 29,
"whitespace": ""
},
{
"message": "From previous event:",
"whitespace": ""
},
{
"function": "Object.onRunnableRun",
"fileUrl": "http://localhost:8888/__cypress/runner/cypress_runner.js",
"originalFile": "http://localhost:8888/__cypress/runner/cypress_runner.js",
"relativeFile": "localhost:8888/__cypress/runner/cypress_runner.js",
"absoluteFile": "/Users/gleb/git/cypress-example-todomvc/localhost:8888/__cypress/runner/cypress_runner.js",
"line": 175742,
"column": 18,
"whitespace": ""
},
{
"function": "$Cypress.action",
"fileUrl": "http://localhost:8888/__cypress/runner/cypress_runner.js",
"originalFile": "http://localhost:8888/__cypress/runner/cypress_runner.js",
"relativeFile": "localhost:8888/__cypress/runner/cypress_runner.js",
"absoluteFile": "/Users/gleb/git/cypress-example-todomvc/localhost:8888/__cypress/runner/cypress_runner.js",
"line": 166291,
"column": 29,
"whitespace": ""
},
{
"function": "Test.Runnable.run",
"fileUrl": "http://localhost:8888/__cypress/runner/cypress_runner.js",
"originalFile": "http://localhost:8888/__cypress/runner/cypress_runner.js",
"relativeFile": "localhost:8888/__cypress/runner/cypress_runner.js",
"absoluteFile": "/Users/gleb/git/cypress-example-todomvc/localhost:8888/__cypress/runner/cypress_runner.js",
"line": 174128,
"column": 14,
"whitespace": ""
},
{
"function": "Runner.../driver/node_modules/mocha/lib/runner.js.Runner.runTest",
"fileUrl": "http://localhost:8888/__cypress/runner/cypress_runner.js",
"originalFile": "http://localhost:8888/__cypress/runner/cypress_runner.js",
"relativeFile": "localhost:8888/__cypress/runner/cypress_runner.js",
"absoluteFile": "/Users/gleb/git/cypress-example-todomvc/localhost:8888/__cypress/runner/cypress_runner.js",
"line": 104886,
"column": 11,
"whitespace": ""
},
{
"function": "<unknown>",
"fileUrl": "http://localhost:8888/__cypress/runner/cypress_runner.js",
"originalFile": "http://localhost:8888/__cypress/runner/cypress_runner.js",
"relativeFile": "localhost:8888/__cypress/runner/cypress_runner.js",
"absoluteFile": "/Users/gleb/git/cypress-example-todomvc/localhost:8888/__cypress/runner/cypress_runner.js",
"line": 105012,
"column": 13,
"whitespace": ""
},
{
"function": "next",
"fileUrl": "http://localhost:8888/__cypress/runner/cypress_runner.js",
"originalFile": "http://localhost:8888/__cypress/runner/cypress_runner.js",
"relativeFile": "localhost:8888/__cypress/runner/cypress_runner.js",
"absoluteFile": "/Users/gleb/git/cypress-example-todomvc/localhost:8888/__cypress/runner/cypress_runner.js",
"line": 104795,
"column": 15,
"whitespace": ""
},
{
"function": "<unknown>",
"fileUrl": "http://localhost:8888/__cypress/runner/cypress_runner.js",
"originalFile": "http://localhost:8888/__cypress/runner/cypress_runner.js",
"relativeFile": "localhost:8888/__cypress/runner/cypress_runner.js",
"absoluteFile": "/Users/gleb/git/cypress-example-todomvc/localhost:8888/__cypress/runner/cypress_runner.js",
"line": 104805,
"column": 8,
"whitespace": ""
},
{
"function": "next",
"fileUrl": "http://localhost:8888/__cypress/runner/cypress_runner.js",
"originalFile": "http://localhost:8888/__cypress/runner/cypress_runner.js",
"relativeFile": "localhost:8888/__cypress/runner/cypress_runner.js",
"absoluteFile": "/Users/gleb/git/cypress-example-todomvc/localhost:8888/__cypress/runner/cypress_runner.js",
"line": 104707,
"column": 15,
"whitespace": ""
},
{
"function": "<unknown>",
"fileUrl": "http://localhost:8888/__cypress/runner/cypress_runner.js",
"originalFile": "http://localhost:8888/__cypress/runner/cypress_runner.js",
"relativeFile": "localhost:8888/__cypress/runner/cypress_runner.js",
"absoluteFile": "/Users/gleb/git/cypress-example-todomvc/localhost:8888/__cypress/runner/cypress_runner.js",
"line": 104773,
"column": 6,
"whitespace": ""
},
{
"function": "timeslice",
"fileUrl": "http://localhost:8888/__cypress/runner/cypress_runner.js",
"originalFile": "http://localhost:8888/__cypress/runner/cypress_runner.js",
"relativeFile": "localhost:8888/__cypress/runner/cypress_runner.js",
"absoluteFile": "/Users/gleb/git/cypress-example-todomvc/localhost:8888/__cypress/runner/cypress_runner.js",
"line": 98699,
"column": 28,
"whitespace": ""
}
],
"docsUrl": [
"https://on.cypress.io/uncaught-exception-from-application"
],
"templateType": ""
}
The code for this is done in cypress-io/cypress#9081, but has yet to be released.
We'll update this issue and reference the changelog when it's released.
Cypress v5.5.0
Reproduction case in https://github.com/cypress-io/cypress-example-todomvc/tree/stack-problem file
cypress/integration/spec.js
Starts local server, opens Cypress
First, the good case
If a Cypress command fails (as it does in this case), the all is good, we show a good error and a good stack trace.
I can click on the file link (blue) or on the error link in the stack trace and go right to the location. Nice. Very happy.
I can find the
error-stack.tsx
code and copy the Error object it receives to show the stack and the files linked. Here is the error object JSON (I used a breakpoint andcopy(err)
to copy it)Nice, then
fileUrl
was "http://localhost:8888/__cypress/tests?p=cypress/integration/spec.js" and it was correctly mapped back to the source file on disk "absoluteFile": "/Users/gleb/git/cypress-example-todomvc/cypress/integration/spec.js". Super.Second - the wrong case
Now, let's do something else. Instead of a Cypress command failing, let the application under test throw an error. For example in the file
js/utils.js
let's randomly add the following code line 9. Neithera
norb
exists.We run the test again and see the application error. good.
Let's open the error stack trace. Well now it makes little sense
We see blue underlined links to
js/utils.js
file - but clicking on them does nothing. Let's see the error objectNotice the parsed stack line
Hmm, the "absoluteFile" value makes no sense here and should not be here.
Proposal
Stricter filter out stack lines where the file does not exist or cannot be found.
The text was updated successfully, but these errors were encountered: