thoughtbot / capybara-webkit

A Capybara driver for headless WebKit to test JavaScript web apps
https://thoughtbot.com/open-source
MIT License
1.97k stars 426 forks source link

Show application backtrace on 500 #226

Closed steve9001 closed 11 years ago

steve9001 commented 12 years ago

WIth rspec_rails integration tests, when you use the rack_test driver, an exception in the rails application during a request results in an informative stack trace for the failed scenario. We can't seem to make this happen with capybara-webkit.

As a partial workaround we remove "js: true" for features to work through 500 errors, and then turn it back on to fix failed assertions, but this is tedious and doesn't work when an ajax request causes an exception.

I'm trying to implement this functionality, starting in browser.rb, but I have no familiarity with capybara or capybara-webkit implementations, so any guidance would be great.

jferris commented 12 years ago

Part of the challenge here is that in most Javascript drivers (including capybara-webkit), the application runs in a separate thread, so errors never bubble up into the test runner thread. The server for the application is booted here: https://github.com/thoughtbot/capybara-webkit/blob/master/lib/capybara/driver/webkit.rb#L23

You could wrap the app in a piece of middleware that records or prints any exceptions raised during requests.

steve9001 commented 12 years ago

Here's an example such middleware: https://gist.github.com/1443408

JDutil commented 12 years ago

@steve9001 is your example used in your own apps at all or was it just a concept? I tried to plug it into an app I'm developing, and couldn't get it to work. I could really use a solution for dealing with this sort of issue also.

I also tried using mongrel for the server per a suggestion on stackoverflow http://stackoverflow.com/questions/4627928/get-rails-exceptions-to-show-using-capybara-and-selenium but that didn't end up working for me either.

I'd definitely prefer to get the middleware working though. Where do you place the diagnostic.rb file? I tried placing it under the config folder, under config/initializers, and also in a custom folder that gets autoloaded but in each case I had to make some tweaks to avoid unitialized constant error for MyApp::DiagnosticMiddleware. Then when i got things running with it required properly there is no output printed or diagnostic.txt file created. Ideally I'd like to change the diagnostic.txt file to be printed within the log or tmp folder too, which should be straight forward once the file is being generated.

steve9001 commented 12 years ago

The code to load the middleware is in config/application.rb. That file opens a module which is the name of your Rails app (the gist uses "MyApp" as an example). So put lines 2-7 of the application.rb gist at the bottom before you close your app module.

diagnostic.rb defines the middleware class within the same module namespace that is your application (you can re-open a module in Ruby). So you'll want to change line 1 so the module name is the same as in application.rb. Then put the file in lib/ which is added to the load path automatically, so you can require any file in there (e.g. line 4 of application.rb gist).

Finally, line 3 of diagnostic.rb sets the output file name, which is relative to Rails.root. If you want it in log/ you can change it to 'log/diagnostic.txt'.

I added diagnostic.txt to .gitignore in my app, and you can also have a line at the setup of your test suite to delete the existing file for less noise.

JDutil commented 12 years ago

Haha not sure why I didn't think to put it in the lib dir...

Actually turned out the reason it wasn't working for me was that I had resolved the specs exception so there was nothing to log... The spec was still failing though, and I didn't realize the exception was gone since I was still getting poor feedback on why the failure is occurring.

Thanks @steve9001 for your solution this is really helpful.

@jferris would it make sense to include this middleware with capybara-webkit or is this out of the scope of the project? If it's out of scope this issue could probably be closed unless you would like me to try putting together a pull request for it.

jferris commented 12 years ago

@jdutil I started a branch for this: reraise_exceptions.

My idea was to reraise exceptions from the server thread in the main thread. For some reason, that tests are hanging for me on that branch. If you figure out why, feel free to submit a pull request.

JDutil commented 12 years ago

I tried digging into this some and haven't been able to figure it out either. Will try again when I have more time, but Steve's solution is working well enough for now.

jferris commented 11 years ago

There's been some movement on this in capybara: https://github.com/jnicklas/capybara/pull/660

I'm going to close this, since my solution didn't really work out, and there's an official solution in the works.

jferris commented 10 years ago

In case anybody else finds this trying to figure out where this ended up, support was officially added for reraising errors in https://github.com/jnicklas/capybara/commit/6f145fb069da7e052378b76491cae074c28afc28.

DougPuchalski commented 10 years ago

@jferris Does this have to be enabled?

jferris commented 10 years ago

@aceofspades no, it doesn't, but there are a couple gotchas:

stevenspiel commented 8 years ago

Thank you @jferris. I was hitting webmock errors and couldn't find why it wasn't bubbling up.