When trying to use Mocha (version 1.3.2) in the browser, along the lines of the given example, I get the following exception when trying to specify acceptable globals in the expected way (i.e. with something like mocha.globals(['amplify', '_'])):
Uncaught TypeError: Object function Mocha(options) {
options = options || {};
this.files = [];
this.options = options;
this.grep(options.grep);
this.suite = new exports.Suite('', new exports.Context);
this.ui(options.ui);
this.reporter(options.reporter);
if (options.timeout) this.suite.timeout(options.timeout);
} has no method 'globals'
This is exhibited in Chrome 21.0.1180.
One may reproduce this by going to the given example link, and in the browser console run mocha.globals(['123']).
I would expect mocha.globals to work as the linked example suggests, or there to be some documentation about an alternative, but I have found none.
This is issue #42 on visionmedia/mocha GitHub. The solution is, in Coffeescript:
mocha.setup
ui: 'bdd'
globals: [ 'jade' ]
Related
I am trying to use scripts in illustrator. Some of these require being able to import other scripts so I found the below code. When I try to run it I receive
Error 21: Undefined is not an object.
Line 6 -> var Libraries = (function(libpath){"
I have looked through other answers and it seems the issue is that "Libraries" (?) is undefined, and that I ought to define it first. Sadly I don't know what it ought to be defined as. Or I don't understand the problem in general.
I expected it to import helloworld.jsx and hence be able to run the helloWorld function. It threw up the error described above.
//Library importing function from https://gist.github.com/jasonrhodes/5286526
// indexOf polyfill from https://gist.github.com/atk/1034425
[].indexOf||(Array.prototype.indexOf=function(a,b,c){for(c=this.length,b=(c+~~b)%c;b<c&&(!(b in this)||this[b]!==a);b++);return b^c?b:-1;});
var Libraries = (function(libPath) {
return {
include: function(path) {
if (!path.match(/\.jsx$/i)) {
path = path + ".jsx";
}
return $.evalFile(libPath + path);
}
};
})($.fileName.split("/").splice(0,$.fileName.split("/").indexOf("adobe_scripts") + 1).join("/") + "/lib/");
Libraries.include("HelloWorld.jsx");
helloWorld();
It's many moons since I did this stuff ...
Isn't Libraries a function that takes a libPath, so you would need to call
Libraries('c:\whereever').include('HellowWorld.jsx');
I'm doing some studies in Javascript using Twitter website as example. In any website i can open Google Devtools and use the console to manipulate anything on the page, such as get DOM nodes, edit elements and so on.
For instance, when i open 'www.google.com', go to Devtools and type the command above :
console.log('testing');
I get 'testing' string showing in the console.
However, when i open 'www.twitter.com' and do the same thing, NOTHING happens. Nothing is shown in console, just an 'undefined' string as shown below :
Why this behaviour happens only on Twitter website ?
EDIT : Tried the solution proposed on
"delete" - restore native function not working for changed prototype, how then?
But did not work :
In Javascript you can modify your global objects, so it's possible for you to do something like
Array.prototype.push = function(element) {
this[this.length] = 'blah'
}
Now every time you add a element to any array it will always add 'blah';
const myArray = [];
myArray.push(1);
myArray.push(2);
myArray.push(3);
console.log(myArray);
// output ['blah', 'blah', 'blah']
In the twitter website they did the same, although the code is minified you can see it here:
, Y = ["log", "warn", "debug", "info"]
, K = function() {}
, Q = ""
Line 1414 file https://abs.twimg.com/k/en/init.en.caa653749241467e7dbb.js
To make it work again, copy each line and run it on your console (credits for this solution to Rob W):
var frame = document.createElement('iframe');
document.body.appendChild(frame);
console = frame.contentWindow.console
console.log('it works')
If you type in just console.log (without any brackets), you can list the code for the log function on that website. Doing this on Twitter gives you
function (){}
Which is indeed an empty function showing that they've overwritten the default. By contrast, the same on google.com gives
function log() { [native code] }
Which is the default.
I have another question (last question). At the moment i am working on a Node.js project and in this I have many console.log() functions. This has worked okay so far but I also want everything that's written to the console to also be written in a log-file. Can someone please help me?
For example:
Console.log('The value of array position [5] is '+ array[5]);
In my real code its a bit more but this should give you an idea.
Thank you hopefully.
Just run the script in your terminal like this...
node script-file.js > log-file.txt
This tells the shell to write the standard output of the command node script-file.js to your log file instead of the default, which is printing it to the console.
This is called redirection and its very powerful. Say you wanted to write all errors to a separate file...
node script-file.js >log-file.txt 2>error-file.txt
Now all console.log are written to log-file.txt and all console.error are written to error-file.txt
I would use a library instead of re-inventing the wheel. I looked for a log4j-type library on npm, and it came up with https://github.com/nomiddlename/log4js-node
if you want to log to the console and to a file:
var log4js = require('log4js');
log4js.configure({
appenders: [
{ type: 'console' },
{ type: 'file', filename: 'logs/cheese.log', category: 'cheese' }
]
});
now your code can create a new logger with
var logger = log4js.getLogger('cheese');
and use the logger in your code
logger.warn('Cheese is quite smelly.');
logger.info('Cheese is Gouda.');
logger.debug('Cheese is not a food.');
const fs = require('fs');
const myConsole = new console.Console(fs.createWriteStream('./output.txt'));
myConsole.log('hello world');
This will create an output file with all the output which can been triggered through console.log('hello world') inside the console.
This is the easiest way to convert the console.log() output into a text file.`
You could try overriding the built in console.log to do something different.
var originalLog = console.log;
console.log = function(str){
originalLog(str);
// Your extra code
}
However, this places the originalLog into the main scope, so you should try wrapping it in a function. This is called a closure, and you can read more about them here.
(function(){
var originalLog = console.log;
console.log = function(str){
originalLog(str);
// Your extra code
})();
To write files, see this stackoverflow question, and to override console.log even better than the way I showed, see this. Combining these two answers will get you the best possible solution.
Just write your own log function:
function log(message) {
console.log(message);
fs.writeFileSync(...);
}
Then replace all your existing calls to console.log() with log().
#activedecay's answer seems the way to go. However, as of april 30th 2018, I have had trouble with that specific model (node crashed due to the structure of the object passed on to .configure, which seems not to work in the latest version). In spite of that, I've managed to work around an updated solution thanks to nodejs debugging messages...
const myLoggers = require('log4js');
myLoggers.configure({
appenders: { mylogger: { type:"file", filename: "path_to_file/filename" } },
categories: { default: { appenders:["mylogger"], level:"ALL" } }
});
const logger = myLoggers.getLogger("default");
Now if you want to log to said file, you can do it just like activedecay showed you:
logger.warn('Cheese is quite smelly.');
logger.info('Cheese is Gouda.');
logger.debug('Cheese is not a food.');
This however, will not log anything to the console, and since I haven't figured out how to implement multiple appenders in one logger, you can still implement the good old console.log();
PD: I know that this is a somewhat old thread, and that OP's particular problem was already solved, but since I came here for the same purpose, I may as well leave my experience so as to help anyone visiting this thread in the future
Here is simple solution for file logging
#grdon/logger
const logger = require('#grdon/logger')({
defaultLogDirectory : __dirname + "/logs",
})
// ...
logger(someParams, 'logfile.txt')
logger(anotherParams, 'anotherLogFile.log')
I would like to fake Navigator platform property of CasperJS(/PhantomJS). I found the easy solutions of overwriting the Navigator Object at page load which is suggested in many other places on the web:
casper.on('page.initialized', function(){
this.evaluate(function(){
(function(oldNav){
var newNav = {};
[].forEach.call(Object.getOwnPropertyNames(navigator), function(prop){
if (prop === 'platform') {
Object.defineProperty(newNav, prop, {
value: 'Win64'
}); }else {
Object.defineProperty(newNav, prop, {
get: function(){
return oldNav[prop];
}
});
}
});
window.navigator = newNav;
})(window.navigator);
});
});
But the problem is that if we get the Navigator properties from an Iframe, the values are still the original one because, the page.initialized only set it for the main page.
So I opted to change it in its source code and build it again. I downloaded Phantomjs from the git repo, and I searched for a hardcoded platform value(Linux x86_64 for my case). I found the hardcoded string in ./phantomjs/src/qt/qtwebkit/Source/WebCore/platform/qt/UserAgentQt.cpp
I changed it to the string I wanted to be returned as the navigator.platform, but it did not affect the navigator.platform. Where should I change it? Is it(platform) a harcoded string or it is created dynamically?
After reviewing the code, I found out that the following file should be changed:
src/qt/qtwebkit/Source/WebCore/page/NavigatorBase.cpp
and NavigatorBase::platform() should be set to the desired string you would like to be returned as the navigator.platform.
But I'm not sure if it will mess up other things, please give suggestions if it is not an appropriate solution.
I've been banging my head a against this particular brick wall now for more than two days. I am attempting to create an XPCOM service for use in a Firefox extension but am unable to initialise the component with the following error displayed in the error console in Firefox.
Timestamp: 07/06/2012 09:23:28 Error: uncaught exception: [Exception...
"Component returned failure code: 0x80570016 (NS_ERROR_XPC_GS_RETURNED_FAILURE)
[nsIJSCID.getService]" nsresult: "0x80570016 (NS_ERROR_XPC_GS_RETURNED_FAILURE)"
location: "JS frame :: chrome://logger/content/logger.js :: <TOP_LEVEL> :: line 21"
data: no]
I have reduced the component to the bare minimum using the excellent boilerplate generator at ted.mielczarek.org. The component code is as follows...
const nsISupports = Components.interfaces.nsISupports;
const CLASS_ID = Components.ID("808e1607-caea-418c-b563-d9fe1df6ee08");
const CLASS_NAME = "Test component";
const CONTRACT_ID = "#test/loggerservice;1";
function LoggerService() {
this.wrappedJSObject = this;
}
LoggerService.prototype = {
QueryInterface: function(aIID)
{
if (!aIID.equals(nsISupports))
throw Components.results.NS_ERROR_NO_INTERFACE;
return this;
}
}
The remainder of the boilerplate that creates the module and factory interfaces is unchanged.
The chrome.manifest file looks like this...
content logger chrome/content/
skin logger classic/1.0 chrome/skin/
locale logger en-US chrome/locale/en-US/
component {808e1607-caea-418c-b563-d9fe1df6ee08} components/loggerservice.js
contract #test/loggerservice;1 {808e1607-caea-418c-b563-d9fe1df6ee08}
overlay chrome://browser/content/browser.xul chrome://logger/content/logger-overlay.xul
style chrome://global/content/customizeToolbar.xul chrome://logger/skin/overlay.css
Finally, the logger-overlay.xul file includes a script file - logger.js - which attempts to get a reference to the LoggerService component using the following code...
this.loggerService = Components.classes["#test/logger;1"].getService().wrappedJSObject;
and it is this line that is reporting in the firefox error console.
I can't see how much simpler I can make it - any insight would be very much appreciated.
This is a nice boilerplate generator but unfortunately an outdated one. For one, you should be using XPCOMUtils, this will get rid of most of the boilerplate. More importantly, this boilerplace generator hasn't been updated to XPCOM changes in Gecko 2.0 and defines NSGetModule function instead of NSGetFactory. Module code like this should work however:
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
function LoggerService() {
this.wrappedJSObject = this;
}
LoggerService.prototype = {
classID: Components.ID("808e1607-caea-418c-b563-d9fe1df6ee08"),
classDescription: "Test component",
contractID: "#test/loggerservice;1",
QueryInterface: XPCOMUtils.generateQI([])
}
if ("generateNSGetFactory" in XPCOMUtils)
var NSGetFactory = XPCOMUtils.generateNSGetFactory([LoggerService]); // 2.0+
else
var NSGetModule = XPCOMUtils.generateNSGetModule([LoggerService]); // 1.9.x
You can remove the NSGetModule code if your extension doesn't need to be compatible with Firefox 3.6. You can also remove the classDescription and contractID properties then, these are specified in chrome.manifest already.
Note: If you only need an object that will stay around for the entire browsing session and can be accessed from anywhere then a JavaScript code module would be a better choice - no XPCOM boilerplate and no wrappedJSObject hacks.