What is does this error method mean: undefined method `method name' for nil:NilClass (NoMethodError) - ruby

I am fairly new to automation testing and I am writing BDD automation test scenarios in Ruby using selenium-webdriver, when running my tests, they fail at the first step. (tumblr just as an example)
What does this error message mean and how do I fix it? Any help would be much appreciated!
In my feature file:
Feature: tumblr
#s1
Scenario: Logging in to Tumblr
Given I am on the Tumblr login page
When I enter my login details
Then I should be sent to the dashboard
In my login_page.rb:
def visit
#browser.goto "#{EnvConfig.base_url}/login"
await_on_page
end
In my login_step_defs.rb:
Given /^I am on the Odicci login page$/ do
#app.tumblr_login.visit
end
When /^I enter my login details$/ do
#app.tumblr_login.login
end
Then /^I should be sent to the dashboard$/ do
#app.tumblr_dashboard.go_to_dashboard
end
Initially when I was running 'cucumber features.feature' but the step definitions could not be located so the scenarios were finishing off as 'undefined' so running 'cucumber features.feature -r step_definitions works to run the tests but they fail because of this error message:
Scenario: Logging in to Tumblr # features.feature:4
Given I am on the Tumblr login page # step_definitions/login_step_defs.rb:2
undefined method `tumblr_login' for nil:NilClass (NoMethodError)
./step_definitions/login_step_defs.rb:3:in `/^I am on the Tumblr login page$/'
features.feature:5:in `Given I am on the Tumblr login page'

#maxpleaner
if ENV['HEADLESS']
require 'headless'
require 'selenium-webdriver'
headless = Headless.new display: '100'
headless.start
end
# Set up browser
# browser = Watir::Browser.new (ENV['BROWSER'] || 'chrome').to_sym
driver = Selenium::WebDriver.for :chrome
browser_type = ENV['BROWSER'] || 'chrome'
$setup_done = false
Before do |scenario|
#browser = browser
#app = App.new #browser
unless $setup_done
$setup_done = true
# This stuff will only run before the first scenario executed. Use it to set up data etc.
end
end
After do |scenario|
end
at_exit do
browser.quit
end

Related

Selenium Does Click on Firefox but PhantomJS doesn't (Ruby)

i'm really new to Selenium WebDriver. I write a simple code for out of curiousity. I made an spam bot to open a page, shuffle in online users list and click everyone of them in order. Send some message, close the new window and repeat.
I made this work on Selenium Firefox driver. It seems work good. But i want to do it silent, not opening firefox everytime. So i found out i can do that by PhantomJS.
Here is my working code for firefox:
require 'selenium-webdriver'
def setup
#driver = Selenium::WebDriver.for :firefox
#reklam = 'Some testing message.'
end
def run
setup
#driver.get 'http://c2.me/okanb3'
first_window = #driver.window_handle
begin
#driver.switch_to.window(first_window)
#driver.find_element(link_text: "Shuffle").click
sleep 20
elements = #driver.find_elements(:class, 'shufflelink')
elements.each do |x|
x.click
all_windows = #driver.window_handles
new_window = all_windows.select { |this_window| this_window != first_window }
#driver.switch_to.window(new_window)
if #driver.page_source.include? 'The user is not available right now.' or #driver.page_source.include? 'User account is disabled.'
#driver.close
#driver.switch_to.window(first_window)
else
input = #driver.find_element(:id, 'inputbox')
input.send_keys(#reklam)
input.send_keys:return
#driver.close
popup = #driver.switch_to.alert
popup.accept
#driver.switch_to.window(first_window)
end
end
end while TRUE
end
run
But when i switch Webdriver from Firefox to PhantomJS, x.click method doesn't work. I made some tests and program doesnt go further from click method. After a while program ends with (Net::ReadTimeout) error.
Here is my last try to work it proper;
require 'selenium-webdriver'
def setup
#driver = Selenium::WebDriver.for :phantomjs
#reklam = 'http://peyloride.com siteme beklerim.'
end
def teardown
#driver.quit
end
def run
setup
#driver.manage.window.resize_to(1920, 1080)
#driver.get 'http://c2.me/okanb3'
first_window = #driver.window_handle
begin
#driver.switch_to.window(first_window)
#driver.find_element(link_text: "Shuffle").click
puts "Shuffleandı"
sleep 20
elements = #driver.find_elements(:class, 'shufflelink')
elements.each do |x|
puts "click'e geldik"
#driver.save_screenshot "phantomjs.png"
x.click
#driver.save_screenshot "phantomjs2.png"
puts "click yaptı sonunda aq"
all_windows = #driver.window_handles
new_window = all_windows.select { |this_window| this_window != first_window }
#driver.switch_to.window(new_window)
if #driver.page_source.include? 'The user is not available right now.' or #driver.page_source.include? 'User account is disabled.'
#driver.close
#driver.switch_to.window(first_window)
else
input = #driver.find_element(:id, 'inputbox')
input.send_keys(#reklam)
input.send_keys:return
#driver.close
popup = #driver.switch_to.alert
popup.accept
#driver.switch_to.window(first_window)
end
end
end while TRUE
end
run
As you can see i tried to take a screenshot to understand the problem but screenshot seems really fine. Here it is:
EDIT: Versions:
ruby -v
ruby 2.2.3p173 (2015-08-18 revision 51636) [x86_64-linux]
gem list
...
selenium-webdriver (2.48.1)
...
phantomjs -v
1.9.0

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

Ruby Page object Gem - Unable to pick a platform for the provided browser (RuntimeError)

I get this error on running my feature file.
Unable to pick a platform for the provided browser (RuntimeError)
Help required, please.
Here is the code;
class GooglePage
include PageObject
def self.visitor
visit("http://www.google.com")
end
end
env.rb
require 'selenium-webdriver'
require 'page-object'
require 'rubygems'
require 'page-object/page_factory'
World (PageObject::PageFactory)
#browser = Selenium::WebDriver.for :firefox
Step-Definitions
require_relative 'GooglePage'
Given(/^I am on the Google home page$/) do
visit(GooglePage)
# visit('http://www.google.com')
on(GooglePage).visitor
end
This won't work:
visit(GooglePage)
because you haven't called page_url in GooglePage (ln 4 below)
class GooglePage
include PageObject
page_url "http://www.google.com"
def self.visitor
visit("http://www.google.com")
end
end
Move the line #browser = Selenium::WebDriver.for :firefox to the Before method in hooks.rb
Before do
#browser = Selenium::WebDriver.for :firefox
end
After do
#browser.close
end
what if you make your rake file pass on tags and BROWSER and URL,e.g.
rake my_task BROWSER=chrome URL=http://google.com.au
and hooks will check if the BROWSER is chrome, then will use the specific Webdriver for chrome. But how to pass the URL in the PageObject?
Currently from hooks I have the ff:
when "chrome" then
caps = Selenium::WebDriver::Remote::Capabilities.chrome
caps.version = "40.0.2214.115 m"
caps.native_events = false
caps.javascript_enabled= true
# This is for increasing the default timeout to 180
client = Selenium::WebDriver::Remote::Http::Default.new
client.timeout = 180
browser = Selenium::WebDriver.for :chrome
browser.manage.window.maximize
end
Before do
browser.cookies.clear
#browser = browser
end
After do
unless ENV["BROWSER"].eql? "ie"
browser.close
sleep 2
end
end
Then on my HomePage pageobject I have the ff:
class HomePage
include PageObject
page_url("#{ENV['URL']}")
#opens the url defined in ENV['URL']
def goto_homepage
visit(HomePage)
end
end
Using Watir, the URL got opened, so trying this out in Selenium and it won't work.

Selenium WebDriver for ruby fails with "too many redirects"

I've got this simple test case that tests a login form.
For some reason webdriver refuses to run the test and comes back with a "too many redirects" message. The page is just an ordinary login screen, very simple and there are no redirects whatsoever. Access from the server to the page seems ok.
I'm using selenium-webdriver-2.25.0 on a centos server.
Below the error message:
(...)
[WARNING] MultiJson is using the default adapter (ok_json). We recommend loading a different JSON library to improve performance.
EE
Finished in 0.206445 seconds.
1) Error: test_login(Login):
Selenium::WebDriver::Error::WebDriverError: too many redirects
/usr/lib/ruby/gems/1.8/gems/selenium-webdriver-2.25.0/lib/selenium/webdriver/remote/http/default.rb:62:in `request'
/usr/lib/ruby/gems/1.8/gems/selenium-webdriver-2.25.0/lib/selenium/webdriver/remote/http/default.rb:63:in `request'
/usr/lib/ruby/gems/1.8/gems/selenium-webdriver-2.25.0/lib/selenium/webdriver/remote/http/common.rb:40:in `call'
(...)
My code:
require "rubygems"
require "selenium-webdriver"
require "test/unit"
class Login < Test::Unit::TestCase
def setup
#driver =Selenium::WebDriver.for(:remote, :url => "http://selenium.server.com/wd/hub")
#base_url = "http://www.myservice.com"
#driver.manage.timeouts.implicit_wait = 30
#verification_errors = []
end
def teardown
#driver.quit
assert_equal [], #verification_errors
end
def test_login
#driver.get(#base_url + "/login/")
#driver.find_element(:id, "username").clear
#driver.find_element(:id, "username").send_keys "user#server"
#driver.find_element(:id, "password").clear
#driver.find_element(:id, "password").send_keys "mykeys!"
#driver.find_element(:xpath, "//input[#value='Login']").click
verify { assert element_present?(:link, "Logout") }
verify { assert element_present?(:link, "Settings") }
verify { assert element_present?(:link, "Products") }
end
def element_present?(how, what)
#driver.find_element(how, what)
true
rescue Selenium::WebDriver::Error::NoSuchElementError
false
end
def verify(&blk)
yield
rescue Test::Unit::AssertionFailedError => ex
#verificatiohttp://jenkins.dev.emesa-auctions.com/cms/n_errors << ex
end
end
UPDATE
It seems that no matter what url I use for the 'base url' the errors keeps occuring.
I managed to solve this problem myself. The issue was that I was accessing the server through its public facing url (selenium.server.com) instead of through the internal lan url (which bypass the firewall).
Changing that fixed the problem.

Using Capybara to test pure JavaScript application

I'm having some problems using Sinatra with Capybara.
I want to test a pure javascript application. It's just a plain index.html that is being served by Sinatra.
require "sinatra"
get "/" do
File.read("public/index.html")
end
Let's say for example that I want to test this code.
$("a.link").click(function(){
$(this).replaceWith("New String");
});
Click me!
Then the test would look something like this.
describe "requests", js: true do
it "should display a message" do
visit "/"
click_link "Click me!"
page.should have_content("New String")
end
end
The problem is that nothing happens. According to Ryan Bates screencast Firefox should start and run the test if js: true is added to the describe block.
Here is my spec_helper file.
require "rspec"
require "capybara"
require "capybara/dsl"
Capybara.javascript_driver = :selenium
require_relative "./../server"
Capybara.app = Sinatra::Application
Capybara.javascript_driver = :selenium
Capybara.default_wait_time = 10
RSpec.configure do |config|
config.mock_with :rspec
config.include Capybara
end
Here is the output when running rspec rspec/request_spec.rb.
requests
should display a message (FAILED - 1)
Failures:
1) requests should display a message
Failure/Error: page.should have_content("New String")
expected #has_content?("New String") to return true, got false
# ./spec/request_spec.rb:5:in `block (2 levels) in <top (required)>'
Finished in 4.38 seconds
1 example, 1 failure
Failed examples:
rspec ./spec/request_spec.rb:2 # requests should display a message
I created an complete example project on Github that can be found here:
https://github.com/oleander/capybara-js-fails
Anyone knows why it fails?
Here is the original answer from Jonas Nicklas.
You need to require 'capybara/rspec' and set :type => :request.
See the Capybara README section on "Using Capybara with RSpec".
/Jonas
Here is a working example on Github.

Resources