Functional Testing of the Android Webview using Java: How purity was invented

A long while ago, we decided to start doing native testing of Android, mostly because we found that we were fixing the same things over and over again on Android in Java.  While the Javascript quality was higher, the Java code was generally the same as when I first wrote PhoneGap back in 2008.  So, we started with manual tests.  Then I got creative and threw in some JUnit tests back when I started working on CordovaWebView.

However, there was something that was nagging us about the manual tests.  Many of these tests required us to click on user interfaces that were implemented in HTML and Javascript.  First we tried to adapt things such as WebDriver to test this, but we found that this was extremely complex to get working on Cordova, and we only ever managed to get an abandoned branch to work with the custom CordovaWebView.  At the end this was completely unmanageable, and we abandoned this work.

However, the tickets remained, such as ones like “Automate JQTouch Tab test” or “Automate iFrame Test”.  The JQTouch one was abandoned because of these develpments, but along the way we discovered how to test the Android WebView using Java and JUnit.

The Android Test Framework gives you some very limited UI functionality tools.  These tools are designed for the Android UI and, they mostly consist of things like TouchUtils.  TouchUtils allows you to click in the middle of view like this:


touch.clickView(this, testView);

This may be super awesome for Android applications, but this sucks for things like Cordova, which is one giant view.  To prove this point, I ressurected some Canvas code that I wrote three years ago and I do some tests on it.

crap_setting

Above, you can see the click happen in the middle. It will always happen in the middle.  There is nothing that I can do to make it not happen in the middle.  This sucks.

I then googled around to see if I can get per-pixel support, and I found a blog post that showed this code:


long downTime = SystemClock.uptimeMillis();
// event time MUST be retrieved only by this way!
long eventTime = SystemClock.uptimeMillis();
Instrumentation inst = getInstrumentation();
MotionEvent event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_DOWN, 300, 300, 0);
inst.sendPointerSync(event);

Now, this code is great, except that anyone who has done any Mobile Web Development knows that a pixel is not a pixel.  We have to factor in the screen density.  This is where purity comes in.

In purity, instead of giving the real pixels in Java, you pass in the WebKit pixels, and purity does the calculation required to do the touch where you want it.  The reason it’s called purity is because it’s simple, and it doesn’t clutter up your Javascript with event handlers and injection code.  Eventually, this may be adapted to be a plugin so that purity code can be written in Javascript, but entirely run in Java.

For example, in purity, you would call this to do a touch event:

touchTool = new Purity(testActivity, getInstrumentation());
touchTool.touch(50, 200);

OK, where is the code:

The code is in the Cordova Android test directory on my personal branch here, and it is under org.apache.cordova.test.util. It’d be awesome if someone wanted to make this a third-party plugin, especially those people who have extreme pain with UI interaction on Android.

will_paginate and Ajax pagination

One thing that I’ve been using a lot is will_paginate and it’s derivatives, such as merb_paginate, ultraminx and ultrasphinx. One problem that I noticed with merb_paginate was that it didn’t want to use the restful paths in the merb app that I was using. This was rather annoying, since I was trying to make my merb app almost entirely restful, except for the home controller. So, instead of using paginator, I decided that I wanted to add ajax pagination.

The first step that needs to be done is to create a create and delete js view. This is extremely basic. I have some code that does this in one of my github repositories. Namely, the sparty_server code.

In the controller, uncomment this line as usual. We are going to be sending back json:

 provides :xml, :yaml, :js

Then create the following *.js.erb files:

index.js.erb

var events = "";
<%= partial "widgets", :with => @widgets %>
<%= partial "shared/paginate", :items => @widgets %>
$jQ("#main_eventlist").empty();
$jQ("#main_eventlist").append(events);
$jQ(".pagination").empty();
$jQ(".pagination").append(navigation);

Note that you should really make this so that it uses your jQuery variable. Here, we’re not using noConflict. noConflict should almost always be used, since you most likely will be using a non-jQuery item with your software. We also created two partials, namely one that just lists the lists. This could be used for anything that will update inside a div. The other thing that we created is a pagination partial, which is just a string definition.

This is pretty obvious. This just uses the methods present in all will_paginate derived objects to determine which page is present. One thing that we found is that we don’t always have access to all the methods and attributes, which is why it looks rather odd.

Here’s the javascript code that does the pagination:

var prevPaginate = function(id)
{
  items = id.split('_')[1];
  current_page = id.split('_')[2];
  next_page = parseInt(current_page) - 1;
  next_page_key = "#page_" + next_page;
  uri = parseMerbUri(window.location.href);
  good_uri = window.location.href.split("#")[0];
  next_page_key = good_uri + next_page_key;
  hist.add(next_page_key);

  query_string = uri + "?page=" + next_page;
  if(next_page > 0)
  {
    jQuery.get(query_string, function(data){eval(data);});
    return false;
  }
}

var nextPaginate = function(id)
{
  items = id.split('_')[1];
  current_page = id.split('_')[2];
  next_page = parseInt(current_page) + 1;
  uri = parseMerbUri(window.location.href);
  good_uri = window.location.href.split("#")[0];
  next_page_key = good_uri + "#page_" + current_page;
  hist.add(next_page_key);

  query_string = uri + "?page=" + next_page;
  jQuery.get(query_string, function(data){eval(data);});
  return false;
}

Of course, we have a method that parses the URI so that we are going to the right resource. This is important for nested resources to do this, since we want to display the correct results. We also use the Nitobi history in this case because we want the back button to use the pagination, and not go back to the previous page in the history.

I’m going to make this more generic in the next couple of weeks and post the code to the blog, however this should be rather trivial for anyone to do once they know how will_paginate works and how to use the json data that it sends back.

Mesh Wireless goes to the Mainstream, (maybe)

I have a hobby of hacking the firmware on the Linksys WRT54G. I originally started doing it because I wanted to learn about how Embedded Linux worked, and I thought it was cool that it could run Linux. That’s how I got introduced to the Community Wireless movement.

Basically, the problem with the DIY Community Wireless hacking is that you’d have to either take off the shelf routers, flash them (and void your warantee) and then hope that you got something working. Then you can write applications for it like WifiDog, or various Mesh Networking Applications such as Optimised Link State Routing. This was great, but it ran into two big problems:

  1. It’s hard to convince someone to run a hacked Linksys router in their home, because it looks sketchy
  2. You’re at the whim of the manufacturer, who may not like that you can extend your hardware, or may change the hardware randomly or End of Life(EOL) it because they can make something that is cheaper.

In fact, the original Linksys WRT54G was changed after Version 4.0 to run vxworks because it took less processing power, voltage and memory to do what they wanted than they needed from their prior cookie-cutter design. Also, Netgear also discontinued the WGT634U because of similar logic. The reason I mention the WGT634U router is because that is what MIT Roofnet originally used to build the prototypes for what is now Meraki Mesh.

After BarCamp and talking to Boris at Bryght, I decided to buy some Meraki hardware. Now, I was expecting some unmarked boxes, and the devices to be large, but I was very suprised to find a branded box, like what you would find in FutureShop, and a very small device. Not only that, but it is extremely user friendly. I was also impressed with the range of the device. I put one in my Window at my apartment, and it seems to have a 100m (about 300 ft) range. Now, this is important, since the way mesh works is that you put a bunch of mesh nodes out into the world, and they route between each other to the nearest gateway node, the node with the least latency.

When I compare the Meraki out-of-the-box solution to the alternative, which is the Freifunk OLSR, there’s really no comparison for how easy it is to use. I think that Meraki has a very interesting project and it’s worth testing out. The main advantage of us testing out mesh is obvious, since we can facilitate a test bed for Ajax components in mobile devices right outside our window. With the release of the iPhone and the iPod touch (more importantly the iPod Touch, since we’re in Canada), content that is dynamic, and takes advantage of both geography, as well as the various user agents, is critical to providing a user experience like nothing else.

With more and more mobile devices equipped with Wifi for mass adoption, it just makes sense to at least play with the stuff. I’ll have pictures up here soon of us playing with the hardware!

Nitobi Grid on Rails – Part 1

Even though we’re doing a lot of work in Ruby on Rails, and we blog about it a lot, we don’t sell a back-end for it. So the question that people may ask is how do we use our Components with Rails?

Here’s some information on how I’m using Rails with the current version of Grid. In Rails, you can use Builder to create XML, so the first thing that I am going to create is a grid controller. In that grid controller, I define a getHandler method, which looks like this:


def getHandler
if params[:SortColumn].nil?
@tblcustomer_pages, @tblcustomers = paginate :tblcustomers, :per_page => params[:PageSize].to_i
else
@tblcustomer_pages, @tblcustomers = paginate :tblcustomers, :per_page => params[:PageSize].to_i , :order => params[:SortColumn] + " " + params[:SortDirection]
end
render :layout => false
end

What this does is use the paginate function to do some pagination of the table. We set the PageSize using the Nitobi Grid’s PageSize paramater, and we use the SortColumn and the SortDirection coming into the function from the grid to determine the column sorting.

I then have a view (rxml) that looks like this:


xml.instruct! :xml, :version => "1.0"
xml.root(:fields => "CustomerName|ContactName", :keys => "CustomerName|ContactName") {
for tblcustomer in @tblcustomers
xml.e(:a => tblcustomer.CustomerName,:b =>tblcustomer.ContactName, :xk => tblcustomer.CustomerID)
end
}

This is very basic. I’m just starting out with builder, so I don’t have the Error Handler here. I suppose that I should have that there, but I don’t know what will happen if its nil. (I suspect it will break). That’s definitely something I’m going to have to ask around about.

And, I make sure that I have the getHandler set in the Grid Definition like this:


gethandler="getHandler/"

Of course, I make sure to include grid and toolkit. Once this is all done, I have a grid that can load. I still have to get the savehandler working on Rails, but this should be enough to get started with Rails. If I find any interesting interactions with Grid, Toolkit and Prototype, I’ll post them here.

This isn't directly work related, but this is the coolest thing I ever made!!!!

I just finished hacking a bunch of Infrared LED lights, and here is a picture of the results:

My FTIR Table

So, this is a picture of my hand. This picture was taken by an off the shelf webcam that I modified to only pick up IR light. My hand is touching a piece of acrylic which has LEDs lighting the edges of it. When my hand touches the Acrylic, this causes the tips of my hand and the heel of my palm to form white blobs which can then be tracked by software. This is called FTIR. I now have a multi-touch interface, similar to the Microsoft Surface sitting at my home. The best part about it is that it’s cost me less than $400 to make. This touch screen is very similar to what Jeff Han is doing at his company, Perceptive Pixel.

This is mentioned on this blog because I think this changes everything. This is evident because of the upcoming release of the iPhone, which is also multi-touch. I think with devices like the table that I built (using instructions from multitouch.nl), Microsoft Surface and the iPhone, onclick may become antiquated. Of course someone already made something for Flash, so I guess that means that Adobe is already prepared for this, but what about the rest of us??

It’s definitely food for thought. I’ll be posting updates about the table to this blog, so stay tuned!