Skip to content

Commit

Permalink
driver: provide additional context when uncaught errors originate eit…
Browse files Browse the repository at this point in the history
…her from spec code or app code (#999)

* driver: provide additional context when uncaught errors originate either from spec code or app code

* server: fix failing snapshots for uncaught exceptions in spec + test code
  • Loading branch information
brian-mann authored Dec 4, 2017
1 parent 875e378 commit a25b828
Show file tree
Hide file tree
Showing 10 changed files with 104 additions and 14 deletions.
10 changes: 9 additions & 1 deletion packages/driver/src/cy/errors.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ create = (state, config, log) ->
obj
})

createUncaughtException = (msg, source, lineno, colno, err) ->
createUncaughtException = (type, args) ->
[msg, source, lineno, colno, err] = args

current = state("current")

## reset the msg on a cross origin script error
Expand All @@ -43,6 +45,12 @@ create = (state, config, log) ->

err.name = "Uncaught " + err.name

suffixMsg = switch type
when "app" then "uncaught.fromApp"
when "spec" then "uncaught.fromSpec"

err = $utils.appendErrMsg(err, $utils.errMessageByPath(suffixMsg))

err.onFail = ->
if l = current and current.getLastLog()
l.error(err)
Expand Down
4 changes: 2 additions & 2 deletions packages/driver/src/cypress/cy.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -871,7 +871,7 @@ create = (specWindow, Cypress, Cookies, state, config, log) ->

onSpecWindowUncaughtException: ->
## create the special uncaught exception err
err = errors.createUncaughtException.apply(null, arguments)
err = errors.createUncaughtException("spec", arguments)

if runnable = state("runnable")
## we're using an explicit done callback here
Expand All @@ -891,7 +891,7 @@ create = (specWindow, Cypress, Cookies, state, config, log) ->
return if not runnable

## create the special uncaught exception err
err = errors.createUncaughtException.apply(null, arguments)
err = errors.createUncaughtException("app", arguments)

results = Cypress.action("app:uncaught:exception", err, runnable)

Expand Down
16 changes: 16 additions & 0 deletions packages/driver/src/cypress/error_messages.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -788,6 +788,22 @@ module.exports = {

msg + if source and lineno then " (#{source}:#{lineno})" else ""

fromApp: """
This error originated from *your* application code, not from Cypress.
When Cypress detects uncaught errors originating from your application it will automatically fail the current test.
This behavior is configurable, and you can choose to turn this off by listening to the 'uncaught:exception' event.
https://on.cypress.io/uncaught-exception-from-application
"""

fromSpec: """
This error originated from *your* test code, not from Cypress.
When Cypress detects uncaught errors originating from your test code it will automatically fail the current test.
"""

viewport:
bad_args: "#{cmd('viewport')} can only accept a string preset or a width and height as numbers."
dimensions_out_of_range: "#{cmd('viewport')} width and height must be between 200px and 3000px."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@ describe "uncaught errors", ->
r = cy.state("runnable")

cy.on "uncaught:exception", (err, runnable) ->
expect(err.name).to.eq("Uncaught ReferenceError")
expect(err.message).to.include("foo is not defined")
expect(err.message).to.include("This error originated from *your* application code, not from Cypress.")
expect(err.message).to.include("https://on.cypress.io/uncaught-exception-from-application")
expect(runnable is r).to.be.true

return false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,14 @@ Started video recording: /foo/bar/.projects/e2e/cypress/videos/abc123.mp4
1) s1b "before each" hook for "t2b":
Uncaught ReferenceError: foo is not defined

This error originated from *your* application code, not from Cypress.

When Cypress detects uncaught errors originating from your application it will automatically fail the current test.

This behavior is configurable, and you can choose to turn this off by listening to the 'uncaught:exception' event.

https://on.cypress.io/uncaught-exception-from-application

Because this error occurred during a 'before each' hook we are skipping the remaining tests in the current suite: 's1b'
at stack trace line

Expand Down Expand Up @@ -134,6 +142,14 @@ Started video recording: /foo/bar/.projects/e2e/cypress/videos/abc123.mp4
1) "before each" hook for "t1c":
Uncaught ReferenceError: foo is not defined

This error originated from *your* application code, not from Cypress.

When Cypress detects uncaught errors originating from your application it will automatically fail the current test.

This behavior is configurable, and you can choose to turn this off by listening to the 'uncaught:exception' event.

https://on.cypress.io/uncaught-exception-from-application

Because this error occurred during a 'before each' hook we are skipping all of the remaining tests.
at stack trace line

Expand Down Expand Up @@ -187,6 +203,14 @@ Started video recording: /foo/bar/.projects/e2e/cypress/videos/abc123.mp4
1) uncaught hook error should continue to fire all mocha events s1 "before each" hook for "does not run":
Uncaught ReferenceError: foo is not defined

This error originated from *your* application code, not from Cypress.

When Cypress detects uncaught errors originating from your application it will automatically fail the current test.

This behavior is configurable, and you can choose to turn this off by listening to the 'uncaught:exception' event.

https://on.cypress.io/uncaught-exception-from-application

Because this error occurred during a 'before each' hook we are skipping the remaining tests in the current suite: 's1'
at stack trace line

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
exports['e2e commands outside of test passes 1'] = `
exports['e2e commands outside of test fails 1'] = `
Started video recording: /foo/bar/.projects/e2e/cypress/videos/abc123.mp4

(Tests Starting)
Expand All @@ -20,6 +20,10 @@ Check your test file for errors.

https://on.cypress.io/cannot-execute-commands-outside-test

This error originated from *your* test code, not from Cypress.

When Cypress detects uncaught errors originating from your test code it will automatically fail the current test.

Cypress could not associate this error to any specific test.

We dynamically generated a new test to display this failure.
Expand Down Expand Up @@ -60,4 +64,3 @@ We dynamically generated a new test to display this failure.
(All Done)

`

24 changes: 24 additions & 0 deletions packages/server/__snapshots__/js_error_handling_spec.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@ Started video recording: /foo/bar/.projects/e2e/cypress/videos/abc123.mp4

1) s1 without an afterEach hook t1:
Uncaught ReferenceError: foo is not defined

This error originated from *your* application code, not from Cypress.

When Cypress detects uncaught errors originating from your application it will automatically fail the current test.

This behavior is configurable, and you can choose to turn this off by listening to the 'uncaught:exception' event.

https://on.cypress.io/uncaught-exception-from-application
at stack trace line
at stack trace line
at stack trace line
Expand All @@ -36,6 +44,14 @@ Started video recording: /foo/bar/.projects/e2e/cypress/videos/abc123.mp4

3) s1 with an afterEach hook t4:
Uncaught ReferenceError: foo is not defined

This error originated from *your* application code, not from Cypress.

When Cypress detects uncaught errors originating from your application it will automatically fail the current test.

This behavior is configurable, and you can choose to turn this off by listening to the 'uncaught:exception' event.

https://on.cypress.io/uncaught-exception-from-application
at stack trace line
at stack trace line
at stack trace line
Expand All @@ -56,6 +72,14 @@ Check your Developer Tools Console for the actual error - it should be printed t
It's possible to enable debugging these scripts by adding the 'crossorigin' attribute and setting a CORS header.
https://on.cypress.io/cross-origin-script-error
This error originated from *your* application code, not from Cypress.
When Cypress detects uncaught errors originating from your application it will automatically fail the current test.
This behavior is configurable, and you can choose to turn this off by listening to the 'uncaught:exception' event.
https://on.cypress.io/uncaught-exception-from-application
at stack trace line
at stack trace line
at stack trace line
Expand Down
16 changes: 16 additions & 0 deletions packages/server/__snapshots__/uncaught_spec_errors_spec.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ Started video recording: /foo/bar/.projects/e2e/cypress/videos/abc123.mp4
1) An uncaught error was detected outside of a test:
Uncaught ReferenceError: foo is not defined

This error originated from *your* test code, not from Cypress.

When Cypress detects uncaught errors originating from your test code it will automatically fail the current test.

Cypress could not associate this error to any specific test.

We dynamically generated a new test to display this failure.
Expand Down Expand Up @@ -64,6 +68,10 @@ Started video recording: /foo/bar/.projects/e2e/cypress/videos/abc123.mp4
1) An uncaught error was detected outside of a test:
Uncaught ReferenceError: foo is not defined

This error originated from *your* test code, not from Cypress.

When Cypress detects uncaught errors originating from your test code it will automatically fail the current test.

Cypress could not associate this error to any specific test.

We dynamically generated a new test to display this failure.
Expand Down Expand Up @@ -118,6 +126,10 @@ Started video recording: /foo/bar/.projects/e2e/cypress/videos/abc123.mp4

1) foo bar:
Uncaught ReferenceError: foo is not defined

This error originated from *your* test code, not from Cypress.

When Cypress detects uncaught errors originating from your test code it will automatically fail the current test.
at stack trace line


Expand Down Expand Up @@ -169,6 +181,10 @@ Started video recording: /foo/bar/.projects/e2e/cypress/videos/abc123.mp4
1) foo "before all" hook for "does not run":
Uncaught ReferenceError: foo is not defined

This error originated from *your* test code, not from Cypress.

When Cypress detects uncaught errors originating from your test code it will automatically fail the current test.

Because this error occurred during a 'before all' hook we are skipping the remaining tests in the current suite: 'foo'
at stack trace line

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ Started video recording: /foo/bar/.projects/uncaught-support-file/cypress/videos
1) An uncaught error was detected outside of a test:
Uncaught Error: bar

This error originated from *your* test code, not from Cypress.

When Cypress detects uncaught errors originating from your test code it will automatically fail the current test.

Cypress could not associate this error to any specific test.

We dynamically generated a new test to display this failure.
Expand Down
10 changes: 1 addition & 9 deletions packages/server/test/e2e/commands_outside_of_test_spec.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,7 @@ e2e = require("../support/helpers/e2e")
describe "e2e commands outside of test", ->
e2e.setup()

it "passes", ->
## TODO: currently this doesn't actually cause mocha
## to fail and therefore our exit code is 0
## because this error is thrown in the console
## and cannot be properly tied to a test
## ---
## perhaps we should dynamically generate a test to
## associate it for stdout? how else would a user know
## whats going on?
it "fails", ->
e2e.exec(@, {
spec: "commands_outside_of_test_spec.coffee"
snapshot: true
Expand Down

0 comments on commit a25b828

Please sign in to comment.