I found a way to inject information into the Firefox Web Console, catching and modifying the return value of createMessageNode, modifying the web-console output:
Oddly enough, the elements returned don't seem to have any possible way to link them back to the object they represent - yet when you click [object Array], it always pops up to the right. How is this connected?
As a side note, when I click upward on the breadcrumbs to see where it came from on the stack trace, some items aren't shown in the debugger. Is this a bug, or are some JS modules compiled so as to never show their contents here? Is this the correct place to add in an array to the console line instead of always saying [object Array] etc.?
Update You can see and run this code above in this branch: https://github.com/programmin1/DevTools-Tweaks/tree/webconsoleOutputBetter
by inject info do you mean Services.console.logStringMessage and stuff?
https://developer.mozilla.org/en-US/docs/Console_service
If you want to access the chrome of the web console do this:
var devtools = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools;
var HUDService = devtools.require("devtools/webconsole/hudservice");
var hud = HUDService.getBrowserConsole();
var btnClear = hud.chromeWindow.document.querySelector('.webconsole-clear-console-button');
btnClear.addEventListener('mouseover', function() {
hud.jsterm.clearOutput(true);
}, false);
var fieldFilter = hud.chromeWindow.document.querySelector('.hud-filter-box');
fieldFilter.value = 'rawr'
this code access the crhome window, you can access all the text dumped there. this example above modies the filter value, and also makes the clear button clear the web console on mouseoever, just an example of how to access web console if thats what you're doing
Related
When I print an array, it shows up as a 100 element array of objects, but when I expand it, it doesn't expand. Instead, there is a blue info icon that says "Value below was evaluated just now", and the arrow changes direction. The problem is still there even if I clone my array when printing (which was an answer in another SO question).
I am actually using node.js with chrome debugger but I think the issue is the same. Here is my code
const axios = require('axios');
axios.get("https://--------")
.then(function(response) {
let data = response.data;
console.log(data.slice(0, 100));
});
axios just sends http requests.
I've read:
Is Chrome's JavaScript console lazy about evaluating arrays?
Weird behavior with objects & console.log
Your problem might be occurring because you are trying to expand the data structure after the debug session has ended.
Try add a debugger; after your console log to ensure you are expanding that array during your debug session.
I'm creating a custom Chrome extension, which is going to retrieve data about an active tab before sending it to a secondary website.
I've been trying to find a method on how to retrieve the console output for an active tab. chrome.tabs.getSelected seemed promising at first, however, it doesn't offer an output of the console text. I've been digging for couple of hours without much success of finding a method that could give me this info.
Could anyone point me in the right direction please?
Edit:
As a way to keep track of everything I've tried so far, for myself and others, I will add info below.
I've found a possible solution which may work for me. The below code will extend the console methods log, error and warn. I'm currently researching for a method that maybe able to attach this code to the active tab, so I can collect the console outputs in the arrays and then make these available on my extension to be sent over to the secondary website.
I will post more info as I progress through it.
var logs = [],
cLogs = [],
cErrors = [],
cWarns = [],
_log = console.log,
_error = console.error,
_warn = console.warn;
console.log = function () {
for (var i = 0; i < arguments.length; i++) {
logs.push(arguments[i]);
cLogs.push(arguments[i]);
}
_log.apply(this, arguments);
};
console.error = function () {
for (var i = 0; i < arguments.length; i++) {
logs.push(arguments[i]);
cErrors.push(arguments[i]);
}
_error.apply(this, arguments);
};
console.warn = function () {
for (var i = 0; i < arguments.length; i++) {
logs.push(arguments[i]);
cWarns.push(arguments[i]);
}
_warn.apply(this, arguments);
};
console.log('welcome');
console.error({'foobar': ['foo','bar']});
console.warn({'foo':'bar'});
_log(logs);
This issue is significantly harder than it appears.
APIs like chrome.tabs have no access to a tab's console. In fact, no "standard" API does.
One could expect a content script running in the context of the page to be able to access it. However, there's no way to access previous output of the console from a JavaScript context.
The method you quote in your update (creating wrappers around console.* functions) can only capture future invocations of those functions, and won't capture things like errors from the JS runtime itself (e.g. unhandled exceptions or network errors). As such, to access console from an arbitrary tab, you'll need to inject this code into every tab, before it loads, even if you only rarely use it.
It is further complicated by the fact that content scripts do not, in fact, run in the same context. To override console for the page itself, you'll need to inject the script in the page context.
So, to summarize:
You can do it by overriding console.* functions and listening to error event on window object, but it has to be done in page context by a document_start content script injecting code into every page. Extracting this data from the page context will be a challenge in itself.
Downsides:
It hurts overall browser performance.
It won't see some browser-initiated messages that go directly to console.
You can take the big hammer and use chrome.debugger API. This API has the same level of access to the page as the Dev Tools themselves - therefore, it's possible to obtain the full console output history.
Downsides:
You'll need to study the remote debugging protocol, see the official examples.
A very scary warning will be shown in all tabs when the debugger API is used.
All in all, what you're trying to achieve is a hard task with fragile solutions. Perhaps you need to rethink your approach.
I'm creating a custom Chrome extension, which is going to retrieve data about an active tab before sending it to a secondary website.
I've been trying to find a method on how to retrieve the console output for an active tab. chrome.tabs.getSelected seemed promising at first, however, it doesn't offer an output of the console text. I've been digging for couple of hours without much success of finding a method that could give me this info.
Could anyone point me in the right direction please?
Edit:
As a way to keep track of everything I've tried so far, for myself and others, I will add info below.
I've found a possible solution which may work for me. The below code will extend the console methods log, error and warn. I'm currently researching for a method that maybe able to attach this code to the active tab, so I can collect the console outputs in the arrays and then make these available on my extension to be sent over to the secondary website.
I will post more info as I progress through it.
var logs = [],
cLogs = [],
cErrors = [],
cWarns = [],
_log = console.log,
_error = console.error,
_warn = console.warn;
console.log = function () {
for (var i = 0; i < arguments.length; i++) {
logs.push(arguments[i]);
cLogs.push(arguments[i]);
}
_log.apply(this, arguments);
};
console.error = function () {
for (var i = 0; i < arguments.length; i++) {
logs.push(arguments[i]);
cErrors.push(arguments[i]);
}
_error.apply(this, arguments);
};
console.warn = function () {
for (var i = 0; i < arguments.length; i++) {
logs.push(arguments[i]);
cWarns.push(arguments[i]);
}
_warn.apply(this, arguments);
};
console.log('welcome');
console.error({'foobar': ['foo','bar']});
console.warn({'foo':'bar'});
_log(logs);
This issue is significantly harder than it appears.
APIs like chrome.tabs have no access to a tab's console. In fact, no "standard" API does.
One could expect a content script running in the context of the page to be able to access it. However, there's no way to access previous output of the console from a JavaScript context.
The method you quote in your update (creating wrappers around console.* functions) can only capture future invocations of those functions, and won't capture things like errors from the JS runtime itself (e.g. unhandled exceptions or network errors). As such, to access console from an arbitrary tab, you'll need to inject this code into every tab, before it loads, even if you only rarely use it.
It is further complicated by the fact that content scripts do not, in fact, run in the same context. To override console for the page itself, you'll need to inject the script in the page context.
So, to summarize:
You can do it by overriding console.* functions and listening to error event on window object, but it has to be done in page context by a document_start content script injecting code into every page. Extracting this data from the page context will be a challenge in itself.
Downsides:
It hurts overall browser performance.
It won't see some browser-initiated messages that go directly to console.
You can take the big hammer and use chrome.debugger API. This API has the same level of access to the page as the Dev Tools themselves - therefore, it's possible to obtain the full console output history.
Downsides:
You'll need to study the remote debugging protocol, see the official examples.
A very scary warning will be shown in all tabs when the debugger API is used.
All in all, what you're trying to achieve is a hard task with fragile solutions. Perhaps you need to rethink your approach.
I am new to debugging JavaScript and AngularJS. I have breakpoints in virtually every line of the following code segment, but I am not able to find the response variable or data or content in the Firefox debugger. There is a very dense nested structure of variables in the debugger. Where do I look in the Firefox debugger variables structure to find the values for response or data or content in the code below?
The alert says that the confirmStatus variable's value has not changed from its default and thus was not populated by the call to the backend service, even though the backend service call produced console logs indicating that it was fired. I want to find out what is coming back and in what form so that I can alter the client side code below.
Here is the segment of Javascript code that I am running through the debugger:
$scope.$on('$viewContentLoaded', function() {
var str1 = "/confirm-email?d=";
var str2 = $routeParams.d;
var res = str1.concat(str2);
$http.post(res).then(function(response) {
$scope.confirmStatus = response.data.content;
});
var str3 = "confirmStatus is: ";
alert(str3.concat($scope.confirmStatus))
alert("viewContentLoaded!")
});
I would suggest using the debugger first. This means:
open the debugger with the developer tools menu or keyboard shortcut: https://developer.mozilla.org/en-US/docs/Tools/Debugger/How_to/Open_the_debugger
Pick the file you want to debug, key shortcut is on mac, then type in part of your .js file to have it open in the debugger.
You should see the source code for your .js file now, and you can click in the left-nav to the line you want to stop on, e.g. the $scope.confirmStatus = ....
There is also a good trick with angular where you can access the scope from the console. To do this
Again open the developer tools this time to the console not debugger
Right-click on the page near some html owned by angular, and pick "Inspect element"
In the console: angular.element($0).scope(), and you will have access to the controller scope for that element.
That said, you might want to try and capture the error handler for the http.post. e.g.
$http.post(res).then(function(response) {},
function(err) {});
Keep in mind that this function will run in parallel to current one, at a later stage when response will come from server:
function(response) {
$scope.confirmStatus = response.data.content;
}
You should put a debugger break point into this $http callback function -- response variable will be destroyed as soon as callback function execution will end.
Your alert will always display unmodified confirmStatus, because confirmStatus is changed in callback function which will be executed later when response will come from server.
In my cappuccino app, I am reading from an RoR backend via JSON and putting the results onto a list. When the app first loads everything is fine, but when I edit an item (and write the edit to the database) there is an error generated when the items list is refreshed.
The error is CPRangeException: -[_CPJavaScriptArray objectAtIndex:]: index (-1) beyond bounds (3).
I get this error even if I edit an item without making any actual changes. The JSON string received by the app remains exactly the same in this case, there are no items added or removed and therefore the array should not be written to out of bounds.
Here is my code:
- (void)connection:(CPRURLConnection)connection didReceiveData:(CPString)data
{
if(connection === listConnection)
{
var results = JSON.parse(data) ;
var posts = [Post initFromJSONObjects:results];
[postListView setContent:posts] ;
// My error occurs at the above line
[postListView setSelectionIndexes:[[CPIndexSet alloc] initWithIndex:0]] ;
}
}
I am not sure if it's an error with my code or if it's some kind of inconsistency with the cappuccino framework. Does anybody know what I can do to fix this?
The rest of the code can be found here
You should probably simply log what's in posts before setting it. CPLog.info('posts: ' + posts); should work, or console.log(posts). Next you can set a 'break on uncaught exception' debug point in Chrome or Safari to stop at the actual error you are seeing. Make sure you run your app using index-debug.html so that you get full method names. Then it should be an easy matter to look at the calling stack to see where things are going wrong. There's a lot of information on debugging a Cappuccino app here.