akephalos-nerian 0.2.4-java

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.
Files changed (37) hide show
  1. data/MIT_LICENSE +20 -0
  2. data/README.md +56 -0
  3. data/bin/akephalos +88 -0
  4. data/lib/akephalos.rb +19 -0
  5. data/lib/akephalos/capybara.rb +316 -0
  6. data/lib/akephalos/client.rb +112 -0
  7. data/lib/akephalos/client/cookies.rb +73 -0
  8. data/lib/akephalos/client/filter.rb +120 -0
  9. data/lib/akephalos/configuration.rb +49 -0
  10. data/lib/akephalos/console.rb +32 -0
  11. data/lib/akephalos/cucumber.rb +6 -0
  12. data/lib/akephalos/htmlunit.rb +38 -0
  13. data/lib/akephalos/htmlunit/ext/http_method.rb +30 -0
  14. data/lib/akephalos/node.rb +172 -0
  15. data/lib/akephalos/page.rb +113 -0
  16. data/lib/akephalos/remote_client.rb +84 -0
  17. data/lib/akephalos/server.rb +56 -0
  18. data/lib/akephalos/version.rb +3 -0
  19. data/src/htmlunit/apache-mime4j-0.6.jar +0 -0
  20. data/src/htmlunit/commons-codec-1.4.jar +0 -0
  21. data/src/htmlunit/commons-collections-3.2.1.jar +0 -0
  22. data/src/htmlunit/commons-io-1.4.jar +0 -0
  23. data/src/htmlunit/commons-lang-2.4.jar +0 -0
  24. data/src/htmlunit/commons-logging-1.1.1.jar +0 -0
  25. data/src/htmlunit/cssparser-0.9.5.jar +0 -0
  26. data/src/htmlunit/htmlunit-2.8.jar +0 -0
  27. data/src/htmlunit/htmlunit-core-js-2.8.jar +0 -0
  28. data/src/htmlunit/httpclient-4.0.1.jar +0 -0
  29. data/src/htmlunit/httpcore-4.0.1.jar +0 -0
  30. data/src/htmlunit/httpmime-4.0.1.jar +0 -0
  31. data/src/htmlunit/nekohtml-1.9.14.jar +0 -0
  32. data/src/htmlunit/sac-1.3.jar +0 -0
  33. data/src/htmlunit/serializer-2.7.1.jar +0 -0
  34. data/src/htmlunit/xalan-2.7.1.jar +0 -0
  35. data/src/htmlunit/xercesImpl-2.9.1.jar +0 -0
  36. data/src/htmlunit/xml-apis-1.3.04.jar +0 -0
  37. metadata +150 -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,56 @@
1
+ # Akephalos
2
+ Akephalos is a full-stack headless browser for integration testing with
3
+ Capybara. It is built on top of [HtmlUnit](http://htmlunit.sourceforge.net),
4
+ a GUI-less browser for the Java platform, but can be run on both JRuby and
5
+ MRI with no need for JRuby to be installed on the system.
6
+
7
+ ## Installation
8
+
9
+ gem install akephalos
10
+
11
+ ## Setup
12
+
13
+ Configuring akephalos is as simple as requiring it and setting Capybara's
14
+ javascript driver:
15
+
16
+ require 'akephalos'
17
+ Capybara.javascript_driver = :akephalos
18
+
19
+ ## Basic Usage
20
+
21
+ Akephalos provides a driver for Capybara, so using Akephalos is no
22
+ different than using Selenium or Rack::Test. For a full usage guide, check
23
+ out Capybara's DSL [documentation](http://github.com/jnicklas/capybara). It
24
+ makes no assumptions about the testing framework being used, and works with
25
+ RSpec, Cucumber, and Test::Unit.
26
+
27
+ Here's some sample RSpec code:
28
+
29
+ describe "Home Page" do
30
+ before { visit "/" }
31
+ context "searching" do
32
+ before do
33
+ fill_in "Search", :with => "akephalos"
34
+ click_button "Go"
35
+ end
36
+ it "returns results" { page.should have_css("#results") }
37
+ it "includes the search term" { page.should have_content("akephalos") }
38
+ end
39
+ end
40
+
41
+ ## More
42
+
43
+ * [bin/akephalos](http://bernerdschaefer.github.com/akephalos/akephalos-bin.html)
44
+ allows you to start an interactive shell or DRb server, as well as perform
45
+ other maintenance features.
46
+
47
+ * [Filters](http://bernerdschaefer.github.com/akephalos/filters.html) allows
48
+ you to declare mock responses for external resources and services requested
49
+ by the browser.
50
+
51
+ ## Resources
52
+
53
+ * [API Documentation](http://bernerdschaefer.github.com/akephalos/api)
54
+ * [Source code](http://github.com/bernerdschaefer/akephalos) and
55
+ [issues](http://github.com/bernerdschaefer/akephalos/issues) are hosted on
56
+ github.
data/bin/akephalos ADDED
@@ -0,0 +1,88 @@
1
+ #!/usr/bin/env ruby
2
+ # vim:set filetype=ruby:
3
+
4
+ require "pathname"
5
+ require "optparse"
6
+
7
+ options = { :interactive => false }
8
+
9
+ parser = OptionParser.new do |opts|
10
+ opts.banner = "Usage: akephalos [--interactive, --use-htmlunit-snapshot] | [--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
+
15
+ opts.on_tail("-h", "--help", "Show this message") { puts opts; exit }
16
+ end
17
+ parser.parse!
18
+
19
+ root = Pathname(__FILE__).expand_path.dirname.parent
20
+ lib = root + 'lib'
21
+ src = root + 'src'
22
+
23
+ case
24
+ when options[:use_htmlunit_snapshot]
25
+ require "fileutils"
26
+
27
+ FileUtils.mkdir_p("vendor/htmlunit")
28
+ Dir["vendor/htmlunit/*.jar"].each { |jar| File.unlink(jar) }
29
+
30
+ Dir.chdir("vendor") do
31
+ $stdout.print "Downloading latest snapshot... "
32
+ $stdout.flush
33
+ %x[curl -O http://build.canoo.com/htmlunit/artifacts/htmlunit-2.9-SNAPSHOT-with-dependencies.zip &> /dev/null]
34
+ puts "done"
35
+
36
+ $stdout.print "Extracting dependencies... "
37
+ $stdout.flush
38
+ %x[unzip -j -d htmlunit htmlunit-2.9-SNAPSHOT-with-dependencies.zip htmlunit-2.9-SNAPSHOT/lib htmlunit-2.9-SNAPSHOT/lib/* &> /dev/null]
39
+ puts "done"
40
+
41
+ File.unlink "htmlunit-2.9-SNAPSHOT-with-dependencies.zip"
42
+ end
43
+
44
+ $stdout.puts "="*40
45
+ $stdout.puts "The latest HtmlUnit snapshot has been extracted to vendor/htmlunit!"
46
+ when options[:interactive]
47
+ $:.unshift('vendor', lib, src)
48
+ require 'rubygems'
49
+ require 'akephalos'
50
+ require 'akephalos/console'
51
+ Akephalos::Console.start
52
+ else
53
+ unless port = ARGV[0]
54
+ puts parser.help
55
+ exit
56
+ end
57
+
58
+ if RUBY_PLATFORM == "java"
59
+ $:.unshift("vendor", lib, src)
60
+ require 'akephalos/server'
61
+ Akephalos::Server.start!(port)
62
+ else
63
+ require 'rubygems'
64
+ require 'jruby-jars'
65
+
66
+ jruby = JRubyJars.core_jar_path
67
+ jruby_stdlib = JRubyJars.stdlib_jar_path
68
+
69
+ java_args = [
70
+ "-Xmx128M",
71
+ "-cp", [JRubyJars.core_jar_path, JRubyJars.stdlib_jar_path].join(":"),
72
+ "org.jruby.Main"
73
+ ]
74
+ ruby_args = [
75
+ "-Ku",
76
+ "-I", "vendor:#{lib}:#{src}",
77
+ "-r", "akephalos/server",
78
+ "-e", "Akephalos::Server.start!(#{port.inspect})"
79
+ ]
80
+
81
+ # Bundler sets ENV["RUBYOPT"] to automatically load bundler/setup.rb, but
82
+ # since the akephalos server doesn't have any gem dependencies and is
83
+ # always executed with the same context, we clear RUBYOPT before running
84
+ # exec.
85
+ ENV["RUBYOPT"] = ""
86
+ exec("java", *(java_args + ruby_args))
87
+ end
88
+ end
data/lib/akephalos.rb ADDED
@@ -0,0 +1,19 @@
1
+ # **Akephalos** is a cross-platform Ruby interface for *HtmlUnit*, a headless
2
+ # browser for the Java platform.
3
+ #
4
+ # The only requirement is that a Java runtime is available.
5
+ #
6
+ require 'java' if RUBY_PLATFORM == 'java'
7
+ require 'pathname'
8
+
9
+ module Akephalos
10
+ BIN_DIR = Pathname(__FILE__).expand_path.dirname.parent + 'bin'
11
+ end
12
+
13
+ require 'akephalos/client'
14
+ require 'capybara'
15
+ require 'akephalos/capybara'
16
+
17
+ Capybara.register_driver :akephalos do |app|
18
+ Capybara::Driver::Akephalos.new(app)
19
+ end
@@ -0,0 +1,316 @@
1
+ # Driver class exposed to Capybara. It implements Capybara's full driver API,
2
+ # and is the entry point for interaction between the test suites and HtmlUnit.
3
+ #
4
+ # This class and +Capybara::Driver::Akephalos::Node+ are written to run on both
5
+ # MRI and JRuby, and is agnostic whether the Akephalos::Client instance is used
6
+ # directly or over DRb.
7
+ class Capybara::Driver::Akephalos < Capybara::Driver::Base
8
+
9
+ # Akephalos-specific implementation for Capybara's Driver::Node class.
10
+ class Node < Capybara::Driver::Node
11
+
12
+ # @api capybara
13
+ # @return [String] the inner text of the node
14
+ def text
15
+ native.text
16
+ end
17
+
18
+ # @api capybara
19
+ # @param [String] name attribute name
20
+ # @return [String] the attribute value
21
+ def [](name)
22
+ name = name.to_s
23
+ case name
24
+ when 'checked'
25
+ native.checked?
26
+ else
27
+ native[name.to_s]
28
+ end
29
+ end
30
+
31
+ # @api capybara
32
+ # @return [String, Array<String>] the form element's value
33
+ def value
34
+ native.value
35
+ end
36
+
37
+ # Set the form element's value.
38
+ #
39
+ # @api capybara
40
+ # @param [String] value the form element's new value
41
+ def set(value)
42
+ if tag_name == 'textarea'
43
+ native.value = value.to_s
44
+ elsif tag_name == 'input' and type == 'radio'
45
+ click
46
+ elsif tag_name == 'input' and type == 'checkbox'
47
+ if value != self['checked']
48
+ click
49
+ end
50
+ elsif tag_name == 'input'
51
+ native.value = value.to_s
52
+ end
53
+ end
54
+
55
+ # @api capybara
56
+ def select_option
57
+ native.click
58
+ end
59
+
60
+ # Unselect an option from a select box.
61
+ #
62
+ # @api capybara
63
+ def unselect_option
64
+ unless select_node.multiple_select?
65
+ raise Capybara::UnselectNotAllowed, "Cannot unselect option from single select box."
66
+ end
67
+
68
+ native.unselect
69
+ end
70
+
71
+ # Click the element.
72
+ def click
73
+ native.click
74
+ end
75
+
76
+ # Drag the element on top of the target element.
77
+ #
78
+ # @api capybara
79
+ # @param [Node] element the target element
80
+ def drag_to(element)
81
+ trigger('mousedown')
82
+ element.trigger('mousemove')
83
+ element.trigger('mouseup')
84
+ end
85
+
86
+ # @api capybara
87
+ # @return [String] the element's tag name
88
+ def tag_name
89
+ native.tag_name
90
+ end
91
+
92
+ # @api capybara
93
+ # @return [true, false] the element's visiblity
94
+ def visible?
95
+ native.visible?
96
+ end
97
+
98
+ # @api capybara
99
+ # @return [true, false] the element's visiblity
100
+ def checked?
101
+ native.checked?
102
+ end
103
+
104
+ # @api capybara
105
+ # @return [true, false] the element's visiblity
106
+ def selected?
107
+ native.selected?
108
+ end
109
+
110
+ # @api capybara
111
+ # @return [String] the XPath to locate the node
112
+ def path
113
+ native.xpath
114
+ end
115
+
116
+ # Trigger an event on the element.
117
+ #
118
+ # @api capybara
119
+ # @param [String] event the event to trigger
120
+ def trigger(event)
121
+ native.fire_event(event.to_s)
122
+ end
123
+
124
+ # @api capybara
125
+ # @param [String] selector XPath query
126
+ # @return [Array<Node>] the matched nodes
127
+ def find(selector)
128
+ nodes = []
129
+ native.find(selector).each { |node| nodes << self.class.new(self, node) }
130
+ nodes
131
+ end
132
+
133
+ protected
134
+
135
+ # @return [true, false] whether the node allows multiple-option selection (if the node is a select).
136
+ def multiple_select?
137
+ tag_name == "select" && native.multiple_select?
138
+ end
139
+
140
+ private
141
+
142
+ # Return all child nodes which match the selector criteria.
143
+ #
144
+ # @api capybara
145
+ # @return [Array<Node>] the matched nodes
146
+ def all_unfiltered(selector)
147
+ nodes = []
148
+ native.find(selector).each { |node| nodes << self.class.new(driver, node) }
149
+ nodes
150
+ end
151
+
152
+ # @return [String] the node's type attribute
153
+ def type
154
+ native[:type]
155
+ end
156
+
157
+ # @return [Node] the select node, if this is an option node
158
+ def select_node
159
+ find('./ancestor::select').first
160
+ end
161
+ end
162
+
163
+ attr_reader :app, :rack_server
164
+
165
+ # @return [Client] an instance of Akephalos::Client
166
+ def self.driver
167
+ @driver ||= Akephalos::Client.new
168
+ end
169
+
170
+ def initialize(app)
171
+ @app = app
172
+ @rack_server = Capybara::Server.new(@app)
173
+ @rack_server.boot if Capybara.run_server
174
+ end
175
+
176
+ # Visit the given path in the browser.
177
+ #
178
+ # @param [String] path relative path to visit
179
+ def visit(path)
180
+ browser.visit(url(path))
181
+ end
182
+
183
+ # @return [String] the page's original source
184
+ def source
185
+ page.source
186
+ end
187
+
188
+ # @return [String] the page's modified source
189
+ # page.modified_source will return a string with
190
+ # html entities converted into the unicode equivalent
191
+ # but the string will be marked as ASCII-8BIT
192
+ # which causes conversion issues so we force the encoding
193
+ # to UTF-8 (ruby 1.9 only)
194
+ def body
195
+ body_source = page.modified_source
196
+
197
+ if body_source.respond_to?(:force_encoding)
198
+ body_source.force_encoding("UTF-8")
199
+ else
200
+ body_source
201
+ end
202
+ end
203
+
204
+ # @return [Hash{String => String}] the page's response headers
205
+ def response_headers
206
+ page.response_headers
207
+ end
208
+
209
+ # @return [Integer] the response's status code
210
+ def status_code
211
+ page.status_code
212
+ end
213
+
214
+ # Execute the given block within the context of a specified frame.
215
+ #
216
+ # @param [String] frame_id the frame's id
217
+ # @raise [Capybara::ElementNotFound] if the frame is not found
218
+ def within_frame(frame_id, &block)
219
+ unless page.within_frame(frame_id, &block)
220
+ raise Capybara::ElementNotFound, "Unable to find frame with id '#{frame_id}'"
221
+ end
222
+ end
223
+
224
+ # Clear all cookie session data.
225
+ # @deprecated This method is deprecated in Capybara's master branch. Use
226
+ # {#reset!} instead.
227
+ def cleanup!
228
+ reset!
229
+ end
230
+
231
+ # Clear all cookie session data.
232
+ def reset!
233
+ cookies.clear
234
+ end
235
+
236
+ # @return [String] the page's current URL
237
+ def current_url
238
+ page.current_url
239
+ end
240
+
241
+ # Search for nodes which match the given XPath selector.
242
+ #
243
+ # @param [String] selector XPath query
244
+ # @return [Array<Node>] the matched nodes
245
+ def find(selector)
246
+ nodes = []
247
+ page.find(selector).each { |node| nodes << Node.new(self, node) }
248
+ nodes
249
+ end
250
+
251
+ # Execute JavaScript against the current page, discarding any return value.
252
+ #
253
+ # @param [String] script the JavaScript to be executed
254
+ # @return [nil]
255
+ def execute_script(script)
256
+ page.execute_script script
257
+ end
258
+
259
+ # Execute JavaScript against the current page and return the results.
260
+ #
261
+ # @param [String] script the JavaScript to be executed
262
+ # @return the result of the JavaScript
263
+ def evaluate_script(script)
264
+ page.evaluate_script script
265
+ end
266
+
267
+ # @return the current page
268
+ def page
269
+ browser.page
270
+ end
271
+
272
+ # @return the browser
273
+ def browser
274
+ self.class.driver
275
+ end
276
+
277
+ # @return the session cookies
278
+ def cookies
279
+ browser.cookies
280
+ end
281
+
282
+ # @return [String] the current user agent string
283
+ def user_agent
284
+ browser.user_agent
285
+ end
286
+
287
+ # Set the User-Agent header for this session. If :default is given, the
288
+ # User-Agent header will be reset to the default browser's user agent.
289
+ #
290
+ # @param [:default] user_agent the default user agent
291
+ # @param [String] user_agent the user agent string to use
292
+ def user_agent=(user_agent)
293
+ browser.user_agent = user_agent
294
+ end
295
+
296
+ # Disable waiting in Capybara, since waiting is handled directly by
297
+ # Akephalos.
298
+ #
299
+ # @return [false]
300
+ def wait
301
+ false
302
+ end
303
+
304
+ private
305
+
306
+ # @param [String] path
307
+ # @return [String] the absolute URL for the given path
308
+ def url(path)
309
+ rack_server.url(path)
310
+ end
311
+
312
+ end
313
+
314
+ Capybara.register_driver :akephalos do |app|
315
+ Capybara::Driver::Akephalos.new(app)
316
+ end