Skip to content

Instantly share code, notes, and snippets.

@oliveiraev
Last active December 26, 2015 05:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save oliveiraev/7103110 to your computer and use it in GitHub Desktop.
Save oliveiraev/7103110 to your computer and use it in GitHub Desktop.
Convert Jasmine suite into parseable CasperJS test suite.
/**
* Convert Jasmine suite into parseable CasperJS test suite.
*/
casper.parseJasmineTests = (function (casper) {
"use strict";
/**
* Build a structure from Jasmine test results.
*
* Each spec generates an object with two keys: specs and tests.
* Specs contains another object with sub-spectations.
* Tests maintain an array with spec test results.
*
* @returns {Object} Object.specName = {specs: {}, tests[]}
*/
function getJasmineResult() {
var reporter, results, output;
/**
* Find out the suite name starting from given element.
*
* Raise up the DOM tree, looking for DIV.suite elements. Each found
* element represent a spec level.
*
* @param {Node,HTMLDocument,HTMLElement} element Usually, an
* a.description element.
* @returns {Array} The text of all the DIV.suite > A.description
* elements found.
*/
function getSuiteFrom(element) {
var suite, child;
suite = [];
while (element.parentNode) {
child = element.getElementsByClassName("description")[0];
if (/suite/.test(element.className)) {
suite.unshift(child.innerHTML);
}
element = element.parentNode;
}
return suite;
}
/**
* Process a detail element.
*
* The function asks for the whole suite name tree and, if a test
* result, append the result to the outputs.
*
* @param {HTMLAnchorElement} element On most cases, the element will
* contain a test result. But it can be the suite name too.
*/
function parse(element) {
var suite, name, spec;
spec = output;
suite = getSuiteFrom(element);
while (suite.length) {
name = suite.shift();
if (!spec[name]) {
spec[name] = {"specs": {}, "tests": []};
}
if (suite.length) {
spec = spec[name].specs;
}
}
if (!(name && element.parentNode.className.match(/^spec/))) {
return;
}
spec[name].tests.push([
element.innerHTML,
/passed/.test(element.parentNode.className)
]);
}
reporter = document.getElementsByClassName("jasmine_reporter")[0];
results = reporter.getElementsByClassName("description");
output = {};
Array.prototype.slice.apply(results).map(parse);
return output;
}
/**
* Convert the Jasmine output into CasperJS suites.
*
* Grabs the object generated by getJasmineResult(), iterates over it and
* adds specs as CasperJS spectations and tests as CasperJS assertions.
*
* @param {Object} jasmineResult A {specs: {}, tests: []} set. It may be
* generated with getJasmineResult().
* @param {String} parentName Any text that should be prepended to the
* spec title. It exists because CasperJS doesn't nest specs like Jasmine.
* With parentName, we can create an output like "# SuperSpec > SubSpec".
*/
function jasmineToCasper(jasmineResult, parentName) {
var specName;
/**
* Starts a CasperJS spec.
*
* This function shouldn't be passed as casper.test.begin() callback. It
* is the responsible for the begin() calls and passes its own callback,
* the runSuite function.
*
* @param {String} specName The text that will be output as CasperJS
* spec.
*/
function begin(specName) {
var suite;
/**
* Performs assertions over the Jasmine tests.
*
* It iterates over the specName.tests array asserting that the 2nd
* item evaluates to true. It happens if the Jasmine expectation
* passed. This approach ensures that failed Jasmine tests also fail
* the CasperJS suite.
*
* @param {Casper.Tester} tester The Tester instance passed to
* callback on test.begin() calls.
*/
function runSuite(tester) {
function runTest(test) {
tester.assert(test[1], test[0]);
}
suite.tests.map(runTest);
tester.done();
}
suite = jasmineResult[specName];
if (parentName) {
specName = parentName + " > " + specName;
}
// Empty suites causes CasperJS to fail.
if (suite.tests.length) {
casper.test.begin(specName, runSuite);
}
jasmineToCasper(suite.specs, specName);
}
for (specName in jasmineResult) {
if (jasmineResult.hasOwnProperty(specName)) {
begin(specName);
}
}
}
return function () {
jasmineToCasper(casper.evaluate(getJasmineResult), null);
}
}(casper));
@oliveiraev
Copy link
Author

Rev #2: It should now works with TrivialReporter too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment