Debugging tips and tricks


#1

I’ve learned many tips and tricks from the Ember.js Community slack that have been lost to other users over the years. I know firsthand how valuable knowing the right trick here or there is to unblocking your problem. So let’s hear them!

Criteria and Guidelines:

  1. It should be generic, though posting specifics to QUnit or Mocha seem fine.
  2. It should be small and understandable.
  3. It should provide sufficient detail to help others use and implement it.

Even small things can help people, so don’t think you can’t share because it is “too basic” or “everybody knows that,” because someone out there might not and this could help them.

And a little bit of attribution goes a long way. If you found this out from someone in the Slack channel, give them a shout out.

You’re experience is valuable, so please feel free to share! :smile:

I think it fair that I start.


Get Settled State

Ember’s test harness wants to wait for async behavior to be completed before it advances the test. It does so by returning a wait promise from many of the test helpers (e.g. visit). The wait function is covered very well in this blogpost. To simplify the wait helper returns a promise that resolves when the following things have completed:

  • router transition
  • scheduled run loops
  • waiters
  • jQuery.ajax

And there is a neat way to kinda “cheat” to figure that out.

Take for instance you have a visit('/some-route'), which does return a wait promise, and you debugger; immediately afterward. You can call the following to get easy access to the state of the wait:

require('@ember/test-helpers').getSettledState()

Which will output something that looks like this:

Pretty excellent. You can use that information to narrow down where you should look if, for instance, your test was timing out.

Shout out to @TBieniek for showing me this in the #-testing channel this afternoon. And inspiring me to create this thread.

Happy (bug) hunting!


#2

Also, @chancancode had a great talk at EmberConf that covered many useful debugging tricks. Like black-boxing scripts and a fun walkthrough of how to use the Chrome devtools.

Check that out here:


#3

Awesome idea!

Just wanted to mention that the @ember/test-helpers API documentation says this about getSettledState:

Check various settledness metrics, and return an object with the following properties:

  • hasRunLoop - Checks if a run-loop has been started. If it has, this will be true otherwise it will be false.
  • hasPendingTimers - Checks if there are scheduled timers in the run-loop. These pending timers are primarily registered by Ember.run.schedule. If there are pending timers, this will be true, otherwise false.
  • hasPendingWaiters - Checks if any registered test waiters are still pending (e.g. the waiter returns true). If there are pending waiters, this will be true, otherwise false.
  • hasPendingRequests - Checks if there are pending AJAX requests (based on ajaxSend / ajaxComplete events triggered by jQuery.ajax). If there are pending requests, this will be true, otherwise false.
  • pendingRequestCount - The count of pending AJAX requests.

#4

2 simple tips come to mind:

ember testing server tip

From my experience working in a larger application, I find narrowing in on a single test or suite indispensible. I run something like ember test --filter 'my test name' --launch nothing. Why --launch nothing? I prefer opening the test server suite in my already open browser instead of ember-cli spawning a new browser for me. This starts the testing server so you can simply navigate to the testing URL. (probably localhost:7357)

3rd party library imports

If you import 3rd party libraries using app.import in your ember-cli-build.js, it can be useful to include development sources instead of the already minified assets. For example, say you are using the Highchart’s library. In your application’s ember-cli-build.js, you can include it like so:

app.import('node_modules/highcharts/highcharts.js');

This will include the already minified version. By editing the import path to include the uncompressed file highcharts.src.js, you get the developer friendly version of the file:

app.import('node_modules/highcharts/highcharts.src.js');

This will vary by 3rd party library, so digging through their installed directory within node_modules shows you what files are available.


#5

This is great! I love the ember test --filter --no-launch command. In fact I have an alias that places the filter at the end like: alias etsf='ember test --no-launch --filter= ' which let’s you invoke it with etsf jonathan.

Great tip!


#6

Better yet, include them all:

app.import({
     production:  './node_modules/highcharts/highcharts.js',
    development: './node_modules/highcharts/highcharts.src..js',
    test: './node_modules/highcharts/highcharts.src..js'
});

Repeat the app.import if you have imports (i.e. css, etc.)

Managing Dependencies


#7

Grand, thanks for the update! I was only able to get this working by not specifying the relative path:

app.import({
	production: 'node_modules/highcharts/highcharts.js',
	development: 'node_modules/highcharts/highcharts.src.js',
	test: 'node_modules/highcharts/highcharts.src.js'
});


#8

FYI, I’ve heard @rwjblue say on multiple occasions that minified assets should never be imported this way, even into the production, because ember-cli will try to re-minify them, which can cause issues. Ideally there would be an option within the import call to say “skip minification”, but I don’t think that exists yet.


#9

Huh, I did not know that. This sounds like a perfect opportunity to clarify and document the appropriate way to import assets on the primary ember-cli website. Could you try opening a PR with this information @Panman8201?