drnic-culerity 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +4 -0
- data/MIT-LICENSE +20 -0
- data/README.textile +101 -0
- data/Rakefile +42 -0
- data/VERSION.yml +4 -0
- data/culerity.gemspec +79 -0
- data/features/fixtures/sample_feature +14 -0
- data/features/installing_culerity.feature +41 -0
- data/features/step_definitions/common_steps.rb +171 -0
- data/features/step_definitions/culerity_setup_steps.rb +7 -0
- data/features/step_definitions/rails_setup_steps.rb +36 -0
- data/features/support/common.rb +32 -0
- data/features/support/env.rb +24 -0
- data/features/support/matchers.rb +11 -0
- data/init.rb +1 -0
- data/lib/culerity/celerity_server.rb +65 -0
- data/lib/culerity/remote_browser_proxy.rb +65 -0
- data/lib/culerity/remote_object_proxy.rb +76 -0
- data/lib/culerity.rb +40 -0
- data/rails/init.rb +1 -0
- data/rails_generators/culerity/culerity_generator.rb +25 -0
- data/rails_generators/culerity/templates/config/environments/culerity_continuousintegration.rb +28 -0
- data/rails_generators/culerity/templates/config/environments/culerity_development.rb +17 -0
- data/rails_generators/culerity/templates/features/step_definitions/common_celerity_steps.rb +87 -0
- data/rails_generators/culerity/templates/lib/tasks/culerity.rake +27 -0
- data/script/console +10 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/spec/celerity_server_spec.rb +77 -0
- data/spec/remote_browser_proxy_spec.rb +59 -0
- data/spec/remote_object_proxy_spec.rb +63 -0
- data/spec/spec_helper.rb +7 -0
- metadata +107 -0
@@ -0,0 +1,65 @@
|
|
1
|
+
module Culerity
|
2
|
+
|
3
|
+
class RemoteBrowserProxy < RemoteObjectProxy
|
4
|
+
def initialize(io, browser_options = {})
|
5
|
+
@io = io
|
6
|
+
unless browser_options.empty?
|
7
|
+
@remote_object_id = 'celerity'
|
8
|
+
configure_browser browser_options
|
9
|
+
@remote_object_id = nil
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
#
|
14
|
+
# Calls the block until it returns true or +time_to_wait+ is reached.
|
15
|
+
# +time_to_wait+ is 30 seconds by default
|
16
|
+
#
|
17
|
+
# Returns true upon success
|
18
|
+
# Raises Timeout::Error when +time_to_wait+ is reached.
|
19
|
+
#
|
20
|
+
def wait_until time_to_wait=30, &block
|
21
|
+
Timeout.timeout(time_to_wait) do
|
22
|
+
until block.call
|
23
|
+
sleep 0.1
|
24
|
+
end
|
25
|
+
end
|
26
|
+
true
|
27
|
+
end
|
28
|
+
|
29
|
+
#
|
30
|
+
# Calls the block until it doesn't return true or +time_to_wait+ is reached.
|
31
|
+
# +time_to_wait+ is 30 seconds by default
|
32
|
+
#
|
33
|
+
# Returns true upon success
|
34
|
+
# Raises Timeout::Error when +time_to_wait+ is reached.
|
35
|
+
#
|
36
|
+
def wait_while time_to_wait=30, &block
|
37
|
+
Timeout.timeout(time_to_wait) do
|
38
|
+
while block.call
|
39
|
+
sleep 0.1
|
40
|
+
end
|
41
|
+
end
|
42
|
+
true
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
#
|
47
|
+
# Specify whether to accept or reject all confirm js dialogs
|
48
|
+
# for the code in the block that's run.
|
49
|
+
#
|
50
|
+
def confirm(bool, &block)
|
51
|
+
blk = "lambda { #{bool} }"
|
52
|
+
|
53
|
+
self.send_remote(:add_listener, :confirm) { blk }
|
54
|
+
block.call
|
55
|
+
self.send_remote(:remove_listener, :confirm) { blk }
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def remote_object_id
|
61
|
+
(@remote_object_id || 'browser').inspect
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module Culerity
|
2
|
+
|
3
|
+
class CulerityException < StandardError
|
4
|
+
def initialize(message, backtrace)
|
5
|
+
super message
|
6
|
+
#self.backtrace = backtrace
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class RemoteObjectProxy
|
11
|
+
def initialize(remote_object_id, io)
|
12
|
+
@remote_object_id = remote_object_id
|
13
|
+
@io = io
|
14
|
+
end
|
15
|
+
|
16
|
+
#
|
17
|
+
# Commonly used to get the HTML id attribute
|
18
|
+
# Use `object_id` to get the local objects' id.
|
19
|
+
#
|
20
|
+
def id
|
21
|
+
send_remote(:id)
|
22
|
+
end
|
23
|
+
|
24
|
+
def method_missing(name, *args)
|
25
|
+
send_remote(name, *args)
|
26
|
+
end
|
27
|
+
|
28
|
+
#
|
29
|
+
# Calls the passed method on the remote object with any arguments specified.
|
30
|
+
# Behaves the same as <code>Object#send</code>.
|
31
|
+
#
|
32
|
+
# If you pass it a block then it will append the block as a "lambda { … }".
|
33
|
+
# If your block returns a lambda string ("lambda { … }") then it will be passed
|
34
|
+
# straight through, otherwise it will be wrapped in a lambda string before sending.
|
35
|
+
#
|
36
|
+
def send_remote(name, *args, &blk)
|
37
|
+
input = [remote_object_id, %Q{"#{name}"}, *args.map{|a| a.inspect}]
|
38
|
+
input << block_to_string(&blk) if block_given?
|
39
|
+
@io << "[#{input.join(", ")}]\n"
|
40
|
+
process_result @io.gets.to_s.strip
|
41
|
+
end
|
42
|
+
|
43
|
+
def exit
|
44
|
+
@io << '["_exit_"]'
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def process_result(result)
|
50
|
+
res = eval result
|
51
|
+
if res.first == :return
|
52
|
+
res[1]
|
53
|
+
elsif res.first == :exception
|
54
|
+
raise CulerityException.new("#{res[1]}: #{res[2]}", res[3])
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
#
|
59
|
+
# Takes a block and either returns the result (if it returns "lambda { … }")
|
60
|
+
# or builds the lambda string with the result of the block in it.
|
61
|
+
#
|
62
|
+
# Returns a string in the format "lambda { … }"
|
63
|
+
#
|
64
|
+
def block_to_string &block
|
65
|
+
result = block.call.to_s
|
66
|
+
unless result.is_a?(String) && result[/^lambda \s* \{ .*? \}/x]
|
67
|
+
result = "lambda { #{result} }"
|
68
|
+
end
|
69
|
+
result
|
70
|
+
end
|
71
|
+
|
72
|
+
def remote_object_id
|
73
|
+
@remote_object_id
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
data/lib/culerity.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/culerity/remote_object_proxy'
|
2
|
+
require File.dirname(__FILE__) + '/culerity/remote_browser_proxy'
|
3
|
+
|
4
|
+
module Culerity
|
5
|
+
|
6
|
+
def self.run_server
|
7
|
+
IO.popen("jruby #{__FILE__}", 'r+')
|
8
|
+
|
9
|
+
# open the two pipes that were created below
|
10
|
+
# while(!File.exists?("tmp/culerity_in.pipe"))
|
11
|
+
# sleep(1)
|
12
|
+
# end
|
13
|
+
# pipe_in = open("tmp/culerity_in.pipe", "w+")
|
14
|
+
# pipe_out = open("tmp/culerity_out.pipe", "r+")
|
15
|
+
|
16
|
+
|
17
|
+
|
18
|
+
# store celerity pid in tmp/culerity_celerity.pid
|
19
|
+
# store server pid in tmp/culerity_rails_server.pid
|
20
|
+
|
21
|
+
# open named pipes to communicate with celerity_server + return them
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
if __FILE__ == $0
|
27
|
+
# `rm tmp/culerity_in.pipe`
|
28
|
+
# `mkfifo tmp/culerity_in.pipe`
|
29
|
+
# `rm tmp/culerity_out.pipe`
|
30
|
+
# `mkfifo tmp/culerity_out.pipe`
|
31
|
+
#
|
32
|
+
# pipe_in = open("tmp/culerity_in.pipe", "r+")
|
33
|
+
# p pipe_in
|
34
|
+
# p STDIN
|
35
|
+
# pipe_out = open("tmp/culerity_out.pipe", "w+")
|
36
|
+
#
|
37
|
+
require File.dirname(__FILE__) + '/culerity/celerity_server'
|
38
|
+
Culerity::CelerityServer.new STDIN, STDOUT
|
39
|
+
end
|
40
|
+
|
data/rails/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'culerity'
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class CulerityGenerator < Rails::Generator::Base
|
2
|
+
|
3
|
+
def manifest
|
4
|
+
record do |m|
|
5
|
+
m.directory 'features/step_definitions'
|
6
|
+
m.file 'features/step_definitions/common_celerity_steps.rb', 'features/step_definitions/common_celerity_steps.rb'
|
7
|
+
m.file 'config/environments/culerity_continuousintegration.rb', 'config/environments/culerity_continuousintegration.rb'
|
8
|
+
m.file 'config/environments/culerity_development.rb', 'config/environments/culerity_development.rb'
|
9
|
+
|
10
|
+
m.gsub_file 'config/database.yml', /cucumber:.*\n/, "cucumber: &CUCUMBER\n"
|
11
|
+
|
12
|
+
m.gsub_file 'config/database.yml', /\z/, "\nculerity_development:\n <<: *CUCUMBER"
|
13
|
+
m.gsub_file 'config/database.yml', /\z/, "\nculerity_continuousintegration:\n <<: *CUCUMBER"
|
14
|
+
|
15
|
+
m.file "lib/tasks/culerity.rake", "lib/tasks/culerity.rake"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
protected
|
20
|
+
|
21
|
+
def banner
|
22
|
+
"Usage: #{$0} culerity"
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
data/rails_generators/culerity/templates/config/environments/culerity_continuousintegration.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# Settings specified here will take precedence over those in config/environment.rb
|
2
|
+
|
3
|
+
# The production environment is meant for finished, "live" apps.
|
4
|
+
# Code is not reloaded between requests
|
5
|
+
config.cache_classes = true
|
6
|
+
|
7
|
+
# Full error reports are disabled and caching is turned on
|
8
|
+
config.action_controller.consider_all_requests_local = false
|
9
|
+
config.action_controller.perform_caching = true
|
10
|
+
config.action_view.cache_template_loading = true
|
11
|
+
|
12
|
+
# See everything in the log (default is :info)
|
13
|
+
# config.log_level = :debug
|
14
|
+
|
15
|
+
# Use a different logger for distributed setups
|
16
|
+
# config.logger = SyslogLogger.new
|
17
|
+
|
18
|
+
# Use a different cache store in production
|
19
|
+
# config.cache_store = :mem_cache_store
|
20
|
+
|
21
|
+
# Enable serving of images, stylesheets, and javascripts from an asset server
|
22
|
+
# config.action_controller.asset_host = "http://assets.example.com"
|
23
|
+
|
24
|
+
# Disable delivery errors, bad email addresses will be ignored
|
25
|
+
# config.action_mailer.raise_delivery_errors = false
|
26
|
+
|
27
|
+
# Enable threaded mode
|
28
|
+
# config.threadsafe!
|
@@ -0,0 +1,17 @@
|
|
1
|
+
config.cache_classes = false
|
2
|
+
|
3
|
+
# Log error messages when you accidentally call methods on nil.
|
4
|
+
config.whiny_nils = true
|
5
|
+
|
6
|
+
# Show full error reports and disable caching
|
7
|
+
config.action_controller.consider_all_requests_local = true
|
8
|
+
config.action_controller.perform_caching = false
|
9
|
+
config.action_view.cache_template_loading = false
|
10
|
+
|
11
|
+
# Disable request forgery protection in test environment
|
12
|
+
config.action_controller.allow_forgery_protection = false
|
13
|
+
|
14
|
+
# Tell Action Mailer not to deliver emails to the real world.
|
15
|
+
# The :test delivery method accumulates sent emails in the
|
16
|
+
# ActionMailer::Base.deliveries array.
|
17
|
+
config.action_mailer.delivery_method = :test
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'culerity'
|
2
|
+
|
3
|
+
Before do
|
4
|
+
$server ||= Culerity::run_server
|
5
|
+
$browser = Culerity::RemoteBrowserProxy.new $server, {:browser => :firefox}
|
6
|
+
@host = 'http://localhost:3001'
|
7
|
+
end
|
8
|
+
|
9
|
+
at_exit do
|
10
|
+
$browser.exit if $browser
|
11
|
+
$server.close if $server
|
12
|
+
end
|
13
|
+
|
14
|
+
When /I press "(.*)"/ do |button|
|
15
|
+
$browser.button(:text, button).click
|
16
|
+
assert_successful_response
|
17
|
+
end
|
18
|
+
|
19
|
+
When /I follow "(.*)"/ do |link|
|
20
|
+
$browser.link(:text, /#{link}/).click
|
21
|
+
assert_successful_response
|
22
|
+
end
|
23
|
+
|
24
|
+
When /I fill in "(.*)" for "(.*)"/ do |value, field|
|
25
|
+
$browser.text_field(:id, find_label(field).for).set(value)
|
26
|
+
end
|
27
|
+
|
28
|
+
When /I check "(.*)"/ do |field|
|
29
|
+
$browser.check_box(:id, find_label(field).for).set(true)
|
30
|
+
end
|
31
|
+
|
32
|
+
When /^I uncheck "(.*)"$/ do |field|
|
33
|
+
$browser.check_box(:id, find_label(field).for).set(false)
|
34
|
+
end
|
35
|
+
|
36
|
+
When /I select "(.*)" from "(.*)"/ do |value, field|
|
37
|
+
$browser.select_list(:id, find_label(field).for).select value
|
38
|
+
end
|
39
|
+
|
40
|
+
When /I choose "(.*)"/ do |field|
|
41
|
+
$browser.radio(:id, find_label(field).for).set(true)
|
42
|
+
end
|
43
|
+
|
44
|
+
When /I go to (.+)/ do |path|
|
45
|
+
$browser.goto @host + path_to(path)
|
46
|
+
assert_successful_response
|
47
|
+
end
|
48
|
+
|
49
|
+
When /I wait for the AJAX call to finish/ do
|
50
|
+
$browser.wait
|
51
|
+
end
|
52
|
+
|
53
|
+
Then /I should see "(.*)"/ do |text|
|
54
|
+
# if we simply check for the browser.html content we don't find content that has been added dynamically, e.g. after an ajax call
|
55
|
+
div = $browser.div(:text, /#{text}/)
|
56
|
+
begin
|
57
|
+
div.html
|
58
|
+
rescue
|
59
|
+
#puts $browser.html
|
60
|
+
raise("div with '#{text}' not found")
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
Then /I should not see "(.*)"/ do |text|
|
65
|
+
div = $browser.div(:text, /#{text}/).html rescue nil
|
66
|
+
div.should be_nil
|
67
|
+
end
|
68
|
+
|
69
|
+
def find_label(text)
|
70
|
+
$browser.label :text, text
|
71
|
+
end
|
72
|
+
|
73
|
+
def assert_successful_response
|
74
|
+
status = $browser.page.web_response.status_code
|
75
|
+
if(status == 302 || status == 301)
|
76
|
+
location = $browser.page.web_response.get_response_header_value('Location')
|
77
|
+
puts "Being redirected to #{location}"
|
78
|
+
$browser.goto location
|
79
|
+
assert_successful_response
|
80
|
+
elsif status != 200
|
81
|
+
tmp = Tempfile.new 'culerity_results'
|
82
|
+
tmp << $browser.html
|
83
|
+
tmp.close
|
84
|
+
`open -a /Applications/Safari.app #{tmp.path}`
|
85
|
+
raise "Brower returned Response Code #{$browser.page.web_response.status_code}"
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
namespace 'culerity' do
|
2
|
+
namespace 'rails' do
|
3
|
+
desc "Starts a rails server for cucumber/culerity tests"
|
4
|
+
task :start => :environment do
|
5
|
+
environment = 'culerity_development'
|
6
|
+
pid_file = RAILS_ROOT + "/tmp/culerity_rails_server.pid"
|
7
|
+
if File.exists?(pid_file)
|
8
|
+
puts "culerity rails server already running; if not, delete tmp/culerity_rails_server.pid and try again"
|
9
|
+
exit 1
|
10
|
+
end
|
11
|
+
rails_server = IO.popen("script/server -e #{environment} -p 3001", 'r+')
|
12
|
+
File.open(pid_file, "w") { |file| file << rails_server.pid }
|
13
|
+
end
|
14
|
+
|
15
|
+
desc "Stops the running rails server for cucumber/culerity tests"
|
16
|
+
task :stop => :environment do
|
17
|
+
pid_file = RAILS_ROOT + "/tmp/culerity_rails_server.pid"
|
18
|
+
if File.exists?(pid_file)
|
19
|
+
pid = File.read(pid_file).to_i
|
20
|
+
Process.kill(6, pid)
|
21
|
+
File.delete(pid_file)
|
22
|
+
else
|
23
|
+
puts "No culerity rails server running. Doing nothing."
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/script/console
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# File: script/console
|
3
|
+
irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
|
4
|
+
|
5
|
+
libs = " -r irb/completion"
|
6
|
+
# Perhaps use a console_lib to store any extra methods I may want available in the cosole
|
7
|
+
# libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
|
8
|
+
libs << " -r #{File.dirname(__FILE__) + '/../lib/culerity.rb'}"
|
9
|
+
puts "Loading culerity gem"
|
10
|
+
exec "#{irb} #{libs} --simple-prompt"
|
data/script/destroy
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'rubigen'
|
6
|
+
rescue LoadError
|
7
|
+
require 'rubygems'
|
8
|
+
require 'rubigen'
|
9
|
+
end
|
10
|
+
require 'rubigen/scripts/destroy'
|
11
|
+
|
12
|
+
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
|
13
|
+
RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
|
14
|
+
RubiGen::Scripts::Destroy.new.run(ARGV)
|
data/script/generate
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'rubigen'
|
6
|
+
rescue LoadError
|
7
|
+
require 'rubygems'
|
8
|
+
require 'rubigen'
|
9
|
+
end
|
10
|
+
require 'rubigen/scripts/generate'
|
11
|
+
|
12
|
+
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
|
13
|
+
RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
|
14
|
+
RubiGen::Scripts::Generate.new.run(ARGV)
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe Culerity::CelerityServer do
|
4
|
+
before(:each) do
|
5
|
+
@browser = stub 'browser'
|
6
|
+
Celerity::Browser.stub!(:new).and_return(@browser)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should pass the method call to the selerity browser" do
|
10
|
+
@browser.should_receive(:goto).with('/homepage')
|
11
|
+
_in = stub 'in'
|
12
|
+
_in.stub!(:gets).and_return("[\"browser\", \"goto\", \"/homepage\"]\n", "[\"_exit_\"]\n")
|
13
|
+
_out = stub 'out', :<< => nil
|
14
|
+
Culerity::CelerityServer.new(_in, _out)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should send back the return value of the call" do
|
18
|
+
@browser.stub!(:goto).and_return(true)
|
19
|
+
_in = stub 'in'
|
20
|
+
_in.stub!(:gets).and_return("[\"browser\", \"goto\", \"/homepage\"]\n", "[\"_exit_\"]\n")
|
21
|
+
_out = stub 'out'
|
22
|
+
_out.should_receive(:<<).with("[:return, true]\n")
|
23
|
+
Culerity::CelerityServer.new(_in, _out)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should ignore empty inputs" do
|
27
|
+
_in = stub 'in'
|
28
|
+
_in.stub!(:gets).and_return("\n", "[\"_exit_\"]\n")
|
29
|
+
_out = stub 'out'
|
30
|
+
_out.should_not_receive(:<<)
|
31
|
+
Culerity::CelerityServer.new(_in, _out)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should send back a proxy if the return value is not a string, number, nil or boolean" do
|
35
|
+
@browser.stub!(:goto).and_return(stub('123', :object_id => 456))
|
36
|
+
_in = stub 'in'
|
37
|
+
_in.stub!(:gets).and_return("[\"browser\", \"goto\", \"/homepage\"]\n", "[\"_exit_\"]\n")
|
38
|
+
_out = stub 'out'
|
39
|
+
_out.should_receive(:<<).with("[:return, Culerity::RemoteObjectProxy.new(456, @io)]\n")
|
40
|
+
Culerity::CelerityServer.new(_in, _out)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should pass the method call to a proxy" do
|
44
|
+
proxy = stub('123', :object_id => 456)
|
45
|
+
@browser.stub!(:goto).and_return(proxy)
|
46
|
+
_in = stub 'in'
|
47
|
+
_in.stub!(:gets).and_return("[\"browser\", \"goto\", \"/homepage\"]\n", "[456, \"goto_2\", \"1\"]", "[\"_exit_\"]\n")
|
48
|
+
_out = stub 'out', :<< => nil
|
49
|
+
proxy.should_receive(:goto_2).with('1')
|
50
|
+
Culerity::CelerityServer.new(_in, _out)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should configure the browser" do
|
54
|
+
_in = stub 'in'
|
55
|
+
_in.stub!(:gets).and_return('["celerity", "configure_browser", {:browser=>:firefox}]' + "\n", '["browser", "goto", "/homepage"]' + "\n", "[\"_exit_\"]\n")
|
56
|
+
Celerity::Browser.should_receive(:new).with(:browser => :firefox)
|
57
|
+
Culerity::CelerityServer.new(_in, stub.as_null_object)
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should pass multiple method calls" do
|
61
|
+
@browser.should_receive(:goto).with('/homepage')
|
62
|
+
@browser.should_receive(:goto).with('/page2')
|
63
|
+
_in = stub 'in'
|
64
|
+
_in.stub!(:gets).and_return("[\"browser\", \"goto\", \"/homepage\"]\n", "[\"browser\", \"goto\", \"/page2\"]\n", "[\"_exit_\"]\n")
|
65
|
+
_out = stub 'out', :<< => nil
|
66
|
+
Culerity::CelerityServer.new(_in, _out)
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should return an exception" do
|
70
|
+
@browser.stub!(:goto).and_raise(RuntimeError.new('test exception with "quotes"'))
|
71
|
+
_in = stub 'in'
|
72
|
+
_in.stub!(:gets).and_return("[\"browser\", \"goto\", \"/homepage\"]\n", "[\"_exit_\"]\n")
|
73
|
+
_out = stub 'out'
|
74
|
+
_out.should_receive(:<<).with(/^\[:exception, \"RuntimeError\", \"test exception with \\\"quotes\\\"\", \[.*\]\]\n$/)
|
75
|
+
Culerity::CelerityServer.new(_in, _out)
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe Culerity::RemoteBrowserProxy do
|
4
|
+
it "should send the serialized method call to the output" do
|
5
|
+
io = stub 'io', :gets => '[return, :okay]'
|
6
|
+
io.should_receive(:<<).with("[\"browser\", \"goto\", \"/homepage\"]\n")
|
7
|
+
proxy = Culerity::RemoteBrowserProxy.new io
|
8
|
+
proxy.goto '/homepage'
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should return the deserialized return value" do
|
12
|
+
io = stub 'io', :gets => "[:return, :okay]\n", :<< => nil
|
13
|
+
proxy = Culerity::RemoteBrowserProxy.new io
|
14
|
+
proxy.goto.should == :okay
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should send the brower options to the remote server" do
|
18
|
+
io = stub 'io', :gets => "[:return, :okay]"
|
19
|
+
io.should_receive(:<<).with('["celerity", "configure_browser", {:browser=>:firefox}]' + "\n")
|
20
|
+
proxy = Culerity::RemoteBrowserProxy.new io, {:browser => :firefox}
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should timeout if wait_until takes too long" do
|
24
|
+
proxy = Culerity::RemoteBrowserProxy.new nil
|
25
|
+
lambda {
|
26
|
+
proxy.wait_until(0.1) { false }
|
27
|
+
}.should raise_error(Timeout::Error)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should return successfully when wait_until returns true" do
|
31
|
+
proxy = Culerity::RemoteBrowserProxy.new nil
|
32
|
+
proxy.wait_until(0.1) { true }.should == true
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should timeout if wait_while takes too long" do
|
36
|
+
proxy = Culerity::RemoteBrowserProxy.new nil
|
37
|
+
lambda {
|
38
|
+
proxy.wait_while(0.1) { true }
|
39
|
+
}.should raise_error(Timeout::Error)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should return successfully when wait_while returns !true" do
|
43
|
+
proxy = Culerity::RemoteBrowserProxy.new nil
|
44
|
+
proxy.wait_while(0.1) { false }.should == true
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should accept all javascript confirmation dialogs" do
|
48
|
+
proxy = Culerity::RemoteBrowserProxy.new nil
|
49
|
+
|
50
|
+
proxy.should_receive(:send_remote).with(:add_listener, :confirm).and_return(true)
|
51
|
+
proxy.should_receive(:send_remote).with(:goto, "http://example.com").and_return(true)
|
52
|
+
proxy.should_receive(:send_remote).with(:remove_listener, :confirm).and_return(true)
|
53
|
+
|
54
|
+
proxy.confirm(true) do
|
55
|
+
proxy.goto "http://example.com"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe Culerity::RemoteObjectProxy do
|
4
|
+
describe "block_to_string method" do
|
5
|
+
it "should return block result when result is lambda string" do
|
6
|
+
proxy = Culerity::RemoteObjectProxy.new nil, nil
|
7
|
+
block = lambda { "lambda { true}" }
|
8
|
+
proxy.send(:block_to_string, &block).should == "lambda { true}"
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should return lambda string when block result isn't a lambda string" do
|
12
|
+
proxy = Culerity::RemoteObjectProxy.new nil, nil
|
13
|
+
[true, false, "blah", 5].each do |var|
|
14
|
+
block = lambda { var }
|
15
|
+
proxy.send(:block_to_string, &block).should == "lambda { #{var} }"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should send the serialized method call to the output" do
|
21
|
+
io = stub 'io', :gets => '[:return]'
|
22
|
+
io.should_receive(:<<).with(%Q{[345, "goto", "/homepage"]\n})
|
23
|
+
proxy = Culerity::RemoteObjectProxy.new 345, io
|
24
|
+
proxy.goto '/homepage'
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should send the serialized method call with argument plus block to the output" do
|
28
|
+
io = stub 'io', :gets => "[:return]"
|
29
|
+
io.should_receive(:<<).with(%Q{[345, "method", true, lambda { true }]\n})
|
30
|
+
proxy = Culerity::RemoteObjectProxy.new 345, io
|
31
|
+
|
32
|
+
proxy.send_remote(:method, true) { "lambda { true }" }
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should send the serialized method call without argument plus block to the output" do
|
36
|
+
io = stub 'io', :gets => "[:return]"
|
37
|
+
io.should_receive(:<<).with(%Q{[345, "method", lambda { true }]\n})
|
38
|
+
proxy = Culerity::RemoteObjectProxy.new 345, io
|
39
|
+
|
40
|
+
proxy.send_remote(:method) { "lambda { true }" }
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should return the deserialized return value" do
|
44
|
+
io = stub 'io', :gets => "[:return, :okay]\n", :<< => nil
|
45
|
+
proxy = Culerity::RemoteObjectProxy.new 345, io
|
46
|
+
proxy.goto.should == :okay
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should raise the received exception" do
|
50
|
+
io = stub 'io', :gets => %Q{[:exception, "RuntimeError", "test exception", []]}, :<< => nil
|
51
|
+
proxy = Culerity::RemoteObjectProxy.new 345, io
|
52
|
+
lambda {
|
53
|
+
proxy.goto '/home'
|
54
|
+
}.should raise_error(Culerity::CulerityException)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should send exit" do
|
58
|
+
io = stub 'io', :gets => '[:return]'
|
59
|
+
io.should_receive(:<<).with('["_exit_"]')
|
60
|
+
proxy = Culerity::RemoteObjectProxy.new 345, io
|
61
|
+
proxy.exit
|
62
|
+
end
|
63
|
+
end
|