You may want to run tests on your Javascript Files Within your Laravel Elixir Project, and wondering where to begin. Look no further, with Jasmine, Karma & Webpack, you'll be up and running in no time.
In this Tutorial I would be Using Vue, but feel free to adapt this to whatever you like.
Note This was tested with Laravel 5.3 (dev-develop branch), should work if you have your 5.2 or lower project configured to use webpack already. Laravel 5.3 comes with webpack out of the box.
To start up we need to install a couple of node plugins via npm
"karma"
"jasmine-core"
"karma-jasmine"
"karma-chrome-launcher"
"karma-firefox-launcher"
"karma-phantomjs-launcher"
"karma-webpack"
"karma-babel-preprocessor"
npm install karma jasmine-core karma-babel-preprocessor karma-phantomjs-launcher karma-jasmine karma-webpack karma-firefox-launcher karma-chrome-launcher --save-dev
This should be created in the root of your laravel project, and should contain:
// Karma configuration
var webpackConf = require('./webpack.config.js');
delete webpackConf.entry
module.exports = function(config) {
config.set({
frameworks: ['jasmine'],
port: 9876, // web server port
colors: true,
logLevel: config.LOG_INFO,
reporters: ['progress'], // dots, progress
autoWatch: true, // enable / disable watching files & then run tests
browsers: ['Chrome'], //'PhantomJS', 'Firefox',
singleRun: true, // if true, Karma captures browsers, runs the tests and exits
concurrency: Infinity, // how many browser should be started simultaneous
webpack: webpackConf, // Pass your webpack.config.js file's content
webpackMiddleware: {
noInfo: true,
stats: 'errors-only'
},
/**
* base path that will be used to resolve all patterns (eg. files, exclude)
* This should be your JS Folder where all source javascript
* files are located.
*/
basePath: './resources/assets/js/',
/**
* list of files / patterns to load in the browser
* The pattern just says load all files within a
* tests directory including subdirectories
**/
files: [
{pattern: 'tests/**/*.js', watched: false},
],
// list of files to exclude
exclude: [
],
/**
* pre-process matching files before serving them to the browser
* Add your App entry point as well as your Tests files which should be
* stored under the tests directory in your basePath also this expects
* you to save your tests with a .spec.js file extension. This assumes we
* are writing in ES6 and would run our file through babel before webpack.
*/
preprocessors: {
'app.js': ['webpack', 'babel'],
'tests/**/*.spec.js': ['babel', 'webpack']
},
})
}
NOTE: Can't seem to figure out why PhantomJS launcher doesn't work when writing in ES6. Will Update this when I find a fix.
If You do not have a webpack.config file already within the root of your project, create one with this minimal content
// Webpack Config
module.exports = {}
To allow this make sense I would go with the approach of creating a Component, Registering it with Vue, writing a basic unit test for that component (which may not make sense nor add value) just to demonstrate the workflow in action.
I am assuming the following
- There is an app.js file located in "resources/assets/js/app.js"
- There is a "tests" directory created in "resources/assets/js/tests"
- I will be putting my unit test in "resources/assets/js/tests/unit"
- I will create my test files with a postfixed file extenstion of .spec.js
- My components would be located in "resources/assets/js/components"
- I will be writing my javascript in ES6/ES2015
We are simply gonna recreate the Markdown Editor example from Vue's Website. This assumed you've installed Vue & Marked via NPM.
import marked from 'marked';
export default {
template: `
<div :id="editor">
<textarea v-model="input" debounce="300"></textarea>
<div class="editorview" v-html="input | marked"></div>
</div>
`,
data() {
return{ input: '# Hello!' }
},
filters: {
marked: marked
}
}
/** Component **/
import Vue from 'vue';
import Editor from './components/Editor';
var app = new Vue({
el: 'body',
components: { Editor }
});
// Test File "Editor.spec.js"
import Editor from '../../components/Editor.js';
describe('Editor', () => {
it('should set correct default data', function () {
expect(typeof Editor.data).toBe('function')
var defaultData = Editor.data()
expect(defaultData.input).toBe('# Hello!')
});
});
To run your Test simply run this in your terminal
./node_modules/karma/bin/karma start
you can make this shorter by either creating an alias to karma or simply installing Karma CLI globally through NPM.
npm install -g karma-cli
karma start
Alternatively you can use a wizard to generate a config file via the CLI
karma init karma.conf.js
And thats it. It couldn't be easier.