fletcherm-culerity 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. data/.gitignore +6 -0
  2. data/CHANGES.md +7 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.md +102 -0
  5. data/Rakefile +47 -0
  6. data/VERSION.yml +5 -0
  7. data/culerity.gemspec +165 -0
  8. data/features/fixtures/jquery +4376 -0
  9. data/features/fixtures/sample_feature +14 -0
  10. data/features/installing_culerity.feature +36 -0
  11. data/features/running_cucumber_without_explicitly_running_external_services.feature +23 -0
  12. data/features/step_definitions/common_steps.rb +175 -0
  13. data/features/step_definitions/culerity_setup_steps.rb +7 -0
  14. data/features/step_definitions/jruby_steps.rb +11 -0
  15. data/features/step_definitions/rails_setup_steps.rb +36 -0
  16. data/features/support/common.rb +32 -0
  17. data/features/support/env.rb +24 -0
  18. data/features/support/matchers.rb +11 -0
  19. data/init.rb +1 -0
  20. data/lib/culerity.rb +44 -0
  21. data/lib/culerity/celerity_server.rb +81 -0
  22. data/lib/culerity/jruby_runner.rb +13 -0
  23. data/lib/culerity/remote_browser_proxy.rb +58 -0
  24. data/lib/culerity/remote_object_proxy.rb +76 -0
  25. data/rails/init.rb +1 -0
  26. data/rails_generators/culerity/culerity_generator.rb +28 -0
  27. data/rails_generators/culerity/templates/config/environments/culerity_continuousintegration.rb +28 -0
  28. data/rails_generators/culerity/templates/config/environments/culerity_development.rb +17 -0
  29. data/rails_generators/culerity/templates/features/step_definitions/culerity_steps.rb +109 -0
  30. data/rails_generators/culerity/templates/features/support/env.rb +9 -0
  31. data/rails_generators/culerity/templates/lib/tasks/culerity.rake +38 -0
  32. data/rails_generators/culerity/templates/public/javascripts/culerity.js +27 -0
  33. data/script/console +10 -0
  34. data/script/destroy +14 -0
  35. data/script/generate +14 -0
  36. data/spec/celerity_server_spec.rb +106 -0
  37. data/spec/culerity_spec.rb +33 -0
  38. data/spec/jruby_runner_spec.rb +12 -0
  39. data/spec/remote_browser_proxy_spec.rb +62 -0
  40. data/spec/remote_object_proxy_spec.rb +63 -0
  41. data/spec/spec_helper.rb +3 -0
  42. data/vendor/gems/celerity-0.7.6/HISTORY +111 -0
  43. data/vendor/gems/celerity-0.7.6/LICENSE +621 -0
  44. data/vendor/gems/celerity-0.7.6/README.rdoc +80 -0
  45. data/vendor/gems/celerity-0.7.6/Rakefile +11 -0
  46. data/vendor/gems/celerity-0.7.6/VERSION.yml +5 -0
  47. data/vendor/gems/celerity-0.7.6/celerity.gemspec +120 -0
  48. data/vendor/gems/celerity-0.7.6/lib/celerity.rb +77 -0
  49. data/vendor/gems/celerity-0.7.6/lib/celerity/browser.rb +893 -0
  50. data/vendor/gems/celerity-0.7.6/lib/celerity/clickable_element.rb +73 -0
  51. data/vendor/gems/celerity-0.7.6/lib/celerity/collections.rb +156 -0
  52. data/vendor/gems/celerity-0.7.6/lib/celerity/container.rb +767 -0
  53. data/vendor/gems/celerity-0.7.6/lib/celerity/default_viewer.rb +14 -0
  54. data/vendor/gems/celerity-0.7.6/lib/celerity/disabled_element.rb +40 -0
  55. data/vendor/gems/celerity-0.7.6/lib/celerity/element.rb +298 -0
  56. data/vendor/gems/celerity-0.7.6/lib/celerity/element_collection.rb +107 -0
  57. data/vendor/gems/celerity-0.7.6/lib/celerity/element_locator.rb +159 -0
  58. data/vendor/gems/celerity-0.7.6/lib/celerity/elements/button.rb +54 -0
  59. data/vendor/gems/celerity-0.7.6/lib/celerity/elements/file_field.rb +29 -0
  60. data/vendor/gems/celerity-0.7.6/lib/celerity/elements/form.rb +33 -0
  61. data/vendor/gems/celerity-0.7.6/lib/celerity/elements/frame.rb +86 -0
  62. data/vendor/gems/celerity-0.7.6/lib/celerity/elements/image.rb +89 -0
  63. data/vendor/gems/celerity-0.7.6/lib/celerity/elements/label.rb +16 -0
  64. data/vendor/gems/celerity-0.7.6/lib/celerity/elements/link.rb +43 -0
  65. data/vendor/gems/celerity-0.7.6/lib/celerity/elements/meta.rb +14 -0
  66. data/vendor/gems/celerity-0.7.6/lib/celerity/elements/non_control_elements.rb +116 -0
  67. data/vendor/gems/celerity-0.7.6/lib/celerity/elements/option.rb +38 -0
  68. data/vendor/gems/celerity-0.7.6/lib/celerity/elements/radio_check.rb +114 -0
  69. data/vendor/gems/celerity-0.7.6/lib/celerity/elements/select_list.rb +147 -0
  70. data/vendor/gems/celerity-0.7.6/lib/celerity/elements/table.rb +153 -0
  71. data/vendor/gems/celerity-0.7.6/lib/celerity/elements/table_cell.rb +36 -0
  72. data/vendor/gems/celerity-0.7.6/lib/celerity/elements/table_elements.rb +42 -0
  73. data/vendor/gems/celerity-0.7.6/lib/celerity/elements/table_row.rb +49 -0
  74. data/vendor/gems/celerity-0.7.6/lib/celerity/elements/text_field.rb +168 -0
  75. data/vendor/gems/celerity-0.7.6/lib/celerity/exception.rb +83 -0
  76. data/vendor/gems/celerity-0.7.6/lib/celerity/htmlunit.rb +64 -0
  77. data/vendor/gems/celerity-0.7.6/lib/celerity/htmlunit/commons-codec-1.4.jar +0 -0
  78. data/vendor/gems/celerity-0.7.6/lib/celerity/htmlunit/commons-collections-3.2.1.jar +0 -0
  79. data/vendor/gems/celerity-0.7.6/lib/celerity/htmlunit/commons-httpclient-3.1.jar +0 -0
  80. data/vendor/gems/celerity-0.7.6/lib/celerity/htmlunit/commons-io-1.4.jar +0 -0
  81. data/vendor/gems/celerity-0.7.6/lib/celerity/htmlunit/commons-lang-2.4.jar +0 -0
  82. data/vendor/gems/celerity-0.7.6/lib/celerity/htmlunit/commons-logging-1.1.1.jar +0 -0
  83. data/vendor/gems/celerity-0.7.6/lib/celerity/htmlunit/cssparser-0.9.5.jar +0 -0
  84. data/vendor/gems/celerity-0.7.6/lib/celerity/htmlunit/htmlunit-2.7-SNAPSHOT.jar +0 -0
  85. data/vendor/gems/celerity-0.7.6/lib/celerity/htmlunit/htmlunit-core-js-2.7-SNAPSHOT.jar +0 -0
  86. data/vendor/gems/celerity-0.7.6/lib/celerity/htmlunit/nekohtml-1.9.14-20091130.152932-3.jar +0 -0
  87. data/vendor/gems/celerity-0.7.6/lib/celerity/htmlunit/sac-1.3.jar +0 -0
  88. data/vendor/gems/celerity-0.7.6/lib/celerity/htmlunit/serializer-2.7.1.jar +0 -0
  89. data/vendor/gems/celerity-0.7.6/lib/celerity/htmlunit/xalan-2.7.1.jar +0 -0
  90. data/vendor/gems/celerity-0.7.6/lib/celerity/htmlunit/xercesImpl-2.9.1.jar +0 -0
  91. data/vendor/gems/celerity-0.7.6/lib/celerity/htmlunit/xml-apis-1.3.04.jar +0 -0
  92. data/vendor/gems/celerity-0.7.6/lib/celerity/identifier.rb +28 -0
  93. data/vendor/gems/celerity-0.7.6/lib/celerity/ignoring_web_connection.rb +15 -0
  94. data/vendor/gems/celerity-0.7.6/lib/celerity/input_element.rb +25 -0
  95. data/vendor/gems/celerity-0.7.6/lib/celerity/javascript_debugger.rb +32 -0
  96. data/vendor/gems/celerity-0.7.6/lib/celerity/listener.rb +143 -0
  97. data/vendor/gems/celerity-0.7.6/lib/celerity/resources/no_viewer.png +0 -0
  98. data/vendor/gems/celerity-0.7.6/lib/celerity/short_inspect.rb +20 -0
  99. data/vendor/gems/celerity-0.7.6/lib/celerity/util.rb +126 -0
  100. data/vendor/gems/celerity-0.7.6/lib/celerity/version.rb +3 -0
  101. data/vendor/gems/celerity-0.7.6/lib/celerity/viewer_connection.rb +89 -0
  102. data/vendor/gems/celerity-0.7.6/lib/celerity/watir_compatibility.rb +70 -0
  103. data/vendor/gems/celerity-0.7.6/lib/celerity/xpath_support.rb +48 -0
  104. data/vendor/gems/celerity-0.7.6/tasks/benchmark.rake +4 -0
  105. data/vendor/gems/celerity-0.7.6/tasks/check.rake +24 -0
  106. data/vendor/gems/celerity-0.7.6/tasks/clean.rake +3 -0
  107. data/vendor/gems/celerity-0.7.6/tasks/fix.rake +25 -0
  108. data/vendor/gems/celerity-0.7.6/tasks/jar.rake +55 -0
  109. data/vendor/gems/celerity-0.7.6/tasks/jeweler.rake +26 -0
  110. data/vendor/gems/celerity-0.7.6/tasks/rdoc.rake +4 -0
  111. data/vendor/gems/celerity-0.7.6/tasks/snapshot.rake +22 -0
  112. data/vendor/gems/celerity-0.7.6/tasks/spec.rake +26 -0
  113. data/vendor/gems/celerity-0.7.6/tasks/website.rake +10 -0
  114. data/vendor/gems/celerity-0.7.6/tasks/yard.rake +16 -0
  115. data/vendor/jruby/jruby-complete-1.4.0.jar +0 -0
  116. metadata +194 -0
@@ -0,0 +1,80 @@
1
+ = Celerity
2
+
3
+ * http://celerity.rubyforge.org/
4
+
5
+ == Description
6
+
7
+ Celerity is a JRuby library for easy and fast functional test automation for web applications.
8
+
9
+ Celerity is a JRuby wrapper around HtmlUnit – a headless Java browser with
10
+ JavaScript support. It provides a simple API for programmatic navigation through
11
+ web applications. Celerity provides a superset of Watir's API.
12
+
13
+ == Features
14
+
15
+ * *Fast*: No time-consuming GUI rendering or unessential downloads
16
+ * *Scalable*: Java threads lets you run tests in parallel
17
+ * *Easy to use*: Simple API
18
+ * *Portable*: Cross-platform thanks to the JVM
19
+ * *Unintrusive*: No browser window interrupting your workflow (runs in background)
20
+
21
+ == Requirements
22
+
23
+ * JRuby 1.2.0 or higher
24
+ * Java 6
25
+
26
+ == Install
27
+
28
+ jruby -S gem install celerity
29
+
30
+ To always get the latest version, you should use Gemcutter as your primary gem source:
31
+
32
+ jruby -S gem install gemcutter
33
+ jruby -S gem tumble
34
+ jruby -S gem install celerity
35
+
36
+
37
+ == Example
38
+
39
+ require "rubygems"
40
+ require "celerity"
41
+
42
+ browser = Celerity::Browser.new
43
+ browser.goto('http://www.google.com')
44
+ browser.text_field(:name, 'q').value = 'Celerity'
45
+ browser.button(:name, 'btnG').click
46
+
47
+ puts "yay" if browser.text.include? 'celerity.rubyforge.org'
48
+
49
+ == Source
50
+
51
+ The source code is available on [GitHub](http://github.com/jarib/celerity/tree/master).
52
+
53
+
54
+ == Wiki & Bug Tracker
55
+
56
+ * [Wiki](http://github.com/jarib/celerity/wikis)
57
+ * [Bug Tracker](http://github.com/jarib/celerity/issues)
58
+
59
+ == Related projects
60
+
61
+ * [WatirSpec](http://github.com/jarib/watirspec/tree/master)
62
+ * [Celerity Viewers](http://github.com/jarib/celerity-viewers)
63
+
64
+ == License
65
+
66
+ Celerity - JRuby wrapper for HtmlUnit
67
+ Copyright (c) 2008-2009 FINN.no AS
68
+
69
+ This program is free software: you can redistribute it and/or modify
70
+ it under the terms of the GNU General Public License as published by
71
+ the Free Software Foundation, either version 3 of the License, or
72
+ (at your option) any later version.
73
+
74
+ This program is distributed in the hope that it will be useful,
75
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
76
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
77
+ GNU General Public License for more details.
78
+
79
+ You should have received a copy of the GNU General Public License
80
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
@@ -0,0 +1,11 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require "lib/celerity/version"
4
+
5
+ Dir['tasks/**/*.rake'].each do |rake|
6
+ begin
7
+ load rake
8
+ rescue LoadError => e
9
+ puts e.message
10
+ end
11
+ end
@@ -0,0 +1,5 @@
1
+ ---
2
+ :patch: 6
3
+ :major: 0
4
+ :build:
5
+ :minor: 7
@@ -0,0 +1,120 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{celerity}
8
+ s.version = "0.7.6"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Jari Bakken", "T. Alexander Lystad", "Knut Johannes Dahle"]
12
+ s.date = %q{2009-12-05}
13
+ s.description = %q{Celerity is a JRuby wrapper around HtmlUnit – a headless Java browser with JavaScript support. It provides a simple API for programmatic navigation through web applications. Celerity provides a superset of Watir's API.}
14
+ s.email = %q{jari.bakken@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ "HISTORY",
21
+ "LICENSE",
22
+ "README.rdoc",
23
+ "Rakefile",
24
+ "VERSION.yml",
25
+ "celerity.gemspec",
26
+ "lib/celerity.rb",
27
+ "lib/celerity/browser.rb",
28
+ "lib/celerity/clickable_element.rb",
29
+ "lib/celerity/collections.rb",
30
+ "lib/celerity/container.rb",
31
+ "lib/celerity/default_viewer.rb",
32
+ "lib/celerity/disabled_element.rb",
33
+ "lib/celerity/element.rb",
34
+ "lib/celerity/element_collection.rb",
35
+ "lib/celerity/element_locator.rb",
36
+ "lib/celerity/elements/button.rb",
37
+ "lib/celerity/elements/file_field.rb",
38
+ "lib/celerity/elements/form.rb",
39
+ "lib/celerity/elements/frame.rb",
40
+ "lib/celerity/elements/image.rb",
41
+ "lib/celerity/elements/label.rb",
42
+ "lib/celerity/elements/link.rb",
43
+ "lib/celerity/elements/meta.rb",
44
+ "lib/celerity/elements/non_control_elements.rb",
45
+ "lib/celerity/elements/option.rb",
46
+ "lib/celerity/elements/radio_check.rb",
47
+ "lib/celerity/elements/select_list.rb",
48
+ "lib/celerity/elements/table.rb",
49
+ "lib/celerity/elements/table_cell.rb",
50
+ "lib/celerity/elements/table_elements.rb",
51
+ "lib/celerity/elements/table_row.rb",
52
+ "lib/celerity/elements/text_field.rb",
53
+ "lib/celerity/exception.rb",
54
+ "lib/celerity/htmlunit.rb",
55
+ "lib/celerity/htmlunit/commons-codec-1.4.jar",
56
+ "lib/celerity/htmlunit/commons-collections-3.2.1.jar",
57
+ "lib/celerity/htmlunit/commons-httpclient-3.1.jar",
58
+ "lib/celerity/htmlunit/commons-io-1.4.jar",
59
+ "lib/celerity/htmlunit/commons-lang-2.4.jar",
60
+ "lib/celerity/htmlunit/commons-logging-1.1.1.jar",
61
+ "lib/celerity/htmlunit/cssparser-0.9.5.jar",
62
+ "lib/celerity/htmlunit/htmlunit-2.7-SNAPSHOT.jar",
63
+ "lib/celerity/htmlunit/htmlunit-core-js-2.7-SNAPSHOT.jar",
64
+ "lib/celerity/htmlunit/nekohtml-1.9.14-20091130.152932-3.jar",
65
+ "lib/celerity/htmlunit/sac-1.3.jar",
66
+ "lib/celerity/htmlunit/serializer-2.7.1.jar",
67
+ "lib/celerity/htmlunit/xalan-2.7.1.jar",
68
+ "lib/celerity/htmlunit/xercesImpl-2.9.1.jar",
69
+ "lib/celerity/htmlunit/xml-apis-1.3.04.jar",
70
+ "lib/celerity/identifier.rb",
71
+ "lib/celerity/ignoring_web_connection.rb",
72
+ "lib/celerity/input_element.rb",
73
+ "lib/celerity/javascript_debugger.rb",
74
+ "lib/celerity/listener.rb",
75
+ "lib/celerity/resources/no_viewer.png",
76
+ "lib/celerity/short_inspect.rb",
77
+ "lib/celerity/util.rb",
78
+ "lib/celerity/version.rb",
79
+ "lib/celerity/viewer_connection.rb",
80
+ "lib/celerity/watir_compatibility.rb",
81
+ "lib/celerity/xpath_support.rb",
82
+ "tasks/benchmark.rake",
83
+ "tasks/check.rake",
84
+ "tasks/clean.rake",
85
+ "tasks/fix.rake",
86
+ "tasks/jar.rake",
87
+ "tasks/jeweler.rake",
88
+ "tasks/rdoc.rake",
89
+ "tasks/snapshot.rake",
90
+ "tasks/spec.rake",
91
+ "tasks/website.rake",
92
+ "tasks/yard.rake"
93
+ ]
94
+ s.homepage = %q{http://github.com/jarib/celerity}
95
+ s.rdoc_options = ["--charset=UTF-8"]
96
+ s.require_paths = ["lib"]
97
+ s.rubyforge_project = %q{celerity}
98
+ s.rubygems_version = %q{1.3.5}
99
+ s.summary = %q{Celerity is a JRuby library for easy and fast functional test automation for web applications.}
100
+
101
+ if s.respond_to? :specification_version then
102
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
103
+ s.specification_version = 3
104
+
105
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
106
+ s.add_development_dependency(%q<rspec>, [">= 0"])
107
+ s.add_development_dependency(%q<yard>, [">= 0"])
108
+ s.add_development_dependency(%q<sinatra>, [">= 0.9.4"])
109
+ else
110
+ s.add_dependency(%q<rspec>, [">= 0"])
111
+ s.add_dependency(%q<yard>, [">= 0"])
112
+ s.add_dependency(%q<sinatra>, [">= 0.9.4"])
113
+ end
114
+ else
115
+ s.add_dependency(%q<rspec>, [">= 0"])
116
+ s.add_dependency(%q<yard>, [">= 0"])
117
+ s.add_dependency(%q<sinatra>, [">= 0.9.4"])
118
+ end
119
+ end
120
+
@@ -0,0 +1,77 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
2
+
3
+ raise "Celerity only works on JRuby at the moment." unless RUBY_PLATFORM =~ /java/
4
+
5
+ require "java"
6
+ require "logger"
7
+ require "uri"
8
+ require "pp"
9
+ require "timeout"
10
+ require "time"
11
+ require "socket"
12
+ require "fileutils"
13
+ require "thread"
14
+
15
+ module Celerity
16
+ Log = Logger.new($DEBUG ? $stderr : nil)
17
+ Log.level = Logger::DEBUG
18
+
19
+ @index_offset = 1
20
+ class << self
21
+
22
+ #
23
+ # This index_offset attribute controls the indexing used when locating
24
+ # elements by :index or fetching from Celerity::ElementCollections.
25
+ #
26
+ # By default it is set to 1 for Watir compatibility, but users who use
27
+ # Celerity exlusively may want it set to 0 to make Celerity more consistent with Ruby.
28
+ #
29
+ attr_accessor :index_offset
30
+ end
31
+
32
+ DIR = File.expand_path(File.dirname(__FILE__) + "/celerity")
33
+ end
34
+
35
+ require "celerity/version"
36
+ require "celerity/htmlunit"
37
+ require "celerity/exception"
38
+ require "celerity/clickable_element"
39
+ require "celerity/disabled_element"
40
+ require "celerity/element_collection"
41
+ require "celerity/collections"
42
+ require "celerity/element_locator"
43
+ require "celerity/identifier"
44
+ require "celerity/short_inspect"
45
+ require "celerity/container"
46
+ require "celerity/xpath_support"
47
+ require "celerity/element"
48
+ require "celerity/input_element"
49
+ require "celerity/elements/non_control_elements"
50
+ require "celerity/elements/button"
51
+ require "celerity/elements/file_field"
52
+ require "celerity/elements/form"
53
+ require "celerity/elements/frame"
54
+ require "celerity/elements/image"
55
+ require "celerity/elements/label"
56
+ require "celerity/elements/link"
57
+ require "celerity/elements/meta"
58
+ require "celerity/elements/option"
59
+ require "celerity/elements/radio_check"
60
+ require "celerity/elements/select_list"
61
+ require "celerity/elements/table"
62
+ require "celerity/elements/table_elements"
63
+ require "celerity/elements/table_cell"
64
+ require "celerity/elements/table_row"
65
+ require "celerity/elements/text_field"
66
+ require "celerity/util"
67
+ require "celerity/default_viewer"
68
+ require "celerity/listener"
69
+ require "celerity/ignoring_web_connection"
70
+ require "celerity/javascript_debugger"
71
+ require "celerity/viewer_connection"
72
+ require "celerity/browser"
73
+ require "celerity/watir_compatibility"
74
+
75
+ # undefine deprecated methods to use them for Element attributes
76
+ Object.send :undef_method, :id if Object.method_defined? "id"
77
+ Object.send :undef_method, :type if Object.method_defined? "type"
@@ -0,0 +1,893 @@
1
+ module Celerity
2
+ class Browser
3
+ include Container
4
+ include XpathSupport
5
+
6
+ attr_accessor :page, :object, :charset
7
+ attr_reader :webclient, :viewer, :options
8
+
9
+ #
10
+ # Initialize a browser and go to the given URL
11
+ #
12
+ # @param [String] uri The URL to go to.
13
+ # @return [Celerity::Browser] instance.
14
+ #
15
+
16
+ def self.start(uri)
17
+ browser = new
18
+ browser.goto(uri)
19
+ browser
20
+ end
21
+
22
+ #
23
+ # Not implemented. Use ClickableElement#click_and_attach instead.
24
+ #
25
+
26
+ def self.attach(*args)
27
+ raise NotImplementedError, "use ClickableElement#click_and_attach instead"
28
+ end
29
+
30
+ #
31
+ # Creates a browser object.
32
+ #
33
+ # @see Celerity::Container for an introduction to the main API.
34
+ #
35
+ # @option opts :browser [:internet_explorer, :firefox, :firefox3] (:firefox3) Set the BrowserVersion used by HtmlUnit. Defaults to Firefox 3.
36
+ # @option opts :charset [String] ("UTF-8") Specify the charset that webclient will use for requests.
37
+ # @option opts :css [Boolean] (false) Enable CSS. Disabled by default.
38
+ # @option opts :ignore_pattern [Regexp] See Browser#ignore_pattern=
39
+ # @option opts :javascript_enabled [Boolean] (true) Enable/disable JavaScript evaluation. Enabled by default.
40
+ # @option opts :javascript_exceptions [Boolean] (false) Raise exceptions on script errors. Disabled by default.
41
+ # @option opts :log_level [Symbol] (:warning) @see log_level=
42
+ # @option opts :proxy [String] (nil) Proxy server to use, in address:port format.
43
+ # @option opts :refresh_handler [:immediate, :waiting, :threaded] (:immediate) Set HtmlUnit's refresh handler.
44
+ # @option opts :render [:html, :xml] (:html) What DOM representation to send to connected viewers.
45
+ # @option opts :resynchronize [Boolean] (false) Use HtmlUnit::NicelyResynchronizingAjaxController to resynchronize Ajax calls.
46
+ # @option opts :secure_ssl [Boolean] (true) Enable/disable secure SSL. Enabled by default.
47
+ # @option opts :status_code_exceptions [Boolean] (false) Raise exceptions on failing status codes (404 etc.). Disabled by default.
48
+ # @option opts :user_agent [String] Override the User-Agent set by the :browser option
49
+ # @option opts :viewer [String, false] ("127.0.0.1:6429") Connect to a CelerityViewer if available.
50
+ #
51
+ # @return [Celerity::Browser] An instance of the browser.
52
+ #
53
+ # @api public
54
+ #
55
+
56
+ def initialize(opts = {})
57
+ unless opts.is_a?(Hash)
58
+ raise TypeError, "wrong argument type #{opts.class}, expected Hash"
59
+ end
60
+
61
+ unless (render_types = [:html, :xml, nil, 'html', 'xml']).include?(opts[:render])
62
+ raise ArgumentError, "expected one of #{render_types.inspect} for key :render"
63
+ end
64
+
65
+ @options = opts.dup # keep the unmodified version around as well
66
+ opts = opts.dup # we'll delete from opts, so dup to avoid side effects
67
+
68
+ @render_type = opts.delete(:render) || :html
69
+ @charset = opts.delete(:charset) || "UTF-8"
70
+ self.log_level = opts.delete(:log_level) || :off
71
+
72
+ @page = nil
73
+ @error_checkers = []
74
+ @browser = self # for Container#browser
75
+
76
+ setup_webclient opts
77
+ setup_viewer opts.delete(:viewer)
78
+
79
+ raise ArgumentError, "unknown option #{opts.inspect}" unless opts.empty?
80
+ end
81
+
82
+ def inspect
83
+ short_inspect :exclude => %w[@webclient @browser @object @options @listener @event_listener]
84
+ end
85
+
86
+ #
87
+ # Goto the given URL
88
+ #
89
+ # @param [String] uri The url.
90
+ # @return [String] The url.
91
+ #
92
+
93
+ def goto(uri)
94
+ uri = "http://#{uri}" unless uri =~ %r{://}
95
+
96
+ request = HtmlUnit::WebRequestSettings.new(::Java::JavaNet::URL.new(uri))
97
+ request.setCharset(@charset)
98
+
99
+ rescue_status_code_exception do
100
+ self.page = @webclient.getPage(request)
101
+ end
102
+
103
+ url()
104
+ end
105
+
106
+ #
107
+ # Set the credentials used for basic HTTP authentication. (Celerity only)
108
+ #
109
+ # Example:
110
+ # browser.credentials = "username:password"
111
+ #
112
+ # @param [String] A string with username / password, separated by a colon
113
+ #
114
+
115
+ def credentials=(string)
116
+ user, pass = string.split(":")
117
+ dcp = HtmlUnit::DefaultCredentialsProvider.new
118
+ dcp.addCredentials(user, pass)
119
+ @webclient.setCredentialsProvider(dcp)
120
+ end
121
+
122
+ #
123
+ # Unsets the current page / closes all windows
124
+ #
125
+
126
+ def close
127
+ @page = nil
128
+ @webclient.closeAllWindows
129
+ @viewer.close
130
+ end
131
+
132
+ #
133
+ # @return [String] the URL of the current page
134
+ #
135
+
136
+ def url
137
+ assert_exists
138
+ @page.getWebResponse.getRequestUrl.toString
139
+ end
140
+
141
+ #
142
+ # @return [String] the title of the current page
143
+ #
144
+
145
+ def title
146
+ @page ? @page.getTitleText : ''
147
+ end
148
+
149
+ #
150
+ # @return [String] the value of window.status
151
+ #
152
+
153
+ def status
154
+ execute_script "window.status" # avoid the listener overhead
155
+ end
156
+
157
+ #
158
+ # @return [String] the HTML content of the current page
159
+ #
160
+
161
+ def html
162
+ @page ? @page.getWebResponse.getContentAsString(@charset) : ''
163
+ end
164
+
165
+ #
166
+ # @return [String] the XML representation of the DOM
167
+ #
168
+
169
+ def xml
170
+ return '' unless @page
171
+ return @page.asXml if @page.respond_to?(:asXml)
172
+ return text # fallback to text (for exampel for "plain/text" pages)
173
+ end
174
+
175
+ #
176
+ # @return [String] a text representation of the current page
177
+ #
178
+
179
+ def text
180
+ return '' unless @page
181
+
182
+ if @page.respond_to?("getContent")
183
+ string = @page.getContent.strip
184
+ elsif doc = @page.documentElement
185
+ string = doc.asText.strip
186
+ else
187
+ string = ''
188
+ end
189
+
190
+ # Celerity::Util.normalize_text(string)
191
+ string
192
+ end
193
+
194
+ #
195
+ # @return [Hash] response headers as a hash
196
+ #
197
+
198
+ def response_headers
199
+ return {} unless @page
200
+
201
+ Hash[*@page.getWebResponse.getResponseHeaders.map { |obj| [obj.name, obj.value] }.flatten]
202
+ end
203
+
204
+ #
205
+ # @return [Fixnum] status code of the last request
206
+ #
207
+
208
+ def status_code
209
+ @page.getWebResponse.getStatusCode
210
+ end
211
+
212
+ #
213
+ # @return [String] content-type as in 'text/html'
214
+ #
215
+
216
+ def content_type
217
+ return '' unless @page
218
+
219
+ @page.getWebResponse.getContentType
220
+ end
221
+
222
+ #
223
+ # @return [IO, nil] page contents as an IO, returns nil if no page is loaded.
224
+ #
225
+
226
+ def io
227
+ return nil unless @page
228
+
229
+ @page.getWebResponse.getContentAsStream.to_io
230
+ end
231
+
232
+ #
233
+ # Check if the current page contains the given text.
234
+ #
235
+ # @param [String, Regexp] expected_text The text to look for.
236
+ # @return [Numeric, nil] The index of the matched text, or nil if it isn't found.
237
+ # @raise [TypeError]
238
+ #
239
+
240
+ def contains_text(expected_text)
241
+ return nil unless exist?
242
+ super
243
+ end
244
+
245
+ #
246
+ # @return [HtmlUnit::HtmlHtml] the underlying HtmlUnit document.
247
+ #
248
+
249
+ def document
250
+ @object
251
+ end
252
+
253
+ #
254
+ # Goto back one history item
255
+ # @return [String] The url of the resulting page.
256
+ #
257
+
258
+ def back
259
+ @webclient.getCurrentWindow.getHistory.back
260
+ refresh_page_from_window
261
+
262
+ url
263
+ end
264
+
265
+ #
266
+ # Go forward one history item
267
+ # @return [String] The url of the resulting page.
268
+ #
269
+
270
+ def forward
271
+ @webclient.getCurrentWindow.getHistory.forward
272
+ refresh_page_from_window
273
+
274
+ url
275
+ end
276
+
277
+ #
278
+ # Wait for javascript jobs to finish
279
+ #
280
+
281
+ def wait
282
+ assert_exists
283
+ @webclient.waitForBackgroundJavaScript(10000);
284
+ end
285
+
286
+ #
287
+ # Refresh the current page
288
+ #
289
+
290
+ def refresh
291
+ assert_exists
292
+ @page.refresh
293
+ end
294
+
295
+ #
296
+ # Clears all cookies. (Celerity only)
297
+ #
298
+
299
+ def clear_cookies
300
+ @webclient.getCookieManager.clearCookies
301
+ end
302
+
303
+ #
304
+ # Clears the cache of "compiled JavaScript files and parsed CSS snippets"
305
+ #
306
+
307
+ def clear_cache
308
+ @webclient.cache.clear
309
+ end
310
+
311
+ #
312
+ # Get the cookies for this session. (Celerity only)
313
+ #
314
+ # @return [Hash<domain, Hash<name, value>>]
315
+ #
316
+
317
+ def cookies
318
+ result = Hash.new { |hash, key| hash[key] = {} }
319
+
320
+ cookies = @webclient.getCookieManager.getCookies
321
+ cookies.each do |cookie|
322
+ result[cookie.getDomain][cookie.getName] = cookie.getValue
323
+ end
324
+
325
+ result
326
+ end
327
+
328
+ #
329
+ # Add a cookie with the given parameters (Celerity only)
330
+ #
331
+ # @param [String] domain
332
+ # @param [String] name
333
+ # @param [String] value
334
+ #
335
+ # @option opts :path [String] ("/") A path
336
+ # @option opts :expires [Time] (1 day from now) An expiration date
337
+ # @option opts :secure [Boolean] (false)
338
+ #
339
+
340
+ def add_cookie(domain, name, value, opts = {})
341
+ path = opts.delete(:path) || "/"
342
+ max_age = opts.delete(:expires) || (Time.now + 60*60*24) # not sure if this is correct
343
+ secure = opts.delete(:secure) || false
344
+
345
+ raise(ArgumentError, "unknown option: #{opts.inspect}") unless opts.empty?
346
+
347
+ cookie = HtmlUnit::Util::Cookie.new(domain, name, value, path, max_age, secure)
348
+ @webclient.getCookieManager.addCookie cookie
349
+
350
+ cookie
351
+ end
352
+
353
+ #
354
+ # Remove the cookie with the given domain and name (Celerity only)
355
+ #
356
+ # @param [String] domain
357
+ # @param [String] name
358
+ #
359
+ # @raise [CookieNotFoundError] if the cookie doesn't exist
360
+ #
361
+
362
+ def remove_cookie(domain, name)
363
+ cm = @webclient.getCookieManager
364
+ cookie = cm.getCookies.find { |c| c.getDomain == domain && c.getName == name }
365
+
366
+ if cookie.nil?
367
+ raise CookieNotFoundError, "no cookie with domain #{domain.inspect} and name #{name.inspect}"
368
+ end
369
+
370
+ cm.removeCookie(cookie)
371
+ end
372
+
373
+ #
374
+ # Execute the given JavaScript on the current page.
375
+ # @return [Object] The resulting Object
376
+ #
377
+
378
+ def execute_script(source)
379
+ assert_exists
380
+ @page.executeJavaScript(source.to_s).getJavaScriptResult
381
+ end
382
+
383
+ # experimental - should be removed?
384
+ def send_keys(keys)
385
+ keys = keys.gsub(/\s*/, '').scan(/((?:\{[A-Z]+?\})|.)/u).flatten
386
+ keys.each do |key|
387
+ element = @page.getFocusedElement
388
+ case key
389
+ when "{TAB}"
390
+ @page.tabToNextElement
391
+ when /\w/
392
+ element.type(key)
393
+ else
394
+ raise NotImplementedError
395
+ end
396
+ end
397
+ end
398
+
399
+ #
400
+ # Wait until the given block evaluates to true (Celerity only)
401
+ #
402
+ # @param [Fixnum] timeout Number of seconds to wait before timing out (default: 30).
403
+ # @yieldparam [Celerity::Browser] browser The browser instance.
404
+ # @see Celerity::Browser#resynchronized
405
+ #
406
+
407
+ def wait_until(timeout = 30, &block)
408
+ returned = nil
409
+
410
+ Timeout.timeout(timeout) do
411
+ until returned = yield(self)
412
+ refresh_page_from_window
413
+ sleep 0.1
414
+ end
415
+ end
416
+
417
+ returned
418
+ end
419
+
420
+ #
421
+ # Wait while the given block evaluates to true (Celerity only)
422
+ #
423
+ # @param [Fixnum] timeout Number of seconds to wait before timing out (default: 30).
424
+ # @yieldparam [Celerity::Browser] browser The browser instance.
425
+ # @see Celerity::Browser#resynchronized
426
+ #
427
+
428
+ def wait_while(timeout = 30, &block)
429
+ returned = nil
430
+
431
+ Timeout.timeout(timeout) do
432
+ while returned = yield(self)
433
+ refresh_page_from_window
434
+ sleep 0.1
435
+ end
436
+ end
437
+
438
+ returned
439
+ end
440
+
441
+ #
442
+ # Allows you to temporarily switch to HtmlUnit's NicelyResynchronizingAjaxController
443
+ # to resynchronize ajax calls.
444
+ #
445
+ # @browser.resynchronized do |b|
446
+ # b.link(:id, 'trigger_ajax_call').click
447
+ # end
448
+ #
449
+ # @yieldparam [Celerity::Browser] browser The current browser object.
450
+ # @see Celerity::Browser#new for how to configure the browser to always use this.
451
+ #
452
+
453
+ def resynchronized(&block)
454
+ old_controller = @webclient.ajaxController
455
+ @webclient.setAjaxController(::HtmlUnit::NicelyResynchronizingAjaxController.new)
456
+ yield self
457
+ @webclient.setAjaxController(old_controller)
458
+ end
459
+
460
+ #
461
+ # Allows you to temporarliy switch to HtmlUnit's default AjaxController, so
462
+ # ajax calls are performed asynchronously. This is useful if you have created
463
+ # the Browser with :resynchronize => true, but want to switch it off temporarily.
464
+ #
465
+ # @yieldparam [Celerity::Browser] browser The current browser object.
466
+ # @see Celerity::Browser#new
467
+ #
468
+
469
+ def asynchronized(&block)
470
+ old_controller = @webclient.ajaxController
471
+ @webclient.setAjaxController(::HtmlUnit::AjaxController.new)
472
+ yield self
473
+ @webclient.setAjaxController(old_controller)
474
+ end
475
+
476
+ #
477
+ # Start or stop HtmlUnit's DebuggingWebConnection. (Celerity only)
478
+ # The output will go to /tmp/«name»
479
+ #
480
+ # @param [String] name directory name
481
+ # @param [block] blk block to execute
482
+ #
483
+
484
+ def debug_web_connection(name, &blk)
485
+ old_wc = @webclient.getWebConnection
486
+
487
+ @webclient.setWebConnection HtmlUnit::Util::DebuggingWebConnection.new(old_wc, name)
488
+ res = yield
489
+ @webclient.setWebConnection old_wc
490
+
491
+ res
492
+ end
493
+
494
+ def trace_javascript(debugger_klass = Celerity::JavascriptDebugger, &blk)
495
+ context_factory = @webclient.getJavaScriptEngine.getContextFactory
496
+ context_factory.setDebugger debugger_klass.new
497
+ yield
498
+ context_factory.setDebugger nil
499
+ end
500
+
501
+ #
502
+ # Add a listener block for one of the available types. (Celerity only)
503
+ # Types map to HtmlUnit interfaces like this:
504
+ #
505
+ # :status => StatusHandler
506
+ # :alert => AlertHandler ( window.alert() )
507
+ # :web_window_event => WebWindowListener
508
+ # :html_parser => HTMLParserListener
509
+ # :incorrectness => IncorrectnessListener
510
+ # :confirm => ConfirmHandler ( window.confirm() )
511
+ # :prompt => PromptHandler ( window.prompt() )
512
+ #
513
+ # Examples:
514
+ #
515
+ # browser.add_listener(:status) { |page, message| ... }
516
+ # browser.add_listener(:alert) { |page, message| ... }
517
+ # browser.add_listener(:web_window_event) { |web_window_event| ... }
518
+ # browser.add_listener(:html_parser) { |message, url, line, column, key| ... }
519
+ # browser.add_listener(:incorrectness) { |message, origin| ... }
520
+ # browser.add_listener(:confirm) { |page, message| ...; true }
521
+ # browser.add_listener(:prompt) { |page, message| ... }
522
+ #
523
+ #
524
+ # @param [Symbol] type One of the above symbols.
525
+ # @param [Proc] block A block to be executed for events of this type.
526
+ #
527
+
528
+ def add_listener(type, &block)
529
+ listener.add_listener(type, &block)
530
+ end
531
+
532
+ def remove_listener(type, block)
533
+ listener.remove_listener(type, block)
534
+ end
535
+
536
+ #
537
+ # Specify a boolean value to click either 'OK' or 'Cancel' in any confirm
538
+ # dialogs that might show up during the duration of the given block.
539
+ #
540
+ # (Celerity only)
541
+ #
542
+ # @param [Boolean] bool true to click 'OK', false to click 'cancel'
543
+ # @param [Proc] block A block that will trigger the confirm() call(s).
544
+ #
545
+
546
+ def confirm(bool, &block)
547
+ blk = lambda { bool }
548
+
549
+ listener.add_listener(:confirm, &blk)
550
+ yield
551
+ listener.remove_listener(:confirm, blk)
552
+ end
553
+
554
+ #
555
+ # Add a 'checker' proc that will be run on every page load
556
+ #
557
+ # @param [Proc] checker The proc to be run (can also be given as a block)
558
+ # @yieldparam [Celerity::Browser] browser The current browser object.
559
+ # @raise [ArgumentError] if no Proc or block was given.
560
+ #
561
+
562
+ def add_checker(checker = nil, &block)
563
+ if block_given?
564
+ @error_checkers << block
565
+ elsif Proc === checker
566
+ @error_checkers << checker
567
+ else
568
+ raise ArgumentError, "argument must be a Proc or block"
569
+ end
570
+ end
571
+
572
+ #
573
+ # Remove the given checker from the list of checkers
574
+ # @param [Proc] checker The Proc to disable.
575
+ #
576
+
577
+ def disable_checker(checker)
578
+ @error_checkers.delete(checker)
579
+ end
580
+
581
+ #
582
+ # :finest, :finer, :fine, :config, :info, :warning, :severe, or :off, :all
583
+ #
584
+ # @return [Symbol] the current log level
585
+ #
586
+
587
+ def log_level
588
+ Celerity::Util.logger_for('com.gargoylesoftware.htmlunit').level.to_s.downcase.to_sym
589
+ end
590
+
591
+ #
592
+ # Set Java log level (default is :warning, can be any of :all, :finest, :finer, :fine, :config, :info, :warning, :severe, :off)
593
+ #
594
+ # @param [Symbol] level The new log level.
595
+ #
596
+
597
+ def log_level=(level)
598
+ log_level = java.util.logging.Level.const_get(level.to_s.upcase)
599
+
600
+ [ 'com.gargoylesoftware.htmlunit',
601
+ 'com.gargoylesoftware.htmlunit.html',
602
+ 'com.gargoylesoftware.htmlunit.javascript',
603
+ 'org.apache.commons.httpclient'
604
+ ].each { |package| Celerity::Util.logger_for(package).level = log_level }
605
+
606
+ level
607
+ end
608
+
609
+ #
610
+ # If a request is made to an URL that matches the pattern set here, Celerity
611
+ # will ignore the request and return an empty page with content type "text/html" instead.
612
+ #
613
+ # This is useful to block unwanted requests (like ads/banners).
614
+ #
615
+
616
+ def ignore_pattern=(regexp)
617
+ unless regexp.kind_of?(Regexp)
618
+ raise TypeError, "expected Regexp, got #{regexp.inspect}:#{regexp.class}"
619
+ end
620
+
621
+ Celerity::IgnoringWebConnection.new(@webclient, regexp)
622
+ end
623
+
624
+ #
625
+ # Checks if we have a page currently loaded.
626
+ # @return [true, false]
627
+ #
628
+
629
+ def exist?
630
+ !!@page
631
+ end
632
+ alias_method :exists?, :exist?
633
+
634
+ #
635
+ # Turn on/off javascript exceptions
636
+ #
637
+ # @param [Bool]
638
+ #
639
+
640
+ def javascript_exceptions=(bool)
641
+ @webclient.throwExceptionOnScriptError = bool
642
+ end
643
+
644
+ def javascript_exceptions
645
+ @webclient.throwExceptionOnScriptError
646
+ end
647
+
648
+ #
649
+ # Turn on/off status code exceptions
650
+ #
651
+ # @param [Bool]
652
+ #
653
+
654
+ def status_code_exceptions=(bool)
655
+ @webclient.throwExceptionOnFailingStatusCode = bool
656
+ end
657
+
658
+ def status_code_exceptions
659
+ @webclient.throwExceptionOnFailingStatusCode
660
+ end
661
+
662
+ #
663
+ # Turn on/off CSS loading
664
+ #
665
+ # @param [Bool]
666
+ #
667
+
668
+ def css=(bool)
669
+ @webclient.cssEnabled = bool
670
+ end
671
+
672
+ def css
673
+ @webclient.cssEnabled
674
+ end
675
+
676
+ def refresh_handler=(symbol)
677
+ handler = case symbol
678
+ when :waiting
679
+ HtmlUnit::WaitingRefreshHandler.new
680
+ when :threaded
681
+ HtmlUnit::ThreadedRefreshHandler.new
682
+ when :immediate
683
+ HtmlUnit::ImmediateRefreshHandler.new
684
+ else
685
+ raise ArgumentError, "expected :waiting, :threaded or :immediate"
686
+ end
687
+
688
+ @webclient.setRefreshHandler handler
689
+ end
690
+
691
+ #
692
+ # Turn on/off secure SSL
693
+ #
694
+ # @param [Bool]
695
+ #
696
+
697
+ def secure_ssl=(bool)
698
+ @webclient.useInsecureSSL = !bool
699
+ end
700
+
701
+ #
702
+ # Turn on/off JavaScript execution
703
+ #
704
+ # @param [Bool]
705
+ #
706
+
707
+ def javascript_enabled=(bool)
708
+ @webclient.setJavaScriptEnabled(bool)
709
+ end
710
+
711
+ def javascript_enabled
712
+ @webclient.isJavaScriptEnabled
713
+ end
714
+
715
+ #
716
+ # Sets the current page object for the browser
717
+ #
718
+ # @param [HtmlUnit::HtmlPage] value The page to set.
719
+ # @api private
720
+ #
721
+
722
+ def page=(value)
723
+ return if @page == value
724
+ @page = value
725
+
726
+ if @page.respond_to?("getDocumentElement")
727
+ @object = @page.getDocumentElement || @object
728
+ elsif @page.is_a? HtmlUnit::UnexpectedPage
729
+ raise UnexpectedPageException, @page.getWebResponse.getContentType
730
+ end
731
+
732
+ render unless @viewer == DefaultViewer
733
+ run_error_checks
734
+
735
+ value
736
+ end
737
+
738
+ #
739
+ # Check that we have a @page object.
740
+ #
741
+ # @raise [UnknownObjectException] if no page is loaded.
742
+ # @api private
743
+ #
744
+
745
+ def assert_exists
746
+ raise UnknownObjectException, "no page loaded" unless exist?
747
+ end
748
+
749
+ #
750
+ # Returns the element that currently has the focus (Celerity only)
751
+ #
752
+
753
+ def focused_element
754
+ element_from_dom_node(page.getFocusedElement())
755
+ end
756
+
757
+ #
758
+ # Enable Celerity's internal WebWindowEventListener
759
+ #
760
+ # @api private
761
+ #
762
+
763
+ def enable_event_listener
764
+ @event_listener ||= lambda do |event|
765
+ self.page = @page ? @page.getEnclosingWindow.getEnclosedPage : event.getNewPage
766
+ end
767
+
768
+ listener.add_listener(:web_window_event, &@event_listener)
769
+ end
770
+
771
+ #
772
+ # Disable Celerity's internal WebWindowEventListener
773
+ #
774
+ # @api private
775
+ #
776
+
777
+ def disable_event_listener
778
+ listener.remove_listener(:web_window_event, @event_listener)
779
+
780
+ if block_given?
781
+ result = yield
782
+ enable_event_listener
783
+
784
+ result
785
+ end
786
+ end
787
+
788
+ private
789
+
790
+ #
791
+ # Runs the all the checker procs added by +add_checker+
792
+ #
793
+ # @see add_checker
794
+ # @api private
795
+ #
796
+
797
+ def run_error_checks
798
+ @error_checkers.each { |e| e[self] }
799
+ end
800
+
801
+ #
802
+ # Configure the webclient according to the options given to #new.
803
+ # @see initialize
804
+ #
805
+
806
+ def setup_webclient(opts)
807
+ browser = (opts.delete(:browser) || :firefox3).to_sym
808
+
809
+ browser_version = case browser
810
+ when :firefox, :ff, :ff2
811
+ ::HtmlUnit::BrowserVersion::FIREFOX_2
812
+ when :firefox3, :ff3
813
+ ::HtmlUnit::BrowserVersion::FIREFOX_3
814
+ when :internet_explorer, :ie
815
+ ::HtmlUnit::BrowserVersion::INTERNET_EXPLORER_7
816
+ else
817
+ raise ArgumentError, "unknown browser: #{browser.inspect}"
818
+ end
819
+
820
+ if ua = opts.delete(:user_agent)
821
+ browser_version.setUserAgent(ua)
822
+ end
823
+
824
+ @webclient = if proxy = opts.delete(:proxy)
825
+ phost, pport = proxy.split(":")
826
+ ::HtmlUnit::WebClient.new(browser_version, phost, pport.to_i)
827
+ else
828
+ ::HtmlUnit::WebClient.new(browser_version)
829
+ end
830
+
831
+ self.javascript_exceptions = false unless opts.delete(:javascript_exceptions)
832
+ self.status_code_exceptions = false unless opts.delete(:status_code_exceptions)
833
+ self.css = false unless opts.delete(:css)
834
+ self.javascript_enabled = opts.delete(:javascript_enabled) != false
835
+ self.secure_ssl = opts.delete(:secure_ssl) != false
836
+ self.ignore_pattern = opts.delete(:ignore_pattern) if opts[:ignore_pattern]
837
+ self.refresh_handler = opts.delete(:refresh_handler) if opts[:refresh_handler]
838
+
839
+ if opts.delete(:resynchronize)
840
+ controller = ::HtmlUnit::NicelyResynchronizingAjaxController.new
841
+ @webclient.setAjaxController controller
842
+ end
843
+
844
+ enable_event_listener
845
+ end
846
+
847
+ def setup_viewer(option)
848
+ @viewer = DefaultViewer
849
+ return if option == false
850
+
851
+ host_string = option.kind_of?(String) ? option : "127.0.0.1:6429"
852
+ host, port = host_string.split(":")
853
+
854
+ if viewer = ViewerConnection.create(host, port.to_i)
855
+ @viewer = viewer
856
+ end
857
+ rescue Errno::ECONNREFUSED, SocketError => e
858
+ nil
859
+ end
860
+
861
+ #
862
+ # This *should* be unneccessary, but sometimes the page we get from the
863
+ # window is different (ie. a different object) from our current @page
864
+ # (Used by #wait_while and #wait_until)
865
+ #
866
+
867
+ def refresh_page_from_window
868
+ new_page = @page.getEnclosingWindow.getEnclosedPage
869
+
870
+ if new_page && (new_page != @page)
871
+ self.page = new_page
872
+ else
873
+ Log.debug "unneccessary refresh"
874
+ end
875
+ end
876
+
877
+ #
878
+ # Render the current page on the connected viewer.
879
+ # @api private
880
+ #
881
+
882
+ def render
883
+ @viewer.render_html(self.send(@render_type), url)
884
+ rescue Errno::ECONNREFUSED, Errno::ECONNRESET, Errno::EPIPE
885
+ @viewer = DefaultViewer
886
+ end
887
+
888
+ def listener
889
+ @listener ||= Celerity::Listener.new(@webclient)
890
+ end
891
+
892
+ end # Browser
893
+ end # Celerity