oki-celerity 0.8.1.dev
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 +111 -0
- data/LICENSE +621 -0
- data/README.rdoc +80 -0
- data/Rakefile +11 -0
- data/VERSION.yml +5 -0
- data/celerity.gemspec +126 -0
- data/lib/celerity/browser.rb +908 -0
- data/lib/celerity/clickable_element.rb +73 -0
- data/lib/celerity/collections.rb +164 -0
- data/lib/celerity/container.rb +800 -0
- data/lib/celerity/default_viewer.rb +14 -0
- data/lib/celerity/disabled_element.rb +40 -0
- data/lib/celerity/element.rb +311 -0
- data/lib/celerity/element_collection.rb +107 -0
- data/lib/celerity/element_locator.rb +164 -0
- data/lib/celerity/elements/button.rb +54 -0
- data/lib/celerity/elements/file_field.rb +29 -0
- data/lib/celerity/elements/form.rb +22 -0
- data/lib/celerity/elements/frame.rb +86 -0
- data/lib/celerity/elements/image.rb +89 -0
- data/lib/celerity/elements/label.rb +16 -0
- data/lib/celerity/elements/link.rb +43 -0
- data/lib/celerity/elements/meta.rb +14 -0
- data/lib/celerity/elements/non_control_elements.rb +124 -0
- data/lib/celerity/elements/option.rb +38 -0
- data/lib/celerity/elements/radio_check.rb +114 -0
- data/lib/celerity/elements/select_list.rb +146 -0
- data/lib/celerity/elements/table.rb +153 -0
- data/lib/celerity/elements/table_cell.rb +36 -0
- data/lib/celerity/elements/table_elements.rb +42 -0
- data/lib/celerity/elements/table_row.rb +49 -0
- data/lib/celerity/elements/text_field.rb +168 -0
- data/lib/celerity/exception.rb +83 -0
- data/lib/celerity/htmlunit/apache-mime4j-0.6.jar +0 -0
- data/lib/celerity/htmlunit/commons-codec-1.4.jar +0 -0
- data/lib/celerity/htmlunit/commons-collections-3.2.1.jar +0 -0
- data/lib/celerity/htmlunit/commons-io-1.4.jar +0 -0
- data/lib/celerity/htmlunit/commons-lang-2.5.jar +0 -0
- data/lib/celerity/htmlunit/commons-logging-1.1.1.jar +0 -0
- data/lib/celerity/htmlunit/cssparser-0.9.5.jar +0 -0
- data/lib/celerity/htmlunit/htmlunit-2.9-SNAPSHOT.jar +0 -0
- data/lib/celerity/htmlunit/htmlunit-core-js-2.8.jar +0 -0
- data/lib/celerity/htmlunit/httpclient-4.0.1.jar +0 -0
- data/lib/celerity/htmlunit/httpcore-4.0.1.jar +0 -0
- data/lib/celerity/htmlunit/httpmime-4.0.1.jar +0 -0
- data/lib/celerity/htmlunit/nekohtml-1.9.14.jar +0 -0
- data/lib/celerity/htmlunit/sac-1.3.jar +0 -0
- data/lib/celerity/htmlunit/serializer-2.7.1.jar +0 -0
- data/lib/celerity/htmlunit/xalan-2.7.1.jar +0 -0
- data/lib/celerity/htmlunit/xercesImpl-2.9.1.jar +0 -0
- data/lib/celerity/htmlunit/xml-apis-1.3.04.jar +0 -0
- data/lib/celerity/htmlunit.rb +64 -0
- data/lib/celerity/identifier.rb +28 -0
- data/lib/celerity/ignoring_web_connection.rb +15 -0
- data/lib/celerity/input_element.rb +25 -0
- data/lib/celerity/javascript_debugger.rb +32 -0
- data/lib/celerity/listener.rb +143 -0
- data/lib/celerity/resources/no_viewer.png +0 -0
- data/lib/celerity/short_inspect.rb +20 -0
- data/lib/celerity/util.rb +129 -0
- data/lib/celerity/version.rb +3 -0
- data/lib/celerity/viewer_connection.rb +89 -0
- data/lib/celerity/watir_compatibility.rb +70 -0
- data/lib/celerity/xpath_support.rb +52 -0
- data/lib/celerity.rb +77 -0
- data/tasks/benchmark.rake +4 -0
- data/tasks/check.rake +24 -0
- data/tasks/clean.rake +3 -0
- data/tasks/fix.rake +25 -0
- data/tasks/jar.rake +55 -0
- data/tasks/jeweler.rake +28 -0
- data/tasks/rdoc.rake +4 -0
- data/tasks/snapshot.rake +25 -0
- data/tasks/spec.rake +26 -0
- data/tasks/website.rake +10 -0
- data/tasks/yard.rake +16 -0
- metadata +204 -0
@@ -0,0 +1,25 @@
|
|
1
|
+
module Celerity
|
2
|
+
class InputElement < Element
|
3
|
+
include ClickableElement
|
4
|
+
include DisabledElement
|
5
|
+
|
6
|
+
ATTRIBUTES = BASE_ATTRIBUTES | [:type, :name, :value, :checked, :disabled, :readonly, :size, :maxlength,
|
7
|
+
:src, :alt, :usemap, :ismap, :tabindex, :accesskey, :onfocus, :onblur,
|
8
|
+
:onselect, :onchange, :accept, :align]
|
9
|
+
|
10
|
+
def readonly?
|
11
|
+
assert_exists
|
12
|
+
@object.hasAttribute 'readonly'
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def assert_not_readonly
|
18
|
+
if readonly?
|
19
|
+
raise ObjectReadOnlyException,
|
20
|
+
"InputElement #{identifier_string} is read only."
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Celerity
|
2
|
+
class JavascriptDebugger
|
3
|
+
include Java::net.sourceforge.htmlunit.corejs.javascript.debug.Debugger
|
4
|
+
|
5
|
+
def handleCompilationDone(ctx, script, source)
|
6
|
+
p debug_info_for(script).merge(:source_code => source)
|
7
|
+
end
|
8
|
+
|
9
|
+
def getFrame(ctx, script)
|
10
|
+
p debug_info_for(script)
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def string_for_context(ctx)
|
16
|
+
ctx.toString
|
17
|
+
end
|
18
|
+
|
19
|
+
def string_for_script(script)
|
20
|
+
script.toString
|
21
|
+
end
|
22
|
+
|
23
|
+
def debug_info_for(script)
|
24
|
+
{
|
25
|
+
:source => "#{script.getSourceName}:#{script.getLineNumbers.to_a.join(",")}",
|
26
|
+
:function_name => script.getFunctionName,
|
27
|
+
:params => (0...script.getParamAndVarCount).map { |idx| script.getParamOrVarName(idx) },
|
28
|
+
:function? => script.isFunction,
|
29
|
+
}
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,143 @@
|
|
1
|
+
module Celerity
|
2
|
+
|
3
|
+
#
|
4
|
+
# This class is used to wrap some of the listeners available from HtmlUnit's WebClient.
|
5
|
+
#
|
6
|
+
|
7
|
+
class Listener
|
8
|
+
include com.gargoylesoftware.htmlunit.AlertHandler
|
9
|
+
include com.gargoylesoftware.htmlunit.ConfirmHandler
|
10
|
+
include com.gargoylesoftware.htmlunit.PromptHandler
|
11
|
+
include com.gargoylesoftware.htmlunit.html.HTMLParserListener
|
12
|
+
include com.gargoylesoftware.htmlunit.IncorrectnessListener
|
13
|
+
include com.gargoylesoftware.htmlunit.StatusHandler
|
14
|
+
include com.gargoylesoftware.htmlunit.WebWindowListener
|
15
|
+
include com.gargoylesoftware.htmlunit.attachment.AttachmentHandler
|
16
|
+
|
17
|
+
def initialize(webclient)
|
18
|
+
@webclient = webclient
|
19
|
+
@procs = Hash.new { |h, k| h[k] = [] }
|
20
|
+
end
|
21
|
+
|
22
|
+
#
|
23
|
+
# Add a listener block for one of the available types.
|
24
|
+
# @see Celerity::Browser#add_listener
|
25
|
+
#
|
26
|
+
|
27
|
+
def add_listener(type, &block)
|
28
|
+
case type
|
29
|
+
when :status
|
30
|
+
@webclient.setStatusHandler(self)
|
31
|
+
when :alert
|
32
|
+
@webclient.setAlertHandler(self)
|
33
|
+
when :attachment
|
34
|
+
@webclient.setAttachmentHandler(self)
|
35
|
+
when :web_window_event
|
36
|
+
@webclient.addWebWindowListener(self)
|
37
|
+
when :html_parser
|
38
|
+
@webclient.setHTMLParserListener(self)
|
39
|
+
when :incorrectness
|
40
|
+
@webclient.setIncorrectnessListener(self)
|
41
|
+
when :confirm
|
42
|
+
@webclient.setConfirmHandler(self)
|
43
|
+
when :prompt
|
44
|
+
@webclient.setPromptHandler(self)
|
45
|
+
else
|
46
|
+
raise ArgumentError, "unknown listener type #{type.inspect}"
|
47
|
+
end
|
48
|
+
|
49
|
+
@procs[type] << block
|
50
|
+
end
|
51
|
+
|
52
|
+
def remove_listener(type, proc_or_index)
|
53
|
+
unless @procs.has_key?(type)
|
54
|
+
raise ArgumentError, "unknown listener type #{type.inspect}"
|
55
|
+
end
|
56
|
+
|
57
|
+
procs = @procs[type]
|
58
|
+
|
59
|
+
case proc_or_index
|
60
|
+
when Fixnum
|
61
|
+
procs.delete_at proc_or_index
|
62
|
+
when Proc
|
63
|
+
procs.delete proc_or_index
|
64
|
+
else
|
65
|
+
raise TypeError, "must give proc or index"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
#
|
70
|
+
# interface StatusHandler
|
71
|
+
#
|
72
|
+
|
73
|
+
def statusMessageChanged(page, message)
|
74
|
+
@procs[:status].each { |handler| handler.call(page, message) }
|
75
|
+
end
|
76
|
+
|
77
|
+
#
|
78
|
+
# interface AlertHandler
|
79
|
+
#
|
80
|
+
|
81
|
+
def handleAlert(page, message)
|
82
|
+
@procs[:alert].each { |handler| handler.call(page, message) }
|
83
|
+
end
|
84
|
+
|
85
|
+
#
|
86
|
+
# interface ConfirmHandler
|
87
|
+
#
|
88
|
+
# The returned value is determined by the last registered :confirm listener proc.
|
89
|
+
# If it is nil, return true, otherwise return that value as a boolean.
|
90
|
+
#
|
91
|
+
# @see Browser#confirm
|
92
|
+
#
|
93
|
+
|
94
|
+
def handleConfirm(page, message)
|
95
|
+
val = @procs[:confirm].map { |handler| handler.call(page, message) }.last
|
96
|
+
val.nil? || !!val
|
97
|
+
end
|
98
|
+
|
99
|
+
#
|
100
|
+
# interface AttachmentHandler
|
101
|
+
#
|
102
|
+
|
103
|
+
def handleAttachment(page)
|
104
|
+
@procs[:attachment].each { |handler| handler.call(page) }
|
105
|
+
end
|
106
|
+
|
107
|
+
#
|
108
|
+
# interface PromptHandler
|
109
|
+
#
|
110
|
+
|
111
|
+
def handlePrompt(page, message)
|
112
|
+
@procs[:prompt].each { |handler| handler.call(page, message) }
|
113
|
+
end
|
114
|
+
|
115
|
+
#
|
116
|
+
# interface WebWindowListener
|
117
|
+
#
|
118
|
+
|
119
|
+
def webWindowClosed(web_window_event)
|
120
|
+
@procs[:web_window_event].each { |handler| handler.call(web_window_event) }
|
121
|
+
end
|
122
|
+
alias_method :webWindowOpened, :webWindowClosed
|
123
|
+
alias_method :webWindowContentChanged, :webWindowClosed
|
124
|
+
|
125
|
+
#
|
126
|
+
# interface HTMLParserListener
|
127
|
+
#
|
128
|
+
|
129
|
+
def error(message, url, line, column, key)
|
130
|
+
@procs[:html_parser].each { |handler| handler.call(message, url, line, column, key) }
|
131
|
+
end
|
132
|
+
alias_method :warning, :error
|
133
|
+
|
134
|
+
#
|
135
|
+
# interface IncorrectnessListener
|
136
|
+
#
|
137
|
+
|
138
|
+
def notify(message, origin)
|
139
|
+
@procs[:incorrectness].each { |handler| handler.call(message, origin) }
|
140
|
+
end
|
141
|
+
|
142
|
+
end # Listener
|
143
|
+
end # Celerity
|
Binary file
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Celerity
|
2
|
+
module ShortInspect
|
3
|
+
|
4
|
+
def short_inspect(opts)
|
5
|
+
if excluded_ivars = opts[:exclude]
|
6
|
+
ivars = (instance_variables - excluded_ivars)
|
7
|
+
elsif included_ivars = opts[:include]
|
8
|
+
ivars = included_ivars
|
9
|
+
else
|
10
|
+
raise ArgumentError, "unknown arg: #{opts.inspect}"
|
11
|
+
end
|
12
|
+
|
13
|
+
ivars.map! { |ivar| "#{ivar}=#{instance_variable_get(ivar).inspect}" }
|
14
|
+
'#<%s:0x%s %s>' % [self.class.name, self.hash.to_s(16), ivars.join(" ")]
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
module Celerity
|
2
|
+
module Util
|
3
|
+
module_function
|
4
|
+
|
5
|
+
HtmlUnit2CelerityElement = {
|
6
|
+
HtmlUnit::Html::HtmlAnchor => Celerity::Link,
|
7
|
+
HtmlUnit::Html::HtmlArea => Celerity::Area,
|
8
|
+
HtmlUnit::Html::HtmlButton => Celerity::Button,
|
9
|
+
HtmlUnit::Html::HtmlSubmitInput => Celerity::Button,
|
10
|
+
HtmlUnit::Html::HtmlResetInput => Celerity::Button,
|
11
|
+
HtmlUnit::Html::HtmlImageInput => Celerity::Button,
|
12
|
+
HtmlUnit::Html::HtmlButtonInput => Celerity::Button,
|
13
|
+
HtmlUnit::Html::HtmlCaption => Celerity::Button, # ?
|
14
|
+
HtmlUnit::Html::HtmlCheckBoxInput => Celerity::CheckBox,
|
15
|
+
HtmlUnit::Html::HtmlDefinitionDescription => Celerity::Dd,
|
16
|
+
HtmlUnit::Html::HtmlDefinitionList => Celerity::Dl,
|
17
|
+
HtmlUnit::Html::HtmlDefinitionTerm => Celerity::Dt,
|
18
|
+
HtmlUnit::Html::HtmlDeletedText => Celerity::Del,
|
19
|
+
HtmlUnit::Html::HtmlDivision => Celerity::Div,
|
20
|
+
HtmlUnit::Html::HtmlFileInput => Celerity::FileField,
|
21
|
+
HtmlUnit::Html::HtmlForm => Celerity::Form,
|
22
|
+
HtmlUnit::Html::HtmlFrame => Celerity::Frame,
|
23
|
+
HtmlUnit::Html::HtmlHeading1 => Celerity::H1,
|
24
|
+
HtmlUnit::Html::HtmlHeading2 => Celerity::H2,
|
25
|
+
HtmlUnit::Html::HtmlHeading3 => Celerity::H3,
|
26
|
+
HtmlUnit::Html::HtmlHeading4 => Celerity::H4,
|
27
|
+
HtmlUnit::Html::HtmlHeading5 => Celerity::H5,
|
28
|
+
HtmlUnit::Html::HtmlHeading6 => Celerity::H6,
|
29
|
+
HtmlUnit::Html::HtmlHiddenInput => Celerity::Hidden,
|
30
|
+
HtmlUnit::Html::HtmlImage => Celerity::Image,
|
31
|
+
HtmlUnit::Html::HtmlLabel => Celerity::Label,
|
32
|
+
HtmlUnit::Html::HtmlListItem => Celerity::Li,
|
33
|
+
HtmlUnit::Html::HtmlMap => Celerity::Map,
|
34
|
+
HtmlUnit::Html::HtmlOption => Celerity::Option,
|
35
|
+
HtmlUnit::Html::HtmlOrderedList => Celerity::Ol,
|
36
|
+
HtmlUnit::Html::HtmlParagraph => Celerity::P,
|
37
|
+
HtmlUnit::Html::HtmlPasswordInput => Celerity::TextField,
|
38
|
+
HtmlUnit::Html::HtmlPreformattedText => Celerity::Pre,
|
39
|
+
HtmlUnit::Html::HtmlRadioButtonInput => Celerity::Radio,
|
40
|
+
HtmlUnit::Html::HtmlSelect => Celerity::SelectList,
|
41
|
+
HtmlUnit::Html::HtmlSpan => Celerity::Span,
|
42
|
+
HtmlUnit::Html::HtmlTable => Celerity::Table,
|
43
|
+
HtmlUnit::Html::HtmlTableBody => Celerity::TableBody,
|
44
|
+
HtmlUnit::Html::HtmlTableCell => Celerity::TableCell,
|
45
|
+
HtmlUnit::Html::HtmlTableDataCell => Celerity::TableCell,
|
46
|
+
HtmlUnit::Html::HtmlTableFooter => Celerity::TableFooter,
|
47
|
+
HtmlUnit::Html::HtmlTableHeader => Celerity::TableHeader,
|
48
|
+
HtmlUnit::Html::HtmlTableRow => Celerity::TableRow,
|
49
|
+
HtmlUnit::Html::HtmlTextArea => Celerity::TextField,
|
50
|
+
HtmlUnit::Html::HtmlTextInput => Celerity::TextField,
|
51
|
+
HtmlUnit::Html::HtmlUnorderedList => Celerity::Ul,
|
52
|
+
HtmlUnit::Html::HtmlInsertedText => Celerity::Ins
|
53
|
+
}
|
54
|
+
|
55
|
+
def htmlunit2celerity(klass)
|
56
|
+
HtmlUnit2CelerityElement[klass]
|
57
|
+
end
|
58
|
+
|
59
|
+
#
|
60
|
+
# HtmlUnit will recognize most common file types, but custom ones can be added here.
|
61
|
+
# Used for FileField uploads.
|
62
|
+
#
|
63
|
+
|
64
|
+
ContentTypes = {
|
65
|
+
".bmp" => "image/x-ms-bmp",
|
66
|
+
".doc" => "application/msword",
|
67
|
+
".odg" => "application/vnd.oasis.opendocument.graphics",
|
68
|
+
".odp" => "application/vnd.oasis.opendocument.presentation",
|
69
|
+
".ods" => "application/vnd.oasis.opendocument.spreadsheet",
|
70
|
+
".odt" => "application/vnd.oasis.opendocument.text",
|
71
|
+
".ppt" => "application/vnd.ms-powerpoint",
|
72
|
+
".xls" => "application/vnd.ms-excel",
|
73
|
+
}
|
74
|
+
|
75
|
+
def content_type_for(path)
|
76
|
+
if ct = java.net.URLConnection.getFileNameMap.getContentTypeFor(path)
|
77
|
+
return ct
|
78
|
+
else
|
79
|
+
ContentTypes[File.extname(path).downcase]
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def normalize_text(string)
|
84
|
+
string.gsub("\302\240", ' '). # non-breaking space 00A0
|
85
|
+
gsub(/\n|\t/, ''). # get rid of newlines/tabs
|
86
|
+
strip
|
87
|
+
end
|
88
|
+
|
89
|
+
def logger_for(package_string)
|
90
|
+
java.util.logging.Logger.getLogger(package_string)
|
91
|
+
end
|
92
|
+
|
93
|
+
# number of spaces that separate the property from the value in the create_string method
|
94
|
+
TO_S_SIZE = 14
|
95
|
+
|
96
|
+
def create_string(element)
|
97
|
+
ret = []
|
98
|
+
|
99
|
+
unless (tag = element.getTagName).empty?
|
100
|
+
ret << "tag:".ljust(TO_S_SIZE) + tag
|
101
|
+
end
|
102
|
+
|
103
|
+
element.getAttributes.each do |attribute|
|
104
|
+
ret << " #{attribute.getName}:".ljust(TO_S_SIZE + 2) + attribute.getValue.to_s
|
105
|
+
end
|
106
|
+
|
107
|
+
unless (text = element.asText).empty?
|
108
|
+
ret << " text:".ljust(TO_S_SIZE + 2) + element.asText
|
109
|
+
end
|
110
|
+
|
111
|
+
ret.join("\n")
|
112
|
+
end
|
113
|
+
|
114
|
+
#
|
115
|
+
# Used internally.
|
116
|
+
#
|
117
|
+
# @param [String] string The string to match against.
|
118
|
+
# @param [Regexp, String, #to_s] what The match we're looking for.
|
119
|
+
# @return [Fixnum, true, false, nil]
|
120
|
+
#
|
121
|
+
# @api private
|
122
|
+
#
|
123
|
+
|
124
|
+
def matches?(string, what)
|
125
|
+
Regexp === what ? string.strip =~ what : string == what.to_s
|
126
|
+
end
|
127
|
+
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module Celerity
|
2
|
+
class ViewerConnection
|
3
|
+
|
4
|
+
#
|
5
|
+
# Create a new connection to the given host/port
|
6
|
+
#
|
7
|
+
|
8
|
+
def self.create(host, port)
|
9
|
+
# if the connection fails, we won't spend time loading json
|
10
|
+
socket = TCPSocket.new(host, port)
|
11
|
+
require "json"
|
12
|
+
new(socket)
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(socket)
|
16
|
+
@socket = socket
|
17
|
+
end
|
18
|
+
|
19
|
+
#
|
20
|
+
# Tells the viewer to render the given HTML, with the given URL as base url.
|
21
|
+
#
|
22
|
+
|
23
|
+
def render_html(html, url)
|
24
|
+
send_data('method' => 'page_changed', 'html' => html, 'url' => url)
|
25
|
+
end
|
26
|
+
|
27
|
+
#
|
28
|
+
# Tells the viewer to save a screenshot of the current page to the given path.
|
29
|
+
# May not be available on all viewers.
|
30
|
+
#
|
31
|
+
|
32
|
+
def save(path)
|
33
|
+
send_data('method' => 'save', 'path' => path)
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
#
|
38
|
+
# Tells the viewer to dump the render tree to the given path.
|
39
|
+
# Only available in the Qt viewer.
|
40
|
+
#
|
41
|
+
|
42
|
+
def save_render_tree(path)
|
43
|
+
send_data('method' => 'save_render_tree', 'path' => path)
|
44
|
+
end
|
45
|
+
|
46
|
+
#
|
47
|
+
# Get the currently rendered page as a Base64-encoded PNG image.
|
48
|
+
# Only available in the Qt viewer.
|
49
|
+
#
|
50
|
+
|
51
|
+
def image_data
|
52
|
+
send_data('method' => 'image_data')
|
53
|
+
data = read_data
|
54
|
+
data['image'] || data['error']
|
55
|
+
end
|
56
|
+
|
57
|
+
#
|
58
|
+
# Close the connection.
|
59
|
+
#
|
60
|
+
|
61
|
+
def close
|
62
|
+
@socket.close rescue nil
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def send_data(msg)
|
68
|
+
json = msg.to_json
|
69
|
+
data = "Content-Length: #{json.size}\n\n#{json}"
|
70
|
+
@socket.write data
|
71
|
+
@socket.flush
|
72
|
+
|
73
|
+
nil
|
74
|
+
end
|
75
|
+
|
76
|
+
def read_data
|
77
|
+
buf = ''
|
78
|
+
until buf =~ /\n\n\z/ || @socket.eof? || @socket.closed?
|
79
|
+
buf << @socket.read(1).to_s
|
80
|
+
end
|
81
|
+
|
82
|
+
return if buf.empty?
|
83
|
+
|
84
|
+
length = buf[/Content-Length: (\d+)/, 1].to_i
|
85
|
+
JSON.parse @socket.read(length)
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module Celerity
|
2
|
+
class Browser
|
3
|
+
class << self
|
4
|
+
|
5
|
+
# Added for Watir compatibility - not in use by Celerity
|
6
|
+
attr_accessor :speed, :attach_timeout, :visible
|
7
|
+
# Added for Watir compatibility - not in use by Celerity
|
8
|
+
alias_method :start_window, :start
|
9
|
+
# Added for Watir compatibility - not in use by Celerity
|
10
|
+
def each; end
|
11
|
+
end
|
12
|
+
|
13
|
+
# Added for Watir compatibility - not in use by Celerity
|
14
|
+
attr_accessor :visible
|
15
|
+
|
16
|
+
# Added for Watir compatibility - not in use by Celerity
|
17
|
+
def bring_to_front; true; end
|
18
|
+
# Added for Watir compatibility - not in use by Celerity
|
19
|
+
def speed=(s); s end
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
module ClickableElement
|
24
|
+
alias_method :click_no_wait, :click
|
25
|
+
end
|
26
|
+
|
27
|
+
module Container
|
28
|
+
alias_method :checkbox, :check_box
|
29
|
+
alias_method :checkBox, :check_box
|
30
|
+
alias_method :body, :tbody
|
31
|
+
alias_method :bodies, :tbodies
|
32
|
+
end
|
33
|
+
|
34
|
+
class Element
|
35
|
+
alias_method :exists, :exists?
|
36
|
+
alias_method :innerText, :text
|
37
|
+
alias_method :inner_text, :text
|
38
|
+
end
|
39
|
+
|
40
|
+
class Image
|
41
|
+
alias_method :hasLoaded?, :loaded?
|
42
|
+
alias_method :fileSize, :file_size
|
43
|
+
alias_method :fileCreatedDate, :file_created_date
|
44
|
+
end
|
45
|
+
|
46
|
+
class Link
|
47
|
+
alias_method :click_no_wait, :click
|
48
|
+
end
|
49
|
+
|
50
|
+
class RadioCheckCommon
|
51
|
+
alias_method :isSet?, :set?
|
52
|
+
alias_method :getState, :set?
|
53
|
+
end
|
54
|
+
|
55
|
+
class SelectList
|
56
|
+
alias_method :getSelectedItems, :selected_options
|
57
|
+
alias_method :getAllContents, :options
|
58
|
+
alias_method :clearSelection, :clear
|
59
|
+
alias_method :includes?, :include?
|
60
|
+
end
|
61
|
+
|
62
|
+
class TextField
|
63
|
+
alias_method :dragContentsTo, :drag_contents_to
|
64
|
+
alias_method :getContents, :value
|
65
|
+
|
66
|
+
def requires_typing; end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
Celerity::IE = Celerity::Browser
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Celerity
|
2
|
+
|
3
|
+
#
|
4
|
+
# Module to search by xpath
|
5
|
+
#
|
6
|
+
|
7
|
+
module XpathSupport
|
8
|
+
|
9
|
+
#
|
10
|
+
# Get the first element found matching the given XPath.
|
11
|
+
#
|
12
|
+
# @param [String] xpath
|
13
|
+
# @return [Celerity::Element] An element subclass (or Element if none is found)
|
14
|
+
#
|
15
|
+
|
16
|
+
def element_by_xpath(xpath)
|
17
|
+
assert_exists
|
18
|
+
obj = @page.getFirstByXPath(xpath)
|
19
|
+
element_from_dom_node(obj)
|
20
|
+
end
|
21
|
+
|
22
|
+
#
|
23
|
+
# Get all the elements matching the given XPath.
|
24
|
+
#
|
25
|
+
# @param [String] xpath
|
26
|
+
# @return [Array<Celerity::Element>] array of elements
|
27
|
+
#
|
28
|
+
|
29
|
+
def elements_by_xpath(xpath)
|
30
|
+
assert_exists
|
31
|
+
objects = @page.getByXPath(xpath)
|
32
|
+
# should use an ElementCollection here?
|
33
|
+
objects.map { |o| element_from_dom_node(o) }.compact
|
34
|
+
end
|
35
|
+
|
36
|
+
#
|
37
|
+
# Convert the given HtmlUnit DomNode to a Celerity object
|
38
|
+
#
|
39
|
+
|
40
|
+
def element_from_dom_node(obj)
|
41
|
+
element_class = Util.htmlunit2celerity(obj.class) || Element
|
42
|
+
element = element_class.new(self, :object, obj)
|
43
|
+
|
44
|
+
element.extend(ClickableElement) unless element.is_a?(ClickableElement)
|
45
|
+
|
46
|
+
element
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
data/lib/celerity.rb
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__)) unless $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
2
|
+
|
3
|
+
raise "Celerity only works on JRuby at the moment." unless RUBY_PLATFORM =~ /java/
|
4
|
+
|
5
|
+
require "java"
|
6
|
+
require "logger"
|
7
|
+
require "uri"
|
8
|
+
require "pp"
|
9
|
+
require "timeout"
|
10
|
+
require "time"
|
11
|
+
require "socket"
|
12
|
+
require "fileutils"
|
13
|
+
require "thread"
|
14
|
+
|
15
|
+
module Celerity
|
16
|
+
Log = Logger.new($DEBUG ? $stderr : nil)
|
17
|
+
Log.level = Logger::DEBUG
|
18
|
+
|
19
|
+
@index_offset = 1
|
20
|
+
class << self
|
21
|
+
|
22
|
+
#
|
23
|
+
# This index_offset attribute controls the indexing used when locating
|
24
|
+
# elements by :index or fetching from Celerity::ElementCollections.
|
25
|
+
#
|
26
|
+
# By default it is set to 1 for Watir compatibility, but users who use
|
27
|
+
# Celerity exlusively may want it set to 0 to make Celerity more consistent with Ruby.
|
28
|
+
#
|
29
|
+
attr_accessor :index_offset
|
30
|
+
end
|
31
|
+
|
32
|
+
DIR = File.expand_path(File.dirname(__FILE__) + "/celerity")
|
33
|
+
end
|
34
|
+
|
35
|
+
require "celerity/version"
|
36
|
+
require "celerity/htmlunit"
|
37
|
+
require "celerity/exception"
|
38
|
+
require "celerity/clickable_element"
|
39
|
+
require "celerity/disabled_element"
|
40
|
+
require "celerity/element_collection"
|
41
|
+
require "celerity/collections"
|
42
|
+
require "celerity/element_locator"
|
43
|
+
require "celerity/identifier"
|
44
|
+
require "celerity/short_inspect"
|
45
|
+
require "celerity/container"
|
46
|
+
require "celerity/xpath_support"
|
47
|
+
require "celerity/element"
|
48
|
+
require "celerity/input_element"
|
49
|
+
require "celerity/elements/non_control_elements"
|
50
|
+
require "celerity/elements/button"
|
51
|
+
require "celerity/elements/file_field"
|
52
|
+
require "celerity/elements/form"
|
53
|
+
require "celerity/elements/frame"
|
54
|
+
require "celerity/elements/image"
|
55
|
+
require "celerity/elements/label"
|
56
|
+
require "celerity/elements/link"
|
57
|
+
require "celerity/elements/meta"
|
58
|
+
require "celerity/elements/option"
|
59
|
+
require "celerity/elements/radio_check"
|
60
|
+
require "celerity/elements/select_list"
|
61
|
+
require "celerity/elements/table"
|
62
|
+
require "celerity/elements/table_elements"
|
63
|
+
require "celerity/elements/table_cell"
|
64
|
+
require "celerity/elements/table_row"
|
65
|
+
require "celerity/elements/text_field"
|
66
|
+
require "celerity/util"
|
67
|
+
require "celerity/default_viewer"
|
68
|
+
require "celerity/listener"
|
69
|
+
require "celerity/ignoring_web_connection"
|
70
|
+
require "celerity/javascript_debugger"
|
71
|
+
require "celerity/viewer_connection"
|
72
|
+
require "celerity/browser"
|
73
|
+
require "celerity/watir_compatibility"
|
74
|
+
|
75
|
+
# undefine deprecated methods to use them for Element attributes
|
76
|
+
Object.send :undef_method, :id if Object.method_defined? "id"
|
77
|
+
Object.send :undef_method, :type if Object.method_defined? "type"
|
data/tasks/check.rake
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
namespace :check do
|
2
|
+
|
3
|
+
desc 'Check syntax of all .rb files'
|
4
|
+
task :syntax do
|
5
|
+
failed = []
|
6
|
+
|
7
|
+
Dir['**/*.rb'].each do |f|
|
8
|
+
begin
|
9
|
+
eval("lambda do\n return true\n #{File.read f} \nend").call
|
10
|
+
print "."
|
11
|
+
rescue SyntaxError => e
|
12
|
+
print "!"
|
13
|
+
failed << [f, e.message]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
if failed.empty?
|
18
|
+
puts "ok."
|
19
|
+
else
|
20
|
+
puts "\n\t#{failed.join("\n\t")}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
data/tasks/clean.rake
ADDED