Unable to get Ruby Page-Object gives error "undefined method" - selenium

I am new to using PageObject::PageFactory.
I can’t get this simple scenario to work. Can someone Help me with this?
My Feature file
Feature: Find Pens
Scenario:
Given a user goes to Amazon website
When they search for “pens”
Then they are able to find “pens”
My Step_definition
Given(/^a user goes to Amazon website$/) do
visit HomePage
end
When(/^they search for “(.*?)”$/) do |page|
on HomePage do
page.look_pens
end
end
Then(/^they are able to find “(.*?)”$/) do |arg1|
pending # express the regexp above with the code you wish you had
end
Page Object file
QUESTION: Is it right to put this file in Support folder or should this be living elsewhere?
class HomePage
include PageObject
page_url(‘http://www.amazon.co.uk’)
text_field(:name, :id=> ‘twotabsearchtextbox’) #:id is the web-element from the actual webpage. Should this be something else?
button(:search, :value=>’Go’)
def look_pens(name,search)
self.name = pens
self.search
end
end
The Given part when run with Cucumber-SeleniumWebdriver does open the Amazon browser, but after that gives the following error for the When part
The Error
p.rb:1
When they search for “pens” # features/step_definitions/buy_pens_ste
p.rb:5
undefined method `look_pens’ for “pens”:String (NoMethodError)
./features/step_definitions/buy_pens_step.rb:7:in `block (2 levels) in ‘
./features/step_definitions/buy_pens_step.rb:6:in `/^they search for “(.*?
)”$/’
features\buy_pens.feature:5:in `When they search for “pens”‘
My env.rb in the support folder contains:
require ‘page-object’
require ‘selenium-webdriver’
require ‘page-object/page_factory’
Before do
#browser = Selenium::WebDriver.for(:firefox)
end
After do
#browser.close
end
World(PageObject::PageFactory)

Typically page object files are maintained in a separate folder that is at the same level as the features directory. You will need to use additional require statements so that Ruby knows that they are located in that folder.
Re the error: Looks like the compiler is having difficulty recognizing that look_pens is a method of the HomePage class. Try moving the |page| from the end of the When step def to the second line, so that it looks like code below.
When(/^they search for “(.*?)”$/) do
on HomePage do |page|
page.look_pens
end
end

Related

populate_page_with method gives an error "Undefined method send_keys" when used with selenium web-driver

I am using page object gem with selenium web-driver. I am trying to automate gmail sign in page. So to enter mail_id and password I am using populate_page_with method.
I am storing my login credentials in a variable "data"
data = { :mail_id => 'abc#abc.com', :mail_password=> '12345' }
And calling populate_page_with method like below
populate_page_with data
When I am trying run the script it gives an error Undefined method send_keys.
But the implementation working fine when I am trying to automate yahoo mail sign in page.
My page object class is
class GmailSignInPage
include PageObject
button :gsubmit, :id => 'signIn'
text_field :mail_id, :id => 'Email'
text_field :mail_password, :id => 'Passwd'
def log_in_to_gmail(data = {})
self.mail_password_element.when_visible
populate_page_with data
self.gsubmit
end
end
My step-definition is
Given /^I navigate to gmail page$/ do
data = { :mail_id => 'abc#abc.com', :mail_password=> '12345' }
on(GmailSignInPage).log_in_to_gmail data
end
In supports/env.rb, I have added PageFactory class also
World(PageObject::PageFactory)
If I modify my log_in_to_gmail method like below then also I am getting same exception
undefined method 'send_keys' for #<NoMethodError: undefined method 'current' for Time:Class> (NoMethodError)
def log_in_to_gmail(data = {})
self.mail_password = data['mail_id']
self.mail_password = data['mail_password']
self.gsubmit
end
But if I use send_keys method its working fine except warning message
def log_in_to_gmail(data = {})
mail_id_element.send_keys data['mail_id']
mail_password_element.send_keys data['mail_password']
self.gsubmit
end
And the warning message is
*** DEPRECATION WARNING
*** You are calling a method named bridge at C:/jruby-1.7.6/lib/ruby/gems/shared/gems/page-object-0.9.2/lib/page-object/elements/element.rb:27:in 'wait_for_document_ready'.
*** This method does not exist in page-object so it is being passed to the driver.
*** This feature will be removed in the near future.
*** Please change your code to call the correct page-object method.
*** If you are using functionality that does not exist in page-object please request it be added.
So I think, this is not the issue with populate_page_with method because even assignment operator = gives same exception. This may be due to page_object gem unable handle gmail sign-in page.
Ok, lets try this again.
I have created a test and copy pasted all of the sample code you have above (Using the populate_page_with() method). I did make one key change to my code compared to yours:
Yours
on(GmailSignInPage).log_in_to_gmail data
Mine
GmailSignInPage.new(#browser).log_in_to_gmail data
I don't know what gem the on() method from your code is from. I could guess, but I want to make this answer more fact based that my previous one. :)
Once I did this, I was able to successfully sign in to Google. So there is nothing unusual about the Google sign in page or any limitation I can come across in the page-object gem or anything wrong with your approach.
So the only things that are different between us is the one line of code I put above, our dev environments, other dependent gems each of us are using.
Try replacing the above line and see if that works.
If not, I would recommend seeing if you have a gem conflict of some sort. Reason I suspect this is due to the strange exception methods you are getting:
undefined method 'send_keys' for # (NoMethodError)
The send_keys part I get, but 'current'? No 'current' method is being called and the Time class is no where to be seen in this example. That's one issue to look at isolating and seeing if you can clean up.

Rails 3 and AWS::S3 Ruby Gem

I am following the documentation (http://amazon.rubyforge.org/) to try to begin working on S3 into my application (for serving files to the end user) but I keep running into errors.
Here is my Model:
class File < AWS::S3::S3Object
set_current_bucket_to 'test-bucket'
end
This is what I am trying via the Rails Console:
File.find 'test.pdf'
But I keep getting this error:
undefined method `find' for File:Class
Not sure what I am doing wrong here... anyone else run into this issue?
File is not a very good name for your model as it gets overwrited by Ruby's standart class File (docs). Just choose another name and everything will just work!

undefined method 'path' for nil:NilClass using chargify_api_ares gem

I feel like this should be a simple problem, but I'm pulling my hair out trying to track it down. I'm installed the chargify_api_ares gem, but can't do even basic things such as
Chargify::Subscription.create
As I get this path error. I feel like this must be a gem issue somehow but don't know where to go from here.
UPDATE: bundle show chargify_api_ares shows the correct path, I just somehow can't access it. Still trying random environment related things.
Looks like this is the source of the problem, in active_resource\base.rb:
# Gets the \prefix for a resource's nested URL (e.g., <tt>prefix/collectionname/1.json</tt>)
# This method is regenerated at runtime based on what the \prefix is set to.
def prefix(options={})
default = site.path
default << '/' unless default[-1..-1] == '/'
# generate the actual method based on the current site path
self.prefix = default
prefix(options)
end
As I understand it, Chargify.subdomain should be setting the site.path, but I don't understand activeresource well enough yet to know what's happening and will continue to dig.
I too had the same issue.
I executed the following on the console
Chargify.configure do |c|
c.api_key = "<<api_key>>"
c.subdomain = "<<subdomain>>"
end
After that performing any Chargify console commands went through fine.

Extend a module in Rails 3

I want to define a function available_translations which lists the translations I have made for my application into the I18n module.
I tried putting the following into the file lib/i18n.rb, but it doesn't work when I try to use it from the rails console:
module I18n
# Return the translations available for this application.
def self.available_translations
languages = []
Dir.glob(Rails.root.to_s + '/config/locales/*.yml') do |filename|
if md = filename.match #^.+/(\w+).yml$#
languages << md[1]
end
end
languages
end
end
Console:
ruby-1.9.2-p290 :003 > require Rails.root.to_s + '/lib/i18n.rb'
=> false
ruby-1.9.2-p290 :004 > I18n.available_translations
NoMethodError: undefined method `available_translations' for I18n:Module
...
Besides solving my concrete problem, I would be very pleased to learn how this whole module thing in Ruby on Rails works because it still confuses me, so I would appreciate links to the docs or source code very much.
Either of these will solve your problem:
move the code to config/initializers/i18n.rb, or
require your file from config/application.rb, or
name your class otherwise (to trigger autoload)
The code in lib/i18n.rb wil not be loaded by autoload since I18n name will be already loaded, so either you load it yourself or change the class name (and file name) so the new name will trigger autoload behavior.
BTW, the I18n.available_locales() method is presented in rails.

Rails 3 Carrierwave-Fog-S3 error: Expected(200) <=> Actual(404 Not Found)

I'm using Carrerwave 0.5.3 and getting a 404 error on my call to Picture.save in the Create method of my picture controller. Per the instructions in lib/carrierwave/storage/s3.rb I have the following in my initialization file (config/initializers/carrierwave_fog.rb):
CarrierWave.configure do |config|
config.s3_access_key_id = "xxxxx"
config.s3_secret_access_key = "xxxxx"
config.s3_bucket = "mybucket" #already created in my S3 account
end
In photo_uploader.rb I have:
class PhotoUploader < CarrierWave::Uploader::Base
include CarrierWave::RMagick
storage :s3
def store_dir
"uploads" # already created in my s3 account
end
def cache_dir
"uploads/cache" #already created in my s3 account
end
end
The exact error:
Excon::Errors::NotFound in PicturesController#create
Expected(200) <=> Actual(404 Not Found)
request => {:expects=>200}
response => #<Excon::Response:0x00000104a72448 #body="", #headers={}, #status=404>
I found a slightly similar question here Carrierwave and s3 with heroku error undefined method `fog_credentials=' . But setting things up the way I have it now apparently worked in that case. Unfortunately it didn't for me.
I've put a picture in my bucket and set the permissions to public and can access the picture via a browser. So things on the AWS S3 side seem to be working.
Not sure where to go next. Any ideas?
Well, I slept on this for a night came back the next day and all was good. Not sure why it suddenly started working.
Make sure your file names are sanitized and do not contain invalid characters like spaces or slashes.
To sanitize a string you can call the gsub method on it. The following method call will sanitize files for upload to S3, Google Cloud Storage etc.
"Invalid\ file *& | | name.png".gsub(/[^0-9A-z.\-]/, '_')