]> git.proxmox.com Git - mirror_novnc.git/blob - tests/run_from_console.js
Support Skipped Tests and Fix JSHint Issues
[mirror_novnc.git] / tests / run_from_console.js
1 #!/usr/bin/env node
2 var ansi = require('ansi');
3 var program = require('commander');
4 var path = require('path');
5
6 var make_list = function(val) {
7 return val.split(',');
8 };
9
10 program
11 .option('-t, --tests <testlist>', 'Run the specified html-file-based test(s). \'testlist\' should be a comma-separated list', make_list, [])
12 .option('-a, --print-all', 'Print all tests, not just the failures')
13 .option('--disable-color', 'Explicitly disable color')
14 .option('-c, --color', 'Explicitly enable color (default is to use color when not outputting to a pipe)')
15 .option('-i, --auto-inject <includefiles>', 'Treat the test list as a set of mocha JS files, and automatically generate HTML files with which to test test. \'includefiles\' should be a comma-separated list of paths to javascript files to include in each of the generated HTML files', make_list, null)
16 .option('-p, --provider <name>', 'Use the given provider (defaults to "casper"). Currently, may be "casper" or "zombie"', 'casper')
17 .option('-g, --generate-html', 'Instead of running the tests, just return the path to the generated HTML file, then wait for user interaction to exit (should be used with -i)')
18 .option('-o, --output-html', 'Instead of running the tests, just output the generated HTML source to STDOUT (should be used with -i)')
19 .option('-d, --debug', 'Show debug output (the "console" event) from the provider')
20 .parse(process.argv);
21
22 var file_paths = [];
23
24 if (program.autoInject) {
25 var temp = require('temp');
26 var fs = require('fs');
27 temp.track();
28
29 var template = {
30 header: "<html>\n<head>\n<meta charset='utf-8' />\n<link rel='stylesheet' href='" + path.resolve(__dirname, 'node_modules/mocha/mocha.css') + "'/>\n</head>\n<body><div id='mocha'></div>",
31 script_tag: function(p) { return "<script src='" + p + "'></script>"; },
32 footer: "<script>\nmocha.checkLeaks();\nmocha.globals(['navigator', 'create', 'ClientUtils', '__utils__']);\nmocha.run();\n</script>\n</body>\n</html>"
33 };
34
35 template.header += "\n" + template.script_tag(path.resolve(__dirname, 'node_modules/chai/chai.js'));
36 template.header += "\n" + template.script_tag(path.resolve(__dirname, 'node_modules/mocha/mocha.js'));
37 template.header += "\n" + template.script_tag(path.resolve(__dirname, 'node_modules/sinon/pkg/sinon.js'));
38 template.header += "\n" + template.script_tag(path.resolve(__dirname, 'node_modules/sinon-chai/lib/sinon-chai.js'));
39 template.header += "\n<script>mocha.setup('bdd');</script>";
40
41
42 template.header = program.autoInject.reduce(function(acc, sn) {
43 return acc + "\n" + template.script_tag(path.resolve(process.cwd(), sn));
44 }, template.header);
45
46 file_paths = program.tests.map(function(jsn, ind) {
47 var templ = template.header;
48 templ += "\n";
49 templ += template.script_tag(path.resolve(process.cwd(), jsn));
50 templ += template.footer;
51
52 var tempfile = temp.openSync({ prefix: 'novnc-zombie-inject-', suffix: '-file_num-'+ind+'.html' });
53 fs.writeSync(tempfile.fd, templ);
54 fs.closeSync(tempfile.fd);
55 return tempfile.path;
56 });
57
58 }
59 else {
60 file_paths = program.tests.map(function(fn) {
61 return path.resolve(process.cwd(), fn);
62 });
63 }
64
65 var use_ansi = false;
66 if (program.color) use_ansi = true;
67 else if (program.disableColor) use_ansi = false;
68 else if (process.stdout.isTTY) use_ansi = true;
69
70 var cursor = ansi(process.stdout, { enabled: use_ansi });
71
72 if (program.outputHtml) {
73 var fs = require('fs');
74 file_paths.forEach(function(path, path_ind) {
75 fs.readFile(path, function(err, data) {
76 if (err) {
77 console.warn(error.stack);
78 return;
79 }
80
81 cursor
82 .bold()
83 .write(program.tests[path_ind])
84 .reset()
85 .write("\n")
86 .write(Array(program.tests[path_ind].length+1).join('='))
87 .write("\n\n")
88 .write(data)
89 .write("\n");
90 });
91 });
92 }
93
94 if (program.generateHtml) {
95 file_paths.forEach(function(path, path_ind) {
96 cursor
97 .bold()
98 .write(program.tests[path_ind])
99 .write(": ")
100 .reset()
101 .write(path)
102 .write("\n");
103 });
104 console.log('');
105 }
106
107 if (program.generateHtml) {
108 process.stdin.resume(); // pause until C-c
109 process.on('SIGINT', function() {
110 process.stdin.pause(); // exit
111 });
112 }
113
114 if (!program.outputHtml && !program.generateHtml) {
115 var failure_count = 0;
116
117 var prov = require(path.resolve(__dirname, 'run_from_console.'+program.provider+'.js'));
118
119 cursor
120 .write("Running tests ")
121 .bold()
122 .write(program.tests.join(', '))
123 .reset()
124 .grey()
125 .write(' using provider '+prov.name)
126 .reset()
127 .write("\n");
128 //console.log("Running tests %s using provider %s", program.tests.join(', '), prov.name);
129
130 var provider = prov.provide_emitter(file_paths);
131 provider.on('test_ready', function(test_json) {
132 console.log('');
133
134 filename = program.tests[test_json.file_ind];
135
136 cursor.bold();
137 console.log('Results for %s:', filename);
138 console.log(Array('Results for :'.length+filename.length+1).join('='));
139 cursor.reset();
140
141 console.log('');
142
143 cursor
144 .write(''+test_json.num_tests+' tests run, ')
145 .green()
146 .write(''+test_json.num_passes+' passed');
147 if (test_json.num_slow > 0) {
148 cursor
149 .reset()
150 .write(' (');
151 cursor
152 .yellow()
153 .write(''+test_json.num_slow+' slow')
154 .reset()
155 .write(')');
156 }
157 cursor
158 .reset()
159 .write(', ');
160 cursor
161 .red()
162 .write(''+test_json.num_fails+' failed');
163 if (test_json.num_skipped > 0) {
164 cursor
165 .reset()
166 .write(', ')
167 .grey()
168 .write(''+test_json.num_skipped+' skipped');
169 }
170 cursor
171 .reset()
172 .write(' -- duration: '+test_json.duration+"s\n");
173
174 console.log('');
175
176 if (test_json.num_fails > 0 || program.printAll) {
177 var traverse_tree = function(indentation, node) {
178 if (node.type == 'suite') {
179 if (!node.has_subfailures && !program.printAll) return;
180
181 if (indentation === 0) {
182 cursor.bold();
183 console.log(node.name);
184 console.log(Array(node.name.length+1).join('-'));
185 cursor.reset();
186 }
187 else {
188 cursor
189 .write(Array(indentation+3).join('#'))
190 .bold()
191 .write(' '+node.name+' ')
192 .reset()
193 .write(Array(indentation+3).join('#'))
194 .write("\n");
195 }
196
197 console.log('');
198
199 for (var i = 0; i < node.children.length; i++) {
200 traverse_tree(indentation+1, node.children[i]);
201 }
202 }
203 else {
204 if (!node.pass) {
205 cursor.magenta();
206 console.log('- failed: '+node.text+test_json.replay);
207 cursor.red();
208 console.log(' '+node.error.split("\n")[0]); // the split is to avoid a weird thing where in PhantomJS where we get a stack trace too
209 cursor.reset();
210 console.log('');
211 }
212 else if (program.printAll) {
213 if (node.skipped) {
214 cursor
215 .grey()
216 .write('- skipped: '+node.text);
217 }
218 else {
219 if (node.slow) cursor.yellow();
220 else cursor.green();
221
222 cursor
223 .write('- pass: '+node.text)
224 .grey()
225 .write(' ('+node.duration+') ');
226 }
227 /*if (node.slow) cursor.yellow();
228 else cursor.green();*/
229 cursor
230 //.write(test_json.replay)
231 .reset()
232 .write("\n");
233 console.log('');
234 }
235 }
236 };
237
238 for (var i = 0; i < test_json.suites.length; i++) {
239 traverse_tree(0, test_json.suites[i]);
240 }
241 }
242
243 if (test_json.num_fails === 0) {
244 cursor.fg.green();
245 console.log('all tests passed :-)');
246 cursor.reset();
247 }
248 });
249
250 if (program.debug) {
251 provider.on('console', function(line) {
252 console.log(line);
253 });
254 }
255
256 /*gprom.finally(function(ph) {
257 ph.exit();
258 // exit with a status code that actually gives information
259 if (program.exitWithFailureCount) process.exit(failure_count);
260 });*/
261 }