TDD javascript in NetBeans

The book Test-Driven JavaScript Development is great, http://tddjs.com/
. It indeed changed my thoughts on javascript,  it is such a powerful dynamic language, very close to ruby, e.g. similar features like everything is object, including functions. While some other feature like hoist variable declaration, this variable scope and closure are very weird.

JsTestDriver is very successful xUnit like test environment. Its community is very active, during only 3 days while I was playing it,  its version bumped from 1.2.2. to 1.3.0!

It’s very annoying that there is no GUI Runner for jsRunner , but picking NetBeans as my javascript IDE seems not a bad choice. I really like the ALT+Shit+F to reformat feature.

Here is some trick to embed jsTestDriver in NetBeans.

  1. Create Ruby project to hold all those javascript source code.
  2. Create Rake file at project root, content look like this:
    
    directory "test/output"
    
    task :run_js_test => "test/output" do
      ff = "C:\\Program Files\\Mozilla Firefox\\firefox.exe"
      output = "--testOutput test/output"
      sh "java -jar tools/JsTestDriver-1.3.0.jar --port 4224 --tests all #{output} --browser  \"#{ff}\" "
    end
    
    task :default => [ :run_js_test ]
    
    
  3. Run this Rake file, we can see the test results from output window:
    Note: Those MUST be a space before the dash in front of coverage name in conf file, otherwise you will get an error:while scanning a block mapping
    expected , but found org.jvyaml.tokens.BlockMappingStartToken
    org.jvyaml.ParserException: ParserException while scanning a block mapping we had this expected , but found org.jvyaml.tokens.BlockMappingStartToken

Room to improve for NetBeans IDE:

  • View codecoverage data file in IDE (Windows ENV)
  • GUI view of those test results
  • Better embed of those test-cases.

All those features already exist in NetBeans Ruby IDE, hope in the future it can also apply for javascript.

Advertisements

jQuery releases Javascript pain

I have a html page to display xml files from the same server. The reasons I didn’t use the server side script includes

  1. ruby needs rails, but I don’t want to create an application for this single page. I tried to run ruby as cgi, no success.
  2. maggiePie can make php eaiser, but I think it’s still kind of overkill for this simple use.

Then I turned to client-side javascript. At first I use this function to load xml file:

function loadXMLtoDIV(file, div_name) {

var xmlDoc = null;

var moz = (typeof document.implementation != ‘undefined’)
&& (typeof document.implementation.createDocument != ‘undefined’);
var ie = (typeof window.ActiveXObject != ‘undefined’);

if (moz) {

xmlDoc = document.implementation.createDocument(“”, “”, null);
xmlDoc.load(file);
xmlDoc.onload = function() { readXML(xmlDoc, div_name); };

} else if (ie) {

xmlDoc = new ActiveXObject(“Microsoft.XMLDOM”);
xmlDoc.async = false;
while(xmlDoc.readyState != 4) {};
xmlDoc.load(file);
readXML(xmlDoc, div_name);
}

}

It worked very well, and I like it until I tried use jQuery:

function XmlOnLoad( xmlData, divId ){

// Get the first 2 items
var jItems = jQuery(‘item:lt(2)’, xmlData);

var jDiv = $( divId );

// reset.
jDiv.html(”);

jItems.each(
function( ){
jDiv.append( $(this).find(‘pubDate’).text() + ‘ : ‘ +$(this).find(‘title’).eq(0).text() +'<br/>’);
}
);
}
function GetXMLData(file, divId){
$.get(file,{},
function(xmlData, status) {
XmlOnLoad(xmlData, divId);
} );

}

And another benefit from jQuery is, I can move those ‘behavior’ from the presentation part. This jQuery ‘onload’ function is to add an universal click event to all the itemlist class div. By doing this my html elements look much neater.

$(function(){

$(“div.itemlist”).each(

function(n){
var current = this;

$(“<a href=”>See latest items … </a>”).click(  function(event){
GetXMLData(   “#”+current.id); return false;}  ).appendTo($(this));
}
);

})

One thing I still don’t understand, if I tried to load too many xml file into the page elements, some xml files just missed. jQuery still doesn’t fix this problem. But coverting from loading to ajax using jQuery is so easy, so I didn’t spent too much time on it at all.

For those TDD fans, you want to look in this QUnit intro.

Looking for Cookie, ForceClick?

I created a podcast which needs get file from an internet network drive provider. I found a good post explaining how to cheat this provider by passing WGet using a cookie option. But I was having a hard time to get this cookie from that site. I tried all kind of different options in wget, and curl, neither one works.

Last night, when I was doing the normal hunting for cookie, I realized this cookie is not generated by post-form or get-request, instead it’s generated by my clicking on the actual link. Javascript!?

Finally, I found that cookie is hidden in the page, as an setkey javascript function. Gee, what a high technology they are using to force user clicking the link when downloading.

During this procedure, I learned some very useful tips,

  1. An great add-on to firefox, Live Http header
  2. WGet, Curl advance options, to save cookie, save header, debug output, print server responce etc.

I also damaged my old Toshiba 4220 laptop by accident during this hunting. This old machine used to be my primary ruby and php coding workstation, but now with pcmcia slot broken, it’s too old to do any developing work any more, hunting for next one.

Browser’s Back button issue

Again, back button problem. I created a jsp page which is not supposed to be backed into from other pages. The following solutions have come to my mind.

Flush, expire form

I started from expire form by adding those famous flush code:

<%@ page autoFlush=”true” %>
<%
response.setDateHeader(“Expires”, 0);
response.setHeader(“Cache-Control”, “no-cache”);
//for old browser that use Pragma instead of Cache-Control”
response.setHeader(“Pragma”, “no-cache”);
%>

It works, kind of. IE shows a standard “page has expired” page, FF pop-up a confirmation window saying Do you want to re-submit? That’s not want I want.

Referer, where-are-you-from url

Then I tried to catch the where-are-you-from url which can be read from server side:

request.getHeader(“Referer”)

or client side:

document.referrer

Unfortunately, when clicking back button, the content of my page has already be cached, both referer keep the old url, not the one I back from.

Same problem happened when trying to use request.setAttribute. The page won’t be re-run or server side when being backed in.

History.previous, obsolete already

Lots of solutions regarding to add history.go(1) or history. forward. But I need history.back, only execute when being back in.

There used to be a history.previous, or histroy[-1].url, for security reason, all the modern browsers have disable this property. Damn!

Onunload? redirect in backing page.

Somebody got this idea to catch window.onunload() event. or, onbeforunload().

Quirksmode has a very good example about this. This almost reach me goal. Works great in IE, not FF. Even in IE, the onunload event also interfere user leaving my site.

Cookie, old fashon, but it works

Then I came to cookie, in no-back-in page, put these code

if (getCookie(“loginsubmitted”) == 1) {
location.replace(“login.jsp”);
//login.jsp needs to do this: setCookie(“loginsubmitted”, 0);
}else{
document.formLogin.submit();
setCookie(“loginsubmitted”, 1);
}

Only one problem, if users disable cookie in their browser the loginfailed page won’t back here then back to itself. Fortunately, that’s very rare, they can’t login normally by doing that.