akephalos2 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. data/MIT_LICENSE +20 -0
  2. data/README.md +287 -0
  3. data/bin/akephalos +102 -0
  4. data/lib/akephalos/capybara.rb +343 -0
  5. data/lib/akephalos/client/cookies.rb +73 -0
  6. data/lib/akephalos/client/filter.rb +120 -0
  7. data/lib/akephalos/client.rb +192 -0
  8. data/lib/akephalos/configuration.rb +49 -0
  9. data/lib/akephalos/console.rb +32 -0
  10. data/lib/akephalos/cucumber.rb +6 -0
  11. data/lib/akephalos/htmlunit/ext/confirm_handler.rb +18 -0
  12. data/lib/akephalos/htmlunit/ext/http_method.rb +30 -0
  13. data/lib/akephalos/htmlunit.rb +36 -0
  14. data/lib/akephalos/node.rb +192 -0
  15. data/lib/akephalos/page.rb +113 -0
  16. data/lib/akephalos/remote_client.rb +93 -0
  17. data/lib/akephalos/server.rb +79 -0
  18. data/lib/akephalos/version.rb +3 -0
  19. data/lib/akephalos.rb +19 -0
  20. data/vendor/html-unit/apache-mime4j-0.6.jar +0 -0
  21. data/vendor/html-unit/commons-codec-1.4.jar +0 -0
  22. data/vendor/html-unit/commons-collections-3.2.1.jar +0 -0
  23. data/vendor/html-unit/commons-io-2.0.1.jar +0 -0
  24. data/vendor/html-unit/commons-lang-2.6.jar +0 -0
  25. data/vendor/html-unit/commons-logging-1.1.1.jar +0 -0
  26. data/vendor/html-unit/cssparser-0.9.5.jar +0 -0
  27. data/vendor/html-unit/htmlunit-2.9.jar +0 -0
  28. data/vendor/html-unit/htmlunit-core-js-2.9.jar +0 -0
  29. data/vendor/html-unit/httpclient-4.1.2.jar +0 -0
  30. data/vendor/html-unit/httpcore-4.1.2.jar +0 -0
  31. data/vendor/html-unit/httpmime-4.1.2.jar +0 -0
  32. data/vendor/html-unit/nekohtml-1.9.15.jar +0 -0
  33. data/vendor/html-unit/sac-1.3.jar +0 -0
  34. data/vendor/html-unit/serializer-2.7.1.jar +0 -0
  35. data/vendor/html-unit/xalan-2.7.1.jar +0 -0
  36. data/vendor/html-unit/xercesImpl-2.9.1.jar +0 -0
  37. data/vendor/html-unit/xml-apis-1.3.04.jar +0 -0
  38. metadata +127 -0
data/MIT_LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Bernerd Schaefer
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,287 @@
1
+ ```
2
+ Important Notice
3
+ This repo has rewrote its history and as such is not compatible with the main Akephalos repo.
4
+
5
+ Further development will be done here.
6
+
7
+ You can get the unaltered pristine copy at: [https://github.com/Nerian/akephalos](https://github.com/Nerian/akephalos)
8
+
9
+ The reason why its history was rewrote was to remove .jar vendor files that were making its size huge.
10
+ ```
11
+
12
+
13
+ # Akephalos
14
+
15
+ Akephalos is a full-stack headless browser for integration testing with
16
+ Capybara. It is built on top of [HtmlUnit](http://htmlunit.sourceforge.net),
17
+ a GUI-less browser for the Java platform, but can be run on both JRuby and
18
+ MRI with no need for JRuby to be installed on the system.
19
+
20
+
21
+ ## Installation
22
+
23
+ ``` ruby
24
+ gem install akephalos # Official gem
25
+ ```
26
+
27
+ Or
28
+
29
+ ``` ruby
30
+ gem 'akephalos', :git => 'git://github.com/Nerian/akephalos.git'
31
+ ```
32
+
33
+ # Development
34
+
35
+ ``` bash
36
+ git clone https://github.com/Nerian/akephalos2
37
+ git submodule update --init
38
+ ```
39
+
40
+ The last line will grab the HTMLUnit jar files from [https://github.com/Nerian/html-unit-vendor](https://github.com/Nerian/html-unit-vendor)
41
+
42
+
43
+ ## Setup
44
+
45
+ Configuring akephalos is as simple as requiring it and setting Capybara's
46
+ javascript driver:
47
+
48
+ ``` ruby
49
+ require 'akephalos'
50
+ Capybara.javascript_driver = :akephalos
51
+ ```
52
+
53
+
54
+ ## Basic Usage
55
+
56
+ Akephalos provides a driver for Capybara, so using Akephalos is no
57
+ different than using Selenium or Rack::Test. For a full usage guide, check
58
+ out Capybara's DSL [documentation](http://github.com/jnicklas/capybara). It
59
+ makes no assumptions about the testing framework being used, and works with
60
+ RSpec, Cucumber, and Test::Unit.
61
+
62
+ Here's some sample RSpec code:
63
+
64
+ ``` ruby
65
+ describe "Home Page" do
66
+ before { visit "/" }
67
+ context "searching" do
68
+ before do
69
+ fill_in "Search", :with => "akephalos"
70
+ click_button "Go"
71
+ end
72
+ it "returns results" { page.should have_css("#results") }
73
+ it "includes the search term" { page.should have_content("akephalos") }
74
+ end
75
+ end
76
+ ```
77
+
78
+
79
+ ## Configuration
80
+
81
+ There are now a few configuration options available through Capybara's new
82
+ `register_driver` API.
83
+
84
+ ### Configuring the max memory that Java Virtual Machine can use
85
+
86
+ The max memory that the JVM is going to use can be set using an environment variable in your spec_helper or .bashrc file.
87
+
88
+ ``` ruby
89
+ ENV['akephalos_jvm_max_memory']
90
+ ```
91
+
92
+
93
+ The default value is 256 MB.
94
+
95
+ If you use akephalos's bin the parameter `-m [memory]` sets the max memory for the JVM.
96
+
97
+ ``` bash
98
+ $ akephalos -m 670
99
+ ```
100
+
101
+
102
+ ### Using a different browser
103
+
104
+ HtmlUnit supports a few browser implementations, and you can choose which
105
+ browser you would like to use through Akephalos. By default, Akephalos uses
106
+ Firefox 3.6.
107
+
108
+ ``` ruby
109
+ Capybara.register_driver :akephalos do |app|
110
+ # available options:
111
+ # :ie6, :ie7, :ie8, :firefox_3, :firefox_3_6
112
+ Capybara::Driver::Akephalos.new(app, :browser => :ie8)
113
+ end
114
+ ```
115
+
116
+
117
+ ### Using a Proxy Server
118
+
119
+ ``` ruby
120
+ Capybara.register_driver :akephalos do |app|
121
+ Capybara::Driver::Akephalos.new(app, :http_proxy => 'myproxy.com', :http_proxy_port => 8080)
122
+ end
123
+ ```
124
+
125
+
126
+ ### Ignoring javascript errors
127
+
128
+ By default HtmlUnit (and Akephalos) will raise an exception when an error
129
+ is encountered in javascript files. This is generally desirable, except
130
+ that certain libraries aren't supported by HtmlUnit. If possible, it's
131
+ best to keep the default behaviour, and use Filters (see below) to mock
132
+ offending libraries. If needed, however, you can configure Akephalos to
133
+ ignore javascript errors.
134
+
135
+ ``` ruby
136
+ Capybara.register_driver :akephalos do |app|
137
+ Capybara::Driver::Akephalos.new(app, :validate_scripts => false)
138
+ end
139
+ ```
140
+
141
+
142
+ ### Setting the HtmlUnit log level
143
+
144
+ By default it uses the 'fatal' level. You can change that like this:
145
+
146
+ ``` ruby
147
+ Capybara.register_driver :akephalos do |app|
148
+ # available options
149
+ # "trace", "debug", "info", "warn", "error", or "fatal"
150
+ Capybara::Driver::Akephalos.new(app, :htmlunit_log_level => 'fatal')
151
+ end
152
+ ```
153
+
154
+
155
+ ### Running Akephalos with Spork
156
+
157
+ ``` ruby
158
+ Spork.prefork do
159
+ ...
160
+ Akephalos::RemoteClient.manager
161
+ end
162
+
163
+ Spork.each_run do
164
+ ...
165
+ Thread.current['DRb'] = { 'server' => DRb::DRbServer.new }
166
+ end
167
+ ```
168
+
169
+
170
+ More info at : [sporking-with-akephalos](http://spacevatican.org/2011/7/3/sporking-with-akephalos)
171
+
172
+ ### Filters
173
+
174
+ Akephalos allows you to filter requests originating from the browser and return mock responses. This will let you easily filter requests for external resources when running your tests, such as Facebook's API and Google Analytics.
175
+
176
+ Configuring filters in Akephalos should be familiar to anyone who has used FakeWeb or a similar library. The simplest filter requires only an HTTP method (:get, :post, :put, :delete, :any) and a string or regex to match against.
177
+
178
+ ``` ruby
179
+ Akephalos.filter(:get, "http://www.google.com")
180
+ Akephalos.filter(:any, %r{^http://(api\.)?twitter\.com/.*$})
181
+ ```
182
+
183
+
184
+ By default, all filtered requests will return an empty body with a 200 status code. You can change this by passing additional options to your filter call.
185
+
186
+ ``` ruby
187
+ Akephalos.filter(:get, "http://google.com/missing",
188
+ :status => 404, :body => "... <h1>Not Found</h1> ...")
189
+
190
+ Akephalos.filter(:post, "http://my-api.com/resource.xml",
191
+ :status => 201, :headers => {
192
+ "Content-Type" => "application/xml",
193
+ "Location" => "http://my-api.com/resources/1.xml" },
194
+ :body => {:id => 100}.to_xml)
195
+ ```
196
+
197
+
198
+ And that's really all there is to it! It should be fairly trivial to set up filters for the external resources you need to fake. For reference, however, here's what we ended up using for our external sources.
199
+
200
+ #### Example: Google Maps
201
+
202
+ Google Analytics code is passively applied based on HTML comments, so simply returning an empty response body is enough to disable it without errors.
203
+
204
+ ``` ruby
205
+ Akephalos.filter(:get, "http://www.google-analytics.com/ga.js",
206
+ :headers => {"Content-Type" => "application/javascript"})
207
+ ```
208
+
209
+
210
+ Google Maps requires the most extensive amount of API definitions of the three, but these few lines cover everything we've encountered so far.
211
+
212
+ ``` ruby
213
+ Akephalos.filter(:get, "http://maps.google.com/maps/api/js?sensor=false",
214
+ :headers => {"Content-Type" => "application/javascript"},
215
+ :body => "window.google = {
216
+ maps: {
217
+ LatLng: function(){},
218
+ Map: function(){},
219
+ Marker: function(){},
220
+ MapTypeId: {ROADMAP:1}
221
+ }
222
+ };")
223
+ ```
224
+
225
+
226
+ #### Example: Facebook Connect
227
+
228
+ Facebook Connect
229
+
230
+ When you enable Facebook Connect on your page, the FeatureLoader is requested, and then additional resources are loaded when you call FB_RequireFeatures. We can therefore return an empty function from our filter to disable all Facebook Connect code.
231
+
232
+ ``` ruby
233
+ Akephalos.filter(:get,
234
+ "http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php",
235
+ :headers => {"Content-Type" => "application/javascript"},
236
+ :body => "window.FB_RequireFeatures = function() {};")
237
+ ```
238
+
239
+
240
+ ### Akephalos' Interactive mode
241
+
242
+ #### bin/akephalos
243
+
244
+ The bundled akephalos binary provides a command line interface to a few useful features.
245
+
246
+ #### akephalos --interactive
247
+
248
+ Running Akephalos in interactive mode gives you an IRB context for interacting with your site just as you would in your tests:
249
+
250
+ ``` ruby
251
+ $ akephalos --interactive
252
+ -> Capybara.app_host # => "http://localhost:3000"
253
+ -> page.visit "/"
254
+ -> page.fill_in "Search", :with => "akephalos"
255
+ -> page.click_button "Go"
256
+ -> page.has_css?("#search_results") # => true
257
+ ```
258
+
259
+
260
+ #### akephalos --use-htmlunit-snapshot
261
+
262
+ This will instruct Akephalos to use the latest development snapshot of HtmlUnit as found on it's Cruise Control server. HtmlUnit and its dependencies will be unpacked into vendor/htmlunit in the current working directory.
263
+
264
+ This is what the output looks like:
265
+
266
+ ``` ruby
267
+ $ akephalos --use-htmlunit-snapshot
268
+
269
+ Downloading latest snapshot... done
270
+ Extracting dependencies... done
271
+ ========================================
272
+ The latest HtmlUnit snapshot has been extracted to vendor/htmlunit!
273
+ Once HtmlUnit has been extracted, Akephalos will automatically detect
274
+ the vendored version and use it instead of the bundled version.
275
+ ```
276
+
277
+
278
+ #### akephalos --server <socket_file>
279
+
280
+ Akephalos uses this command internally to start a JRuby DRb server using the provided socket file.
281
+
282
+ ## Resources
283
+
284
+ * [API Documentation](http://bernerdschaefer.github.com/akephalos/api)
285
+ * [Source code](http://github.com/bernerdschaefer/akephalos) and
286
+ [issues](http://github.com/bernerdschaefer/akephalos/issues) are hosted on
287
+ github.
data/bin/akephalos ADDED
@@ -0,0 +1,102 @@
1
+ #!/usr/bin/env ruby
2
+ # vim:set filetype=ruby:
3
+
4
+ require "pathname"
5
+ require "optparse"
6
+
7
+ options = { :interactive => false, :default_jvm_max_memory => '256' }
8
+
9
+ parser = OptionParser.new do |opts|
10
+ opts.banner = "Usage: akephalos [--interactive, --use-htmlunit-snapshot, --memory [number]] | [--server] <port>"
11
+ opts.on("-s", "--server", "Run in server mode (default)")
12
+ opts.on("-i", "--interactive", "Run in interactive mode") { options[:interactive] = true }
13
+ opts.on("--use-htmlunit-snapshot", "Use the snapshot of htmlunit") { options[:use_htmlunit_snapshot] = true }
14
+ opts.on("-m", "--memory [number]", "Max memory for the Java Virtual Machine, defaults to #{options[:default_jvm_max_memory]}
15
+ or env variable $akephalos_jvm_max_memory") do |memory|
16
+ options[:akephalos_jvm_max_memory] = memory.to_s
17
+ end
18
+
19
+ if options[:akephalos_jvm_max_memory].nil?
20
+ if ENV['akephalos_jvm_max_memory'].nil?
21
+ options[:akephalos_jvm_max_memory] = options[:default_jvm_max_memory]
22
+ else
23
+ options[:akephalos_jvm_max_memory] = ENV['akephalos_jvm_max_memory']
24
+ end
25
+ end
26
+
27
+ puts "Using #{options[:akephalos_jvm_max_memory]} MB for the JVM"
28
+
29
+ opts.on_tail("-h", "--help", "Show this message") { puts opts; exit }
30
+ end
31
+ parser.parse!
32
+
33
+ root = Pathname(__FILE__).expand_path.dirname.parent
34
+ lib = root + 'lib'
35
+ src = root + 'src'
36
+
37
+ case
38
+ when options[:use_htmlunit_snapshot]
39
+ require "fileutils"
40
+
41
+ FileUtils.mkdir_p("vendor/htmlunit")
42
+ Dir["vendor/htmlunit/*.jar"].each { |jar| File.unlink(jar) }
43
+
44
+ Dir.chdir("vendor") do
45
+ $stdout.print "Downloading latest snapshot... "
46
+ $stdout.flush
47
+ %x[curl -O http://build.canoo.com/htmlunit/artifacts/htmlunit-2.9-SNAPSHOT-with-dependencies.zip &> /dev/null]
48
+ puts "done"
49
+
50
+ $stdout.print "Extracting dependencies... "
51
+ $stdout.flush
52
+ %x[unzip -j -d htmlunit htmlunit-2.9-SNAPSHOT-with-dependencies.zip htmlunit-2.9-SNAPSHOT/lib htmlunit-2.9-SNAPSHOT/lib/* &> /dev/null]
53
+ puts "done"
54
+
55
+ File.unlink "htmlunit-2.9-SNAPSHOT-with-dependencies.zip"
56
+ end
57
+
58
+ $stdout.puts "="*40
59
+ $stdout.puts "The latest HtmlUnit snapshot has been extracted to vendor/htmlunit!"
60
+ when options[:interactive]
61
+ $:.unshift('vendor', lib, src)
62
+ require 'rubygems'
63
+ require 'akephalos'
64
+ require 'akephalos/console'
65
+ Akephalos::Console.start
66
+ else
67
+ unless port = ARGV[0]
68
+ puts parser.help
69
+ exit
70
+ end
71
+
72
+ if RUBY_PLATFORM == "java"
73
+ $:.unshift("vendor", lib, src)
74
+ require 'akephalos/server'
75
+ Akephalos::Server.start!(port)
76
+ else
77
+ require 'rubygems'
78
+ require 'jruby-jars'
79
+
80
+ jruby = JRubyJars.core_jar_path
81
+ jruby_stdlib = JRubyJars.stdlib_jar_path
82
+
83
+ java_args = [
84
+ "-Xmx#{options[:akephalos_jvm_max_memory]}M",
85
+ "-cp", [JRubyJars.core_jar_path, JRubyJars.stdlib_jar_path].join(File::PATH_SEPARATOR),
86
+ "org.jruby.Main"
87
+ ]
88
+ ruby_args = [
89
+ "-Ku",
90
+ "-I", ["vendor", lib, src].join(File::PATH_SEPARATOR),
91
+ "-r", "akephalos/server",
92
+ "-e", "Akephalos::Server.start!(#{port.inspect})"
93
+ ]
94
+
95
+ # Bundler sets ENV["RUBYOPT"] to automatically load bundler/setup.rb, but
96
+ # since the akephalos server doesn't have any gem dependencies and is
97
+ # always executed with the same context, we clear RUBYOPT before running
98
+ # exec.
99
+ ENV["RUBYOPT"] = ""
100
+ exec("java", *(java_args + ruby_args))
101
+ end
102
+ end