Running browser javascript unit tests in node - javascript

I've got a project that I'd like to move the testing from rhino to nodejs for (rhino simply takes too long to start and load in envjs). This is the current blocker before being able to move forward:
ExampleSingleton = new function () {
var something = someFunction () {/*Does something*/}
$(window).bind('resize', something);
}();
This complains about window not being defined - I don't know how to get the 'window' that I made in the shell (#!/usr/bin/env node) script that I wrote (see below, and pardon the chaos, as I've gotten to that "try anything and everything" point).
var dom = require("jsdom").jsdom()
var window = global.window = dom.createWindow();
global.jQuery = require("jQuery");
global.$ = global.jQuery;
....
require("path/to/file"); //This is where it breaks, before the tests even start
I've tried reading in and eval'ing as well, but that didn't much help and of course the error was masked because it was an anonymous function.
Am I trying to do the impossible here? Or is there a very simple browser friendly thing I can do to get this working?

Have you thought about using PhantomJS instead of node?
PhantomJS is a headless WebKit with JavaScript API. It has fast and
native support for various web standards: DOM handling, CSS selector,
JSON, Canvas, and SVG.
PhantomJS is an optimal solution for fast headless testing, site
scraping, pages capture, SVG renderer, network monitoring and many
other use cases.
Because it is a real browser, you won't need jsdom or envjs. JavaScript continuous testing with QUnit, PhantomJS and Powershell might help you get started.

Related

Test DOM methods in javascript IDE not in browser console

I am wondering why when using any IDE that support javascript language if you try to get element of HTML page using document.querySelectorAll() or any DOM selector method it will return run time error ReferenceError: document is not defined ?
is the reason that document only defined in browser javascript build in console ?
my problem that I only need to run javascript app on my IDE not on browser console to test it.
if there is any suggested solution please mention it.
What do you mean by run "on my IDE" ?
I think you rather talking about rendering on server side.
Either way, yeah the document exist solely on the browser, if nothing is done to mock it. but there are solutions to mock the document, for example, jsdom :
https://github.com/tmpvar/jsdom
It is useful for example for running unit tests on server side, without browser, to test UI components which require DOM and have some logic.
Finally solution that worked in my case using Nodejs,jQuery and jsdom library as suggested in jony89's answer.
in newer jsdom v10 API I should parse my HTML page into JSDOM constructor to get the result that I expected.
but it's difficult and inconvenient to pass the whole HTML page to JSDOM constructor so I used another simpler way to solve it using older jsdom API and exactly by jsdom.env() method :
https://github.com/tmpvar/jsdom/blob/master/lib/old-api.md
I pass the page url that I want to use DOM methods on it and then print the output on my nodejs IDE:
var jsdom = require("jsdom/lib/old-api.js");
jsdom.env(
"http://www.ammanu.edu.jo/English/Research/Research.aspx",
["http://code.jquery.com/jquery.js"],
function (err, window) {
var $ = window.$;
var a = $("section a");
for(var i = 0; i < a.length; i++){
console.log(a[i].getAttribute("href"));
}
}
);

Most performant way to execute JS within a webpage in Ruby (HtmlUnit, Celerity, PhantomJS, CasperJS ...)

What's the most performant way to execute JS directly after a HTTP request in JRuby? I know about all the test frameworks like HtmlUnit, Celerity, Capybara + PhantomJS == Poltergeist, CasperJS etc. but they're still test frameworks.
What I need is a simple way to execute all JS code which is included in HTML after fetching the URL e.g. by Net::Http.
First of all, it goes with out saying: DON'T DO THIS IN PRODUCTION!
Executing some script that's been pulled from somewhere on the internet is a recipe for disaster. If you're using it as part of your testing infrastructure, it may be of some use but I'd guess that there's a simpler way to solve your problem.
To answer the more general question, here's how you'd initialize a JavaScript engine bundled with JDK 1.6+ (effectively a cut down version of Rhino, although this will change in Java 8 probably):
import javax.script.ScriptEngineManager
import javax.script.SimpleBindings
manager = ScriptEngineManager.new
engine = manager.getEngineByName("JavaScript")
bindings = SimpleBindings.new
bindings['x'] = 1
engine.eval("print(x)", bindings)
Getting your engine to evaluate any dependencies like jQuery is left as an exercise to the user. Have a look at the javax.script JavaDoc.
If you need more control over the evaluation environment you'll have to use Rhino directly, or wait for Nashorn...

Workflow/tools for frontend javascript development/test and production?

A Web frontend javascript application, in production, will have little to nothing "exposed", that is, declared as a global var or attached to window.
all code minimized and appended to one (or a few) js file(s);
little to nothing "exposed", that is, declared as a global var or attached to window.
During development, though, life is easier if the code is readable, split in several files, and also if prototypes and relevant instances are accessible from console.
To be more clear (leaving aside minimization, which is easy obtained with a number of different tools), in production I'll have something like:
(function() {
var Greeter = function() {
};
Greeter.prototype.msg = function() {
return 'Hello, world!';
};
Greeter.prototype.greet = function() {
console.log(this.msg());
};
new Greeter().greet();
}());
This way, my code will do its stuff without exposing anything: neither the Greeter object nor its instances are accessible to other code.
(Of course this is just one of many ways to accomplish this, but that's not the point of the question).
Debugging this code, though, is hard, and unit testing is impossible.
In order to allow both debugging and testing, I would usually attach both Greeter and its instance to the window object, or to some other object.
So, during development, I'll use something like:
(function() {
var Greeter = function() {
};
Greeter.prototype.msg = function() {
return 'Hello, world!';
};
Greeter.prototype.greet = function() {
console.log(this.msg());
};
window.Greeter = Greeter;
window.greeter = new Greeter();
window.greeter.greet();
}());
This way I'll be able to unit test Greeter, and also to interrogate it from the browser's console to check its status.
Is there a tool, or a set of tools, or some different way to organize my code, so that it's possible to pass from the development version to the production one (which will also be minimized)?
There is no single package or executable you can install that will get you 100% of the way there. You will need to combine an editor, command line tools and your browser to create an effective web application / javascript development environment.
3.18.13: Added a link for Sublime Web Inspector. Debug Javascript inside of Sublime Text! http://sokolovstas.github.com/SublimeWebInspector/
Editor
Things to look for: Plugin system, system highlighting, linting, autocomplete. If you are using an editor today that supports plugins your best bet is to stick with it and setup linting and syntax highlighting. If you are looking for some recommendations all of the following are solid choices.
Sublime Text 2 (free trial)
Textmate (commercial, 30 day trial)
VIM (free)
Webstorm (commercial, 30 day trial)
Workflow Tools:
I recommend starting with a high level toolset like Yeoman or lineman. They are somewhat opinionated but provide a complete workflow and will allow you to get stuff done quickly. Once you are comfortable with using it you can peek under the covers and pick and customize it to your needs.
Yeoman : Provides scaffolding, package management, dev server, concatenate & minify and will run specs
Lineman: Dev server, concatenate & minify, run specs
Grunt: More low level (used by both Yeoman and Lineman). Similar to ruby's rake
VCS: Not to be overlooked, a good command line based VCS is essential. I recommend Git, again use what you are comfortable with to start.
Browser:
The development tools in the browser will provide you with a console, and debugging tool. Spend some time researching and really getting to know how to use the development tools provided in the browser. They are extremely powerful.
Webkit browser (Chrome or Safari): Built in Developer Tools (Command option J).
Firefox + firebug
Browser testing: Highly recommend browserstack for cross browser testing.

Using third-party JS libraries in Mozilla Add-On SDK

I'm starting a new project (Firefox add-on) and I'd like to try using behavior-driven development. I particularly like the Jasmine BDD library. However, I can't find a good way how to use a framework such as Jasmine in the Add-On SDK.
One problem is that Jasmine needs setTimeout (and similar) functions to be specified on the global object, whereas Add-On SDK exports those using "timers" module. But let's say I tweak Jasmine to get those object from "timers" (or add the the methods exported by timers to the global object).
The bigger problem is that I don't know how to actually run the tests. There is a test directory generated by the SDK, however, there's no window or document object there to allow me to see the output (and I'd really like to see the fancy HTML output). I guess I could create a content script that would modify the page, but then I can't access (test) the background script.
Have you ever faced this before? Is there any recommended way how to deal with that?
Thanks!
Tomas
You can use the Add-on SDK windows API to open a new window to run your tests in. You should be able to load the Jasmine script(s) with the subscript loader and set window and document to whatever you want in the scope of that subscript:
var windows = require("windows").browserWindows;
windows.open({
url: "about:blank",
onOpen: function(window) {
var script;
var scriptLoader = Cc["#mozilla.org/moz/jssubscript-loader;1"].
getService(Ci.mozIJSSubScriptLoader);
scriptLoader.loadSubScript(subscriptSpec, script);
script["window"] = window;
script["document"] = window.document;
// ... run your tests here by calling script.someFunc() ...
}
});
Update: Further research shows that the browserWindows are actually special wrappers that don't give you access to the content window. You might try getting a window/document from a hidden frame. That's the only way I can see to get access to an HTML document from privileged code.

Tutorial for using JavaScript on a Desktop

I need to do some scripts in java script.
I am working on it but couldn't find a few solutions to a few problems.
First of all I need a GOOD tutorial, but not for an internet page but for a DESKTOP script.
Things couldn't find out like :
1) I wanted a simple message box in order to debug my program, I used:
var name = prompt("What is your name","Type Name Here");
When running it I get error of "Object expected"
2) Couldn't find how to open a file
Based on your comments, I guess that you are attempting to run a JavaScript file directly on Windows. Double-clicking on a .js file in windows will (probably) run it in Windows Script Host.
The prompt() function will not work this way, since WSH provides a completely different API than browser-embedded engines.
The following code should accomplish your intentions. However if you want anything more than a simple popup, HTAs are the only way to do complex GUIs with JScript on the desktop.
var fso, ws, ts;
fso = new ActiveXObject('Scripting.FileSystemObject');
ws = WScript.CreateObject('WScript.Shell');
var ForWriting= 2;
ts = fso.OpenTextFile('foo.txt', ForWriting, true);
ts.WriteLine(new Date().getTime());
ts.Close();
ws.Popup('Wrote to file!');
var ForReading= 1;
ts = fso.OpenTextFile('foo.txt', ForReading, false);
var fileContents = ts.ReadLine();
ts.Close();
ws.Popup('The file contained: ' + fileContents);
WScript.Quit();
I have to ask: why is JavaScript the right tool for the job? Why not use a scripting language intended to be used this way, such as Python, Ruby, Lua, ... etc?
If you are using Microsoft's JScript (and it sounds like you are), look to the MSDN web site for help. The page here looks fairly good. Google can also help with that.
Assuming you don't mind using Java, you could also use the Mozilla Rhino shell. But it doesn't look like there is a standard way of reading from the console in JavaScript. (presumably since this is not something typically required in a JavaScript application...) The built in JavaScript functions in the shell seem fairly basic, but you can read a file.
There area also examples of using Rhino, which may be helpful. You can interface with the Java API to do whatever else you need to do.
Edit: I wrote this answer a long time ago; today I would use node.js. See their learning page.
The latest prerelease of Opera acts as a runtime for JS applications.
They have tutorials describing how to use it.
I used: var name = prompt("What is your name","Type Name Here");
When running it I get error of "Object expected"
Presumably your runtime doesn't implement prompt that in a way that is compatible with those arguments.
2) Couldn't find how to open a file
This depends on the runtime you use. JS itself doesn't have anything built in to read files (or display a prompt). You need an environment that provides those objects.

Categories

Resources