The code below works with when running Chrome and Firefox. I am having issues with Safari using apple's new driver, however. Safari loads up, maximises window, but it will not input anything into the text fields. Please advise?
require 'capybara/rspec'
Capybara.configure do |config|
config.run_server = false
config.default_driver = :selenium
config.app_host = 'https://www.fake.com'
end
Capybara.register_driver :selenium do |app|
Capybara::Selenium::Driver.new(app, browser: :safari)
end
Capybara.page.driver.browser.manage.window.maximize
Capybara.default_max_wait_time = 10
describe "Entering invalid credentials,", :type => :feature do
it "should prompt an error message." do
visit '/#/login'
#Code below does not work
fill_in 'Email', with: 'fake#email.com'
fill_in 'Password', with: 'fake'
click_button 'Log In'
end
end
: https://i.stack.imgur.com/tEG6f.png
Related
Hi I am learning capybara, and i ve tried various answers in SO I am not able to proceed. I am trying to test a application with capybara. Visit is not working, errors out saying it needs to be within 'it' or example/executable block etc. but with below code , background and scenario etc is not working, execution is not going inside.
Results::
C:\Ruby223\bin\ruby.exe -e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift) C:/Users/xxx/RubymineProjects/xxx-app/spec/features/xxxxx.rb
"aaa"
Process finished with exit code 0
i dont want to mess up the Rails application, so I want a standalone file from where i can execute tests and then integrate with rails app with developers help.
require 'capybara/dsl'
require 'capybara'
require 'capybara/rspec'
require 'rspec'
feature "Signing in" do
p 'aaa'
background do
p 'aaa1'
Capybara.register_driver :selenium_chrome do |app|
Capybara::Selenium::Driver.new(app, :browser => :chrome)
end
Capybara.run_server = false
Capybara.current_driver = :selenium_chrome
Capybara.app_host = 'http://www.google.com'
end
scenario "Signing in with correct credentials" do
p 'aaa2'
visit '/q=?alkjaaa'
within("#session") do
fill_in 'email', with: 'user#example.com'
fill_in 'password', with: 'caplin'
end
click_button 'Signin'
expect(page).to have_content 'results'
end
given(:other_user) { User.make(email: 'other#example.com', password: 'rous') }
scenario "Signing in as another user" do
p 'aaa'
visit '/sessions/new'
within("#session") do
fill_in 'Email', with: other_user.email
fill_in 'Password', with: other_user.password
end
click_button 'Signin'
expect(page).to have_content 'Invalid email or password'
end
end
Running that file alone with ruby isn't going to do anything because all it does is define tests, it doesn't execute them. If you run that file with rspec then it will run the tests defined in the file.
rspec your_file.rb
My very basic feature specs are passing just fine locally but failing on CircleCI and Codeship. The tests that are failing:
require 'spec_helper'
describe 'Authentication' do
describe "sign in" do
it "is the landing page for non-authenticated users" do
user = create(:user)
visit root_path
expect( page ).to have_content 'LOG IN' # On sign-in page
fill_in 'Email', with: user.email
fill_in "Password", with: user.password
click_button 'Sign in'
expect( current_path ).to eq user_path(user)
end
end
describe 'registration' do
it "allows new users to register" do
visit root_path
click_link 'Sign up'
fill_in 'Email', with: 'myfake#email.com'
fill_in 'Password', with: 'password'
fill_in 'Password confirmation', with: 'password'
fill_in 'First name', with: 'John'
fill_in 'Last name', with: 'Doe'
click_button "Sign up"
expect( current_path ).to include '/users/'
expect( page ).to have_content "Welcome! You have signed up successfully."
end
end
end
The tests both fail on the first lines where they set expectations of the pages (expect( page ).to have_content "LOG IN" and click_link "Sign up", respectively), with errors suggesting the page HTML is completely blank:
expected to find text "LOG IN" in ""
I saved screenshots on CircleCI, and they indeed show a completely blank page.
Here's where it gets interesting. I tried debugging the problem by running/watching the specs on Circle using a VNC. When I a) set driver: :selenium for the tests, b) add a sleep 1 or two to the tests before testing the page expectations, and c) manually run the test after SSHing into their servers with the VNC, I can see the tests run in Selenium (they open a browser in the VNC) and they pass perfectly.
Outside of the VNC, however, the tests fail consistently in both CI servers. With or without tons of sleeps and driver: :selenium. Any ideas what could be causing this discrepancy between the regular CircleCI/Codeship servers and their VCN/my local test environment? I got in touch with the folks at CircleCI, but they're stumped for the moment.
If relevant, I'm running Ruby 2.2.0, Rails 4.2, Capybara 2.4.4, Capybara-Webkit 1.4.1, and Selenium-Webdriver 2.44.0
Some potentially relevant files:
spec_helper.rb
ENV["RAILS_ENV"] = "test"
require File.expand_path("../../config/environment", __FILE__)
require "rspec/rails"
require "shoulda/matchers"
require "webmock/rspec"
require 'vcr'
Dir[Rails.root.join("spec/support/**/*.rb")].each { |file| require file }
module Features
include Warden::Test::Helpers
Warden.test_mode!
def sign_in(user)
login_as(user, scope: :user)
end
end
module Controllers
# Pre-parse controller responses for easy access
def response_body
body = JSON.parse(response.body)
body.is_a?(Hash) ? body.to_sh : body.map(&:to_sh)
end
end
module Mock
def disable_webmock(&block)
WebMock.disable!
yield
WebMock.enable!
end
end
RSpec.configure do |config|
config.expect_with :rspec do |c|
c.syntax = :expect
end
# Save a screenshot to CircleCI when a feature test fails
config.after(:each, :type => :feature) do |example|
if example.exception
artifact = save_page
puts "\"#{example.description}\" failed. Page saved to #{artifact}"
end
end
config.include Features, type: :feature
config.include Controllers, type: :controller
config.include Mock
config.include Formulaic::Dsl, type: :feature
config.infer_spec_type_from_file_location!
config.infer_base_class_for_anonymous_controllers = false
config.order = "random"
config.use_transactional_fixtures = false
end
RSpec::Matchers.define :hash_eq do |expected|
match do |actual|
actual.recursive_symbolize_keys == expected.recursive_symbolize_keys
end
end
VCR.configure do |c|
c.cassette_library_dir = 'spec/fixtures/vcr_cassettes'
c.hook_into :webmock
c.allow_http_connections_when_no_cassette = true
c.configure_rspec_metadata!
c.ignore_hosts '127.0.0.1', 'localhost:3000'
end
ActiveRecord::Migration.maintain_test_schema!
Capybara.javascript_driver = :webkit
if ENV['CIRCLE_ARTIFACTS']
Capybara.save_and_open_page_path = ENV['CIRCLE_ARTIFACTS']
end
WebMock.disable_net_connect!(allow_localhost: true)
database_cleaner.rb
RSpec.configure do |config|
config.use_transactional_fixtures = false
config.before(:suite) do
DatabaseCleaner.strategy = :truncation
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
end
I can think of a couple of things to try:
If you want to get your specs to run headless, try using poltergeist rather than capybara-webkit. poltergeist has several advantages which I described here: https://stackoverflow.com/a/24108439/634576
Selenium might just be a distraction, but, if you want to get it to work, be sure that your CI environment has the right version of Firefox. Each version of selenium-webdriver seems to need a narrow range of versions of Firefox. On CircleCI, you can configure circle.yml to install a specific version of Firefox. Right now we use selenium-webdriver 2.46.2 and Firefox 39.0.3, installed with the following in circle.yml:
dependencies:
pre:
- sudo apt-get update; sudo apt-get install firefox=39.0.3+build2-0ubuntu0.12.04.1
I don't know about Codeship.
I have experienced instability of my Selenium tests on CircleCI until I came across this post https://discuss.circleci.com/t/selenium-tests-timing-out/7765/2
After adding:
machine:
environment:
DBUS_SESSION_BUS_ADDRESS: /dev/null
to my circle.yml, my tests have become stable.
I added some confirmation dialog boxes for my Rails 3.1 application and, prior to that, their corresponding tests. Following the model of Railscast #257, I added ':js => true' to the test, added database_cleaner and modified the spec_helper.rb file accordingly.
When I run the test, Firefox launches, Capybara-Selenium fills in the fields the the appropriate username and a password, but log-in fails (i.e., "invalid username/password".) Other tests that do not have ':js => true' and also login, do still pass.
I would like to add more javascript to my application in the future and I am avoiding solutions that would hack Capybara to get this to work (e.g., click 'OK' on all dialogs.)
Any ideas what I might be missing? Fail that, any suggestions on how to debug this problem?
Thank you.
You should set use_transactional_fixtures = false for your seleniumtests.
This can be done in the spec_helper.rb with
config.use_transactional_fixtures = false
for all your tests.
Or do this for a single testcase:
describe 'testcase' , :type => :request do
self.use_transactional_fixtures = false
it 'your test', :js => :true do
testing...
end
end
This happens because selenium-tests access the database in a different way. With transactional fixtures enabled, selenium will work on an empty database -> your user does not exist and you cannot login.
For normal tests you should use transactional fixtures because your tests run much faster.
As per Avdi Grimm's post (features a detailed explanation):
Gemfile:
group :test do
gem 'database_cleaner'
end
spec_helper.rb:
config.use_transactional_fixtures = false
spec/support/database_cleaner.rb:
RSpec.configure do |config|
config.before(:suite) do
DatabaseCleaner.clean_with(:truncation)
end
config.before(:each) do
DatabaseCleaner.strategy = :transaction
end
config.before(:each, :js => true) do
DatabaseCleaner.strategy = :truncation
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
end
I had transactional fixtures disabled but adding the :js => true block to database_cleaner.rb did it for me.
I have the following integration test. It loads a page with a form on it. The submit button is pressed without any data so the form should show an error box. The form is submitted with ajax and should put the form back on the page with the errors.
I can see this in the browser but the test fails.
What am I doing wrong? I am a complete NOOB so need some guidance.
require 'spec_helper'
require "rubygems"
describe "Boards" do
describe "board creation failure" do
attr_reader :selenium_driver
alias :page :selenium_driver
before(:all) do
#verification_errors = []
#selenium_driver = Selenium::Client::Driver.new \
:host => "localhost",
:port => 4444,
:browser => "*chrome",
:url => "http://localhost:3000/",
:timeout_in_second => 60
end
before(:each) do
#selenium_driver.start_new_browser_session
end
after(:each) do
#selenium_driver.close_current_browser_session
#verification_errors.should == []
end
it "should show the error explanation div" do
page.open "/"
page.click "board_submit"
page.is_element_present("error_explanation").should be_true #should show error box
end
end
I figured it out.
I needed to add the following metho to tell Selenium to wait until all of the ajax calls were completed.
I put this method in my spec/spec_helper.rb file and made sure to have require 'spec_helper' in the file.
Here is the method in spec_helper.rb:
#needed for selenium ajax testing
def wait_for_ajax(timeout=5000)
js_condition = 'selenium.browserbot.getUserWindow().jQuery.active == 0'
#selenium_driver.wait_for_condition(js_condition, timeout)
end
#needed for selenium ajax testing
def selenium_setup
#verification_errors = []
#selenium_driver = Selenium::Client::Driver.new \
:host => "localhost",
:port => 4444,
:browser => "*firefox",
:url => "http://localhost:3000/",
:timeout_in_second => 60
#return #selenium_driver
end
As you can see above I also moved the setup code for the selenium_driver to the spec_helper.rb file to clean up my code and make it more DRY:
Here are my integration tests file:
require 'spec_helper'
describe "Board form" do
attr_reader :selenium_driver
alias :page :selenium_driver
before(:all) do
selenium_setup
#selenium_driver.start_new_browser_session
end
after(:all) do
#selenium_driver.close_current_browser_session
#verification_errors.should == []
end
describe "create board" do
describe "failure" do
it "test_ home page form" do
page.open "/"
("Happy Birthday Greetings | Home").should == page.get_title
page.is_element_present("board_bp_name").should be_true
page.is_text_present("Name").should be_true
("Happy Birthday Greetings | Home").should == page.get_title
page.click "board_submit"
wait_for_ajax
page.is_element_present("board_bp_name").should be_true
page.is_text_present("Name").should be_true
page.is_element_present("board_birthday_1i").should be_true
page.is_element_present("board_submit").should be_true
page.is_text_present("exact:Oops, looks like 1 error occured: \n Hey whose birthday is it? Please enter a name.").should be_true
page.is_element_present("error_explanation").should be_true
end
end
describe "success" do
it "should create a new board for a properly filled in form and show the correct flash message" do
page.open "/"
page.type "board_bp_name", "Test User"
page.select "board_birthday_2i", "label=October"
page.select "board_birthday_1i", "label=1967"
page.select "board_birthday_3i", "label=7"
page.click "board_submit"
wait_for_ajax
page.wait_for_page_to_load("30000")
page.get_location().should =~ /boards\/\d/i
page.is_element_present("css=div.flash.success").should be_true
page.is_text_present("Your friend's board has been created.").should be_true
page.is_text_present("Test User").should be_true
page.is_text_present("43").should be_true
page.is_element_present("greeting_link").should be_true
page.is_text_present("Add greeting").should be_true
end
end
end
end
Using capybara (0.3.9) with steak and when running my steak acceptance spec with :js => true, firefox is fired and it works.
But when I upgrade capybara to 0.4.1.2 in Gemfile and run the same spec, firefox is fired on port 9887 but the page just show Unable to connect.
I think the selenium server couldn't fire.
This also affects my cucumber scenarios with #javascript tag too.
Following is my spec_helper.rb
require 'spork'
Spork.prefork do
ENV["RAILS_ENV"] ||= 'test'
...
RSpec.configure do |config|
...
config.before(:each, :type => :acceptance) do
Capybara.reset_sessions!
Capybara.default_selector = :css
Capybara.default_driver = :selenium
Capybara.javascript_driver = :selenium
Capybara.current_driver = :selenium if example.metadata[:js]
end
config.after(:each, :type => :acceptance) do
Capybara.use_default_driver if example.metadata[:js]
end
end
end
Spork.each_run do
load "#{Rails.root}/spec/Sporkfile.rb" if File.exists?("#{Rails.root}/spec/Sporkfile.rb")
end
and this is the acceptance_helper.rb
require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
require "steak"
# Put your acceptance spec helpers inside /spec/acceptance/support
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}