Search code examples
rubywatirpageobjects

Trying to learn to use PageObjects with Ruby - getting error "uninitialized constant Site (NameError)"


I have some experience of Selenium in Python and Cucumber/Watir/RSpec in Ruby, and can write scripts that execute successfully, but they aren't using classes, so I am trying to learn more about classes and splitting the scripts up in to pageobejcts.

I found this example to learn from: http://watir.com/guides/page-objects/ so copied the script and made some minor edits as you'll see below.

I'm using SublimeText 3.x with Ruby 2.4.x on Win10, so you know what tools I'm using.

I put the whole script in to a single .rb file (the only differences are that I replaced the URL and the elements to enter the username and password) and tried to execute it and get the following error:

C:/selenium/ruby/lotw/lotwlogin.rb:3:in `<main>': uninitialized constant Site (NameError).

I added the top line (required 'watir') line and it made no difference to the error encountered.

So I have in lotwlogin.rb essentilly the structure and syntax of the original script with custom elements. However, the core structure is reporting an error and I don't know what to do about it.

Here is my script:

require 'watir'

site = Site.new(Watir::Browser.new :chrome) # was :firefox but that no longer works since FF63

login_page = site.login_page.open 
user_page = login_page.login_as "testuser", "testpassword" # dummy user and password for now

user_page.should be_logged_in

class BrowserContainer   
  def initialize(browser)
    @browser = browser   
  end 
end

class Site < BrowserContainer   
  def login_page
    @login_page = LoginPage.new(@browser)
  end

  def user_page
    @user_page = UserPage.new(@browser)
  end

  def close
    @browser.close
  end
end


class LoginPage < BrowserContainer
  URL = "https://lotw.arrl.org/lotw/login"

  def open
    @browser.goto URL
    #@browser.window.maximize
    self   # no idea what this is for
  end

  def login_as(user, pass)
    user_field.set user
    password_field.set pass

    login_button.click

    next_page = UserPage.new(@browser)
    Watir::Wait.until { next_page.loaded? }

    next_page
  end

  private

  def user_field
    @browser.text_field(:name => "login")
  end

  def password_field
    @browser.text_field(:name => "password")
  end

  def login_button
    @browser.button(:value => "Log On")   
  end
end # LoginPage

class UserPage < BrowserContainer   
  def logged_in?
    logged_in_element.exists?   
  end

  def loaded?
    @browser.h3 == "Welcome to Your Logbook of the World User Account Home Page"   
  end

  private

  def logged_in_element
    @browser.div(:text => "Log off")   
  end 
end # UserPage

Any assistance how to not get the Site error would be appreciated.

Thanks

Mike


Solution

  • You define class Site only a few lines below. But at that point, it's not yet known.

    Move this logic to after all class definitions:

    site = Site.new(Watir::Browser.new :chrome) # was :firefox but that no longer works since FF63
    
    login_page = site.login_page.open 
    user_page = login_page.login_as "testuser", "testpassword" # dummy user and password for now
    
    user_page.should be_logged_in