celerity 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +36 -0
- data/Manifest.txt +82 -0
- data/README.rdoc +78 -0
- data/Rakefile +25 -10
- data/celerity.gemspec +40 -0
- data/lib/celerity.rb +36 -20
- data/lib/celerity/browser.rb +396 -189
- data/lib/celerity/clickable_element.rb +25 -5
- data/lib/celerity/collections.rb +2 -2
- data/lib/celerity/container.rb +74 -61
- data/lib/celerity/default_viewer.rb +8 -4
- data/lib/celerity/disabled_element.rb +5 -5
- data/lib/celerity/element.rb +57 -35
- data/lib/celerity/element_collection.rb +22 -21
- data/lib/celerity/element_locator.rb +25 -18
- data/lib/celerity/elements/button.rb +13 -11
- data/lib/celerity/elements/file_field.rb +8 -4
- data/lib/celerity/elements/form.rb +7 -5
- data/lib/celerity/elements/frame.rb +6 -4
- data/lib/celerity/elements/image.rb +4 -4
- data/lib/celerity/elements/label.rb +1 -1
- data/lib/celerity/elements/link.rb +5 -5
- data/lib/celerity/elements/meta.rb +2 -1
- data/lib/celerity/elements/non_control_elements.rb +3 -3
- data/lib/celerity/elements/option.rb +7 -7
- data/lib/celerity/elements/radio_check.rb +18 -18
- data/lib/celerity/elements/select_list.rb +55 -25
- data/lib/celerity/elements/table.rb +21 -18
- data/lib/celerity/elements/table_cell.rb +1 -1
- data/lib/celerity/elements/table_elements.rb +1 -1
- data/lib/celerity/elements/table_row.rb +5 -5
- data/lib/celerity/elements/text_field.rb +33 -28
- data/lib/celerity/exception.rb +11 -5
- data/lib/celerity/htmlunit.rb +24 -8
- data/lib/celerity/htmlunit/commons-codec-1.4.jar +0 -0
- data/lib/celerity/htmlunit/htmlunit-2.6.jar +0 -0
- data/lib/celerity/htmlunit/htmlunit-core-js-2.6.jar +0 -0
- data/lib/celerity/htmlunit/nekohtml-1.9.13.jar +0 -0
- data/lib/celerity/htmlunit/{xercesImpl-2.8.1.jar → xercesImpl-2.9.1.jar} +0 -0
- data/lib/celerity/ignoring_web_connection.rb +15 -0
- data/lib/celerity/input_element.rb +1 -1
- data/lib/celerity/listener.rb +23 -17
- data/lib/celerity/short_inspect.rb +20 -0
- data/lib/celerity/util.rb +5 -2
- data/lib/celerity/version.rb +3 -10
- data/lib/celerity/viewer_connection.rb +89 -0
- data/lib/celerity/watir_compatibility.rb +2 -5
- data/lib/celerity/xpath_support.rb +48 -0
- data/spec/browser_authentication_spec.rb +16 -0
- data/spec/browser_spec.rb +300 -0
- data/spec/clickable_element_spec.rb +39 -0
- data/spec/default_viewer_spec.rb +23 -0
- data/spec/element_spec.rb +51 -0
- data/spec/filefield_spec.rb +18 -0
- data/spec/htmlunit_spec.rb +56 -0
- data/spec/index_offset_spec.rb +24 -0
- data/spec/listener_spec.rb +142 -0
- data/spec/spec_helper.rb +8 -0
- data/tasks/benchmark.rake +4 -0
- data/tasks/deployment.rake +43 -0
- data/tasks/environment.rake +7 -0
- data/tasks/fix.rake +25 -0
- data/tasks/jar.rake +4 -6
- data/tasks/rspec.rake +43 -0
- data/tasks/simple_ci.rake +94 -0
- data/tasks/snapshot.rake +22 -0
- data/tasks/website.rake +17 -0
- data/tasks/yard.rake +9 -0
- metadata +59 -26
- data/README.txt +0 -69
- data/lib/celerity/extra/method_generator.rb +0 -170
- data/lib/celerity/htmlunit/commons-codec-1.3.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/History.txt
CHANGED
@@ -1,3 +1,39 @@
|
|
1
|
+
== 0.0.7 2009-09-04
|
2
|
+
* :firefox (Firefox 2) is now the default browser, :firefox3 support added.
|
3
|
+
* Avoid huge Java backtraces on FailingHttpStatusCodeException
|
4
|
+
* Browser#log_level= sets the log level for more HtmlUnit packages
|
5
|
+
* Default log level is now :off
|
6
|
+
* ClickableElement#click_and_attach inherits options from parent browser
|
7
|
+
* Allow searching by XPath in frames.
|
8
|
+
* Fix bug with scripts in body onload.
|
9
|
+
* Nicer API for Browser#debug_web_connection
|
10
|
+
* Fix bug in Browser#element_by_xpath(s) and Element#method_missing
|
11
|
+
* Fix bug when selecting empty SelectList options
|
12
|
+
* Fix issue when using multiple attributes to locate elements on a page with non-unique IDs.
|
13
|
+
* Nicer #inspect methods on some objects
|
14
|
+
* Improved IPC with viewers
|
15
|
+
* Methods added:
|
16
|
+
- Browser#clear_cache
|
17
|
+
- Browser#confirm
|
18
|
+
- Browser#css=
|
19
|
+
- Browser#ignore_pattern=
|
20
|
+
- Browser#javascript_excepetion=
|
21
|
+
- Browser#secure_ssl=
|
22
|
+
- Browser#status
|
23
|
+
- Browser#status_code
|
24
|
+
- Browser#status_code_exceptions=
|
25
|
+
- Celerity.index_offset=
|
26
|
+
- ClickableElement#download
|
27
|
+
- Element#fire_event
|
28
|
+
- Element#javascript_object
|
29
|
+
* New constructor options:
|
30
|
+
- :javascript_enabled => true, false
|
31
|
+
- :viewer => true, false, String
|
32
|
+
- :refresh_handler => :immediate, :waiting, :threaded
|
33
|
+
* Features removed:
|
34
|
+
- Celerity::MethodGenerator
|
35
|
+
* Most of the spec suite moved to the WatirSpec project
|
36
|
+
|
1
37
|
== 0.0.6 2009-03-19
|
2
38
|
* Support for meta, strong, dl, dt, dd, and em HTML elements.
|
3
39
|
* Update to HtmlUnit 2.5-SNAPSHOT.
|
data/Manifest.txt
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
History.txt
|
2
|
+
License.txt
|
3
|
+
Manifest.txt
|
4
|
+
README.rdoc
|
5
|
+
Rakefile
|
6
|
+
celerity.gemspec
|
7
|
+
lib/celerity.rb
|
8
|
+
lib/celerity/browser.rb
|
9
|
+
lib/celerity/clickable_element.rb
|
10
|
+
lib/celerity/collections.rb
|
11
|
+
lib/celerity/container.rb
|
12
|
+
lib/celerity/default_viewer.rb
|
13
|
+
lib/celerity/disabled_element.rb
|
14
|
+
lib/celerity/element.rb
|
15
|
+
lib/celerity/element_collection.rb
|
16
|
+
lib/celerity/element_locator.rb
|
17
|
+
lib/celerity/elements/button.rb
|
18
|
+
lib/celerity/elements/file_field.rb
|
19
|
+
lib/celerity/elements/form.rb
|
20
|
+
lib/celerity/elements/frame.rb
|
21
|
+
lib/celerity/elements/image.rb
|
22
|
+
lib/celerity/elements/label.rb
|
23
|
+
lib/celerity/elements/link.rb
|
24
|
+
lib/celerity/elements/meta.rb
|
25
|
+
lib/celerity/elements/non_control_elements.rb
|
26
|
+
lib/celerity/elements/option.rb
|
27
|
+
lib/celerity/elements/radio_check.rb
|
28
|
+
lib/celerity/elements/select_list.rb
|
29
|
+
lib/celerity/elements/table.rb
|
30
|
+
lib/celerity/elements/table_cell.rb
|
31
|
+
lib/celerity/elements/table_elements.rb
|
32
|
+
lib/celerity/elements/table_row.rb
|
33
|
+
lib/celerity/elements/text_field.rb
|
34
|
+
lib/celerity/exception.rb
|
35
|
+
lib/celerity/htmlunit.rb
|
36
|
+
lib/celerity/htmlunit/commons-codec-1.4.jar
|
37
|
+
lib/celerity/htmlunit/commons-collections-3.2.1.jar
|
38
|
+
lib/celerity/htmlunit/commons-httpclient-3.1.jar
|
39
|
+
lib/celerity/htmlunit/commons-io-1.4.jar
|
40
|
+
lib/celerity/htmlunit/commons-lang-2.4.jar
|
41
|
+
lib/celerity/htmlunit/commons-logging-1.1.1.jar
|
42
|
+
lib/celerity/htmlunit/cssparser-0.9.5.jar
|
43
|
+
lib/celerity/htmlunit/htmlunit-2.6.jar
|
44
|
+
lib/celerity/htmlunit/htmlunit-core-js-2.6.jar
|
45
|
+
lib/celerity/htmlunit/nekohtml-1.9.13.jar
|
46
|
+
lib/celerity/htmlunit/sac-1.3.jar
|
47
|
+
lib/celerity/htmlunit/serializer-2.7.1.jar
|
48
|
+
lib/celerity/htmlunit/xalan-2.7.1.jar
|
49
|
+
lib/celerity/htmlunit/xercesImpl-2.9.1.jar
|
50
|
+
lib/celerity/htmlunit/xml-apis-1.3.04.jar
|
51
|
+
lib/celerity/identifier.rb
|
52
|
+
lib/celerity/ignoring_web_connection.rb
|
53
|
+
lib/celerity/input_element.rb
|
54
|
+
lib/celerity/listener.rb
|
55
|
+
lib/celerity/resources/no_viewer.png
|
56
|
+
lib/celerity/short_inspect.rb
|
57
|
+
lib/celerity/util.rb
|
58
|
+
lib/celerity/version.rb
|
59
|
+
lib/celerity/viewer_connection.rb
|
60
|
+
lib/celerity/watir_compatibility.rb
|
61
|
+
lib/celerity/xpath_support.rb
|
62
|
+
spec/browser_authentication_spec.rb
|
63
|
+
spec/browser_spec.rb
|
64
|
+
spec/clickable_element_spec.rb
|
65
|
+
spec/default_viewer_spec.rb
|
66
|
+
spec/element_spec.rb
|
67
|
+
spec/filefield_spec.rb
|
68
|
+
spec/htmlunit_spec.rb
|
69
|
+
spec/index_offset_spec.rb
|
70
|
+
spec/listener_spec.rb
|
71
|
+
spec/spec_helper.rb
|
72
|
+
tasks/benchmark.rake
|
73
|
+
tasks/deployment.rake
|
74
|
+
tasks/environment.rake
|
75
|
+
tasks/fix.rake
|
76
|
+
tasks/jar.rake
|
77
|
+
tasks/rdoc.rake
|
78
|
+
tasks/rspec.rake
|
79
|
+
tasks/simple_ci.rake
|
80
|
+
tasks/snapshot.rake
|
81
|
+
tasks/website.rake
|
82
|
+
tasks/yard.rake
|
data/README.rdoc
ADDED
@@ -0,0 +1,78 @@
|
|
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
|
+
It 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 aims at being API compatible with Watir.
|
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
|
+
or from GitHub (updated frequently)
|
31
|
+
|
32
|
+
jruby -S gem install jarib-celerity
|
33
|
+
|
34
|
+
|
35
|
+
== Example
|
36
|
+
|
37
|
+
require "rubygems"
|
38
|
+
require "celerity"
|
39
|
+
|
40
|
+
browser = Celerity::Browser.new
|
41
|
+
browser.goto('http://www.google.com')
|
42
|
+
browser.text_field(:name, 'q').value = 'Celerity'
|
43
|
+
browser.button(:name, 'btnG').click
|
44
|
+
|
45
|
+
puts "yay" if browser.text.include? 'celerity.rubyforge.org'
|
46
|
+
|
47
|
+
== Source
|
48
|
+
|
49
|
+
The source code is available on [GitHub](http://github.com/jarib/celerity/tree/master).
|
50
|
+
|
51
|
+
|
52
|
+
== Wiki & Bug Tracker
|
53
|
+
|
54
|
+
* [Wiki](http://github.com/jarib/celerity/wikis)
|
55
|
+
* [Bug Tracker](http://github.com/jarib/celerity/issues)
|
56
|
+
|
57
|
+
== Related projects
|
58
|
+
|
59
|
+
* [WatirSpec](http://github.com/jarib/watirspec/tree/master)
|
60
|
+
* [Celerity Viewers](http://github.com/jarib/celerity-viewers)
|
61
|
+
|
62
|
+
== License
|
63
|
+
|
64
|
+
Celerity - JRuby wrapper for HtmlUnit
|
65
|
+
Copyright (c) 2008-2009 FINN.no AS
|
66
|
+
|
67
|
+
This program is free software: you can redistribute it and/or modify
|
68
|
+
it under the terms of the GNU General Public License as published by
|
69
|
+
the Free Software Foundation, either version 3 of the License, or
|
70
|
+
(at your option) any later version.
|
71
|
+
|
72
|
+
This program is distributed in the hope that it will be useful,
|
73
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
74
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
75
|
+
GNU General Public License for more details.
|
76
|
+
|
77
|
+
You should have received a copy of the GNU General Public License
|
78
|
+
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
data/Rakefile
CHANGED
@@ -1,12 +1,27 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
else # in gem dir
|
8
|
-
load 'tasks/jar.rake'
|
9
|
-
load 'tasks/rdoc.rake'
|
10
|
-
end
|
1
|
+
require 'rubygems'
|
2
|
+
gem 'hoe', '>= 2.3.0'
|
3
|
+
require 'hoe'
|
4
|
+
%w[fileutils rubigen].each { |f| require f }
|
5
|
+
|
6
|
+
require "lib/celerity/version"
|
11
7
|
|
8
|
+
Hoe.plugin :newgem # newgem 1.5.2+
|
9
|
+
Hoe.plugin :website
|
12
10
|
|
11
|
+
# Generate all the Rake tasks
|
12
|
+
# Run 'rake -T' to see list of generated tasks (from gem root directory)
|
13
|
+
Hoe.spec 'celerity' do
|
14
|
+
author << "Jari Bakken" << "T. Alexander Lystad" << "Knut Johannes Dahle"
|
15
|
+
email << "jari.bakken@finn.no"
|
16
|
+
extra_dev_deps << ['sinatra', '>= 0.9.4']
|
17
|
+
version = Celerity::VERSION
|
18
|
+
end
|
19
|
+
|
20
|
+
Dir['tasks/**/*.rake'].each do |rake|
|
21
|
+
begin
|
22
|
+
load rake
|
23
|
+
rescue LoadError
|
24
|
+
end
|
25
|
+
end
|
26
|
+
# load 'tasks/jar.rake'
|
27
|
+
# load 'tasks/rdoc.rake'
|
data/celerity.gemspec
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{celerity}
|
5
|
+
s.version = "0.0.7"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Jari Bakken", "T. Alexander Lystad", "Knut Johannes Dahle"]
|
9
|
+
s.date = %q{2009-09-04}
|
10
|
+
s.description = %q{Celerity is a JRuby library for easy and fast functional test automation for web applications.
|
11
|
+
|
12
|
+
It is a JRuby wrapper around HtmlUnit – a headless Java browser with
|
13
|
+
JavaScript support. It provides a simple API for programmatic navigation through
|
14
|
+
web applications. Celerity aims at being API compatible with Watir.}
|
15
|
+
s.email = ["jari.bakken@finn.no"]
|
16
|
+
s.extra_rdoc_files = ["History.txt", "License.txt", "Manifest.txt"]
|
17
|
+
s.files = ["History.txt", "License.txt", "Manifest.txt", "README.rdoc", "Rakefile", "celerity.gemspec", "lib/celerity.rb", "lib/celerity/browser.rb", "lib/celerity/clickable_element.rb", "lib/celerity/collections.rb", "lib/celerity/container.rb", "lib/celerity/default_viewer.rb", "lib/celerity/disabled_element.rb", "lib/celerity/element.rb", "lib/celerity/element_collection.rb", "lib/celerity/element_locator.rb", "lib/celerity/elements/button.rb", "lib/celerity/elements/file_field.rb", "lib/celerity/elements/form.rb", "lib/celerity/elements/frame.rb", "lib/celerity/elements/image.rb", "lib/celerity/elements/label.rb", "lib/celerity/elements/link.rb", "lib/celerity/elements/meta.rb", "lib/celerity/elements/non_control_elements.rb", "lib/celerity/elements/option.rb", "lib/celerity/elements/radio_check.rb", "lib/celerity/elements/select_list.rb", "lib/celerity/elements/table.rb", "lib/celerity/elements/table_cell.rb", "lib/celerity/elements/table_elements.rb", "lib/celerity/elements/table_row.rb", "lib/celerity/elements/text_field.rb", "lib/celerity/exception.rb", "lib/celerity/htmlunit.rb", "lib/celerity/htmlunit/commons-codec-1.4.jar", "lib/celerity/htmlunit/commons-collections-3.2.1.jar", "lib/celerity/htmlunit/commons-httpclient-3.1.jar", "lib/celerity/htmlunit/commons-io-1.4.jar", "lib/celerity/htmlunit/commons-lang-2.4.jar", "lib/celerity/htmlunit/commons-logging-1.1.1.jar", "lib/celerity/htmlunit/cssparser-0.9.5.jar", "lib/celerity/htmlunit/htmlunit-2.6.jar", "lib/celerity/htmlunit/htmlunit-core-js-2.6.jar", "lib/celerity/htmlunit/nekohtml-1.9.13.jar", "lib/celerity/htmlunit/sac-1.3.jar", "lib/celerity/htmlunit/serializer-2.7.1.jar", "lib/celerity/htmlunit/xalan-2.7.1.jar", "lib/celerity/htmlunit/xercesImpl-2.9.1.jar", "lib/celerity/htmlunit/xml-apis-1.3.04.jar", "lib/celerity/identifier.rb", "lib/celerity/ignoring_web_connection.rb", "lib/celerity/input_element.rb", "lib/celerity/listener.rb", "lib/celerity/resources/no_viewer.png", "lib/celerity/short_inspect.rb", "lib/celerity/util.rb", "lib/celerity/version.rb", "lib/celerity/viewer_connection.rb", "lib/celerity/watir_compatibility.rb", "lib/celerity/xpath_support.rb", "spec/browser_authentication_spec.rb", "spec/browser_spec.rb", "spec/clickable_element_spec.rb", "spec/default_viewer_spec.rb", "spec/element_spec.rb", "spec/filefield_spec.rb", "spec/htmlunit_spec.rb", "spec/index_offset_spec.rb", "spec/listener_spec.rb", "spec/spec_helper.rb", "tasks/benchmark.rake", "tasks/deployment.rake", "tasks/environment.rake", "tasks/fix.rake", "tasks/jar.rake", "tasks/rdoc.rake", "tasks/rspec.rake", "tasks/simple_ci.rake", "tasks/snapshot.rake", "tasks/website.rake", "tasks/yard.rake"]
|
18
|
+
s.homepage = %q{http://celerity.rubyforge.org/}
|
19
|
+
s.rdoc_options = ["--main", "README.rdoc"]
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
s.rubyforge_project = %q{celerity}
|
22
|
+
s.rubygems_version = %q{1.3.5}
|
23
|
+
s.summary = %q{Celerity is a JRuby library for easy and fast functional test automation for web applications}
|
24
|
+
|
25
|
+
if s.respond_to? :specification_version then
|
26
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
27
|
+
s.specification_version = 3
|
28
|
+
|
29
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
30
|
+
s.add_development_dependency(%q<sinatra>, [">= 0.9.4"])
|
31
|
+
s.add_development_dependency(%q<hoe>, [">= 2.3.3"])
|
32
|
+
else
|
33
|
+
s.add_dependency(%q<sinatra>, [">= 0.9.4"])
|
34
|
+
s.add_dependency(%q<hoe>, [">= 2.3.3"])
|
35
|
+
end
|
36
|
+
else
|
37
|
+
s.add_dependency(%q<sinatra>, [">= 0.9.4"])
|
38
|
+
s.add_dependency(%q<hoe>, [">= 2.3.3"])
|
39
|
+
end
|
40
|
+
end
|
data/lib/celerity.rb
CHANGED
@@ -2,13 +2,13 @@ $:.unshift(File.dirname(__FILE__)) unless $:.include?(File.dirname(__FILE__)) ||
|
|
2
2
|
|
3
3
|
raise "Celerity only works on JRuby at the moment." unless RUBY_PLATFORM =~ /java/
|
4
4
|
|
5
|
-
require
|
5
|
+
require "java"
|
6
6
|
require "logger"
|
7
7
|
require "uri"
|
8
8
|
require "pp"
|
9
9
|
require "timeout"
|
10
10
|
require "time"
|
11
|
-
require
|
11
|
+
require "socket"
|
12
12
|
require "fileutils"
|
13
13
|
require "thread"
|
14
14
|
|
@@ -16,12 +16,24 @@ module Celerity
|
|
16
16
|
Log = Logger.new($DEBUG ? $stderr : nil)
|
17
17
|
Log.level = Logger::DEBUG
|
18
18
|
|
19
|
-
|
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
|
+
|
20
32
|
DIR = File.expand_path(File.dirname(__FILE__) + "/celerity")
|
21
33
|
end
|
22
34
|
|
23
|
-
require "celerity/htmlunit"
|
24
35
|
require "celerity/version"
|
36
|
+
require "celerity/htmlunit"
|
25
37
|
require "celerity/exception"
|
26
38
|
require "celerity/clickable_element"
|
27
39
|
require "celerity/disabled_element"
|
@@ -29,29 +41,33 @@ require "celerity/element_collection"
|
|
29
41
|
require "celerity/collections"
|
30
42
|
require "celerity/element_locator"
|
31
43
|
require "celerity/identifier"
|
44
|
+
require "celerity/short_inspect"
|
32
45
|
require "celerity/container"
|
46
|
+
require "celerity/xpath_support"
|
33
47
|
require "celerity/element"
|
34
48
|
require "celerity/input_element"
|
35
49
|
require "celerity/elements/non_control_elements"
|
36
|
-
require "celerity/elements/button
|
37
|
-
require "celerity/elements/file_field
|
38
|
-
require "celerity/elements/form
|
39
|
-
require "celerity/elements/frame
|
40
|
-
require "celerity/elements/image
|
41
|
-
require "celerity/elements/label
|
42
|
-
require "celerity/elements/link
|
43
|
-
require "celerity/elements/meta
|
44
|
-
require "celerity/elements/option
|
45
|
-
require "celerity/elements/radio_check
|
46
|
-
require "celerity/elements/select_list
|
47
|
-
require "celerity/elements/table
|
48
|
-
require "celerity/elements/table_elements
|
49
|
-
require "celerity/elements/table_cell
|
50
|
-
require "celerity/elements/table_row
|
51
|
-
require "celerity/elements/text_field
|
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"
|
52
66
|
require "celerity/util"
|
53
67
|
require "celerity/default_viewer"
|
54
68
|
require "celerity/listener"
|
69
|
+
require "celerity/ignoring_web_connection"
|
70
|
+
require "celerity/viewer_connection"
|
55
71
|
require "celerity/browser"
|
56
72
|
require "celerity/watir_compatibility"
|
57
73
|
|
data/lib/celerity/browser.rb
CHANGED
@@ -1,16 +1,17 @@
|
|
1
1
|
module Celerity
|
2
2
|
class Browser
|
3
3
|
include Container
|
4
|
+
include XpathSupport
|
4
5
|
|
5
6
|
attr_accessor :page, :object, :charset
|
6
|
-
attr_reader :webclient, :viewer
|
7
|
+
attr_reader :webclient, :viewer, :options
|
7
8
|
|
8
9
|
#
|
9
10
|
# Initialize a browser and go to the given URL
|
10
|
-
#
|
11
|
+
#
|
11
12
|
# @param [String] uri The URL to go to.
|
12
13
|
# @return [Celerity::Browser] instance.
|
13
|
-
#
|
14
|
+
#
|
14
15
|
|
15
16
|
def self.start(uri)
|
16
17
|
browser = new
|
@@ -26,27 +27,26 @@ module Celerity
|
|
26
27
|
raise NotImplementedError, "use ClickableElement#click_and_attach instead"
|
27
28
|
end
|
28
29
|
|
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
30
|
#
|
36
31
|
# Creates a browser object.
|
37
32
|
#
|
38
33
|
# @see Celerity::Container for an introduction to the main API.
|
39
34
|
#
|
40
|
-
# @option opts :
|
41
|
-
# @option opts :
|
35
|
+
# @option opts :browser [:internet_explorer, :firefox, :firefox3] (:firefox) Set the BrowserVersion used by HtmlUnit. Defaults to Firefox 2.
|
36
|
+
# @option opts :charset [String] ("UTF-8") Specify the charset that webclient will use for requests, and those where texts are getting gibberished, like Browser#html.
|
42
37
|
# @option opts :css [Boolean] (false) Enable CSS. Disabled by default.
|
43
|
-
# @option opts :
|
44
|
-
# @option opts :
|
38
|
+
# @option opts :ignore_pattern [Regexp] See Browser#ignore_pattern=
|
39
|
+
# @option opts :javascript_enabled [Boolean] (true) Enable/disable JavaScript evaluation. Enabled by default.
|
45
40
|
# @option opts :javascript_exceptions [Boolean] (false) Raise exceptions on script errors. Disabled by default.
|
46
|
-
# @option opts :
|
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.
|
41
|
+
# @option opts :log_level [Symbol] (:warning) @see log_level=
|
49
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 [Boolean] (true) Connect to a CelerityViewer on port 6429 if available.
|
50
50
|
#
|
51
51
|
# @return [Celerity::Browser] An instance of the browser.
|
52
52
|
#
|
@@ -58,22 +58,29 @@ module Celerity
|
|
58
58
|
raise TypeError, "wrong argument type #{opts.class}, expected Hash"
|
59
59
|
end
|
60
60
|
|
61
|
-
unless (render_types = [:html, :xml, nil]).include?(opts[:render])
|
61
|
+
unless (render_types = [:html, :xml, nil, 'html', 'xml']).include?(opts[:render])
|
62
62
|
raise ArgumentError, "expected one of #{render_types.inspect} for key :render"
|
63
63
|
end
|
64
64
|
|
65
|
+
opts = opts.dup # we'll delete from opts, so dup to avoid side effects
|
66
|
+
@options = opts.dup # keep the unmodified version around as well
|
67
|
+
|
65
68
|
@render_type = opts.delete(:render) || :html
|
66
69
|
@charset = opts.delete(:charset) || "UTF-8"
|
67
|
-
self.log_level = opts.delete(:log_level) || :
|
70
|
+
self.log_level = opts.delete(:log_level) || :off
|
68
71
|
|
69
|
-
@
|
70
|
-
@error_checkers
|
71
|
-
@browser
|
72
|
+
@page = nil
|
73
|
+
@error_checkers = []
|
74
|
+
@browser = self # for Container#browser
|
75
|
+
|
76
|
+
setup_webclient opts
|
77
|
+
setup_viewer opts.delete(:viewer)
|
72
78
|
|
73
|
-
setup_webclient(opts)
|
74
|
-
|
75
79
|
raise ArgumentError, "unknown option #{opts.inspect}" unless opts.empty?
|
76
|
-
|
80
|
+
end
|
81
|
+
|
82
|
+
def inspect
|
83
|
+
short_inspect :exclude => %w[@webclient @browser @object @options @listener @event_listener]
|
77
84
|
end
|
78
85
|
|
79
86
|
#
|
@@ -89,7 +96,9 @@ module Celerity
|
|
89
96
|
request = HtmlUnit::WebRequestSettings.new(::Java::JavaNet::URL.new(uri))
|
90
97
|
request.setCharset(@charset)
|
91
98
|
|
92
|
-
|
99
|
+
rescue_status_code_exception do
|
100
|
+
self.page = @webclient.getPage(request)
|
101
|
+
end
|
93
102
|
|
94
103
|
url()
|
95
104
|
end
|
@@ -117,11 +126,12 @@ module Celerity
|
|
117
126
|
def close
|
118
127
|
@page = nil
|
119
128
|
@webclient.closeAllWindows
|
129
|
+
@viewer.close
|
120
130
|
end
|
121
131
|
|
122
132
|
#
|
123
133
|
# @return [String] the URL of the current page
|
124
|
-
#
|
134
|
+
#
|
125
135
|
|
126
136
|
def url
|
127
137
|
assert_exists
|
@@ -136,18 +146,26 @@ module Celerity
|
|
136
146
|
@page ? @page.getTitleText : ''
|
137
147
|
end
|
138
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
|
+
|
139
157
|
#
|
140
158
|
# @return [String] the HTML content of the current page
|
141
159
|
#
|
142
|
-
|
160
|
+
|
143
161
|
def html
|
144
|
-
@page ? @page.getWebResponse.getContentAsString : ''
|
162
|
+
@page ? @page.getWebResponse.getContentAsString(@charset) : ''
|
145
163
|
end
|
146
|
-
|
164
|
+
|
147
165
|
#
|
148
166
|
# @return [String] the XML representation of the DOM
|
149
167
|
#
|
150
|
-
|
168
|
+
|
151
169
|
def xml
|
152
170
|
return '' unless @page
|
153
171
|
return @page.asXml if @page.respond_to?(:asXml)
|
@@ -157,14 +175,16 @@ module Celerity
|
|
157
175
|
#
|
158
176
|
# @return [String] a text representation of the current page
|
159
177
|
#
|
160
|
-
|
178
|
+
|
161
179
|
def text
|
162
180
|
return '' unless @page
|
163
181
|
|
164
182
|
if @page.respond_to?("getContent")
|
165
183
|
string = @page.getContent.strip
|
166
|
-
|
184
|
+
elsif @page.documentElement
|
167
185
|
string = @page.documentElement.asText.strip
|
186
|
+
else
|
187
|
+
string = ''
|
168
188
|
end
|
169
189
|
|
170
190
|
# Celerity::Util.normalize_text(string)
|
@@ -177,27 +197,35 @@ module Celerity
|
|
177
197
|
|
178
198
|
def response_headers
|
179
199
|
return {} unless @page
|
180
|
-
|
200
|
+
|
181
201
|
Hash[*@page.getWebResponse.getResponseHeaders.map { |obj| [obj.name, obj.value] }.flatten]
|
182
202
|
end
|
183
203
|
|
204
|
+
#
|
205
|
+
# @return [Fixnum] status code of the last request
|
206
|
+
#
|
207
|
+
|
208
|
+
def status_code
|
209
|
+
@page.getWebResponse.getStatusCode
|
210
|
+
end
|
211
|
+
|
184
212
|
#
|
185
213
|
# @return [String] content-type as in 'text/html'
|
186
214
|
#
|
187
215
|
|
188
216
|
def content_type
|
189
217
|
return '' unless @page
|
190
|
-
|
218
|
+
|
191
219
|
@page.getWebResponse.getContentType
|
192
220
|
end
|
193
221
|
|
194
222
|
#
|
195
223
|
# @return [IO, nil] page contents as an IO, returns nil if no page is loaded.
|
196
|
-
#
|
197
|
-
|
224
|
+
#
|
225
|
+
|
198
226
|
def io
|
199
227
|
return nil unless @page
|
200
|
-
|
228
|
+
|
201
229
|
@page.getWebResponse.getContentAsStream.to_io
|
202
230
|
end
|
203
231
|
|
@@ -207,7 +235,7 @@ module Celerity
|
|
207
235
|
# @param [String, Regexp] expected_text The text to look for.
|
208
236
|
# @return [Numeric, nil] The index of the matched text, or nil if it isn't found.
|
209
237
|
# @raise [TypeError]
|
210
|
-
#
|
238
|
+
#
|
211
239
|
|
212
240
|
def contains_text(expected_text)
|
213
241
|
return nil unless exist?
|
@@ -215,131 +243,128 @@ module Celerity
|
|
215
243
|
end
|
216
244
|
|
217
245
|
#
|
218
|
-
#
|
219
|
-
#
|
220
|
-
# @param [String] xpath
|
221
|
-
# @return [Celerity::Element] An element subclass (or Element if none is found)
|
246
|
+
# @return [HtmlUnit::HtmlHtml] the underlying HtmlUnit document.
|
222
247
|
#
|
223
|
-
|
224
|
-
def
|
225
|
-
|
226
|
-
obj = @page.getFirstByXPath(xpath)
|
227
|
-
element_from_dom_node(obj)
|
248
|
+
|
249
|
+
def document
|
250
|
+
@object
|
228
251
|
end
|
229
252
|
|
230
253
|
#
|
231
|
-
#
|
232
|
-
#
|
233
|
-
# @param [String] xpath
|
234
|
-
# @return [Array<Celerity::Element>] array of elements
|
254
|
+
# Goto back one history item
|
255
|
+
# @return [String] The url of the resulting page.
|
235
256
|
#
|
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
|
242
|
-
end
|
243
257
|
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
@object
|
258
|
+
def back
|
259
|
+
@webclient.getCurrentWindow.getHistory.back
|
260
|
+
refresh_page_from_window
|
261
|
+
|
262
|
+
url
|
250
263
|
end
|
251
264
|
|
252
265
|
#
|
253
|
-
#
|
254
|
-
# @return [String
|
255
|
-
#
|
266
|
+
# Go forward one history item
|
267
|
+
# @return [String] The url of the resulting page.
|
268
|
+
#
|
256
269
|
|
257
|
-
def
|
258
|
-
|
259
|
-
|
270
|
+
def forward
|
271
|
+
@webclient.getCurrentWindow.getHistory.forward
|
272
|
+
refresh_page_from_window
|
273
|
+
|
274
|
+
url
|
260
275
|
end
|
261
276
|
|
262
277
|
#
|
263
278
|
# Wait for javascript jobs to finish
|
264
|
-
#
|
279
|
+
#
|
265
280
|
|
266
281
|
def wait
|
267
282
|
assert_exists
|
268
|
-
@
|
283
|
+
@webclient.waitForBackgroundJavaScript(10000);
|
269
284
|
end
|
270
285
|
|
271
286
|
#
|
272
287
|
# Refresh the current page
|
273
|
-
#
|
288
|
+
#
|
274
289
|
|
275
290
|
def refresh
|
276
291
|
assert_exists
|
277
|
-
|
292
|
+
@page.refresh
|
278
293
|
end
|
279
294
|
|
280
295
|
#
|
281
296
|
# Clears all cookies. (Celerity only)
|
282
|
-
#
|
297
|
+
#
|
283
298
|
|
284
299
|
def clear_cookies
|
285
300
|
@webclient.getCookieManager.clearCookies
|
286
301
|
end
|
287
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
|
+
|
288
311
|
#
|
289
312
|
# Get the cookies for this session. (Celerity only)
|
290
|
-
#
|
291
|
-
# @return [Hash<domain, Hash<name, value>>]
|
313
|
+
#
|
314
|
+
# @return [Hash<domain, Hash<name, value>>]
|
292
315
|
#
|
293
316
|
|
294
317
|
def cookies
|
295
318
|
result = Hash.new { |hash, key| hash[key] = {} }
|
296
|
-
|
319
|
+
|
297
320
|
cookies = @webclient.getCookieManager.getCookies
|
298
321
|
cookies.each do |cookie|
|
299
322
|
result[cookie.getDomain][cookie.getName] = cookie.getValue
|
300
323
|
end
|
301
|
-
|
324
|
+
|
302
325
|
result
|
303
326
|
end
|
304
|
-
|
327
|
+
|
305
328
|
#
|
306
329
|
# Add a cookie with the given parameters (Celerity only)
|
307
|
-
#
|
330
|
+
#
|
308
331
|
# @param [String] domain
|
309
332
|
# @param [String] name
|
310
333
|
# @param [String] value
|
311
334
|
#
|
312
|
-
# @option opts :path [String] ("/") A path
|
335
|
+
# @option opts :path [String] ("/") A path
|
313
336
|
# @option opts :max_age [Fixnum] (??) A max age
|
314
|
-
# @option opts :secure [Boolean] (false)
|
337
|
+
# @option opts :secure [Boolean] (false)
|
315
338
|
#
|
316
|
-
|
339
|
+
|
317
340
|
def add_cookie(domain, name, value, opts = {})
|
318
341
|
path = opts.delete(:path) || "/"
|
319
342
|
max_age = opts.delete(:max_age) || (Time.now + 60*60*24) # not sure if this is correct
|
320
343
|
secure = opts.delete(:secure) || false
|
321
344
|
|
322
|
-
raise "unknown option: #{opts.inspect}" unless opts.empty?
|
345
|
+
raise(ArgumentError, "unknown option: #{opts.inspect}") unless opts.empty?
|
323
346
|
|
324
347
|
cookie = Cookie.new(domain, name, value, path, max_age, secure)
|
325
348
|
@webclient.getCookieManager.addCookie(cookie)
|
326
349
|
end
|
327
|
-
|
350
|
+
|
328
351
|
#
|
329
352
|
# Remove the cookie with the given domain and name (Celerity only)
|
330
353
|
#
|
331
354
|
# @param [String] domain
|
332
355
|
# @param [String] name
|
333
356
|
#
|
334
|
-
|
357
|
+
# @raise [CookieNotFoundError] if the cookie doesn't exist
|
358
|
+
#
|
359
|
+
|
335
360
|
def remove_cookie(domain, name)
|
336
361
|
cm = @webclient.getCookieManager
|
337
362
|
cookie = cm.getCookies.find { |c| c.getDomain == domain && c.getName == name }
|
338
|
-
|
363
|
+
|
339
364
|
if cookie.nil?
|
340
|
-
raise "no cookie with domain #{domain.inspect} and name #{name.inspect}"
|
365
|
+
raise CookieNotFoundError, "no cookie with domain #{domain.inspect} and name #{name.inspect}"
|
341
366
|
end
|
342
|
-
|
367
|
+
|
343
368
|
cm.removeCookie(cookie)
|
344
369
|
end
|
345
370
|
|
@@ -376,14 +401,18 @@ module Celerity
|
|
376
401
|
# @yieldparam [Celerity::Browser] browser The browser instance.
|
377
402
|
# @see Celerity::Browser#resynchronized
|
378
403
|
#
|
379
|
-
|
404
|
+
|
380
405
|
def wait_until(timeout = 30, &block)
|
406
|
+
returned = nil
|
407
|
+
|
381
408
|
Timeout.timeout(timeout) do
|
382
|
-
until yield(self)
|
409
|
+
until returned = yield(self)
|
383
410
|
refresh_page_from_window
|
384
411
|
sleep 0.1
|
385
412
|
end
|
386
413
|
end
|
414
|
+
|
415
|
+
returned
|
387
416
|
end
|
388
417
|
|
389
418
|
#
|
@@ -392,19 +421,24 @@ module Celerity
|
|
392
421
|
# @param [Fixnum] timeout Number of seconds to wait before timing out (default: 30).
|
393
422
|
# @yieldparam [Celerity::Browser] browser The browser instance.
|
394
423
|
# @see Celerity::Browser#resynchronized
|
395
|
-
#
|
424
|
+
#
|
396
425
|
|
397
426
|
def wait_while(timeout = 30, &block)
|
427
|
+
returned = nil
|
428
|
+
|
398
429
|
Timeout.timeout(timeout) do
|
399
|
-
while yield(self)
|
430
|
+
while returned = yield(self)
|
400
431
|
refresh_page_from_window
|
401
432
|
sleep 0.1
|
402
433
|
end
|
403
434
|
end
|
435
|
+
|
436
|
+
returned
|
404
437
|
end
|
405
438
|
|
406
439
|
#
|
407
|
-
# Allows you to temporarily switch to HtmlUnit's NicelyResynchronizingAjaxController
|
440
|
+
# Allows you to temporarily switch to HtmlUnit's NicelyResynchronizingAjaxController
|
441
|
+
# to resynchronize ajax calls.
|
408
442
|
#
|
409
443
|
# @browser.resynchronized do |b|
|
410
444
|
# b.link(:id, 'trigger_ajax_call').click
|
@@ -420,15 +454,16 @@ module Celerity
|
|
420
454
|
yield self
|
421
455
|
@webclient.setAjaxController(old_controller)
|
422
456
|
end
|
423
|
-
|
457
|
+
|
458
|
+
#
|
459
|
+
# Allows you to temporarliy switch to HtmlUnit's default AjaxController, so
|
460
|
+
# ajax calls are performed asynchronously. This is useful if you have created
|
461
|
+
# the Browser with :resynchronize => true, but want to switch it off temporarily.
|
424
462
|
#
|
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
463
|
# @yieldparam [Celerity::Browser] browser The current browser object.
|
429
464
|
# @see Celerity::Browser#new
|
430
465
|
#
|
431
|
-
|
466
|
+
|
432
467
|
def asynchronized(&block)
|
433
468
|
old_controller = @webclient.ajaxController
|
434
469
|
@webclient.setAjaxController(::HtmlUnit::AjaxController.new)
|
@@ -440,21 +475,18 @@ module Celerity
|
|
440
475
|
# Start or stop HtmlUnit's DebuggingWebConnection. (Celerity only)
|
441
476
|
# The output will go to /tmp/«name»
|
442
477
|
#
|
443
|
-
# @param [
|
444
|
-
# @param [
|
445
|
-
#
|
446
|
-
|
447
|
-
def debug_web_connection(
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
@webclient.setWebConnection(@old_webconnection) if @old_webconnection
|
456
|
-
$stderr.puts "debug-webconnection off"
|
457
|
-
end
|
478
|
+
# @param [String] name directory name
|
479
|
+
# @param [block] blk block to execute
|
480
|
+
#
|
481
|
+
|
482
|
+
def debug_web_connection(name, &blk)
|
483
|
+
old_wc = @webclient.getWebConnection
|
484
|
+
|
485
|
+
@webclient.setWebConnection HtmlUnit::Util::DebuggingWebConnection.new(old_wc, name)
|
486
|
+
res = yield
|
487
|
+
@webclient.setWebConnection old_wc
|
488
|
+
|
489
|
+
res
|
458
490
|
end
|
459
491
|
|
460
492
|
#
|
@@ -469,23 +501,54 @@ module Celerity
|
|
469
501
|
# :confirm => ConfirmHandler ( window.confirm() )
|
470
502
|
# :prompt => PromptHandler ( window.prompt() )
|
471
503
|
#
|
504
|
+
# Examples:
|
505
|
+
#
|
506
|
+
# browser.add_listener(:status) { |page, message| ... }
|
507
|
+
# browser.add_listener(:alert) { |page, message| ... }
|
508
|
+
# browser.add_listener(:web_window_event) { |web_window_event| ... }
|
509
|
+
# browser.add_listener(:html_parser) { |message, url, line, column, key| ... }
|
510
|
+
# browser.add_listener(:incorrectness) { |message, origin| ... }
|
511
|
+
# browser.add_listener(:confirm) { |page, message| ...; true }
|
512
|
+
# browser.add_listener(:prompt) { |page, message| ... }
|
513
|
+
#
|
472
514
|
#
|
473
515
|
# @param [Symbol] type One of the above symbols.
|
474
516
|
# @param [Proc] block A block to be executed for events of this type.
|
475
|
-
#
|
517
|
+
#
|
476
518
|
|
477
519
|
def add_listener(type, &block)
|
478
|
-
|
479
|
-
|
520
|
+
listener.add_listener(type, &block)
|
521
|
+
end
|
522
|
+
|
523
|
+
def remove_listener(type, &block)
|
524
|
+
listener.remove_listener(type, &block)
|
480
525
|
end
|
481
|
-
|
526
|
+
|
527
|
+
#
|
528
|
+
# Specify a boolean value to click either 'OK' or 'Cancel' in any confirm
|
529
|
+
# dialogs that might show up during the duration of the given block.
|
530
|
+
#
|
531
|
+
# (Celerity only)
|
532
|
+
#
|
533
|
+
# @param [Boolean] bool true to click 'OK', false to click 'cancel'
|
534
|
+
# @param [Proc] block A block that will trigger the confirm() call(s).
|
535
|
+
#
|
536
|
+
|
537
|
+
def confirm(bool, &block)
|
538
|
+
blk = lambda { bool }
|
539
|
+
|
540
|
+
listener.add_listener(:confirm, &blk)
|
541
|
+
yield
|
542
|
+
listener.remove_listener(:confirm, blk)
|
543
|
+
end
|
544
|
+
|
482
545
|
#
|
483
546
|
# Add a 'checker' proc that will be run on every page load
|
484
547
|
#
|
485
548
|
# @param [Proc] checker The proc to be run (can also be given as a block)
|
486
549
|
# @yieldparam [Celerity::Browser] browser The current browser object.
|
487
550
|
# @raise [ArgumentError] if no Proc or block was given.
|
488
|
-
#
|
551
|
+
#
|
489
552
|
|
490
553
|
def add_checker(checker = nil, &block)
|
491
554
|
if block_given?
|
@@ -500,7 +563,7 @@ module Celerity
|
|
500
563
|
#
|
501
564
|
# Remove the given checker from the list of checkers
|
502
565
|
# @param [Proc] checker The Proc to disable.
|
503
|
-
#
|
566
|
+
#
|
504
567
|
|
505
568
|
def disable_checker(checker)
|
506
569
|
@error_checkers.delete(checker)
|
@@ -508,22 +571,45 @@ module Celerity
|
|
508
571
|
|
509
572
|
#
|
510
573
|
# :finest, :finer, :fine, :config, :info, :warning, :severe, or :off, :all
|
511
|
-
#
|
574
|
+
#
|
512
575
|
# @return [Symbol] the current log level
|
513
|
-
#
|
576
|
+
#
|
514
577
|
|
515
578
|
def log_level
|
516
|
-
|
579
|
+
Celerity::Util.logger_for('com.gargoylesoftware.htmlunit').level.to_s.downcase.to_sym
|
517
580
|
end
|
518
581
|
|
519
582
|
#
|
520
|
-
# Set Java log level (default is :warning)
|
583
|
+
# Set Java log level (default is :warning, can be any of :all, :finest, :finer, :fine, :config, :info, :warning, :severe, :off)
|
584
|
+
#
|
585
|
+
# @param [Symbol] level The new log level.
|
521
586
|
#
|
522
|
-
# @param [Symbol] level :finest, :finer, :fine, :config, :info, :warning, :severe, or :off, :all
|
523
|
-
#
|
524
587
|
|
525
588
|
def log_level=(level)
|
526
|
-
|
589
|
+
log_level = java.util.logging.Level.const_get(level.to_s.upcase)
|
590
|
+
|
591
|
+
[ 'com.gargoylesoftware.htmlunit',
|
592
|
+
'com.gargoylesoftware.htmlunit.html',
|
593
|
+
'com.gargoylesoftware.htmlunit.javascript',
|
594
|
+
'org.apache.commons.httpclient'
|
595
|
+
].each { |package| Celerity::Util.logger_for(package).level = log_level }
|
596
|
+
|
597
|
+
level
|
598
|
+
end
|
599
|
+
|
600
|
+
#
|
601
|
+
# If a request is made to an URL that matches the pattern set here, Celerity
|
602
|
+
# will ignore the request and return an empty page with content type "text/html" instead.
|
603
|
+
#
|
604
|
+
# This is useful to block unwanted requests (like ads/banners).
|
605
|
+
#
|
606
|
+
|
607
|
+
def ignore_pattern=(regexp)
|
608
|
+
unless regexp.kind_of?(Regexp)
|
609
|
+
raise TypeError, "expected Regexp, got #{regexp.inspect}:#{regexp.class}"
|
610
|
+
end
|
611
|
+
|
612
|
+
Celerity::IgnoringWebConnection.new(@webclient, regexp)
|
527
613
|
end
|
528
614
|
|
529
615
|
#
|
@@ -536,6 +622,91 @@ module Celerity
|
|
536
622
|
end
|
537
623
|
alias_method :exists?, :exist?
|
538
624
|
|
625
|
+
#
|
626
|
+
# Turn on/off javascript exceptions
|
627
|
+
#
|
628
|
+
# @param [Bool]
|
629
|
+
#
|
630
|
+
|
631
|
+
def javascript_exceptions=(bool)
|
632
|
+
@webclient.throwExceptionOnScriptError = bool
|
633
|
+
end
|
634
|
+
|
635
|
+
def javascript_exceptions
|
636
|
+
@webclient.throwExceptionOnScriptError
|
637
|
+
end
|
638
|
+
|
639
|
+
#
|
640
|
+
# Turn on/off status code exceptions
|
641
|
+
#
|
642
|
+
# @param [Bool]
|
643
|
+
#
|
644
|
+
|
645
|
+
def status_code_exceptions=(bool)
|
646
|
+
@webclient.throwExceptionOnFailingStatusCode = bool
|
647
|
+
end
|
648
|
+
|
649
|
+
def status_code_exceptions
|
650
|
+
@webclient.throwExceptionOnFailingStatusCode
|
651
|
+
end
|
652
|
+
|
653
|
+
#
|
654
|
+
# Turn on/off CSS loading
|
655
|
+
#
|
656
|
+
# @param [Bool]
|
657
|
+
#
|
658
|
+
|
659
|
+
def css=(bool)
|
660
|
+
@webclient.cssEnabled = bool
|
661
|
+
end
|
662
|
+
|
663
|
+
def css
|
664
|
+
@webclient.cssEnabled
|
665
|
+
end
|
666
|
+
|
667
|
+
def refresh_handler=(symbol)
|
668
|
+
handler = case symbol
|
669
|
+
when :waiting
|
670
|
+
HtmlUnit::WaitingRefreshHandler.new
|
671
|
+
when :threaded
|
672
|
+
HtmlUnit::ThreadedRefreshHandler.new
|
673
|
+
when :immediate
|
674
|
+
HtmlUnit::ImmediateRefreshHandler.new
|
675
|
+
else
|
676
|
+
raise ArgumentError, "expected :waiting, :threaded or :immediate"
|
677
|
+
end
|
678
|
+
|
679
|
+
@webclient.setRefreshHandler handler
|
680
|
+
end
|
681
|
+
|
682
|
+
#
|
683
|
+
# Turn on/off secure SSL
|
684
|
+
#
|
685
|
+
# @param [Bool]
|
686
|
+
#
|
687
|
+
|
688
|
+
def secure_ssl=(bool)
|
689
|
+
@webclient.useInsecureSSL = !bool
|
690
|
+
end
|
691
|
+
|
692
|
+
def secure_ssl
|
693
|
+
!@webclient.useInsecureSSL
|
694
|
+
end
|
695
|
+
|
696
|
+
#
|
697
|
+
# Turn on/off JavaScript execution
|
698
|
+
#
|
699
|
+
# @param [Bool]
|
700
|
+
#
|
701
|
+
|
702
|
+
def javascript_enabled=(bool)
|
703
|
+
@webclient.setJavaScriptEnabled(bool)
|
704
|
+
end
|
705
|
+
|
706
|
+
def javascript_enabled
|
707
|
+
@webclient.isJavaScriptEnabled
|
708
|
+
end
|
709
|
+
|
539
710
|
#
|
540
711
|
# Sets the current page object for the browser
|
541
712
|
#
|
@@ -544,11 +715,11 @@ module Celerity
|
|
544
715
|
#
|
545
716
|
|
546
717
|
def page=(value)
|
547
|
-
|
718
|
+
return if @page == value
|
548
719
|
@page = value
|
549
720
|
|
550
721
|
if @page.respond_to?("getDocumentElement")
|
551
|
-
@object = @page.getDocumentElement
|
722
|
+
@object = @page.getDocumentElement || @object
|
552
723
|
elsif @page.is_a? HtmlUnit::UnexpectedPage
|
553
724
|
raise UnexpectedPageException, @page.getWebResponse.getContentType
|
554
725
|
end
|
@@ -562,21 +733,52 @@ module Celerity
|
|
562
733
|
#
|
563
734
|
# Check that we have a @page object.
|
564
735
|
#
|
565
|
-
# @raise [
|
736
|
+
# @raise [UnknownObjectException] if no page is loaded.
|
566
737
|
# @api private
|
567
|
-
#
|
568
|
-
|
738
|
+
#
|
739
|
+
|
569
740
|
def assert_exists
|
570
741
|
raise UnknownObjectException, "no page loaded" unless exist?
|
571
742
|
end
|
572
|
-
|
743
|
+
|
573
744
|
#
|
574
745
|
# Returns the element that currently has the focus (Celerity only)
|
575
746
|
#
|
576
747
|
|
577
748
|
def focused_element
|
578
749
|
element_from_dom_node(page.getFocusedElement())
|
579
|
-
end
|
750
|
+
end
|
751
|
+
|
752
|
+
#
|
753
|
+
# Enable Celerity's internal WebWindowEventListener
|
754
|
+
#
|
755
|
+
# @api private
|
756
|
+
#
|
757
|
+
|
758
|
+
def enable_event_listener
|
759
|
+
@event_listener ||= lambda do |event|
|
760
|
+
self.page = @page ? @page.getEnclosingWindow.getEnclosedPage : event.getNewPage
|
761
|
+
end
|
762
|
+
|
763
|
+
listener.add_listener(:web_window_event, &@event_listener)
|
764
|
+
end
|
765
|
+
|
766
|
+
#
|
767
|
+
# Disable Celerity's internal WebWindowEventListener
|
768
|
+
#
|
769
|
+
# @api private
|
770
|
+
#
|
771
|
+
|
772
|
+
def disable_event_listener
|
773
|
+
listener.remove_listener(:web_window_event, @event_listener)
|
774
|
+
|
775
|
+
if block_given?
|
776
|
+
result = yield
|
777
|
+
enable_event_listener
|
778
|
+
|
779
|
+
result
|
780
|
+
end
|
781
|
+
end
|
580
782
|
|
581
783
|
private
|
582
784
|
|
@@ -585,49 +787,78 @@ module Celerity
|
|
585
787
|
#
|
586
788
|
# @see add_checker
|
587
789
|
# @api private
|
588
|
-
#
|
589
|
-
|
790
|
+
#
|
791
|
+
|
590
792
|
def run_error_checks
|
591
793
|
@error_checkers.each { |e| e[self] }
|
592
794
|
end
|
593
|
-
|
795
|
+
|
594
796
|
#
|
595
797
|
# Configure the webclient according to the options given to #new.
|
596
798
|
# @see initialize
|
597
799
|
#
|
598
800
|
|
599
801
|
def setup_webclient(opts)
|
600
|
-
browser = (opts.delete(:browser) || :
|
802
|
+
browser = (opts.delete(:browser) || :firefox).to_sym
|
803
|
+
|
804
|
+
browser_version = case browser
|
805
|
+
when :firefox, :ff, :ff2
|
806
|
+
::HtmlUnit::BrowserVersion::FIREFOX_2
|
807
|
+
when :firefox3, :ff3
|
808
|
+
::HtmlUnit::BrowserVersion::FIREFOX_3
|
809
|
+
when :internet_explorer, :ie
|
810
|
+
::HtmlUnit::BrowserVersion::INTERNET_EXPLORER_7
|
811
|
+
else
|
812
|
+
raise ArgumentError, "unknown browser: #{browser.inspect}"
|
813
|
+
end
|
814
|
+
|
815
|
+
if ua = opts.delete(:user_agent)
|
816
|
+
browser_version.setUserAgent(ua)
|
817
|
+
end
|
601
818
|
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
819
|
+
@webclient = if proxy = opts.delete(:proxy)
|
820
|
+
phost, pport = proxy.split(":")
|
821
|
+
::HtmlUnit::WebClient.new(browser_version, phost, pport.to_i)
|
822
|
+
else
|
823
|
+
::HtmlUnit::WebClient.new(browser_version)
|
824
|
+
end
|
825
|
+
|
826
|
+
self.javascript_exceptions = false unless opts.delete(:javascript_exceptions)
|
827
|
+
self.status_code_exceptions = false unless opts.delete(:status_code_exceptions)
|
828
|
+
self.css = false unless opts.delete(:css)
|
829
|
+
self.javascript_enabled = opts.delete(:javascript_enabled) != false
|
830
|
+
self.secure_ssl = opts.delete(:secure_ssl) == false
|
831
|
+
self.ignore_pattern = opts.delete(:ignore_pattern) if opts[:ignore_pattern]
|
832
|
+
self.refresh_handler = opts.delete(:refresh_handler) if opts[:refresh_handler]
|
833
|
+
|
834
|
+
if opts.delete(:resynchronize)
|
835
|
+
controller = ::HtmlUnit::NicelyResynchronizingAjaxController.new
|
836
|
+
@webclient.setAjaxController controller
|
609
837
|
end
|
610
838
|
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
839
|
+
enable_event_listener
|
840
|
+
end
|
841
|
+
|
842
|
+
def setup_viewer(option)
|
843
|
+
@viewer = DefaultViewer
|
844
|
+
return if option == false
|
845
|
+
|
846
|
+
host_string = option.kind_of?(String) ? option : "127.0.0.1:6429"
|
847
|
+
host, port = host_string.split(":")
|
848
|
+
|
849
|
+
if viewer = ViewerConnection.create(host, port.to_i)
|
850
|
+
@viewer = viewer
|
616
851
|
end
|
617
|
-
|
618
|
-
|
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)
|
852
|
+
rescue Errno::ECONNREFUSED => e
|
853
|
+
nil
|
623
854
|
end
|
624
855
|
|
625
856
|
#
|
626
857
|
# This *should* be unneccessary, but sometimes the page we get from the
|
627
858
|
# window is different (ie. a different object) from our current @page
|
628
859
|
# (Used by #wait_while and #wait_until)
|
629
|
-
#
|
630
|
-
|
860
|
+
#
|
861
|
+
|
631
862
|
def refresh_page_from_window
|
632
863
|
new_page = @page.getEnclosingWindow.getEnclosedPage
|
633
864
|
|
@@ -637,44 +868,20 @@ module Celerity
|
|
637
868
|
Log.debug "unneccessary refresh"
|
638
869
|
end
|
639
870
|
end
|
640
|
-
|
871
|
+
|
641
872
|
#
|
642
|
-
# Render the current page on the viewer.
|
873
|
+
# Render the current page on the connected viewer.
|
643
874
|
# @api private
|
644
|
-
#
|
875
|
+
#
|
645
876
|
|
646
877
|
def render
|
647
878
|
@viewer.render_html(self.send(@render_type), url)
|
648
|
-
rescue
|
879
|
+
rescue Errno::ECONNREFUSED, Errno::ECONNRESET, Errno::EPIPE
|
649
880
|
@viewer = DefaultViewer
|
650
881
|
end
|
651
882
|
|
652
|
-
|
653
|
-
|
654
|
-
# @api private
|
655
|
-
#
|
656
|
-
|
657
|
-
def find_viewer
|
658
|
-
viewer = DRbObject.new_with_uri("druby://127.0.0.1:6429")
|
659
|
-
if viewer.respond_to?(:render_html)
|
660
|
-
@viewer = viewer
|
661
|
-
else
|
662
|
-
@viewer = DefaultViewer
|
663
|
-
end
|
664
|
-
rescue DRb::DRbConnError, Errno::ECONNREFUSED
|
665
|
-
@viewer = DefaultViewer
|
666
|
-
end
|
667
|
-
|
668
|
-
#
|
669
|
-
# Convert the given HtmlUnit object to a Celerity object
|
670
|
-
#
|
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
|
883
|
+
def listener
|
884
|
+
@listener ||= Celerity::Listener.new(@webclient)
|
678
885
|
end
|
679
886
|
|
680
887
|
end # Browser
|