Read more

Auto-generate Cucumber navigation paths

Henning Koch
February 17, 2012Software engineer at makandra GmbH

Don't you just hate to write Cucumber path helpers to be able to say this?

When I go to the user form for "foo@bar.de"               # goes to edit_user_path(User.find_by_anything!('foo@bar.de'))
When I go to the form for the user "foo@bar.de"           # goes to edit_user_path(User.find_by_anything!('foo@bar.de'))
When I go to the form for the user above"                 # goes to edit_user_path(User.last)
When I go to the project page for "World Domination"      # goes to project_path(Project.find_by_anything!('World Domination')
When I go to the page for the project "World Domination"  # goes to project_path(Project.find_by_anything!('World Domination')
When I go to the page for the user above                  # goes to user_path(User.last)
When I go to the user form                                # goes to new_user_path
When I go to the list of users                            # goes to users_path
Illustration web development

Do you need DevOps-experts?

Your development team has a full backlog? No time for infrastructure architecture? Our DevOps team is ready to support you!

  • We build reliable cloud solutions with Infrastructure as code
  • We are experts in security, Linux and databases
  • We support your dev team to perform
Read more Show archive.org snapshot

Cry no more. Just merge the following code into your features/support/paths.rb and

module NavigationHelpers

  def path_to(page_name)
    case page_name

    when 'the homepage'
      root_path

    when /^the list of (.*?)$/
      models_prose = $1
      route = "#{model_prose_to_route_segment(models_prose)}_path"
      send(route)

    when /^the (page|form) for the (.*?) above$/
      action_prose, model_prose = $1, $2
      route = "#{action_prose == 'form' ? 'edit_' : ''}#{model_prose_to_route_segment(model_prose)}_path"
      model = model_prose_to_class(model_prose)
      send(route, model.last)

    when /^the (page|form) for the (.*?) "(.*?)"$/
      action_prose, model_prose, identifier = $1, $2, $3
      path_to_show_or_edit(action_prose, model_prose, identifier)

    when /^the (.*?) (page|form) for "(.*?)"$/
      model_prose, action_prose, identifier = $1, $2, $3
      path_to_show_or_edit(action_prose, model_prose, identifier)

    when /^the (.*?) form$/
      model_prose = $1
      route = "new_#{model_prose_to_route_segment(model_prose)}_path"
      send(route)

    when /"(.+?)"$/
      $1

    end
  end

  private

  def path_to_show_or_edit(action_prose, model_prose, identifier)
    model = model_prose_to_class(model_prose)
    route = "#{action_prose == 'form' ? 'edit_' : ''}#{model_prose_to_route_segment(model_prose)}_path"
    send(route, model.find_by_anything!(identifier))
  end

  def model_prose_to_class(model_prose)
    model_prose.gsub(' ', '_').classify.constantize
  end

  def model_prose_to_route_segment(model_prose)
    model_prose = model_prose.downcase
    model_prose.gsub(/[\ \/]/, '_')
  end

end

World(NavigationHelpers)

Note that you will need the find_by_anything helper for this to work.

Henning Koch
February 17, 2012Software engineer at makandra GmbH
Posted by Henning Koch to makandra dev (2012-02-17 12:11)