gib is short for gilbert

and also "big" spelled backwards

¡Hola Octopress!

It’s time for a change! I ditched Posterous. Say hello to Octopress.

Coming soon…

  • new design
  • more experiments
  • useful github projects

Px or Percent?

Note to self: Most browsers give px results from jQuery css retrieval even if they’re set as percentages.

When working with jQuery UI Sliders, it can be nice to use percentages for positioning. However, it’s good to know that only webkit browsers return an element’s css values in percentages.

Webkit browsers (Chrome/Safari):

1
2
$('.slider-handle').css('left');
// returns 46.234234%

Others:

1
2
$('.slider-handle').css('left');
// returns 53px

A Päst(ə)rəs Apology

I can’t believe this. I’ve been saying it wrong for years. Years. I’ve incorrectly corrected clients, co-workers, friends, my wife

Here it goes. I was wrong. Wrong! For the two of you out there reading this, I acknowledge you are reading a Posterous (päst(ə)rəs) blog. Posterous as in pre-posterous minus the “pre”. Like pasta with an “erous” at the end.

How many times did I say, “That makes no sense!”?

“Clearly the service is POST-erous. You’re POSTing on the web! Their home page has (used to have) a giant yellow POST-it note on it. Do you think that is a PÄST-it note?”, I would say.

I just finished watching a video on the new home page explaining Posterous Spaces and clearly, several times, the narrator said, päst(ə)rəs.

And yet… I’m typing this post in a form titled “Create a Post”.

Maybe it’s time to switch to tümblr?

Update March 24, 2012

You’re reading an Octopress blog! I wrote a post about it.

Faking It on LinkedIn

About a week ago I got this message through LinkedIn. It looked like a common recruiter shout out, but something caught my eye. Specifically the line, “How are things going for you at Art.sy? I’ve heard the company is experiencing some difficulties so, even if you’re planing on staying if things turn around…”.

Statistically speaking, in the current economy, a high percentage of companies could be labeled as “experiencing some difficulties”. That probably holds true for any time actually. Still, I felt like I had stumbled into a psychic cold reading… “I’m getting something about the money? Do you have any connection to the money?”. It felt a little creepy.

Nathan Hurst is the founder of HireLite, Speed Dating for Hiring. He’s written a nice post titled Black Hat Recruiter Tactics and this made the list (faking a relationship).

I also noticed that this recruiter has an InMail Feedback rating of five stars. He does have a few firms that work “exclusively with [him], and no one else”. Maybe I’m just being cyncial, and lacking in trust?

Preparing for the Evolution to HTML5

Art.sy sent me to DevCon5 at NYU a few weeks ago. What a great title. It gets better, “DevCon5: Prepare for the evolution to HTML5”. You know what happens to those that don’t evolve?

EXTINCTION. Are you scared yet?

Word play really is the best play.

So the term “HTML5” carries a lot more than markup: CSS3, offline storage, 3D! Checkout the HTML5 logo page for the complete picture.

Not Your Father’s Web Apps

I think the most inspiring presentation I saw was Charles Jolley’s (creator of the SproutCore JavaScript framework and CEO of Strobe), HTML5 Is The Future (But Not Like You Think).

I remember when SproutCore was released after Apple mirrored their new iPhoto events with MobileMe galleries. Steve Jobs demoed the web galleries in his keynote and while I knew what was possible in a web browser, I was blown away. When I went to MobileMe and looked under the hood, I was led to SproutCore. SproutCore also drives Apple’s new iCloud web applications.

Jolly described a future of multi-head applications (aka multi-screen, multi-client, multi-device). Some possible elements of “multi”: * A web app to run in a desktop browser * A mobile web app optimized for mobile devices (maybe a tablet optimized web app too?) * iOS/Android/WebOS/RIM/Windows? native app for phones * iOS/Android/WebOS/RIM native app for tablets * Televisions? * Game Consoles? * Refrigerators?

That’s a lot of clients. Check out this article that discusses how Netflix is coping with over four hundred devices. Spoiler alert… HTML5 is a big part of their solution. HTML5 and a custom build of Webkit to run it on.

The Trifecta

Maybe your app doesn’t need to support 400+ devices. Let’s settle on smart phones, tablets, and traditional web browers (the Trifecta!). Jolley mentioned the different ways these sets of devices are interacted with. Each user interface must be designed specifically for the device that will run it.

Jakob Nielson is a well known web usuability guru. His article, Transmedia Design for the 3 Screens (Make That 5), offers some insite on how different screen sizes are used. The data presented here can help developers focus and prioritize their efforts. Not surprisingly, for many applications, the standard PC still offers the most benefit. When supporting “multi”, Nielson strongly advocates separate and distinct UIs accross devices:

Create separate and distinct UI designs for device categories that are sufficiently different. It’s okay to have a similar design for, say, iOS and Android, with only a few modifications to suit each platform vendor’s human interface guidelines. But your mobile sites and full desktop sites must be different, just as your mobile and desktop applications should be different.

He defines a transmedia design strategy as focusing on success in balancing these four areas: visual continuity, feature continuity, data continuity, and content continuity.

To conclude: cross-platform UIs should be different but similar.

A Basic Strategy

While the unique business goals of each device’s interface can get quite complex, we can apply good software design principles to a larger system and reap the same benefits.

  1. A RESTful (HTTP) JSON API

    HTML5 apps, iOS, and Android all speak HTTP, the data transfer protocol of the web. Decoupling your data and common logic through a [RESTful](http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods) API is the first step to supporting multiple applications on different devices. This layer can be independently tested, versioned, and abstracts all of the common concerns any client application will require.

    (I specified JSON above because XML isn’t a great fit for the HTML5 clients consuming the API.)

  2. Thick HTML5 Clients

    This is the future Chris Jolley presented. Thick HTML5 web clients with common JavaScript layers that can be deployed on different devices. In some cases these common JavaScript layers can be leveraged in “hybrid” mobile apps that can be packaged as an iOS or Android native application while still using web technologies for much of the UI.

Art.sy

We’re taking this approach at Art.sy. Supporting smart phones and tablets is part of our core mission of helping people discover art while they’re out enjoying it as well as researching at home on a PC. We started with an API from day one and plan to decouple thick clients for web as well as mobile devices.

It’s a very exciting time to be developing with web technologies and the future looks very bright for HTML5. While we need not fear extinction, clearly HTML5 offers a lot to multi-device supported systems and is worth investing in.

FireFox 6 Broke My Selenium Tests

Here’s Mozilla’s public FTP server where you can download older versions:

ftp://ftp.mozilla.org/pub/mozilla.org/firefox/releases/k

Running any tests that use the Selenium web driver (Jasmine and Capybara for me) fail to run. The web driver can’t get a stable connection:

1
unable to obtain stable firefox connection in 60 seconds

Rolled back FireFox (to version 5.0.1) and I’m testing again.


Update: (March 26, 2012)

This is all good to go again. I was referring to a Rails project above using the selenium-webdriver. Update it to >2.20 and you can stop rolling back your FireFox.

Wait, Wait, Don’t Test Me

We rely on Capybara’s Selenium web driver for integration testing. After getting over the headless integration server hurdle for Selenium tests that require FireFox, we were able to test a lot of JavaScript functionality in our app. We’ve got great coverage and currently run over 1300 tests.

In general, they say with more power comes more responsibility. Alas, our CI server is destined for ever-growing responsibility on the same virtual hardware (for the time being anyway). This led to an intersting bit of growing pains, i.e. test failures. The common issue was one of timing. Our application is heavy on client side JavaScript. The test would open up a new page in FireFox and start verifying content that had not loaded yet.

1
2
3
Failure/Error: find('.flag .delete').click
Capybara::ElementNotFound:
Unable to find css ".flag .delete"

Wait up Capybara!

We want a way of telling the test to wait for the content to load. Capybara is smart enough to keep trying to find an element for a period of seconds (2 seconds is the default). Upping this time to a comfortable 10 seconds doesn’t mean it will always take that long, but will take up to that time before reporting the element is not found.

1
Capybara.default_wait_time = 10

If you haven’t already, read the README.rdoc section under the heading, Asynchronous JavaScript (Ajax and friends). There are a few great examples that describe what to watch out for in general. I’m still not 100% sure which Capybara methods wait and which ones do not. Except for page.find. It’s my “old reliable” while I’m figuring things out.

Testing Hidden Elements

Here’s another one to watch out for. In this example, our markup contains a list of artworks. Each work of art is in a list item element that contains an image and a set of actions the user can take on this artwork. The actions’ parent element is hidden until the user mouses over the artwork.

1
2
3
4
5
6
7
8
9
10
<ul class="artworks">
  <li class="artwork">...</li>
  <li class="artwork">
    <img src="/artworks/monalisa.jpg" />
    <div class="hover_actions">
      <a href="#edit"<Edit</a>
      <a href="#save"<Save</a>
    </div>
  </li>
</ul>

We want to verify that the save link does its job. Let’s say that it displays a message returned from an AJAX call in an element with an id of #message. Here’s a sample spec.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
require 'spec_helper'

feature "Artwork Hover Menu" do

  # Wrapping in this context does a nice job of encapsulating tests that require Selenium
  context "capybara", :driver => :selenium do

    scenario "a user can save an artwork from the hover menu" do
      visit "/#/artworks/abstract-puppies"
      page.find(".artworks .artwork:first .hover_actions .save").click()
      page.should have_css(".collections ul li[data-artwork=abstract-puppies]")
    end

  end

  # More specs can go outside of the Selenium context. Only use Selenium if you really need it.
  # Launching FireFox really increases the total run time of the specs.

end

The error message in this type of scenario is helpful in reporting that the element is not visible.

Failure/Error: page.find('.artworks .artwork:first .hover_actions .save').click
    Selenium::WebDriver::Error::ElementNotDisplayedError:
      Element is not currently visible and so may not be interacted with

We need to make the element visible. There are a few ways to do this. You could trigger whatever DOM event causes the element to become visible, a mouseover in this case, but I prefer to alter the CSS and set whatever display property is hiding it (opacity: 0, display: none, or visibility: hidden). We’ll also assume jQuery is available:

scenario "a user can save an artwork from the hover menu" do
    visit "/#/artworks/abstract-puppies"
    page.execute_script('$(".artworks .artwork:first .hover_actions").show()')
    page.find(".artworks .artwork:first .hover_actions .save").click()
    page.find("#message")
    page.should have_css("#message)
  end

The general rule is that if you manipulate the DOM with page.execute_script, just like your production scripts that are manipulating the DOM, it’s a good idea to use a page.find to get Capybara to wait for the new state.

It can be hard to know the state of the page when verifying dynamic content. You can call Capybara’s save_and_open_page in your spec to save out an html file that will then open in your default browser where you can view source.

Happy Testing!

Linux on JavaScript

Got this in my ReadWriteWeb RSS feed this morning. Fabrice Bellard has written an x86 PC emulator in JavaScript and is running Linux on it.

http://www.readwriteweb.com/hack/2011/05/run-linux-on-javascript.php

JavaScript is the future.

Fun Fact: A friend at work informed me that Fabrice Bellard is the creator of FFmpeg. The Internet owes him a lot. I personally have benefitted from FFmpeg in many past projects including OpenHallway. Thank you Mr. Bellard.

Running Jasmine CI on a Headless Server

Problem: Your continuous integration server is on some virtual slice somewhere. You can’t run a Jasmine CI task without X windows and a monitor… or can you?

Solution: A virtual X frame buffer!

Some background:

  • Jasmine is a behavior-driven development framework for testing your JavaScript code. It fits in nicely with rspec.
  • The X window system (commonly X Window System or X11) provides desktop GUIs on Unix systems.
  • Xvfb does everything X would in memory, without putting it on a screen (vfb = virtual frame buffer).

Assuming a flavor of linux with apt-get, install these:

1
2
3
apt-get install xvfb
apt-get install openjdk-6-jdk
apt-get install firefox

Create a virtual X frame buffer (labeled :99) and set the default screen (screen 0) to the given dimensions and color depth.

1
Xvfb :99 -screen 0 1440x900x16

Set the DISPLAY environment variable to the X virtual frame buffer labeled :99 and run the rake task:

1
DISPLAY=":99" rake jasmine:ci

My googling found it possible to take screen shots of the in memory frame buffer… magic!