Cucumber & Cheese

My book if finally out! You can pick up a beta copy of the book at the LeanPub site.

A few years ago I set out to master Acceptance Test Driven Development (ATDD, also variously known as Behavior Driven Development or Storytesting). After trying several of the available tools I settled on Cucumber. For Web applications, I also used the most popular Ruby tool for page traversal and verification, Watir.

As I started working with teams to implement this practice, I discovered that the ATDD community was writing more and more new Ruby gems to empower and simplify this kind of testing. I also found that some of the things I personally wanted to simplify were not supported by any existing Ruby gem, so like the crazed developer I am, I set out to build my own. To my surprise, others started using some of the gems I created and began asking a lot of questions about their usage.

This book is my attempt to share as much of my experience using Cucumber and Watir as possible. I will cover many patterns, practices, tools, and (Yes) Ruby gems that make testing applications (particularly but not limited to Web applications) easier including a few of my own. I will also cover the proper way to structure and write your test automation code so that it is less brittle, simpler, better organized, more expressive, and therefore easier to change over the lifecycle of your application. My goal is to help you see and understand the benefits of ATDD and learn how to use Cucumber and Ruby to adopt (and help us refine!) this amazing practice.

This book is full of hands-on programming exercises and I strongly suggest you do them all. Even if you are not testing applications that are like the ones showcased in this book, the knowledge of how to write sound robust tests will transfer to whatever you have to test.

Downloads

The puppy application used in the book can be downloaded from here.

114 thoughts on “Cucumber & Cheese

  1. Eagerly waiting for your book ! I hope it will be about a testing framework using Cucumber+RSpec+watir-webdriver. Am I right?
    and btw, could you hihg-light the difference between your page object implementation from that of Alister Scott’s (watirmelon.com) ?

    Thank You
    Feby George

    • Feby George,

      You are right about the topic of my book. It will be focused on those topics as well as other interests for writing robust test suites like test data management, etc.

      Alister Scott’s gem is based on a simple module I wrote for a client a couple of years ago and blogged about here. It is a very nice, clean wrapper for making pages. My gem adds a lot more functionality. I believe it addresses many of the problems people have when testing websites.

      -Cheezy

  2. I have been given the opportunity to work in corporate environment on an agile software development right out of college as a tester and will start learning about automated tesing soon. I am very much a beginner and have little to no exposure to Ruby and much less programming in general. I will be using RubyMine and Cucumber to develop test scripts so I watned to know if your book will be for an advanced user or a rookie like me?

    Thanks,

    Rob

  3. Hi !

    I though I was testing not too bad, and after your book, I want to do it better.
    So, I am asking myself a lots of details.
    - Is it seems acceptable to play with the @browser in a PageObject method ?
    - How to go on a particular url in start of a PageObject method ? Actually, I add a cucumber step to make a goto before to use my PageObject.

    • Fabrice,

      1) I think you will not need to play with the @browser in your methods. Everything you should need is available through the PageObject module and supporting classes. If you find some capability that is only available through the @browser instance please let me know so I can add it to the gem.

      2) I am not sure how far you are in the book but what you are describing is exactly what the page_url and visit_page combo are designed to do. In you page object you use the page_url class method to define the url for the page and in your step definitions you can use the visit_page(YourPage). This will take you to the page and then you can begin your work.

      -Cheezy

  4. Hi Cheezy

    I’m new to automated testing, but I’m trying to get my head round Gherkin, BDD and stuff like that. Coming from a PHP background, I have been using Behat and I have thrown a few rather obscure questions at the Behat forum, which led to Marcello telling me I am
    ‘trying to achieve the “acceptance-testing-centric model” ..’ rather than ‘.. the “system-behaviour-specification-centric model”‘

    So, my question is.. should I buy your book? Will it help me understand how to structure acceptance tests and develop a testing framework using Behat, Gherkin, Mink and PHP, or is it purely aimed at the Ruby / Watir / Cucumber world?

    I will probably buy it anyway, but if you can tell me it would be useful then I can get the company to pay for it!

    Regards
    John

    • John,

      This book is definitely targeting the Ruby/Cucumber market. It focuses on several specific gems that I have found helpful when implementing ATDD with teams.

      -Cheezy

  5. Hi Cheezy,

    I have just started working through the exercises in the book, but as you may already know one of the links required to complete the exercise is not working. This is where you click on the “Adopt Me” button for the chosen puppy and then fill out details. Do you have any idea when this will be back up?

    As an alternative can I try downloading the application locally and changing the web links in the ruby scripts?

    Thanks
    Cantz

  6. Hi ,

    Hi
    I’m trying to run the following command:>testgen project test_puppies
    and getting the error below after installing the testgen gem. I have looked around for answers to similar issues on various sites but can’t find anything that seems useful.
    Was wondering if you had run into this before and could advise what I can do to solve?

    Thanks again
    Cantz

    C:/Temp/Ruby193/lib/ruby/gems/1.9.1/gems/ffi-1.1.5/lib/ffi/library.rb:249:in `at
    tach_function’: Function ‘uname’ not found in [msvcrt.dll] (FFI::NotFoundError)
    from C:/Temp/Ruby193/lib/ruby/gems/1.9.1/gems/sys-uname-0.9.0/lib/unix/s
    ys/uname.rb:32:in `’
    from C:/Temp/Ruby193/lib/ruby/gems/1.9.1/gems/sys-uname-0.9.0/lib/unix/s
    ys/uname.rb:8:in `’
    from C:/Temp/Ruby193/lib/ruby/gems/1.9.1/gems/sys-uname-0.9.0/lib/unix/s
    ys/uname.rb:6:in `’
    from C:/Temp/Ruby193/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb
    :55:in `require’
    from C:/Temp/Ruby193/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb
    :55:in `require’
    from C:/Temp/Ruby193/lib/ruby/gems/1.9.1/gems/testgen-0.5.1/lib/testgen/
    generators/project.rb:2:in `’
    from C:/Temp/Ruby193/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb
    :55:in `require’
    from C:/Temp/Ruby193/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb
    :55:in `require’
    from C:/Temp/Ruby193/lib/ruby/gems/1.9.1/gems/testgen-0.5.1/lib/testgen/
    cli.rb:2:in `’
    from C:/Temp/Ruby193/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb
    :55:in `require’
    from C:/Temp/Ruby193/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb
    :55:in `require’
    from C:/Temp/Ruby193/lib/ruby/gems/1.9.1/gems/testgen-0.5.1/bin/testgen:
    3:in `’
    from C:/Temp/Ruby193/bin/testgen:23:in `load’
    from C:/Temp/Ruby193/bin/testgen:23:in `’

    • Some extra info that may help.
      I have been having trouble executing the commands to install gems as outline in the book. As an example I have tried to run

      >gem install rake bundler yard watir-webdriver

      ERROR: Could not find a valid gem ‘rake’ (>= 0) in any repository
      ERROR: While executing gem … (Gem::RemoteFetcher::FetchError)
      Errno::EHOSTUNREACH: A socket operation was attempted to an unreachable host
      . – connect(2) (http://rubygems.org/latest_specs.4.8.gz)

      The first time I did this on my personal machine it worked. Several weeks later however I tried it on our dev/test machine and it gave the error above. At the time there was a message on the http://rubygems.org/ site saying that the “Dependancy API” was not working 100% and the status of the API was shown as red at http://status.rubygems.org/. I thought that this may have had something to do with it. I then proceeded to download and install each gem manually, including the dependant gems. One of the one’s I missed was the aruba gem. Was wondering if this may be the cause of not being able to run the testgen command above?

      So I tried to install the aruba gem but getting following error
      C:\Software\Ruby\Gems>gem install aruba
      ERROR: While executing gem … (Gem::DependencyError)
      Unable to resolve dependencies: childprocess requires ffi (~> 1.0.6)

      I already had successfully installed ffi v1.1.5 . I tried to install ffi v1.06 but again got an error and could not proceed with installation

      • Just tried on another machine and got a similar error. Note the status is all green at http://status.rubygems.org/

        >gem install rake bundler yard watir-webdriver
        ERROR: Could not find a valid gem ‘rake’ (>= 0) in any repository
        ERROR: While executing gem … (Gem::RemoteFetcher::FetchError)
        Errno::ETIMEDOUT: A connection attempt failed because the connected party di
        d not properly respond after a period of time, or established connection failed
        because connected host has failed to respond. – connect(2) (http://rubygems.org/
        latest_specs.4.8.gz)

        • That error typically means that the gem process is unable to make a connection with rubygems.org or one of the other mirrors. Is it possible that the machine you are trying this on is not connected to the internet or is having some networking issues?

          • Hi
            1) I have tried on three different machines within my company LAN , one of which was a virtual machine and they are all displaying the same sort of behaviour. I can access the internet on all of them. I have also tried disconnecting one of the machines from the company LAN and connecting it to my home internet connection and getting similar behaviour.

            a) Could it be an issue with rubygems.org web site
            b) Is there another way to install them?

            2) Do you have any feedback on my initial question regarding the error I was getting running the “testgen create project” command dated October 27, 2012 at 3:47 further up the blog

            p.S apologies for all the questions, just eager to get something running!

            Thanks

  7. In regards to 2) I am still getting this error when I just type in “testgen” at the prompt.
    C:\Documents and Settings\Costa Antzoulatos>testgen

    C:/Software/Ruby/Ruby193/lib/ruby/gems/1.9.1/gems/ffi-1.1.5/lib/ffi/library.rb:2
    49:in `attach_function’: Function ‘uname’ not found in [msvcrt.dll] (FFI::NotFou
    ndError)
    from C:/Software/Ruby/Ruby193/lib/ruby/gems/1.9.1/gems/sys-uname-0.9.0/l
    ib/unix/sys/uname.rb:32:in `’
    from C:/Software/Ruby/Ruby193/lib/ruby/gems/1.9.1/gems/sys-uname-0.9.0/l
    ib/unix/sys/uname.rb:8:in `’
    from C:/Software/Ruby/Ruby193/lib/ruby/gems/1.9.1/gems/sys-uname-0.9.0/l
    ib/unix/sys/uname.rb:6:in `’
    from C:/Software/Ruby/Ruby193/lib/ruby/site_ruby/1.9.1/rubygems/custom_r
    equire.rb:55:in `require’
    from C:/Software/Ruby/Ruby193/lib/ruby/site_ruby/1.9.1/rubygems/custom_r
    equire.rb:55:in `require’
    from C:/Software/Ruby/Ruby193/lib/ruby/gems/1.9.1/gems/testgen-0.5.1/lib
    /testgen/generators/project.rb:2:in `’
    from C:/Software/Ruby/Ruby193/lib/ruby/site_ruby/1.9.1/rubygems/custom_r
    equire.rb:55:in `require’
    from C:/Software/Ruby/Ruby193/lib/ruby/site_ruby/1.9.1/rubygems/custom_r
    equire.rb:55:in `require’
    from C:/Software/Ruby/Ruby193/lib/ruby/gems/1.9.1/gems/testgen-0.5.1/lib
    /testgen/cli.rb:2:in `’
    from C:/Software/Ruby/Ruby193/lib/ruby/site_ruby/1.9.1/rubygems/custom_r
    equire.rb:55:in `require’
    from C:/Software/Ruby/Ruby193/lib/ruby/site_ruby/1.9.1/rubygems/custom_r
    equire.rb:55:in `require’
    from C:/Software/Ruby/Ruby193/lib/ruby/gems/1.9.1/gems/testgen-0.5.1/bin
    /testgen:3:in `’
    from C:/Software/Ruby/Ruby193/bin/testgen:23:in `load’
    from C:/Software/Ruby/Ruby193/bin/testgen:23:in `’

    • I did a check of the testgen gem and discovered that I am no longer using the functionality that caused me to include the sys-uname gem. In response to this discovery I just released a new version of testgen that eliminates that dependency. Please get the latest testgen (version 0.5.2) and then perform a bundle update on your project.

  8. Hey Cheezy, I’m going through this book and I’m loving it! I’ve been using Watir for a few years now. You’re showing me a lot of neat things I can do with the page-object gem.

    • George,

      Really glad you’re enjoying it. Keep the feedback coming. I’m trying to finish the remaining sections by the end of the year so stay tuned.

      -Cheezy

  9. Pingback: Using Cucumber to Adopt a Puppy | CheezyWorld

  10. Hi! A concept question. On page 97 you create a module called SideMenuPanel that holds the elements for the side menu and afterwards require and include it on the class.

    If the SideMenuPanel is almost all around the site, what about to create a class for it? I know its not a Page but this way you can reference to it as on_page(SideMenuPanel) to perform menu actions and you can continue with on_page(HomePage) for the other interactions. Is there any other problems on that except the Menu is not a Page and is not “elegant” to use a class?

    Thank you very much!

    • There is no reason why this would not work. I do think it does not read as well and might be confusing to some but it will work.

      The point I was trying to make in the example in the book was that when we have reusable parts it is nearly always best to make modules that can be included in several pages.

      Thanks for reading the book and for your comments.

      -Cheezy

    • I’m about to catch a flight and won’t be able to look into it for several hours. Are you getting an error or is it just not coming up at all?

  11. Hello:

    I’m trying to follow the Chapter on working with and connecting to Databases and experienced the following issue when setting up the puppy site on my local. In the puppies directory I ran the bundle Install command and received “Could not find addressable-2.3.1 in any of the sources” I checked the rubygems.org site and this version of addressable is marked as yanked. So when I run the rails s command the puppy site does not start. Is there a workaround for this? I’m new to ATDD, and your book has been a tremendous help! Keep up the good work!

    Regards

  12. I have a problem with “bundle install” in the puppies directory(page 106)
    C:\puppies>bundle install
    Fetching gem metadata from http://rubygems.org/………
    Fetching gem metadata from http://rubygems.org/..
    Resolving dependencies…
    Could not find addressable-2.3.1 in any of the sources

    OS: Windows 7
    btw, “test_puppies” project works fine and test_puppies and puppies are in the same diractory

  13. Hello! I purchased your book this week and have found it to be very useful. I have just started the section Cucumbers & Puppies and have run into some problems. I should start by saying that I am behind a corporate firewall and the only way I could get the gems installed was to go to the RubyGems website and download one at a time as I was made aware of the dependencies, and then install from the download folder. My OS is Windows Server 2008 R2 – 64 bit. When I try to run making_cheese.feature, I get the following errors:
    C:\Ruby200\bin\ruby.exe -EUTF-8 -e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift) C:\Ruby200\bin/cucumber C:/RubymineProjects/test_puppies/features/making_cheese.feature –format Teamcity::Cucumber::Formatter –expand –color -r features
    Testing started at 1:52 PM …
    Using the default profile…
    WARNING: cannot load such file — 2.0/gherkin_lexer_en
    Couldn’t load 2.0/gherkin_lexer_en
    The $LOAD_PATH was:
    C:/Ruby200/lib/ruby/gems/2.0.0/gems/cucumber-1.2.1/bin/../lib
    C:/RubyMine 5.0/rb/testing/patch/common
    C:/RubyMine 5.0/rb/testing/patch/bdd
    C:/Ruby200/lib/ruby/gems/2.0.0/gems/gherkin-2.11.6/lib
    C:/Ruby200/lib/ruby/gems/2.0.0/gems/builder-3.2.0/lib
    C:/Ruby200/lib/ruby/gems/2.0.0/gems/diff-lcs-1.2.1/lib
    C:/Ruby200/lib/ruby/gems/2.0.0/gems/cucumber-1.2.1/lib
    C:/Ruby200/lib/ruby/gems/2.0.0/gems/rspec-expectations-2.13.0/lib
    C:/Ruby200/lib/ruby/gems/2.0.0/gems/multi_json-1.6.1/lib
    C:/Ruby200/lib/ruby/gems/2.0.0/gems/rubyzip-0.9.9/lib
    C:/Ruby200/lib/ruby/gems/2.0.0/gems/ffi-1.4.0/lib
    C:/Ruby200/lib/ruby/gems/2.0.0/gems/ffi-1.4.0/ext/ffi_c
    C:/Ruby200/lib/ruby/gems/2.0.0/gems/childprocess-0.3.8/lib
    C:/Ruby200/lib/ruby/gems/2.0.0/gems/websocket-1.0.7/lib
    C:/Ruby200/lib/ruby/gems/2.0.0/gems/selenium-webdriver-2.30.0/lib
    C:/Ruby200/lib/ruby/gems/2.0.0/gems/watir-webdriver-0.6.2/lib
    C:/Ruby200/lib/ruby/gems/2.0.0/gems/i18n-0.6.4/lib
    C:/Ruby200/lib/ruby/gems/2.0.0/gems/faker-1.1.2/lib
    C:/Ruby200/lib/ruby/gems/2.0.0/gems/yml_reader-0.2/lib
    C:/Ruby200/lib/ruby/gems/2.0.0/gems/data_magic-0.14/lib
    C:/Ruby200/lib/ruby/gems/2.0.0/gems/page_navigation-0.7/lib
    C:/Ruby200/lib/ruby/gems/2.0.0/gems/page-object-0.8.6/lib
    C:/Ruby200/lib/ruby/site_ruby/2.0.0
    C:/Ruby200/lib/ruby/site_ruby/2.0.0/i386-msvcrt
    C:/Ruby200/lib/ruby/site_ruby
    C:/Ruby200/lib/ruby/vendor_ruby/2.0.0
    C:/Ruby200/lib/ruby/vendor_ruby/2.0.0/i386-msvcrt
    C:/Ruby200/lib/ruby/vendor_ruby
    C:/Ruby200/lib/ruby/2.0.0
    C:/Ruby200/lib/ruby/2.0.0/i386-mingw32. Reverting to Ruby lexer.
    No lexer was found for en (cannot load such file — gherkin/lexer/en). Supported languages are listed in gherkin/i18n.json. (Gherkin::I18n::LexerNotFound)
    C:/Ruby200/lib/ruby/gems/2.0.0/gems/gherkin-2.11.6/lib/gherkin/i18n.rb:108:in `rescue in lexer’
    C:/Ruby200/lib/ruby/gems/2.0.0/gems/gherkin-2.11.6/lib/gherkin/i18n.rb:97:in `lexer’
    C:/Ruby200/lib/ruby/gems/2.0.0/gems/gherkin-2.11.6/lib/gherkin/parser/parser.rb:138:in `transition_table’
    C:/Ruby200/lib/ruby/gems/2.0.0/gems/gherkin-2.11.6/lib/gherkin/parser/parser.rb:127:in `build_transition_map’
    C:/Ruby200/lib/ruby/gems/2.0.0/gems/gherkin-2.11.6/lib/gherkin/parser/parser.rb:123:in `transition_map’
    C:/Ruby200/lib/ruby/gems/2.0.0/gems/gherkin-2.11.6/lib/gherkin/parser/parser.rb:90:in `initialize’
    C:/Ruby200/lib/ruby/gems/2.0.0/gems/gherkin-2.11.6/lib/gherkin/parser/parser.rb:67:in `new’
    C:/Ruby200/lib/ruby/gems/2.0.0/gems/gherkin-2.11.6/lib/gherkin/parser/parser.rb:67:in `push_machine’
    C:/Ruby200/lib/ruby/gems/2.0.0/gems/gherkin-2.11.6/lib/gherkin/parser/parser.rb:30:in `parse’
    C:/Ruby200/lib/ruby/gems/2.0.0/gems/cucumber-1.2.1/lib/cucumber/feature_file.rb:37:in `parse’
    C:/Ruby200/lib/ruby/gems/2.0.0/gems/cucumber-1.2.1/lib/cucumber/runtime/features_loader.rb:28:in `block in load’
    C:/Ruby200/lib/ruby/gems/2.0.0/gems/cucumber-1.2.1/lib/cucumber/runtime/features_loader.rb:26:in `each’
    C:/Ruby200/lib/ruby/gems/2.0.0/gems/cucumber-1.2.1/lib/cucumber/runtime/features_loader.rb:26:in `load’
    C:/Ruby200/lib/ruby/gems/2.0.0/gems/cucumber-1.2.1/lib/cucumber/runtime/features_loader.rb:14:in `features’
    C:/Ruby200/lib/ruby/gems/2.0.0/gems/cucumber-1.2.1/lib/cucumber/runtime.rb:170:in `features’
    C:/Ruby200/lib/ruby/gems/2.0.0/gems/cucumber-1.2.1/lib/cucumber/runtime.rb:46:in `run!’
    C:/Ruby200/lib/ruby/gems/2.0.0/gems/cucumber-1.2.1/lib/cucumber/cli/main.rb:43:in `execute!’
    C:/Ruby200/lib/ruby/gems/2.0.0/gems/cucumber-1.2.1/lib/cucumber/cli/main.rb:20:in `execute’
    C:/Ruby200/lib/ruby/gems/2.0.0/gems/cucumber-1.2.1/bin/cucumber:14:in `’
    C:/Ruby200/bin/cucumber:23:in `load’
    C:/Ruby200/bin/cucumber:23:in `’
    -e:1:in `load’
    -e:1:in `’

    Any help would be appreciated!

    • I would suspect that the gems were not installed properly. Please take a look at this page and see if setting the http-proxy value will allow you to get through the firewall. If so, I would suggest installing the gems again. Let me know if this is not an option and we will look at other solutions.

  14. Hi Cheezy
    I run into wrong number of arguments error. Please take a look at the output listed below. – Thanks

    $ cucumber features/adopt.feature
    Using the default profile…
    file:/C:/jruby-1.7.2/lib/jruby.jar!/jruby/java/java_package_module_template.rb:11 warning: `eval’ should not be aliased
    wrong number of arguments calling `initialize` (0 for 1) (ArgumentError)
    c:/jruby-1.7.2/lib/ruby/gems/shared/gems/cucumber-1.2.3/bin/../lib/cucumber/feature_file.rb:31:in `parse’
    c:/jruby-1.7.2/lib/ruby/gems/shared/gems/cucumber-1.2.3/bin/../lib/cucumber/runtime/features_loader.rb:28:in `load’
    org/jruby/RubyArray.java:1613:in `each’
    c:/jruby-1.7.2/lib/ruby/gems/shared/gems/cucumber-1.2.3/bin/../lib/cucumber/runtime/features_loader.rb:26:in `load’
    c:/jruby-1.7.2/lib/ruby/gems/shared/gems/cucumber-1.2.3/bin/../lib/cucumber/runtime/features_loader.rb:14:in `features’
    c:/jruby-1.7.2/lib/ruby/gems/shared/gems/cucumber-1.2.3/bin/../lib/cucumber/runtime.rb:177:in `features’
    c:/jruby-1.7.2/lib/ruby/gems/shared/gems/cucumber-1.2.3/bin/../lib/cucumber/runtime.rb:47:in `run!’
    c:/jruby-1.7.2/lib/ruby/gems/shared/g

  15. Cheezy,
    Please ignore my post above to do with ‘wrong number of arguments’
    That error was gone after removing this line from my steps : include PageObject

    Somehow this include syntax was causing the problem. I am all set for now but any explanation about the wrong number of arguments will help. – Thanks.

    • Sreenivas,

      When you included PageObject it added a method named initialize that requires you to pass a browser object. You would only want to include this module in classes that are indeed page objects. That will be explained later in the book.

      -Cheezy

  16. i tried runnning chezy on ruby mine but it didn’t ran the tests and showing all tests as failed.
    it seems it did not get the step definitions for the written features!
    please help

    • I’ve run into this problem with RubyMine as well, and contacting their support they will inform you that you must require ‘minitest’.

      However, I solved it by reorganizing my folder structure. I’m not certain what causes this, However your step definitions folder must be inside of the same folder of your features.

      e.g. Features are are stored in folder ‘Test’, you must have your ‘step definitions’ folder inside of ‘Test’ as well.

      Hope this helps some.

      Respectfully,
      Rodney U.

      • You should have all of your features in a directory named features and the step definitions in a directory named step_definitions under that directory. If you use the tool testgen to generate your project structure it will follow this pattern. These are the directories that cucumber is expecting.

  17. Cheezy,

    I just want to thank you for writing this blog, your book and building the gems! It has greatly helped me achieve QA goals I was assigned. Please keep the post coming!

    Your friend,
    Rodney U.

  18. Hi Cheezy,

    I am practicing using database chapter. I got below error. how to resolve it?
    C:/Ruby193/lib/ruby/gems/1.9.1/gems/bundler-1.3.1/lib/bundler/resolver.rb:130:in `block in resolve’: Bundler could not find compatible versions for gem “builder”: (Bundler::VersionConflict)
    In Gemfile:
    activerecord (= 3.2.1) x86-mingw32 depends on
    builder (~> 3.0.0) x86-mingw32

    cucumber (>= 0) x86-mingw32 depends on
    builder (3.2.0)

  19. Hi, I am not under standing the concept given below. Please explain

    myhash = {"emp1" => "sudheer", "emp2" => "cheezy"}
    myhash.each do |x|
      puts x
    end
    

    result:
    sudheer
    cheezy
    Here I understood that, x represent each element in the hash.

    In chapter, 5. more puppies

    div(:error_div, :id => 'error_explanation')  ... # calling div method
    unordered_list(:error_list) do |page|
      page.error_div_element.unordered_list_element
    end
    

    I understood that unordered_list is a method available in the page_object gem. How we are passing a local variable, (named as a page, here) which is acting as a parent object (like current page) for the div object. Please explain. I am not understanding this block of code.
    Explanation in the book – “Instead we are passing a block which receives a local variable which is an instance of our page” – actually we are writing a class which is going to represent a page. Where we are creating the instance of our page.

    Hope you got my question. Waiting for your response with more excitement.

    • Sudheer,

      This is an excellent question. Thanks for asking.

      A block is nothing more than a piece of code that is passed to a method as an argument. At some later point, the method receiving the block decides when it is time to execute that block.

      In the case of the each method above, it takes a single argument which is a block. In the unordered_list method above we have the following signature:

      unordered_list(name, identifier={:index => 0}, &block)
      

      This method can be called in one of three ways.

      1) You can call it with the name only like this – unordered_list(:error_list). In this case the second parameter kicks in and it will select the first unordered list if finds when you call one of the generated methods.

      2) You can call it with the name and identifier like this – unordered_list(:error_list, :id => 'some_id'). In this case it will use the id to locate the unordered list when you call one of the generated methods.

      3) You can call it with the name and the block like this – unordered_list(:error_list) do |page|... end. IN this case it will expect the block to find the unordered list. The reason we can pass the page as a parameter is that the block is not executed until you use one of the generated methods which is after the instance of the page is created.

      Again, when we call one of the generated methods on the page instance the block is executed and when it is executed it is passed the instance of the page. I hope this all makes sense.

      -Cheezy

  20. Hi, Thanks for your immediate responses.

    I got a laptop with Windows 8 o/s. installed ruby 1.9.3 and rubymine 4.0.3.
    After installing testgen and bundler, using testgen created test_puppies project.
    did .bundle install n Bundle update .
    Added a first feature as below
    Feature: Adopting puppies
    Scenario: Adopting one puppy
    Given I am on the puppies adoption website
    when I ran the scenario got the fallowing error. Tried a lot to resolve but not succeeded. Please help me.

    C:\Ruby193\bin\ruby.exe -e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift) C:\Ruby193\bin/cucumber C:/RubyTraining/test_puppies/features/adopting_puppies.feature –format Teamcity::Cucumber::Formatter –expand –name “Adopting\ one\ puppy” –color -r features
    Testing started at 2:34 AM …
    wrong number of arguments (1 for 0) (ArgumentError)
    C:/Ruby193/lib/ruby/gems/1.9.1/gems/cucumber-1.3.1/lib/cucumber/ast/location.rb:22:in `file_colon_line’
    C:/Program Files (x86)/JetBrains/RubyMine 4.0.3/rb/testing/patch/bdd/teamcity/cucumber/common.rb:112:in `tc_before_feature’
    C:/Program Files (x86)/JetBrains/RubyMine 4.0.3/rb/testing/patch/bdd/teamcity/cucumber/formatter_03103.rb:32:in `before_feature’
    C:/Ruby193/lib/ruby/gems/1.9.1/gems/cucumber-1.3.1/lib/cucumber/ast/tree_walker.rb:181:in `block in send_to_all’
    C:/Ruby193/lib/ruby/gems/1.9.1/gems/cucumber-1.3.1/lib/cucumber/ast/tree_walker.rb:179:in `each’
    C:/Ruby193/lib/ruby/gems/1.9.1/gems/cucumber-1.3.1/lib/cucumber/ast/tree_walker.rb:179:in `send_to_all’
    C:/Ruby193/lib/ruby/gems/1.9.1/gems/cucumber-1.3.1/lib/cucumber/ast/tree_walker.rb:169:in `broadcast’
    C:/Ruby193/lib/ruby/gems/1.9.1/gems/cucumber-1.3.1/lib/cucumber/ast/tree_walker.rb:26:in `visit_feature’
    C:/Ruby193/lib/ruby/gems/1.9.1/gems/cucumber-1.3.1/lib/cucumber/ast/features.rb:28:in `block in accept’
    C:/Ruby193/lib/ruby/gems/1.9.1/gems/cucumber-1.3.1/lib/cucumber/ast/features.rb:17:in `each’
    C:/Ruby193/lib/ruby/gems/1.9.1/gems/cucumber-1.3.1/lib/cucumber/ast/features.rb:17:in `each’
    C:/Ruby193/lib/ruby/gems/1.9.1/gems/cucumber-1.3.1/lib/cucumber/ast/features.rb:27:in `accept’
    C:/Ruby193/lib/ruby/gems/1.9.1/gems/cucumber-1.3.1/lib/cucumber/ast/tree_walker.rb:21:in `block in visit_features’
    C:/Ruby193/lib/ruby/gems/1.9.1/gems/cucumber-1.3.1/lib/cucumber/ast/tree_walker.rb:170:in `broadcast’
    C:/Ruby193/lib/ruby/gems/1.9.1/gems/cucumber-1.3.1/lib/cucumber/ast/tree_walker.rb:20:in `visit_features’
    C:/Ruby193/lib/ruby/gems/1.9.1/gems/cucumber-1.3.1/lib/cucumber/runtime.rb:48:in `run!’
    C:/Ruby193/lib/ruby/gems/1.9.1/gems/cucumber-1.3.1/lib/cucumber/cli/main.rb:47:in `execute!’
    C:/Ruby193/lib/ruby/gems/1.9.1/gems/cucumber-1.3.1/bin/cucumber:13:in `’
    C:/Ruby193/bin/cucumber:23:in `load’
    C:/Ruby193/bin/cucumber:23:in `’
    -e:1:in `load’
    -e:1:in `’

    Process finished with exit code 1
    Empty test suite.

    • Sudheer,

      Please update to the latest version of RubyMine. The error you are experiencing is related to an incompatibility between older versions of RubyMine and a change that was made in Cucumber recently.

      -Cheezy

  21. Sir, May I know which version you suggest for the problem. There are 3 versions available after Rubymine 4.0. Thanks

  22. When I installed latest version of the rubymine how to make sure that all the gems installed earlier will automatically gets loaded to Rubymine latest version showthat I can see in setttings/rubysdk and gems window.

    • RubyMine does not actually load the gems. Instead, it points to them. You can select the appropriate version of ruby to use (from the ones you have installed) in the Settings dialog in the section labeled “Ruby SDK and Gems”.

  23. Hi, I am trying to run rubyscripts in Chrome. I am getting the fallowing error for all scrips. Please help me.
    Program:
    require ‘rubygems’
    require ‘watir-webdriver’
    browser = Watir::Browser.new :chrome
    browser.goto ‘http://www.apple.com’
    Error:
    C:/Ruby193/lib/ruby/gems/1.9.1/gems/selenium-webdriver-2.32.1/lib/selenium/webdriver/remote/http/common.rb:66:in `create_response’: unexpected response, code=404, content-type=”” (Selenium::WebDriver::Error::WebDriverError)
    unknown command: session/url
    from C:/Ruby193/lib/ruby/gems/1.9.1/gems/selenium-webdriver-2.32.1/lib/selenium/webdriver/remote/http/default.rb:66:in `request’
    from C:/Ruby193/lib/ruby/gems/1.9.1/gems/selenium-webdriver-2.32.1/lib/selenium/webdriver/remote/http/common.rb:40:in `call’
    from C:/Ruby193/lib/ruby/gems/1.9.1/gems/selenium-webdriver-2.32.1/lib/selenium/webdriver/remote/bridge.rb:619:in `raw_execute’
    from C:/Ruby193/lib/ruby/gems/1.9.1/gems/selenium-webdriver-2.32.1/lib/selenium/webdriver/remote/bridge.rb:597:in `execute’
    from C:/Ruby193/lib/ruby/gems/1.9.1/gems/selenium-webdriver-2.32.1/lib/selenium/webdriver/remote/bridge.rb:103:in `get’
    from C:/Ruby193/lib/ruby/gems/1.9.1/gems/selenium-webdriver-2.32.1/lib/selenium/webdriver/common/navigation.rb:14:in `to’
    from C:/Ruby193/lib/ruby/gems/1.9.1/gems/watir-webdriver-0.6.4/lib/watir-webdriver/browser.rb:77:in `goto’
    from C:/rubytraining/learn_ruby/first_script.rb:4:in `’
    from -e:1:in `load’
    from -e:1:in `’

    Process finished with exit code 1

  24. Hello Cheezy,

    Thank you for an excellent book, I like the very hands on approach, I am stuck at the end of chapter 5 , section “Removing the duplicate navigation”,B6.0 the method call to navigate_to does not work in the below step, am I missing something ? all routes are setup in env.rb and all requires seem to be in place. I cant also find the definition of navigate_to in page_factory.rb

    When(/^I checkout leaving the name field blank$/) do
    navigate_to(CheckoutPage).checkout(‘name’ => ”)
    end

    When I checkout leaving the name field blank
    undefined method `new’ for PageObject::PageFactory:Module (NoMethodError)
    ./features/step_definitions/adoption_steps.rb:85:in `/^I checkout leaving
    the name field blank$/’
    features\adopting_puppies.feature:80:in `When I checkout leaving the name
    field blank’


    Having said that the below step from another scenario that uses navigate_all works

    When /^I complete the adoption of a puppy$/ do
    navigate_all
    end

    • Sorry pl ignore the previous error , the actual error message I get is is below
      ———-
      When I checkout leaving the name field blank
      undefined method `navigate_to’ for nil:NilClass (NoMethodError)
      ./features/step_definitions/adoption_steps.rb:85:in `/^I checkout leaving
      the name field blank$/’
      features\adopting_puppies.feature:80:in `When I checkout leaving the name
      field blank’
      Then I should see error message “Name can’t be blank”
      ———-

      • Its me again :-), just realised that I had missed the page_navigation gem, how ever this still does not work, I am not sure how will the navigate_to will work without an initial page reference ? how ever the code in the book uses it without a reference ?

        • Did you add PageObject::PageFactory to World? If not, please add this line to your env.rb file.

          World(PageObject::PageFactory)

          -Cheezy

          • Thanks for your message.
            Solved it, found out that in my env.rb I had World(PageObject::PageFactory, PageObject) causing the navigate_to of module PageObject being invoked instead of the page_navigation method ! removed the PageObject from there.

  25. Hello again Cheezy,

    I am encountering some problems when setting up to use active record and factory girl. The error I get is

    —– Start ———–
    Unable to activate activesupport-3.2.13, because i18n-0.6.4 conflicts with i18n (= 0.6.1) (Gem::LoadError)
    D:/RailsInstaller/Ruby1.9.3/lib/ruby/site_ruby/1.9.1/rubygems/specification.rb:1637:in `raise_if_conflicts’
    D:/RailsInstaller/Ruby1.9.3/lib/ruby/site_ruby/1.9.1/rubygems/specification.rb:746:in `activate’
    D:/RailsInstaller/Ruby1.9.3/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:51:in `block in require’
    D:/RailsInstaller/Ruby1.9.3/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:50:in `each’
    D:/RailsInstaller/Ruby1.9.3/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:50:in `require’
    D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/factory_girl-4.2.0/lib/factory_girl.rb:2:in `’
    D:/RailsInstaller/Ruby1.9.3/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:60:in `require’
    D:/RailsInstaller/Ruby1.9.3/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:60:in `rescue in require’
    D:/RailsInstaller/Ruby1.9.3/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:35:in `require’
    D:/eBook/cucumber/cukes_and_cheese/test_puppies/features/support/env.rb:10:in `’
    D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/cucumber-1.3.2/lib/cucumber/rb_support/rb_language.rb:122
    :in `load’
    D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/cucumber-1.3.2/lib/cucumber/rb_support/rb_language.rb:122
    :in `load_code_file’
    D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/cucumber-1.3.2/lib/cucumber/runtime/support_code.rb:180:i
    n `load_file’
    D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/cucumber-1.3.2/lib/cucumber/runtime/support_code.rb:83:in
    `block in load_files!’
    D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/cucumber-1.3.2/lib/cucumber/runtime/support_code.rb:82:in
    `each’
    D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/cucumber-1.3.2/lib/cucumber/runtime/support_code.rb:82:in
    `load_files!’
    D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/cucumber-1.3.2/lib/cucumber/runtime.rb:183:in `load_step_
    definitions’
    D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/cucumber-1.3.2/lib/cucumber/runtime.rb:42:in `run!’
    D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/cucumber-1.3.2/lib/cucumber/cli/main.rb:47:in `execute!’
    D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/cucumber-1.3.2/bin/cucumber:13:in `’
    D:/RailsInstaller/Ruby1.9.3/bin/cucumber:23:in `load’
    D:/RailsInstaller/Ruby1.9.3/bin/cucumber:23:in `’
    —– End —-
    I have discovered that factory girl tries to use i18n-0.6.4 but some one else has already loaded i18n-0.6.1 ? Also not sure why active support 3.2.13 is being activated when I have said active record 3.2.1 in database.rb ??

    bundle install for test_puppies gives
    —— Start —
    D:\eBook\cucumber\cukes_and_cheese\test_puppies>bundle install
    Using i18n (0.6.4)
    Using multi_json (1.7.7)
    Using activesupport (3.2.1)
    Using builder (3.0.4)
    Using activemodel (3.2.1)
    Using arel (3.0.2)
    Using tzinfo (0.3.37)
    Using activerecord (3.2.1)
    Using ffi (1.9.0)
    Using childprocess (0.3.9)
    Using diff-lcs (1.2.4)
    Using gherkin (2.12.0)
    Using cucumber (1.3.2)
    Using faker (1.1.2)
    Using yml_reader (0.2)
    Using data_magic (0.14)
    Using database_cleaner (1.0.1)
    Using factory_girl (4.2.0)
    Using page_navigation (0.9)
    Using rubyzip (0.9.9)
    Using websocket (1.0.7)
    Using selenium-webdriver (2.33.0)
    Using watir-webdriver (0.6.4)
    Using page-object (0.9.0)
    Using rspec-core (2.13.1)
    Using rspec-expectations (2.13.0)
    Using rspec-mocks (2.13.1)
    Using rspec (2.13.0)
    Using sqlite3 (1.3.7)
    Using bundler (1.0.22)
    Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem is installed.
    — End —

    env.rb has require ‘factory_girl’ and

    World(PageObject::PageFactory, Watir::Waitable, StepHelper,FactoryGirl::Syntax::Methods)

    I also have the puppy application running as a rails app on localhost while I try to run cucumber.

  26. Hello Cheezy,

    Just a suggestion about the book, I often tend to copy and paste the code snippets from the book as I progress but am having to delete the line numbers that get copied from the pdf , is there a way this can be avoided perhaps by havng line numbers a comments on the right hand side instead or have a ‘figure’ label for each snippet that points to a url ? I find the snippets extremly useful and prefer to either type them myself or copy paste instead of downloading an entire zip file. This makes it stick to you more.

  27. Hello Cheezy,
    Having issues running the android demo, error “Unknown error (Windows says “The operation completed successfully.”, but it did not.) (ChildProcess::LaunchError) on Windows 7 Enterprise 64 bit. I understand that this might be a known issue. Any workarounds ?

    • I have not seen this reported. Can you provide some more details that might help me troubleshoot? Also, please open an issue on the gem page.

      • Hello Cheezy,
        This is my first ever test test for a mobile app !
        I have managed to install the android SDK and managed to install the puppy application which then I can start from the android avd command and I can start the puppy app on the emulator. I then try to run cuke features as mentioned in the book which throws the error.

        bundle update gives
        Using rake (10.1.0)
        Using ffi (1.9.0)
        Using childprocess (0.3.9)
        Using ADB (0.5.6)
        Using brazenhead (0.4.7)
        Using builder (3.2.2)
        Using diff-lcs (1.2.4)
        Using multi_json (1.7.7)
        Using gherkin (2.12.0)
        Using multi_test (0.0.1)
        Using cucumber (1.3.3)
        Using i18n (0.6.4)
        Using faker (1.1.2)
        Using yml_reader (0.2)
        Using data_magic (0.14)
        Using page_navigation (0.9)
        Using gametel (0.7)
        Using require_all (1.2.1)
        Using rspec-core (2.14.1)
        Using rspec-expectations (2.14.0)
        Using rspec-mocks (2.14.1)
        Using rspec (2.14.0)
        Using bundler (1.0.22)
        —————————-
        Error thrown to console
        ——————————
        Using the default profile…
        Feature: Displaying information about the puppies available for adoption

        This screen really has no behavior. It simply displayes the
        list of puppies available for adoption.

        Background:
         Unknown error (Windows says "The operation completed successfully.", but it did not.) (ChildProcess::LaunchError)
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/childprocess-0.3.9/lib/childprocess/windows/process_builder.rb:87:in `create_process'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/childprocess-0.3.9/lib/childprocess/windows/process_builder.rb:34:in `start'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/childprocess-0.3.9/lib/childprocess/windows/process.rb:63:in `launch_process'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/childprocess-0.3.9/lib/childprocess/abstract_process.rb:72:in `start'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/brazenhead-0.4.7/lib/brazenhead/process.rb:12:in `run'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/brazenhead-0.4.7/lib/brazenhead/manifest_info.rb:32:in `load_manifest'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/brazenhead-0.4.7/lib/brazenhead/manifest_info.rb:28:in `manifest'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/brazenhead-0.4.7/lib/brazenhead/manifest_info.rb:37:in `first_capture'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/brazenhead-0.4.7/lib/brazenhead/manifest_info.rb:7:in `package'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/brazenhead-0.4.7/lib/brazenhead/builder.rb:68:in `the_target'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/brazenhead-0.4.7/lib/brazenhead/builder.rb:58:in `update_test_manifest'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/brazenhead-0.4.7/lib/brazenhead/builder.rb:30:in `block in install_server'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/brazenhead-0.4.7/lib/brazenhead/builder.rb:28:in `chdir'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/brazenhead-0.4.7/lib/brazenhead/builder.rb:28:in `install_server'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/brazenhead-0.4.7/lib/brazenhead/builder.rb:20:in `block in build_for'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/tmpdir.rb:83:in `mktmpdir'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/brazenhead-0.4.7/lib/brazenhead/builder.rb:19:in `build_for'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/brazenhead-0.4.7/lib/brazenhead/server.rb:26:in `build'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/brazenhead-0.4.7/lib/brazenhead/server.rb:15:in `start'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/gametel-0.7/lib/gametel.rb:41:in `start'
         D:/eBook/cucumber/cukes_and_cheese/android_puppies/features/support/env.rb:18:in `Before'
        When I am looking at the available puppies
         An existing connection was forcibly closed by the remote host. (Errno::ECONNRESET)
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/protocol.rb:141:in `read_nonblock'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/protocol.rb:141:in `rbuf_fill'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/protocol.rb:122:in `readuntil'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/protocol.rb:132:in `readline'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:2562:in `read_status_line'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:2551:in `read_new'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:1319:in `block in transport_request'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:1316:in `catch'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:1316:in `transport_request'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:1293:in `request'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:1286:in `block in request'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:745:in `start'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:1284:in `request'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:1307:in `send_entity'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:1096:in `post'
         ./features/step_definitions/android_steps.rb:2:in `/^I am looking at the available puppies$/'
         features\android.feature:7:in `When I am looking at the available puppies'
         An existing connection was forcibly closed by the remote host. (Errno::ECONNRESET)
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/protocol.rb:141:in `read_nonblock'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/protocol.rb:141:in `rbuf_fill'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/protocol.rb:122:in `readuntil'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/protocol.rb:132:in `readline'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:2562:in `read_status_line'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:2551:in `read_new'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:1319:in `block in transport_request'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:1316:in `catch'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:1316:in `transport_request'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:1293:in `request'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:1286:in `block in request'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:745:in `start'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:1284:in `request'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:1307:in `send_entity'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:1096:in `post'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/brazenhead-0.4.7/lib/brazenhead/device.rb:22:in `stop'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/brazenhead-0.4.7/lib/brazenhead/server.rb:20:in `stop'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/gametel-0.7/lib/gametel.rb:46:in `stop'
         D:/eBook/cucumber/cukes_and_cheese/android_puppies/features/support/env.rb:22:in `After'

        Scenario: Knowing the name of the available puppies
        Then I can see that "Sparky" is available for adoption

        Scenario: Knowing the breed and gender of available puppies
        Then I can see the "Ruby Sue" is a "Pit Bull Terrier"
        And I can see that "Ruby Sue" is a "Female"

        Scenario: Being overwhelmed by the cuteness of the available puppies
        Then I will be moved when I look into "Maggie Mae"s eyes

        Scenario: Getting to know the available puppies
        Then I can see that "Brook"s description starts with "This young lady is trying"

        Feature: Displaying the details of a puppy

        Background:
         Unknown error (Windows says "The operation completed successfully.", but it did not.) (ChildProcess::LaunchError)
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/childprocess-0.3.9/lib/childprocess/windows/process_builder.rb:87:in `create_process'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/childprocess-0.3.9/lib/childprocess/windows/process_builder.rb:34:in `start'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/childprocess-0.3.9/lib/childprocess/windows/process.rb:63:in `launch_process'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/childprocess-0.3.9/lib/childprocess/abstract_process.rb:72:in `start'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/brazenhead-0.4.7/lib/brazenhead/process.rb:12:in `run'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/brazenhead-0.4.7/lib/brazenhead/manifest_info.rb:32:in `load_manifest'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/brazenhead-0.4.7/lib/brazenhead/manifest_info.rb:28:in `manifest'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/brazenhead-0.4.7/lib/brazenhead/manifest_info.rb:37:in `first_capture'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/brazenhead-0.4.7/lib/brazenhead/manifest_info.rb:7:in `package'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/brazenhead-0.4.7/lib/brazenhead/builder.rb:68:in `the_target'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/brazenhead-0.4.7/lib/brazenhead/builder.rb:58:in `update_test_manifest'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/brazenhead-0.4.7/lib/brazenhead/builder.rb:30:in `block in install_server'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/brazenhead-0.4.7/lib/brazenhead/builder.rb:28:in `chdir'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/brazenhead-0.4.7/lib/brazenhead/builder.rb:28:in `install_server'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/brazenhead-0.4.7/lib/brazenhead/builder.rb:20:in `block in build_for'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/tmpdir.rb:83:in `mktmpdir'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/brazenhead-0.4.7/lib/brazenhead/builder.rb:19:in `build_for'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/brazenhead-0.4.7/lib/brazenhead/server.rb:26:in `build'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/brazenhead-0.4.7/lib/brazenhead/server.rb:15:in `start'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/gametel-0.7/lib/gametel.rb:41:in `start'
         D:/eBook/cucumber/cukes_and_cheese/android_puppies/features/support/env.rb:18:in `Before'
        Given I am looking at the available puppies
         An existing connection was forcibly closed by the remote host. (Errno::ECONNRESET)
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/protocol.rb:141:in `read_nonblock'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/protocol.rb:141:in `rbuf_fill'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/protocol.rb:122:in `readuntil'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/protocol.rb:132:in `readline'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:2562:in `read_status_line'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:2551:in `read_new'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:1319:in `block in transport_request'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:1316:in `catch'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:1316:in `transport_request'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:1293:in `request'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:1286:in `block in request'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:745:in `start'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:1284:in `request'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:1307:in `send_entity'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:1096:in `post'
         ./features/step_definitions/android_steps.rb:2:in `/^I am looking at the available puppies$/'
         features\puppy_details.feature:4:in `Given I am looking at the available puppies'
         An existing connection was forcibly closed by the remote host. (Errno::ECONNRESET)
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/protocol.rb:141:in `read_nonblock'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/protocol.rb:141:in `rbuf_fill'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/protocol.rb:122:in `readuntil'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/protocol.rb:132:in `readline'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:2562:in `read_status_line'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:2551:in `read_new'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:1319:in `block in transport_request'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:1316:in `catch'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:1316:in `transport_request'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:1293:in `request'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:1286:in `block in request'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:745:in `start'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:1284:in `request'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:1307:in `send_entity'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:1096:in `post'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/brazenhead-0.4.7/lib/brazenhead/device.rb:22:in `stop'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/brazenhead-0.4.7/lib/brazenhead/server.rb:20:in `stop'
         D:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/gametel-0.7/lib/gametel.rb:46:in `stop'
         D:/eBook/cucumber/cukes_and_cheese/android_puppies/features/support/env.rb:22:in `After'

        Scenario: Learning more about a puppy I am interested in
        When I want to learn more information about "Sparky"
        Then I will be able to see "Sparky"s details

        Scenario: Seeing the name and breed of my puppy
        When I want to learn more information about "Sparky"
        Then I know that he is a type of "Austrailian Cattle Dog (Blue Heeler)"
        And I know that he is a "Male"

        Scenario: Learning more about the life of my puppy
        When I want to learn more information about "Spud"
        Then I can see that my puppy "is playful and friendly and would make a great addition to your family"

        Scenario: Looking into the eyes of my puppy one last time
        When I want to learn more information about "Ruby Sue"
        Then I can look into the eyes of my puppy before I make my decision

        Scenario: Knowing what my puppy will set me back
        When I want to learn more information about "Tipsy"
        Then I know that the adoption fee is "$42.00"

        Failing Scenarios:
        cucumber features\android.feature:9
        cucumber features\puppy_details.feature:6

        9 scenarios (2 failed, 7 skipped)
        25 steps (2 failed, 23 skipped)
        0m22.529s
        ---
        Failed to send the command commands=[{"name":"waitForActivity","arguments":["PuppiesActivity"]}] 20 times…
        ——————-

  28. Hello Cheezy,

    Your book and your gems have been very helpful.

    I am trying to develop a suite of acceptance tests for a legacy .NET web application. One of our goals is to have this suite available so that we can do extensive refactoring of the original backend code. The tests will let us know if we break something.

    I am trying to use the PageObject gem to click on a button. Unfortunately the button is not really a button, but is a div, declared in HTML like this:

    SignOut

    In the legacy javascript/JQuery I read:

    $(“#SignOut”).button();

    And also:

    $(“#SignOut”).click(function() {

    });

    So the button is declared as a div and somehow given a clickable property which functions as desired.

    When I try to access and click this element via PageObject I fail.

    When I have “button(:signout_button, :id=> ‘SignOut’)” in my page class and “on(DefaultPage).signout_button” in my step definition I get:
    unable to locate element, using {:id=>”SignOut”, :tag_name=>”button”} (Watir::Exception::UnknownObjectException)
    (eval):1:in `process_watir_call’

    When I try using “div(:signout_div, :id=> ‘SignOut’)” in my page class and “on(DefaultPage).signout_div.click” in my step definition I get:

    undefined method `click’ for “Sign Out”:String (NoMethodError)

    Which makes sense because “on(DefaultPage).signout_div” would just return the contents of the div.

    How can I click on this “button” in my test? I prefer to not have to modify the legacy code in order to make it testable.

  29. Hi:

    Do you know of any way to use Cucumber and Watir to interact with a flash module (swf)? I would like to be able to click on links and buttons in the flash element similar to how I interact with a browser application. Any information would be appreciated.

    Keep up the good work!
    Regards,
    Gordon

    • PageObject does not work with Flash because selenium-webdriver and watir-webdriver do not work with Flash. I’ve never worked with Flash so I do not have a good solution for you. You might ask a friend of mine – @robpark on twitter. I think he has some experience with Flash and Cucumber.

  30. Hi Cheezy,
    I have a test that works fine with Firefox web driver.
    With Chrome Web Driver, it errors like:
    NoMethodError: undefined method `>’ for nil:NilClass
    Points to code: mymax = page.page_count > 3 ? 3 : page.page_count

    Looks like Chrome doesn’t like the greater than sign ‘>’.
    Any help or workaround? – Thanks

  31. Hi Cheezy,
    Resolved => NoMethodError: undefined method `>’ for nil:NilClass
    Chrome is not as forgiving as Firefox. I had to change page.page_count to page.page_count.to_i.

    Regards

  32. Hi Cheezy,
    When I tried to install the puppy application, I am getting error – ‘rails’ is not recognized as an internal or external command,
    operable program or batch file.

    I extracted the zip to the directory where puppy_test is located
    In cmd I set the path to – C:\SanjayWork\Ruby-Project\puppies
    and run bundle install
    It complained that
    C:\SanjayWork\Ruby-Project\puppies>bundle install
    Fetching gem metadata from http://rubygems.org/……..
    Fetching gem metadata from http://rubygems.org/..
    Resolving dependencies…
    Could not find addressable-2.3.1 in any of the sources

    I did a manual install for addressable gem and it installed version 2.3.5

    Then I run rails s, then another error –
    ‘rails’ is not recognized as an internal or external command,
    operable program or batch file.

    Can you please help ?

    Many Thanks,
    Sanjay

    • Try this. Change to the directory where you unzipped the zip file and execute ‘bundle update’. Let me know if this works.

  33. Hi Cheezy,
    In this, text_field :your_name, :id => ‘some_id’, how it is finding the element.
    Is it thru xpath or CSS.
    Because I have issues while executing in IE.
    Could you please clarify?

    • That depends on the driver you are using. It is totally internal to either watir or selenium and is not consistent from browser to browser. What issue are you seeing with IE and what version of IE?

  34. Hi Cheezy,
    I verify something for a particular product and my scenario works fine.
    I want to do the same for 3 products. Is there a way to run the 3 scenarios in parallel?

    -Thanks

    • The good news is that if you follow the approach in the book you do not need to focus on watir or selenium. PageObject abstracts all of that away.

      I’m happy you like the book. Please help me spread the word. Let others know about it!

      -Cheezy

  35. Hi,
    I’m making my way through the book and stuck at testgen on page 40.
    I ran gem install testgen
    gem install bundler
    Then i ran testgen project test_puppies –pageobject-driver=watir
    and got an error :

    No command ‘testgen’ found, did you mean:
    Command ‘tetgen’ from package ‘tetgen’ (multiverse)
    testgen: command not found

    Thanks for your help

      • Thanks for replying!
        Yes, I do see it when I run gem list:
        testgem (0.1.0).
        Worst case scenario, I can create file structure manually.

        Thanks again. Awesome book !

        • The problem is that testgen is currently on version 0.8.4. Please update the gem and let me know if the problem still exists. If you are using bundler you can simply execute `bundler update`. If not simply execute `gem update testgen`.

      • Actually I tried again and it worked. Interesting, I VPN-ed to my workstation (linux) and then It complained. Sorry for the noise

  36. Hi Cheezy,

    Stuck on the webservices example on page 135. I get a bad URI exception. The URI how ever seems to be perfectly valid. Did some googling but not sure if this is a bug in the ruby uri module or something else ? I am using ruby ruby 1.9.3p125 (2012-02-16) [i386-mingw32]

    I get the below when I try to run the feature

    When I ask the service for the supported operations
    bad URI(is not URI?): {:host=>”www.webservicex.net”, :path=>”/uszip.asmx”, :port=>”80″, :query
    =>”WSDL”, :scheme=>”http”, :headers=>{}, :body=>nil, :ssl_verify_peer=>true} (URI::InvalidURIError)
    D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/uri/common.rb:178:in `split’
    D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/uri/common.rb:213:in `parse’
    D:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/uri/common.rb:749:in `parse’
    ./features/step_definitions/web_service_steps.rb:2:in `/^I ask the service for the supported operations$/’
    features\web_service.feature:4:in `When I ask the service for the supported operations’

  37. Hey Cheese ,
    How are you?
    I am newvbie in automation , learning things from your book . but here i am facing a challenge is that – how could user background scernario in my every feauter .
    example : I want to fill up a form in website . so it needs to log into the site . I have successfully done with login as seperate feature . but when i am writing feature for fill up form , then I could i impletement login in filling up a form feature

    Can you please help me out

    • I would instead allow a route to handle all of this for me. Setup a route that logs into the system and navigates to the pages. Then your first step could say “Given I’m ” and your step definition could simply “navigate_to(PageForAction)”. Look up the section that talks about navigation and routes in the book.

  38. Hi Cheezy,

    Thanks so much for this book, has saved me countless hours on trying to create a framework using the page object model. I found a typo on page 206; ‘complicated’ should be complicated.

    Thanks!

  39. Love the book. Thanks! I do have a couple questions I hope you can answer.

    How would you recommend storing data. For example a list of emails. I want to do something like this:
    Given I am signed in as user1

    My step would be:
    Given(/^I am signed in as ([^"]*)$/) do |user|
    @email = somemethod(user)
    visit HomePage do |page|
    page.signin(:email => @email)
    end
    end

    Should it be stored in a hash? In a module? In a hash in a module? I thought of putting it in the default.yml file that is used by DataMagic but was not sure how to access that in the step definitions. There are currently about 15 email addresses.

    • Jesse,

      I would store them in the DataMagic file like this:


      Sam:
      email: sam@example.com

      and then I would simply pass the user name to the page like this:

      Given(/^I am signed in as ([^"]*)$/) do |user|
        visit(HomePage).signin_as(user)
      end
      

      Inside the page you can simply call data_for(user) to get the email address.

      -Cheezy

      • Thanks. After some trial and error I did something similar.

        Had another question about running tests in parallel. How many threads are possible before stability becomes an issue? I run 8 threads with my quad core. If possible I would like to take advantage of a second quad core using Selenium Grid2. I would run the hub and one node on my laptop. The other node would be on the second machine. Could I run 12-16 threads in this type of setup without issues?
        Thanks for your help.

  40. Hi,

    I try to Installing the puppy application on your computer.
    When I run
    rails s
    I am getting:
    C:/Ruby193/lib/ruby/gems/1/9.1/gems/execjs-2.0.2/lib/execjs/runtimes.rb:51:in ‘autodetect’: Could not find JavaScript runtime.
    See https:github.com/sstephenson/execjs for a list of available runtimes.(ExecJS::RuntimeUnavailable)


    I have installed execjs 2.0.2
    But I am getting the same error.

    Do you know what do I have to do?

    Thanks,
    Cristina

  41. Hi Cheezy,

    I’m getting a Deprecation Warning when I attempt to use tr, trs, and row methods through page-object.

    I know you’re planning on removing the forwarding to watir that you have setup, so I’m wondering what is the intended way to use page object for dynamically figuring out what row to hit.

    The line of my code that’s giving me an issue is

    individual_list_element.tr(:id=>"#{user}").button(:class=>'btn btn-primary dropdown-toggle')

    • Michael,

      Sorry for not getting back sooner. Can you tell me what is the `individual_list_element`? Is it a table?

      Thanks
      -Cheezy

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>