fletcherm-culerity 0.2.5

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 (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