mirror of
https://github.com/teamcapybara/capybara.git
synced 2022-11-09 12:08:07 -05:00
Changed to use selenium-webdriver and it works!
This commit is contained in:
parent
feb29e2d64
commit
ac7d044243
11 changed files with 135 additions and 141 deletions
9
lib/webcat/cucumber.rb
Normal file
9
lib/webcat/cucumber.rb
Normal file
|
@ -0,0 +1,9 @@
|
|||
require 'webcat'
|
||||
require 'webcat/dsl'
|
||||
|
||||
if defined?(Rails)
|
||||
Webcat.app = ActionController::Dispatcher.new
|
||||
end
|
||||
|
||||
World(Webcat)
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
module Webcat
|
||||
module Selenium
|
||||
|
||||
class SeleniumRCServer
|
||||
unless Kernel.respond_to?(:silence_stream)
|
||||
def silence_stream(stream)
|
||||
old_stream = stream.dup
|
||||
stream.reopen(RUBY_PLATFORM =~ /mswin/ ? 'NUL:' : '/dev/null')
|
||||
stream.sync = true
|
||||
yield
|
||||
ensure
|
||||
stream.reopen(old_stream)
|
||||
end
|
||||
end
|
||||
|
||||
def booted?
|
||||
@booted || false
|
||||
end
|
||||
|
||||
def boot
|
||||
return if booted?
|
||||
silence_stream(STDOUT) do
|
||||
remote_control.start :background => true
|
||||
end
|
||||
wait
|
||||
@booted = true
|
||||
at_exit do
|
||||
silence_stream(STDOUT) do
|
||||
remote_control.stop
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def remote_control
|
||||
return @remote_control if @remote_control
|
||||
|
||||
@remote_control = ::Selenium::RemoteControl::RemoteControl.new("0.0.0.0", 5041, 15)
|
||||
@remote_control.jar_file = jar_path
|
||||
|
||||
return @remote_control
|
||||
end
|
||||
|
||||
def jar_path
|
||||
File.expand_path("selenium-server.jar", File.dirname(__FILE__))
|
||||
end
|
||||
|
||||
def wait
|
||||
return true
|
||||
$stderr.print "==> Waiting for Selenium RC server on port #{Webrat.configuration.selenium_server_port}... "
|
||||
TCPSocket.wait_for_service_with_timeout(:host => "localhost", :port => 5041, :timeout => 15)
|
||||
$stderr.print "Ready!\n"
|
||||
rescue SocketError
|
||||
$stderr.puts "==> Failed to boot the Selenium RC server... exiting!"
|
||||
exit
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
Binary file not shown.
|
@ -1,7 +1,4 @@
|
|||
require 'selenium/client'
|
||||
require 'webcat/driver/selenium/rc_server'
|
||||
require 'webcat/core_ext/tcp_socket'
|
||||
|
||||
require 'selenium-webdriver'
|
||||
|
||||
class Webcat::Driver::Selenium
|
||||
class Node < Struct.new(:node)
|
||||
|
@ -9,13 +6,32 @@ class Webcat::Driver::Selenium
|
|||
node.text
|
||||
end
|
||||
|
||||
def attribute(name)
|
||||
value = if name.to_sym == :class
|
||||
node.class_name
|
||||
def [](name)
|
||||
if name == :value
|
||||
node.value
|
||||
else
|
||||
node.send(name.to_sym)
|
||||
node.attribute(name)
|
||||
end
|
||||
return value if value and not value.empty?
|
||||
rescue Selenium::WebDriver::Error::WebDriverError
|
||||
nil
|
||||
end
|
||||
|
||||
def set(value)
|
||||
if tag_name == 'input' and %w(text password hidden file).include?(type)
|
||||
node.clear
|
||||
node.send_keys(value.to_s)
|
||||
elsif tag_name == 'input' and type == 'radio'
|
||||
node.select
|
||||
elsif tag_name == 'input' and type == 'checkbox'
|
||||
node.toggle
|
||||
elsif tag_name == "textarea"
|
||||
node.clear
|
||||
node.send_keys(value.to_s)
|
||||
end
|
||||
end
|
||||
|
||||
def select(option)
|
||||
node.find_element(:xpath, ".//option[text()='#{option}']").select
|
||||
end
|
||||
|
||||
def click
|
||||
|
@ -23,35 +39,45 @@ class Webcat::Driver::Selenium
|
|||
end
|
||||
|
||||
def tag_name
|
||||
# FIXME: this might be the dumbest way ever of getting the tag name
|
||||
# there has to be something better...
|
||||
node.to_xml[/^\s*<([a-z0-9\-\:]+)/, 1]
|
||||
node.tag_name
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def type
|
||||
self[:type]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
attr_reader :app, :rack_server
|
||||
|
||||
def self.server
|
||||
@server ||= Webcat::Selenium::SeleniumRCServer.new
|
||||
def self.driver
|
||||
unless @driver
|
||||
@driver = Selenium::WebDriver.for :firefox
|
||||
at_exit do
|
||||
@driver.quit
|
||||
end
|
||||
end
|
||||
@driver
|
||||
end
|
||||
|
||||
def initialize(app)
|
||||
@app = app
|
||||
@rack_server = Webcat::Server.new(@app)
|
||||
@rack_server.boot
|
||||
self.class.server.boot
|
||||
end
|
||||
|
||||
def visit(path)
|
||||
browser.open(url(path))
|
||||
driver.navigate.to(url(path))
|
||||
end
|
||||
|
||||
def body
|
||||
browser.html
|
||||
driver.page_source
|
||||
end
|
||||
|
||||
def find(selector)
|
||||
browser.elements_by_xpath(selector).map { |node| Node.new(node) }
|
||||
driver.find_elements(:xpath, selector).map { |node| Node.new(node) }
|
||||
end
|
||||
|
||||
private
|
||||
|
@ -60,21 +86,8 @@ private
|
|||
rack_server.url(path)
|
||||
end
|
||||
|
||||
def browser
|
||||
unless @_browser
|
||||
@_browser = Selenium::Client::Driver.new :host => 'localhost',
|
||||
:port => 4444,
|
||||
:browser => "*firefox",
|
||||
:url => rack_server.url('/'),
|
||||
:timeout_in_second => 10
|
||||
@_browser.start_new_browser_session
|
||||
|
||||
at_exit do
|
||||
@_browser.close_current_browser_session
|
||||
end
|
||||
end
|
||||
@_browser
|
||||
def driver
|
||||
self.class.driver
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
|
|
@ -12,6 +12,8 @@ class Webcat::Session
|
|||
Webcat::Driver::RackTest.new(app)
|
||||
when :culerity
|
||||
Webcat::Driver::Culerity.new(app)
|
||||
when :selenium
|
||||
Webcat::Driver::Selenium.new(app)
|
||||
else
|
||||
raise Webcat::DriverNotFoundError, "no driver called #{mode} was found"
|
||||
end
|
||||
|
|
|
@ -5,6 +5,6 @@ describe Webcat::Driver::Selenium do
|
|||
@driver = Webcat::Driver::Selenium.new(TestApp)
|
||||
end
|
||||
|
||||
# it_should_behave_like "driver"
|
||||
# it_should_behave_like "driver with javascript support"
|
||||
it_should_behave_like "driver"
|
||||
it_should_behave_like "driver with javascript support"
|
||||
end
|
||||
|
|
|
@ -30,7 +30,7 @@ shared_examples_for 'driver' do
|
|||
end
|
||||
|
||||
it "should find the correct number of elements" do
|
||||
@driver.find('//a').size.should == 2
|
||||
@driver.find('//a').size.should == 3
|
||||
end
|
||||
|
||||
it "should extract node texts" do
|
||||
|
|
1
spec/fixtures/test_file.txt
vendored
Normal file
1
spec/fixtures/test_file.txt
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
ThisIsTheTestFile
|
23
spec/session/selenium_session_spec.rb
Normal file
23
spec/session/selenium_session_spec.rb
Normal file
|
@ -0,0 +1,23 @@
|
|||
require File.expand_path('../spec_helper', File.dirname(__FILE__))
|
||||
|
||||
describe Webcat::Session do
|
||||
context 'with selenium driver' do
|
||||
before do
|
||||
@session = Webcat::Session.new(:selenium, TestApp)
|
||||
end
|
||||
|
||||
describe '#driver' do
|
||||
it "should be a rack test driver" do
|
||||
@session.driver.should be_an_instance_of(Webcat::Driver::Selenium)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#mode' do
|
||||
it "should remember the mode" do
|
||||
@session.mode.should == :selenium
|
||||
end
|
||||
end
|
||||
|
||||
it_should_behave_like "session"
|
||||
end
|
||||
end
|
|
@ -1,6 +1,12 @@
|
|||
require File.expand_path('spec_helper', File.dirname(__FILE__))
|
||||
|
||||
require 'nokogiri'
|
||||
|
||||
shared_examples_for "session" do
|
||||
def extract_results(session)
|
||||
YAML.load Nokogiri::HTML(session.body).xpath("//pre[@id='results']").first.text
|
||||
end
|
||||
|
||||
describe '#app' do
|
||||
it "should remember the application" do
|
||||
@session.app.should == TestApp
|
||||
|
@ -10,9 +16,9 @@ shared_examples_for "session" do
|
|||
describe '#visit' do
|
||||
it "should fetch a response from the driver" do
|
||||
@session.visit('/')
|
||||
@session.body.should == 'Hello world!'
|
||||
@session.body.should include('Hello world!')
|
||||
@session.visit('/foo')
|
||||
@session.body.should == 'Another World'
|
||||
@session.body.should include('Another World')
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -24,21 +30,21 @@ shared_examples_for "session" do
|
|||
context "with id given" do
|
||||
it "should take user to the linked page" do
|
||||
@session.click_link('foo')
|
||||
@session.body.should == 'Another World'
|
||||
@session.body.should include('Another World')
|
||||
end
|
||||
end
|
||||
|
||||
context "with text given" do
|
||||
it "should take user to the linked page" do
|
||||
@session.click_link('labore')
|
||||
@session.body.should == '<h1>Bar</h1>'
|
||||
@session.body.should include('<h1>Bar</h1>')
|
||||
end
|
||||
end
|
||||
|
||||
context "with title given" do
|
||||
it "should take user to the linked page" do
|
||||
@session.click_link('awesome title')
|
||||
@session.body.should == '<h1>Bar</h1>'
|
||||
@session.body.should include('<h1>Bar</h1>')
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -64,7 +70,7 @@ shared_examples_for "session" do
|
|||
context "with value given on a submit button" do
|
||||
before do
|
||||
@session.click_button('awesome')
|
||||
@results = YAML.load(@session.body)
|
||||
@results = extract_results(@session)
|
||||
end
|
||||
|
||||
it "should serialize and submit text fields" do
|
||||
|
@ -121,24 +127,21 @@ shared_examples_for "session" do
|
|||
context "with id given on a submit button" do
|
||||
it "should submit the associated form" do
|
||||
@session.click_button('awe123')
|
||||
results = YAML.load(@session.body)
|
||||
results['first_name'].should == 'John'
|
||||
extract_results(@session)['first_name'].should == 'John'
|
||||
end
|
||||
end
|
||||
|
||||
context "with value given on an image button" do
|
||||
it "should submit the associated form" do
|
||||
@session.click_button('okay')
|
||||
results = YAML.load(@session.body)
|
||||
results['first_name'].should == 'John'
|
||||
extract_results(@session)['first_name'].should == 'John'
|
||||
end
|
||||
end
|
||||
|
||||
context "with id given on an image button" do
|
||||
it "should submit the associated form" do
|
||||
@session.click_button('okay556')
|
||||
results = YAML.load(@session.body)
|
||||
results['first_name'].should == 'John'
|
||||
extract_results(@session)['first_name'].should == 'John'
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -156,39 +159,39 @@ shared_examples_for "session" do
|
|||
it "should fill in a text field by id" do
|
||||
@session.fill_in('form_first_name', :with => 'Harry')
|
||||
@session.click_button('awesome')
|
||||
YAML.load(@session.body)['first_name'].should == 'Harry'
|
||||
extract_results(@session)['first_name'].should == 'Harry'
|
||||
end
|
||||
|
||||
it "should fill in a text field by label" do
|
||||
@session.fill_in('First Name', :with => 'Harry')
|
||||
@session.click_button('awesome')
|
||||
YAML.load(@session.body)['first_name'].should == 'Harry'
|
||||
extract_results(@session)['first_name'].should == 'Harry'
|
||||
end
|
||||
|
||||
it "should fill in a textarea by id" do
|
||||
@session.fill_in('form_description', :with => 'Texty text')
|
||||
@session.click_button('awesome')
|
||||
YAML.load(@session.body)['description'].should == 'Texty text'
|
||||
extract_results(@session)['description'].should == 'Texty text'
|
||||
end
|
||||
|
||||
it "should fill in a textarea by label" do
|
||||
@session.fill_in('Description', :with => 'Texty text')
|
||||
@session.click_button('awesome')
|
||||
YAML.load(@session.body)['description'].should == 'Texty text'
|
||||
extract_results(@session)['description'].should == 'Texty text'
|
||||
end
|
||||
|
||||
it "should fill in a password field by id" do
|
||||
pending "Culerity doesn't like password fields for some reason" if @session.mode == :culerity
|
||||
@session.fill_in('form_password', :with => 'supasikrit')
|
||||
@session.click_button('awesome')
|
||||
YAML.load(@session.body)['password'].should == 'supasikrit'
|
||||
extract_results(@session)['password'].should == 'supasikrit'
|
||||
end
|
||||
|
||||
it "should fill in a password field by label" do
|
||||
pending "Culerity doesn't like password fields for some reason" if @session.mode == :culerity
|
||||
@session.fill_in('Password', :with => 'supasikrit')
|
||||
@session.click_button('awesome')
|
||||
YAML.load(@session.body)['password'].should == 'supasikrit'
|
||||
extract_results(@session)['password'].should == 'supasikrit'
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -200,13 +203,13 @@ shared_examples_for "session" do
|
|||
it "should choose a radio button by id" do
|
||||
@session.choose("gender_male")
|
||||
@session.click_button('awesome')
|
||||
YAML.load(@session.body)['gender'].should == 'male'
|
||||
extract_results(@session)['gender'].should == 'male'
|
||||
end
|
||||
|
||||
it "should choose a radio button by label" do
|
||||
@session.choose("Both")
|
||||
@session.click_button('awesome')
|
||||
YAML.load(@session.body)['gender'].should == 'both'
|
||||
extract_results(@session)['gender'].should == 'both'
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -219,7 +222,7 @@ shared_examples_for "session" do
|
|||
pending "Culerity doesn't like hidden fields for some reason" if @session.mode == :culerity
|
||||
@session.set_hidden_field("form_token", :to => 'test567')
|
||||
@session.click_button('awesome')
|
||||
YAML.load(@session.body)['token'].should == 'test567'
|
||||
extract_results(@session)['token'].should == 'test567'
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -231,13 +234,13 @@ shared_examples_for "session" do
|
|||
it "should check a checkbox by id" do
|
||||
@session.check("form_pets_cat")
|
||||
@session.click_button('awesome')
|
||||
YAML.load(@session.body)['pets'].should include('dog', 'cat', 'hamster')
|
||||
extract_results(@session)['pets'].should include('dog', 'cat', 'hamster')
|
||||
end
|
||||
|
||||
it "should check a checkbox by label" do
|
||||
@session.check("Cat")
|
||||
@session.click_button('awesome')
|
||||
YAML.load(@session.body)['pets'].should include('dog', 'cat', 'hamster')
|
||||
extract_results(@session)['pets'].should include('dog', 'cat', 'hamster')
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -250,16 +253,16 @@ shared_examples_for "session" do
|
|||
pending "Culerity doesn't seem to uncheck this" if @session.mode == :culerity
|
||||
@session.uncheck("form_pets_hamster")
|
||||
@session.click_button('awesome')
|
||||
YAML.load(@session.body)['pets'].should include('dog')
|
||||
YAML.load(@session.body)['pets'].should_not include('hamster')
|
||||
extract_results(@session)['pets'].should include('dog')
|
||||
extract_results(@session)['pets'].should_not include('hamster')
|
||||
end
|
||||
|
||||
it "should uncheck a checkbox by label" do
|
||||
pending "Culerity doesn't seem to uncheck this" if @session.mode == :culerity
|
||||
@session.uncheck("Hamster")
|
||||
@session.click_button('awesome')
|
||||
YAML.load(@session.body)['pets'].should include('dog')
|
||||
YAML.load(@session.body)['pets'].should_not include('hamster')
|
||||
extract_results(@session)['pets'].should include('dog')
|
||||
extract_results(@session)['pets'].should_not include('hamster')
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -271,13 +274,13 @@ shared_examples_for "session" do
|
|||
it "should select an option from a select box by id" do
|
||||
@session.select("Finish", :from => 'form_locale')
|
||||
@session.click_button('awesome')
|
||||
YAML.load(@session.body)['locale'].should == 'fi'
|
||||
extract_results(@session)['locale'].should == 'fi'
|
||||
end
|
||||
|
||||
it "should select an option from a select box by label" do
|
||||
@session.select("Finish", :from => 'Locale')
|
||||
@session.click_button('awesome')
|
||||
YAML.load(@session.body)['locale'].should == 'fi'
|
||||
extract_results(@session)['locale'].should == 'fi'
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -305,27 +308,31 @@ shared_examples_for "session" do
|
|||
it "should set a file path by id" do
|
||||
@session.attach_file "form_image", __FILE__
|
||||
@session.click_button('awesome')
|
||||
YAML.load(@session.body)['image'].should == File.basename(__FILE__)
|
||||
extract_results(@session)['image'].should == File.basename(__FILE__)
|
||||
end
|
||||
|
||||
it "should set a file path by label" do
|
||||
@session.attach_file "Image", __FILE__
|
||||
@session.click_button('awesome')
|
||||
YAML.load(@session.body)['image'].should == File.basename(__FILE__)
|
||||
extract_results(@session)['image'].should == File.basename(__FILE__)
|
||||
end
|
||||
end
|
||||
|
||||
context "with multipart form" do
|
||||
before do
|
||||
@test_file_path = File.expand_path('fixtures/test_file.txt', File.dirname(__FILE__))
|
||||
end
|
||||
|
||||
it "should set a file path by id" do
|
||||
@session.attach_file "form_document", __FILE__
|
||||
@session.attach_file "form_document", @test_file_path
|
||||
@session.click_button('Upload')
|
||||
@session.body.should == File.read(__FILE__)
|
||||
@session.body.should include(File.read(@test_file_path))
|
||||
end
|
||||
|
||||
it "should set a file path by label" do
|
||||
@session.attach_file "Document", __FILE__
|
||||
@session.attach_file "Document", @test_file_path
|
||||
@session.click_button('Upload')
|
||||
@session.body.should == File.read(__FILE__)
|
||||
@session.body.should include(File.read(@test_file_path))
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ class TestApp < Sinatra::Base
|
|||
end
|
||||
|
||||
post '/form' do
|
||||
params[:form].to_yaml
|
||||
'<pre id="results">' + params[:form].to_yaml + '</pre>'
|
||||
end
|
||||
|
||||
post '/upload' do
|
||||
|
|
Loading…
Reference in a new issue