uninitialized constant SitePrism from page declariation - ruby

I'm trying to set up a basic framework using Capybara, Cucumber and SitePrism, but I keep getting the error, "uninitialized constant SitePrism (NameError)" when I kick off a test.
Gemfile:
gem 'cucumber', '2.3.3'
gem 'capybara', '2.6.2'
gem 'selenium-webdriver', '2.53.0'
gem 'rspec'
gem 'site_prism'
gem 'mime-types', '>2.6', '<2.99.1'
Env.rb
require 'capybara'
require 'capybara/rspec'
require 'capybara/dsl'
require 'capybara/cucumber'
require 'selenium-webdriver'
require 'site_prism'
require 'cucumber'
require_rel '../features/pages'
require_rel '../features/classes'
World(Capybara::DSL)
World(Capybara::RSpecMatchers)
Login page
class LoginPage < SitePrism::Page
end
Login class
class Login
def initialize
#current_page = LoginPage.new
end
The error is being thrown on the line with "class LoginPage < SitePrism::Page". RubyMine can't find the SitePrism declaration to go to either. Am I missing something in the setup?

Your error looks 'require' related, but here is how I got it to work via:
https://github.com/thuss/standalone-cucumber
Haven't used cucumber in a while, but the way I see "pages" currently implemented in my Rails project:
Create a file in "features/support/pages"
Follow the namespace conventions
Use modules, then import via the World() method.
Maybe this might work:
features/support/pages/login_page.rb
module Pages
module LoginPage
class LoginPageObj < SitePrism::Page
end
def login_obj
LoginPageObj.new
end
end
end
World(Pages::LoginPage)
Env file:
require 'capybara'
require 'capybara/cucumber'
require 'site_prism'
Capybara.configure do |config|
config.default_driver = :selenium
config.app_host = 'http://www.google.com'
end
World(Capybara::DSL)
World(Capybara::RSpecMatchers)
Notice how I didn't have to explicitly require any pages class, it looks like Cucumber might require it for you?
Note this is without RubyMine (I dont use it). If it works without RubyMine, I'd point fingers to that.

So the reason you were getting this problem is because of the files being auto-loaded. Just ensure you require the gem files first so the namespaces are understood

Related

Ruby gem dependency loading

I'm putting some shared models for a rails app inside it's own gem. It's just models, so I'm not using an engine. Getting it set up seemed to work fine until I added the "acts_as_list" gem.
# gem - domain.gemspec
spec.add_dependency "acts_as_list"
# gem - lib/domain.rb
require "acts_as_list"
# gem - lib/domain/models/page.rb
acts_as_list scope: [:ancestry]
This works fine in the console for my gem, I can run methods specific to acts_as_list as usual. However, when I add my gem to another project, it gives me an error.
# project - Gemfile
gem "www_domain", path: "../www_domain"
Bundler::GemRequireError: There was an error while trying to load the gem 'domain'.
NoMethodError: undefined method `acts_as_list' for #<Class:0x0055da70121ab0>
/home/shaun/sites/demo/domain/lib/domain/models/page.rb:32:in `<class:Page>'
Is there something special I have to do in this case to access the acts_as_list method because my model is inside a gem?
Update: Here is my complete lib/domain.rb file for the gem:
require "yaml"
require "active_record"
require "acts_as_list"
require "ancestry"
# rbfiles = File.join(File.dirname(__FILE__), "lib", "**", "*.rb")
# Dir.glob(rbfiles).each do |file|
# require file.gsub("lib/", "")
# end
module Domain
# Your code goes here...
def self.root
File.dirname(__dir__)
end
def self.db_config
YAML.load_file("#{Domain.root}/db/config.yml")["development"]
end
end
require "domain/version"
require "domain/models/page"
require "domain/models/menu"
require "domain/models/article"
require "domain/models/page_part"
I can use acts_as_list and ancestry methods in the console of my gem (running bin/console from the gem directory). But the project console (running bundle exec rails console from the project directory) will not start because of the gem error I mentioned.
This might result from a load order issue if the model being required before the require :acts_as_list statement. Check to see if the gem specifies the load order. If not, you could try something like:
# gem - lib/domain.rb
require "acts_as_list"
require "models/page"
If the load order is unclear, I find it helpful to simply add a
puts __FILE__
at the top of the relevant source files.

"require if" in Ruby

Here is what I have in my rack app
#rb file
require 'pry'
class .....
#GemFile
group :development do
gem "pry"
gem "pry-nav"
end
Of course, in production it causes an error. How do make a kind of "require if"?
require 'pry' if ENV['RACK_ENV'] == 'development'
May be you can embed it inside a if block
according to docs Sinatra provides a environment variable
http://www.sinatrarb.com/intro#Environments
if development?
require 'pry'
end
wherever you need to use it.
this may not be the exact solution you may be looking for just a wild guess
I suggest to write such method in Object or Kernel in your app:
def require_pry
require 'pry' if ENV['RACK_ENV'] == 'development'
end
After that you can call require_pry if you need it in your code. But I have doubts why it cannot be handled by Bundler, Bundle.require will require all gems needed for environment.

Capybara/Selenium - NS_ERROR_MALFORMED_URI for app on http://localhost

I'm trying to set up RSpec, Capybara & Selenium to test a PHP application running on the traditional localhost:80. Whenever I run the suite, Selenium fails and complains about a malformed URI.
Here's my spec_helper.rb.
require 'bundler/setup'
require 'rspec'
require 'capybara/rspec'
Capybara.server_port = 80
Capybara.app_host = 'http://localhost'
Capybara.run_server = false
Capybara.default_driver = :selenium
And here's my only spec:
require File.dirname(__FILE__) + '/../spec_helper'
describe "visting the website", :type => :request do
it "should display an html page" do
visit ( '/' )
page.should have_selector( 'html' )
end
end
But it bails. What am I missing?
Failures:
1) visting the website should display an html page
Failure/Error: visit ( '/' )
Selenium::WebDriver::Error::UnknownError:
Component returned failure code: 0x804b000a (NS_ERROR_MALFORMED_URI) [nsIIOService.newURI]
# ./spec/requests/sign_in_spec.rb:6:in `block (2 levels) in <top (required)>'
My URI doesn't look malformed to me... visit works if I pass in 'http://localhost' but that's not ideal.
Here's my Gemfile for good measure
gem 'rspec'
gem 'capybara', :git => 'https://github.com/jnicklas/capybara.git'
gem 'launchy'
gem 'ruby-debug19'
Thanks for any help.
#andrykonchin was right - switching back to stable worked
You need install bundler if it is not install
gem install bundler
Then you need to create a file called gemfile in the root directory (For my simple example I am using just capybara and no rspec)
source "http://rubygems.org"
gem "capybara" , "1.1.3"
Create a basic ruby file as follows
require 'bundler/setup'
require 'capybara/dsl'
Capybara.server_port = 80
Capybara.app_host = 'http://google.com'
Capybara.run_server = false
Capybara.default_driver = :selenium
class Browser
include Capybara::DSL
end
w = Browser.new
w.visit("/")
Use the command
bundle install
Now you will be using the stable version of Capybara
For more information on bundler look at http://gembundler.com/

undefined method `have_content' using Cucumber / Capybara / sinatra

I'm trying to validate the start of an initial page for a Sinatra application but am struggling to get the testing framework working. Googling around suggests I add cucumber/rails/rspec or similar, but do I really need to add rails related libraries when not using Rails?
Here's my Gemfile
source :rubygems
gem 'sinatra', '1.3.1'
gem 'json', '1.6.3'
group :test do
gem 'rspec', '2.7.0'
gem 'cucumber', '1.1.3'
gem 'capybara', '1.1.2'
gem 'rack-test', '0.6.1'
end
and my steps:
Given /^a room needs to be surveyed$/ do
end
When /^I start a survey$/ do
survey_tool.start_a_survey
end
Then /^the system will prompt me for a survey summary$/ do
survey_tool.validate_start_a_survey_page
end
and my world extensions
module KnowsTheUserInterface
class UserInterface
include Capybara::DSL
def start_a_survey()
visit '/start_a_survey'
end
def validate_start_a_survey_page ()
page.should have_content('Welcome')
end
end
def survey_tool
#survey_tool ||=UserInterface.new
end
end
World(KnowsTheUserInterface)
and my env
require File.join(File.dirname(__FILE__), '..', '..', 'lib', 'survey_tool')
require 'capybara/cucumber'
require 'capybara/rspec'
Capybara.app = Sinatra::Application
Sinatra::Application.set :environment, :test
The error I receive is
Scenario: Start a survey # features/start_a_survey.feature:4
Given a room needs to be surveyed # features/step_definitions/start_a_survey_steps.rb:1
When I start a survey # features/step_definitions/start_a_survey_steps.rb:5
Then the system will prompt me for a survey summary # features/step_definitions/start_a_survey_steps.rb:9
undefined method have_content' for #<KnowsTheUserInterface::UserInterface:0x007f910465fc38> (NoMethodError)
./features/support/world_extensions.rb:10:invalidate_start_a_survey_page'
./features/step_definitions/start_a_survey_steps.rb:10:in /^the system will prompt me for a survey summary$/'
features/start_a_survey.feature:7:inThen the system will prompt me for a survey summary'
I think the problem here is that you do not have the rspec expectations included. A Capybara node has a has_content? method.
It is the rspec expectation that, when given 'have_content' as an argument, calls 'has_content?' on the target.
So try adding 'rspec-expectations' to your Gemfile, and adding require 'rspec/expectations' into your module.

How to use Capybara in pure Ruby (without Rails)?

I'm trying to get Capybara running in a simple Ruby script -- i.e. without/outside of Rails. Here's the script:
require 'rubygems'
require 'capybara'
require 'capybara/dsl'
include Capybara
Capybara.current_driver = :selenium
Capybara.app_host = 'http://www.google.com'
visit('/')
The problem is that when I run this I get this error:
NameError: uninitialized constant Capybara::Session
at top level in dsl.rb at line 52
method gem_original_require in custom_require.rb at line 36
method require in custom_require.rb at line 36
at top level in capybara_test.rb at line 3
method gem_original_require in custom_require.rb at line 31
method require in custom_require.rb at line 31
at top level in capybara_test.rb at line
What am I doing wrong?
Some more info:
Mac OS X 10.5
ruby 1.8.6 (2009-06-08 patchlevel 369) [universal-darwin9.0]
capybara (0.3.9)
Thanks!
Neal
Note: Per the comment from jnicklas I tried this, which matches the new README more closely:
require 'rubygems'
require 'capybara'
require 'capybara/dsl'
Capybara.default_driver = :selenium
Capybara.app_host = 'http://www.google.com'
module MyCapybaraTest
include Capybara
def test_google
visit('/')
end
end
Unfortunately, I'm still seeing the same error:
NameError: uninitialized constant Capybara::Session
Thoughts?
Thanks!
Here's something that seems to work for me:
require 'rubygems'
require 'capybara'
require 'capybara/dsl'
Capybara.run_server = false
Capybara.current_driver = :selenium
Capybara.app_host = 'http://www.google.com'
module MyCapybaraTest
class Test
include Capybara::DSL
def test_google
visit('/')
end
end
end
t = MyCapybaraTest::Test.new
t.test_google
It goes to show that even incorrect documentation lives forever. The Capybara README used to recommend to include Capybara in the global namespace, this is a really bad idea, and messes up any number of random things. You should include Capybara in your own module or class and use that instead.
Check out the README for current best practices.
Please check this CapybaraRspec101 example and fork it.
It's a small example for acceptance tests on http://www.hi5.com using from scratch:
Capybara
Rspec
Selenium-webdriver
All instructions are in the repo

Resources