Set of common everyday steps with shortcuts


Keywords
capybara, cucumber, helpers, steps
License
MIT
Install
gem install pickles -v 0.1.1

Documentation

Pickles

Available steps summary
 When I click "My button" 
 When I click "=Mo" 
 When I click ">Mo" 
 When I navigate:
   | click | My button   |
   | hover | My span     |

 When I fill in the following:
   | User data       | Sex         (select) | Male       |
   |                 | Avatar               | avatar.png |

 When I attach the file "test.png" to "Avatar" within "User data"
 When I fill "Name" with "Peter" within "User data" 
 When I fill "Avatar" with "test.png" within "User data" 

 Then fields are filled with:
   | Account Number       | 5002       |
   | Expiry date          | 2009-11-01 |

 Then I can see:
   | form                       | Sarah |
   | menu_item "profile change" | admin |

 Then I can see video "cool_stuff"
 Then I cannot see image "test.png"
 Then focus is on "Sample"
 Then focus is on form_field "Fill user data"

This gem contains some helpers to simplify testing with capybara along with afew predefined cucumber steps.

Installation

Add this line to your application's Gemfile:

gem 'pickles', require: false

And then execute:

$ bundle

Or install it yourself as:

$ gem install pickles
require 'cucumber/pickles/helpers' # require only helpers without steps
# or
require 'cucumber/pickles' # require everything alltogether

Configure

Pickles.configure do |c|

  #
  # Usually referring to elements on page as .some-css-class is a bad practice.
  #
  # You can provide a map with aliases pointing to that stuff in this config 
  #   Ex: c.css_node_map = { some_block: '.some-css-class' }
  #
  # And refer to it across within blocks in every predefined step or by manually using detect_node_helper
  # 
  c.css_node_map = {} 
  # Same as above but shouled be aliased to xpath selector
  c.xpath_node_map = {} 

  #
  # Log xhr error response to browser console, 
  # 
  # You can configure capybara to log this to your console: ( For example if example failed )
  #
  # puts page.driver.browser.manage.logs.get('browser').select { |log| log.level == 'SEVERE' }.map(&:message).map(&:red)
  #
  c.log_xhr_response = false 
  
  # 
  # In some table steps you can provide '(...)' identifier to override how that step should be handled
  # 
  # See 'I fill in the following:' for explaination
  #
  c.fill_tag_steps_map = { 'select' => Select }

  #
  # Same as above for 'fields are filled with:' step
  #
  c.check_tag_steps_map = { 'text' => Text }

end

Capybara test helpers

Bunch of usefull helpers for everyday testing with capybara.

Mostly usefull if you're building a SPA app or just have tons of javascript and standard Capybara helper methods isnt enough.

Start with:

If you're using cucumber you may want to:

World(Pickles)

Or you can use it through:

Pickles.helper_name

Index:

  1. wait_for_ajax
  2. Locator string
  3. find_node
  4. detect_node
  5. find_input
  6. blur
  7. select_input
  8. attach_file
  • Locator string: Ex: "=Text[2]":

    • 'Text' - required - text to look up by
    • '=' - optional - lookup exact text in node if given
    • '[2]' - optional - index of element on page. If found 4 elements than 3rd will be selected - indexed from 0.
  • find_node(locator, within: nil)

    Find node on page by Locator string

    within - capybara node to limit lookup

    returns: capybara node

  • find_input(locator, within: nil)

    Find input | textarea | [contenteditable] on page identified by Locator string

  • detect_node(el_alias, locator = nil, within: nil)

    Does lookup based on provided in config maps

    if within.present? => limit search to within if locator.present? => use locator in step location

    Use el_alias to find needed xpath / css in maps provided to config. Priority xpath_map => css_map => el_alias as it is

    locator and el_alias can use index configuration from Locator string

  • wait_for_ajax

    Waits for ajax requests to end before proceeding further. Terminated with Capybara::ElementNotFound after Capybara.default_wait_time seconds

  • blur(node)

    Triggers node blur event and clicks on body to perform blur

  • select_input(input, value = nil)

    Selects input[type="checkbox"] OR input[type="radio"] on form

    Triggers click after selection to trigger javascript events ( may change in future )

  • attach_file(input, file_name)

    Attaches file with file_name to input[type="file"]

    file_name is fetched from features/support/attachments/*file_name* and raises RuntimeError if file not found

Supported cucumber steps:

  • Navigation

    1. When I (?:click|navigate) "([^"]*)"( within (?:.*))?

      Examples:
      When I click "My button" # standard click by text
      
      When I click "=Mo" # click node that has exact this text. i.e. ignore: Monday, Moth
        
      When I click ">Mo" # ajax wait requests done before clicking
      When I click "Mo>" # ajax wait requests done after clicking
        
      When I click ">Mo>" # both of the above
        
      When I click "My button,=Mo" # chain clicks ( click My button then click exact Mo )
      
      When I click "My button->=Mo" # same as above (-> is for chaining sequential clicks)
        
      When I click "My button>->=Mo>" # click My button, ajax wait then click Mo
      
      When I navigate ... # alias
      
      Description:
      • for within checkout docs
    2. When I (?:click|navigate):( within (?:.*))?

    Examples:
    When I navigate:
      | click | My button   |
      | hover | My span     |
      | hover | Your span   |
      | click | Your button |
        
    When I navigate: within form "User data"
      | click | Submit   |
    Description:
    • Same as previous, but allows table as argument.
    • note : in the definition
  • Forms:

    • Fill:
      1. When (?:|I )fill in the following:( within (?:.*))?

        Examples:
        When I fill in the following:
          |                 | Account Number       | 5002       |
          |                 | Expiry date          | 2009-11-01 |
          |                 | Note                 | Nice guy   |
          |                 | Wants Email?         |            |
          | User data       | Sex         (select) | Male       |
          |                 | Avatar               | avatar.png |
          |                 | Due date             | 12:35      |
          | Additional data | Accept user agrement | true       |
          |                 | Send me letters      | false      |
          |                 | radio 1              | true       |
        Description:
        • Fills form fields identified by second column.
        • First column is optional and defines 'within block' - see docs for within
        • Add custom (...) block for second column to define your own form fill steps in config.fill_tag_steps_map supported by default: (select) - uses When I select ".." with ".." under the hood. Ex:
          class FillDatepicker
          
            def initialize(label, value, within)
              # label = 'Date of birth'
              @label = label
              # value = '23.12.1998'
              @value = Date.parse(value)
              # within = detect_node("form", "User profile", within: page)
              @within = within
            end
            
            def call
               # implement datepicker selecting logic
            end
          end
          
          Pickles.configure do |c|
            c.fill_tag_steps_map = { datepicker: FillDatepicker }
          end
          
          When I fill in the following:
            | form "User profile" | Date of birth (datepicker) | 23.12.1998 |
      2. When (?:|I )attach the file "([^"]*)" to "([^"]*)"( within (?:.*))?

        Examples:
         When I attach the file "test.png" to "Avatar" within "User data"
        Description:
        • Attaches given file to identified fields
        • Params:
          1. features/support/attachments/ + file_name is used to identify file
          2. Input identifier. see find_input helper for searching details
          3. within block identifier
        • within part is optional
      3. When (?:|I )(?:fill|select)(?: "([^"]*)")?(?: with "([^"]*)")?( within (?:.*))?

        Examples:
         When I fill "Name" with "Peter" within "User data" # input[type="text"]
         When I fill "Avatar" with "test.png" within "User data" # input[type="file"]
        
         When I fill "Male" within "User data" # input[type="checkbox"] || input[type="radio"]
         When I select "Male" 
        
         When I select "sex" with "Male" # selector
        
        Description:
        • Tries to fill data by guessing field type from found input type(text|checkbox|radio|etc)
        • There MUST always be an input identified by identifier
        • within part is optional
  • Check

    Then fields are filled with:( within (?:.*))?

    Examples:
    Then fields are filled with:
      | Account Number       | 5002       |
      | Expiry date          | 2009-11-01 |
      | Note                 | Nice guy   |
      | Wants Email?         | true       |
      | Sex                  | Male       |
      | Accept user agrement | true       |
      | Send me letters      | false      |
      | radio 1              | true       |
      | Avatar               | avatar.png |
      | Due date             | 12:35      |
    Description:
    • Check fields filled by I fill in the folllwing
    • Supports exact same table syntax and optional column

    Then I can(not)? see:

    Examples:
    Then I can see:
      | form                       | Sarah |
      | menu_item "profile change" | admin |
    Description:
    • First column is optional for identifying within blocks

    Then I can(not)? see video (".*?")( within (?:.*))?

    Examples:
    Then I can see video "cool_stuff"
    Description:
    • value is src link to the video ( i.e. youtube link )

    Then I can(not)? see image (".*?")( within (?:.*))?

    Examples:
    Then I cannot see image "test.png"
    Description:
    • value is image_url ( i.e. assets/images/first.png )

    Then focus is on (.*) ?"(.*?)"

    Examples:
    Then focus is on "Sample"
    Then focus is on form_field "Fill user data"
    Description:
    • first matching group is optional and used from node maps ( see #detect_node )

Contributing

 Bug reports and pull requests are welcome on GitHub at https://github.com/vshaveyko/pickles.

License

 The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).