Attila Györffy
Software Engineer

Debugging Ember Apps in End-to-End Tests

When your Capybara tests drive a full Ember app, failures are opaque. Here is how to load Ember Inspector into the Selenium-driven browser.

End-to-end testing an Ember app through Capybara sounds dead simple on paper: Selenium drives a real browser, the browser boots the Ember app, Capybara clicks buttons and checks things. Beautiful. Except the moment anything goes sideways, you're left staring at a blank browser window like a dog watching a magic trick. You have absolutely no idea what just happened inside the Ember runtime.

Now, the "proper" Ember testing approach dodges this whole mess by mocking the backend and running integration tests entirely in JavaScript-land. Lovely. Very tidy. Also completely useless if you want to know whether your Rails API, your Ember frontend, and the actual HTTP requests flying between them work together in the real world. If you need to prove that a critical business flow doesn't explode across that boundary, you need Capybara driving a real browser against a real server. No shortcuts. (For a proper deep dive into why this is such a pain, Jo Liss' presentation is excellent.)

Here's where it gets fun. When these end-to-end tests fail, the error messages are about as helpful as a fortune cookie. Capybara tells you "the expected text never appeared on the page." Cheers, mate. But why? Was the route wrong? Did a promise reject silently into the void? Is the model sitting there in some cursed half-state? You can't just pop open DevTools in a Selenium-driven browser like you would normally. The Ember app is a black box.

Loading Ember Inspector into Selenium

So here's the stupid-simple fix that took me way too long to figure out. Chrome has a --load-extension flag that lets you shove unpacked extensions into the browser Selenium launches. Clone and build Ember Inspector locally (the README tells you how), point the Chrome driver at it, and suddenly every test run gives you the full Inspector panel: routes, data, components, promises — all the stuff that was completely invisible five minutes ago. It's almost offensive how easy it is.

Chuck the built extension into spec/support/ember_inspector and wire it up:

# Ensure we load the Selenium Driver and the Chrome Driver helper.

group :test do
  gem 'selenium-webdriver'
  gem 'chromedriver-helper'
end
# place this in rails_helper.rb if you are using RSpec

Capybara.register_driver :selenium do |app|
  ember_inspector = File.expand_path('../support/ember-inspector', __FILE__)
  Capybara::Selenium::Driver.new(app,
    browser: :chrome,
    switches: [
      "--load-extension=#{ember_inspector}"
    ]
  )
end

That's it. That's the whole bloody thing. The custom Capybara driver tells Chrome to load the extension on launch, so every test session starts with the Inspector right there waiting for you. Slap a binding.pry in your test, switch over to the browser, open DevTools, and poke around your Ember app exactly the way you would during development. You know, like a normal human being.

Because I'm a generous soul, I've since wrapped this into the capybara-ember-inspector gem, so you don't even have to do the wiring yourself. You're welcome.

Notes

  • The Inspector also exists as a Firefox addon, if you're one of those people. Fair warning though, the Capybara setup is different, because of course it is.
  • You'll need chromedriver installed on your machine to drive Chrome via Selenium. On a Mac it's just brew install chromedriver. One whole command. You'll survive.
  • Use Chrome's --load-extension flag to inject Ember Inspector into Selenium-driven test runs
  • Pause with binding.pry, switch to the browser, and inspect Ember state during failures
  • The capybara-ember-inspector gem packages this setup into a single dependency