We're on the cusp of 2022 and most software is now written in JavaScript, but it is still virtually impossible to fail integration tests on a JavaScript error and get a useful stack trace from the browser.
This gist includes my description of the problem and sample code from my attempts to solve it.
- Integration test should fail (preferabbly immediately) on any uncaught JavaScript error (
window.onerror
,unhandledrejection
, etc) - The stack trace should use source maps and be close to what browsers show in DevTools
- Ruby on Rails system tests
- which uses Capybara
- driven by Selenium WebDriver using headless chrome
assert_no_console_messages
defined below asserts that there is nothing in the browser console after each test. This is insufficient because:- It only includes the error message and not the stack trace
- It's only checked at the end of the tests (or manually by calling the assertion after each step), so it's very difficult to figure out which step in the test triggered the error or where in the source code it is coming from.
- A custom error tracker in the app to capture errors (see
errors.js
), which can be accessed from the tests.assert_no_js_errors
defined below is an improvement on checking for console messages, but is still insufficient because:error.stack
(in all browsers) does not use sourcemaps, so the stack trace is virtual useless in a modern app- Errors are not persisted, so
assert_no_js_errors
must be called on every page after asynchronous actions, but before navigating to a different page (calling the assertion after one of the other Capybara assertions likeassert_content
helps becasue it will wait until the expected behavior is done. Errors could be sent to the server or persisted in localStorage, which would be an improvement. - Assertions are still only performed manually or at the end of the test instead of when the error occurs
- stacktrace.js looks promising for improving the stack traces. I tried TraceKit, but it is very outdated and does not support source maps.
Any other ideas?