Module: PageObject::PageInstanceMethods

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.



263
264
265
# File 'lib/site-object/page.rb', line 263

def arguments
  @arguments
end

#browserObject (readonly)

Returns the value of attribute browser.



263
264
265
# File 'lib/site-object/page.rb', line 263

def browser
  @browser
end

Returns the value of attribute navigation_disabled.



263
264
265
# File 'lib/site-object/page.rb', line 263

def navigation_disabled
  @navigation_disabled
end

#page_elementsObject (readonly)

Returns the value of attribute page_elements.



263
264
265
# File 'lib/site-object/page.rb', line 263

def page_elements
  @page_elements
end

#page_featuresObject (readonly)

Returns the value of attribute page_features.



263
264
265
# File 'lib/site-object/page.rb', line 263

def page_features
  @page_features
end

#page_urlObject (readonly)

Returns the value of attribute page_url.



263
264
265
# File 'lib/site-object/page.rb', line 263

def page_url
  @page_url
end

#required_argumentsObject (readonly)

Returns the value of attribute required_arguments.



263
264
265
# File 'lib/site-object/page.rb', line 263

def required_arguments
  @required_arguments
end

#siteObject (readonly)

Returns the value of attribute site.



263
264
265
# File 'lib/site-object/page.rb', line 263

def site
  @site
end

#url_matcherObject (readonly)

Returns the value of attribute url_matcher.



263
264
265
# File 'lib/site-object/page.rb', line 263

def url_matcher
  @url_matcher
end

#url_templateObject (readonly)

Returns the value of attribute url_template.



263
264
265
# File 'lib/site-object/page.rb', line 263

def url_template
  @url_template
end

Instance Method Details

#expect_page(page) ⇒ Object

Takes the name of a page class. If the current page is of that class then it returns a page object for the page. Raises a SiteObject::WrongPageError if that’s not the case. It’s generally not a good idea to put error checking inside a page object. This should only be used in cases where there is a page transition and that transition is always expected to work.



269
270
271
# File 'lib/site-object/page.rb', line 269

def expect_page(page)
  @site.expect_page(page)
end

#initialize(site, args = {}) ⇒ Object

There’s no need to ever call this directly. Initializes a page object within the context of a site object. Takes a site object and a hash of configuration arguments. The site object will handle all of this for you.



276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
# File 'lib/site-object/page.rb', line 276

def initialize(site, args={})
  @browser = site.browser  
  @navigation_disabled = self.class.navigation_disabled
  @page_url = self.class.page_url
  @page_elements = self.class.page_elements
  @page_features = self.class.page_features
  @required_arguments = self.class.required_arguments
  @site = site
  @url_matcher = self.class.url_matcher 
  @url_template = self.class.url_template    

  # Try to expand the URL template if the URL has parameters. 
  @arguments = {}.with_indifferent_access # Stores the param list that will expand the url_template after examining the arguments used to initialize the page.
  if @required_arguments.length > 0
    @required_arguments.each do |arg| # Try to extract each URL argument from the hash or object provided, OR from the site object.
      if args.is_a?(Hash) && !args.empty?
        if args.with_indifferent_access[arg] #The hash has the required argument.
          @arguments[arg]= args.with_indifferent_access[arg]
        elsif @site.respond_to?(arg)
          @arguments[arg]= site.send(arg)
        else
          raise SiteObject::PageInitError, "#{args.class} was provided, but this object did not respond to :#{arg}, which is necessary to build an URL for the #{self.class.name} page.\n\n#{caller.join("\n")}"
        end
      # elsif args.is_a?(Hash) && args.empty?
      #   raise SiteObject::PageInitError, "An attempt to initialize the #{self.class.name} page object failed because no page arguments were provided. This page object requires the following arguments for initialization: :#{@required_arguments.join(", :")}\n\n#{caller.join("\n")}."
      elsif args # Some non-hash object was provided.
        if args.respond_to?(arg) #The hash has the required argument.
          @arguments[arg]= args.send(arg)
        elsif @site.respond_to?(arg)
          @arguments[arg]= site.send(arg)
        else
          raise SiteObject::PageInitError, "#{args.class} was provided, but this object did not respond to :#{arg}, which is necessary to build an URL for the #{self.class.name} page.\n\n#{caller.join("\n")}"
        end
      else
        # Do nothing here.
      end
    end
  elsif @required_arguments.length >  0 && !args
    raise SiteObject::PageInitError, "No object was provided when attempting to initialize #{self.class.name}. This page object requires the following arguments for initialization: :#{@required_arguments.join(', :')}.\n\n#{caller.join("\n")}"
  elsif @required_arguments.length == 0 && !args
    unless @args.is_a?(Hash) && args.empty?
      raise SiteObject::PageInitError, "#{args.class} was provided as a #{self.class.name} initialization argument, but the page URL doesn't require any arguments.\n\n#{caller.join("\n")}"
    end
  else
    # Do nothing here.
  end
  @url = @url_template.expand(@arguments).to_s

  @page_features ||= []
  @page_features.each do |arg|
    self.class_eval do
      klass = eval("#{arg.to_s.camelize}")
      if klass.alias
        define_method(klass.alias) do
          klass.new(@browser, args)
        end
      else
        define_method(arg) do
          klass.new(@browser, args)
        end
      end
    end
  end
  
  @site.most_recent_page = self
  unless on_page?
    if @navigation_disabled
      if page = @site.page
        raise SiteObject::PageNavigationNotAllowedError, "The #{self.class.name} page could not be accessed. Navigation is intentionally disabled for this page and the browser was displaying the #{@site.page.class.name} page when you tried to access it.\n\nPAGE URL:\n------------\n#{@site.browser.url}\n\n#{caller.join("\n")}"
      else
        raise SiteObject::PageNavigationNotAllowedError, "The #{self.class.name} page could not be accessed. Navigation is intentionally disabled for this page and the page that the browser was displaying could not be recognized.\n\nPAGE URL:\n------------\n#{@site.browser.url}\n\nPAGE TEXT:\n------------\n#{@site.browser.text}\n\n#{caller.join("\n")}"
      end
    end         
    visit         
  end
end

#inspectObject

Custom inspect method so that console output doesn’t get in the way when debugging.



354
355
356
# File 'lib/site-object/page.rb', line 354

def inspect
  "#<#{self.class.name}:#{object_id} @url_template=#{@url_template.inspect}>"
end

#on_page?Boolean

Returns true if the page defined by the page object is currently being displayed in the browser, false if not. It does this in two different ways, which are described below.

A page always has a URL defined for it. This is typically done by using the Page.set_url method to specify a URL when defining the page. You can skip using the set_url method but in that case the page URL defaults to the base URL defined for the site object.

The default approach for determining if the page is being displayed relies on the URL defined for the page. This method first does a general match against the current browser URL page’s URL template. If a match occurs here, and there are no required arguments for the page the method returns true. If the page’s URL template does require arguments the method performs an additional check to verify that each of the arguments defined for the page match what’s in the current browser URL. If all of the arguments match then the method will return true.

This should work for most cases but may not always be enough. For example, there may be a redirect and the URL used to navigate to the page may not be the final page URL. There’s a fallback mechanism for these sorts of situations. You can use the Page.set_url_matcher method to define a regular expression that the method will use in place of the URL template. If the regular expression matches, then the method will return true even if the URL wouldn’t match the URL template.

It’s better to use the default URL matching if possible. But if for some reason it’s not feasible you can use the alternate method to specify how to match the page.

Returns:

  • (Boolean)


380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
# File 'lib/site-object/page.rb', line 380

def on_page?
  url = @browser.url    
  
  if @url_matcher && @url_matcher =~ url
    return true
  elsif @url_template.match(url)
    if @arguments.empty?
      return true
    else
      if page_args = @url_template.extract(Addressable::URI.parse(url))
        page_args = page_args.with_indifferent_access
        return true if @arguments.all? { |k, v| page_args[k] == v.to_s }
      end
    end
  end
  false
end

#refreshObject

Refreshes the page.



399
400
401
402
403
404
405
406
407
408
# File 'lib/site-object/page.rb', line 399

def refresh # TODO: Isolate browser library-specific code so that the adding new browser
  if @browser.is_a?(Watir::Browser) 
    @browser.refresh
  elsif @browser.is_a?(Selenium::WebDriver::Driver)
    @browser.navigate.refresh
  else
    raise SiteObject::BrowserLibraryNotSupportedError, "Only Watir-Webdriver and Selenium Webdriver are currently supported. Class of browser object: #{@browser.class.name}"
  end
  self
end

#visitObject

Navigates to the page that it’s called on. Raises a SiteObject::PageNavigationNotAllowedError when navigation has been disabled for the page. Raises a SiteObject::WrongPageError if the specified page isn’t getting displayed after navigation.



413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
# File 'lib/site-object/page.rb', line 413

def visit
  if @navigation_disabled
    raise SiteObject::PageNavigationNotAllowedError, "Navigation has been disabled for the #{self.class.name} page. This was done when defining the page class and usually means that the page can't be reached directly through a URL and requires some additional work to access."
  end       
  if @browser.is_a?(Watir::Browser)
    @browser.goto(@url)
  elsif @browser.is_a?(Selenium::WebDriver::Driver)
    @browser.get(@url)
  else
    raise SiteObject::BrowserLibraryNotSupportedError, "Only Watir-Webdriver and Selenium Webdriver are currently supported. Class of browser object: #{@browser.class.name}"
  end     
  
  if @url_matcher
    raise SiteObject::WrongPageError, "Navigation check failed after attempting to access the #{self.class.name} page. Current URL #{@browser.url} did not match #{@url_template.pattern}. A URL matcher was also defined for the page and the secondary check against the URL matcher also failed. URL matcher: #{@url_matcher}" unless on_page?
  else
    raise SiteObject::WrongPageError, "Navigation check failed after attempting to access the #{self.class.name} page. Current URL #{@browser.url} did not match #{@url_template.pattern}" unless on_page?
  end

  @site.most_recent_page = self 
  self
end