Reputation: 558
I've searched for answers on this on the internet for a while. It concerns testing an AngularJS custom directive, using external templateUrl stored in a html-file, in Maven build. (After getting it to work successfully on Karma)
There is a lot of information and answers on how to make custom directive tests with external templateUrl work on Karma, but I find very little to nothing that applies on the Jasmine Maven Plugin. All I find is the API on http://searls.github.io/jasmine-maven-plugin, and overview descriptions. Not much in-depth tutorials or guides to be found, neither problems others have had, that is directly related to testing custom directive on Maven build.
First, I had to solve the problem with making it run on Karma, as we all do our first time. I solved it with preprocessing, and I will first explain the setup (using pseudofiles and paths):
karma.conf.js (simplified version that hides unrelated files for this question)
module.exports = function(config) {
config.set({
basePath: 'src/',
preprocessors: {
'main/pathToHtmlFiles/myModule/directive/**/*.html': 'ng-html2js'
},
files: [
'https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js',
'https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular-resource.min.js',
'main/pathToJsFiles/myModule/mainApp.js',
'main/pathToJsFiles/myModule/directive/myDirective.js',
'test/pathToJsFiles/**/*.js',
'main/pathToHtmlFiles/myModule/directive/myDirectiveTemplate.html'
],
ngHtml2JsPreprocessor: {
stripPrefix : 'main/pathToHtmlFiles/',
moduleName: 'directiveHtmlTemplates'
},
frameworks: ['jasmine'],
autowatch: true,
browsers: ['PhantomJS'],
plugins: [
'karma-jasmine',
'karma-chrome-launcher',
'karma-opera-launcher',
'karma-ng-html2js-preprocessor'
]
})
};
The config that are added specifically for the custom directive testing to work in Karma, are the
templateUrl property in the custom directive is 'myModule/directive/myDirectiveTemplate.html',
I don't consider the contents of the html-file relevant for the question. I have not included angular-mocks.js in the code above, but it is included in the real work.
In the jasmine tests, I inject the preprocessed directive:
beforeEach(module('mainApp'));
beforeEach(module('directiveHtmlTemplates'));
Then I compile the directive before each test:
var element = angular.element('<my-custom-directive><my-custom-directive>');
var compiledElement = compile(element)(scope);
scope.$digest();
So far, so good, and the tests are working.
Now comes the real problem: Making this work with Maven build.
The setup we have had with jasmine-maven-plugin has been the following:
pom.xml
<plugin>
<groupId>com.github.searls</groupId>
<artifactId>jasmine-maven-plugin</artifactId>
<version>2.0</version>
<executions>
<execution>
<goals>
<goal>test</goal>
</goals>
</execution>
</executions>
<configuration>
<jsSrcDir>src/main/pathToJsFiles/myModule/js</jsSrcDir>
<jsTestSrcDir>src/test/pathToJsFiles/myModule/js</jsTestSrcDir>
<preloadSources>
<source>https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js</source>
<source>https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular-resource.min.js</source>
<source>${basedir}/src/main/pathToJsFiles/myModule/mainApp.js</source>
<source>${basedir}/src/main/pathToJsFiles/myModule/directive/myDirective.js</source>
</preloadSources>
</configuration>
</plugin>
myDirective.js is the new file here.
(I just discovered that 'jsSrcDir' was outdated as I write this, but given that we haven't had any problems before, I assume that both 'jsSrcDir' and 'jsTestSrcDir' have paths overlapping with the files under 'preloadSources'. Still, this is what we have had until now, so I'll add them in case you should happen to see something relevant there)
I've also tried to add some extra in package.json in an attempt at getting the build to work.
package.json
{
"name": "my-module",
"version": "1.3.0-SNAPSHOT",
"dependencies": {
"grunt-cli": "1.2.0",
"jasmine-core": "^2.4.1",
"karma-cli": "0.1.2"
},
"devDependencies": {
"grunt": "~0.4.5",
"grunt-contrib-jshint": "~0.10.0",
"grunt-contrib-nodeunit": "~0.4.1",
"grunt-contrib-uglify": "~0.5.0",
"grunt-karma": "^0.12.1",
"karma": "^0.13.22",
"karma-jasmine": "^0.3.8",
"karma-phantomjs-launcher": "^1.0.0",
"karma-ng-html2js-preprocessor": "0.2.1"
}
}
'karma-ng-html2js-preprocessor' at the bottom is the new addition, but the setup otherwise are done by my collegues, and I don't necessarily know all I should about what runs in the background (such as phantomjs)
The problem
If I try maven build, this is what I get for every test in myCustomDirectiveTest
[$injector:modulerr] http://errors.angularjs.org/1.4.9/$injector/modulerr?p0=directiveHtmlTemplates&p1=[$injector:nomod]
I'm familiar about this from when I suffered from bad Karma (pun intended), the injector can't find the module 'directiveHtmlTemplate'. It's fixed now for Karma, but how do I do this for jasmine-maven-plugin?
I'm aware of the existence of the specRunners, and the option of using custom runners (customRunnerTemplate, customRunnerConfiguration), but the brief explanation on the jasmine-maven-plugin homepages are not making me much wiser.
Other details: - Ran the following command before adding the preprocessor to package.json:
$ npm install karma-ng-html2js-preprocessor --save-dev
Here is where I am at a loss: Where do I go on from here? How do I get jasmine-maven-plugin to preprocess and add the html-file as the named component 'directiveHtmlTemplates', like I have in Karma?
Upvotes: 0
Views: 566
Reputation: 558
We found a different solution, by using a different plugin in Maven.
The jasmine-maven-plugin has been scrapped, and replaced with frontend-maven-plugin, which can install necessary plugins and run karma.
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>1.0</version>
<executions>
<execution>
<id>install node and npm</id>
<goals>
<goal>install-node-and-npm</goal>
</goals>
<configuration>
<nodeVersion>v6.0.0</nodeVersion>
<npmVersion>3.8.8</npmVersion>
</configuration>
</execution>
<execution>
<id>npm install</id>
<goals>
<goal>npm</goal>
</goals>
<configuration>
<arguments>
install karma-ng-html2js-preprocessor --save-dev
</arguments>
</configuration>
</execution>
<execution>
<id>javascript tests</id>
<goals>
<goal>karma</goal>
</goals>
</execution>
</executions>
</plugin>
Also added the following in karma.conf.js, in order to avoid getting stuck in the Maven build:
config.set({
singleRun : true,
...........
It's probably possible to specify single run in the configs of the frontend-maven-plugin, which is more preferable in most cases. I know it's possible in Grunt, and frontend-maven-plugin supports Grunt as well.
But for now, this will have to do.
In retrospective, npm install karma-ng-html2js-preprocessor --save-dev might have been the missing factor for jasmine-maven-plugin. If I had used a plugin for npm and had it run that command, I suspect it could have solved the problem.
But on the bright side, both the Maven build and the manual Karma-tests now rely on the same karma.config.js file, which is a good advantage. Previously, I listed them separately in both Karma.conf.js and under in the jasmine-maven-plugin.
Upvotes: 0