Using Capybara to drag a jQuery UI sortable onto a jQuery UI droppable

I've been writing integration tests for our card sorting tool, OptimalSort. Part of those tests should obviously be that, in an "open" card sort, that a user can drag a card onto the stage, drop it, and have it create a new category with that card in it.

It seemed like it should be pretty simple, using a Capybara driver that supported javascript:

should "be able to drag a card onto the stage and create a new group" do
card = page.find_by_id('unsorted-column').find('ul').find('li')
target = page.first('.column')
card.drag_to(target)
assert page.first('.group ul li')
end

That is, find the first unsorted card, find the first drop target (".column") and drag the card onto it. The final assertion checks that a group has been created that contains a card element.

The problem was when the tests ran, I could clearly see the card being dragged to the top of the column, and not triggering the column's droppable "over" or "drop" events.

The cause is that the droppable was set to tolerance:intersect - dragged elements had to be 50% inside the droppable to trigger anything. When the capybara's drag_to was called, it was dragging the card to the top of the target, in a way that it wasn't 50% inside.

The sneaky solution was to create a new element for drag_to to target, underneath and clearly inside the bounds of the droppable. I used capybara's execute_script to add a new element with jQuery, and then dragged the card to this hidden target.

should "be able to drag a card onto the stage and create a new group" do
page.execute_script("$('#sort-area').prepend($('<div id=\"test_drop_helper\" style=\"position:absolute; top:300px; left:300px; z-index:-1000; width:10px; height:10px;\" ></div>'))")

card = page.find_by_id('unsorted-column').find('ul').find('li')
target = page.first('#test_drop_helper')
card.drag_to(target)
assert page.first('.group ul li')
end

I knew that at those particular values it was where I wanted it and I only needed it for this one test. If you needed to target more than one thing you might need to be more discerning about the parameters you assigned to it, etc.

Now, if I could just get the tests to take sliiiightly less time...

heatdeathoftheuniverse.png

Asking for what credit card type someone has is inefficient

I was buying tickets to fly to Auckland for Radiohead ("Hey William," you say. "Aren't they playing Sydney?" "Yes," I reply. "I didn't know I was moving to Australia, then.") and as much as I love Air New Zealand, being faced with this makes me sad:

On another note, do those blue stars denote information, or required fields? Asking for a friend.

On another note, do those blue stars denote information, or required fields? Asking for a friend.

Maybe it's because I've been implementing credit card processing at work over the last couple of days, but this kind of laziness in an interface really gets to me.

Dropdowns for numeric dates are the scum of the earth

The expiry date thing is crap because GOMS analysis will tell you that it's faster to type a number than select it from a dropdown list (this is something I picked up at UX Australia: check out these slides). I'm not going to dwell on that. I understand why they're doing it but I want them to know that they're wrong and they need to look at the choices they've made in their life.

If you're asking me what card I have, you're wasting my time

Second, "select provider"? Pull the other one. Credit card numbers encode the issuer within the first six digits of the number (wikipedia). While I will concede that, yes, Air New Zealand has to deal with JCB and Diners along with the Big Three that I have to deal with, I don't think that's any excuse. I had to go and look it up, but still. That's hardly the end of the world.

All you have to do is read the card number as they're typing it (or wait til they focus out) and write a set of case statements to handle all the IIN numbers you support. Adding new providers is going to be about as difficult as adding a new option to your list of supported cards (unless you're getting that from a database, I guess, but that's not the point).

The only reason I can think of to put a dropdown for card issuer is to give an indication of the cards you support. There is no reason to force the user to select an option from a dropdown to do this; you can do it with a series of icons (which seems to work fine for Paypal, and I assume they know something about payments). If you want to get real fancy you can highlight the card provider they're entering, as they enter it. That's what I did today, and I was unnecessarily pleased by how neat it looked.

Credit card utopia.

Credit card utopia.

If the user still manages to miss all the signs that you don't support their card, their payment will just fail when it reaches your payment gateway. I'm assuming you're already handling this situation with some sort of error message. Stop getting in your users' way.