Friday, August 29, 2014

Testing Custom Polymer Elements with Polymer-Test-Tools


I discovered polymer-test-tools last night, but could not quite get them working. While exploring, I began to suspect that they were meant more to support the Polymer project's infrastructure than to help “regular” programmers build elements. Even so, I would like to get them working with my Polymer element, if only to see what polymer-test-tools can teach me about my own testing approach.

I left off last night with a strange SSL / socket.io error. It seemed like an old node.js, but it turns out that I have a relatively recent version of node installed. And, in fact, I no longer see the error tonight. I swear that I have done nothing that could possibly have fixed this, except… it is fixed. Rather than question fortune, I say a prayer of thanks to the gods of the chain and quickly move on before they change their mind.

Not all is well just yet, but I am quite familiar with the next errors thanks to earlier experiments testing Polymer with mocha and chai. First up the before-each failure on start-up:
$ karma start
INFO [karma]: Karma v0.12.23 server started at http://localhost:9876/
INFO [launcher]: Starting browser Chrome
Chrome 37.0.2062 (Linux)  "before each" hook FAILED
        Error: timeout of 2000ms exceeded
Chrome 37.0.2062 (Linux) SLOW 2.003 secs:  "before each" hook
Chrome 37.0.2062 (Linux): Executed 1 of 2 (1 FAILED) ERROR (2.037 secs / 2.003 secs)
I fix this with the same solution from the last time—test setup that relies on Polymer.whenReady() instead of the too-quick polymer-ready event:
// Delay Jasmine specs until Polymer is ready
var POLYMER_READY = false;
beforeEach(function(done) {
  function waitForPolymer() {
    if (Polymer) {
      Polymer.whenReady(done);
      return;
    }
    setTimeout(waitForPolymer, 1000);
  }
  waitForPolymer();

  if (POLYMER_READY) done();
});
I had expected that to be the last of my woes, but I still have another sadly familiar error message to fix:
$ karma start
INFO [karma]: Karma v0.12.23 server started at http://localhost:9876/
INFO [launcher]: Starting browser Chrome
INFO [Chrome 37.0.2062 (Linux)]: Connected on socket sgWf2bLuHEiLYy7BxgN0 with id 56442994
Chrome 37.0.2062 (Linux)  element content displays click events FAILED
        ReferenceError: expect is not defined
            at Context.<anonymous> (/home/chris/repos/polymer-book/book/code-js/parent_events/test/ClickSinkSpec.js:23:7)
I ran into this same error when I setup mocha on my own, but am surprised to see it with polymer-test-tools. The problem is that the chai framework is not loaded. I am surprised by this because the chai framework is included directly in the polymer-test-tools source. Why include it in the source if it is not going to be enabled by default? I can only guess that the answer has to do with using polymer-test-tools in the Polymer framework code rather than testing custom built Polymer elements.

Whatever the reason, the solution remains the same—I have to alter my karma.conf.js file to include chai in addition to mocha (which polymer-test-tools does include by default):
module.exports = function(config) {
  var common = require('./bower_components/polymer-test-tools/karma-common.conf.js');

  config.set(common.mixin_common_opts(config, {
    frameworks: ['mocha', 'chai'],
    // ...
  }));
};
Only this time, my problem is still not resolved. Since I overrode polymer-test-tools' plugins setting last night, I also have to add karma-chai to it here:
module.exports = function(config) {
  var common = require('./bower_components/polymer-test-tools/karma-common.conf.js');

  config.set(common.mixin_common_opts(config, {
    frameworks: ['mocha', 'chai'],

    plugins: [
      'karma-mocha',
      'karma-chai',
      'karma-chrome-launcher',
      'karma-script-launcher'
    ],
    // ...
  }));
};
After that, all that remains is to change Jasmine's toEqual() and toContain() to chai's to.equal() and to.contain():
  describe('element content', function(){
    beforeEach(function(done){
      document.body.click();
      setTimeout(done, 0); // One event loop for Polymer to process
    });
    it('displays click events', function(){
      expect(el.shadowRoot.textContent).to.contain('Page clicked');
    });
  });
With that, I have all (both) of my tests passing under polymer-test-tools:
$ karma start
...
Chrome 37.0.2062 (Linux): Executed 2 of 2 SUCCESS (0.196 secs / 0.003 secs)
In the end, this really saved me no work. In fact, I had to do a little extra work to disable settings that were not relevant to my on my Linux machine (e.g. IE, Safari testing support). Since I still have to manually install mocha and chai (and setup chai) despite both being included in the polymer-test-tools repository, I save no effort. In other words, this is not a tool for testing custom Polymer elements. Polymer-test-tools is a place for common framework settings to go.

Still, the effort was hardly a complete waste. It is instructive seeing how the Polymer team tests different platforms and browsers (conditionals depending on the operating system). The overall approach seems similar to what I have been using, though I probably ought to investigate a bit more before claiming confirmation of my approach.

Bottom line: I plan to stick with my current approach in Patterns in Polymer.


Day #167

No comments:

Post a Comment