StaleElementException
StaleElementException

Reputation: 270

undefined method error when accessing class page object from module

I'm trying to access class method which is defined in Module, I can call function but function has page object element which performs some operation like click, I'm getting following error:

undefined method "label_year" for Datefunctions:Class (NoMethodError)

Here's my files structure:

./lib/calender_util.rb:

module CalenderUtil
    def set_date
        Datefunctions.get_calender_year
    end
end
class Datefunctions
    include PageObject
    span(:label_year, :class=> 'ui-datepicker-year')
    span(:label_month, :class=> 'ui-datepicker-month')

   def self.get_calender_year
      return label_year
   end
end

./home_page.rb:

require 'calender_helper.rb'
include CalenderUtil

 def setTravelDate date
    CalenderUtil.set_date
 end

parts of env.rb:

require 'page-object'
require 'page-object/page_factory'
$: << File.dirname(__FILE__)+'/../../lib'

require 'calender_helper.rb'
include CalenderHelper

World PageObject::PageFactory
World CalenderHelper

In addition; I've defined include/require multiple times I'll take off once this solved.

Upvotes: 0

Views: 1737

Answers (2)

Justin Ko
Justin Ko

Reputation: 46846

The problem is that label_year is an instance method while get_calender_year is a class method. You cannot call the instance method since you have not created an instance of the class.

As Billy Chan pointed out, for your code to work, you need to create an instance of the Datefunctions class within your module. This seems a bit awkward since you would need to pass the browser instance to each method called in the CalenderUtil. To me CalenderUtil is a layer of abstraction that is not adding any value.

I think that you should:

  1. Use modules to encapsulate controls that are used across multiple pages.
  2. Include these modules within the page object classes that have the controls.
  3. Call the methods from the page objects.

For your example, I would create a Datefunctions module that defines the datepicker controls.

module DateFunctions
  include PageObject
  span(:label_year, :class=> 'ui-datepicker-year')
  span(:label_month, :class=> 'ui-datepicker-month')
end

Then for each page class that uses the datepicker control, include the module:

class MyPage
  include PageObject
  include DateFunctions
end

In your tests, I assume it is Cucumber but the same is true for whatever framework, use the method from the page object.

page = MyPage.new(browser)
page.label_year.should == '1/1/2013'

Upvotes: 1

Billy Chan
Billy Chan

Reputation: 24815

The reason is, the methods auto-generated by PageObject, are all instance methods. You can't use it in a class method because there is no instance.

Look at the doc's example:

class LoginPage
  include PageObject

  text_field(:username, :id => 'username')
  text_field(:password, :id => 'password')
  button(:login, :id => 'login')
end

login_page.username = 'cheezy'
login_page.password = 'secret'
login_page.login

The methods are for instances.

To fix, you need to create an instance.

module CalenderUtil
  def set_date
    page = Datefunctions.new(args_foo)
    page.label_year
  end
end

Upvotes: 1

Related Questions