michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this file, michael@0: * You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /** michael@0: * michael@0: * This file contains common code that is shared between marionette-server.js michael@0: * and marionette-listener.js. michael@0: * michael@0: */ michael@0: michael@0: /** michael@0: * Creates an error message for a JavaScript exception thrown during michael@0: * execute_(async_)script. michael@0: * michael@0: * This will generate a [msg, trace] pair like: michael@0: * michael@0: * ['ReferenceError: foo is not defined', michael@0: * 'execute_script @test_foo.py, line 10 michael@0: * inline javascript, line 2 michael@0: * src: "return foo;"'] michael@0: * michael@0: * @param error An Error object passed to a catch() clause. michael@0: fnName The name of the function to use in the stack trace message michael@0: (e.g., 'execute_script'). michael@0: pythonFile The filename of the test file containing the Marionette michael@0: command that caused this exception to occur. michael@0: pythonLine The line number of the above test file. michael@0: script The JS script being executed in text form. michael@0: */ michael@0: this.createStackMessage = function createStackMessage(error, fnName, pythonFile, michael@0: pythonLine, script) { michael@0: let python_stack = fnName + " @" + pythonFile; michael@0: if (pythonLine !== null) { michael@0: python_stack += ", line " + pythonLine; michael@0: } michael@0: let trace, msg; michael@0: if (typeof(error) == "object" && 'name' in error && 'stack' in error) { michael@0: let stack = error.stack.split("\n"); michael@0: let match = stack[0].match(/:(\d+):\d+$/); michael@0: let line = match ? parseInt(match[1]) : 0; michael@0: msg = error.name + ('message' in error ? ": " + error.message : ""); michael@0: trace = python_stack + michael@0: "\ninline javascript, line " + line + michael@0: "\nsrc: \"" + script.split("\n")[line] + "\""; michael@0: } michael@0: else { michael@0: trace = python_stack; michael@0: msg = error + ""; michael@0: } michael@0: return [msg, trace]; michael@0: } michael@0: michael@0: this.MarionetteLogObj = function MarionetteLogObj() { michael@0: this.logs = []; michael@0: } michael@0: MarionetteLogObj.prototype = { michael@0: /** michael@0: * Log message. Accepts user defined log-level. michael@0: * @param msg String michael@0: * The message to be logged michael@0: * @param level String michael@0: * The logging level to be used michael@0: */ michael@0: log: function ML_log(msg, level) { michael@0: let lev = level ? level : "INFO"; michael@0: this.logs.push( [lev, msg, (new Date()).toString()]); michael@0: }, michael@0: michael@0: /** michael@0: * Add a list of logs to its list michael@0: * @param msgs Object michael@0: * Takes a list of strings michael@0: */ michael@0: addLogs: function ML_addLogs(msgs) { michael@0: for (let i = 0; i < msgs.length; i++) { michael@0: this.logs.push(msgs[i]); michael@0: } michael@0: }, michael@0: michael@0: /** michael@0: * Return all logged messages. michael@0: */ michael@0: getLogs: function ML_getLogs() { michael@0: let logs = this.logs; michael@0: this.clearLogs(); michael@0: return logs; michael@0: }, michael@0: michael@0: /** michael@0: * Clears the logs michael@0: */ michael@0: clearLogs: function ML_clearLogs() { michael@0: this.logs = []; michael@0: }, michael@0: }