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