Bumping gaia.json for 2 gaia revision(s) a=gaia-bump
[gecko.git] / testing / marionette / marionette-simpletest.js
blob1e9b7a698079cf8dce0d6db87edc16a4ca7284d0
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
3  * You can obtain one at http://mozilla.org/MPL/2.0/. */
4 /*
5  * The Marionette object, passed to the script context.
6  */
8 this.Marionette = function Marionette(scope, window, context, logObj, timeout,
9                                       heartbeatCallback, testName) {
10   this.scope = scope;
11   this.window = window;
12   this.tests = [];
13   this.logObj = logObj;
14   this.context = context;
15   this.timeout = timeout;
16   this.heartbeatCallback = heartbeatCallback;
17   this.testName = testName;
18   this.TEST_UNEXPECTED_FAIL = "TEST-UNEXPECTED-FAIL";
19   this.TEST_UNEXPECTED_PASS = "TEST-UNEXPECTED-PASS";
20   this.TEST_PASS = "TEST-PASS";
21   this.TEST_KNOWN_FAIL = "TEST-KNOWN-FAIL";
24 Marionette.prototype = {
25   exports: ['ok', 'is', 'isnot', 'todo', 'log', 'getLogs', 'generate_results', 'waitFor',
26             'runEmulatorCmd', 'runEmulatorShell', 'TEST_PASS', 'TEST_KNOWN_FAIL',
27             'TEST_UNEXPECTED_FAIL', 'TEST_UNEXPECTED_PASS'],
29   addTest: function Marionette__addTest(condition, name, passString, failString, diag, state) {
31     let test = {'result': !!condition, 'name': name, 'diag': diag, 'state': state};
32     this.logResult(test,
33                    typeof(passString) == "undefined" ? this.TEST_PASS : passString,
34                    typeof(failString) == "undefined" ? this.TEST_UNEXPECTED_FAIL : failString);
35     this.tests.push(test);
36   },
38   ok: function Marionette__ok(condition, name, passString, failString) {
39     this.heartbeatCallback();
40     let diag = this.repr(condition) + " was " + !!condition + ", expected true";
41     this.addTest(condition, name, passString, failString, diag);
42   },
44   is: function Marionette__is(a, b, name, passString, failString) {
45     this.heartbeatCallback();
46     let pass = (a == b);
47     let diag = pass ? this.repr(a) + " should equal " + this.repr(b)
48                     : "got " + this.repr(a) + ", expected " + this.repr(b);
49     this.addTest(pass, name, passString, failString, diag);
50   },
52   isnot: function Marionette__isnot (a, b, name, passString, failString) {
53     this.heartbeatCallback();
54     let pass = (a != b);
55     let diag = pass ? this.repr(a) + " should not equal " + this.repr(b)
56                     : "didn't expect " + this.repr(a) + ", but got it";
57     this.addTest(pass, name, passString, failString, diag);
58   },
60   todo: function Marionette__todo(condition, name, passString, failString) {
61     this.heartbeatCallback();
62     let diag = this.repr(condition) + " was expected false";
63     this.addTest(!condition,
64                  name,
65                  typeof(passString) == "undefined" ? this.TEST_KNOWN_FAIL : passString,
66                  typeof(failString) == "undefined" ? this.TEST_UNEXPECTED_FAIL : failString,
67                  diag,
68                  "todo");
69   },
71   log: function Marionette__log(msg, level) {
72     this.heartbeatCallback();
73     dump("MARIONETTE LOG: " + (level ? level : "INFO") + ": " + msg + "\n");
74     if (this.logObj != null) {
75       this.logObj.log(msg, level);
76     }
77   },
79   getLogs: function Marionette__getLogs() {
80     this.heartbeatCallback();
81     if (this.logObj != null) {
82       this.logObj.getLogs();
83     }
84   },
86   generate_results: function Marionette__generate_results() {
87     this.heartbeatCallback();
88     let passed = 0;
89     let failures = [];
90     let expectedFailures = [];
91     let unexpectedSuccesses = [];
92     for (let i in this.tests) {
93       let isTodo = (this.tests[i].state == "todo");
94       if(this.tests[i].result) {
95         if (isTodo) {
96           expectedFailures.push({'name': this.tests[i].name, 'diag': this.tests[i].diag});
97         }
98         else {
99           passed++;
100         }
101       }
102       else {
103         if (isTodo) {
104           unexpectedSuccesses.push({'name': this.tests[i].name, 'diag': this.tests[i].diag});
105         }
106         else {
107           failures.push({'name': this.tests[i].name, 'diag': this.tests[i].diag});
108         }
109       }
110     }
111     // Reset state in case this object is reused for more tests.
112     this.tests = [];
113     return {"passed": passed, "failures": failures, "expectedFailures": expectedFailures,
114             "unexpectedSuccesses": unexpectedSuccesses};
115   },
117   logToFile: function Marionette__logToFile(file) {
118     this.heartbeatCallback();
119     //TODO
120   },
122   logResult: function Marionette__logResult(test, passString, failString) {
123     this.heartbeatCallback();
124     //TODO: dump to file
125     let resultString = test.result ? passString : failString;
126     let diagnostic = test.name + (test.diag ? " - " + test.diag : "");
127     let msg = resultString + " | " + this.testName + " | " + diagnostic;
128     dump("MARIONETTE TEST RESULT:" + msg + "\n");
129   },
131   repr: function Marionette__repr(o) {
132       if (typeof(o) == "undefined") {
133           return "undefined";
134       } else if (o === null) {
135           return "null";
136       }
137       try {
138           if (typeof(o.__repr__) == 'function') {
139               return o.__repr__();
140           } else if (typeof(o.repr) == 'function' && o.repr != arguments.callee) {
141               return o.repr();
142           }
143      } catch (e) {
144      }
145      try {
146           if (typeof(o.NAME) == 'string' && (
147                   o.toString == Function.prototype.toString ||
148                   o.toString == Object.prototype.toString
149               )) {
150               return o.NAME;
151           }
152       } catch (e) {
153       }
154       let ostring;
155       try {
156           ostring = (o + "");
157       } catch (e) {
158           return "[" + typeof(o) + "]";
159       }
160       if (typeof(o) == "function") {
161           o = ostring.replace(/^\s+/, "");
162           let idx = o.indexOf("{");
163           if (idx != -1) {
164               o = o.substr(0, idx) + "{...}";
165           }
166       }
167       return ostring;
168   },
170   waitFor: function test_waitFor(callback, test, timeout) {
171       this.heartbeatCallback();
172       if (test()) {
173         callback();
174         return;
175       }
176       var now = new Date();
177       var deadline = (timeout instanceof Date) ? timeout :
178                      new Date(now.valueOf() + (typeof(timeout) == "undefined" ? this.timeout : timeout))
179       if (deadline <= now) {
180         dump("waitFor timeout: " + test.toString() + "\n");
181         // the script will timeout here, so no need to raise a separate
182         // timeout exception
183         return;
184       }
185       this.window.setTimeout(this.waitFor.bind(this), 100, callback, test, deadline);
186   },
188   runEmulatorCmd: function runEmulatorCmd(cmd, callback) {
189     this.heartbeatCallback();
190     this.scope.runEmulatorCmd(cmd, callback);
191   },
193   runEmulatorShell: function runEmulatorShell(args, callback) {
194     this.heartbeatCallback();
195     this.scope.runEmulatorShell(args, callback);
196   },