Last active
December 26, 2015 05:49
-
-
Save oliveiraev/7103110 to your computer and use it in GitHub Desktop.
Convert Jasmine suite into parseable CasperJS test suite.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Rev #2: It should now works with TrivialReporter too.