grunt-contrib-qunit
Advanced tools
Comparing version 2.0.0 to 3.0.0
{ | ||
"name": "grunt-contrib-qunit", | ||
"description": "Run QUnit unit tests in a headless PhantomJS instance", | ||
"version": "2.0.0", | ||
"description": "Run QUnit unit tests in a headless Chrome instance", | ||
"version": "3.0.0", | ||
"author": { | ||
@@ -19,3 +19,5 @@ "name": "Grunt Team", | ||
"dependencies": { | ||
"grunt-lib-phantomjs": "^1.0.0" | ||
"bluebird": "^3.5.1", | ||
"eventemitter2": "^5.0.1", | ||
"puppeteer": "1.3.x" | ||
}, | ||
@@ -25,4 +27,4 @@ "devDependencies": { | ||
"grunt": "^1.0.1", | ||
"grunt-contrib-connect": "^1.0.0", | ||
"grunt-contrib-internal": "^1.1.0", | ||
"grunt-contrib-connect": "^1.0.2", | ||
"grunt-contrib-internal": "^3.0.0", | ||
"grunt-contrib-jshint": "^1.0.0", | ||
@@ -37,5 +39,5 @@ "grunt-shell": "^1.3.0", | ||
"tasks", | ||
"phantomjs" | ||
"chrome" | ||
], | ||
"appveyor_id": "3vd43779joyj6qji" | ||
} |
@@ -1,4 +0,4 @@ | ||
# grunt-contrib-qunit v2.0.0 [![Build Status: Linux](https://travis-ci.org/gruntjs/grunt-contrib-qunit.svg?branch=master)](https://travis-ci.org/gruntjs/grunt-contrib-qunit) [![Build Status: Windows](https://ci.appveyor.com/api/projects/status/3vd43779joyj6qji/branch/master?svg=true)](https://ci.appveyor.com/project/gruntjs/grunt-contrib-qunit/branch/master) | ||
# grunt-contrib-qunit v3.0.0 [![Build Status: Linux](https://travis-ci.org/gruntjs/grunt-contrib-qunit.svg?branch=master)](https://travis-ci.org/gruntjs/grunt-contrib-qunit) [![Build Status: Windows](https://ci.appveyor.com/api/projects/status/3vd43779joyj6qji/branch/master?svg=true)](https://ci.appveyor.com/project/gruntjs/grunt-contrib-qunit/branch/master) | ||
> Run QUnit unit tests in a headless PhantomJS instance | ||
> Run QUnit unit tests in a headless Chrome instance | ||
@@ -27,3 +27,3 @@ | ||
You have chosen to write your unit tests using [QUnit][], you have written a | ||
You have chosen to write your unit tests using [QUnit](http://qunitjs.com/), you have written a | ||
html page which reports the summary and indivudual details of your unit | ||
@@ -35,3 +35,3 @@ tests, you are happy with this but realize you miss the ability to have your | ||
This is where the `grunt-contrib-qunit` plugin comes in the play: | ||
`grunt-contrib-qunit` lets you run your tests in the invisible [PhantomJS][] | ||
`grunt-contrib-qunit` lets you run your tests in the invisible [Chrome][] | ||
browser, thus converting your unit test suite into something you can run | ||
@@ -50,23 +50,16 @@ from a script, a script you can have automatically run on travis-ci (or the | ||
When installed by npm, this plugin will automatically download and install | ||
[PhantomJS][] locally via the [grunt-lib-phantomjs][] library. If your | ||
system already provides the PhantomJS program, this plugin will use the | ||
globally installed program. | ||
When installed by npm, this plugin will automatically download and install a local | ||
[Chrome][] binary within the `node_modules` directory of the [puppeteer][] library, | ||
which is used for launching a Chrome process. If your system already provides an | ||
installation of Chrome, you can configure this plugin to use the globally installed | ||
executable by specifying a custom `executablePath` in the puppeteer launch options. | ||
This will almost certainly be needed in order to run Chrome in a CI environment | ||
[PhantomJS]: http://www.phantomjs.org/ | ||
[grunt-lib-phantomjs]: https://github.com/gruntjs/grunt-lib-phantomjs | ||
[Puppeteer]: https://pptr.dev/ | ||
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. | ||
#### OS Dependencies | ||
This plugin uses PhantomJS to run tests. PhantomJS requires these dependencies | ||
This plugin uses Puppeteer to run tests in a Chrome process. Chrome requires a number of dependencies that must be installed, depending on your OS. | ||
Please see Puppeteer's docs to see the latest docs for what dependencies you need for your OS: | ||
**On Ubuntu/Debian** | ||
`apt-get install libfontconfig1 fontconfig libfontconfig1-dev libfreetype6-dev` | ||
**On CentOS** | ||
`yum install fontconfig freetype` | ||
https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md | ||
### Options | ||
@@ -82,8 +75,8 @@ | ||
Type: `String`|`Array` | ||
Default: `phantomjs/bridge.js` | ||
Default: `chrome/bridge.js` | ||
One or multiple (array) JavaScript file names to inject into the html test page. Defaults to the path of the QUnit-PhantomJS bridge file. | ||
One or multiple (array) JavaScript file names to inject into the html test page. Defaults to the path of the QUnit-Chrome bridge file. | ||
You may want to inject something different than the provided QUnit-PhantomJS bridge, or to inject more than just the provided bridge. | ||
See [the built-in bridge](https://github.com/gruntjs/grunt-contrib-qunit/blob/master/phantomjs/bridge.js) for more information. | ||
You may want to inject something different than the provided QUnit-Chrome bridge, or to inject more than just the provided bridge. | ||
See [the built-in bridge](https://github.com/gruntjs/grunt-contrib-qunit/blob/master/chrome/bridge.js) for more information. | ||
@@ -100,3 +93,3 @@ #### httpBase | ||
Set to false to hide PhantomJS console output. | ||
By default, `console.[log|warn|error]` output from the Chrome browser will be piped into QUnit console. Set to `false` to disable this behavior. | ||
@@ -107,3 +100,3 @@ #### urls | ||
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](https://github.com/gruntjs/grunt-contrib-connect) provides a basic web server. | ||
Absolute `http://` or `https://` urls to be passed to Chrome. 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](https://github.com/gruntjs/grunt-contrib-connect) provides a basic web server. | ||
@@ -122,7 +115,7 @@ #### force | ||
#### (-- PhantomJS arguments) | ||
Type: `String` | ||
Default: (none) | ||
#### puppeteer | ||
Type: `Object` | ||
Default: `{ headless: true }` | ||
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. | ||
Arguments to be used when `puppeteer.launch()` is invoked. This may be useful for specifying a custom Chrome executable path, running in non-headless mode, specifying environment variables to use when launching Chrome, etc. See the [Puppeteer API Reference][https://pptr.dev/#?product=Puppeteer&version=v1.3.0] for a list of launch options that are available. | ||
@@ -154,3 +147,3 @@ #### noGlobals | ||
#### Wildcards | ||
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). | ||
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 [Chrome][] (one at a time). | ||
@@ -167,3 +160,3 @@ ```js | ||
#### Testing via http:// or https:// | ||
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 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 [Chrome][] (one at a time). | ||
@@ -228,6 +221,6 @@ In this example, `grunt qunit` will test two files, served from the server running at `localhost:8000`. | ||
#### Custom timeouts and PhantomJS options | ||
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. | ||
#### Custom timeouts and Puppeteer options | ||
In the following example, the default timeout value of `5000` is overridden with the value `10000` (timeout values are in milliseconds). Custom options to use when launching Puppeteer can be specified using `options.puppeteer`, with all property names corresponding directly to options supported by [`puppeteer.launch()`](https://pptr.dev/#?product=Puppeteer&version=v1.3.0&show=api-puppeteerlaunchoptions). For example, the following configuration sets the TZ environment variable and invokes a custom Chrome executable at "/usr/bin/chromium" | ||
[PhantomJS API Reference]: http://phantomjs.org/api | ||
[Puppeteer API Reference]: https://pptr.dev/ | ||
@@ -240,3 +233,8 @@ ```js | ||
timeout: 10000, | ||
'--cookies-file': 'misc/cookies.txt' | ||
puppeteer: { | ||
env: { | ||
TZ: "UTC" | ||
}, | ||
executablePath: "/usr/bin/chromium" | ||
} | ||
}, | ||
@@ -267,4 +265,4 @@ all: ['test/**/*.html'] | ||
* `qunit.spawn` `(url)`: when [PhantomJS][] is spawned for a test | ||
* `qunit.fail.load` `(url)`: when [PhantomJS][] could not open the given url | ||
* `qunit.spawn` `(url)`: when [Chrome][] is spawned for a test | ||
* `qunit.fail.load` `(url)`: when [Chrome][] could not open the given url | ||
* `qunit.fail.timeout`: when a QUnit test times out, usually due to a missing `QUnit.start()` call | ||
@@ -284,2 +282,3 @@ * `qunit.error.onError` `(message, stackTrace)`: when a JavaScript execution error occurs | ||
* 2018-07-24 v3.0.0 Switch to using headless chrome / puppeteer instead of phantomjs | ||
* 2017-04-04 v2.0.0 Remove usage of `QUnit.jsDump` Upgrade qunitjs to 2.3.0 (#123) adding an Introduction to the README (#140) | ||
@@ -310,2 +309,2 @@ * 2017-02-07 v1.3.0 Add ability to run tests in seeded-random order through `--seed` flag Add note about min version of QUnit required to use the CLI flags Implement support for todo tests and revamp reporting logic (#137) | ||
*This file was generated on Tue Apr 04 2017 22:09:26.* | ||
*This file was generated on Tue Jul 24 2018 17:47:21.* |
@@ -11,14 +11,116 @@ /* | ||
// Nodejs libs. | ||
var fs = require('fs'); | ||
var path = require('path'); | ||
var url = require('url'); | ||
var EventEmitter2 = require('eventemitter2'); | ||
// NPM libs. | ||
var Promise = require('bluebird'); | ||
var puppeteer = require('puppeteer'); | ||
// Shared functions | ||
// Allow an error message to retain its color when split across multiple lines. | ||
function formatMessage (str) { | ||
return String(str).split('\n') | ||
.map(function(s) { | ||
return s.magenta; | ||
}) | ||
.join('\n'); | ||
} | ||
function createStatus () { | ||
return { | ||
passed: 0, | ||
failed: 0, | ||
skipped: 0, | ||
todo: 0, | ||
runtime: 0, | ||
assertions: { | ||
passed: 0, | ||
failed: 0 | ||
} | ||
}; | ||
} | ||
function mergeStatus(statusA, statusB) { | ||
statusA.passed += statusB.passed; | ||
statusA.failed += statusB.failed; | ||
statusA.skipped += statusB.skipped; | ||
statusA.todo += statusB.todo; | ||
statusA.runtime += statusB.runtime; | ||
statusA.assertions.passed += statusB.assertions.passed; | ||
statusA.assertions.failed += statusB.assertions.failed; | ||
} | ||
function generateMessage(status) { | ||
var totalTests = status.passed + status.failed + status.skipped + status.todo; | ||
var totalAssertions = status.assertions.passed + status.assertions.failed; | ||
return [ | ||
totalTests, | ||
' tests completed with ', | ||
status.failed, | ||
' failed, ' + | ||
status.skipped, | ||
' skipped, and ', | ||
status.todo, | ||
' todo. \n' + | ||
totalAssertions, | ||
' assertions (in ', | ||
status.runtime, | ||
'ms), passed: ' + | ||
status.assertions.passed, | ||
', failed: ', | ||
status.assertions.failed | ||
].join(''); | ||
} | ||
// Copied from QUnit source code | ||
function generateHash (module) { | ||
var hex; | ||
var i = 0; | ||
var hash = 0; | ||
var str = module + '\x1C' + undefined; | ||
var len = str.length; | ||
for (; i < len; i++) { | ||
hash = ((hash << 5) - hash) + str.charCodeAt(i); | ||
hash |= 0; | ||
} | ||
// Convert the possibly negative integer hash code into an 8 character | ||
// hex string, which isn't strictly necessary but increases user understanding | ||
// that the id is a SHA-like hash | ||
hex = (0x100000000 + hash).toString(16); | ||
if (hex.length < 8) { | ||
hex = '0000000' + hex; | ||
} | ||
return hex.slice(-8); | ||
} | ||
function getFullUrl(url) { | ||
if ((url.length < 4) || (url.substring(0,4) !== 'http')) { | ||
return 'file://' + path.resolve(__dirname, '..', url); | ||
} else { | ||
return url; | ||
} | ||
} | ||
module.exports = function(grunt) { | ||
// Nodejs libs. | ||
var path = require('path'); | ||
var url = require('url'); | ||
var eventBus = new EventEmitter2({wildcard: true, maxListeners: 0}); | ||
// External lib. | ||
var phantomjs = require('grunt-lib-phantomjs').init(grunt); | ||
// Keep track of the last-started module and test. Additionally, keep track | ||
// of status for individual test files and the entire test suite. | ||
var options, currentModule, currentTest, currentStatus, status; | ||
var options; | ||
var puppeteerLaunchOptions; | ||
var currentModule; | ||
var currentTest; | ||
var currentStatus; | ||
var status; | ||
var browser; | ||
var page; | ||
@@ -31,9 +133,4 @@ // Keep track of the last-started test(s). | ||
// Allow an error message to retain its color when split across multiple lines. | ||
var formatMessage = function(str) { | ||
return String(str).split('\n').map(function(s) { return s.magenta; }).join('\n'); | ||
}; | ||
// If options.force then log an error, otherwise exit with a warning | ||
var warnUnlessForced = function (message) { | ||
function warnUnlessForced (message) { | ||
if (options && options.force) { | ||
@@ -44,7 +141,7 @@ grunt.log.error(message); | ||
} | ||
}; | ||
} | ||
// Keep track of failed assertions for pretty-printing. | ||
var failedAssertions = []; | ||
var logFailedAssertions = function() { | ||
function logFailedAssertions () { | ||
var assertion; | ||
@@ -69,81 +166,11 @@ | ||
} | ||
}; | ||
} | ||
var createStatus = function() { | ||
return { | ||
passed: 0, | ||
failed: 0, | ||
skipped: 0, | ||
todo: 0, | ||
runtime: 0, | ||
assertions: { | ||
passed: 0, | ||
failed: 0 | ||
} | ||
}; | ||
}; | ||
var mergeStatus = function(statusA, statusB) { | ||
statusA.passed += statusB.passed; | ||
statusA.failed += statusB.failed; | ||
statusA.skipped += statusB.skipped; | ||
statusA.todo += statusB.todo; | ||
statusA.runtime += statusB.runtime; | ||
statusA.assertions.passed += statusB.assertions.passed; | ||
statusA.assertions.failed += statusB.assertions.failed; | ||
}; | ||
var generateMessage = function(status) { | ||
var totalTests = status.passed + status.failed + status.skipped + status.todo; | ||
var totalAssertions = status.assertions.passed + status.assertions.failed; | ||
return [ | ||
totalTests, | ||
" tests completed with ", | ||
status.failed, | ||
" failed, " + | ||
status.skipped, | ||
" skipped, and ", | ||
status.todo, | ||
" todo. \n" + | ||
totalAssertions, | ||
" assertions (in ", | ||
status.runtime, | ||
"ms), passed: " + | ||
status.assertions.passed, | ||
", failed: ", | ||
status.assertions.failed | ||
].join( "" ); | ||
}; | ||
// Copied from QUnit source code | ||
var generateHash = function(module) { | ||
var hex; | ||
var i = 0; | ||
var hash = 0; | ||
var str = module + '\x1C' + undefined; | ||
var len = str.length; | ||
for (; i < len; i++) { | ||
hash = ((hash << 5) - hash) + str.charCodeAt(i); | ||
hash |= 0; | ||
} | ||
// Convert the possibly negative integer hash code into an 8 character | ||
// hex string, which isn't strictly necessary but increases user understanding | ||
// that the id is a SHA-like hash | ||
hex = (0x100000000 + hash).toString(16); | ||
if (hex.length < 8) { | ||
hex = '0000000' + hex; | ||
} | ||
return hex.slice(-8); | ||
}; | ||
// QUnit hooks. | ||
phantomjs.on('qunit.begin', function() { | ||
eventBus.on('qunit.begin', function() { | ||
currentStatus = createStatus(); | ||
}); | ||
phantomjs.on('qunit.moduleStart', function(name) { | ||
eventBus.on('qunit.moduleStart', function(name) { | ||
unfinished[name] = true; | ||
@@ -153,7 +180,7 @@ currentModule = name; | ||
phantomjs.on('qunit.moduleDone', function(name/*, failed, passed, total*/) { | ||
eventBus.on('qunit.moduleDone', function(name) { | ||
delete unfinished[name]; | ||
}); | ||
phantomjs.on('qunit.log', function(result, actual, expected, message, source, todo) { | ||
eventBus.on('qunit.log', function(result, actual, expected, message, source, todo) { | ||
if (!result && !todo) { | ||
@@ -170,3 +197,3 @@ failedAssertions.push({ | ||
phantomjs.on('qunit.testStart', function(name) { | ||
eventBus.on('qunit.testStart', function(name) { | ||
currentTest = (currentModule ? currentModule + ' - ' : '') + name; | ||
@@ -176,3 +203,3 @@ grunt.verbose.write(currentTest + '...'); | ||
phantomjs.on('qunit.testDone', function(name, failed, passed, total, runtime, skipped, todo) { | ||
eventBus.on('qunit.testDone', function(name, failed, passed, total, runtime, skipped, todo) { | ||
var testPassed = failed > 0 ? todo : !todo; | ||
@@ -191,22 +218,19 @@ | ||
// Log errors if necessary, otherwise success. | ||
if (!testPassed) { | ||
if (testPassed) { | ||
grunt.verbose.ok().or.write('.'); | ||
// list assertions or message about todo failure | ||
if (grunt.option('verbose')) { | ||
grunt.log.error(); | ||
} else if (grunt.option('verbose')) { | ||
grunt.log.error(); | ||
if (todo) { | ||
grunt.log.error('Expected at least one failing assertion in todo test:' + name); | ||
} else { | ||
logFailedAssertions(); | ||
} | ||
if (todo) { | ||
grunt.log.error('Expected at least one failing assertion in todo test:' + name); | ||
} else { | ||
grunt.log.write('F'.red); | ||
logFailedAssertions(); | ||
} | ||
} else { | ||
grunt.verbose.ok().or.write('.'); | ||
grunt.log.write('F'.red); | ||
} | ||
}); | ||
phantomjs.on('qunit.done', function(failed, passed, total, runtime) { | ||
phantomjs.halt(); | ||
eventBus.on('qunit.done', function(failed, passed, total, runtime) { | ||
@@ -230,4 +254,6 @@ currentStatus.runtime += runtime; | ||
// Re-broadcast qunit events on grunt.event. | ||
phantomjs.on('qunit.*', function() { | ||
eventBus.on('qunit.*', function() { | ||
var args = [this.event].concat(grunt.util.toArray(arguments)); | ||
@@ -238,7 +264,6 @@ grunt.event.emit.apply(grunt.event, args); | ||
// Built-in error handlers. | ||
phantomjs.on('fail.load', function(url) { | ||
phantomjs.halt(); | ||
eventBus.on('fail.load', function(url) { | ||
grunt.verbose.write('...'); | ||
grunt.event.emit('qunit.fail.load', url); | ||
grunt.log.error('PhantomJS unable to load "' + url + '" URI.'); | ||
grunt.log.error('Chrome unable to load \'' + url + '\' URI.'); | ||
@@ -248,7 +273,6 @@ status.failed += 1; | ||
phantomjs.on('fail.timeout', function() { | ||
phantomjs.halt(); | ||
eventBus.on('fail.timeout', function() { | ||
grunt.log.writeln(); | ||
grunt.event.emit('qunit.fail.timeout'); | ||
grunt.log.error('PhantomJS timed out, possibly due to:\n' + | ||
grunt.log.error('Chrome timed out, possibly due to:\n' + | ||
'- QUnit is not loaded correctly.\n- A missing QUnit start() call.\n' + | ||
@@ -260,17 +284,17 @@ '- Or, a misconfiguration of this task.'); | ||
phantomjs.on('error.onError', function (msg, stackTrace) { | ||
eventBus.on('error.onError', function (msg, stackTrace) { | ||
grunt.event.emit('qunit.error.onError', msg, stackTrace); | ||
}); | ||
grunt.registerMultiTask('qunit', 'Run QUnit unit tests in a headless PhantomJS instance.', function() { | ||
grunt.registerMultiTask('qunit', 'Run QUnit unit tests in a headless Chrome instance.', function() { | ||
// Merge task-specific and/or target-specific options with these defaults. | ||
options = this.options({ | ||
// Default PhantomJS timeout. | ||
// Default Chrome timeout. | ||
timeout: 5000, | ||
// QUnit-PhantomJS bridge file to be injected. | ||
inject: asset('phantomjs/bridge.js'), | ||
// QUnit-Chrome bridge file to be injected. | ||
inject: asset('chrome/bridge.js'), | ||
// Explicit non-file URLs to test. | ||
urls: [], | ||
force: false, | ||
// Connect phantomjs console output to grunt output | ||
// Connect Chrome console output to Grunt output | ||
console: true, | ||
@@ -281,7 +305,17 @@ // Do not use an HTTP base by default | ||
}); | ||
puppeteerLaunchOptions = options.puppeteer || {}; | ||
// This task is asynchronous. | ||
var done = this.async(); | ||
var urls; | ||
var bridgeFile = fs.readFileSync(options.inject, 'utf8'); | ||
if (!bridgeFile) { | ||
grunt.fail.fatal('Could not load the specified Chrome/QUnit bridge file.'); | ||
done(false); | ||
return; | ||
} | ||
if (options.httpBase) { | ||
//If URLs are explicitly referenced, use them still | ||
// If URLs are explicitly referenced, use them still | ||
urls = options.urls; | ||
@@ -297,3 +331,13 @@ // Then create URLs for the src files | ||
var appendToUrls = function(queryParam, value) { | ||
// The final tasks to run before terminating the task | ||
function finishTask(success) { | ||
// Close the puppeteer browser | ||
if (browser) { | ||
browser.close(); | ||
} | ||
// Finish the task | ||
done(success); | ||
} | ||
function appendToUrls (queryParam, value) { | ||
// Append the query param to all urls | ||
@@ -306,3 +350,3 @@ urls = urls.map(function(testUrl) { | ||
}); | ||
}; | ||
} | ||
@@ -328,61 +372,106 @@ if (options.noGlobals) { | ||
// This task is asynchronous. | ||
var done = this.async(); | ||
// Reset status. | ||
status = createStatus(); | ||
// Pass-through console.log statements. | ||
if(options.console) { | ||
phantomjs.on('console', console.log.bind(console)); | ||
} | ||
// Instantiate headless browser | ||
puppeteer.launch(Object.assign({ | ||
headless: true, | ||
}, puppeteerLaunchOptions)) | ||
.then(function(b) { | ||
browser = b; | ||
return b.newPage(); | ||
}) | ||
.then(function(p) { | ||
page = p; | ||
// emit events published in bridge.js. | ||
// This function exposure survives url navigations. | ||
return page.exposeFunction('__grunt_contrib_qunit__', function() { | ||
eventBus.emit.apply(eventBus, [].slice.call(arguments)); | ||
}); | ||
}) | ||
.then(function() { | ||
// Pass through the console logs if instructed | ||
if (options.console) { | ||
page.on('console', function() { | ||
var args = [].slice.apply(arguments); | ||
var colors = { | ||
'error': 'red', | ||
'warning': 'yellow' | ||
}; | ||
for (var i = 0; i < args.length; ++i) { | ||
var txt = args[i].text(); | ||
var color = colors[args[i].type()]; | ||
grunt.log.writeln(color ? txt[color] : txt); | ||
} | ||
}); | ||
} | ||
// Process each filepath in-order. | ||
grunt.util.async.forEachSeries(urls, function(url, next) { | ||
grunt.verbose.subhead('Testing ' + url + ' ').or.write('Testing ' + url + ' '); | ||
// Surface uncaught exceptions | ||
page.on('pageerror', function() { | ||
var args = [].slice.apply(arguments); | ||
for (var i = 0; i < args.length; i++) { | ||
eventBus.emit('error.onError', args[i]); | ||
} | ||
}); | ||
// Reset current module. | ||
currentModule = null; | ||
// Whenever a page is loaded with a new document, before scripts execute, inject the bridge file. | ||
// Tell the client that when DOMContentLoaded fires, it needs to tell this | ||
// script to inject the bridge. This should ensure that the bridge gets | ||
// injected before any other DOMContentLoaded or window.load event handler. | ||
page.evaluateOnNewDocument('if (window.QUnit) {\n' + bridgeFile + '\n} else {\n' + 'document.addEventListener("DOMContentLoaded", function() {\n' + bridgeFile + '\n});\n}\n'); | ||
// Launch PhantomJS. | ||
grunt.event.emit('qunit.spawn', url); | ||
phantomjs.spawn(url, { | ||
// Additional PhantomJS options. | ||
options: options, | ||
// Do stuff when done. | ||
done: function(err) { | ||
if (err) { | ||
// If there was an error, abort the series. | ||
done(); | ||
} else { | ||
// Otherwise, process next url. | ||
next(); | ||
} | ||
}, | ||
}); | ||
}, | ||
// All tests have been run. | ||
function() { | ||
var message = generateMessage(status); | ||
var success; | ||
return Promise.mapSeries(urls, function(url) { | ||
// Reset current module. | ||
currentModule = null; | ||
grunt.event.emit('qunit.spawn', url); | ||
grunt.verbose.subhead('Testing ' + url + ' ').or.write('Testing ' + url + ' '); | ||
// Log results. | ||
if (status.failed > 0) { | ||
warnUnlessForced(message); | ||
} else { | ||
grunt.verbose.writeln(); | ||
grunt.log.ok(message); | ||
} | ||
return Promise.all([ | ||
// Setup listeners for qunit.done / fail events | ||
new Promise(function(resolve, reject) { | ||
eventBus.once('qunit.done', function() { | ||
setTimeout(resolve, 1); | ||
}); | ||
eventBus.once('fail.*', function() { | ||
setTimeout(function() { | ||
reject(url); | ||
}, 1); | ||
}); | ||
}), | ||
// Navigate to the url to be tested | ||
page.goto(getFullUrl(url), { | ||
timeout: options.timeout | ||
}) | ||
]); | ||
}); | ||
}) | ||
.then(function() { | ||
// All tests have been run. | ||
var message = generateMessage(status); | ||
var success; | ||
if (options && options.force) { | ||
success = true; | ||
} else { | ||
success = status.failed === 0; | ||
} | ||
// Log results. | ||
if (status.failed > 0) { | ||
warnUnlessForced(message); | ||
} else { | ||
grunt.verbose.writeln(); | ||
grunt.log.ok(message); | ||
} | ||
// All done! | ||
done(success); | ||
}); | ||
if (options && options.force) { | ||
success = true; | ||
} else { | ||
success = status.failed === 0; | ||
} | ||
// All done! | ||
finishTask(success); | ||
}) | ||
.catch(function(err) { | ||
// If anything goes wrong, terminate the grunt task | ||
grunt.log.error("There was an error with headless chrome"); | ||
grunt.fail.fatal(err); | ||
finishTask(false); | ||
}); | ||
}); | ||
}; |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
33100
457
3
297
3
1
+ Addedbluebird@^3.5.1
+ Addedeventemitter2@^5.0.1
+ Addedpuppeteer@1.3.x
+ Addedagent-base@4.3.0(transitive)
+ Addedasync-limiter@1.0.1(transitive)
+ Addedbluebird@3.7.2(transitive)
+ Addeddebug@3.2.7(transitive)
+ Addedes6-promisify@5.0.0(transitive)
+ Addedeventemitter2@5.0.1(transitive)
+ Addedhttps-proxy-agent@2.2.4(transitive)
+ Addedmime@1.6.0(transitive)
+ Addedms@2.1.3(transitive)
+ Addedprogress@2.0.3(transitive)
+ Addedproxy-from-env@1.1.0(transitive)
+ Addedpuppeteer@1.3.0(transitive)
+ Addedultron@1.1.1(transitive)
+ Addedws@3.3.3(transitive)
- Removedgrunt-lib-phantomjs@^1.0.0
- Removedajv@6.12.6(transitive)
- Removedasn1@0.2.6(transitive)
- Removedassert-plus@1.0.0(transitive)
- Removedasynckit@0.4.0(transitive)
- Removedaws-sign2@0.7.0(transitive)
- Removedaws4@1.13.2(transitive)
- Removedbcrypt-pbkdf@1.0.2(transitive)
- Removedcaseless@0.12.0(transitive)
- Removedcombined-stream@1.0.8(transitive)
- Removedcore-util-is@1.0.2(transitive)
- Removeddashdash@1.14.1(transitive)
- Removeddelayed-stream@1.0.0(transitive)
- Removedecc-jsbn@0.1.2(transitive)
- Removedeventemitter2@0.4.14(transitive)
- Removedextend@3.0.2(transitive)
- Removedextsprintf@1.3.0(transitive)
- Removedfast-deep-equal@3.1.3(transitive)
- Removedfast-json-stable-stringify@2.1.0(transitive)
- Removedforever-agent@0.6.1(transitive)
- Removedform-data@2.3.3(transitive)
- Removedfs-extra@1.0.0(transitive)
- Removedgetpass@0.1.7(transitive)
- Removedgraceful-fs@4.2.11(transitive)
- Removedgrunt-lib-phantomjs@1.1.0(transitive)
- Removedhar-schema@2.0.0(transitive)
- Removedhar-validator@5.1.5(transitive)
- Removedhasha@2.2.0(transitive)
- Removedhttp-signature@1.2.0(transitive)
- Removedis-stream@1.1.0(transitive)
- Removedis-typedarray@1.0.0(transitive)
- Removedisexe@2.0.0(transitive)
- Removedisstream@0.1.2(transitive)
- Removedjsbn@0.1.1(transitive)
- Removedjson-schema@0.4.0(transitive)
- Removedjson-schema-traverse@0.4.1(transitive)
- Removedjson-stringify-safe@5.0.1(transitive)
- Removedjsonfile@2.4.0(transitive)
- Removedjsprim@1.4.2(transitive)
- Removedkew@0.7.0(transitive)
- Removedklaw@1.3.1(transitive)
- Removedmime-db@1.52.0(transitive)
- Removedmime-types@2.1.35(transitive)
- Removedoauth-sign@0.9.0(transitive)
- Removedpackage@1.0.1(transitive)
- Removedperformance-now@2.1.0(transitive)
- Removedphantomjs-prebuilt@2.1.16(transitive)
- Removedpinkie@2.0.4(transitive)
- Removedpinkie-promise@2.0.1(transitive)
- Removedprogress@1.1.8(transitive)
- Removedpsl@1.9.0(transitive)
- Removedpunycode@2.3.1(transitive)
- Removedqs@6.5.3(transitive)
- Removedrequest@2.88.2(transitive)
- Removedrequest-progress@2.0.1(transitive)
- Removedsafer-buffer@2.1.2(transitive)
- Removedsemver@5.7.2(transitive)
- Removedsshpk@1.18.0(transitive)
- Removedtemporary@0.0.8(transitive)
- Removedthrottleit@1.0.1(transitive)
- Removedtough-cookie@2.5.0(transitive)
- Removedtunnel-agent@0.6.0(transitive)
- Removedtweetnacl@0.14.5(transitive)
- Removeduri-js@4.4.1(transitive)
- Removeduuid@3.4.0(transitive)
- Removedverror@1.10.0(transitive)
- Removedwhich@1.3.1(transitive)