Reputation: 646
The following unit test works in Chrome (due to its native support for HTML-imports), but I'm struggling to get it to work with PhantomJS (and other browsers for that matter).
I'm trying to polyfill the import ('webcomponents.js/HTMLImports.min.js') but it doesn't have any effect.
karma.conf.js
module.exports = function(config) {
config.set({
frameworks: ['jasmine'],
plugins: [
'karma-phantomjs-launcher',
'karma-chrome-launcher',
'karma-jasmine'
],
files: [
'node_modules/angular/angular.js',
'node_modules/angular-mocks/angular-mocks.js',
'node_modules/webcomponents.js/HTMLImports.min.js',
'component/so-example.html',
'test/test.spec.js'
],
port: 9876,
browsers: ['Chrome', 'PhantomJS']
});
};
component/so-example.html
<script>
(function () {
var soExampleComponent = {
transclude: true,
bindings: {
number: '@'
},
template: '<span class="compiled">{{$ctrl.number}}</span>'
};
angular.module('so.components.example', []).component('soExample', soExampleComponent);
})();
</script>
test/test.spec.js
describe('<so-example>', function () {
var $scope, el;
beforeEach(module('so.components.example'));
beforeEach(inject(function ($compile, $rootScope) {
$scope = $rootScope.$new();
el = $compile('<so-example number="{{ 3 }}"></so-example>')($scope)[0];
$scope.$digest();
}));
it('should import and compile', function () {
expect(el.querySelector('.compiled').textContent).toBe('3');
});
});
the error from PhantomJS
forEach@C:/Temp/so-example/node_modules/angular/angular.js:322:24
loadModules@C:/Temp/so-example/node_modules/angular/angular.js:4591:12
createInjector@C:/Temp/so-example/node_modules/angular/angular.js:4513:30
workFn@C:/Temp/so-example/node_modules/angular-mocks/angular-mocks.js:3060:60
C:/Temp/so-example/node_modules/angular/angular.js:4631:53
TypeError: undefined is not an object (evaluating 'el.querySelector') in C:/Temp/so-example/test/test.spec.js (line 14)
C:/Temp/so-example/test/test.spec.js:14:14
Upvotes: 1
Views: 590
Reputation: 646
After banging my head against this for about a day, it turns out the solution was quite simple.
We can force jasmine
to wait until the import has finished by having the following block execute before any tests which rely on an HTML import.
// Wait for the HTML Imports polyfill to finish before running anything else
beforeAll(function(done) {
window.addEventListener('HTMLImportsLoaded', done);
});
I've put this into a separate file that is referenced in karma.conf.js
before all of my other spec.js
files.
However, it can be placed within a single describe
block or a single spec.js
if it isn't required anywhere else.
Upvotes: 1