Debugging Ember.js QUnit Tests in PhantomJS

Sometimes you can run into issues where QUnit tests are passing just fine in Chrome, but failing in PhantomJS. Or perhaps a single test is failing and you just want to debug it in PhantomJS instead of firing up Chrome. Whatever the case, it's handy to be able to debug an issue when a test is running in PhantomJS.

Before I jump in, here's my current environment for the record:

ember-cli: 2.6.1  
ember: 2.6.0  
ember-qunit: 0.4.20  
qunit: 1.23.1

It can be tricky because you're basically trying to debug something you cannot see. What you can do, however, is stop execution at a certain point - similar to debugger - and inspect the application state from there.

Setting PhantomJS Debug Port

First you need to add the PhantomJS debug port to your testem.js file.

"phantomjs_debug_port": 9000

You can choose whatever port you want, but in this example it's 9000. This is basically specifying the port where you can navigate to localhost:9000 and you'll be able to see a Chrome devtools style page where you can poke and prod your code.

Stopping Execution

The second part is specifying where you want to halt execution. To do this just add these lines of code:

QUnit.config.testTimeout = 600000;  
return application.testHelpers.pauseTest();  

The first line sets a 10 minute timeout, so that you can inspect your app without the test timing out on you. The second line uses the pauseTest helper from the ember test helpers, which basically creates a promise that never resolves. This is basically the debugger equivalent for PhantomJS.

Here's an example test.

test('Hello world displays', function(assert) {  
  assert.expect(1);
  visit('/hello_world');
  andThen(function() {
    QUnit.config.testTimeout = 600000;
    return application.testHelpers.pauseTest();
    let $header = find('.header');
    assert.strictEqual($header.text().trim(), 'Hello World');
  });
});

Inspecting

Now when you navigate to http://localhost:9000, you should see something like this:

image

When clicking on your test, you should arrive to a page like this where you can inspect application state:

image

Caveats

The pauseTest() helper only works with ember acceptance tests. If you want to debug an integration test you can use assert.async(), which is similar to pauseTest().

The async() method comes free with QUnit and works in both acceptance and integration tests.

Resources