kroe761 kroe761 - 6 months ago 45
Ruby Question

(Ruby) Cannot use selenium commands in cucumber tests?

I am trying to save object definitions in a "home page" file and simply call those methods whenever I need to use that button/link/image/etc. But for some reason the selenium commands are bringing up a

NoMethodError
. When I simply run the
cucumber
command while on the features folder in the terminal, I get these errors:

When I click on Site Management # features/step_definitions/steps.rb:17
undefined method `find_element' for nil:NilClass (NoMethodError)
./features/lib/pages/home.rb:3:in `siteMgmt'
./features/step_definitions/steps.rb:18:in `/^I click on Site Management$/'
features/test.feature:6:in `When I click on Site Management'


So in other words, it's trying to "click on site management," the code moves to the Home class, the SiteMgmt method (great!) and then fails when trying to run the selenium
find_method
method. I thought I might have to add a
require selenium-webdriver
at the top of
home.rb
, but a) that's NOT the case in
steps.rb
and, even if I add it, it doesn't work.

Here is the folder structure:

features/
--test.feature
lib/
pages/
--home.rb
step_definitions/
--steps.rb
support/
--env.rb


env.rb

require 'selenium-webdriver'

Dir[File.dirname(__FILE__) + "/../lib/pages/*.rb"].each {|file| require file }

Before do |scenario|
@driver = Selenium::WebDriver.for :chrome
@url = "URL goes here"
end

After do |scenario|
@driver.quit
end


test.feature

Feature: Proof of Concept
Stack overflow help!

Scenario:
Given I am logged into the site
When I click on Site Management
Then the Site Management page should load


steps.rb

Given(/^I am logged into AMP$/) do
@driver.get @amp_url
end

When(/^I click on Site Management$/) do
link = Home.new.siteMgmt
link.click
end

Then(/^the Site Management page should load$/) do
# assert here
end


home.rb

class Home
def siteMgmt
elem = @driver.find_element(:xpath, '//*[@id="body"]/section[2]/ul/li[1]/h3/a')
return elem
end
end


Thanks for all your help!

Answer

The @driver instance variable that's created in the Before block isn't available to an instantiated Home object. You could add a parameter to the site_mgmt method and pass the @driver instance variable in. Here's a contrived example:

class Home
  def site_mgmt(driver)
    elem = driver.find_element(:id, "logo")
  end
end

require 'selenium-webdriver'

@driver = Selenium::WebDriver.for :chrome
@driver.navigate.to "http://www.iana.org/domains/reserved"

link = Home.new.site_mgmt(@driver)
link.click

A couple of notes: 1) variables in ruby are snake_case'd (i.e. site_mgmt instead of siteMgmt; and 2) return elem in site_mgmt isn't needed because ruby methods implicitly return.