Watir from Ruby on Rails controller - ruby-on-rails

I have the requirement to run a Watir test code from the Ruby on Rails framework. My ruby on rails hello world works perfectly and so does my Watir test (when i run from the irb and when run as an individial ruby script ) , but my requirement is to call the watir code from within the rails controller, which is giving a cannot Load Watir error.
This requirement is very urgent, and i can't figure out what the error is.
Note: The rails application is run on the netbeans 6.9 IDE and uses the native ruby interpreter in the system (not the default jruby)
I have the following versions:
ruby : 1.9.3
watir : 3.0.0
Rails : 3.2.8
LoadError (cannot load such file -- Watir):
app/controllers/watir_controller.rb:4:in `<class:WatirController>'
app/controllers/watir_controller.rb:1:in `<top (required)>'
This is my controller class which calls the watir script:
class WatirController < ApplicationController
## the Watir controller
require 'rubygems'
require 'watir'
# set a variable
test_site = "http://www.google.com"
# open the IE browser
ie = Watir::IE.new
# print some comments
puts "Beginning of test: Google search."
puts " Step 1: go to the test site: " + test_site
ie.goto test_site
puts " Step 2: enter 'pickaxe' in the search text field."
ie.text_field(:name, "q").set "pickaxe" # "q" is the name of the search field
#puts " Step 3: click the 'Google Search' button."
ie.button(:name, "btnG").click # "btnG" is the name of the Search button
puts " Expected Result:"
puts " A Google page with results should be shown. 'Programming Ruby' should be high on the list."
puts " Actual Result:"
if ie.text.include? "Programming Ruby"
puts " Test Passed. Found the test string: 'Programming Ruby'. Actual Results match Expected Results."
else
puts " Test Failed! Could not find: 'Programming Ruby'."
end
puts "End of test: Google search."
end

I don't understand as to why you need to use Watir inside of your Rails controller?
Watir is for browser automation to test things out which means that you should put it into your test/spec directory and put watir to the Gemfile into development and test group like this:
group :development, :test do
gem "watir"
end
Since you're using Rails and you probably would test the application written in Rails then i'd also recommend to use watir-rails. Also, if you're using RSpec, use watir-rspec. This means that your Gemfile should look like this:
group :development, :test do
gem "watir-rails"
gem "watir-rspec"
end

You have to include it in your gem file.
Gemfile
gem 'watir'
controller
class MyApp::WebCrawlerController
require "watir"
require "nokogiri"
def index
browser = Watir::Browser.new
browser.goto 'http://www.google.com'
doc = Nokogiri::HTML.parse(browser.html)
end
end

Related

How to load a Ruby gem into a module

I am trying to write a web scraper using Watir that can be run on a schedule.
My module is called PriceScraperModule but it is not loading. I get this error:
NameError (uninitialized constant PriceScraperModule::Watir)
My module looks like:
module PriceScraperModule
def self.scrape
browser = Watir::Browser.new
end
end
My Gemfile includes:
gem 'watir'
gem 'webdrivers'
When I try requiring it, it doesn't work either:
module PriceScraperModule
require 'watir'
def self.scrape
browser = Watir::Browser.new
end
end
I get this error:
LoadError (cannot load such file -- watir)
What should I do?
I have written the following code and it's working properly.
require 'watir'
module PriceScraperModule
def self.scrape
b = Watir::Browser.new
b.goto 'www.google.com'
end
end
PriceScraperModule.scrape
Fixed it. In your terminal, run
$ spring stop
I was just checking as I did comment with perspective of Rails but you are not using rails so in case if you want to use it as a individual ruby project with bundler following will work.
Gemfile
# frozen_string_literal: true
source 'https://rubygems.org'
git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
gem 'watir'
gem 'webdrivers'
your module price_scraper_module.rb file
module PriceScraperModule
require 'watir'
def self.scrape
browser = Watir::Browser.new
browser.goto 'www.google.com'
end
end
and now any file where you want to use I am using sample.rb
#!/usr/bin/ruby
$LOAD_PATH << '.'
require 'price_scraper_module'
include PriceScraperModule
PriceScraperModule.scrape
Now just run following commands to get all Gems
bundle
and to run the sample
ruby sample
Although your one file is perfectly working, in case you want to make it part of an individual project with Gemfile.

Run tests in custom test folder in Rails 5

When I want to run all model tests we do
rails test:models
If I similarly would like to run tests that sits in a folder called service_objects (in the test folder) - what would be the required steps?
With inspiration from multiple, sources I have tried the following in lib/tasks:
namespace :test do
Rails::TestTask.new(classes: 'test:prepare') do |t|
t.pattern = 'test/service_objects/**/*_test.rb'
end
end
But running rails test:service_objects returns this error message:
NameError: uninitialized constant Rails::TestTask
Replace Rails::TestTask with Rails::TestUnit::Runner as shown in the file below, with the require path indicated at the top.
Then to run ONLY the tests in test/focused directory, you can call
rails test:focused
and to run ALL tests in the test directory EXCEPT those in test/long_running, you can call
rails test:without_long_running
Tested with Rails 5.1.6
The new Rails 5 test runner does have some really helpful features, but sometimes you still need a little more control.
# lib/tasks/test_tasks.rake
require "rails/test_unit/runner"
namespace :test do
task :focused => "test:prepare" do
$: << "test"
test_files = FileList['test/focused/*_test.rb']
Rails::TestUnit::Runner.run(test_files)
end
task :without_long_running_tests => "test:prepare" do
$: << "test"
test_files = FileList['test/**/*_test.rb'].exclude('test/long_running/**/*_test.rb')
Rails::TestUnit::Runner.run(test_files)
end
end
Credit should go to jonatack may 2015 post here: https://github.com/rails/rails/issues/19997

Cucumber and Capybara keep saying that I have an undefined method called `visit'

I keep getting the error message undefined method 'visit' (NoMethodError) when I try to run an example given to me from Instant Cucumber BDD How-to by Wayne Ye. I have lots of gems installed, and I think I have run all the necessary commands on my project folder.
My setup notes for what I have installed are:
gem install selenium-cucumber
gem install bundler
gem install cucumber-rails
gem install launchy
gem install database_cleaner
gem install factory_girl_rails
gem install webmock
gem install pickle
gem install spork-rails
gem install nokogiri
gem install ffi
gem install capybara
chdir C:\DevKit
ruby dk.rb init
ruby dk.rb install
gem install json
gem install sqlite3
<project folder>cucumber --init
<project folder>bundler init
<project folder>bundler install
The example I am trying to run is from the book and looks like this.
Amazon.features
Feature: Shopping in Amazon
As an internet user
I want to search stuff on Amazon
So that I can choose and buy items I like
#javascript
Scenario: Search for baseball gloves
Given I am on Amazon homepage
When I enter "baseball glove" in the search box
And I click "Go" button
Then I should see a list of results related with Baseball Gloves
step_definitions/amazon_search_steps.rb
Given /^I am on Amazon homepage$/ do
visit "http://www.amazon.com"
end
When /^I enter "(.*?)" in the search box$/ do |keywords|
fill_in "Search", :with => keywords
end
When /^I click "Go" button$/ do
click_button "Go"
end
Then /^I should see a list of results related with Baseball Gloves/ do
page.should have_content("#centerBelow")
end
When I run this, I get the following error message.
Looking online, the solution appears to be to add the following line to my spec_helper.rb file, but I don't know which one, and none of the ones I have tried have worked.
config.include Capybara::DSL
EDIT: As requested my env.rb file.
Full path is C:\Ruby22-x64\lib\ruby\gems\2.2.0\gems\cucumber-rails-1.4.3\features\support\env.rb
$:.unshift(File.dirname(__FILE__) + '/../../lib')
require 'rubygems'
require 'bundler/setup'
require 'rspec/expectations'
require 'aruba/cucumber'
if(ENV['ARUBA_REPORT_DIR'])
# Override reporting behaviour so we don't document all files, only the ones
# that have been created after #aruba_report_start (a Time object). This is
# given a value after the Rails app is generated (see cucumber_rails_steps.rb)
module Aruba
module Reporting
def children(dir)
children = Dir["#{dir}/*"].sort
# include
children = children.select do |child|
File.directory?(child) ||
(#aruba_report_start && File.stat(child).mtime > #aruba_report_start)
end
# exclude
children = children.reject do |child|
child =~ /Gemfile/ ||
child =~ /\.log$/
end
children
end
end
end
end

Custom irb not printing objects

Trying to write a custom irb for a gem to ease debugging. At the point where the shell loads and you can use it like ruby console but running into this wall
MyClass.get_last_instance
=>
_.attributes
=> {'attribute'=> 'test'}
The instance was found but a blank string is echo'ed. Here are the requires involved in starting the shell
require 'irb'
require 'irb/completion'
require 'debugger'
I tried reading through the rails source code, didn't get very far, mostly because I didn't really know what I was looking for. I think I'm just missing a require of a part of rails that echos objects.
create a .irbrc in your home path for ubuntu/osx and use the below code, it will work. Also you can add additional gems also debugger or irb
# print SQL to STDOUT
if ENV.include?('RAILS_ENV') && !Object.const_defined?('RAILS_DEFAULT_LOGGER')
require 'logger'
end
# Autocomplete
require 'irb/completion'
# Prompt behavior
ARGV.concat [ "--readline", "--prompt-mode", "simple" ]
# History
require 'irb/ext/save-history'
IRB.conf[:SAVE_HISTORY] = 100
IRB.conf[:HISTORY_FILE] = "#{ENV['HOME']}/.irb-save-history"
# Easily print methods local to an object's class
class Object
def local_methods
(methods - Object.instance_methods).sort
end
end
# copy a string to the clipboard
def pbcopy(string)
`echo "#{string}" | pbcopy`
string
end
require "rubygems"

Testing a patch to the Rails mysql adapter

I wrote a little monkeypatch to the Rails MySQLAdapter and want to package it up to use it in my other projects. I am trying to write some tests for it but I am still new to testing and I am not sure how to test this. Can someone help get me started?
Here is the code I want to test:
unless RAILS_ENV == 'production'
module ActiveRecord
module ConnectionAdapters
class MysqlAdapter < AbstractAdapter
def select_with_explain(sql, name = nil)
explanation = execute_with_disable_logging('EXPLAIN ' + sql)
e = explanation.all_hashes.first
exp = e.collect{|k,v| " | #{k}: #{v} "}.join
log(exp, 'Explain')
select_without_explain(sql, name)
end
def execute_with_disable_logging(sql, name = nil) #:nodoc:
#Run a query without logging
#connection.query(sql)
rescue ActiveRecord::StatementInvalid => exception
if exception.message.split(":").first =~ /Packets out of order/
raise ActiveRecord::StatementInvalid, "'Packets out of order' error was received from the database. Please update your mysql bindings (gem install mysql) and read http://dev.mysql.com/doc/mysql/en/password-hashing.html for more information. If you're on Windows, use the Instant Rails installer to get the updated mysql bindings."
else
raise
end
end
alias_method_chain :select, :explain
end
end
end
end
Thanks.
General testing
You could start reading about testing.
After you are understanding the basics of testing, you should think what you have changed. Then make some tests which test for
the original situation, resulting in errors since you updated it. So reverse the test after it indeed is working for the original situation.
the new situation to see whether you have implemented your idea correctly
The hardest part is to be sure that you covered all situations. Finally, if both parts pass then you could say that your code it working as expected.
Testing gems
In order to test gems you can run
rake test:plugins
to test all plugins of your rails application (see more in chapter 6 of the testing guide), this only works when the gem is in the vendor directory of an application.
Another possibility is to modify the Rakefile of the gem by including a testing task. For example this
desc 'Test my custom made gem.'
Rake::TestTask.new(:test) do |t|
t.libs << 'lib'
t.libs << 'test'
t.pattern = 'test/**/*_test.rb'
t.verbose = true
end
would run all available tests in the test directory ending with _test.rb. To execute this test you can type rake test (from the gem directory!).
In order to run the tests for the gem by default (when typing just rake) you can add/modify this line:
task :default => :test
I used the second method in my ruby-bbcode gem, so you could take a look at it to see the complete example.

Resources