Search code examples
watirpage-object-gem

Passing parameter via PageFactory


I'm using page-object gem with watir and RSpec to test my web application. Here is my page object.

require 'page-object'

class UserEditPage
  include PageObject
  page_url "#{$context}/user/edit?id=#{@params[:id]}"

  text_field :user_id, name: 'userName'

  text_field :pw, name: 'password'
  text_field :pw_retype, name: 'password2'

  # snip uninteresting stuff

  button :submit, index: 0
end

I would like to parameterize :id in page_url via PageObject::PageFactory like this:

visit UserEditPage, using_params: {id: 1000} do |page|
# operation on page
end

This document implies that above usage is possible, but I couldn't understand how exactly this is achieved.

Question: how can I pass parameter id from visit method to UserEditPage?

Running code results in

       ***/user/edit_page.rb:8:in `<class:UserEditPage>': undefined method `[]' for nil:NilClass (NoMethodError)
        from ***/user/edit_page.rb:5:in `<top (required)>'

probably because @params is nil when evaluating page_url. Changing using_params: {id: 1000} to id: 1000 with no luck.


Solution

  • The page_url needs to be:

    page_url "#{$context}/user/edit?id=<%=params[:id]%>"
    

    Note how the parameters need to be included differently - ie <%=params[:id]%> instead of #{params[:id]}.

    The problem is that the page_url is evaluated when the page object class is evaluated. This means that when the class is evaluated, params[:id] must already exist. This is not going to be true when you want to include the parameters dynamically.

    The page object gem uses ERB to allow you to create a template, which allows substitution of the params later - ie when calling visit.

    In summary, when creating a page_url:

    1. Use string interpolation if the value is known when the page object class is evaluated.
    2. Use ERB if the value is to be dynamically specified on visit.

    Working Example

    Below is a working example of the dynamic parameters.

    require 'watir-webdriver'
    require 'page-object'
    
    $context = 'http://testurl.com'
    
    class UserEditPage
      include PageObject
    
      page_url "#{$context}/user/edit?id=<%=params[:id]%>"
    end
    
    include PageObject::PageFactory   
    @browser = Watir::Browser.new
    
    visit UserEditPage, using_params: {id: 1000} do |page|
      p page.current_url
      #=> "http://testurl.com/user/edit?id=1000"
    end