Using semantic meaning in features and user interfaces

April 24, 2009

WORK IN PROGRESS

This explains why I need to fork webrat, and why I believe features should rely upon css classes and id’s.

I believe that the CSS class is generally the best mechanism for expressing the semantic meaning of a particular piece of html (combined with DOM location and html tags). For example if somehow in viewing an order we want to reorder the order then I would first produce

.order
  .reorder
    # re-order goes here

This clearly establishes the semantic meaning - that I can reorder an order. Now the actual UI could be a number of things

  • Instructions: Reorder by phoning 0800 555 5555 and quoting order#
  • a button ` [reorder] `
  • a link ` click to reorder`

Now as far as my business requirement and feature is concerned I don’t care about these implementation details, and these details are certainly volatile. However the semantic layout is fixed. Here I see a representation of an order and can reorder the order.

I can now refine this feature to state that I should be able to tell the order to reorder. When I do this I should see some response in the UI which indicates whether my command has been successful.

When I reorder
Then I should see ...   

In web applications you can do this in two ways

  • follow a link
  • submit a form (by pressing a button)

Again my feature does not care how I reorder unfortunately with webrat I now have to choose - I can either ‘click’ or ‘press’.

.order
  .reorder
    %a{:href => order_path(:id => order.id)}= h(order.name)

above I am ‘clicking’ a link, whilst below I am pressing a button

.order
  .reorder
     -form_for @order do |f|
       ... 
       f.submit "reorder" 

Now as far as my feature is concerned I don’t give a damn how the re-ordering is done I just want to reorder. However I have to change my scenario (yes I know I can hide this change to a degree by re-using steps and having fancy step definition).

Scenario: Reorder
Given there is an order
When I view orders 
And I click reorder
Then ...
   
     OR 
     
Scenario: Reorder
Given there is an order
When I view orders 
And I press reorder
Then ...

Webrat compounds this frustration by making it really hard to press or click. Currently it will click only using text, id or an href, and its even more restrictive when it comes to pressing. So my first improvement was to extend click link to also be able to use classes. Now at least I can do

click link reorder

Although I have to change my implementation code

.order
    %a{:clases => reorder, :href => order_path(:id => order.id)}= h(order.name)