Today, I hope to get a feel for fixing bugs in Polymer elements by driving the fixes with Protractor.
A while back, I noticed a problem in my
<x-pizza> pizza building element:
The problem occurs when adding non-standard toppings, which results in a JavaScript error. I actually noticed the problem while writing Protractor tests, so if I can fix it with another Protractor test, it would make for nice symmetry.
My Protractor test for adding valid toppings looks like:
describe('<x-pizza>', function(){
beforeEach(function(){
browser.get('http://localhost:8000');
});
it('updates value when internal state changes', function() {
new XPizzaComponent().
addFirstHalfTopping('pepperoni');
expect($('x-pizza').getAttribute('value')).
toMatch('pepperoni');
});
});That is nice and compact thanks to the Page Objects pattern—the XPizzaComponent in this case.The page object makes it easy to write a new test that breaks things:
it('adds "unknown" topping when invalid item selected', function() {
new XPizzaComponent().
addFirstHalfTopping('');
expect($('x-pizza').getAttribute('value')).
toMatch('unknown');
});Instead of choosing an option from the list, this should select the first item on the drop down list, which is blank. When I run the Protractor test, I get a failure, but not an error: 1) <x-pizza> adds "unknown" topping when invalid item selected
Message:
Expected '
' to match 'unknown'.
Stacktrace:
Error: Failed expectation
at [object Object].<anonymous> (/home/chris/repos/polymer-book/play/protractor/tests/XPizzaSpec.js:31:7)If I add a browser.pause(): it('adds "unknown" topping when invalid item selected', function() {
new XPizzaComponent().
addFirstHalfTopping('');
browser.pause();
expect($('x-pizza').getAttribute('value')).
toMatch('unknown');
});
Then I can see the error in the WebDriver console:
I find that I can also use this very verbose code to print out the console:
it('adds "unknown" topping when invalid item selected', function() {
new XPizzaComponent().
addFirstHalfTopping('');
browser.manage().logs().get('browser').then(function(browserLog) {
console.log('log: ' + require('util').inspect(browserLog));
});
expect($('x-pizza').getAttribute('value')).
toMatch('unknown');
});Regardless of how I find the error, it is fairly easy to fix it. The console in both cases reports the error to be at:ReferenceError: _svgUnknown is not defined
at x-pizza.Polymer._toppingMaker (http://localhost:8000/elements/x_pizza.js:94:12)Looking at the _toppingMaker() method, I see right away that, unlike the SVG makers for know elements, I am trying to call _svgUnknown() as a function instead of a method: _toppingMaker: function(topping) {
if (topping == 'pepperoni') return this._svgPepperoni;
if (topping == 'sausage') return this._svgSausage;
if (topping == 'green peppers') return this._svgGreenPepper;
return _svgUnknown;
},And, indeed, converting that to a method resolves the bug: _toppingMaker: function(topping) {
if (topping == 'pepperoni') return this._svgPepperoni;
if (topping == 'sausage') return this._svgSausage;
if (topping == 'green peppers') return this._svgGreenPepper;
return this._svgUnknown;
},Just as importantly, I know have an e2e test that exercises this code, ensuring that I do not make a dumb mistake again:<x-pizza> has a shadow DOM - pass updates value when internal state changes - pass syncs <input> values - pass adds "unknown" topping when invalid item selected - pass Finished in 1.938 seconds 4 tests, 4 assertions, 0 failuresThis might seem like a small thing for all that test code, but if I made that mistake once, I can make it again. Unless I have a test.
Day #32
No comments:
Post a Comment