Gathering detailed insights and metrics for grunt-croc-qunit
Gathering detailed insights and metrics for grunt-croc-qunit
Gathering detailed insights and metrics for grunt-croc-qunit
Gathering detailed insights and metrics for grunt-croc-qunit
npm install grunt-croc-qunit
Module System
Min. Node Version
Typescript Support
Node Version
NPM Version
5 Stars
42 Commits
3 Forks
4 Watching
1 Branches
7 Contributors
Updated on 06 Nov 2019
JavaScript (94.42%)
CSS (4.48%)
HTML (1.1%)
Cumulative downloads
Total Downloads
Last day
-75%
3
Compared to previous day
Last week
-27.8%
13
Compared to previous week
Last month
25.7%
44
Compared to previous month
Last year
-61.2%
844
Compared to previous year
4
5
Run QUnit unit tests in a headless PhantomJS instance with code coverage support.
This plugin is modified version of two plugins: grunt-contrib-qunit and grunt-lib-phantomjs. Here's reasoning why it was forked and modified.
Original grunt-contrib-qunit
creates the following dependencies tree:
This works great when you install grunt-contrib-qunit from official npm registry. All dependencies downloaded and installed automatically.
But phantomjs npm module has very specific feature: on installation after PhantomJS downloading it hardcodes absolute path to its executable.
Such behavior makes it impossible to share node_modules
folder between machines.
Consequently, it's impossible to keep node_modules
in VCS (Git/Subversion).
That's because this plugin was created. It does not depend on grunt-lib-phantomjs
and phantomjs
npm modules.
It expects that you will install PhantomJS on your own and supply path to its executable in task's options.
There are other distinctions from original grunt-contrib-qunit
:
bridge.js
script was modified to remove excess processing of QUnit.equal's arguments (see this issue)bridge.js
reports code coverage info from window.__coverage__
as phantomjs' qunit.coverage
event on test completioneventHandlers
option for qunit
taskPay attention not to redefine
window.alert
as it is used internally by the tasks for coordination purposes
To install the plugin:
1npm install grunt-croc-qunit --save-dev
Once the plugin has been installed, it may be enabled inside your Gruntfile with this line of JavaScript:
1grunt.loadNpmTasks('grunt-croc-qunit');
Or just use matchdep
module.
Grunt task for executing QUnit tests inside PhantomJS.
Task targets, files and options may be specified according to the grunt Configuring tasks guide.
Please note that this plugin doesn't download and install PhantomJS.
For running QUnit tests you'll need to manually install PhantomJS first into some reachable place. You can use phantomjs npm module for this.
Also note that running grunt with the --debug
flag will output a lot of PhantomJS-specific debugging information. This can be very helpful in seeing what actual URIs are being requested and received by PhantomJS.
Type: String
Default: (none)
Required: yes
The path to PhantomJS executable. It can be absolute or relative to the current working directory (by default it's folder where Gruntfile.js lives).
Type: Object
Default: (none)
An object map where keys are event names and values are event handlers.
Type: Number
Default: 5000
The amount of time (in milliseconds) that grunt will wait for a QUnit start()
call before failing the task with an error.
Type: String
Default: (built-in)
Path to an alternate QUnit-PhantomJS bridge file to be injected. See the built-in bridge for more information.
Type: Array
Default: []
Absolute http://
or https://
urls to be passed to PhantomJS. Specified URLs will be merged with any specified src
files first. Note that urls must be served by a web server, and since this task doesn't contain a web server, one will need to be configured separately. The grunt-contrib-connect plugin provides a basic web server.
Type: String
Default: (none)
Additional --
style arguments that need to be passed in to PhantomJS may be specified as options, like {'--option': 'value'}
. This may be useful for specifying a cookies file, local storage file, or a proxy. See the PhantomJS API Reference for a list of --
options that PhantomJS supports.
Type: boolean
Default: false
Do not fail task if some failed
Type: String
Values: "console" | "teamcity"
Default: "console"
Name of reporter to use. By default plugin will report progress to console (via grunt.log
).
Specify "teamcity" for usage of a reporter which uses TeamCity syntax.
Type: Boolean
Default: true
Use false
to more concise output (only module start/end and test pass/fail result will be logged).
In this example, grunt qunit:all
will test all .html
files in the test directory and all subdirectories. First, the wildcard is expanded to match each individual file. Then, each matched filename is passed to PhantomJS (one at a time).
1// Project configuration. 2grunt.initConfig({ 3 qunit: { 4 options: { 5 'phantomPath': 'tools/phantomjs/phantomjs.exe' 6 }, 7 all: ['test/**/*.html'] 8 } 9});
In circumstances where running unit tests from local files is inadequate, you can specify http://
or https://
URLs via the urls
option. Each URL is passed to PhantomJS (one at a time).
In this example, grunt qunit
will test two files, served from the server running at localhost:8000
.
1// Project configuration.
2grunt.initConfig({
3 qunit: {
4 options: {
5 'phantomPath': 'node_modules/phantomjs/lib/phantom/phantomjs.exe'
6 },
7 all: {
8 options: {
9 urls: [
10 'http://localhost:8000/tests/run-tests.html?filter=UnitTest1',
11 'http://localhost:8000/tests/run-tests.html?filter=UnitTest1'
12 ]
13 }
14 }
15 }
16});
Wildcards and URLs may be combined by specifying both.
It's important to note that grunt does not automatically start a localhost
web server. That being said, the grunt-contrib-connect plugin connect
task can be run before the qunit
task to serve files via a simple connect web server.
In the following example, if a web server isn't running at localhost:8000
, running grunt qunit
with the following configuration will fail because the qunit
task won't be able to load the specified URLs. However, running grunt connect qunit
will first start a static connect web server at localhost:8000
with its base path set to the Gruntfile's directory. Then, the qunit
task will be run, requesting the specified URLs.
1// Project configuration.
2grunt.initConfig({
3 qunit: {
4 options: {
5 'phantomPath': 'node_modules/phantomjs/lib/phantom/phantomjs.exe'
6 },
7 testserver: {
8 options: {
9 urls: [
10 'http://localhost:8000/tests/run-tests.html'
11 ]
12 }
13 }
14 },
15 connect: {
16 testserver: {
17 options: {
18 port: 8000,
19 base: '.'
20 }
21 }
22 }
23});
24
25// This plugin provides the "connect" task.
26grunt.loadNpmTasks('grunt-contrib-connect');
27
28// A convenient task alias.
29grunt.registerTask('test', ['connect:testserver', 'qunit:testserver']);
It can be usefull to run a single test. QUnit supports filter
query string parameter. If the parameter is specified then QUnit executes only tests which names satisfy the filter.
1grunt.initConfig({
2 qunit:{
3 options: {
4 'phantomPath': '../../Tools/phantomjs/phantomjs.exe',
5 urlFilter: ""
6 },
7 test: {
8 options: {
9 urls: ['http://127.0.0.1:<%= connect.test.options.port %>/tests-runner.html<%= qunit.options.urlFilter %>']
10 }
11 },
12 connect: {
13 test: {
14 options: {
15 port: 8001,
16 base: '.'
17 }
18 }
19 }
20});
21
22grunt.registerTask('test', function (target) {
23 addQUnitUrlFilter('qunit.options.urlFilter');
24 var filter = grunt.option('filter');
25 if (filter) {
26 grunt.config.set(taskPropName, '?filter=' + filter);
27 }
28 grunt.task.run(['qunit:test']);
29});
30
Now you can execute a single test (or any other ones with filter) via QUnit as: grunt test --filter=MyTestName
In the following example, the default timeout value of 5000
is overridden with the value 10000
(timeout values are in milliseconds). Additionally, PhantomJS will read stored cookies from the specified file. See the PhantomJS API Reference for a list of --
options that PhantomJS supports.
1// Project configuration.
2grunt.initConfig({
3 qunit: {
4 options: {
5 timeout: 10000,
6 '--cookies-file': 'misc/cookies.txt'
7 },
8 all: ['test/**/*.html']
9 }
10});
QUnit callback methods and arguments are also emitted through grunt's event system so that you may build custom reporting tools. Please refer to the QUnit documentation for more information.
The events are as follows :
qunit.begin
qunit.moduleStart
qunit.testStart
qunit.log
qunit.testDone
qunit.moduleDone
qunit.done
qunit.coverage
Starting with v1.0 events arguments are the same in QUnit callbacks.
In addition to QUnit callback-named events, the following event is emitted when PhantomJS is spawned for a test:
qunit.spawn
: urlYou may listen for these events like so:
1grunt.event.on('qunit.spawn', function (url) { 2 grunt.log.ok("Running test: " + url); 3});
Additionally you can supply an object in eventHandlers
task's option.
1 qunit:{ 2 options: { 3 'phantomPath': '../../Tools/phantomjs/phantomjs.exe' 4 }, 5 test: { 6 options: { 7 eventHandlers: { 8 'qunit.coverage': function (coverage) { 9 grunt.file.write('.tmp/coverage.json', JSON.stringify(coverage)); 10 } 11 }, 12 urls: ['http://127.0.0.1:9002/tests-runner.html'] 13 } 14 } 15 }
The event qunit.coverage
allows using Istanbul code coverage library. See next chapter.
The module contains Grunt tasks coverageInstrument
, coverageReport
for code coverage via Istanbul.
When you have loaded the plugin (via grunt.loadNpmTasks
) you have some tasks available besides qunit
. These tasks are for creating code coverage reports using Istanbul:
The plugin doesn't depend on Istanbul module directly. So it doesn't add additional dependency into your project if you aren't going to use code coverage with Istanbul.
If you decide to use Istanbul for code coverage you will need to install Istanbul:
npm install istanbul --save-dev
.
You should also install grunt-contrib-connect and serve-static in order to be able to generate the static web server that will allow you to execute the instrumented .js code in place of the original .js code:
npm install grunt-contrib-connect serve-static --save-dev
Code coverage tasks are supposed to be run in the following order: coverageInstrument => connect:testcoverage => qunit => coverageReport.
coverageInstrument
taskTask targets, files and options may be specified according to the grunt Configuring tasks guide.
Task's src
specifies what files will be instrumented. Task's parameters should describe a set of *.js
files. Task's dest
property specifies a folder path where instrumented files will be saved (some kind of temporary folder). These instrumented files should be used during tests execution.
The task src-dest
mappings specification use standard Grunt rules for files processing.
Type: String
Required: yes
src
, expand
, cwd
properties should descibe a set of *.js
files to instument.
Type: String
Required: yes
A folder path where instrumented files will be saved.
Type: Boolean
Required: no
Default: true
If autoBind
option is set then the task will automatically adds a handler for qunit.coverage
event via qunit
task's options (see eventHandlers
option). Also the task will define coverageFile
option for coverageReport
task (coverage file will be placed into dest
folder). So by default you can leave your qunit
task untouched and get coverage reports.
connect:testcoverage
In order to be able to substitute the original sources with the instrumented sources without having to modify the test files, one should create a webserver serving static content that can server the instrumented sources as the original one.
The grub-contrib-connect
and serve-static
packages allow the on-the-fly creation of a local web server where the tests can be run and where the http://localhost:port/src will be associated with the instrumented local version of the sources files. The middleware functionnality of connect is exploited and a specific mountFolder function is used in order to associate the web server aliases with the local folders.
1 var serveStatic = require('serve-static'); 2 3 grunt.initConfig({..., 4 connect: { 5 testcoverage: { 6 options: { 7 .. 8 middleware: function (connect) { 9 return [ 10 // instrumented sources first as "regular" sources 11 serveStatic('.tmp'), 12 // then test fixtures and libs 13 serveStatic('tests'), 14 serveStatic('libs'), 15 ]; 16 } 17 } 18 } 19 }, ...}); 20 }
Type: Object
Required: no
The option allows to generade a AMD module with imports of all instrumented files. This is usefull for getting more accurate coverage reports. If an instrumeneted file wasn't loaded during tests execution then coverage report won't take it into account at all and you'll get falsy high numbers of coverage.
For getting correct numbers of code coverage you need to load all your files during test execution. You can do it manually or allow coverageInstrument
task to do it for you.
The task supposes that all files are AMD-modules (e.g. loaded via RequireJS or the like). In your main module for tests you can import a stub like 'all-modules'. Then tell coverageInstrument
task to replace the stub with generated module which will contain imports of all instrumented files.
For more info see examples below.
generateModule
option is an object with properties:
output
- path to generated module (i.e. js file path):String
ignore
- an array of module names to ignore (they won't be included into generated module):Array
Generated AMD-module will contain imports of modules which names are relative to the module folder.
For example if generateModule.output
equals to .tmp/all-modules.js
then all module names will relative to '.tmp' folder. It's supposed that instrumented files are put into the same folder (via dest
option).
coverageReport
taskcoverageReport
task controls what reports to generate from coverage info. In most cases coverage info is a json file created on qunit test completion. You can use qunit.coverage
event to manually handle coverage info and save it into a file or leave it to happen automatically if autoBind
option was set for coverageInstrument
task.
Type: String
Default: (none)
Required: yes
The file path to coverage.json
file with coverage info saved after tests completion. To create this file you can use qunit.coverage
event. See example below.
This option is set automatically if autoBind
option of coverageInstrument
task is specified (by default).
Type: Object
Required: no
An object to specify what reports should be generated. The object's key can be any report name which Istanbul supports (html
, lcov
, text
; see the doc for details). The key's value should be a folder path where the report will be created.
It doesn't make much sence to run tasks coverageInstrument
and coverageReport
individually. Instead they are designed to be run in a pipeline with qunit
task.
But they were designed specifically to be independent from qunit
task to simplify re-using if you will.
1 var serveStatic = require('serve-static'); 2 3 grunt.initConfig({ 4 qunit:{ 5 options: { 6 'phantomPath': '../../Tools/phantomjs/phantomjs.exe' 7 }, 8 test: { 9 options: { 10 // url which `connect` server will be serve 11 urls: ['http://127.0.0.1:<%= connect.testcoverage.options.port %>/tests-runner.html'] 12 } 13 } 14 }, 15 connect: { 16 testcoverage: { 17 options: { 18 port: 9002, 19 hostname: '127.0.0.1', 20 middleware: function (connect) { 21 return [ 22 // instrumented sources first as real src through alias usage 23 serveStatic('.tmp'), 24 // then test fixtures and helpers 25 serveStatic('tests'), 26 // other libs 27 serveStatic('lib') 28 ]; 29 } 30 } 31 } 32 }, 33 coverageInstrument: { 34 test: { 35 // NOTE: we instrument only subset of our sources ('lib') 36 src: 'lib/**/*.js', 37 expand: true, 38 cwd: 'src', 39 dest: '.tmp' 40 } 41 }, 42 coverageReport: { 43 test: { 44 options: { 45 reports: { 46 html: 'coverageReports/' 47 } 48 } 49 } 50 } 51 }); 52 grunt.registerTask('testcoverage', ['coverageInstrument', 'connect:testcoverage', 'qunit:test', 'coverageReport']);
Now just run: grunt testcoverage
generateModule
option usageThe config from the previous example can be extended by adding generateModule
option into coverageInstrument
task:
1 2 coverageInstrument: { 3 test: { 4 options: { 5 generateModule: { 6 output: '.tmp/all-modules.js', 7 // put here all modules for which you have aliases in requirejs' config (paths) 8 ignore: ['lib/core', 'lib/xcss', 'lib/xhtmpl'] 9 } 10 }, 11 // NOTE: we instrument only subset of our sources ('lib') 12 src: 'lib/**/*.js', 13 expand: true, 14 cwd: 'src', 15 dest: '.tmp' 16 } 17 },
tests-runner.html file contains something like this:
1<script type="text/javascript" src="require.config.js"></script> 2<script type="text/javascript" src="vendor/require.js" data-main="tests-main"></script>
main script tests-main.js:
1require([ 2 "all-modules", 3 "fixtures/component1-tests", ... all other tests 4], function () { 5 6 // run all tests after their modules were loaded 7 QUnit.start(); 8});
Here all-modules.js is a stub module:
1define([], function () {});
coverageInstrument
task was incorrectly overriding qunit.options.eventHandlers
window.__coverage__
object.Authored by Sergei Dorogin
(c) Copyright CROC Inc. 2013-2016
Original tasks (grunt-contrib-qunit and grunt-lib-phantomjs) were authored by:
Contributors:
No vulnerabilities found.
Reason
no binaries found in the repo
Reason
0 existing vulnerabilities detected
Reason
license file detected
Details
Reason
Found 3/29 approved changesets -- score normalized to 1
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
Reason
project is not fuzzed
Details
Reason
branch protection not enabled on development/release branches
Details
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
Score
Last Scanned on 2024-11-25
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More