rails-carrot 1.0.0

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/Manifest ADDED
@@ -0,0 +1,9 @@
1
+ Manifest
2
+ README
3
+ Rakefile
4
+ carrot.gemspec
5
+ lib/carrot.rb
6
+ lib/carrot/extend_server.rb
7
+ lib/carrot/rails.rb
8
+ lib/carrot/server.rb
9
+ lib/carrot/util/timeout.rb
data/README ADDED
@@ -0,0 +1,81 @@
1
+ You can use carrot with celerity, or another driver.
2
+
3
+ 1. gem 'carrot'
4
+
5
+ 2. add a celerity_helper
6
+
7
+ 3. Add some code in celerity_helper
8
+ require 'database_cleaner'
9
+ require 'celerity'
10
+ require 'carrot'
11
+
12
+ ENV["RAILS_ENV"] = 'celerity' # You can change it with your enviroment
13
+ require File.expand_path("../../config/environment", __FILE__)
14
+ require 'rspec/rails'
15
+
16
+
17
+
18
+ 4. Three test styles
19
+ a) Remote
20
+ Carrot.configure do |config|
21
+ config.run_server = false
22
+ config.app_host = "www.google.com"
23
+ end
24
+ Carrot.register_driver(Celerity::Browser.new)
25
+
26
+ b) Local
27
+ Carrot.configure do |config|
28
+ config.run_server = true
29
+ end
30
+ Carrot.register_driver(Celerity::Browser.new)
31
+ Carrot.boot
32
+
33
+ c) Local, server with external ruby
34
+
35
+ Carrot.configure do |config|
36
+ config.run_server = true
37
+ config.external_ruby = true
38
+ config.rails_command = "~/.rvm/gems/ruby-1.9.2-p0/bin/rails s -e celerity -p 3001"
39
+ config.project_path = "#{Rails.root}"
40
+ config.server_port = 3001
41
+ # config.server_debug = true
42
+ end
43
+ Carrot.register_driver(Celerity::Browser.new)
44
+ Carrot.boot
45
+
46
+ RSpec.configure do |config|
47
+ DatabaseCleaner.strategy = :truncation
48
+
49
+ config.before :each do
50
+ @browser = Carrot.driver # get native driver
51
+ DatabaseCleaner.clean
52
+ end
53
+
54
+ config.after :all do
55
+ Carrot.shutdown # shutdown server
56
+ DatabaseCleaner.clean
57
+ end
58
+
59
+ config.use_transactional_fixtures = false
60
+
61
+ end
62
+
63
+ 5 Test
64
+ a) get url
65
+ Carrot.url(path)
66
+ eg:
67
+ Carrot.url('/') => http://host/
68
+ Carrot.url('/hello') => http://host/hello
69
+
70
+ b) get native browser driver
71
+ Carrot.driver
72
+
73
+ 6 FAQ
74
+ a) Does Carrot support server with external ruby?
75
+ Yes, but it just supports jruby run rspec and run server using external ruby. I use jruby to create native java process to run server using external ruby.
76
+
77
+ If you want to use ruby to run rspec and run server using external ruby, you can create a new server class to support it or wait for my upgrade.
78
+
79
+
80
+
81
+
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'echoe'
4
+
5
+ Echoe.new('rails-carrot', '1.0.0') do |p|
6
+ p.description = "Carrot can make QA test easy with any integration test gem."
7
+ p.url = "http://github.com/sloanwu/carrot.git"
8
+ p.author = "Sloan Wu"
9
+ p.email = "sloanwu@gmail.com"
10
+ p.ignore_pattern = ["tmp/*", "script/*"]
11
+ p.development_dependencies = []
12
+ end
data/carrot.gemspec ADDED
@@ -0,0 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{carrot}
5
+ s.version = "1.0.0"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Sloan Wu"]
9
+ s.date = %q{2010-11-02}
10
+ s.description = %q{Carrot can make QA test easy with any integration test gem.}
11
+ s.email = %q{sloanwu@gmail.com}
12
+ s.extra_rdoc_files = ["lib/carrot.rb", "lib/carrot/extend_server.rb", "lib/carrot/rails.rb", "lib/carrot/server.rb", "lib/carrot/util/timeout.rb"]
13
+ s.files = ["Manifest", "Rakefile", "carrot.gemspec", "lib/carrot.rb", "lib/carrot/extend_server.rb", "lib/carrot/rails.rb", "lib/carrot/server.rb", "lib/carrot/util/timeout.rb"]
14
+ s.homepage = %q{http://github.com/sloanwu/carrot.git}
15
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Carrot", "--main", "README"]
16
+ s.require_paths = ["lib"]
17
+ s.rubyforge_project = %q{carrot}
18
+ s.rubygems_version = %q{1.3.7}
19
+ s.summary = %q{Carrot can make QA test easy with any integration test gem.}
20
+
21
+ if s.respond_to? :specification_version then
22
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
23
+ s.specification_version = 3
24
+
25
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
26
+ else
27
+ end
28
+ else
29
+ end
30
+ end
@@ -0,0 +1,59 @@
1
+ require "java"
2
+ require 'carrot/util/timeout'
3
+ require 'uri'
4
+ require 'net/http'
5
+ require 'rack'
6
+ import java.lang.Runtime
7
+ import java.io.InputStreamReader
8
+ import java.io.BufferedReader
9
+
10
+ module Carrot
11
+ class ExtendServer
12
+ attr_accessor :server_process, :shutdown_process
13
+
14
+ def run()
15
+ Thread.new do
16
+ command = ["/bin/bash","-c", "cd #{Carrot.project_path} ; #{Carrot.rails_command}"].to_java(java.lang.String)
17
+ begin
18
+ @server_process = Runtime.getRuntime().exec(command);
19
+ if Carrot.server_debug
20
+ buf = BufferedReader.new(InputStreamReader.new(@server_process.get_input_stream))
21
+ while line = buf.readLine()
22
+ puts line
23
+ end
24
+ end
25
+ @server_process.wait_for
26
+ rescue Exception => e
27
+ puts e
28
+ end
29
+
30
+ end
31
+ Carrot.timeout(60) { if responsive? then true else sleep(0.5) and false end }
32
+ end
33
+
34
+ def shutdown
35
+ Thread.new do
36
+ command = ["/bin/bash","-c", "cd #{Carrot.project_path} ; kill `cat #{Carrot.project_path}/tmp/pids/server.pid`"].to_java(java.lang.String)
37
+ begin
38
+ @shutdown_process = Runtime.getRuntime().exec(command);
39
+ @shutdown_process.wait_for
40
+ @shutdown_process.destroy
41
+ rescue Exception => e
42
+ puts e
43
+ end
44
+ end
45
+ end
46
+
47
+ def responsive?
48
+ host = "127.0.0.1"
49
+ res = Net::HTTP.start(host, Carrot.server_port) { |http| http.get('/__identify__') }
50
+
51
+ unless res.nil?
52
+ return true
53
+ end
54
+ rescue Errno::ECONNREFUSED, Errno::EBADF
55
+ return false
56
+ end
57
+
58
+ end
59
+ end
@@ -0,0 +1,15 @@
1
+ require 'carrot'
2
+
3
+ Carrot.app = Rack::Builder.new do
4
+ map "/" do
5
+ if Rails.version.to_f >= 3.0
6
+ run Rails.application
7
+ else # Rails 2
8
+ use Rails::Rack::Static
9
+ run ActionController::Dispatcher.new
10
+ end
11
+ end
12
+ end.to_app
13
+
14
+ Carrot.asset_root = Rails.root.join('public')
15
+
@@ -0,0 +1,96 @@
1
+ require 'uri'
2
+ require 'net/http'
3
+ require 'rack'
4
+ require 'carrot/util/timeout'
5
+ require 'carrot/rails'
6
+
7
+ module Carrot
8
+ class Server
9
+ class Identify
10
+ def initialize(app)
11
+ @app = app
12
+ end
13
+
14
+ def call(env)
15
+ if env["PATH_INFO"] == "/__identify__"
16
+ [200, {}, @app.object_id.to_s]
17
+ else
18
+ @app.call(env)
19
+ end
20
+ end
21
+ end
22
+
23
+ class << self
24
+ def ports
25
+ @ports ||= {}
26
+ end
27
+ end
28
+
29
+ attr_reader :app, :port
30
+
31
+ def initialize(app)
32
+ @app = app
33
+ end
34
+
35
+ def host
36
+ "127.0.0.1"
37
+ end
38
+
39
+ def url(path)
40
+ if path =~ /^http/
41
+ path
42
+ else
43
+ (Carrot.app_host || "http://#{host}:#{Carrot.server_port || port}") + path.to_s
44
+ end
45
+ end
46
+
47
+ def responsive?
48
+ res = Net::HTTP.start(host, @port) { |http| http.get('/__identify__') }
49
+
50
+ if res.is_a?(Net::HTTPSuccess) or res.is_a?(Net::HTTPRedirection)
51
+ return res.body == @app.object_id.to_s
52
+ end
53
+ rescue Errno::ECONNREFUSED, Errno::EBADF
54
+ return false
55
+ end
56
+
57
+ def boot
58
+ if Carrot.external_ruby
59
+ require 'carrot/extend_server'
60
+ Carrot.external_server = ExtendServer.new
61
+ Carrot.external_server.run
62
+ elsif @app
63
+ @port = Carrot::Server.ports[@app.object_id]
64
+
65
+ if not @port or not responsive?
66
+ @port = Carrot.server_port || find_available_port
67
+ Carrot::Server.ports[@app.object_id] = @port
68
+
69
+ Thread.new do
70
+ begin
71
+ require 'rack/handler/thin'
72
+ Thin::Logging.silent = true
73
+ Rack::Handler::Thin.run(Identify.new(@app), :Port => @port)
74
+ rescue LoadError
75
+ require 'rack/handler/webrick'
76
+ Rack::Handler::WEBrick.run(Identify.new(@app), :Port => @port, :AccessLog => [], :Logger => WEBrick::Log::new(nil, 0))
77
+ end
78
+ end
79
+
80
+ Carrot.timeout(10) { if responsive? then true else sleep(0.5) and false end }
81
+ end
82
+ end
83
+ end
84
+
85
+
86
+ private
87
+
88
+ def find_available_port
89
+ server = TCPServer.new('127.0.0.1', 0)
90
+ server.addr[1]
91
+ ensure
92
+ server.close if server
93
+ end
94
+
95
+ end
96
+ end
@@ -0,0 +1,27 @@
1
+ module Carrot
2
+ class << self
3
+
4
+ ##
5
+ # Provides timeout similar to standard library Timeout, but avoids threads
6
+ #
7
+ def timeout(seconds = 1, driver = nil, &block)
8
+ start_time = Time.now
9
+
10
+ result = nil
11
+
12
+ until result
13
+ return result if result = yield
14
+
15
+ delay = seconds - (Time.now - start_time)
16
+ if delay <= 0
17
+ raise TimeoutError
18
+ end
19
+
20
+ driver && driver.wait_until(delay)
21
+
22
+ sleep(0.05)
23
+ end
24
+ end
25
+
26
+ end
27
+ end
data/lib/carrot.rb ADDED
@@ -0,0 +1,75 @@
1
+ require 'timeout'
2
+ require 'nokogiri'
3
+ require 'xpath'
4
+
5
+ module Carrot
6
+ class CarrotError < StandardError; end
7
+ class DriverNotFoundError < CarrotError; end
8
+ class ElementNotFound < CarrotError; end
9
+ class UnselectNotAllowed < CarrotError; end
10
+ class NotSupportedByDriverError < CarrotError; end
11
+ class TimeoutError < CarrotError; end
12
+ class LocateHiddenElementError < CarrotError; end
13
+ class InfiniteRedirectError < TimeoutError; end
14
+
15
+ class << self
16
+ attr_accessor :asset_root, :app_host, :run_server, :default_host
17
+ attr_accessor :server_port
18
+ attr_accessor :driver
19
+ attr_accessor :app
20
+ attr_accessor :external_ruby, :rails_command, :project_path
21
+ attr_accessor :external_server, :server_debug
22
+
23
+ ##
24
+ #
25
+ # Configure Carrot to suit your needs.
26
+ #
27
+ # Carrot.configure do |config|
28
+ # config.run_server = false
29
+ # config.app_host = 'http://www.google.com'
30
+ # end
31
+ #
32
+ # === Configurable options
33
+ #
34
+ # [asset_root = String] Where static assets are located, used by save_and_open_page
35
+ # [app_host = String] The default host to use when giving a relative URL to visit
36
+ # [run_server = Boolean] Whether to start a Rack server for the given Rack app (Default: true)
37
+ # [default_selector = :css/:xpath] Methods which take a selector use the given type by default (Default: CSS)
38
+ # [default_wait_time = Integer] The number of seconds to wait for asynchronous processes to finish (Default: 2)
39
+ # [ignore_hidden_elements = Boolean] Whether to ignore hidden elements on the page (Default: false)
40
+ #
41
+
42
+ def configure
43
+ yield self
44
+ end
45
+
46
+ def url(path)
47
+ @rack_server.url(path)
48
+ end
49
+
50
+ def register_driver(obj)
51
+ @driver = obj
52
+ end
53
+
54
+ def boot
55
+ @rack_server = Carrot::Server.new(@app)
56
+ @rack_server.boot if Carrot.run_server
57
+ end
58
+
59
+ def shutdown
60
+ @external_server.shutdown if @external_server
61
+ end
62
+
63
+ end
64
+
65
+ autoload :Server, 'carrot/server'
66
+
67
+ end
68
+
69
+ Carrot.configure do |config|
70
+ config.run_server = true
71
+ config.external_ruby = false
72
+ config.server_debug = false
73
+ config.server_port = 3000
74
+ end
75
+
@@ -0,0 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{rails-carrot}
5
+ s.version = "1.0.0"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Sloan Wu"]
9
+ s.date = %q{2010-11-02}
10
+ s.description = %q{Carrot can make QA test easy with any integration test gem.}
11
+ s.email = %q{sloanwu@gmail.com}
12
+ s.extra_rdoc_files = ["README", "lib/carrot.rb", "lib/carrot/extend_server.rb", "lib/carrot/rails.rb", "lib/carrot/server.rb", "lib/carrot/util/timeout.rb"]
13
+ s.files = ["Manifest", "README", "Rakefile", "carrot.gemspec", "lib/carrot.rb", "lib/carrot/extend_server.rb", "lib/carrot/rails.rb", "lib/carrot/server.rb", "lib/carrot/util/timeout.rb", "rails-carrot.gemspec"]
14
+ s.homepage = %q{http://github.com/sloanwu/carrot.git}
15
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Rails-carrot", "--main", "README"]
16
+ s.require_paths = ["lib"]
17
+ s.rubyforge_project = %q{rails-carrot}
18
+ s.rubygems_version = %q{1.3.7}
19
+ s.summary = %q{Carrot can make QA test easy with any integration test gem.}
20
+
21
+ if s.respond_to? :specification_version then
22
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
23
+ s.specification_version = 3
24
+
25
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
26
+ else
27
+ end
28
+ else
29
+ end
30
+ end
metadata ADDED
@@ -0,0 +1,84 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rails-carrot
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 1
7
+ - 0
8
+ - 0
9
+ version: 1.0.0
10
+ platform: ruby
11
+ authors:
12
+ - Sloan Wu
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-11-02 00:00:00 +08:00
18
+ default_executable:
19
+ dependencies: []
20
+
21
+ description: Carrot can make QA test easy with any integration test gem.
22
+ email: sloanwu@gmail.com
23
+ executables: []
24
+
25
+ extensions: []
26
+
27
+ extra_rdoc_files:
28
+ - README
29
+ - lib/carrot.rb
30
+ - lib/carrot/extend_server.rb
31
+ - lib/carrot/rails.rb
32
+ - lib/carrot/server.rb
33
+ - lib/carrot/util/timeout.rb
34
+ files:
35
+ - Manifest
36
+ - README
37
+ - Rakefile
38
+ - carrot.gemspec
39
+ - lib/carrot.rb
40
+ - lib/carrot/extend_server.rb
41
+ - lib/carrot/rails.rb
42
+ - lib/carrot/server.rb
43
+ - lib/carrot/util/timeout.rb
44
+ - rails-carrot.gemspec
45
+ has_rdoc: true
46
+ homepage: http://github.com/sloanwu/carrot.git
47
+ licenses: []
48
+
49
+ post_install_message:
50
+ rdoc_options:
51
+ - --line-numbers
52
+ - --inline-source
53
+ - --title
54
+ - Rails-carrot
55
+ - --main
56
+ - README
57
+ require_paths:
58
+ - lib
59
+ required_ruby_version: !ruby/object:Gem::Requirement
60
+ none: false
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ segments:
65
+ - 0
66
+ version: "0"
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ segments:
73
+ - 1
74
+ - 2
75
+ version: "1.2"
76
+ requirements: []
77
+
78
+ rubyforge_project: rails-carrot
79
+ rubygems_version: 1.3.7
80
+ signing_key:
81
+ specification_version: 3
82
+ summary: Carrot can make QA test easy with any integration test gem.
83
+ test_files: []
84
+