watir-classic 3.3.0 → 3.4.0
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/CHANGES +17 -0
- data/Gemfile.lock +9 -8
- data/LICENSE +1 -0
- data/README.rdoc +6 -7
- data/Rakefile +3 -1
- data/VERSION +1 -1
- data/lib/watir-classic.rb +0 -5
- data/lib/watir-classic/browser.rb +58 -35
- data/lib/watir-classic/browsers.rb +1 -1
- data/lib/watir-classic/container.rb +39 -33
- data/lib/watir-classic/cookies.rb +32 -2
- data/lib/watir-classic/core.rb +0 -1
- data/lib/watir-classic/dialogs/alert.rb +12 -0
- data/lib/watir-classic/dialogs/file_field.rb +11 -0
- data/lib/watir-classic/drag_and_drop_helper.rb +14 -0
- data/lib/watir-classic/element.rb +292 -257
- data/lib/watir-classic/element_collection.rb +26 -8
- data/lib/watir-classic/element_extensions.rb +22 -16
- data/lib/watir-classic/exceptions.rb +4 -4
- data/lib/watir-classic/form.rb +52 -49
- data/lib/watir-classic/frame.rb +23 -14
- data/lib/watir-classic/ie-class.rb +363 -315
- data/lib/watir-classic/ie-process.rb +1 -0
- data/lib/watir-classic/ie.rb +0 -17
- data/lib/watir-classic/image.rb +58 -64
- data/lib/watir-classic/input_elements.rb +224 -219
- data/lib/watir-classic/link.rb +14 -15
- data/lib/watir-classic/locator.rb +12 -7
- data/lib/watir-classic/matches.rb +7 -3
- data/lib/watir-classic/modal_dialog.rb +38 -26
- data/lib/watir-classic/non_control_elements.rb +29 -0
- data/lib/watir-classic/options.rb +10 -15
- data/lib/watir-classic/page-container.rb +30 -48
- data/lib/watir-classic/process.rb +4 -2
- data/lib/watir-classic/screenshot.rb +6 -0
- data/lib/watir-classic/supported_elements.rb +36 -14
- data/lib/watir-classic/table.rb +81 -71
- data/lib/watir-classic/util.rb +9 -11
- data/lib/watir-classic/wait.rb +17 -4
- data/lib/watir-classic/wait_helper.rb +15 -2
- data/lib/watir-classic/win32.rb +2 -1
- data/lib/watir-classic/window.rb +35 -7
- data/lib/watir-classic/xpath_locator.rb +1 -0
- data/lib/watir-classic/yard/global_macros.rb +7 -0
- data/spec/frame_spec.rb +17 -0
- metadata +5 -7
- data/lib/watir-classic/close_all.rb +0 -31
- data/lib/watir-classic/contrib/enabled_popup.rb +0 -21
- data/lib/watir-classic/contrib/ie-new-process.rb +0 -27
- data/lib/watir-classic/contrib/page_checker.rb +0 -29
- data/watir.gif +0 -0
@@ -4,36 +4,19 @@ module Watir
|
|
4
4
|
module PageContainer
|
5
5
|
include Watir::Exception
|
6
6
|
|
7
|
-
#
|
8
|
-
#
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
url = self.document.location.href
|
21
|
-
if /shdoclc.dll/.match(url)
|
22
|
-
m = /id=IEText.*?>(.*?)</i.match(self.html)
|
23
|
-
raise NavigationException, m[1] if m
|
24
|
-
end
|
25
|
-
end
|
26
|
-
false
|
27
|
-
end
|
28
|
-
|
29
|
-
# The HTML Page
|
30
|
-
def page
|
31
|
-
document.documentelement
|
32
|
-
end
|
33
|
-
|
34
|
-
private :page
|
35
|
-
|
36
|
-
# Execute the given JavaScript string
|
7
|
+
# Execute the given JavaScript string in the context of the current page.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# browser.execute_script "var a=1; var b=a+1; return b"
|
11
|
+
#
|
12
|
+
# @example
|
13
|
+
# browser.execute_script("return {a: 1, b: 2}")["b"] # => 1
|
14
|
+
#
|
15
|
+
# @note It is needed to call return inside of the JavaScript if the value
|
16
|
+
# is needed at Ruby side.
|
17
|
+
#
|
18
|
+
# @return [Object] appropriate type of the object, which is returned from the
|
19
|
+
# JavaScript via "return" keyword or nil when "return" is omitted.
|
37
20
|
def execute_script(source)
|
38
21
|
result = nil
|
39
22
|
begin
|
@@ -50,36 +33,24 @@ module Watir
|
|
50
33
|
MultiJson.load(result)["value"] rescue nil
|
51
34
|
end
|
52
35
|
|
53
|
-
#
|
36
|
+
# @return [String] html of the current page.
|
54
37
|
def html
|
55
38
|
page.outerhtml
|
56
39
|
end
|
57
40
|
|
58
|
-
#
|
41
|
+
# @return [String] url of the page.
|
59
42
|
def url
|
60
43
|
page.document.location.href
|
61
44
|
end
|
62
45
|
|
63
|
-
#
|
46
|
+
# @return [String] text of the page.
|
64
47
|
def text
|
65
48
|
page.innertext.strip
|
66
49
|
end
|
67
50
|
|
68
|
-
|
69
|
-
@container = container
|
70
|
-
@page_container = self
|
71
|
-
end
|
72
|
-
|
73
|
-
# Search the current page for specified text or regexp.
|
74
|
-
# Returns the index if the specified text was found.
|
75
|
-
# Returns matchdata object if the specified regexp was found.
|
76
|
-
#
|
77
|
-
# *Deprecated*
|
78
|
-
# Instead use
|
79
|
-
# IE#text.include? target
|
80
|
-
# or
|
81
|
-
# IE#text.match target
|
51
|
+
# @deprecated Use "browser.text.include?(target)" or "browser.text.match(target) instead."
|
82
52
|
def contains_text(target)
|
53
|
+
Kernel.warn "Deprecated(Element#contains_text) - use \"browser.text.include?(target)\" or \"browser.text.match(target)\" instead."
|
83
54
|
if target.kind_of? Regexp
|
84
55
|
self.text.match(target)
|
85
56
|
elsif target.kind_of? String
|
@@ -89,6 +60,14 @@ module Watir
|
|
89
60
|
end
|
90
61
|
end
|
91
62
|
|
63
|
+
# @private
|
64
|
+
def set_container container
|
65
|
+
@container = container
|
66
|
+
@page_container = self
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
92
71
|
def with_json2_if_needed source
|
93
72
|
%Q[
|
94
73
|
(function() {
|
@@ -104,7 +83,10 @@ module Watir
|
|
104
83
|
]
|
105
84
|
end
|
106
85
|
|
107
|
-
|
86
|
+
# The HTML Page
|
87
|
+
def page
|
88
|
+
document.documentelement
|
89
|
+
end
|
108
90
|
|
109
91
|
end # module
|
110
92
|
end
|
@@ -1,8 +1,9 @@
|
|
1
1
|
module Watir
|
2
|
+
# @private
|
2
3
|
module Process
|
3
4
|
|
4
5
|
# Returns the number of windows processes running with the specified name.
|
5
|
-
def self.count
|
6
|
+
def self.count(name)
|
6
7
|
mgmt = WIN32OLE.connect('winmgmts:\\\\.')
|
7
8
|
processes = mgmt.InstancesOf('win32_process')
|
8
9
|
processes.extend Enumerable
|
@@ -13,8 +14,9 @@ module Watir
|
|
13
14
|
|
14
15
|
class IE
|
15
16
|
# Returns the number of IEXPLORE processes currently running.
|
17
|
+
# @return [Fixnum] number of ie processes.
|
16
18
|
def self.process_count
|
17
19
|
Watir::Process.count 'iexplore.exe'
|
18
20
|
end
|
19
21
|
end
|
20
|
-
end
|
22
|
+
end
|
@@ -3,15 +3,20 @@ require "base64"
|
|
3
3
|
require "win32/screenshot"
|
4
4
|
|
5
5
|
module Watir
|
6
|
+
# Returned by {IE#screenshot}.
|
6
7
|
class Screenshot
|
7
8
|
def initialize(browser_hwnd)
|
8
9
|
@hwnd = browser_hwnd
|
9
10
|
end
|
10
11
|
|
12
|
+
# Save screenshot to the file.
|
13
|
+
#
|
14
|
+
# @param [String] path path to the image.
|
11
15
|
def save(path)
|
12
16
|
screenshot.write(path)
|
13
17
|
end
|
14
18
|
|
19
|
+
# @return [String] image in png format.
|
15
20
|
def png
|
16
21
|
path = File.expand_path "temporary-image-#{Time.now.to_i}.png", Dir.tmpdir
|
17
22
|
save path
|
@@ -20,6 +25,7 @@ module Watir
|
|
20
25
|
File.delete path rescue nil
|
21
26
|
end
|
22
27
|
|
28
|
+
# @return [String] {#png} image formatted as base64.
|
23
29
|
def base64
|
24
30
|
Base64.encode64 png
|
25
31
|
end
|
@@ -2,7 +2,30 @@ module Watir
|
|
2
2
|
module Container
|
3
3
|
|
4
4
|
class << self
|
5
|
-
|
5
|
+
|
6
|
+
private
|
7
|
+
|
8
|
+
# @!macro support_element
|
9
|
+
# @!method $1
|
10
|
+
# Create an $1 html element instance.
|
11
|
+
#
|
12
|
+
# Elements can be searched by using different locators.
|
13
|
+
#
|
14
|
+
# @example Search by partial text:
|
15
|
+
# browser.$1(:text => /partial text/)
|
16
|
+
#
|
17
|
+
# @example Search by id:
|
18
|
+
# browser.$1(:id => "htmlid")
|
19
|
+
#
|
20
|
+
# @example Search by any arbitrary html attribute:
|
21
|
+
# browser.$1(:foo => "value-of-foo-attribute)
|
22
|
+
#
|
23
|
+
# @example Search by multiple attributes, all provided locators should evaluate to true - only then element is considered to be found:
|
24
|
+
# browser.$1(:text => "some text", :class => "css class")
|
25
|
+
#
|
26
|
+
# @example It is also possible to search for multiple elements of the same type like this:
|
27
|
+
# browser.divs(:class => "foo") # => instance of Watir::DivCollection
|
28
|
+
def support_element(method_name, args={})
|
6
29
|
klass = args[:class] || method_name.to_s.capitalize
|
7
30
|
super_class = args[:super_class] || "Element"
|
8
31
|
|
@@ -28,20 +51,8 @@ module Watir
|
|
28
51
|
]
|
29
52
|
end
|
30
53
|
|
31
|
-
private :support_element
|
32
|
-
end
|
33
|
-
|
34
|
-
def format_specifiers(tag_name, how, what)
|
35
|
-
defaults = {:tag_name => [tag_name].flatten.map(&:to_s)}
|
36
|
-
formatted_specifiers = defaults.merge(what ? {how => what} : how)
|
37
|
-
if (formatted_specifiers[:css] || formatted_specifiers[:xpath]) && formatted_specifiers.size > 2
|
38
|
-
raise ArgumentError, ":xpath and :css specifiers should be the only one when used in #{formatted_specifiers.inspect}"
|
39
|
-
end
|
40
|
-
formatted_specifiers
|
41
54
|
end
|
42
55
|
|
43
|
-
private :format_specifiers
|
44
|
-
|
45
56
|
support_element :a, :class => :Link
|
46
57
|
alias_method :link, :a
|
47
58
|
alias_method :links, :as
|
@@ -103,7 +114,6 @@ module Watir
|
|
103
114
|
support_element :hgroup
|
104
115
|
support_element :hidden, :super_class => :TextField, :super_collection => :InputElement
|
105
116
|
support_element :hr
|
106
|
-
# html and htmls?!
|
107
117
|
support_element :i
|
108
118
|
support_element :img, :class => :Image
|
109
119
|
alias_method :image, :img
|
@@ -168,5 +178,17 @@ module Watir
|
|
168
178
|
support_element :var
|
169
179
|
support_element :video
|
170
180
|
support_element :wbr
|
181
|
+
|
182
|
+
private
|
183
|
+
|
184
|
+
def format_specifiers(tag_name, how, what)
|
185
|
+
defaults = {:tag_name => [tag_name].flatten.map(&:to_s)}
|
186
|
+
formatted_specifiers = defaults.merge(what ? {how => what} : how)
|
187
|
+
if (formatted_specifiers[:css] || formatted_specifiers[:xpath]) && formatted_specifiers.size > 2
|
188
|
+
raise ArgumentError, ":xpath and :css specifiers should be the only one when used in #{formatted_specifiers.inspect}"
|
189
|
+
end
|
190
|
+
formatted_specifiers
|
191
|
+
end
|
192
|
+
|
171
193
|
end
|
172
194
|
end
|
data/lib/watir-classic/table.rb
CHANGED
@@ -1,13 +1,16 @@
|
|
1
1
|
module Watir
|
2
2
|
|
3
3
|
module TableContainer
|
4
|
-
#
|
5
|
-
#
|
4
|
+
# @return [TableRow] a row in the {Table}.
|
5
|
+
# @param [Fixnum] index row number to retrieve.
|
6
|
+
# @macro exists
|
6
7
|
def [](index)
|
7
8
|
assert_exists
|
8
9
|
TableRow.new(self, :ole_object => @o.rows.item(index))
|
9
10
|
end
|
10
11
|
|
12
|
+
# @return [Array<String>] array of table element texts.
|
13
|
+
# @macro exists
|
11
14
|
def strings
|
12
15
|
assert_exists
|
13
16
|
rows_memo = []
|
@@ -23,22 +26,28 @@ module Watir
|
|
23
26
|
end
|
24
27
|
|
25
28
|
module TableElementsContainer
|
29
|
+
|
30
|
+
private
|
31
|
+
|
26
32
|
def table_elements(klass, tags, how, what, ole_collection)
|
27
33
|
specifiers = format_specifiers(tags, how, what)
|
28
34
|
klass.new(self, specifiers, ole_collection)
|
29
35
|
end
|
30
36
|
|
31
|
-
private :table_elements
|
32
37
|
end
|
33
38
|
|
34
39
|
module TableCellsContainer
|
35
40
|
include TableElementsContainer
|
36
41
|
|
42
|
+
# @return [TableCellCollection] cells inside of the {Table}.
|
43
|
+
# @macro exists
|
37
44
|
def cells(how={}, what=nil)
|
38
45
|
assert_exists
|
39
46
|
table_elements(TableCellCollection, [:th, :td], how, what, @o.cells)
|
40
47
|
end
|
41
48
|
|
49
|
+
# @return [TableCell] cell inside of the {Table}.
|
50
|
+
# @macro exists
|
42
51
|
def cell(how={}, what=nil)
|
43
52
|
specifiers = format_specifiers([:th, :td], how, what)
|
44
53
|
index = specifiers.delete(:index) || 0
|
@@ -49,11 +58,15 @@ module Watir
|
|
49
58
|
module TableRowsContainer
|
50
59
|
include TableElementsContainer
|
51
60
|
|
61
|
+
# @return [TableRowCollection] rows inside of the {Table}.
|
62
|
+
# @macro exists
|
52
63
|
def rows(how={}, what=nil)
|
53
64
|
assert_exists
|
54
65
|
table_elements(TableRowCollection, [:tr], how, what, @o.rows)
|
55
66
|
end
|
56
67
|
|
68
|
+
# @return [TableRow] row inside of the {Table}.
|
69
|
+
# @macro exists
|
57
70
|
def row(how={}, what=nil)
|
58
71
|
specifiers = format_specifiers([:tr], how, what)
|
59
72
|
index = specifiers.delete(:index) || 0
|
@@ -61,11 +74,7 @@ module Watir
|
|
61
74
|
end
|
62
75
|
end
|
63
76
|
|
64
|
-
#
|
65
|
-
# Normally a user would not need to create this object as it is returned by the Watir::Container#table method
|
66
|
-
#
|
67
|
-
# many of the methods available to this object are inherited from the Element class
|
68
|
-
#
|
77
|
+
# Returned by {Container#table}
|
69
78
|
class Table < Element
|
70
79
|
include TableContainer
|
71
80
|
include TableRowsContainer
|
@@ -73,81 +82,39 @@ module Watir
|
|
73
82
|
|
74
83
|
attr_ole :rules
|
75
84
|
|
76
|
-
#
|
77
|
-
#
|
78
|
-
|
79
|
-
if set_or_clear == :set
|
80
|
-
begin
|
81
|
-
@original_border = @o.border.to_i
|
82
|
-
if @o.border.to_i==1
|
83
|
-
@o.border = 2
|
84
|
-
else
|
85
|
-
@o.border = 1
|
86
|
-
end
|
87
|
-
rescue
|
88
|
-
@original_border = nil
|
89
|
-
end
|
90
|
-
else
|
91
|
-
begin
|
92
|
-
@o.border= @original_border unless @original_border == nil
|
93
|
-
@original_border = nil
|
94
|
-
rescue
|
95
|
-
# we could be here for a number of reasons...
|
96
|
-
ensure
|
97
|
-
@original_border = nil
|
98
|
-
end
|
99
|
-
end
|
100
|
-
super
|
101
|
-
end
|
102
|
-
|
103
|
-
# this method is used to populate the properties in the to_s method
|
104
|
-
def table_string_creator
|
105
|
-
n = []
|
106
|
-
n << "rows:".ljust(TO_S_SIZE) + self.row_count.to_s
|
107
|
-
n << "cols:".ljust(TO_S_SIZE) + self.column_count.to_s
|
108
|
-
return n
|
109
|
-
end
|
110
|
-
private :table_string_creator
|
111
|
-
|
112
|
-
# returns the properties of the object in a string
|
113
|
-
# raises an ObjectNotFound exception if the object cannot be found
|
114
|
-
def to_s
|
115
|
-
assert_exists
|
116
|
-
r = string_creator
|
117
|
-
r += table_string_creator
|
118
|
-
return r.join("\n")
|
119
|
-
end
|
120
|
-
|
121
|
-
# Returns the number of rows inside the table, including rows in nested tables.
|
85
|
+
# @return [Fixnum] number of rows inside of the table, including rows from
|
86
|
+
# nested tables.
|
87
|
+
# @macro exists
|
122
88
|
def row_count
|
123
89
|
assert_exists
|
124
90
|
rows.length
|
125
91
|
end
|
126
92
|
|
127
|
-
#
|
128
|
-
#
|
129
|
-
#
|
93
|
+
# @return [Fixnum] number of columns inside of the table, including columns from
|
94
|
+
# nested tables.
|
95
|
+
# @param [Fixnum] index the number of row.
|
96
|
+
# @macro exists
|
130
97
|
def column_count(index=0)
|
131
98
|
assert_exists
|
132
99
|
rows[index].cells.length
|
133
100
|
end
|
134
101
|
|
135
|
-
#
|
136
|
-
#
|
137
|
-
#
|
138
|
-
# row of the table
|
139
|
-
# * columnnumber - column index to extract values from
|
102
|
+
# @return [Array<String>] array of each row's specified column text.
|
103
|
+
# @param [Fixnum] columnnumber the number of column to extract text from.
|
104
|
+
# @macro exists
|
140
105
|
def column_values(columnnumber)
|
141
|
-
|
106
|
+
(0..row_count - 1).collect {|i| self[i][columnnumber].text}
|
142
107
|
end
|
143
108
|
|
144
|
-
#
|
145
|
-
#
|
146
|
-
#
|
109
|
+
# @return [Array<String>] array of each column's text on specified row.
|
110
|
+
# @param [Fixnum] rownumber the number of row to extract column texts from.
|
111
|
+
# @macro exists
|
147
112
|
def row_values(rownumber)
|
148
|
-
|
113
|
+
(0..column_count(rownumber) - 1).collect {|i| self[rownumber][i].text}
|
149
114
|
end
|
150
115
|
|
116
|
+
# @return [Array<Hash>] array with hashes of table data.
|
117
|
+
# @macro exists
|
151
118
|
def hashes
|
152
119
|
assert_exists
|
153
120
|
|
@@ -176,6 +143,41 @@ module Watir
|
|
176
143
|
end
|
177
144
|
rows_memo
|
178
145
|
end
|
146
|
+
|
147
|
+
def to_s
|
148
|
+
assert_exists
|
149
|
+
r = string_creator
|
150
|
+
r += table_string_creator
|
151
|
+
r.join("\n")
|
152
|
+
end
|
153
|
+
|
154
|
+
private
|
155
|
+
|
156
|
+
# this method is used to populate the properties in the to_s method
|
157
|
+
def table_string_creator
|
158
|
+
n = []
|
159
|
+
n << "rows:".ljust(TO_S_SIZE) + self.row_count.to_s
|
160
|
+
n << "cols:".ljust(TO_S_SIZE) + self.column_count.to_s
|
161
|
+
n
|
162
|
+
end
|
163
|
+
|
164
|
+
# override the highlight method, as if the tables rows are set to have a background color,
|
165
|
+
# this will override the table background color, and the normal flash method won't work
|
166
|
+
def set_highlight
|
167
|
+
perform_highlight do
|
168
|
+
@original_border = @o.border.to_i
|
169
|
+
@o.border = @original_border + 1
|
170
|
+
super
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
def clear_highlight
|
175
|
+
perform_highlight do
|
176
|
+
@o.border = @original_border if @original_border
|
177
|
+
super
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
179
181
|
end
|
180
182
|
|
181
183
|
class TableSection < Element
|
@@ -184,24 +186,30 @@ module Watir
|
|
184
186
|
include TableCellsContainer
|
185
187
|
end
|
186
188
|
|
189
|
+
# Returned by {Container#tr}.
|
187
190
|
class TableRow < Element
|
188
191
|
include TableCellsContainer
|
189
192
|
|
190
|
-
#
|
193
|
+
# Iterate over each of the cell in the row.
|
194
|
+
# @yieldparam [TableCell] cell cell instance.
|
191
195
|
def each
|
192
196
|
locate
|
193
197
|
cells.each {|cell| yield cell}
|
194
198
|
end
|
195
199
|
|
196
|
-
#
|
200
|
+
# @return [TableCell] cell from the row.
|
201
|
+
# @param [Fixnum] index cell index in the row.
|
202
|
+
# @macro exists
|
197
203
|
def [](index)
|
198
204
|
assert_exists
|
199
205
|
if cells.length <= index
|
200
206
|
raise UnknownCellException, "Unable to locate a cell at index #{index}"
|
201
207
|
end
|
202
|
-
|
208
|
+
cells[index]
|
203
209
|
end
|
204
210
|
|
211
|
+
# @return [Fixnum] cells count in the row.
|
212
|
+
# @macro exists
|
205
213
|
def column_count
|
206
214
|
assert_exists
|
207
215
|
cells.length
|
@@ -209,12 +217,14 @@ module Watir
|
|
209
217
|
|
210
218
|
end
|
211
219
|
|
212
|
-
#
|
220
|
+
# Returned by {Container#td} and {Container#th}.
|
213
221
|
class TableCell < Element
|
214
222
|
attr_ole :headers
|
215
223
|
|
216
224
|
alias_method :to_s, :text
|
217
225
|
|
226
|
+
# @return [Fixnum] colspan attribute value.
|
227
|
+
# @macro exists
|
218
228
|
def colspan
|
219
229
|
locate
|
220
230
|
@o.colSpan
|