celerity 0.0.4 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +33 -0
- data/README.txt +19 -9
- data/Rakefile +9 -3
- data/lib/celerity.rb +39 -39
- data/lib/celerity/browser.rb +538 -153
- data/lib/celerity/clickable_element.rb +48 -7
- data/lib/celerity/collections.rb +155 -131
- data/lib/celerity/container.rb +766 -385
- data/lib/celerity/default_viewer.rb +10 -0
- data/lib/celerity/disabled_element.rb +19 -2
- data/lib/celerity/element.rb +152 -83
- data/lib/celerity/element_collection.rb +106 -0
- data/lib/celerity/element_locator.rb +89 -66
- data/lib/celerity/elements/button.rb +23 -13
- data/lib/celerity/elements/file_field.rb +17 -5
- data/lib/celerity/elements/form.rb +21 -16
- data/lib/celerity/elements/frame.rb +75 -53
- data/lib/celerity/elements/image.rb +76 -63
- data/lib/celerity/elements/label.rb +4 -2
- data/lib/celerity/elements/link.rb +30 -18
- data/lib/celerity/elements/meta.rb +6 -0
- data/lib/celerity/{non_control_elements.rb → elements/non_control_elements.rb} +106 -76
- data/lib/celerity/elements/option.rb +16 -2
- data/lib/celerity/elements/radio_check.rb +55 -20
- data/lib/celerity/elements/select_list.rb +65 -29
- data/lib/celerity/elements/table.rb +141 -94
- data/lib/celerity/elements/table_cell.rb +13 -6
- data/lib/celerity/elements/{table_body.rb → table_elements.rb} +20 -8
- data/lib/celerity/elements/table_row.rb +23 -7
- data/lib/celerity/elements/text_field.rb +89 -33
- data/lib/celerity/exception.rb +77 -41
- data/lib/celerity/extra/method_generator.rb +42 -24
- data/lib/celerity/htmlunit.rb +49 -0
- data/lib/celerity/htmlunit/commons-collections-3.2.1.jar +0 -0
- data/lib/celerity/htmlunit/htmlunit-2.5-SNAPSHOT.jar +0 -0
- data/lib/celerity/htmlunit/htmlunit-core-js-2.5-SNAPSHOT.jar +0 -0
- data/lib/celerity/htmlunit/nekohtml-1.9.12-20090308.130127-11.jar +0 -0
- data/lib/celerity/htmlunit/serializer-2.7.1.jar +0 -0
- data/lib/celerity/htmlunit/xalan-2.7.1.jar +0 -0
- data/lib/celerity/htmlunit/xml-apis-1.3.04.jar +0 -0
- data/lib/celerity/identifier.rb +3 -2
- data/lib/celerity/input_element.rb +5 -5
- data/lib/celerity/listener.rb +135 -0
- data/lib/celerity/resources/no_viewer.png +0 -0
- data/lib/celerity/util.rb +88 -0
- data/lib/celerity/version.rb +4 -3
- data/lib/celerity/watir_compatibility.rb +35 -25
- data/tasks/jar.rake +57 -0
- metadata +35 -142
- data.tar.gz.sig +0 -0
- data/Manifest.txt +0 -150
- data/lib/celerity/element_collections.rb +0 -54
- data/lib/celerity/element_map.rb +0 -51
- data/lib/celerity/elements/table_footer.rb +0 -30
- data/lib/celerity/elements/table_header.rb +0 -30
- data/lib/celerity/htmlunit/commons-collections-3.2.jar +0 -0
- data/lib/celerity/htmlunit/download.sh +0 -23
- data/lib/celerity/htmlunit/htmlunit-2.2.jar +0 -0
- data/lib/celerity/htmlunit/htmlunit-core-js-2.2.jar +0 -0
- data/lib/celerity/htmlunit/nekohtml-1.9.8.jar +0 -0
- data/lib/celerity/htmlunit/xalan-2.7.0.jar +0 -0
- data/lib/celerity/htmlunit/xml-apis-1.0.b2.jar +0 -0
- data/spec/area_spec.rb +0 -97
- data/spec/areas_spec.rb +0 -40
- data/spec/browser_spec.rb +0 -266
- data/spec/button_spec.rb +0 -227
- data/spec/buttons_spec.rb +0 -39
- data/spec/checkbox_spec.rb +0 -302
- data/spec/checkboxes_spec.rb +0 -38
- data/spec/div_spec.rb +0 -207
- data/spec/divs_spec.rb +0 -39
- data/spec/element_spec.rb +0 -79
- data/spec/filefield_spec.rb +0 -123
- data/spec/filefields_spec.rb +0 -40
- data/spec/form_spec.rb +0 -59
- data/spec/forms_spec.rb +0 -41
- data/spec/frame_spec.rb +0 -121
- data/spec/frames_spec.rb +0 -71
- data/spec/hidden_spec.rb +0 -127
- data/spec/hiddens_spec.rb +0 -39
- data/spec/hn_spec.rb +0 -104
- data/spec/hns_spec.rb +0 -45
- data/spec/html/2000_spans.html +0 -2009
- data/spec/html/bug_duplicate_attributes.html +0 -14
- data/spec/html/bug_javascript_001.html +0 -11
- data/spec/html/form_js_bug.html +0 -11
- data/spec/html/forms_with_input_elements.html +0 -114
- data/spec/html/frame_1.html +0 -17
- data/spec/html/frame_2.html +0 -16
- data/spec/html/frames.html +0 -11
- data/spec/html/iframes.html +0 -12
- data/spec/html/images.html +0 -27
- data/spec/html/images/1.gif +0 -0
- data/spec/html/images/2.gif +0 -0
- data/spec/html/images/3.gif +0 -0
- data/spec/html/images/button.jpg +0 -0
- data/spec/html/images/circle.jpg +0 -0
- data/spec/html/images/map.gif +0 -0
- data/spec/html/images/map2.gif +0 -0
- data/spec/html/images/minus.gif +0 -0
- data/spec/html/images/originaltriangle.jpg +0 -0
- data/spec/html/images/plus.gif +0 -0
- data/spec/html/images/square.jpg +0 -0
- data/spec/html/images/triangle.jpg +0 -0
- data/spec/html/invalid_js.html +0 -11
- data/spec/html/latin1_text.html +0 -17
- data/spec/html/non_control_elements.html +0 -115
- data/spec/html/simple_ajax.html +0 -22
- data/spec/html/tables.html +0 -119
- data/spec/html/utf8_text.html +0 -15
- data/spec/htmlunit_spec.rb +0 -26
- data/spec/image_spec.rb +0 -220
- data/spec/images_spec.rb +0 -39
- data/spec/label_spec.rb +0 -79
- data/spec/labels_spec.rb +0 -40
- data/spec/li_spec.rb +0 -139
- data/spec/link_spec.rb +0 -189
- data/spec/links_spec.rb +0 -43
- data/spec/lis_spec.rb +0 -40
- data/spec/map_spec.rb +0 -102
- data/spec/maps_spec.rb +0 -40
- data/spec/meta_spec.rb +0 -8
- data/spec/ol_spec.rb +0 -87
- data/spec/ols_spec.rb +0 -40
- data/spec/option_spec.rb +0 -154
- data/spec/p_spec.rb +0 -171
- data/spec/pre_spec.rb +0 -135
- data/spec/pres_spec.rb +0 -40
- data/spec/ps_spec.rb +0 -40
- data/spec/radio_spec.rb +0 -299
- data/spec/radios_spec.rb +0 -42
- data/spec/select_list_spec.rb +0 -299
- data/spec/select_lists_spec.rb +0 -47
- data/spec/span_spec.rb +0 -184
- data/spec/spans_spec.rb +0 -64
- data/spec/spec.opts +0 -1
- data/spec/spec_helper.rb +0 -55
- data/spec/table_bodies_spec.rb +0 -57
- data/spec/table_body_spec.rb +0 -111
- data/spec/table_cell_spec.rb +0 -74
- data/spec/table_cells_spec.rb +0 -59
- data/spec/table_footer_spec.rb +0 -101
- data/spec/table_footers_spec.rb +0 -55
- data/spec/table_header_spec.rb +0 -101
- data/spec/table_headers_spec.rb +0 -55
- data/spec/table_row_spec.rb +0 -104
- data/spec/table_rows_spec.rb +0 -58
- data/spec/table_spec.rb +0 -160
- data/spec/tables_spec.rb +0 -42
- data/spec/text_field_spec.rb +0 -323
- data/spec/text_fields_spec.rb +0 -44
- data/spec/ul_spec.rb +0 -88
- data/spec/uls_spec.rb +0 -40
- data/spec/watir_compatibility_spec.rb +0 -260
- data/support/spec_server.rb +0 -73
- data/tasks/rspec.rake +0 -30
- data/tasks/specserver.rake +0 -21
- metadata.gz.sig +0 -0
data/History.txt
CHANGED
|
@@ -1,3 +1,36 @@
|
|
|
1
|
+
== 0.0.6 2009-03-19
|
|
2
|
+
* Support for meta, strong, dl, dt, dd, and em HTML elements.
|
|
3
|
+
* Update to HtmlUnit 2.5-SNAPSHOT.
|
|
4
|
+
* New options for Browser#new: :proxy, :charset, :render, :log_level
|
|
5
|
+
* Methods added:
|
|
6
|
+
- Browser#add_cookie
|
|
7
|
+
- Browser#asynchronized
|
|
8
|
+
- Browser#add_listener
|
|
9
|
+
- Browser#content_type
|
|
10
|
+
- Browser#cookies
|
|
11
|
+
- Browser#debug_web_connection
|
|
12
|
+
- Browser#focused_element
|
|
13
|
+
- Browser#io
|
|
14
|
+
- Browser#remove_cookie
|
|
15
|
+
- Browser#response_headers
|
|
16
|
+
- Browser#wait
|
|
17
|
+
- Browser#xml
|
|
18
|
+
- Browser#{element,elements}_by_xpath
|
|
19
|
+
- ClickableElement#{double,right}_click
|
|
20
|
+
- ElementCollection#{first,last}
|
|
21
|
+
* Methods removed:
|
|
22
|
+
- Browser#show_*
|
|
23
|
+
* Methods renamed:
|
|
24
|
+
- SelectList#get_all_contents => SelectList#options
|
|
25
|
+
- SelectList#get_selected_items => selected_options
|
|
26
|
+
- SelectList#clear_selection => SelectList#clear
|
|
27
|
+
* Add support for finding elements by their corresponding <label>.
|
|
28
|
+
* Recognize buttons of type image, reset, submit.
|
|
29
|
+
* Proxy support (see Browser.new)
|
|
30
|
+
* Lots of refactorings, bug fixes and minor enhancements.
|
|
31
|
+
|
|
32
|
+
Thanks to Hirobumi Hama, Kamal Fariz Mahyuddin and Thomas Marek for contributions in this release.
|
|
33
|
+
|
|
1
34
|
== 0.0.4 2008-08-18
|
|
2
35
|
* Minor enhancements
|
|
3
36
|
* Update HtmlUnit to 2.2
|
data/README.txt
CHANGED
|
@@ -2,14 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
* http://celerity.rubyforge.org/
|
|
4
4
|
|
|
5
|
-
== TUTORIAL:
|
|
6
|
-
|
|
7
|
-
* http://celerity.rubyforge.org/wiki/wiki.pl?GettingStarted
|
|
8
|
-
|
|
9
5
|
== DESCRIPTION:
|
|
10
6
|
|
|
11
|
-
Celerity is a JRuby
|
|
12
|
-
It
|
|
7
|
+
Celerity is a JRuby wrapper around HtmlUnit – a headless Java browser with
|
|
8
|
+
JavaScript support. It provides a simple API for programmatic navigation through
|
|
9
|
+
web applications. Celerity aims at being API compatible with Watir.
|
|
13
10
|
|
|
14
11
|
== FEATURES:
|
|
15
12
|
|
|
@@ -21,13 +18,18 @@ It is a wrapper around the HtmlUnit Java library and is currently aimed at provi
|
|
|
21
18
|
|
|
22
19
|
== REQUIREMENTS:
|
|
23
20
|
|
|
24
|
-
* JRuby 1.
|
|
21
|
+
* JRuby 1.2.0 or higher
|
|
25
22
|
* Java 6
|
|
26
23
|
|
|
27
24
|
== INSTALL:
|
|
28
25
|
|
|
29
|
-
jruby -S gem install celerity
|
|
30
|
-
|
|
26
|
+
`jruby -S gem install celerity`
|
|
27
|
+
|
|
28
|
+
or from GitHub
|
|
29
|
+
|
|
30
|
+
`jruby -S gem install jarib-celerity`
|
|
31
|
+
|
|
32
|
+
|
|
31
33
|
== EXAMPLE:
|
|
32
34
|
|
|
33
35
|
require "rubygems"
|
|
@@ -39,6 +41,14 @@ It is a wrapper around the HtmlUnit Java library and is currently aimed at provi
|
|
|
39
41
|
browser.button(:name, 'btnG').click
|
|
40
42
|
|
|
41
43
|
puts "yay" if browser.text.include? 'celerity.rubyforge.org'
|
|
44
|
+
|
|
45
|
+
== SOURCE
|
|
46
|
+
|
|
47
|
+
The source code is available at http://github.com/jarib/celerity/tree/master
|
|
48
|
+
|
|
49
|
+
== WIKI:
|
|
50
|
+
|
|
51
|
+
* http://github.com/jarib/celerity/wikis
|
|
42
52
|
|
|
43
53
|
== LICENSE:
|
|
44
54
|
|
data/Rakefile
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
$:.unshift("#{File.dirname(__FILE__)}/lib")
|
|
2
|
+
|
|
3
|
+
if File.exist?('config') # are we in a git clone
|
|
2
4
|
require 'config/requirements'
|
|
3
5
|
require 'config/hoe' # setup Hoe + all gem configuration
|
|
4
|
-
|
|
6
|
+
Dir['tasks/**/*.rake'].each { |rake| load rake }
|
|
7
|
+
else # in gem dir
|
|
8
|
+
load 'tasks/jar.rake'
|
|
9
|
+
load 'tasks/rdoc.rake'
|
|
5
10
|
end
|
|
6
|
-
|
|
11
|
+
|
|
12
|
+
|
data/lib/celerity.rb
CHANGED
|
@@ -1,60 +1,60 @@
|
|
|
1
1
|
$:.unshift(File.dirname(__FILE__)) unless $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
Jars = Dir[File.dirname(__FILE__) + '/celerity/htmlunit/*.jar']
|
|
5
|
-
end
|
|
3
|
+
raise "Celerity only works on JRuby at the moment." unless RUBY_PLATFORM =~ /java/
|
|
6
4
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
5
|
+
require 'java'
|
|
6
|
+
require "logger"
|
|
7
|
+
require "uri"
|
|
8
|
+
require "pp"
|
|
9
|
+
require "timeout"
|
|
10
|
+
require "time"
|
|
11
|
+
require 'drb'
|
|
12
|
+
require "fileutils"
|
|
13
|
+
require "thread"
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
module Celerity
|
|
16
|
+
Log = Logger.new($DEBUG ? $stderr : nil)
|
|
17
|
+
Log.level = Logger::DEBUG
|
|
15
18
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
else
|
|
22
|
-
raise "Celerity only works on JRuby at the moment."
|
|
19
|
+
INDEX_OFFSET = 1
|
|
20
|
+
DIR = File.expand_path(File.dirname(__FILE__) + "/celerity")
|
|
23
21
|
end
|
|
24
|
-
# require "rjb"
|
|
25
|
-
# Rjb::load(Celerity::Jars.join(";"))
|
|
26
|
-
# module HtmlUnit
|
|
27
|
-
# WebClient = Rjb::import('com.gargoylesoftware.htmlunit.WebClient')
|
|
28
|
-
# BrowserVersion = Rjb::import('com.gargoylesoftware.htmlunit.BrowserVersion')
|
|
29
|
-
# end
|
|
30
22
|
|
|
23
|
+
require "celerity/htmlunit"
|
|
31
24
|
require "celerity/version"
|
|
32
25
|
require "celerity/exception"
|
|
33
26
|
require "celerity/clickable_element"
|
|
34
27
|
require "celerity/disabled_element"
|
|
35
|
-
require "celerity/
|
|
28
|
+
require "celerity/element_collection"
|
|
36
29
|
require "celerity/collections"
|
|
37
30
|
require "celerity/element_locator"
|
|
38
31
|
require "celerity/identifier"
|
|
39
32
|
require "celerity/container"
|
|
40
33
|
require "celerity/element"
|
|
41
34
|
require "celerity/input_element"
|
|
42
|
-
require "celerity/non_control_elements"
|
|
43
|
-
|
|
44
|
-
require "celerity/
|
|
35
|
+
require "celerity/elements/non_control_elements"
|
|
36
|
+
require "celerity/elements/button.rb"
|
|
37
|
+
require "celerity/elements/file_field.rb"
|
|
38
|
+
require "celerity/elements/form.rb"
|
|
39
|
+
require "celerity/elements/frame.rb"
|
|
40
|
+
require "celerity/elements/image.rb"
|
|
41
|
+
require "celerity/elements/label.rb"
|
|
42
|
+
require "celerity/elements/link.rb"
|
|
43
|
+
require "celerity/elements/meta.rb"
|
|
44
|
+
require "celerity/elements/option.rb"
|
|
45
|
+
require "celerity/elements/radio_check.rb"
|
|
46
|
+
require "celerity/elements/select_list.rb"
|
|
47
|
+
require "celerity/elements/table.rb"
|
|
48
|
+
require "celerity/elements/table_elements.rb"
|
|
49
|
+
require "celerity/elements/table_cell.rb"
|
|
50
|
+
require "celerity/elements/table_row.rb"
|
|
51
|
+
require "celerity/elements/text_field.rb"
|
|
52
|
+
require "celerity/util"
|
|
53
|
+
require "celerity/default_viewer"
|
|
54
|
+
require "celerity/listener"
|
|
45
55
|
require "celerity/browser"
|
|
46
|
-
|
|
47
56
|
require "celerity/watir_compatibility"
|
|
48
57
|
|
|
49
|
-
require "logger"
|
|
50
|
-
require "uri"
|
|
51
|
-
require "pp"
|
|
52
|
-
require "time"
|
|
53
|
-
|
|
54
|
-
Log = Logger.new($DEBUG ? $stderr : nil)
|
|
55
|
-
Log.level = Logger::DEBUG
|
|
56
58
|
# undefine deprecated methods to use them for Element attributes
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
Object.send :undef_method, :type
|
|
60
|
-
end
|
|
59
|
+
Object.send :undef_method, :id if Object.method_defined? "id"
|
|
60
|
+
Object.send :undef_method, :type if Object.method_defined? "type"
|
data/lib/celerity/browser.rb
CHANGED
|
@@ -1,155 +1,492 @@
|
|
|
1
1
|
module Celerity
|
|
2
2
|
class Browser
|
|
3
3
|
include Container
|
|
4
|
-
|
|
4
|
+
|
|
5
|
+
attr_accessor :page, :object, :charset
|
|
5
6
|
attr_reader :webclient, :viewer
|
|
6
|
-
|
|
7
|
-
#
|
|
8
|
-
#
|
|
9
|
-
#
|
|
7
|
+
|
|
8
|
+
#
|
|
9
|
+
# Initialize a browser and go to the given URL
|
|
10
|
+
#
|
|
11
|
+
# @param [String] uri The URL to go to.
|
|
12
|
+
# @return [Celerity::Browser] instance.
|
|
13
|
+
#
|
|
14
|
+
|
|
10
15
|
def self.start(uri)
|
|
11
16
|
browser = new
|
|
12
17
|
browser.goto(uri)
|
|
13
18
|
browser
|
|
14
19
|
end
|
|
15
|
-
|
|
20
|
+
|
|
21
|
+
#
|
|
22
|
+
# Not implemented. Use ClickableElement#click_and_attach instead.
|
|
23
|
+
#
|
|
24
|
+
|
|
16
25
|
def self.attach(*args)
|
|
17
|
-
raise NotImplementedError, "
|
|
26
|
+
raise NotImplementedError, "use ClickableElement#click_and_attach instead"
|
|
18
27
|
end
|
|
19
|
-
|
|
28
|
+
|
|
29
|
+
def inspect
|
|
30
|
+
vars = (instance_variables - %w[@webclient @browser @object])
|
|
31
|
+
vars = vars.map { |var| "#{var}=#{instance_variable_get(var).inspect}" }.join(" ")
|
|
32
|
+
'#<%s:0x%s %s>' % [self.class.name, self.hash.to_s(16), vars]
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
#
|
|
20
36
|
# Creates a browser object.
|
|
21
37
|
#
|
|
22
|
-
# @
|
|
23
|
-
#
|
|
24
|
-
# @option :
|
|
25
|
-
#
|
|
26
|
-
# @option :css[
|
|
27
|
-
#
|
|
28
|
-
# @option :
|
|
29
|
-
#
|
|
30
|
-
# @option :
|
|
31
|
-
# @option :
|
|
32
|
-
#
|
|
33
|
-
# @option :
|
|
34
|
-
# Disabled by default.
|
|
38
|
+
# @see Celerity::Container for an introduction to the main API.
|
|
39
|
+
#
|
|
40
|
+
# @option opts :log_level [Symbol] (:warning) @see log_level=
|
|
41
|
+
# @option opts :browser [:firefox, :internet_explorer] (:internet_explorer) Set the BrowserVersion used by HtmlUnit. Defaults to Internet Explorer.
|
|
42
|
+
# @option opts :css [Boolean] (false) Enable CSS. Disabled by default.
|
|
43
|
+
# @option opts :secure_ssl [Boolean] (true) Disable secure SSL. Enabled by default.
|
|
44
|
+
# @option opts :resynchronize [Boolean] (false) Use HtmlUnit::NicelyResynchronizingAjaxController to resynchronize Ajax calls.
|
|
45
|
+
# @option opts :javascript_exceptions [Boolean] (false) Raise exceptions on script errors. Disabled by default.
|
|
46
|
+
# @option opts :status_code_exceptions [Boolean] (false) Raise exceptions on failing status codes (404 etc.). Disabled by default.
|
|
47
|
+
# @option opts :render [:html, :xml] (:html) What DOM representation to send to connected viewers.
|
|
48
|
+
# @option opts :charset [String] ("UTF-8") Specify the charset that webclient will use by default.
|
|
49
|
+
# @option opts :proxy [String] (nil) Proxy server to use, in address:port format.
|
|
35
50
|
#
|
|
36
51
|
# @return [Celerity::Browser] An instance of the browser.
|
|
52
|
+
#
|
|
37
53
|
# @api public
|
|
54
|
+
#
|
|
55
|
+
|
|
38
56
|
def initialize(opts = {})
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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]).include?(opts[:render])
|
|
62
|
+
raise ArgumentError, "expected one of #{render_types.inspect} for key :render"
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
@render_type = opts.delete(:render) || :html
|
|
66
|
+
@charset = opts.delete(:charset) || "UTF-8"
|
|
67
|
+
self.log_level = opts.delete(:log_level) || :warning
|
|
68
|
+
|
|
42
69
|
@last_url, @page = nil
|
|
43
|
-
@page_container = self
|
|
44
70
|
@error_checkers = []
|
|
45
|
-
|
|
46
|
-
self.log_level = :warning
|
|
47
|
-
|
|
48
|
-
browser = @opts[:browser] == :firefox ?
|
|
49
|
-
::HtmlUnit::BrowserVersion::FIREFOX_2 : ::HtmlUnit::BrowserVersion::INTERNET_EXPLORER_7_0
|
|
50
|
-
|
|
51
|
-
@webclient = ::HtmlUnit::WebClient.new(browser)
|
|
71
|
+
@browser = self # for Container#browser
|
|
52
72
|
|
|
53
|
-
|
|
54
|
-
|
|
73
|
+
setup_webclient(opts)
|
|
74
|
+
|
|
75
|
+
raise ArgumentError, "unknown option #{opts.inspect}" unless opts.empty?
|
|
76
|
+
find_viewer
|
|
55
77
|
end
|
|
56
|
-
|
|
78
|
+
|
|
79
|
+
#
|
|
57
80
|
# Goto the given URL
|
|
58
81
|
#
|
|
59
|
-
# @param [String]
|
|
60
|
-
# @return [String]
|
|
82
|
+
# @param [String] uri The url.
|
|
83
|
+
# @return [String] The url.
|
|
84
|
+
#
|
|
85
|
+
|
|
61
86
|
def goto(uri)
|
|
62
87
|
uri = "http://#{uri}" unless uri =~ %r{://}
|
|
63
|
-
|
|
64
|
-
uri
|
|
88
|
+
|
|
89
|
+
request = HtmlUnit::WebRequestSettings.new(::Java::JavaNet::URL.new(uri))
|
|
90
|
+
request.setCharset(@charset)
|
|
91
|
+
|
|
92
|
+
self.page = @webclient.getPage(request)
|
|
93
|
+
|
|
94
|
+
url()
|
|
65
95
|
end
|
|
66
|
-
|
|
67
|
-
#
|
|
96
|
+
|
|
97
|
+
#
|
|
98
|
+
# Set the credentials used for basic HTTP authentication. (Celerity only)
|
|
99
|
+
#
|
|
100
|
+
# Example:
|
|
101
|
+
# browser.credentials = "username:password"
|
|
102
|
+
#
|
|
103
|
+
# @param [String] A string with username / password, separated by a colon
|
|
104
|
+
#
|
|
105
|
+
|
|
106
|
+
def credentials=(string)
|
|
107
|
+
user, pass = string.split(":")
|
|
108
|
+
dcp = HtmlUnit::DefaultCredentialsProvider.new
|
|
109
|
+
dcp.addCredentials(user, pass)
|
|
110
|
+
@webclient.setCredentialsProvider(dcp)
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
#
|
|
114
|
+
# Unsets the current page / closes all windows
|
|
115
|
+
#
|
|
116
|
+
|
|
68
117
|
def close
|
|
69
118
|
@page = nil
|
|
119
|
+
@webclient.closeAllWindows
|
|
70
120
|
end
|
|
71
121
|
|
|
122
|
+
#
|
|
72
123
|
# @return [String] the URL of the current page
|
|
124
|
+
#
|
|
125
|
+
|
|
73
126
|
def url
|
|
74
127
|
assert_exists
|
|
75
|
-
@page.getWebResponse.
|
|
128
|
+
@page.getWebResponse.getRequestUrl.toString
|
|
76
129
|
end
|
|
77
|
-
|
|
130
|
+
|
|
131
|
+
#
|
|
78
132
|
# @return [String] the title of the current page
|
|
133
|
+
#
|
|
134
|
+
|
|
79
135
|
def title
|
|
80
136
|
@page ? @page.getTitleText : ''
|
|
81
137
|
end
|
|
82
138
|
|
|
139
|
+
#
|
|
83
140
|
# @return [String] the HTML content of the current page
|
|
141
|
+
#
|
|
142
|
+
|
|
84
143
|
def html
|
|
85
144
|
@page ? @page.getWebResponse.getContentAsString : ''
|
|
86
145
|
end
|
|
146
|
+
|
|
147
|
+
#
|
|
148
|
+
# @return [String] the XML representation of the DOM
|
|
149
|
+
#
|
|
150
|
+
|
|
151
|
+
def xml
|
|
152
|
+
return '' unless @page
|
|
153
|
+
return @page.asXml if @page.respond_to?(:asXml)
|
|
154
|
+
return text # fallback to text (for exampel for "plain/text" pages)
|
|
155
|
+
end
|
|
87
156
|
|
|
157
|
+
#
|
|
88
158
|
# @return [String] a text representation of the current page
|
|
159
|
+
#
|
|
160
|
+
|
|
89
161
|
def text
|
|
90
162
|
return '' unless @page
|
|
91
163
|
|
|
92
164
|
if @page.respond_to?("getContent")
|
|
93
|
-
@page.getContent
|
|
165
|
+
string = @page.getContent.strip
|
|
94
166
|
else
|
|
95
|
-
|
|
96
|
-
@page.documentElement.asText
|
|
97
|
-
|
|
98
|
-
# if @opts[:browser] == :firefox
|
|
99
|
-
# # # this is what firewatir does - only works with HtmlUnit::BrowserVersion::FIREFOX_2
|
|
100
|
-
# res = execute_script("document.body.textContent").getJavaScriptResult
|
|
101
|
-
# else
|
|
102
|
-
# # this only works with HtmlUnit::BrowserVersion::INTERNET_EXPLORER_*, and isn't identical to Watir's ole_object.innerText
|
|
103
|
-
# res = execute_script("document.body.innerText").getJavaScriptResult
|
|
104
|
-
# end
|
|
167
|
+
string = @page.documentElement.asText.strip
|
|
105
168
|
end
|
|
169
|
+
|
|
170
|
+
# Celerity::Util.normalize_text(string)
|
|
171
|
+
string
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
#
|
|
175
|
+
# @return [Hash] response headers as a hash
|
|
176
|
+
#
|
|
177
|
+
|
|
178
|
+
def response_headers
|
|
179
|
+
return {} unless @page
|
|
180
|
+
|
|
181
|
+
Hash[*@page.getWebResponse.getResponseHeaders.map { |obj| [obj.name, obj.value] }.flatten]
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
#
|
|
185
|
+
# @return [String] content-type as in 'text/html'
|
|
186
|
+
#
|
|
187
|
+
|
|
188
|
+
def content_type
|
|
189
|
+
return '' unless @page
|
|
190
|
+
|
|
191
|
+
@page.getWebResponse.getContentType
|
|
106
192
|
end
|
|
107
193
|
|
|
194
|
+
#
|
|
195
|
+
# @return [IO, nil] page contents as an IO, returns nil if no page is loaded.
|
|
196
|
+
#
|
|
197
|
+
|
|
198
|
+
def io
|
|
199
|
+
return nil unless @page
|
|
200
|
+
|
|
201
|
+
@page.getWebResponse.getContentAsStream.to_io
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
#
|
|
108
205
|
# Check if the current page contains the given text.
|
|
109
206
|
#
|
|
110
207
|
# @param [String, Regexp] expected_text The text to look for.
|
|
111
|
-
# @return [Numeric, nil] The index of the matched text, or nil if it
|
|
208
|
+
# @return [Numeric, nil] The index of the matched text, or nil if it isn't found.
|
|
209
|
+
# @raise [TypeError]
|
|
210
|
+
#
|
|
211
|
+
|
|
112
212
|
def contains_text(expected_text)
|
|
113
213
|
return nil unless exist?
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
214
|
+
super
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
#
|
|
218
|
+
# Get the first element found matching the given XPath.
|
|
219
|
+
#
|
|
220
|
+
# @param [String] xpath
|
|
221
|
+
# @return [Celerity::Element] An element subclass (or Element if none is found)
|
|
222
|
+
#
|
|
223
|
+
|
|
224
|
+
def element_by_xpath(xpath)
|
|
225
|
+
assert_exists
|
|
226
|
+
obj = @page.getFirstByXPath(xpath)
|
|
227
|
+
element_from_dom_node(obj)
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
#
|
|
231
|
+
# Get all the elements matching the given XPath.
|
|
232
|
+
#
|
|
233
|
+
# @param [String] xpath
|
|
234
|
+
# @return [Array<Celerity::Element>] array of elements
|
|
235
|
+
#
|
|
236
|
+
|
|
237
|
+
def elements_by_xpath(xpath)
|
|
238
|
+
assert_exists
|
|
239
|
+
objects = @page.getByXPath(xpath)
|
|
240
|
+
# should use an ElementCollection here?
|
|
241
|
+
objects.map { |o| element_from_dom_node(o) }.compact
|
|
122
242
|
end
|
|
123
243
|
|
|
124
|
-
#
|
|
244
|
+
#
|
|
245
|
+
# @return [HtmlUnit::HtmlHtml] the underlying HtmlUnit document.
|
|
246
|
+
#
|
|
247
|
+
|
|
125
248
|
def document
|
|
126
249
|
@object
|
|
127
250
|
end
|
|
128
|
-
|
|
251
|
+
|
|
252
|
+
#
|
|
129
253
|
# Goto the last url - HtmlUnit doesn't have a 'back' functionality, so we only have 1 history item :)
|
|
130
254
|
# @return [String, nil] The url of the resulting page, or nil if none was stored.
|
|
255
|
+
#
|
|
256
|
+
|
|
131
257
|
def back
|
|
132
|
-
# TODO: this is naive, need capability from HtmlUnit
|
|
258
|
+
# TODO: this is naive, need capability from HtmlUnit
|
|
133
259
|
goto(@last_url) if @last_url
|
|
134
260
|
end
|
|
135
|
-
|
|
261
|
+
|
|
262
|
+
#
|
|
263
|
+
# Wait for javascript jobs to finish
|
|
264
|
+
#
|
|
265
|
+
|
|
266
|
+
def wait
|
|
267
|
+
assert_exists
|
|
268
|
+
@page.getEnclosingWindow.getJobManager.waitForAllJobsToFinish(10000)
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
#
|
|
136
272
|
# Refresh the current page
|
|
273
|
+
#
|
|
274
|
+
|
|
137
275
|
def refresh
|
|
138
276
|
assert_exists
|
|
139
277
|
self.page = @page.refresh
|
|
140
278
|
end
|
|
141
279
|
|
|
142
|
-
#
|
|
143
|
-
#
|
|
280
|
+
#
|
|
281
|
+
# Clears all cookies. (Celerity only)
|
|
282
|
+
#
|
|
283
|
+
|
|
284
|
+
def clear_cookies
|
|
285
|
+
@webclient.getCookieManager.clearCookies
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
#
|
|
289
|
+
# Get the cookies for this session. (Celerity only)
|
|
290
|
+
#
|
|
291
|
+
# @return [Hash<domain, Hash<name, value>>]
|
|
292
|
+
#
|
|
293
|
+
|
|
294
|
+
def cookies
|
|
295
|
+
result = Hash.new { |hash, key| hash[key] = {} }
|
|
296
|
+
|
|
297
|
+
cookies = @webclient.getCookieManager.getCookies
|
|
298
|
+
cookies.each do |cookie|
|
|
299
|
+
result[cookie.getDomain][cookie.getName] = cookie.getValue
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
result
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
#
|
|
306
|
+
# Add a cookie with the given parameters (Celerity only)
|
|
307
|
+
#
|
|
308
|
+
# @param [String] domain
|
|
309
|
+
# @param [String] name
|
|
310
|
+
# @param [String] value
|
|
311
|
+
#
|
|
312
|
+
# @option opts :path [String] ("/") A path
|
|
313
|
+
# @option opts :max_age [Fixnum] (??) A max age
|
|
314
|
+
# @option opts :secure [Boolean] (false)
|
|
315
|
+
#
|
|
316
|
+
|
|
317
|
+
def add_cookie(domain, name, value, opts = {})
|
|
318
|
+
path = opts.delete(:path) || "/"
|
|
319
|
+
max_age = opts.delete(:max_age) || (Time.now + 60*60*24) # not sure if this is correct
|
|
320
|
+
secure = opts.delete(:secure) || false
|
|
321
|
+
|
|
322
|
+
raise "unknown option: #{opts.inspect}" unless opts.empty?
|
|
323
|
+
|
|
324
|
+
cookie = Cookie.new(domain, name, value, path, max_age, secure)
|
|
325
|
+
@webclient.getCookieManager.addCookie(cookie)
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
#
|
|
329
|
+
# Remove the cookie with the given domain and name (Celerity only)
|
|
330
|
+
#
|
|
331
|
+
# @param [String] domain
|
|
332
|
+
# @param [String] name
|
|
333
|
+
#
|
|
334
|
+
|
|
335
|
+
def remove_cookie(domain, name)
|
|
336
|
+
cm = @webclient.getCookieManager
|
|
337
|
+
cookie = cm.getCookies.find { |c| c.getDomain == domain && c.getName == name }
|
|
338
|
+
|
|
339
|
+
if cookie.nil?
|
|
340
|
+
raise "no cookie with domain #{domain.inspect} and name #{name.inspect}"
|
|
341
|
+
end
|
|
342
|
+
|
|
343
|
+
cm.removeCookie(cookie)
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
#
|
|
347
|
+
# Execute the given JavaScript on the current page.
|
|
348
|
+
# @return [Object] The resulting Object
|
|
349
|
+
#
|
|
350
|
+
|
|
144
351
|
def execute_script(source)
|
|
145
352
|
assert_exists
|
|
146
|
-
@page.executeJavaScript(source.to_s)
|
|
353
|
+
@page.executeJavaScript(source.to_s).getJavaScriptResult
|
|
147
354
|
end
|
|
148
355
|
|
|
149
|
-
#
|
|
356
|
+
# experimental - should be removed?
|
|
357
|
+
def send_keys(keys)
|
|
358
|
+
keys = keys.gsub(/\s*/, '').scan(/((?:\{[A-Z]+?\})|.)/u).flatten
|
|
359
|
+
keys.each do |key|
|
|
360
|
+
element = @page.getFocusedElement
|
|
361
|
+
case key
|
|
362
|
+
when "{TAB}"
|
|
363
|
+
@page.tabToNextElement
|
|
364
|
+
when /\w/
|
|
365
|
+
element.type(key)
|
|
366
|
+
else
|
|
367
|
+
raise NotImplementedError
|
|
368
|
+
end
|
|
369
|
+
end
|
|
370
|
+
end
|
|
371
|
+
|
|
372
|
+
#
|
|
373
|
+
# Wait until the given block evaluates to true (Celerity only)
|
|
374
|
+
#
|
|
375
|
+
# @param [Fixnum] timeout Number of seconds to wait before timing out (default: 30).
|
|
376
|
+
# @yieldparam [Celerity::Browser] browser The browser instance.
|
|
377
|
+
# @see Celerity::Browser#resynchronized
|
|
378
|
+
#
|
|
379
|
+
|
|
380
|
+
def wait_until(timeout = 30, &block)
|
|
381
|
+
Timeout.timeout(timeout) do
|
|
382
|
+
until yield(self)
|
|
383
|
+
refresh_page_from_window
|
|
384
|
+
sleep 0.1
|
|
385
|
+
end
|
|
386
|
+
end
|
|
387
|
+
end
|
|
388
|
+
|
|
389
|
+
#
|
|
390
|
+
# Wait while the given block evaluates to true (Celerity only)
|
|
391
|
+
#
|
|
392
|
+
# @param [Fixnum] timeout Number of seconds to wait before timing out (default: 30).
|
|
393
|
+
# @yieldparam [Celerity::Browser] browser The browser instance.
|
|
394
|
+
# @see Celerity::Browser#resynchronized
|
|
395
|
+
#
|
|
396
|
+
|
|
397
|
+
def wait_while(timeout = 30, &block)
|
|
398
|
+
Timeout.timeout(timeout) do
|
|
399
|
+
while yield(self)
|
|
400
|
+
refresh_page_from_window
|
|
401
|
+
sleep 0.1
|
|
402
|
+
end
|
|
403
|
+
end
|
|
404
|
+
end
|
|
405
|
+
|
|
406
|
+
#
|
|
407
|
+
# Allows you to temporarily switch to HtmlUnit's NicelyResynchronizingAjaxController to resynchronize ajax calls.
|
|
408
|
+
#
|
|
409
|
+
# @browser.resynchronized do |b|
|
|
410
|
+
# b.link(:id, 'trigger_ajax_call').click
|
|
411
|
+
# end
|
|
412
|
+
#
|
|
413
|
+
# @yieldparam [Celerity::Browser] browser The current browser object.
|
|
414
|
+
# @see Celerity::Browser#new for how to configure the browser to always use this.
|
|
415
|
+
#
|
|
416
|
+
|
|
417
|
+
def resynchronized(&block)
|
|
418
|
+
old_controller = @webclient.ajaxController
|
|
419
|
+
@webclient.setAjaxController(::HtmlUnit::NicelyResynchronizingAjaxController.new)
|
|
420
|
+
yield self
|
|
421
|
+
@webclient.setAjaxController(old_controller)
|
|
422
|
+
end
|
|
423
|
+
|
|
424
|
+
#
|
|
425
|
+
# Allows you to temporarliy switch to HtmlUnit's default AjaxController, so ajax calls are performed asynchronously.
|
|
426
|
+
# This is useful if you have created the Browser with :resynchronize => true, but want to switch it off temporarily.
|
|
427
|
+
#
|
|
428
|
+
# @yieldparam [Celerity::Browser] browser The current browser object.
|
|
429
|
+
# @see Celerity::Browser#new
|
|
430
|
+
#
|
|
431
|
+
|
|
432
|
+
def asynchronized(&block)
|
|
433
|
+
old_controller = @webclient.ajaxController
|
|
434
|
+
@webclient.setAjaxController(::HtmlUnit::AjaxController.new)
|
|
435
|
+
yield self
|
|
436
|
+
@webclient.setAjaxController(old_controller)
|
|
437
|
+
end
|
|
438
|
+
|
|
439
|
+
#
|
|
440
|
+
# Start or stop HtmlUnit's DebuggingWebConnection. (Celerity only)
|
|
441
|
+
# The output will go to /tmp/«name»
|
|
442
|
+
#
|
|
443
|
+
# @param [Boolean] bool start or stop
|
|
444
|
+
# @param [String] name required if bool is true
|
|
445
|
+
#
|
|
446
|
+
|
|
447
|
+
def debug_web_connection(bool, name = nil)
|
|
448
|
+
if bool
|
|
449
|
+
raise "no name given" unless name
|
|
450
|
+
@old_webconnection = @webclient.getWebConnection
|
|
451
|
+
dwc = HtmlUnit::Util::DebuggingWebConnection.new(@old_webconnection, name)
|
|
452
|
+
@webclient.setWebConnection(dwc)
|
|
453
|
+
$stderr.puts "debug-webconnection on"
|
|
454
|
+
else
|
|
455
|
+
@webclient.setWebConnection(@old_webconnection) if @old_webconnection
|
|
456
|
+
$stderr.puts "debug-webconnection off"
|
|
457
|
+
end
|
|
458
|
+
end
|
|
459
|
+
|
|
460
|
+
#
|
|
461
|
+
# Add a listener block for one of the available types. (Celerity only)
|
|
462
|
+
# Types map to HtmlUnit interfaces like this:
|
|
463
|
+
#
|
|
464
|
+
# :status => StatusHandler
|
|
465
|
+
# :alert => AlertHandler ( window.alert() )
|
|
466
|
+
# :web_window_event => WebWindowListener
|
|
467
|
+
# :html_parser => HTMLParserListener
|
|
468
|
+
# :incorrectness => IncorrectnessListener
|
|
469
|
+
# :confirm => ConfirmHandler ( window.confirm() )
|
|
470
|
+
# :prompt => PromptHandler ( window.prompt() )
|
|
471
|
+
#
|
|
472
|
+
#
|
|
473
|
+
# @param [Symbol] type One of the above symbols.
|
|
474
|
+
# @param [Proc] block A block to be executed for events of this type.
|
|
150
475
|
#
|
|
151
|
-
|
|
476
|
+
|
|
477
|
+
def add_listener(type, &block)
|
|
478
|
+
@listener ||= Celerity::Listener.new(@webclient)
|
|
479
|
+
@listener.add_listener(type, &block)
|
|
480
|
+
end
|
|
481
|
+
|
|
482
|
+
#
|
|
483
|
+
# Add a 'checker' proc that will be run on every page load
|
|
484
|
+
#
|
|
485
|
+
# @param [Proc] checker The proc to be run (can also be given as a block)
|
|
486
|
+
# @yieldparam [Celerity::Browser] browser The current browser object.
|
|
152
487
|
# @raise [ArgumentError] if no Proc or block was given.
|
|
488
|
+
#
|
|
489
|
+
|
|
153
490
|
def add_checker(checker = nil, &block)
|
|
154
491
|
if block_given?
|
|
155
492
|
@error_checkers << block
|
|
@@ -159,138 +496,186 @@ module Celerity
|
|
|
159
496
|
raise ArgumentError, "argument must be a Proc or block"
|
|
160
497
|
end
|
|
161
498
|
end
|
|
162
|
-
|
|
499
|
+
|
|
500
|
+
#
|
|
163
501
|
# Remove the given checker from the list of checkers
|
|
164
|
-
# @param [Proc]
|
|
502
|
+
# @param [Proc] checker The Proc to disable.
|
|
503
|
+
#
|
|
504
|
+
|
|
165
505
|
def disable_checker(checker)
|
|
166
506
|
@error_checkers.delete(checker)
|
|
167
507
|
end
|
|
168
508
|
|
|
509
|
+
#
|
|
510
|
+
# :finest, :finer, :fine, :config, :info, :warning, :severe, or :off, :all
|
|
511
|
+
#
|
|
512
|
+
# @return [Symbol] the current log level
|
|
513
|
+
#
|
|
514
|
+
|
|
515
|
+
def log_level
|
|
516
|
+
java.util.logging.Logger.getLogger('com.gargoylesoftware.htmlunit').level.to_s.downcase.to_sym
|
|
517
|
+
end
|
|
518
|
+
|
|
519
|
+
#
|
|
169
520
|
# Set Java log level (default is :warning)
|
|
170
521
|
#
|
|
171
522
|
# @param [Symbol] level :finest, :finer, :fine, :config, :info, :warning, :severe, or :off, :all
|
|
523
|
+
#
|
|
524
|
+
|
|
172
525
|
def log_level=(level)
|
|
173
526
|
java.util.logging.Logger.getLogger('com.gargoylesoftware.htmlunit').level = java.util.logging.Level.const_get(level.to_s.upcase)
|
|
174
527
|
end
|
|
175
|
-
|
|
176
|
-
# @return [Symbol] the current log level
|
|
177
|
-
def log_level
|
|
178
|
-
java.util.logging.Logger.getLogger('com.gargoylesoftware.htmlunit').level.to_s.downcase.to_sym
|
|
179
|
-
end
|
|
180
528
|
|
|
181
|
-
#
|
|
529
|
+
#
|
|
530
|
+
# Checks if we have a page currently loaded.
|
|
182
531
|
# @return [true, false]
|
|
532
|
+
#
|
|
533
|
+
|
|
183
534
|
def exist?
|
|
184
535
|
!!@page
|
|
185
536
|
end
|
|
186
537
|
alias_method :exists?, :exist?
|
|
187
538
|
|
|
188
|
-
# Allows you to temporarily switch to HtmlUnit's NicelyResynchronizingAjaxController to resynchronize ajax calls.
|
|
189
539
|
#
|
|
190
|
-
#
|
|
191
|
-
# @browser.resynchroniced do |b|
|
|
192
|
-
# b.link(:id, 'load_fancy_ajax_stuff').click
|
|
193
|
-
# end
|
|
540
|
+
# Sets the current page object for the browser
|
|
194
541
|
#
|
|
195
|
-
# @param [
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
@
|
|
542
|
+
# @param [HtmlUnit::HtmlPage] value The page to set.
|
|
543
|
+
# @api private
|
|
544
|
+
#
|
|
545
|
+
|
|
546
|
+
def page=(value)
|
|
547
|
+
@last_url = url() if exist?
|
|
548
|
+
@page = value
|
|
549
|
+
|
|
550
|
+
if @page.respond_to?("getDocumentElement")
|
|
551
|
+
@object = @page.getDocumentElement
|
|
552
|
+
elsif @page.is_a? HtmlUnit::UnexpectedPage
|
|
553
|
+
raise UnexpectedPageException, @page.getWebResponse.getContentType
|
|
554
|
+
end
|
|
555
|
+
|
|
556
|
+
render unless @viewer == DefaultViewer
|
|
557
|
+
run_error_checks
|
|
558
|
+
|
|
559
|
+
value
|
|
201
560
|
end
|
|
202
561
|
|
|
203
|
-
#--
|
|
204
|
-
# TODO: could be private?
|
|
205
|
-
#++
|
|
206
562
|
#
|
|
207
563
|
# Check that we have a @page object.
|
|
564
|
+
#
|
|
565
|
+
# @raise [Celerity::Exception::UnknownObjectException] if no page is loaded.
|
|
566
|
+
# @api private
|
|
208
567
|
#
|
|
209
|
-
|
|
210
|
-
# @api internal
|
|
568
|
+
|
|
211
569
|
def assert_exists
|
|
212
570
|
raise UnknownObjectException, "no page loaded" unless exist?
|
|
213
571
|
end
|
|
214
572
|
|
|
215
|
-
|
|
216
|
-
#
|
|
217
|
-
|
|
573
|
+
#
|
|
574
|
+
# Returns the element that currently has the focus (Celerity only)
|
|
575
|
+
#
|
|
576
|
+
|
|
577
|
+
def focused_element
|
|
578
|
+
element_from_dom_node(page.getFocusedElement())
|
|
579
|
+
end
|
|
580
|
+
|
|
581
|
+
private
|
|
582
|
+
|
|
583
|
+
#
|
|
218
584
|
# Runs the all the checker procs added by +add_checker+
|
|
219
585
|
#
|
|
220
586
|
# @see add_checker
|
|
221
|
-
# @api
|
|
587
|
+
# @api private
|
|
588
|
+
#
|
|
589
|
+
|
|
222
590
|
def run_error_checks
|
|
223
|
-
@error_checkers.each { |e| e
|
|
591
|
+
@error_checkers.each { |e| e[self] }
|
|
224
592
|
end
|
|
225
593
|
|
|
226
|
-
# Set the current page object for the browser
|
|
227
594
|
#
|
|
228
|
-
#
|
|
229
|
-
# @
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
595
|
+
# Configure the webclient according to the options given to #new.
|
|
596
|
+
# @see initialize
|
|
597
|
+
#
|
|
598
|
+
|
|
599
|
+
def setup_webclient(opts)
|
|
600
|
+
browser = (opts.delete(:browser) || :internet_explorer).to_sym
|
|
601
|
+
|
|
602
|
+
case browser
|
|
603
|
+
when :firefox
|
|
604
|
+
browser_version = ::HtmlUnit::BrowserVersion::FIREFOX_2
|
|
605
|
+
when :internet_explorer, :ie
|
|
606
|
+
browser_version = ::HtmlUnit::BrowserVersion::INTERNET_EXPLORER_7_0
|
|
607
|
+
else
|
|
608
|
+
raise ArgumentError, "unknown browser: #{browser.inspect}"
|
|
236
609
|
end
|
|
237
|
-
|
|
238
|
-
render if @viewer
|
|
239
|
-
run_error_checks
|
|
240
|
-
|
|
241
|
-
value
|
|
242
|
-
end
|
|
243
610
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
611
|
+
if proxy = opts.delete(:proxy)
|
|
612
|
+
phost, pport = proxy.split(":")
|
|
613
|
+
@webclient = ::HtmlUnit::WebClient.new(browser_version, phost, pport.to_i)
|
|
614
|
+
else
|
|
615
|
+
@webclient = ::HtmlUnit::WebClient.new(browser_version)
|
|
616
|
+
end
|
|
617
|
+
|
|
618
|
+
@webclient.throwExceptionOnScriptError = false unless opts.delete(:javascript_exceptions)
|
|
619
|
+
@webclient.throwExceptionOnFailingStatusCode = false unless opts.delete(:status_code_exceptions)
|
|
620
|
+
@webclient.cssEnabled = false unless opts.delete(:css)
|
|
621
|
+
@webclient.useInsecureSSL = opts.delete(:secure_ssl) == false
|
|
622
|
+
@webclient.setAjaxController(::HtmlUnit::NicelyResynchronizingAjaxController.new) if opts.delete(:resynchronize)
|
|
248
623
|
end
|
|
249
624
|
|
|
250
|
-
|
|
625
|
+
#
|
|
626
|
+
# This *should* be unneccessary, but sometimes the page we get from the
|
|
627
|
+
# window is different (ie. a different object) from our current @page
|
|
628
|
+
# (Used by #wait_while and #wait_until)
|
|
629
|
+
#
|
|
251
630
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
@webclient.setAjaxController(::HtmlUnit::NicelyResynchronizingAjaxController.new) if @opts[:resynchronize]
|
|
260
|
-
end
|
|
261
|
-
|
|
262
|
-
# Create a string representation of all the elements returned by collection_method
|
|
263
|
-
# @param [Symbol] collection_method
|
|
264
|
-
# @return [String]
|
|
265
|
-
def collection_string(collection_method)
|
|
266
|
-
collection = self.send collection_method
|
|
267
|
-
result = "Found #{collection.size} #{collection_method.downcase}\n"
|
|
268
|
-
|
|
269
|
-
collection.each_with_index do |element, index|
|
|
270
|
-
result << "#{index+1}: #{element.attribute_string}\n"
|
|
631
|
+
def refresh_page_from_window
|
|
632
|
+
new_page = @page.getEnclosingWindow.getEnclosedPage
|
|
633
|
+
|
|
634
|
+
if new_page && (new_page != @page)
|
|
635
|
+
self.page = new_page
|
|
636
|
+
else
|
|
637
|
+
Log.debug "unneccessary refresh"
|
|
271
638
|
end
|
|
272
|
-
|
|
273
|
-
result
|
|
274
639
|
end
|
|
275
640
|
|
|
641
|
+
#
|
|
276
642
|
# Render the current page on the viewer.
|
|
277
|
-
# @api
|
|
643
|
+
# @api private
|
|
644
|
+
#
|
|
645
|
+
|
|
278
646
|
def render
|
|
279
|
-
@viewer.render_html(
|
|
647
|
+
@viewer.render_html(self.send(@render_type), url)
|
|
280
648
|
rescue DRb::DRbConnError, Errno::ECONNREFUSED => e
|
|
281
|
-
@viewer =
|
|
282
|
-
end
|
|
283
|
-
|
|
649
|
+
@viewer = DefaultViewer
|
|
650
|
+
end
|
|
651
|
+
|
|
652
|
+
#
|
|
284
653
|
# Check if we have a viewer available on druby://127.0.0.1:6429
|
|
285
|
-
# @api
|
|
654
|
+
# @api private
|
|
655
|
+
#
|
|
656
|
+
|
|
286
657
|
def find_viewer
|
|
287
|
-
# FIXME: not ideal
|
|
288
|
-
require 'drb'
|
|
289
658
|
viewer = DRbObject.new_with_uri("druby://127.0.0.1:6429")
|
|
290
|
-
|
|
659
|
+
if viewer.respond_to?(:render_html)
|
|
660
|
+
@viewer = viewer
|
|
661
|
+
else
|
|
662
|
+
@viewer = DefaultViewer
|
|
663
|
+
end
|
|
291
664
|
rescue DRb::DRbConnError, Errno::ECONNREFUSED
|
|
292
|
-
@viewer =
|
|
665
|
+
@viewer = DefaultViewer
|
|
293
666
|
end
|
|
667
|
+
|
|
668
|
+
#
|
|
669
|
+
# Convert the given HtmlUnit object to a Celerity object
|
|
670
|
+
#
|
|
294
671
|
|
|
672
|
+
def element_from_dom_node(obj)
|
|
673
|
+
if element_class = Celerity::Util.htmlunit2celerity(obj.class)
|
|
674
|
+
element_class.new(self, :object, obj)
|
|
675
|
+
else
|
|
676
|
+
Element.new(self, :object, nil)
|
|
677
|
+
end
|
|
678
|
+
end
|
|
679
|
+
|
|
295
680
|
end # Browser
|
|
296
|
-
end # Celerity
|
|
681
|
+
end # Celerity
|