Need to login before going to a new page - ruby

I'm currently using Ruby and Capybara and writing tests. I have a login page already done and it works fine. I'm trying to create a separate test where I want it to already login before going to that page.
My login Code:
class LoginPage < SitePrism::Page
set_url '/'
element :username_field, '#username'
element :password_field, '#password'
element :login_button, '#login_button'
def login()
username_field.send_keys 'Cow'
password_field.send_keys 'dogs'
login_button.click
end
def load_and_login(*args)
self.load
login(*args)
self
end
end
This is my new page. Where I want it to login prior to going to this page.
describe login do
before(:each) do
home = LoginPage.new
home.load
home.login
end
end
class newPage < SitePrism::Page
include RSpec::Matchers
include Capybara::RSpecMatchers
set_url '/new'
end
This is the error that I"m getting:
Failure/Error: Dir['./pages/**/*.rb'].sort.each { |f| require f }
NameError:
undefined local variable or method `login' for main:Object

describe login do -- looks like problem here
Change it to describe '#login' do

Related

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
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

Sinatra App - Separating Concerns

Probably something really basic, but I want to be able to separate my Sinatra routes from controllers. I have this code in my routes.rb:
require 'sinatra/base'
class Server < Sinatra::Base
get '/' do
Action.index
end
end
This is my controller/server.rb
class Action
def sef.index
#user = User.new("Abiodun Shuaib")
haml: index
end
end
It gives the error undefined method 'haml' in Action:Class.
How can I fix this?
You are trying to access method haml in class Action. It simply doesn't contain it.
For example, you can do:
class Server
def index
#user = User.new("Abiodun Shuaib")
haml :index
end
end
By doing this, you will add to Server method index.
Or you can do in such way(it's called Mixin):
module ActionNew
def index
#user = User.new("Abiodun Shuaib")
haml :index
end
end
class Server < Sinatra::Base
include ActionNew
get '/' do
index
end
end

Watir / MiniTest - Undefined local variable or method 'browser'

I have 66 watir scripts that I have been creating over the past week to automate testing on the clients website.
However I have recently found out about a test framework called MiniTest which I am trying to implement now.
The reason I have set the URL as a variable is because there are 5 different sites that these tests need to run on so when they want me to run my pack on a different website I just need to update that 1 variable and not in each individual test.
require 'minitest/autorun'
require "watir-webdriver"
class MPTEST < MiniTest::Unit::TestCase
def setup()
url = "http://thewebsite.com/"
$browser = Watir::Browser.new :chrome
$browser.goto url
end
def test_myTestCase
$browser.link(:text, "Submit your CV").click
sleep(2)
$browser.button(:value,"Submit").click
assert($browser.label.text.includes?("This field is required"))
def teardown
$browser.close
end
end
When running that I receive the following output:
NameError: undefined local variable or method 'browser' for #<MPTEST:0x4cc72f8>c:/directory stuff...
Any ideas?
EDIT I have browser working however now there is an issue with my assert:
New code:
require 'minitest/autorun'
require "watir-webdriver"
class MPTEST < MiniTest::Unit::TestCase
def setup()
url ="http://thewebsite.com"
$browser = Watir::Browser.new :chrome
$browser.goto url
end
def test_myTestCase
$browser.link(:text, "Submit your CV").click
sleep(2)
$browser.button(:value,"Submit").click
assert($browser.label.text.includes?("This field is required"))
end
def teardown
$browser.close
end
end
And the error is:
NoMEthodError: undefined method 'includes?' for "":String
it seems to me you can you use #browser instead of $browser (but the problem might be not in this code)
The exception
NoMEthodError: undefined method 'includes?' for "":String
Is due to strings, in this case the value returned by $browser.label.text do not have an includes? method.
The method you actually want is include? (no plural):
assert($browser.label.text.include?("This field is required"))

Accessing to JS-widget from module

I try to access to custom JS-widget from my module.
Base page class just include PageObject, DataMagic and RSpec::Matchers.
My class
require_all 'lib/pages/billing/billing_form_panel.rb'
class RealtyCpBillingPage < BasePage
include BillingFormPanel
end
Module
require_all 'lib/widgets/jquery_datepicker.rb'
module BillingFormPanel
include PageObject
button :show_datepicker, class: 'ui-datepicker-trigger'
jquery_datepicker :datepicker, id: 'ui-datepicker-div'
def datepicker
datepicker_element
end
def select_packet data
if data['date']
show_datepicker
data['date'] = data['date'].split(' ').reverse
datepicker.year = data['date'][0]
datepicker.month = data['date'][1]
end
end
end
JQuery UI datepicker widget
class JQueryDatepicker < PageObject::Elements::Div
include PageObject
PageObject.register_widget :jquery_datepicker, JQueryDatepicker, :div
def month month
select_list_element(class: 'ui-datepicker-month').select month
end
def year year
select_list_element(class: 'ui-datepicker-year').select year
end
end
And steps:
Если(/^если выбираю тариф:$/) do |table|
on(RealtyCpBillingPage).select_packet table.hashes.first
end
When run this test, I see the following error:
Unable to pick a platform for the provided browser (RuntimeError)
./lib/pages/billing/billing_form_panel.rb:22:in `datepicker'
./lib/pages/billing/billing_form_panel.rb:34:in `select_packet'
So, How can I access to that Widget from my Module?
UPD: Browser start here hooks.rb.
Before do
#browser = Watir::Browser.new :firefox
#browser.driver.manage.timeouts.implicit_wait = 8
end
After do
#browser.close
end
There is no need to include PageObject in widget class.
The full answer is here
https://github.com/cheezy/page-object/issues/173

Access Sinatra settings from a model

I have a modular Sinatra app. I'm setting some custom variables in my configure block and want to access these settings in my model.
The problem is, I get a NoMethodError when I try and access my custom settings from MyModel. Standard settings still seem to work fine though. How can I make this work?
# app.rb
require_relative 'models/document'
class App < Sinatra::Base
configure do
set :resource_path, '/xfiles/i_want_to_believe'
end
get '/' do
#model = MyModel.new
haml :index
end
end
# models/my_model.rb
class MyModel
def initialize
do_it
end
def do_it
...
settings.resource_path # no method error
...
settings.root # works fine
end
end
i think that you should be able to access it via
Sinatra::Application.settings.documents_path
I ended up doing:
#document.rb
class Document
def self.documents_path=(path)
#documents_path = path
end
def self.documents_path
#documents_path
end
...
end
#app.rb
configure do
set :documents_path, settings.root + "/../documents/"
Document.documents_path = settings.documents_path
end
then just using Document.documents_path inside my find method.

Resources