celerity 0.0.6 → 0.0.7
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 +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
|