Using Capybara live without RSpec - ruby

I'd like to use Capybara for live testing, outside RSpec. Just as I'd do using pure Selenium. Is it possible to build scenarios and do logs this way? If not and I have to stick with Selenium - how can I create scenarios and do logs using Ruby?

You can manually create a Capybara session and use that to interact with your production website. For example, the following will go to Google and get the text:
require 'capybara'
session = Capybara::Session.new(:selenium)
session.visit('https://www.google.com')
puts session.text
Note that neither Capybara nor RSpec require the system under test to be a local Ruby project. For example, the following RSpec test goes to Google and checks that the word "Google" appears:
require 'capybara/rspec'
Capybara.current_driver = :selenium
Capybara.app_host = 'http://www.google.com'
feature "google", :js => true do
scenario "should have text" do
visit('/')
page.should have_content(/Google/)
end
end

Related

Capybara with headless chrome doesn't clear session between test cases which use different subdomains

I switched my rails tests from capybara-webkit to headless chrome. When I run a test which visits not the default Capybara host the first case passes but the second one fails because the user are already logged in when they try to login
I use chromedriver v2.45, selenium-webdriver (3.141.0) and capybara (2.18.0)
I have the following setup:
require 'selenium-webdriver'
Capybara.register_driver :chrome do |app|
options = Selenium::WebDriver::Chrome::Options.new(
args: %w[headless disable-gpu no-sandbox]
)
Capybara::Selenium::Driver.new(app, browser: :chrome, options: options)
end
Capybara.javascript_driver = :chrome
I tried to change the app host to the default domain after visiting another domain
using_app_host("http://another.lvh.me") do
visit '/'
# do something
end
where using_app_host is
def using_app_host(host)
original_host = Capybara.app_host
Capybara.app_host = host
yield
ensure
Capybara.app_host = original_host
end
but it didn't help.
The spec structure looks the following way:
feature "Use another subdomain", js: true do
before { login } # use default Capybara app host http://root.lvh.me
scenario "case 1" do
using_app_host("http://another.lvh.me") do
# do something
end
end
scenario "case 2" do
using_app_host("http://another.lvh.me") do
# do something else
end
end
end
Any ideas why capybara/headless chrome doesn't clean the user session between the test cases when navigating to another domain?
Are you storing session information in the browsers window.localStorage and/or window.sessionStorage? If so you can set those to be cleared via options passed to the driver (Note: these settings are the default for the selenium driver in Capybara 3.12+)
Capybara.register_driver :chrome do |app|
options = Selenium::WebDriver::Chrome::Options.new(args: %w[no-sandbox])
options.headless!
Capybara::Selenium::Driver.new(app, browser: :chrome, options: options, clear_local_storage: true, clear_session_storage: true)
end
Even I was facing same issue.
After adding the steps to clear the cookies, session it is not working either. I added below code in env.rb to start a new session every time for a new test
May be you can try this.
Before do
Capybara.session_name = ":session_#{Time.zone.now.to_i}"
end
After do
Capybara.current_session.driver.quit
end
Also, you can add in chrome options to open the session in incognito window
I found this thread useful in a reverse context. I have a test setup wherein I'm storing session credentials in local storage. And so upgrading from capybara v3.11 to v3.12 broke the suite such that only the first scenario would pass and the rest of the scenarios would fail on the login page every time.
That's because the local storage was getting cleared based on the default behavior of capybara 3.12
I updated my suite to set clear_local_storage and clear_session_storage to false explicitly at time of registering the driver.
Capybara.register_driver :selenium_chrome do |app|
Capybara::Selenium::Driver.new(app,
browser: :chrome,
clear_local_storage: false,
clear_session_storage: false)

How can I fake a response to Capybara/poltergeist using webmock?

I'm testing a webscraper and I'd like to use Webmock to deliver fake websites for faster testing. When I mock a website, Ruby's native HTTP library works fine, but Capybara doesn't seem capable of receiving the mocked response. I know that webmock is stubbing low level HTTP requests, and I assume it matters which one capybara uses and which one webmock is configured to use. However, I need to know how Capybara makes HTTP requests and how I can configure webmock to stub that particular method set.
require 'capybara/poltergeist'
require 'webmock'
require 'pry'
include WebMock::API
WebMock.disable_net_connect!(allow_localhost:true)
Capybara.register_driver :poltergeist do |app|
Capybara::Poltergeist::Driver.new(app, js_errors: false)
end
# Configure Capybara to use Poltergeist as the driver
Capybara.default_driver = :poltergeist
Capybara.javascript_driver = :poltergeist
U = /google.com/
b = Capybara.current_session
stub_request(:any, U).
with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'}).
to_return(status:200, body:"abc", headers:{})
puts Net::HTTP.get(U,'/') #=> This returns "abc"
b.visit U
puts b.html #=> Throws error
The error I'm getting is as follows:
command': Request failed to reach server, check DNS and/or server status (Capybara::Poltergeist::StatusFailError)
I've tried using FakeWeb as well, but that simply was not capable of registering URIs. I'm open to using other APIs besides webmock if you think this is the wrong tool for the job.
Thanks in advance :)
Tom Walpole is correct. You can use WebMock to mock things your server is connecting to, but the browser makes its own connections and is unaffected by the changes you make to the server.
If you want to fake responses that the browser requests from other servers try something like Puffing Billy. Take a look at the Caching capability which can be setup to re-play results (much like VCR).
If you're working with something VERY simple you could try just loading the data you need with Capybara.string. But that's probably too limited for what you want.
Capybara doesn't make web requests, it tells the browser where to visit and the browser in turn makes the request. The way to do what you want is to use a proxy that can redirect specific browser requests to your own app
There is a newer and better way of doing this.
# spec/spec_helper.rb
RSpec.configure do |config|
config.before(:each) do |example|
if example.metadata[:type] == :feature
Capybara::Webmock.start
end
end
config.after(:suite) do
Capybara::Webmock.stop
end
end
Then use the capybara_webmock JavaScript driver:
# Use Chrome Driver
Capybara.javascript_driver = :capybara_webmock_chrome
https://github.com/hashrocket/capybara-webmock

How can I test the page title while working with Sinatra + MiniTest

I am having the configuration as below :
Rakefile
require 'rake/testtask'
Rake::TestTask.new do |t|
t.pattern = 'spec/*_spec.rb'
end
Gemfile
source 'https://rubygems.org'
gem 'sinatra'
gem 'thin'
gem 'rack-test'
spec_helper.rb
ENV['RACK_ENV'] = 'test'
require 'minitest/autorun'
require 'rack/test'
require_relative '../app'
include Rack::Test::Methods
def app
MyApp
end
app_spec.rb
require_relative 'spec_helper'
describe 'Hello World' do
it 'should have hello world' do
get '/'
last_response.must_be :ok?
# I want to do something like below
last_response.title must_match /home page/i
end
end
How can I test the page title of a view using MiniTest and Sinatra.
You can't check this with minitest alone.
You should be looking at Capybara to achieve this.
Capybara helps you test web applications by simulating how a real user
would interact with your app.
Once setup use has_title? matcher to test the title of the rendered page.
Using Capybara you can test various aspects of your page like its content/text, if it has a particular link or not, a particular button, text field, email field, etc.
You can simulate the behavior of filling up a form and clicking on a button to submit the same. Putting it simply, it just behaves as a real user would by simulating the actions that a user can perform on a given page with what all a user can see on a given page.

"undefined method" when using Capybara without any framework

I'd want to use Capybara in plain Ruby without Rails, Cucumber, Rspec, Test::Unit, etc. for debugging purposes. I configured it as shown here but I still have exceptions when using Capybara API.
require 'rspec'
require 'capybara'
require 'capybara/dsl'
require 'rspec/expectations'
Capybara.app_host = "http://somedomain.com"
Capybara.run_server = false
Capybara.current_driver = :selenium
include Capybara::DSL
visit '/'
page.should have_xpath "//span[#class='my_class']"
visit method works fine. But I have exception undefined method 'have_xpath' for main:Object.
How can I solve this?
You use RSpec matchers without including them:
include RSpec::Matchers

Login to Vimeo Via Mechanize (ruby)

I am trying to login to my vimeo account using Mechanize in order to scrape hundreds of video titles and urls. Here is my code:
task :import_list => :environment do
require 'rubygems'
require 'mechanize'
agent = Mechanize.new
agent.user_agent = "Mac Safari"
puts "Logging in..."
page = agent.get("http://vimeo.com/log_in")
form = page.forms[0]
form.fields[0].value = 'sample#email.com'
form.fields[1].value = 'somepassword'
page = agent.submit(form)
pp page
end
and my error message:
401 => Net::HTTPUnauthorized
This is running through a rake task if it matters at all.
Any ideas?
Not sure how to do it with Mecnanize but here is code to do it with Capybara:
require 'capybara/dsl'
require 'selenium-webdriver'
Capybara.run_server = false
Capybara.default_driver = :selenium
class Vimeo
include Capybara::DSL
def go
visit "https://vimeo.com/log_in"
fill_in "email", :with => "ivan.bisevac#gmail.com"
fill_in "password", :with => "strx8UnK0a-"
find("span.submit > input").click
end
end
v = Vimeo.new
v.go
Also, Capybara is better for scraping javascript sites.
my first thought was:
Vimeo login does not work without JavaScript, so it's not possible to login with Mechanize.
To test my bold statement:
without javascript
disable javascript for all sites in your browser
try to login ( fill out the form in your browser like you normally do )
you'll get an unauthorized message on the resulting page
with javascript
enable javascript
everything works as expected
update
Vimeo.com uses the following querystring when logging in.
Gonna try and post the string manually with Mechanize.
action=login&service=vimeo&email=your-email&password=your-password&token=k7yd5du3L9aa5577bb0e8fc
update 2
I've got a Ruby Rake task that logs in to a Vimeo Pro account
and reads the HTTP Live Streaming link from a video settings page.
update 3
I've posted a working Ruby Rake task: https://gist.github.com/webdevotion/5635755.
Have you tried using the official Vimeo API?
It seems that authorization give something 'token'
http header part:
action=login&service=vimeo&email=your_mail&password=asfsdfsdf&token=51605c24c92a4d4706ecbe9ded7e3851

Resources