karma-polymer-test

A karma plugin that allows easy unit testing of a Polymer component

Usage no npm install needed!

<script type="module">
  import karmaPolymerTest from 'https://cdn.skypack.dev/karma-polymer-test';
</script>

README

karma-polymer-test

A karma plugin that allows easy unit testing of a Polymer component.

Features

  • Automatically loads necessary Karma frameworks for testing Polymer components
  • Built in bootstrap for loading the Polymer element via the elementSuite Mocha extension
  • Can load boilerplate HTML files for use in the testing
  • Sets up proxies to the correct locations of the Polymer bower components

Installation

The easiest way is to keep karma-polymer-test as a devDependency in you package.json.

{
  "devDependencies": {
    "karma-polymer-test": "~0.1"
  }
}

You can simple do it by:

npm install karma-polymer-test --save-dev

Configuration

// karma.conf.js
module.exports = function(config) {
  config.set({
    frameworks: ['polymerTest'],

    // configuration
    polymerTest: {
    }
  });
};

Getting Started

The karma-polymer-test component allows a very simple method to test Polymer components. It uses the Mocha test framework coupled with chai as the assertion library. This allows the tests to run in the browser but also be hosted by the grunt karma plugin.

To get going, add some tests create the test/attributes.js file in the root of the repository:

/* global elementSuite, suite, test, assert */
(function() {
  'use strict';
  // Specify that we are running tests for the `vca-colour-picker` element
  elementSuite('vca-colour-picker', function() {
    suite('attributes', function() {
      test('setting the RGB values should change the web value', function(done) {
        // The karma-polymer-test adds some extra function calls to Mocha to work
        // around the timing issues of setting Polymer attributes. Set the attributes in
        // the `this.set` callback then check them in the `this.then` callback
        this.set(function(element) {
          element.r = 128;
          element.g = 48;
          element.b = 196;
        }).then(function(element) {
          assert.equal(element.web, '#8030c4');
        });
      });
    });
  });
}());

Karma is a testing runner that has a plugin for grunt. Karma allows the tests to be run from the command line on multiple browsers.

First add the following to your package.json:

{
  "devDependencies": {
    "karma": "*",
    "karma-polymer-test": "*"
  }
}

This will allow automatic testing on the browsers available on the system. You'll want the karma-cli globally:

npm install -g karma-cli

Now you'll need a configuration file to tell Karma what to load and test. The following configuration file works well, but may need tweaks. Save it as karma.js in the root of the repository:

module.exports = function(config) {
  'use strict';
  // Set up karma
  config.set({
    frameworks: ['polymerTest'],
    files: ['test/*.js']
  });
};

Tests can now be run in the Karma server. The Karma server watches the files for any changes and re-runs the tests when they are modified which is really useful for fast iterations:

karma start karma.js

The final step is to hook up Karma to grunt so the tests can be run in a continuous integration server. Make sure you have the necessary plugins in your package.json:

{
  "devDependencies": {
    "grunt-bower-install-simple": "*",
    "grunt-karma": "*"
  }
}

Then add the following to the gruntfile.js to add the tests to the build step:

module.exports = function(grunt) {
  'use strict';
  // Project Configuration
  grunt.initConfig({
    // Metadata
    bower: grunt.file.exists('.bowerrc') && grunt.file.readJSON('.bowerrc') || {directory:'bower_components'},

    // Task configuration
    'bower-install-simple': {
      options: {
        forceLatest: true,
        color: true,
        production: false,
        directory: '<%= bower.directory %>'
      }
    },
    karma: {
      config: {
        configFile: 'karma.conf.js',
        autoWatch: false,
        singleRun: true
      }
    },
  });

  // Plugins
  grunt.loadNpmTasks('grunt-karma');
  grunt.loadNpmTasks('grunt-bower-install-simple');

  // Some aliases
  grunt.registerTask('bower-install', [ 'bower-install-simple' ]);

  // Task registration
  grunt.registerTask('test', ['bower-install', 'karma:config']);
};

Running grunt test will now run the tests automatically as part of the build process.

Boilerplate HTML

Polymer elements have the capability of have children nodes injected using the <content> tag. To be able to test this capability a boilerplate piece of HTML needs to be inserted into the testing iframe. To use this feature of karma-polymer-test add the serving of HTML boilerplate files to the karma.conf.js:

module.exports = function(config) {
  'use strict';
  // Set up karma
  config.set({
    frameworks: ['polymerTest'],
    files: [
      'test/*.js',
      // We need this to allow the HTML boilerplate files to be loaded via
      // elementSuite, Karma will now serve the files
      {pattern:'test/*.html', included: false, watched: true, served: true}
    ]
  });
};

Add a second parameter to the elementSuite test case with the name of the HTML boilerplate file to load:

/* global elementSuite, suite, test, assert */
(function() {
  'use strict';
  elementSuite('my-element', 'my-boilerplate', function() {
// The HTML file name to load ^^^^^^^^^^^^^^
  });
)());

Now it is possible to create a boilerplate file called test/my-boilerplate.html that will be used for each test in the elementSuite tests:

<!doctype html>
<html>
  <head>
    <title>VCA Element Test</title>
    <meta charset="UTF-8">

    <!-- Make sure the web components polyfill is loaded -->
    <script src="/bower_components/webcomponentsjs/webcomponents.min.js"></script>
  </head>
  <body>
    <my-element>
      <p>This is <content></p>
    </my-element>
  </body>
</html>

The karma-polyer-test framework proxies the bower components directory to /bower_components even if the .bowerrc sets the folder to another location locally. It is then easy to load dependent elements for testing.