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/. */
5 * The Marionette object, passed to the script context.
8 this.Marionette = function Marionette(scope, window, context, logObj, timeout,
9 heartbeatCallback, testName) {
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};
33 typeof(passString) == "undefined" ? this.TEST_PASS : passString,
34 typeof(failString) == "undefined" ? this.TEST_UNEXPECTED_FAIL : failString);
35 this.tests.push(test);
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);
44 is: function Marionette__is(a, b, name, passString, failString) {
45 this.heartbeatCallback();
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);
52 isnot: function Marionette__isnot (a, b, name, passString, failString) {
53 this.heartbeatCallback();
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);
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,
65 typeof(passString) == "undefined" ? this.TEST_KNOWN_FAIL : passString,
66 typeof(failString) == "undefined" ? this.TEST_UNEXPECTED_FAIL : failString,
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);
79 getLogs: function Marionette__getLogs() {
80 this.heartbeatCallback();
81 if (this.logObj != null) {
82 this.logObj.getLogs();
86 generate_results: function Marionette__generate_results() {
87 this.heartbeatCallback();
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) {
96 expectedFailures.push({'name': this.tests[i].name, 'diag': this.tests[i].diag});
104 unexpectedSuccesses.push({'name': this.tests[i].name, 'diag': this.tests[i].diag});
107 failures.push({'name': this.tests[i].name, 'diag': this.tests[i].diag});
111 // Reset state in case this object is reused for more tests.
113 return {"passed": passed, "failures": failures, "expectedFailures": expectedFailures,
114 "unexpectedSuccesses": unexpectedSuccesses};
117 logToFile: function Marionette__logToFile(file) {
118 this.heartbeatCallback();
122 logResult: function Marionette__logResult(test, passString, failString) {
123 this.heartbeatCallback();
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");
131 repr: function Marionette__repr(o) {
132 if (typeof(o) == "undefined") {
134 } else if (o === null) {
138 if (typeof(o.__repr__) == 'function') {
140 } else if (typeof(o.repr) == 'function' && o.repr != arguments.callee) {
146 if (typeof(o.NAME) == 'string' && (
147 o.toString == Function.prototype.toString ||
148 o.toString == Object.prototype.toString
158 return "[" + typeof(o) + "]";
160 if (typeof(o) == "function") {
161 o = ostring.replace(/^\s+/, "");
162 let idx = o.indexOf("{");
164 o = o.substr(0, idx) + "{...}";
170 waitFor: function test_waitFor(callback, test, timeout) {
171 this.heartbeatCallback();
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
185 this.window.setTimeout(this.waitFor.bind(this), 100, callback, test, deadline);
188 runEmulatorCmd: function runEmulatorCmd(cmd, callback) {
189 this.heartbeatCallback();
190 this.scope.runEmulatorCmd(cmd, callback);
193 runEmulatorShell: function runEmulatorShell(args, callback) {
194 this.heartbeatCallback();
195 this.scope.runEmulatorShell(args, callback);