| OLD | NEW |
| (Empty) |
| 1 (function() { | |
| 2 | |
| 3 var files; | |
| 4 var browserId; | |
| 5 | |
| 6 var socketEndpoint = window.location.protocol + '//' + window.location.host; | |
| 7 var thisFile = 'ci-support.js'; | |
| 8 var thisScript = document.querySelector('script[src$="' + thisFile + '"]'); | |
| 9 var base = thisScript.src.substring(0, thisScript.src.lastIndexOf('/')+1); | |
| 10 | |
| 11 var tools = { | |
| 12 'mocha-tdd': [ | |
| 13 base + 'mocha/mocha.css', | |
| 14 base + 'mocha/mocha.js', | |
| 15 base + 'mocha-htmltest.js', | |
| 16 function() { | |
| 17 var div = document.createElement('div'); | |
| 18 div.id = 'mocha'; | |
| 19 document.body.appendChild(div); | |
| 20 mocha.setup({ui: 'tdd', slow: 1000, timeout: 10000, htmlbase: ''}); | |
| 21 } | |
| 22 ], | |
| 23 'chai': [ | |
| 24 base + 'chai/chai.js' | |
| 25 ] | |
| 26 }; | |
| 27 | |
| 28 function addFile() { | |
| 29 var file = files.shift(); | |
| 30 if (Object.prototype.toString.call(file) == '[object Function]') { | |
| 31 file(); | |
| 32 nextFile(); | |
| 33 } | |
| 34 else if (file.slice(-3) == '.js') { | |
| 35 var script = document.createElement('script'); | |
| 36 script.src = file; | |
| 37 script.onload = nextFile; | |
| 38 script.onerror = function() { console.error('Could not load ' + script.src
); }; | |
| 39 document.head.appendChild(script); | |
| 40 } else if (file.slice(-4) == '.css') { | |
| 41 var sheet = document.createElement('link'); | |
| 42 sheet.rel = 'stylesheet'; | |
| 43 sheet.href = file; | |
| 44 document.head.appendChild(sheet); | |
| 45 nextFile(); | |
| 46 } | |
| 47 } | |
| 48 | |
| 49 function nextFile() { | |
| 50 if (files.length) { | |
| 51 addFile(); | |
| 52 } else { | |
| 53 startMocha(); | |
| 54 } | |
| 55 } | |
| 56 | |
| 57 function getQueryVariable(variable) { | |
| 58 var query = window.location.search.substring(1); | |
| 59 var vars = query.split("&"); | |
| 60 for (var i=0;i<vars.length;i++) { | |
| 61 var pair = vars[i].split("="); | |
| 62 if (pair[0] == variable) { | |
| 63 return pair[1]; | |
| 64 } | |
| 65 } | |
| 66 return(false); | |
| 67 } | |
| 68 | |
| 69 function runTests(setup) { | |
| 70 browserId = getQueryVariable('browser'); | |
| 71 files = []; | |
| 72 | |
| 73 if (browserId) { | |
| 74 files.push(socketEndpoint + '/socket.io/socket.io.js'); | |
| 75 } | |
| 76 | |
| 77 if (typeof setup == 'string') { | |
| 78 var xhr = new XMLHttpRequest(); | |
| 79 xhr.open('GET', setup); | |
| 80 xhr.responseType = 'application/json'; | |
| 81 xhr.send(); | |
| 82 xhr.onreadystatechange = function() { | |
| 83 if (xhr.readyState == 4) { | |
| 84 setupTests(JSON.parse(xhr.response)); | |
| 85 } | |
| 86 }; | |
| 87 } else { | |
| 88 setupTests(setup); | |
| 89 } | |
| 90 } | |
| 91 | |
| 92 function setupTests(setup) { | |
| 93 if (setup.tools) { | |
| 94 setup.tools.forEach(function(tool) { | |
| 95 if (tools[tool]) { | |
| 96 files = files.concat(tools[tool]); | |
| 97 } else { | |
| 98 console.error('Unknown tool: ' + tool); | |
| 99 } | |
| 100 }); | |
| 101 } | |
| 102 if (setup.dependencies) { | |
| 103 files = files.concat(setup.dependencies.map(function(d) { | |
| 104 return '../' + d; | |
| 105 })); | |
| 106 } | |
| 107 files = files.concat(setup.tests); | |
| 108 nextFile(); | |
| 109 } | |
| 110 | |
| 111 function startMocha() { | |
| 112 var runner = mocha.run(); | |
| 113 | |
| 114 var socket; | |
| 115 if (browserId) { | |
| 116 socket = io(socketEndpoint); | |
| 117 } | |
| 118 | |
| 119 var emitEvent = function(event, data) { | |
| 120 var payload = {browserId: browserId, event: event, data: data}; | |
| 121 console.log('client-event:', payload); | |
| 122 if (!socket) return; | |
| 123 socket.emit('client-event', payload); | |
| 124 }; | |
| 125 | |
| 126 var getTitles = function(runnable) { | |
| 127 var titles = []; | |
| 128 while (runnable && runnable.title) { | |
| 129 titles.unshift(runnable.title); | |
| 130 runnable = runnable.parent; | |
| 131 } | |
| 132 return titles; | |
| 133 }; | |
| 134 | |
| 135 var getState = function(runnable) { | |
| 136 if (runnable.state === 'passed') { | |
| 137 return 'passing'; | |
| 138 } else if (runnable.state == 'failed') { | |
| 139 return 'failing'; | |
| 140 } else if (runnable.pending) { | |
| 141 return 'pending'; | |
| 142 } else { | |
| 143 return 'unknown'; | |
| 144 } | |
| 145 }; | |
| 146 | |
| 147 var cleanError = function(error) { | |
| 148 if (!error) return undefined; | |
| 149 return {message: error.message, stack: error.stack}; | |
| 150 }; | |
| 151 | |
| 152 // the runner's start event has already fired. | |
| 153 emitEvent('browser-start', { | |
| 154 total: runner.total, | |
| 155 url: window.location.toString(), | |
| 156 }); | |
| 157 | |
| 158 // We only emit a subset of events that we care about, and follow a more | |
| 159 // general event format that is hopefully applicable to test runners beyond | |
| 160 // mocha. | |
| 161 // | |
| 162 // For all possible mocha events, see: | |
| 163 // https://github.com/visionmedia/mocha/blob/master/lib/runner.js#L36 | |
| 164 runner.on('test', function(test) { | |
| 165 emitEvent('test-start', {test: getTitles(test)}); | |
| 166 }); | |
| 167 runner.on('test end', function(test) { | |
| 168 emitEvent('test-end', { | |
| 169 state: getState(test), | |
| 170 test: getTitles(test), | |
| 171 duration: test.duration, | |
| 172 error: cleanError(test.err), | |
| 173 }); | |
| 174 }); | |
| 175 runner.on('end', function() { | |
| 176 emitEvent('browser-end'); | |
| 177 }); | |
| 178 } | |
| 179 | |
| 180 window.runTests = runTests; | |
| 181 })(); | |
| OLD | NEW |