Today, I try my hand at combining Grunt and web-component-tester for local Polymer development.
Last night's experiment with Gulp was reasonable successful. Initial setup with Gulp and web-component-tester (WCT) was brilliantly easy. Even the first bits of customization was relatively simple. Quickly, however, I reached a point where I was hip-deep in node.js streams, error handling and the alphabet soup of NPM packages that Gulp uses to make sense of them.
Grunt will certainly require a little more initial effort, but I am all-but-certain that I can get my complete local setup in place. The best laid plans....
What I want is a means to automatically run my tests locally whenever I make a change to code or test files. I also a appreciate a little LiveReload support for my sample pages. I have done both with Grunt before, though not with web-component-tester.
I start by wiping my sample application's
package.json
file so that I can re-add Grunt, web-component-tester, and a couple of other dependencies that I know that I will want to use:$ npm install grunt grunt-notify grunt-contrib-watch web-component-tester --save-devThis leaves me with a
package.json
that contains:{ "name": "wct_sample", "devDependencies": { "grunt": "^0.4.5", "grunt-contrib-watch": "^0.6.1", "grunt-notify": "^0.4.1", "web-component-tester": "^2.2.6" } }I start my
Gruntfile.js
configuration file with the sample included in the WCT homepage:module.exports = function(grunt) { pkg: grunt.file.readJSON('package.json'), grunt.initConfig({ 'wct-test': { local: { options: {remote: false} }, remote: { options: {remote: true} }, chrome: { options: {browsers: ['chrome']} } } }); grunt.loadNpmTasks('web-component-tester'); };That gives me
wct-test:local
, wct-test:remote
, and wct-test:chrome
tasks. The first is the one that will run my test suite (currently just a single test):$ grunt wct-test:local:chrome Running "wct-test:local:chrome" (wct-test) task Starting Selenium server for local browsers Selenium server running on port 33822 Web server running on port 35707 and serving from /home/chris/repos/polymer-book/play/web-component-tester chrome 41 Beginning tests via http://localhost:35707/js/test/index.html?cli_browser_id=0 chrome 41 Tests passed firefox 36 Beginning tests via http://localhost:35707/js/test/index.html?cli_browser_id=1 firefox 36 Tests passed Test run ended with great success chrome 41 (1/0/0) firefox 36 (1/0/0) Done, without errors.Nice. That was just as easy to get running as the Gulp version (admittedly there is less configuration with Gulp for the very simple case).
Next, I would like to run my test suite whenever there is a change to any file in the
tests
or elements
directories. This is why I included the grunt-contrib-watch
development dependency at the outset. I update Gruntfile.js
to include the watch tasks and definitions:module.exports = function(grunt) { pkg: grunt.file.readJSON('package.json'), grunt.initConfig({ 'wct-test': { local: { options: {remote: false} }, // ... }, watch: { code: { files: ['index.html', 'elements/**'], options: { livereload: true } }, tests: { files: ['elements/**', 'test/**'], tasks: ['wct-test:local'], options: {atBegin: true} } } }); grunt.loadNpmTasks('web-component-tester'); grunt.loadNpmTasks('grunt-contrib-watch'); };The
watch:code
task will watch the specified files which impact the sample page. On update, they trigger the browser to LiveReload the page (if the extension is being used). The watch:tests
task will watch code and test files for changes, running the WCT's wct-test:local
task when it sees those changes. For good measure, I specify that the tests should be run at start as well. And that all works nicely. When I invoke
watch
, my tests are run right away:$ grunt watch Running "watch" task Waiting... Running "wct-test:local" (wct-test) task Starting Selenium server for local browsers Selenium server running on port 44706 Web server running on port 37026 and serving from /home/chris/repos/polymer-book/play/web-component-tester chrome 41 Beginning tests via http://localhost:37026/js/test/index.html?cli_browser_id=0 chrome 41 Tests passed firefox 36 Beginning tests via http://localhost:37026/js/test/index.html?cli_browser_id=1 firefox 36 Tests passed Test run ended with great success chrome 41 (1/0/0) firefox 36 (1/0/0) Done, without errors. Completed in 7.828s at Tue Mar 31 2015 23:37:56 GMT-0400 (EDT) - Waiting...This task does not end, but polls for changes to the specified files. If I make a change to one of them, I find:
>> File "test/index.html" changed. Running "wct-test:local" (wct-test) task Starting Selenium server for local browsers Selenium server running on port 49367 Web server running on port 41348 and serving from /home/chris/repos/polymer-book/play/web-component-tester chrome 41 Beginning tests via http://localhost:41348/js/test/index.html?cli_browser_id=0 chrome 41 Tests passed firefox 36 Beginning tests via http://localhost:41348/js/test/index.html?cli_browser_id=1 firefox 36 Tests passed Test run ended with great success chrome 41 (1/0/0) firefox 36 (1/0/0) Done, without errors. Completed in 7.491s at Tue Mar 31 2015 23:38:18 GMT-0400 (EDT) - Waiting...To complete my desired setup, I would like to have desktop notifications fire at the end of each test run. This is where the
grunt-notify
package comes in handy. I want to use "notify hooks” in this case. Whenever a task completes successfully, these hooks will send a desktop notification with the result message.To use hooks, I have to load the
grunt-notify
tasks as usual, then run the hooks task:module.exports = function(grunt) { pkg: grunt.file.readJSON('package.json'), grunt.initConfig({ /* ... */ }); grunt.loadNpmTasks('web-component-tester'); grunt.loadNpmTasks('grunt-contrib-watch'); grunt.loadNpmTasks('grunt-notify'); grunt.task.run('notify_hooks'); };That is all that is needed, but I like to specify two configuration options: one to send notifications when the tests succeed (only failure messages are displayed by default) and one to display the message for 8 seconds (instead of the default 3):
module.exports = function(grunt) { pkg: grunt.file.readJSON('package.json'), grunt.initConfig({ 'wct-test': { /* ... */ }, watch: { /* ... */ }, notify_hooks: { options: { success: true, duration: 8 } } }); grunt.loadNpmTasks('web-component-tester'); grunt.loadNpmTasks('grunt-contrib-watch'); grunt.loadNpmTasks('grunt-notify'); grunt.task.run('notify_hooks'); };With that, I see a nice success message when I start Grunt:
And, if I break something, I see:
I might like to see the actual failure message in there, but that is a minor quibble (and a byproduct of WCT since I saw just the one line in Gulp as well). That aside, this is exactly what I want in my test setup and should serve nicely for actual development of Polymer code—something that I will put to the test over the next few days.
Day #15