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