123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209 |
- /* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
- "use strict";
- const {utils: Cu} = Components;
- Cu.import("chrome://marionette/content/error.js");
- this.EXPORTED_SYMBOLS = ["simpletest"];
- this.simpletest = {};
- /**
- * The simpletest harness, exposed in the script evaluation sandbox.
- */
- simpletest.Harness = class {
- constructor(window, context, contentLogger, timeout, testName) {
- this.window = window;
- this.tests = [];
- this.logger = contentLogger;
- this.context = context;
- this.timeout = timeout;
- this.testName = testName;
- this.TEST_UNEXPECTED_FAIL = "TEST-UNEXPECTED-FAIL";
- this.TEST_UNEXPECTED_PASS = "TEST-UNEXPECTED-PASS";
- this.TEST_PASS = "TEST-PASS";
- this.TEST_KNOWN_FAIL = "TEST-KNOWN-FAIL";
- }
- get exports() {
- return new Map([
- ["ok", this.ok.bind(this)],
- ["is", this.is.bind(this)],
- ["isnot", this.isnot.bind(this)],
- ["todo", this.todo.bind(this)],
- ["log", this.log.bind(this)],
- ["getLogs", this.getLogs.bind(this)],
- ["generate_results", this.generate_results.bind(this)],
- ["waitFor", this.waitFor.bind(this)],
- ["TEST_PASS", this.TEST_PASS],
- ["TEST_KNOWN_FAIL", this.TEST_KNOWN_FAIL],
- ["TEST_UNEXPECTED_FAIL", this.TEST_UNEXPECTED_FAIL],
- ["TEST_UNEXPECTED_PASS", this.TEST_UNEXPECTED_PASS],
- ]);
- }
- addTest(condition, name, passString, failString, diag, state) {
- let test = {
- result: !!condition,
- name: name,
- diag: diag,
- state: state
- };
- this.logResult(
- test,
- typeof passString == "undefined" ? this.TEST_PASS : passString,
- typeof failString == "undefined" ? this.TEST_UNEXPECTED_FAIL : failString);
- this.tests.push(test);
- }
- ok(condition, name, passString, failString) {
- let diag = `${this.repr(condition)} was ${!!condition}, expected true`;
- this.addTest(condition, name, passString, failString, diag);
- }
- is(a, b, name, passString, failString) {
- let pass = (a == b);
- let diag = pass ? this.repr(a) + " should equal " + this.repr(b)
- : "got " + this.repr(a) + ", expected " + this.repr(b);
- this.addTest(pass, name, passString, failString, diag);
- }
- isnot(a, b, name, passString, failString) {
- let pass = (a != b);
- let diag = pass ? this.repr(a) + " should not equal " + this.repr(b)
- : "didn't expect " + this.repr(a) + ", but got it";
- this.addTest(pass, name, passString, failString, diag);
- }
- todo(condition, name, passString, failString) {
- let diag = this.repr(condition) + " was expected false";
- this.addTest(!condition,
- name,
- typeof(passString) == "undefined" ? this.TEST_KNOWN_FAIL : passString,
- typeof(failString) == "undefined" ? this.TEST_UNEXPECTED_FAIL : failString,
- diag,
- "todo");
- }
- log(msg, level) {
- dump("MARIONETTE LOG: " + (level ? level : "INFO") + ": " + msg + "\n");
- if (this.logger) {
- this.logger.log(msg, level);
- }
- }
- // TODO(ato): Suspect this isn't used anywhere
- getLogs() {
- if (this.logger) {
- return this.logger.get();
- }
- }
- generate_results() {
- let passed = 0;
- let failures = [];
- let expectedFailures = [];
- let unexpectedSuccesses = [];
- for (let i in this.tests) {
- let isTodo = (this.tests[i].state == "todo");
- if(this.tests[i].result) {
- if (isTodo) {
- expectedFailures.push({'name': this.tests[i].name, 'diag': this.tests[i].diag});
- }
- else {
- passed++;
- }
- }
- else {
- if (isTodo) {
- unexpectedSuccesses.push({'name': this.tests[i].name, 'diag': this.tests[i].diag});
- }
- else {
- failures.push({'name': this.tests[i].name, 'diag': this.tests[i].diag});
- }
- }
- }
- // Reset state in case this object is reused for more tests.
- this.tests = [];
- return {
- passed: passed,
- failures: failures,
- expectedFailures: expectedFailures,
- unexpectedSuccesses: unexpectedSuccesses,
- };
- }
- logToFile(file) {
- //TODO
- }
- logResult(test, passString, failString) {
- //TODO: dump to file
- let resultString = test.result ? passString : failString;
- let diagnostic = test.name + (test.diag ? " - " + test.diag : "");
- let msg = resultString + " | " + this.testName + " | " + diagnostic;
- dump("MARIONETTE TEST RESULT:" + msg + "\n");
- }
- repr(o) {
- if (typeof o == "undefined") {
- return "undefined";
- } else if (o === null) {
- return "null";
- }
- try {
- if (typeof o.__repr__ == "function") {
- return o.__repr__();
- } else if (typeof o.repr == "function" && o.repr !== arguments.callee) {
- return o.repr();
- }
- } catch (e) {}
- try {
- if (typeof o.NAME === "string" &&
- (o.toString === Function.prototype.toString || o.toString === Object.prototype.toString)) {
- return o.NAME;
- }
- } catch (e) {}
- let ostring;
- try {
- ostring = (o + "");
- } catch (e) {
- return "[" + typeof(o) + "]";
- }
- if (typeof o == "function") {
- o = ostring.replace(/^\s+/, "");
- let idx = o.indexOf("{");
- if (idx != -1) {
- o = o.substr(0, idx) + "{...}";
- }
- }
- return ostring;
- }
- waitFor(callback, test, timeout) {
- if (test()) {
- callback();
- return;
- }
- let now = new Date();
- let deadline = (timeout instanceof Date) ? timeout :
- new Date(now.valueOf() + (typeof timeout == "undefined" ? this.timeout : timeout));
- if (deadline <= now) {
- dump("waitFor timeout: " + test.toString() + "\n");
- // the script will timeout here, so no need to raise a separate
- // timeout exception
- return;
- }
- this.window.setTimeout(this.waitFor.bind(this), 100, callback, test, deadline);
- }
- };
|