Search code examples
calabashcalabash-ioscalabash-android

How to override a Calabash predefined step?


I'm defining custom calabash steps (to use on both iOS and Android) and would like to selectively override various predefined steps. An example is:

Given /^I press the "([^\"]*)" button$/ do |text|
  tap_when_element_exists("android.widget.Button {text CONTAINS[c] '#{text}'}")
end

Instead of using this implementation, I would like to provide my own. If I define and use a step with a matching regex I get an error:

Ambiguous match of "I press the "big red" button"

It also suggests using "--guess" but that didn't help, and I still get the Cucumber::Ambiguous error. I could make some arbitrary change to the regex for my step, ex:

I tap the "big red" button

But that feels like a poor solution for a few reasons

  • Having to prevent usage of the built in step, especially since it may be the most natural phrasing
  • If canned_steps adds a conflicting step in a future revision, I'd be forced to change my phrasing and all my scenarios
    • It also appears that the phrasing is a bit different between the Android and iOS predefined steps. If I can't override, this means I need to avoid using the iOS predefined steps on Android, even though I will not get the Cucumber::Ambiguous error on Android.
  • In general I don't like to tell the scenario authors (often QA) to not use a particular phrasing, I would rather add alternate phrasing than remove options

Is there a way to un-define a built in step? The android canned_step documentation suggests there should be: You can add your own steps or change the ones you see here

I don't want to lose ALL the predefined steps immediately either (ex: not require calabash_steps.rb). I'd rather phase them out only when they become a problem. And I don't want to directly edit the calabash code if I can help it, as that would require rolling my own calabash distro instead of using gem to install it.


Solution

  • I'd rather phase them out only when they become a problem. And I don't want to directly edit the calabash code if I can help it, as that would require rolling my own calabash distro instead of using gem to install it.

    In your features/support/env.rb, replace require calabash-android/cucumber with

    require 'calabash-android/color_helper'
    require 'calabash-android/operations'
    
    World(Calabash::Android::ColorHelper)
    World(Calabash::Android::Operations)
    

    Then copy the calabash-android canned steps to a file in your project features/step_definitions/canned_steps.rb.

    Remove or replace the predefined steps as needed.

    And a heads up - we are working on Calabash 2.0: a merge of the iOS and Android APIs. We are talking about removing the pre-defined steps from the new calabash gem and distributing them as a separate gem. As an example have a look at the way rspec distributes behaviors as separate gems. No decision has been made about this yet.