e9bf784f41777c5168695a1f73e8bf72ab7d9b7a
[mkws-moved-to-github.git] / test / phantom / run-jasmine.js
1 /*
2     Fetch a mkws/jasmine based page into node.js, evaluate the page and check if test status
3     This should make it possible to run the test on the command line in jenkins.  e.g.:
4
5       phantomjs evaluate.js https://mkws-dev.indexdata.com/jasmine-local-popup.html
6 */
7
8 var page = require('webpage').create(),
9     system = require('system');
10
11 if (system.args.length === 1) {
12     console.log('Usage: screenshot.js <some URL>');
13     phantom.exit();
14 }
15 var url = system.args[1];
16
17 var run_time = 8; // poll up to seconds
18 if (system.args[2] && parseFloat(system.args[2]) > 0) {
19     run_time = parseFloat(system.args[2]);
20 }
21
22 page.viewportSize = {
23     width: 1200,
24     height: 1000
25 };
26
27 // 0: silent, 1: some infos,  2: display console.log() output
28 var debug = 2;
29 if (typeof system.env['DEBUG'] != 'undefined' && parseInt(system.env['DEBUG']) != NaN) {
30     debug = system.env['DEBUG'];
31     if (debug > 0) console.log("reset debug level to: " + debug);
32 }
33
34 /************************/
35
36 function wait_for_jasmine(checkFx, readyFx, failFx, timeout) {
37     var max_timeout = timeout ? timeout : run_time * 1000,
38         start = new Date().getTime(),
39         result, condition = false;
40
41     var interval = setInterval(function () {
42         if (debug == 1) console.log(".");
43
44         // done
45         if (condition) {
46             clearInterval(interval);
47             result.time = (new Date().getTime() - start);
48             result.failed ? failFx(result) : readyFx(result);
49
50             // See: https://github.com/ariya/phantomjs/issues/12697
51             // phantomjs 1.9.8
52             page.close();
53             setTimeout(function(){ phantom.exit(result.failed == 0 ? 0 : 2); }, 0);
54         }
55
56         // timeout
57         else if (new Date().getTime() - start >= max_timeout) {
58             result.time = (new Date().getTime() - start);
59             failFx(result);
60             phantom.exit(1);
61         }
62
63         // checking
64         else {
65             result = checkFx();
66             if (result) condition = result.done;
67         }
68
69     }, 500); //< repeat check every N ms
70 };
71
72 function dump_html(file) {
73     // not yet implemented
74     var spawn = require('child_process').spawn,
75         lynx = spawn("lynx", ["-nolist", "-dump", file]);
76
77     lynx.stdout.on('data', function (data) {
78         console.log('lynx >> ' + data);
79     });
80
81     // lynx.stderr.on('data', function (data) { console.log('stderr: ' + data); });
82     // lynx.on('close', function (code) { console.log('child process exited with code ' + code) });
83 };
84
85 // redirect webkit console.log() output
86 page.onConsoleMessage = function (message) {
87     if (debug >= 2) console.log(message);
88 };
89
90 // cat webkit alert()
91 page.onAlert = function (msg) {
92     console.log("Alert: " + msg);
93 };
94
95 // display HTTP errors
96 page.onResourceError = function (resourceError) {
97     // console.log('phantomjs error code: ' + resourceError.errorCode);
98     console.log(resourceError.errorString);
99     phantom.exit(3);
100 };
101
102 page.open(url, function (status) {
103     if (debug >= 1) console.log("fetch " + url + " with status: " + status);
104
105     if (status != 'success') {
106         console.log("Failed to fetch page, give up. Network error?");
107         phantom.exit(1);
108     }
109
110     if (debug >= 1) console.log("polling MKWS jasmine test status for " + run_time + " seconds");
111
112
113     var exit = wait_for_jasmine(function () {
114         return page.evaluate(function () {
115             if (!window || !window.mkws || !window.mkws.$) {
116                 console.log("No window object found");
117                 return false;
118             }
119
120             var $ = window.mkws.$;
121             var error_msg = [""];
122             var passing = $(".passingAlert").text() || $(".failingAlert").text();
123
124             // extract failed tests
125             var list = $('.results > #details > .specDetail.failed');
126             if (list && list.length > 0) {
127                 error_msg.push("==> " + list.length + ' test(s) FAILED:');
128                 for (i = 0; i < list.length; ++i) {
129                     var el = list[i],
130                         desc = el.querySelector('.description'),
131                         msg = el.querySelector('.resultMessage.fail');
132                     error_msg.push($(desc).text());
133                     error_msg.push($(msg).text());
134                 }
135             }
136
137             return {
138                 mkws: window.mkws,
139                 done: $('.symbolSummary .pending').length == 0,
140                 html: $("html").html(),
141                 duration: $(".duration").text(),
142                 error_msg: error_msg,
143                 failed: (list.length > 0 || !passing),
144                 passing: passing
145             };
146         })
147     },
148
149     function (result) {
150         if (debug < 1) return;
151
152         console.log("");
153         console.log("MKWS tests are successfully done in " + result.time / 1000 + " seconds. Hooray!");
154         console.log("jasmine duration: " + result.duration);
155         console.log("jasmine passing: " + result.passing);
156     },
157
158     function (result) {
159         var error_png = "./mkws-error.png";
160         var error_html = "./mkws-error.html";
161
162         var html = result.html + "\n\n<!-- mkws: " + JSON.stringify(result.mkws) + " -->\n";
163         var fs = require('fs');
164         fs.write(error_html, html, "wb");
165         dump_html(error_html);
166
167         console.log("MKWS tests failed after " + result.time / 1000 + " seconds");
168         console.log(result.error_msg.join("\n"));
169         console.log("keep screenshot in '" + error_png + "'");
170         page.render(error_png);
171
172         console.log("keep html DOM in '" + error_html + "'");
173         // console.log("you may run: lynx -nolist -dump " + error_html);
174     }, run_time * 1000);
175 });