Read console.log() output form javascript - javascript

I am writing an overlay UI for one application using Greasemonkey, injecting JS to a page.
Now I have issue to hook on some ajax calls that runs on the webpage.
However, the page is generating console logs, informing that content is fully loaded. My question is:
In plain javascript, is there a possibility of reading console output generated by completely different script?
function blackBox(){
//this is generating come console output.
//this runs on code layer I have no access to.
}
function readConsole(){
//read console record by record
if(console.msg == "something I want"){
doSomething();
}
}
Thanks in advance :)

As others have stated, you can override the console.log() function with your own, and implement your own implementation:
var oldLog = unsafeWindow.console.log;
var messages = [];
unsafeWindow.console.log = function(msg) {
messages.push(msg);
oldLog.apply(null, arguments);
}
// Access the entire console.log history in messages

Redefine console.log and storage messages on a array:
var consoleStorage = [];
console.log = function(msg){
consoleStorage.push(msg);
console.warn(msg); // if you need to print the output
}
Now you can read all logs:
function readConsole(){
//read console record by record
consoleStorage.forEach(msg => {
doSomething(msg);
});
}

Even if it were possible, that would be bad practice. The console is for human eyes to see, when debugging. It usually takes several milliseconds to execute console.log, so executing it in production code is not a good idea.
I would say programming in booleans (like ifDidX and ifDidY) would be better. But if you really had to do this message-history thing, a better alternative would be to store messages in some other array. Here is an example:
var messagesLog = [];
//Since console.log takes several milliseconds to execute, you should tick this to false in production code.
const logToConsole = true;
function logMessage( message ){
//adds message to JS log.
messagesLog.push(message);
//performs console.log if not production code
if(logToConsole){
console.log(message);
}
}
logMessage("pizza");
logMessage("second to last message");
logMessage("last message");
//checks last message and this will be true
if( messagesLog[messagesLog.length - 1] == "last message" ){
logMessage("The last message in the log was 'last message'");
}
//checks last message and this will be false
if( messagesLog[messagesLog.length - 1] == "pizza" ){
logMessage("This will not occur because the last message was 'last message'");
}
//searches through log to find certain message
for(let i = 0; i < messagesLog.length; i++){
if(messagesLog[i] == "pizza"){
logMessage("one of the messages in the log was pizza");
}
}

Directly there's no way to access console outputs, but what you can do is that you can override console.log in a way where it checks for you condition first and then outputs the content, below is a sample code for that
console.stdlog = console.log.bind(console);
console.log = function(msg){
if(msg == "something I want"){
...
}
console.stdlog.apply(console, arguments);
}
Although you'll need to be very careful with this since if you add any console.log in that condition, it will create an infinite loop.

Related

I am trying to write a while loop in javascript. My console.log does not print the requested message

var ask = prompt('Are we there yet???');
while (ask != 'y') {
if (ask[0] === 'y') {
// For some unknown reason to me my solution will not print the message.
console.log('Yea, we made it!!!');
} else {
var ask = prompt('Are we there yet???');
};
}
Your code is setting a variable inside of the while loop to the output of the prompt which is why the loop can't access it.
To achieve your goal, you'll need something like this:
while (prompt('Are we there yet???') !== 'y') {}
console.log('Yea, we made it!!!');
Basically, the code goes in an infinite loop of asking the user to type y before continuing the code and in this case, logging the message to the console.

Grab JavaScript console output with PhantomJS and evaluate it

I'm trying to parse the status page of my router to get the number of wlan devices. The page uses some JavaScript to get the status, so I tried to use PhantomJS, but had no luck.
This is the html source of the status page (status.html and status.js): http://pastebin.com/dmvptBqv
The developer tools of my browser show me this output on the console (anonymized):
([
{"vartype":"value","varid":"device_name","varvalue":"Speedport W 921V"},
{"vartype":"value","varid":"factorydefault","varvalue":"1"},
{"vartype":"value","varid":"rebooting","varvalue":"0"},
{"vartype":"value","varid":"router_state","varvalue":"OK"},
{"vartype":"value","varid":"bngscrat","varvalue":"0"},
{"vartype":"value","varid":"acsreach","varvalue":"0"},
Full reference
How can I get this evaluated output out of PhantomJS? Maybe it is very simple and I just missed the part in the documentation.
I think that i have to use the evluate function, but have no idea what is the correct function for the document object to return the complete evaluation.
var webPage = require('webpage');
var page = webPage.create();
page.open('blubb', function (status) {
var js= page.evaluate(function() {
return document.???;
});
console.log(js);
phantom.exit();
});
The main problem that you have is to get the console messages from the page into a single structure that you can do further processing on. This is easily done with the following code which waits indefinitely until the first console message appears and stops waiting as soon as no further messages appeared during 1 second.
var logs = []
timeoutID;
page.onConsoleMessage = function(msg){
if (timeoutID) clearTimeout(timeoutID);
logs.push(msg); // possibly also further processing
timeoutID = setTimeout(function(){
page.onConsoleMessage = function(msg){
console.log("CONSOLE: " + msg);
};
// TODO: further processing
console.log(JSON.stringify(logs, undefined, 4));
phantom.exit();
}, 1000);
};
page.open(url); // wait indefinitely
If each msg is valid JSON, then you can parse it immediately to get JavaScript objects. Change
logs.push(msg);
to
logs.push(JSON.parse(msg));

Execute JavaScript code to get the log from console using selenium webdriver or WatiN

(Sorry for being a bit descriptive)
I wanted to wait for a page to load completely but after searching on Google it seems that browsers react differently, when we try to use readyState or onLoad.
Also, for application I am working on, it seems that a particular log message ("TNP is ready") appears in console (chrome console or IE developer tool console), when the required page is loaded.
My plan is to execute a small JavaScript code on the browser, using Selenium WebDriver C# and WatiN C# (IE), to get this message from the console log.
Can this be done? Can I get the Last Log generated by console.log ?
Because when I execute the script it might happen that the message is already gone or yet to come. I need to fire it repeatedly.
Any suggestions?
This question, while not exactly a duplicate of In WatiN how to wait until postback is complete, is probably caused by the same thing.
The browser.WaitUntilComplete() method will wait for the page to finish loading, but if you have AJAX going on in the background as the page is loading then WaitUntilComplete won't do the trick.
From my research, there is no way to get log messages from the browser console unless you include some JavaScript to mirror the console and overwrite window.console and provide a mechanism for inspecting console messages.
(function(win) {
var console = win.console;
if (!console)
throw new Error("This browser does not support a debug console");
var mirror = {},
data = {};
var toString = Object.prototype.toString,
mirrorMethod = function(key) {
data[key] = [];
return function() {
data[key].push(arguments);
console[key].apply(console, arguments);
};
};
for (var key in console) {
if (toString.call(console[key]) == "[object Function]") {
mirror[key] = mirrorMethod(key);
}
}
win.console = mirror;
win.consoleMirror = {
getData: function(key) {
return data[key] || [];
}
};
}(this));
JSFiddle: http://jsfiddle.net/fyhLw0to/
And to use:
console.log("foo");
alert(consoleMirror.getData("log")[0][0]);
An alternative is to grab an element using WatiN that you need to interact with, and call WaitUntilExists:
var button = browser.Button("buttonIdThatDoesNotExistYet");
button.WaitUntilExists();
button.Click();
This way you don't have to hack the debug console, or hack XMLHttpRequest to infer when AJAX is done. Your tests will attempt to wait for elements to appear on the page before acting upon them. Test failures will be slower, but your tests should be more robust.

Debugging a Windows store app - error messages always show the same line number

I've set up error logging on my windows store app, which reports the error message and the line number in the code.
I've been getting two error messages from the same line, line 301. The error messages are
The process cannot access the file because it is being used by another process.
Access is denied.
Based on the First error message I presume the error is with my autosave function, but without the line number I can't say where it's failing. Here's my autosave code
function autosave()
{
if ((localSettings.values["useAutoSave"] == null || localSettings.values["useAutoSave"] == "true")) {
editorContent = editor.textContent;
var text_length = editorContent.length;
if (editedSinceSave && text_length > 0) {
localSettings.values["lastContent"] = text_length;
setStatus("<span class='loader'></span>autosaving", 2000);
writeTempFile();
}
}
window.setTimeout(autosave, _autosave_timeout);
}
function writeTempFile()
{
try{
tempFolder.createFileAsync("tempFile.txt", Windows.Storage.CreationCollisionOption.replaceExisting)
.then(function (theFile) {
return Windows.Storage.FileIO.writeTextAsync(theFile, editor.textContent);
}).done(function () {
localSettings.values["lastPos"] = _lastStartPos;
});
}
catch (e) {
// statements to handle any exceptions
logError(e); // pass exception object to error handler
}
}
Even we I move all my functions around and recompile my code, the error is always at line 301. I suspect that the errorline I'm seeing is actually from whatever underlying js files are used to run my app, but I don't know where to access them. How the hell do I debug this?
Make sure there's not a capability that you have not declared. It doesn't look like your code is using anything special, but it's worth a try.

JavaScript: How do I print a message to the error console?

How can I print a message to the error console, preferably including a variable?
For example, something like:
print('x=%d', x);
Install Firebug and then you can use console.log(...) and console.debug(...), etc. (see the documentation for more).
console.error(message); // Outputs an error message to the Web Console
console.log(message); // Outputs a message to the Web Console
console.warn(message); // Outputs a warning message to the Web Console
console.info(message); // Outputs an informational message to the Web Console. In some browsers it shows a small "i" in front of the message.
You also can add CSS:
console.log('%c My message here', "background: blue; color: white; padding-left:10px;");
More info can be found here: https://developer.mozilla.org/en-US/docs/Web/API/console
Exceptions are logged into the JavaScript console. You can use that if you want to keep Firebug disabled.
function log(msg) {
setTimeout(function() {
throw new Error(msg);
}, 0);
}
Usage:
log('Hello World');
log('another message');
One good way to do this that works cross-browser is outlined in Debugging JavaScript: Throw Away Your Alerts!.
Here is a solution to the literal question of how to print a message to the browser's error console, not the debugger console. (There might be good reasons to bypass the debugger.)
As I noted in comments about the suggestion to throw an error to get a message in the error console, one problem is that this will interrupt the thread of execution. If you don't want to interrupt the thread, you can throw the error in a separate thread, one created using setTimeout. Hence my solution (which turns out to be an elaboration of the one by Ivo Danihelka):
var startTime = (new Date()).getTime();
function logError(msg)
{
var milliseconds = (new Date()).getTime() - startTime;
window.setTimeout(function () {
throw( new Error(milliseconds + ': ' + msg, "") );
});
}
logError('testing');
I include the time in milliseconds since the start time because the timeout could skew the order in which you might expect to see the messages.
The second argument to the Error method is for the filename, which is an empty string here to prevent output of the useless filename and line number. It is possible to get the caller function but not in a simple browser independent way.
It would be nice if we could display the message with a warning or message icon instead of the error icon, but I can't find a way to do that.
Another problem with using throw is that it could be caught and thrown away by an enclosing try-catch, and putting the throw in a separate thread avoids that obstacle as well. However, there is yet another way the error could be caught, which is if the window.onerror handler is replaced with one that does something different. Can't help you there.
If you use Safari, you can write
console.log("your message here");
and it appears right on the console of the browser.
To actually answer the question:
console.error('An error occurred!');
console.error('An error occurred! ', 'My variable = ', myVar);
console.error('An error occurred! ' + 'My variable = ' + myVar);
Instead of error, you can also use info, log or warn.
If you are using Firebug and need to support IE, Safari or Opera as well, Firebug Lite adds console.log() support to these browsers.
The WebKit Web Inspector also supports Firebug's console API (just a minor addition to Dan's answer).
A note about 'throw()' mentioned above. It seems that it stops execution of the page completely (I checked in IE8) , so it's not very useful for logging "on going processes" (like to track a certain variable...)
My suggestion is perhaps to add a textarea element somewhere in your document and to change (or append to) its value (which would change its text) for logging information whenever needed...
As always, Internet Explorer is the big elephant in rollerskates that stops you just simply using console.log().
jQuery's log can be adapted quite easily, but is a pain having to add it everywhere. One solution if you're using jQuery is to put it into your jQuery file at the end, minified first:
function log()
{
if (arguments.length > 0)
{
// Join for graceful degregation
var args = (arguments.length > 1) ? Array.prototype.join.call(arguments, " ") : arguments[0];
// This is the standard; Firebug and newer WebKit browsers support this.
try {
console.log(args);
return true;
} catch(e) {
// Newer Opera browsers support posting erros to their consoles.
try {
opera.postError(args);
return true;
}
catch(e)
{
}
}
// Catch all; a good old alert box.
alert(args);
return false;
}
}
Visit https://developer.chrome.com/devtools/docs/console-api for a complete console api reference
console.error(object[Obj,....])\
In this case, object would be your error string
function foo() {
function bar() {
console.trace("Tracing is Done here");
}
bar();
}
foo();
console.log(console); //to print console object
console.clear('console.clear'); //to clear console
console.log('console.log'); //to print log message
console.info('console.info'); //to print log message
console.debug('console.debug'); //to debug message
console.warn('console.warn'); //to print Warning
console.error('console.error'); //to print Error
console.table(["car", "fruits", "color"]);//to print data in table structure
console.assert('console.assert'); //to print Error
console.dir({"name":"test"});//to print object
console.dirxml({"name":"test"});//to print object as xml formate
To Print Error:- console.error('x=%d', x);
console.log("This is the outer level");
console.group();
console.log("Level 2");
console.group();
console.log("Level 3");
console.warn("More of level 3");
console.groupEnd();
console.log("Back to level 2");
console.groupEnd();
console.log("Back to the outer level");
console.log("your message here");
working for me.. i'm searching for this.. i used Firefox.
here is my Script.
$('document').ready(function() {
console.log('all images are loaded');
});
works in Firefox and Chrome.
The simplest way to do this is:
console.warn("Text to print on console");
To answer your question you can use ES6 features,
var var=10;
console.log(`var=${var}`);
This does not print to the Console, but will open you an alert Popup with your message which might be useful for some debugging:
just do:
alert("message");
With es6 syntax you can use:
console.log(`x = ${x}`);

Categories

Resources