Module: PageObject::PageClassMethods

Defined in:
lib/site-object/page.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#argumentsObject (readonly)

Returns the value of attribute arguments.



65
66
67
# File 'lib/site-object/page.rb', line 65

def arguments
  @arguments
end

#browserObject (readonly)

Returns the value of attribute browser.



65
66
67
# File 'lib/site-object/page.rb', line 65

def browser
  @browser
end

Returns the value of attribute navigation_disabled.



65
66
67
# File 'lib/site-object/page.rb', line 65

def navigation_disabled
  @navigation_disabled
end

#page_elementsObject (readonly)

Returns the value of attribute page_elements.



65
66
67
# File 'lib/site-object/page.rb', line 65

def page_elements
  @page_elements
end

#page_featuresObject (readonly)

Returns the value of attribute page_features.



65
66
67
# File 'lib/site-object/page.rb', line 65

def page_features
  @page_features
end

#page_urlObject (readonly)

Returns the value of attribute page_url.



65
66
67
# File 'lib/site-object/page.rb', line 65

def page_url
  @page_url
end

#siteObject (readonly)

Returns the value of attribute site.



65
66
67
# File 'lib/site-object/page.rb', line 65

def site
  @site
end

#unique_methodsObject (readonly)

Returns the value of attribute unique_methods.



65
66
67
# File 'lib/site-object/page.rb', line 65

def unique_methods
  @unique_methods
end

#url_matcherObject (readonly)

Returns the value of attribute url_matcher.



65
66
67
# File 'lib/site-object/page.rb', line 65

def url_matcher
  @url_matcher
end

#url_templateObject (readonly)

Returns the value of attribute url_template.



65
66
67
# File 'lib/site-object/page.rb', line 65

def url_template
  @url_template
end

Instance Method Details

#descendantsObject

Looks up all of the descendants of the current class. Used to figure out which page object classes belong to the site.



69
70
71
# File 'lib/site-object/page.rb', line 69

def descendants
  ObjectSpace.each_object(Class).select { |klass| klass < self }
end

#disable_automatic_navigationObject

This method can be used to disable page navigation when defining a page class (it sets an instance variable called @navigation during initialization.) The use case for this is a page that can’t be accessed directly and requires some level of browser interaction to reach. To disable navigation:

class SomePage < SomeSite::Page
  disable_automatic_navigation true
end

When navigation is disabled there will be no automatic navigation when the page is called. If the current page is not the page that you want a SiteObject::WrongPageError will be raised. If the visit method is called on the page a SiteObject::PageNavigationNotAllowedError will be raised.



87
88
89
# File 'lib/site-object/page.rb', line 87

def disable_automatic_navigation
  @navigation_disabled = true
end

#element(name, &block) ⇒ Object Also known as: el

Used to define access to a single HTML element on a page. This method takes two arguments:

  • A symbol representing the element you are defining. This symbol is used to create an accessor method on the page object.

  • A block where access to the HTML element gets defined.

Example: The page you are working with has a “First Name” field:

element(:first_name) { |b| b.text_field(:id 'signup-first-name') }

In the example above, the block argument ‘b’ is the browser object that will get passed down from the site to the page and used when the page needs to access the element. You can actually use any label for the block argument but it’s recommended that you use something like ‘b’ or ‘browser’ consistently here because it’s always going to be some sort of browser object.

When page objects get initialized they’ll create an accessor method for the element and you can then work with the element in the same way you’d work with it in Watir or Selenium.

The element method is aliased to ‘el’ and using this alias is recommended as it saves space:

el(:first_name) { |b| b.text_field(:id 'signup-first-name') }


111
112
113
114
115
116
117
# File 'lib/site-object/page.rb', line 111

def element(name, &block)
  @page_elements ||= []
  @page_elements << name.to_sym
  define_method(name) do
    block.call(@browser)
  end
end

#required_argumentsObject

Returns an array of symbols representing the required arguments for the page’s page URL.



121
122
123
# File 'lib/site-object/page.rb', line 121

def required_arguments
  @arguments ||= @url_template.keys.map { |k| k.to_sym }
end

#set_url(url) ⇒ Object

Used to define the full or relative URL to the page. Typically, you will almost always want to use this method when defining a page object (but see notes below.) The URL can be defined in a number of different ways. Here are some examples using Google News:

Relative URL

set_url "/nwshp?hl=en"

Relative URLs are most commonly used when defining page objects. The idea here is that you can change the base_url when calling the site object, which allows you to use the same code across multiple test environments by changing the base_url as you initialize a site object.

Relative URL with URL Templating

set_url "/nwshp?hl={language}"

This takes the relative URL example one step further, allowing you to set the page’s parameters. Note that the the language specified in the first relative URL example (‘en’) was replaced by ‘language’ in this one. Siteobject uses the Addressable library, which supports this kind of templating. When you template a value in the URL, the page object will allow you to specify the templated value when it’s being initialized. Here’s an example of how this works using a news site. Here’s the base site object class:

class NewsSite
  include SiteObject
end

Here’s a page object for the news page, templating the language value in the URL:

class NewsPage < NewsSite::Page
  set_url "/news?l={language}"
end

After you’ve initialized the site object you can load the Spanish or French versions of the page by changing the hash argument used to call the page from the site object:

site = NewsSite.new(base_url: "http://news.somesite.com")
site.news_page(language: 'es')
site.news_page(language: 'fr')

In addition to providing a hash of templated values when initializing a page you can also use an object, as long as that object responds to all of the templated arguments in the page’s URL definition. Here’s a simple class that has a language method that we can use for the news page described above:

class Country
  attr_reader :language

  def initialize(lang)
    @language = lang
  end
end

In the example below, the Country class is used to create a new new country object called ‘c’. This object has been initialized with a Spanish language code and the news page will load the spanish version of the page when it’s called with the country object.

site = NewsSite.new(base_url: "http://news.somesite.com")
c = Country.new('es')
=> <Country:0x007fcb0dc67f98 @language="es">
c.language
=> 'es'
site.news_page(c)
=> <NewsPage:0x003434546566>

If one or more URL parameters are missing when the page is getting initialized then the page will look at the hash arguments used to initialize the site. If the argument the page needs is defined in the site’s initialization arguments it will use that. For example, if the site object is initialized with a port, subdomain, or any other argument you can use those values when defining a page URL. Example:

class ConfigPage < MySite::Page
  set_url "/foo/{subdomain}/config"
end

site = MySite.new(subdomain: 'foo')
=> <MySite:0x005434546511>
site.configuration_page # No need to provide a subdomain here as long as the site object has it.
=> <ConfigPage:0x705434546541>

Full URL

set_url "http://news.google.com/nwshp?hl=en"

Every once in a while you may not want to use a base URL that has been defined. This allows you to do that. Just define a complete URL for that page object and that’s what will get used; the base_url will be ignored.

No URL

The set_url method is not mandatory. when defining a page. If you don’t use set_url in the page definition then the page will defined the base_url as the page’s URL.



215
216
217
# File 'lib/site-object/page.rb', line 215

def set_url(url)
  url ? @page_url = url : nil
end

#set_url_matcher(regexp) ⇒ Object

Optional. Allows you to specify a fallback mechanism for checking to see if the correct page is being displayed. This only gets used in cases where the primary mechanism for checking a page (the URL template defined by Page#set_url) fails to match the current browser URL. When that happens the regular expression defined here will be applied and the navigation check will pass if the regular expression matches the current browser URL.

In most cases, you won’t need to define a URL matcher and should just rely on the default page matching that uses the page’s URL template. The default matching should work fine for most cases.



242
243
244
# File 'lib/site-object/page.rb', line 242

def set_url_matcher(regexp)
  regexp ? @url_matcher = regexp : nil
end

#set_url_template(base_url) ⇒ Object



219
220
221
222
223
224
225
226
227
228
229
230
231
232
# File 'lib/site-object/page.rb', line 219

def set_url_template(base_url)
  begin
    case @page_url.to_s
    when '' # There's no page URL so just assume the base URL
      @url_template = Addressable::Template.new(base_url)
    when /(http:\/\/|https:\/\/)/i
      @url_template = Addressable::Template.new(@page_url)
    else
      @url_template = Addressable::Template.new(Addressable::URI.parse("#{base_url}#{@page_url}"))
    end
  rescue Addressable::URI::InvalidURIError => e
    raise SiteObject::PageInitError, "Unable to initialize #{self.class} because there's no base_url defined for the site and the page object URL that was defined was a URL fragment (#{@page_url})\n\n#{caller.join("\n")}"
  end
end

#use_features(*args) ⇒ Object

Used to import page features for use within the page. Example:

class ConfigPage < MySite::Page
  use_features :footer, :sidebar
end

Then, once the page object has been initialized:

site.config_page.footer.about.click

Use the PageFeature class to define page features.



257
258
259
# File 'lib/site-object/page.rb', line 257

def use_features(*args)
  @page_features = args
end