It looks as though I will be replacing Karma with web-component-tester as the testing framework in Patterns in Polymer. I only really need to do the in the two testing chapters, but I'm in for a penny...
To get started, I will switch testing for the very simple
<hello-you>
Polymer element from chapter 1 of the book, then upgrade to the latest Polymer to see if anything breaks. That seems like a nice little test of things.I start by simply replacing the karma dependencies in my chapter's
package.json
with web-component-tester (WCT):{ "name": "hello-you", "devDependencies": { "grunt": "~0.4.5", "grunt-contrib-watch": "~0.6.1", "grunt-notify": "^0.4.1", "web-component-tester": "^2.2.6" } }I remove the Karma configuration, the
test/PolymerSetup.js
that was needed in Karma, and the existing node_modules
. Then I install the new WCT dependencies:➜ polymer git:(master) rm -rf karma.conf.js test/PolymerSetup.js node_modules; npm installFrom there, I can convert my tests fairly easily. I had defined the test files in the old
karma.conf.js
. The web-component-tester expects the test entry point to reside in test/index.html
. So I create test/index.html
and point it the existing test file:<!doctype html> <html> <head> <meta charset="utf-8"> <script src="../bower_components/webcomponentsjs/webcomponents.min.js"></script> <script src="../../web-component-tester/browser.js"></script> <link rel="import" href="../elements/hello-you.html"> </head> <body> <hello-you id="fixture"></hello-you> <script src="index.js"></script> </body> </html>I also add a fixture in there for easier access to the Polymer element that I want to test.
The tests themselves nearly work without change. I had been using Jasmine for my tests. The BDD interface supported by Chai is very similar to Jasmine—all I need to change is my assert statements:
describe('<hello-you>', function(){ var el; beforeEach(function(){ el = document.querySelector('#fixture'); }); // ... describe('typing', function(){ beforeEach(function(done){ var input = el.shadowRoot.querySelector('input'); var e = document.createEvent('TextEvent'); e.initTextEvent('textInput', true, true, null, 'Bob'); input.dispatchEvent(e); setTimeout(done, 0); // One event loop for Polymer to process }); it('says a friendly hello', function() { var h2 = el.shadowRoot.querySelector('h2'); assert.equal(h2.textContent, 'Hello Bob'); }); }); });Just like that, I have passing tests:
chrome 41 Beginning tests via http://localhost:59285/polymer/test/index.html?cli_browser_id=0 chrome 41 ✓ index.html » <hello-you> » element content » has a shadow DOM chrome 41 ✓ index.html » <hello-you> » typing » says a friendly hello chrome 41 Tests passed Test run ended with great success chrome 41 (2/0/0) Done, without errors.I have another test that relies on Jasmine spies. WCT supports spies, but Sinon stubs instead of Jasmine spies. In this case, I want to stub the return value of
Math.random
so that the otherwise random color change is deterministic. Sinon (like Jasmine) makes this easy: describe('clicking', function(){
beforeEach(function(){
// spyOn(Math, "random").and.returnValue(0.99);
sinon.stub(Math, "random").returns(0.99);
});
it('randomly changes the title\'s color', function(){
var button = el.shadowRoot.querySelector('input[type=submit]');
var e = document.createEvent('MouseEvent');
e.initMouseEvent(
"click", true, true, window,
0, 0, 0, 80, 20,
false, false, false, false, 0, null
);
button.dispatchEvent(e);
var h2 = el.shadowRoot.querySelector('h2');
assert.equal(h2.style.color, 'green');
});
});
With that, I again have three passing tests for my simple element:chrome 41 Beginning tests via http://localhost:37627/polymer/test/index.html?cli_browser_id=0 chrome 41 ✓ index.html »My next step is to upgrade the Polymer library to verify that (hopefully) nothing breaks. For the book, I have left Polymer unconstrained in Bower:» element content » has a shadow DOM chrome 41 ✓ index.html » » typing » says a friendly hello chrome 41 ✓ index.html » » clicking » randomly changes the title's color chrome 41 Tests passed Test run ended with great success chrome 41 (3/0/0) Done, without errors.
{ "name": "hello-you", // ... "dependencies": { "polymer": ">0.0" } }So a simple
bower update
gets me to Polymer 0.8:$ bower update ... polymer#0.8.0 bower_components/polymer ├── core-component-page#0.5.5 └── webcomponentsjs#0.6.0 webcomponentsjs#0.6.0 bower_components/webcomponentsjsWith that, I re-run my tests and find… that two tests are now failing:
chrome 41 Beginning tests via http://localhost:42253/polymer/test/index.html?cli_browser_id=0 chrome 41 ✖ index.html » <hello-you> » element content » has a shadow DOM expected null to not equal null <unknown> at Context.<anonymous> at /polymer/test/index.js:10:0 chrome 41 ✖ index.html » <hello-you> » clicking » randomly changes the title's color Cannot read property 'querySelector' of null <unknown> at Context.<anonymous> at /polymer/test/index.js:44:0 chrome 41 Tests failed: 2 failed tests Test run ended in failure: 2 failed tests chrome 41 (0/0/2) 2 failed testsAt first, I suspect that there is a newer version of the web-component-tester that I need for Polymer 0.8. Then I take a closer look a the 0.8 Migration Guide and… wow. I am in some serious trouble with 0.8. Not only has the API completely changed, but many of the core concepts that have been baked in to Polymer for nearly two years have changed. Shady DOM? Ouch.
With not _too_ much effort, I am able to get my very simple element migrated to 0.8 and the tests passing again. But I need to give some very serious consideration to how I plan to handle 0.8 in the book. Given that it is only a preview release at this point, I may push to get the latest version of the book done sooner rather than later then deal with the repercussions of 0.8 after the new API stabilizes. Ugh. And I was having such a nice time with web-component-tester.
Day #21
Thanks! Your click example really helped. I have a button that, when clicked, initiates an ajax call, which seems to fail immediately when I test it in Chrome. The Timing tab says "stalled". Any idea how I fix that in web-component-tester?
ReplyDelete