langalex-culerity 0.1.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/README.textile ADDED
@@ -0,0 +1,86 @@
1
+ h2. Introduction
2
+
3
+ Culerity integrates Cucumber and Celerity in order to test your application's full stack.
4
+
5
+ Culerity lets you:
6
+ * run Celerity from within Cucumber which allows you to test the full stack of your Rails (or other web) application from Database to in browser JavaScript
7
+ * run your application in any Ruby (like MRI 1.8.6) while Celerity runs in JRuby so you can still use gems/plugins that would not work with JRuby
8
+ * reuse existing Webrat-Style step definitions
9
+
10
+ h2. Getting Started
11
+
12
+ The following guide is written for a Rails application (tested with 2.2.2) but Culerity should work with any other Web Framework that is supported by Cucumber.
13
+
14
+ First download JRuby and unpack it to some location, for example $HOME/jruby. Make sure that the jruby executable is in your path. You can do this by either setting your PATH accordingly...
15
+
16
+ export PATH=$HOME/jruby/bin:$PATH
17
+
18
+ ... or by creating a symlink from your bin directory:
19
+
20
+ ln -s $HOME/jruby/bin/jruby /usr/bin/jruby
21
+
22
+ Next install the celerity gem for JRuby:
23
+
24
+ jruby -S gem install celerity
25
+
26
+ Now (assuming you have a Rails application set up already) install Culerity as a Rails Plugin:
27
+
28
+ cd RAILS_ROOT
29
+ git clone git://github.com/langalex/culerity.git
30
+
31
+ or as a gem: (definitely preferred)
32
+
33
+ gem install langalex-culerity
34
+
35
+ And add the culerity gem to your environment.rb:
36
+
37
+ config.gem 'langalex-culerity', :lib => 'culerity', :version => '0.1', :source => 'http://gems.github.com'
38
+
39
+ Run the RSpec, Cucumber and Culerity generators:
40
+
41
+ cd RAILS_ROOT
42
+ script/generate rspec
43
+ script/generate cucumber
44
+ script/generate culerity
45
+
46
+ This creates the features folder and a file common_celerity.rb into your application. This file contains step definitions for basic interactions like clicking links or filling out forms.
47
+
48
+ After you have written a first feature you can run it just like you would run a standard cucumber feature. The only difference is that you have to start a web server (e.g. mongrel) with the test environment enabled beforehand.
49
+
50
+ NOTE: For now this server has to run on port 80 because of some problem with redirects losing the port information.
51
+
52
+
53
+ sudo script/server -p 80 -e test
54
+ cucumber features/my_feature.feature
55
+
56
+ h2. How does it work
57
+
58
+ While Celerity is based on Java and requires JRuby to run, with Culerity you can still run your tests in your own Ruby Environment. When you run your features a separate JRuby process for Celerity is spawned and all Celerity Commands are redirected to this other process.
59
+
60
+ h2. Troubleshooting
61
+
62
+ I get a broken pipe error:
63
+ * make sure JRuby is installed and in your path: running _jruby -v_ should not produce an error
64
+
65
+ I get _Connection Refused_ errors
66
+ * make sure you have started a server in the test environment that runs on port 80
67
+
68
+
69
+ h2. Links to Celerity documentation
70
+
71
+ * "How to select elements":http://celerity.rubyforge.org/yard/Celerity/Container.html
72
+ * "FAQ":http://celerity.rubyforge.org/wiki/wiki.pl
73
+ * "Tutorial":http://celerity.rubyforge.org/wiki/wiki.pl?GettingStarted
74
+ * "API docs":http://celerity.rubyforge.org/yard/
75
+
76
+ h2. Links
77
+
78
+ * "cucumber":http://github.com/aslakhellesoy/cucumber/wikis
79
+ * "celerity":http://celerity.rubyforge.org
80
+ * "jruby":http://jruby.codehaus.org
81
+ * "rspec":http://rspec.info
82
+ * "htmlunit":http://htmlunit.sourceforge.net/
83
+
84
+ h2. Contact
85
+
86
+ Written 2009 by Alexander Lang, contact alex[at]upstream-berlin.com or http://github.com/langalex, released under the MIT license
data/VERSION.yml ADDED
@@ -0,0 +1,4 @@
1
+ ---
2
+ :major: 0
3
+ :minor: 1
4
+ :patch: 1
@@ -0,0 +1,20 @@
1
+ class CulerityGenerator < Rails::Generator::Base
2
+
3
+ def initialize(runtime_args, runtime_options = {})
4
+ Dir.mkdir('features/step_definitions') unless File.directory?('features/step_definitions')
5
+ super
6
+ end
7
+
8
+ def manifest
9
+ record do |m|
10
+ m.template 'common_celerity.rb', 'features/step_definitions/common_celerity.rb'
11
+ end
12
+ end
13
+
14
+ protected
15
+
16
+ def banner
17
+ "Usage: #{$0} culerity"
18
+ end
19
+
20
+ end
@@ -0,0 +1,70 @@
1
+ Before do
2
+ @server = Culerity::run_server
3
+ @browser = Culerity::RemoteBrowserProxy.new @server
4
+ @host = 'http://localhost'
5
+ end
6
+
7
+ After do
8
+ @browser.close
9
+ @browser.exit
10
+ @server.close
11
+ end
12
+
13
+ When /I press "(.*)"/ do |button|
14
+ @browser.button(:text, button).click
15
+ assert_successful_response
16
+ end
17
+
18
+ When /I follow "(.*)"/ do |link|
19
+ @browser.link(:text, /#{link}/).click
20
+ assert_successful_response
21
+ end
22
+
23
+ When /I fill in "(.*)" for "(.*)"/ do |value, field|
24
+ @browser.text_field(:id, find_label(field).for).set(value)
25
+ end
26
+
27
+ When /I check "(.*)"/ do |field|
28
+ @browser.check_box(:id, find_label(field).for).set(true)
29
+ end
30
+
31
+ When /^I uncheck "(.*)"$/ do |field|
32
+ @browser.check_box(:id, find_label(field).for).set(false)
33
+ end
34
+
35
+ When /I choose "(.*)"/ do |field|
36
+ @browser.radio(:id, find_label(field).for).set(true)
37
+ end
38
+
39
+ When /I go to "(.*)"/ do |path|
40
+ @browser.goto @host + path
41
+ assert_successful_response
42
+ end
43
+
44
+ When "I wait for the AJAX call to finish" do
45
+ @browser.page.getEnclosingWindow().getThreadManager().joinAll(10000)
46
+ end
47
+
48
+
49
+ Then /I should see "(.*)"/ do |text|
50
+ @browser.html.should =~ /#{text}/m
51
+ end
52
+
53
+ Then /I should not see "(.*)"/ do |text|
54
+ @browser.html.should_not =~ /#{text}/m
55
+ end
56
+
57
+ def find_label(text)
58
+ @browser.label :text, text
59
+ end
60
+
61
+ def assert_successful_response
62
+ status = @browser.page.web_response.status_code
63
+ if(status == 302 || status == 301)
64
+ location = @browser.page.web_response.get_response_header_value('Location')
65
+ puts "Being redirected to #{location}"
66
+ @browser.goto location
67
+ elsif status != 200
68
+ raise "Brower returned Response Code #{@browser.page.web_response.status_code}"
69
+ end
70
+ end
@@ -0,0 +1,46 @@
1
+ require 'rubygems'
2
+ require 'celerity'
3
+
4
+
5
+ module Culerity
6
+ class CelerityServer
7
+
8
+ def initialize(_in, _out)
9
+ @browser = Celerity::Browser.new
10
+ @proxies = {}
11
+
12
+ while(true)
13
+ call = eval _in.gets.to_s.strip
14
+ return if call == ["_exit_"]
15
+ unless call.nil?
16
+ begin
17
+ result = target(call.first).send call[1], *call[2..-1]
18
+ _out << "[:return, #{proxify result}]\n"
19
+ rescue => e
20
+ _out << "[:exception, \"#{e.class}\", #{e.message.inspect}]\n"
21
+ end
22
+ end
23
+ end
24
+
25
+ end
26
+
27
+ private
28
+
29
+ def target(object_id)
30
+ if object_id == 'browser'
31
+ @browser
32
+ else
33
+ @proxies[object_id]
34
+ end
35
+ end
36
+
37
+ def proxify(result)
38
+ if [String, TrueClass, FalseClass, Fixnum, Float, NilClass].include?(result.class)
39
+ result.inspect
40
+ else
41
+ @proxies[result.object_id] = result
42
+ "Culerity::RemoteObjectProxy.new(#{result.object_id}, @io)"
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,15 @@
1
+ module Culerity
2
+
3
+ class RemoteBrowserProxy < RemoteObjectProxy
4
+ def initialize(io)
5
+ @io = io
6
+ end
7
+
8
+ private
9
+
10
+ def remote_object_id
11
+ '"browser"'
12
+ end
13
+ end
14
+
15
+ end
@@ -0,0 +1,33 @@
1
+ module Culerity
2
+
3
+ class RemoteObjectProxy
4
+ def initialize(remote_object_id, io)
5
+ @remote_object_id = remote_object_id
6
+ @io = io
7
+ end
8
+
9
+ def method_missing(name, *args)
10
+ @io << "[#{remote_object_id}, \"#{name}\", #{args.map{|a| a.inspect}.join(', ')}]\n"
11
+ process_result @io.gets.to_s.strip
12
+ end
13
+
14
+ def exit
15
+ @io << '["_exit_"]'
16
+ end
17
+
18
+ private
19
+
20
+ def process_result(result)
21
+ res = eval result
22
+ if res.first == :return
23
+ res[1]
24
+ elsif res.first == :exception
25
+ raise "#{res[1]}: #{res[2]}"
26
+ end
27
+ end
28
+
29
+ def remote_object_id
30
+ @remote_object_id
31
+ end
32
+ end
33
+ end
data/lib/culerity.rb ADDED
@@ -0,0 +1,15 @@
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
+ end
9
+
10
+ end
11
+
12
+ if __FILE__ == $0
13
+ require File.dirname(__FILE__) + '/culerity/celerity_server'
14
+ Culerity::CelerityServer.new STDIN, STDOUT
15
+ end
@@ -0,0 +1,70 @@
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 pass multiple method calls" do
54
+ @browser.should_receive(:goto).with('/homepage')
55
+ @browser.should_receive(:goto).with('/page2')
56
+ _in = stub 'in'
57
+ _in.stub!(:gets).and_return("[\"browser\", \"goto\", \"/homepage\"]\n", "[\"browser\", \"goto\", \"/page2\"]\n", "[\"_exit_\"]\n")
58
+ _out = stub 'out', :<< => nil
59
+ Culerity::CelerityServer.new(_in, _out)
60
+ end
61
+
62
+ it "should return an exception" do
63
+ @browser.stub!(:goto).and_raise(RuntimeError.new('test exception'))
64
+ _in = stub 'in'
65
+ _in.stub!(:gets).and_return("[\"browser\", \"goto\", \"/homepage\"]\n", "[\"_exit_\"]\n")
66
+ _out = stub 'out'
67
+ _out.should_receive(:<<).with("[:exception, \"RuntimeError\", \"test exception\"]\n")
68
+ Culerity::CelerityServer.new(_in, _out)
69
+ end
70
+ end
@@ -0,0 +1,17 @@
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
+ end
@@ -0,0 +1,31 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe Culerity::RemoteObjectProxy do
4
+ it "should send the serialized method call to the output" do
5
+ io = stub 'io', :gets => '[:return]'
6
+ io.should_receive(:<<).with("[345, \"goto\", \"/homepage\"]\n")
7
+ proxy = Culerity::RemoteObjectProxy.new 345, 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::RemoteObjectProxy.new 345, io
14
+ proxy.goto.should == :okay
15
+ end
16
+
17
+ it "should raise the received exception" do
18
+ io = stub 'io', :gets => "[:exception, \"RuntimeError\", \"test exception\"]", :<< => nil
19
+ proxy = Culerity::RemoteObjectProxy.new 345, io
20
+ lambda {
21
+ proxy.goto '/home'
22
+ }.should raise_error(RuntimeError, 'RuntimeError: test exception')
23
+ end
24
+
25
+ it "should send exit" do
26
+ io = stub 'io', :gets => '[:return]'
27
+ io.should_receive(:<<).with('["_exit_"]')
28
+ proxy = Culerity::RemoteObjectProxy.new 345, io
29
+ proxy.exit
30
+ end
31
+ end
@@ -0,0 +1,7 @@
1
+ if RUBY_PLATFORM != 'java'
2
+ puts "You need JRuby to run these specs"
3
+ exit -1
4
+ end
5
+
6
+ require File.dirname(__FILE__) + '/../lib/culerity'
7
+ require File.dirname(__FILE__) + '/../lib/culerity/celerity_server'
metadata ADDED
@@ -0,0 +1,85 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: langalex-culerity
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Alexander Lang
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-01-25 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: cucumber
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: "0"
23
+ version:
24
+ - !ruby/object:Gem::Dependency
25
+ name: rspec
26
+ version_requirement:
27
+ version_requirements: !ruby/object:Gem::Requirement
28
+ requirements:
29
+ - - ">="
30
+ - !ruby/object:Gem::Version
31
+ version: "0"
32
+ version:
33
+ description: Culerity integrates Cucumber and Celerity in order to test your application's full stack.
34
+ email: alex@upstream-berlin.com
35
+ executables: []
36
+
37
+ extensions: []
38
+
39
+ extra_rdoc_files: []
40
+
41
+ files:
42
+ - README.textile
43
+ - VERSION.yml
44
+ - generators/culerity
45
+ - generators/culerity/culerity_generator.rb
46
+ - generators/culerity/templates
47
+ - generators/culerity/templates/common_celerity.rb
48
+ - lib/culerity
49
+ - lib/culerity/celerity_server.rb
50
+ - lib/culerity/remote_browser_proxy.rb
51
+ - lib/culerity/remote_object_proxy.rb
52
+ - lib/culerity.rb
53
+ - spec/celerity_server_spec.rb
54
+ - spec/remote_browser_proxy_spec.rb
55
+ - spec/remote_object_proxy_spec.rb
56
+ - spec/spec_helper.rb
57
+ has_rdoc: true
58
+ homepage: http://github.com/langalex/culerity
59
+ post_install_message:
60
+ rdoc_options:
61
+ - --inline-source
62
+ - --charset=UTF-8
63
+ require_paths:
64
+ - lib
65
+ required_ruby_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: "0"
70
+ version:
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: "0"
76
+ version:
77
+ requirements: []
78
+
79
+ rubyforge_project:
80
+ rubygems_version: 1.2.0
81
+ signing_key:
82
+ specification_version: 2
83
+ summary: Culerity integrates Cucumber and Celerity in order to test your application's full stack.
84
+ test_files: []
85
+