lebowski 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.md +17 -1
- data/Manifest.txt +8 -0
- data/README.md +6 -0
- data/lib/lebowski/foundation/application.rb +340 -74
- data/lib/lebowski/foundation/core.rb +23 -0
- data/lib/lebowski/foundation/dom_element.rb +15 -0
- data/lib/lebowski/foundation/errors/timeout.rb +5 -0
- data/lib/lebowski/foundation/mixins/collection_item_view_support.rb +5 -0
- data/lib/lebowski/foundation/mixins/define_paths_support.rb +318 -0
- data/lib/lebowski/foundation/mixins/delegate_support.rb +5 -0
- data/lib/lebowski/foundation/mixins/frame_application_context_support.rb +37 -0
- data/lib/lebowski/foundation/mixins/inline_text_field_support.rb +5 -0
- data/lib/lebowski/foundation/mixins/key_check.rb +5 -0
- data/lib/lebowski/foundation/mixins/list_item_view_support.rb +5 -0
- data/lib/lebowski/foundation/mixins/positioned_element.rb +24 -0
- data/lib/lebowski/foundation/mixins/stall_support.rb +5 -0
- data/lib/lebowski/foundation/mixins/user_actions.rb +37 -8
- data/lib/lebowski/foundation/mixins/wait_actions.rb +5 -0
- data/lib/lebowski/foundation/object_array.rb +96 -1
- data/lib/lebowski/foundation/proxy_factory.rb +2 -0
- data/lib/lebowski/foundation/proxy_object.rb +128 -130
- data/lib/lebowski/foundation/views/select_button.rb +69 -0
- data/lib/lebowski/foundation/views/view.rb +10 -0
- data/lib/lebowski/foundation/views/web.rb +26 -0
- data/lib/lebowski/foundation.rb +10 -0
- data/lib/lebowski/runtime/errors/remote_control_command_execution_error.rb +5 -0
- data/lib/lebowski/runtime/errors/remote_control_command_timeout_error.rb +5 -0
- data/lib/lebowski/runtime/errors/remote_control_error.rb +5 -0
- data/lib/lebowski/runtime/errors/selenium_server_error.rb +5 -0
- data/lib/lebowski/runtime/object_encoder.rb +5 -0
- data/lib/lebowski/runtime/sprout_core_driver.rb +5 -0
- data/lib/lebowski/runtime/sprout_core_extensions.rb +114 -0
- data/lib/lebowski/runtime.rb +5 -0
- data/lib/lebowski/scui/mixins/link_support.rb +32 -0
- data/lib/lebowski/scui/mixins/node_item_view_support.rb +50 -13
- data/lib/lebowski/scui/mixins/terminal_view_support.rb +30 -0
- data/lib/lebowski/scui/views/color_well.rb +48 -0
- data/lib/lebowski/scui/views/combo_box.rb +90 -87
- data/lib/lebowski/scui/views/content_editable.rb +422 -0
- data/lib/lebowski/scui/views/date_picker.rb +70 -58
- data/lib/lebowski/scui/views/linkit.rb +8 -0
- data/lib/lebowski/scui/views/select_field_tab.rb +30 -0
- data/lib/lebowski/scui.rb +18 -0
- data/lib/lebowski/version.rb +2 -2
- data/resources/user-extensions.js +293 -11
- metadata +69 -25
@@ -61,21 +61,41 @@ module Lebowski
|
|
61
61
|
return @prefilter.clone
|
62
62
|
end
|
63
63
|
|
64
|
+
#
|
65
|
+
# Used to create a new filtered object array from this array based on this given filter. The new object
|
66
|
+
# array will only reference those items that match the given filter
|
67
|
+
#
|
64
68
|
def filter(filter)
|
65
69
|
merged_filter = merge_filter_with_prefilter(filter)
|
66
70
|
return create_filtered_object_array(@parent, @array_rel_path, @array_length_property_name, merged_filter)
|
67
71
|
end
|
68
72
|
|
73
|
+
#
|
74
|
+
# Returns an enumerable object of indexes for those items in the array that match the given filter
|
75
|
+
#
|
76
|
+
# This method gives you a chance to perform any processing on the given filter by overriding the
|
77
|
+
# find_indexes_process_filter method. Once indexes are found you can also process the index before
|
78
|
+
# a final result is returned by overriding the find_indexes_process_indexes method.
|
79
|
+
#
|
80
|
+
# @see #find_indexes_process_filter
|
81
|
+
# @see #find_indexes_process_indexes
|
82
|
+
#
|
69
83
|
def find_indexes(filter=nil)
|
70
84
|
raise ArgumentError.new "No filter was supplied" if (filter.nil? and @prefilter.empty?)
|
71
85
|
|
86
|
+
# Do some initial processing of the given filter
|
72
87
|
if filter.nil?
|
88
|
+
# Filter is nil, so make it an empty hash object
|
73
89
|
filter = {}
|
74
90
|
elsif filter.kind_of? String
|
91
|
+
# Filter is just a string, therefore assume the string is an SproutCore type
|
75
92
|
filter = { :sc_type => filter }
|
76
93
|
elsif filter.kind_of?(Class) and filter.ancestors.member?(SCObject)
|
94
|
+
# Filter is an SCObject, therefore get the SC type as a string
|
77
95
|
filter = { :sc_type => filter.represented_sc_class }
|
78
96
|
elsif filter.kind_of?(Hash)
|
97
|
+
# Filter is a hash object. Just need to check if the hash contains the special
|
98
|
+
# key :sc_type. If so then do necessary conversions.
|
79
99
|
if filter.has_key? :sc_type
|
80
100
|
type = filter[:sc_type]
|
81
101
|
if type.kind_of?(Class) and type.ancestors.member?(SCObject)
|
@@ -86,30 +106,38 @@ module Lebowski
|
|
86
106
|
raise ArgumentInvalidTypeError.new "filter", filter, 'class < SCObject', String, Hash
|
87
107
|
end
|
88
108
|
|
109
|
+
# Merge the given filter with this object's prefilter
|
89
110
|
filter = merge_filter_with_prefilter(filter)
|
90
111
|
|
112
|
+
# Give a chance for the filter to be processed before finding matching indexes
|
91
113
|
processed_filter = find_indexes_process_filter(filter)
|
92
114
|
raise StandardError.new "process filter can not be nil" if processed_filter.nil?
|
93
115
|
|
94
116
|
if not processed_filter.empty?
|
117
|
+
# Filter is not empty therefore actually determine what indexes matches the filter
|
95
118
|
sc_path = @parent.abs_path_with(@array_rel_path)
|
96
119
|
indexes = @driver.get_sc_object_array_index_lookup(sc_path, processed_filter)
|
97
120
|
return indexes if indexes.empty?
|
98
121
|
else
|
122
|
+
# Filter is empty, so just return a range of indexes for this array
|
99
123
|
val = unfiltered_count
|
100
124
|
return [] if val <= 0
|
101
125
|
indexes = (0..(val - 1))
|
102
126
|
end
|
103
127
|
|
128
|
+
# Now give a chance for the matching indexes to be processed before returning the
|
129
|
+
# final result
|
104
130
|
processed_indexes = find_indexes_process_indexes(indexes)
|
105
131
|
raise StandardError.new "process indexes can not be nil" if processed_indexes.nil?
|
106
132
|
|
133
|
+
# We're done. Return the final result
|
107
134
|
return processed_indexes
|
108
135
|
|
109
136
|
end
|
110
137
|
|
111
138
|
#
|
112
|
-
# Returns the number of
|
139
|
+
# Returns the number of items in the array. If a filter is provided then the count
|
140
|
+
# will be for those items in the array that match the filter
|
113
141
|
#
|
114
142
|
def count(filter=nil, &block)
|
115
143
|
if @prefilter.empty? and filter.nil? and (not block_given?)
|
@@ -126,6 +154,9 @@ module Lebowski
|
|
126
154
|
return counter
|
127
155
|
end
|
128
156
|
|
157
|
+
#
|
158
|
+
# Returns an item at the given index of the array
|
159
|
+
#
|
129
160
|
def [](index, expected_type=nil)
|
130
161
|
error = ArgumentError.new "index is out of bounds: #{index}"
|
131
162
|
|
@@ -143,14 +174,24 @@ module Lebowski
|
|
143
174
|
end
|
144
175
|
end
|
145
176
|
|
177
|
+
#
|
178
|
+
# Returns the first item in the array
|
179
|
+
#
|
146
180
|
def first(expected_type=nil)
|
147
181
|
return self[0, expected_type]
|
148
182
|
end
|
149
183
|
|
184
|
+
#
|
185
|
+
# Returns the last item in the array
|
186
|
+
#
|
150
187
|
def last(expected_type=nil)
|
151
188
|
return self[count - 1, expected_type]
|
152
189
|
end
|
153
190
|
|
191
|
+
#
|
192
|
+
# Used to iterative through each item in the array. Can filter what items
|
193
|
+
# are iterated over by supply a filter object
|
194
|
+
#
|
154
195
|
def each(filter=nil, &block)
|
155
196
|
raise ArgumentError.new "block is required" if (not block_given?)
|
156
197
|
|
@@ -175,6 +216,13 @@ module Lebowski
|
|
175
216
|
|
176
217
|
alias_method :each_with_index, :each
|
177
218
|
|
219
|
+
#
|
220
|
+
# Returns all the items matching a given filter. If the filter is nil
|
221
|
+
# then all the items are returns. If no mathing items are found then
|
222
|
+
# an empty array is returned.
|
223
|
+
#
|
224
|
+
# @return {Array} basic array containing the matching found items
|
225
|
+
#
|
178
226
|
def find_all(filter=nil, &block)
|
179
227
|
if filter.nil? and (not block_given?)
|
180
228
|
raise ArugmentError.new "Must provide at least a filter or a block"
|
@@ -192,6 +240,10 @@ module Lebowski
|
|
192
240
|
return collected
|
193
241
|
end
|
194
242
|
|
243
|
+
#
|
244
|
+
# Returns the first item matching the given filter. If no items match
|
245
|
+
# then nil is returned
|
246
|
+
#
|
195
247
|
def find_first(filter, expected_type=nil)
|
196
248
|
if filter.nil?
|
197
249
|
raise ArgumentError.new "filter can not be nil"
|
@@ -202,6 +254,10 @@ module Lebowski
|
|
202
254
|
return create_object(indexes[0], expected_type)
|
203
255
|
end
|
204
256
|
|
257
|
+
#
|
258
|
+
# Returns the last item matching a given filter. If no items match then
|
259
|
+
# nil is returned.
|
260
|
+
#
|
205
261
|
def find_last(filter, expected_type=nil)
|
206
262
|
if filter.nil?
|
207
263
|
raise ArgumentError.new "filter can not be nil"
|
@@ -212,34 +268,55 @@ module Lebowski
|
|
212
268
|
return create_object(indexes[indexes.length - 1], expected_type)
|
213
269
|
end
|
214
270
|
|
271
|
+
#
|
272
|
+
# Returns the index of the given object
|
273
|
+
#
|
215
274
|
def index_of(obj)
|
216
275
|
return -1 if (not obj.kind_of? ProxyObject)
|
217
276
|
indexes = find_indexes({ :sc_guid => obj.sc_guid })
|
218
277
|
return indexes.empty? ? -1 : indexes[0]
|
219
278
|
end
|
220
279
|
|
280
|
+
#
|
281
|
+
# Used to determine if an object is part of this array
|
282
|
+
#
|
221
283
|
def member?(obj)
|
222
284
|
return (index_of(obj) >= 0)
|
223
285
|
end
|
224
286
|
|
287
|
+
#
|
288
|
+
# Used to check if all items in the array match the given filter
|
289
|
+
#
|
225
290
|
def all?(filter=nil, &block)
|
226
291
|
return (count(filter, &block) == count)
|
227
292
|
end
|
228
293
|
|
294
|
+
#
|
295
|
+
# Used to check if any items in the array match the given filter
|
296
|
+
#
|
229
297
|
def any?(filter=nil, &block)
|
230
298
|
return (count(filter, &block) > 0)
|
231
299
|
end
|
232
300
|
|
233
301
|
alias_method :some?, :any?
|
234
302
|
|
303
|
+
#
|
304
|
+
# Used to check if no items in the array match the given filter
|
305
|
+
#
|
235
306
|
def none?(filter=nil, &block)
|
236
307
|
return (count(filter, &block) == 0)
|
237
308
|
end
|
238
309
|
|
310
|
+
#
|
311
|
+
# Used to check if only one item in the array matches the given filter
|
312
|
+
#
|
239
313
|
def one?(filter=nil, &block)
|
240
314
|
return (count(filter, &block) == 1)
|
241
315
|
end
|
242
316
|
|
317
|
+
#
|
318
|
+
# Used to check if the array is empty
|
319
|
+
#
|
243
320
|
def empty?()
|
244
321
|
return (count == 0)
|
245
322
|
end
|
@@ -262,10 +339,28 @@ module Lebowski
|
|
262
339
|
end
|
263
340
|
end
|
264
341
|
|
342
|
+
#
|
343
|
+
# Called by the find_indexes method. Used to do any processing of a given filter before
|
344
|
+
# it is used to find matching indexes. By default, the method just returns the given array
|
345
|
+
# without any processing done.
|
346
|
+
#
|
347
|
+
# @return {Hash} a filter object that has been processed.
|
348
|
+
#
|
349
|
+
# @see #find_indexes
|
350
|
+
#
|
265
351
|
def find_indexes_process_filter(filter)
|
266
352
|
return filter
|
267
353
|
end
|
268
354
|
|
355
|
+
#
|
356
|
+
# Called by the find_indexes method. Used to do any processing of a given enumerable object of
|
357
|
+
# indexes before the final result is returned. By default, the method just returns the given
|
358
|
+
# indexes without any processing done.
|
359
|
+
#
|
360
|
+
# @return {Enumerable} an enumerable object of indexes
|
361
|
+
#
|
362
|
+
# @see #find_indexes
|
363
|
+
#
|
269
364
|
def find_indexes_process_indexes(indexes)
|
270
365
|
return indexes
|
271
366
|
end
|
@@ -18,6 +18,7 @@ module Lebowski
|
|
18
18
|
|
19
19
|
include Lebowski::Foundation
|
20
20
|
include Lebowski::Foundation::Mixins::WaitActions
|
21
|
+
include Lebowski::Foundation::Mixins::DefinePathsSupport
|
21
22
|
|
22
23
|
attr_reader :parent, # The parent object of this object. Must derive from Lebowski::Foundation::ProxyObject
|
23
24
|
:rel_path, # The relative path to the remote object using SC property path notation
|
@@ -49,7 +50,7 @@ module Lebowski
|
|
49
50
|
@rel_path = rel_path
|
50
51
|
@driver = driver
|
51
52
|
@guid = nil
|
52
|
-
@
|
53
|
+
@cached_proxy_objects = {}
|
53
54
|
@defined_proxies = {}
|
54
55
|
@name = ""
|
55
56
|
|
@@ -165,91 +166,6 @@ module Lebowski
|
|
165
166
|
return "#{path}.#{rel_path}"
|
166
167
|
end
|
167
168
|
|
168
|
-
def define(key, rel_path, expected_type=nil)
|
169
|
-
if (not key.kind_of?(String)) or key.empty? or (not key.match(/[\. ]/).nil?)
|
170
|
-
raise ArgumentError.raise "key must be a valid string"
|
171
|
-
end
|
172
|
-
|
173
|
-
if (not rel_path.kind_of?(String)) or rel_path.empty?
|
174
|
-
raise ArgumentError.raise "rel_path must be a valid string"
|
175
|
-
end
|
176
|
-
|
177
|
-
if @defined_paths.has_key? key
|
178
|
-
raise ArgumentError.raise "key '#{key}' already defined as path '#{@defined_paths[key]}'"
|
179
|
-
end
|
180
|
-
|
181
|
-
first_path_part = rel_path_first_part(rel_path)
|
182
|
-
sub_path = rel_path_sub_path(rel_path, first_path_part)
|
183
|
-
|
184
|
-
type = ""
|
185
|
-
err_abs_path = abs_path_with(rel_path)
|
186
|
-
|
187
|
-
if @defined_paths.has_key? first_path_part
|
188
|
-
obj = @defined_paths[first_path_part]
|
189
|
-
type = obj.sc_type_of(sub_path)
|
190
|
-
err_abs_path = obj.abs_path_with(sub_path)
|
191
|
-
else
|
192
|
-
type = sc_type_of(rel_path)
|
193
|
-
end
|
194
|
-
|
195
|
-
if not (type == SC_T_OBJECT or type == SC_T_HASH)
|
196
|
-
err_msg = "Error trying to define key '#{key}'. "
|
197
|
-
err_msg << "Relative path '#{rel_path}' does not point to an object. "
|
198
|
-
err_msg << "Path is refencing: #{type}. Absolute path = #{err_abs_path}"
|
199
|
-
raise ArgumentError.new err_msg
|
200
|
-
end
|
201
|
-
|
202
|
-
obj = self[rel_path, expected_type]
|
203
|
-
|
204
|
-
@defined_paths[key] = obj
|
205
|
-
|
206
|
-
return obj
|
207
|
-
end
|
208
|
-
|
209
|
-
def defined()
|
210
|
-
return @defined_paths.clone if (not @defined_paths.nil?)
|
211
|
-
return {}
|
212
|
-
end
|
213
|
-
|
214
|
-
def proxy(klass, rel_path)
|
215
|
-
obj = self[rel_path]
|
216
|
-
if not obj.kind_of?(ProxyObject)
|
217
|
-
raise ArgumentError.new "rel_path does not point to an object that can be proxied: #{obj} (#{obj.class})"
|
218
|
-
end
|
219
|
-
|
220
|
-
if not (klass.kind_of?(Class) and klass.ancestors.member?(ProxyObject))
|
221
|
-
raise ArgumentInvalidTypeError.new "klass", klass, 'class < ProxyObject'
|
222
|
-
end
|
223
|
-
|
224
|
-
@defined_proxies[rel_path] = obj.represent_as(klass)
|
225
|
-
end
|
226
|
-
|
227
|
-
#
|
228
|
-
# Given a relative path, unravel it to access an object. Unraveling means to take
|
229
|
-
# any defined paths in the given relative path and convert the entire path back
|
230
|
-
# into a full relative path without definitions.
|
231
|
-
#
|
232
|
-
def unravel_relative_path(rel_path)
|
233
|
-
if not @defined_proxies[rel_path].nil?
|
234
|
-
return @defined_proxies[rel_path]
|
235
|
-
end
|
236
|
-
|
237
|
-
first_path_part = rel_path_first_part(rel_path)
|
238
|
-
sub_path = rel_path_sub_path(rel_path, first_path_part)
|
239
|
-
|
240
|
-
return rel_path if (not @defined_paths.has_key?(first_path_part))
|
241
|
-
|
242
|
-
obj = @defined_paths[first_path_part]
|
243
|
-
return obj if sub_path.empty?
|
244
|
-
|
245
|
-
result = obj.unravel_relative_path(sub_path)
|
246
|
-
|
247
|
-
return "#{obj.rel_path}.#{result}" if result.kind_of?(String)
|
248
|
-
return result if result.kind_of?(Lebowski::Foundation::SCObject)
|
249
|
-
|
250
|
-
raise StandardError.new "Unexpected result unreeling rel path: #{result}"
|
251
|
-
end
|
252
|
-
|
253
169
|
#
|
254
170
|
# Gets the remote SproutCore GUID for this object
|
255
171
|
#
|
@@ -321,6 +237,68 @@ module Lebowski
|
|
321
237
|
return (type == SC_T_OBJECT or type == SC_T_HASH)
|
322
238
|
end
|
323
239
|
|
240
|
+
# DEPRECATED
|
241
|
+
def proxy(klass, rel_path)
|
242
|
+
puts "DEPRECATED: proxy is deprecated. use define_proxy instead"
|
243
|
+
define_proxy(klass, rel_path)
|
244
|
+
end
|
245
|
+
|
246
|
+
# DEPRECATED
|
247
|
+
def define(path, rel_path=nil, expected_type=nil)
|
248
|
+
puts "DEPRECATED: define is deprecated. use define_path instead"
|
249
|
+
define_path(path, rel_path, expected_type)
|
250
|
+
end
|
251
|
+
|
252
|
+
#
|
253
|
+
# Defines a path proxy for a relative path on this proxy object. The path proxy
|
254
|
+
# will be loaded only when actually requested for use.
|
255
|
+
#
|
256
|
+
# @param klass The klass to use as the path proxy
|
257
|
+
# @param rel_path The relative path agaist this proxy object
|
258
|
+
#
|
259
|
+
def define_proxy(klass, rel_path)
|
260
|
+
if (not rel_path.kind_of?(String)) or rel_path.empty?
|
261
|
+
raise ArgumentError.new "rel_path must be a valid string"
|
262
|
+
end
|
263
|
+
|
264
|
+
if not (klass.kind_of?(Class) and klass.ancestors.member?(ProxyObject))
|
265
|
+
raise ArgumentInvalidTypeError.new "klass", klass, 'class < ProxyObject'
|
266
|
+
end
|
267
|
+
|
268
|
+
@defined_proxies[rel_path] = klass
|
269
|
+
end
|
270
|
+
|
271
|
+
#
|
272
|
+
# Given a relative path, unravel it to access an object. Unraveling means to take
|
273
|
+
# any defined path in the given relative path and convert the entire path back
|
274
|
+
# into a full relative path without definitions.
|
275
|
+
#
|
276
|
+
def unravel_relative_path(rel_path)
|
277
|
+
path_parts = rel_path.split '.'
|
278
|
+
|
279
|
+
full_rel_path = ""
|
280
|
+
defined_path = nil
|
281
|
+
counter = path_parts.length
|
282
|
+
|
283
|
+
for path_part in path_parts do
|
284
|
+
path = defined_path.nil? ? path_part : "#{defined_path}.#{path_part}"
|
285
|
+
if path_defined? path
|
286
|
+
defined_path = path
|
287
|
+
else
|
288
|
+
break
|
289
|
+
end
|
290
|
+
counter = counter - 1
|
291
|
+
end
|
292
|
+
|
293
|
+
full_rel_path << self.defined_path(defined_path).full_rel_path if (not defined_path.nil?)
|
294
|
+
if (counter > 0)
|
295
|
+
full_rel_path << "." if (not defined_path.nil?)
|
296
|
+
full_rel_path << path_parts.last(counter).join('.')
|
297
|
+
end
|
298
|
+
|
299
|
+
return full_rel_path
|
300
|
+
end
|
301
|
+
|
324
302
|
#
|
325
303
|
# The primary method used to access a proxied object's properties. Accessing
|
326
304
|
# a property is done using a relative property path. The path is a chain of
|
@@ -401,58 +379,39 @@ module Lebowski
|
|
401
379
|
# will be returned.
|
402
380
|
#
|
403
381
|
def [](rel_path, expected_type=nil)
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
if (not result.kind_of?(String))
|
408
|
-
if (not expected_type.nil?)
|
409
|
-
got_expected_type = (expected_type == :object or result.sc_kind_of?(expected_type))
|
410
|
-
if (not got_expected_type)
|
411
|
-
raise UnexpectedTypeError.new(abs_path_with(rel_path), expected_type, "object", result)
|
412
|
-
end
|
413
|
-
end
|
414
|
-
return result
|
382
|
+
if (not rel_path.kind_of?(String)) or rel_path.empty?
|
383
|
+
raise ArgumentError.new "rel_path must be a valid string"
|
415
384
|
end
|
416
385
|
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
case type
|
421
|
-
when SC_T_NULL
|
422
|
-
return handle_type_null(rel_path, expected_type)
|
423
|
-
|
424
|
-
when SC_T_UNDEFINED
|
425
|
-
return handle_type_undefined(rel_path, expected_type)
|
426
|
-
|
427
|
-
when SC_T_ERROR
|
428
|
-
return handle_type_error(rel_path, expected_type)
|
429
|
-
|
430
|
-
when SC_T_STRING
|
431
|
-
return handle_type_string(rel_path, expected_type)
|
432
|
-
|
433
|
-
when SC_T_NUMBER
|
434
|
-
return handle_type_number(rel_path, expected_type)
|
435
|
-
|
436
|
-
when SC_T_BOOL
|
437
|
-
return handle_type_bool(rel_path, expected_type)
|
438
|
-
|
439
|
-
when SC_T_ARRAY
|
440
|
-
return handle_type_array(rel_path, expected_type)
|
441
|
-
|
442
|
-
when SC_T_HASH
|
443
|
-
return handle_type_hash(rel_path, expected_type)
|
386
|
+
if @cached_proxy_objects.has_key? rel_path
|
387
|
+
return @cached_proxy_objects[rel_path]
|
388
|
+
end
|
444
389
|
|
445
|
-
|
446
|
-
return handle_type_object(rel_path, expected_type)
|
390
|
+
defined_proxy = @defined_proxies.has_key?(rel_path) ? @defined_proxies[rel_path] : nil
|
447
391
|
|
448
|
-
|
449
|
-
return handle_type_class(rel_path, expected_type)
|
392
|
+
path_defined = path_defined? rel_path
|
450
393
|
|
451
|
-
|
452
|
-
|
394
|
+
if path_defined
|
395
|
+
path = defined_path rel_path
|
396
|
+
expected_type = path.expected_type if (path.has_expected_type? and expected_type.nil?)
|
453
397
|
end
|
398
|
+
|
399
|
+
unraveled_rel_path = unravel_relative_path rel_path
|
400
|
+
value = fetch_rel_path_value unraveled_rel_path, expected_type
|
401
|
+
|
402
|
+
if value.kind_of? ProxyObject
|
403
|
+
value = value.represent_as(defined_proxy) if (not defined_proxy.nil?)
|
404
|
+
@cached_proxy_objects[rel_path] = value if (path_defined or not defined_proxy.nil?)
|
405
|
+
end
|
406
|
+
|
407
|
+
return value
|
454
408
|
end
|
455
409
|
|
410
|
+
#
|
411
|
+
# Retain a reference to the original eql? method so we can still use it
|
412
|
+
#
|
413
|
+
alias_method :__eql?, :eql?
|
414
|
+
|
456
415
|
#
|
457
416
|
# Override the == operator so that a proxy object can be compared to another
|
458
417
|
# proxy object via their SproutCore GUIDs
|
@@ -509,6 +468,45 @@ module Lebowski
|
|
509
468
|
return sub_path
|
510
469
|
end
|
511
470
|
|
471
|
+
def fetch_rel_path_value(rel_path, expected_type)
|
472
|
+
type = sc_type_of(rel_path)
|
473
|
+
|
474
|
+
case type
|
475
|
+
when SC_T_NULL
|
476
|
+
return handle_type_null(rel_path, expected_type)
|
477
|
+
|
478
|
+
when SC_T_UNDEFINED
|
479
|
+
return handle_type_undefined(rel_path, expected_type)
|
480
|
+
|
481
|
+
when SC_T_ERROR
|
482
|
+
return handle_type_error(rel_path, expected_type)
|
483
|
+
|
484
|
+
when SC_T_STRING
|
485
|
+
return handle_type_string(rel_path, expected_type)
|
486
|
+
|
487
|
+
when SC_T_NUMBER
|
488
|
+
return handle_type_number(rel_path, expected_type)
|
489
|
+
|
490
|
+
when SC_T_BOOL
|
491
|
+
return handle_type_bool(rel_path, expected_type)
|
492
|
+
|
493
|
+
when SC_T_ARRAY
|
494
|
+
return handle_type_array(rel_path, expected_type)
|
495
|
+
|
496
|
+
when SC_T_HASH
|
497
|
+
return handle_type_hash(rel_path, expected_type)
|
498
|
+
|
499
|
+
when SC_T_OBJECT
|
500
|
+
return handle_type_object(rel_path, expected_type)
|
501
|
+
|
502
|
+
when SC_T_CLASS
|
503
|
+
return handle_type_class(rel_path, expected_type)
|
504
|
+
|
505
|
+
else
|
506
|
+
raise StandardError.new "Unrecognized returned type '#{type}' for path #{abs_path_with(rel_path)}"
|
507
|
+
end
|
508
|
+
end
|
509
|
+
|
512
510
|
def handle_type_null(rel_path, expected_type)
|
513
511
|
if (not expected_type.nil?) and not (expected_type == :null)
|
514
512
|
raise UnexpectedTypeError.new(abs_path_with(rel_path), expected_type, SC_T_NULL, :null)
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# ==========================================================================
|
2
|
+
# Project: Lebowski Framework - The SproutCore Test Automation Framework
|
3
|
+
# License: Licensed under MIT license (see License.txt)
|
4
|
+
# ==========================================================================
|
5
|
+
|
6
|
+
module Lebowski
|
7
|
+
module Foundation
|
8
|
+
module Views
|
9
|
+
|
10
|
+
#
|
11
|
+
# Represents a proxy to a SproutCore select button (SC.SelectButtonView)
|
12
|
+
#
|
13
|
+
class SelectButtonView < Lebowski::Foundation::Views::View
|
14
|
+
include Lebowski::Foundation::Util
|
15
|
+
|
16
|
+
representing_sc_class 'SC.SelectButtonView'
|
17
|
+
|
18
|
+
def display_menu
|
19
|
+
self.mouse_down if !menu_displayed?
|
20
|
+
end
|
21
|
+
|
22
|
+
def hide_menu
|
23
|
+
menu.click_off if menu_displayed?
|
24
|
+
end
|
25
|
+
|
26
|
+
def menu_displayed?
|
27
|
+
return (not menu.nil?)
|
28
|
+
end
|
29
|
+
|
30
|
+
def menu
|
31
|
+
@menu = get_root_application_object.responding_panes.find_first(MenuPane)
|
32
|
+
if not @menu.nil?
|
33
|
+
@menu = @menu.represent_as(SelectButtonMenu)
|
34
|
+
@menu.select_button = self
|
35
|
+
end
|
36
|
+
return @menu
|
37
|
+
end
|
38
|
+
|
39
|
+
def select_item(title)
|
40
|
+
display_menu
|
41
|
+
menu.menu_items.click title
|
42
|
+
end
|
43
|
+
|
44
|
+
def checkbox_enabled?
|
45
|
+
@checkbox_enabled = self['checkboxEnabled'] if @checkbox_enabled.nil?
|
46
|
+
return @checkbox_enabled
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class SelectButtonMenu < Lebowski::Foundation::Panes::MenuPane
|
51
|
+
attr_writer :select_button
|
52
|
+
|
53
|
+
def item_checked?(title)
|
54
|
+
raise "The checkbox option is not enabled for this select button." if not @select_button.checkbox_enabled?
|
55
|
+
menu_item = nil
|
56
|
+
if title.kind_of? String
|
57
|
+
menu_item = menu_items.find_first({ :title => /^#{title}$/i })
|
58
|
+
elsif title.kind_of? Regexp
|
59
|
+
menu_item = menu_items.find_first({ :title => title })
|
60
|
+
else
|
61
|
+
raise ArgumentInvalidTypeError.new "title", title, String, Regexp
|
62
|
+
end
|
63
|
+
return menu_item['content.checkbox']
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -66,6 +66,16 @@ module Lebowski
|
|
66
66
|
return @driver.get_sc_element_window_position(action_target, *action_locator_args)
|
67
67
|
end
|
68
68
|
|
69
|
+
# @override Lebowski::Foundation::Mixins::PositionedElement#width
|
70
|
+
def width()
|
71
|
+
return frame.width
|
72
|
+
end
|
73
|
+
|
74
|
+
# @override Lebowski::Foundation::Mixins::PositionedElement#height
|
75
|
+
def height()
|
76
|
+
return frame.height
|
77
|
+
end
|
78
|
+
|
69
79
|
# @override Lebowski::Foundation::Mixins::PositionedElement#scroll_to_visible
|
70
80
|
def scroll_to_visible()
|
71
81
|
@driver.sc_view_scroll_to_visible(abs_path)
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# ==========================================================================
|
2
|
+
# Project: Lebowski Framework - The SproutCore Test Automation Framework
|
3
|
+
# License: Licensed under MIT license (see License.txt)
|
4
|
+
# ==========================================================================
|
5
|
+
|
6
|
+
module Lebowski
|
7
|
+
module Foundation
|
8
|
+
module Views
|
9
|
+
|
10
|
+
#
|
11
|
+
# Represents a proxy to a SproutCore web view (SC.WebView)
|
12
|
+
#
|
13
|
+
class WebView < Lebowski::Foundation::Views::View
|
14
|
+
include Lebowski::Foundation::Mixins::FrameApplicationContextSupport
|
15
|
+
|
16
|
+
representing_sc_class 'SC.WebView'
|
17
|
+
|
18
|
+
def frame_app_context_locator()
|
19
|
+
return "css=##{layer_id} iframe"
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/lebowski/foundation.rb
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
# ==========================================================================
|
2
|
+
# Project: Lebowski Framework - The SproutCore Test Automation Framework
|
3
|
+
# License: Licensed under MIT license (see License.txt)
|
4
|
+
# ==========================================================================
|
5
|
+
|
1
6
|
require File.expand_path(File.dirname(__FILE__) + '/foundation/core')
|
2
7
|
|
3
8
|
require File.expand_path(File.dirname(__FILE__) + '/foundation/errors/unexpected_type')
|
@@ -13,6 +18,8 @@ require File.expand_path(File.dirname(__FILE__) + '/foundation/mixins/inline_tex
|
|
13
18
|
require File.expand_path(File.dirname(__FILE__) + '/foundation/mixins/delegate_support')
|
14
19
|
require File.expand_path(File.dirname(__FILE__) + '/foundation/mixins/collection_item_view_support')
|
15
20
|
require File.expand_path(File.dirname(__FILE__) + '/foundation/mixins/list_item_view_support')
|
21
|
+
require File.expand_path(File.dirname(__FILE__) + '/foundation/mixins/frame_application_context_support')
|
22
|
+
require File.expand_path(File.dirname(__FILE__) + '/foundation/mixins/define_paths_support')
|
16
23
|
|
17
24
|
require File.expand_path(File.dirname(__FILE__) + '/foundation/proxy_object')
|
18
25
|
require File.expand_path(File.dirname(__FILE__) + '/foundation/sc_object')
|
@@ -37,6 +44,7 @@ require File.expand_path(File.dirname(__FILE__) + '/foundation/views/collection'
|
|
37
44
|
require File.expand_path(File.dirname(__FILE__) + '/foundation/views/list')
|
38
45
|
require File.expand_path(File.dirname(__FILE__) + '/foundation/views/list_item')
|
39
46
|
require File.expand_path(File.dirname(__FILE__) + '/foundation/views/grid')
|
47
|
+
require File.expand_path(File.dirname(__FILE__) + '/foundation/views/web')
|
40
48
|
|
41
49
|
require File.expand_path(File.dirname(__FILE__) + '/foundation/panes/pane')
|
42
50
|
require File.expand_path(File.dirname(__FILE__) + '/foundation/panes/main')
|
@@ -48,5 +56,7 @@ require File.expand_path(File.dirname(__FILE__) + '/foundation/panes/picker')
|
|
48
56
|
require File.expand_path(File.dirname(__FILE__) + '/foundation/panes/sheet')
|
49
57
|
require File.expand_path(File.dirname(__FILE__) + '/foundation/panes/menu')
|
50
58
|
|
59
|
+
require File.expand_path(File.dirname(__FILE__) + '/foundation/views/select_button')
|
60
|
+
|
51
61
|
require File.expand_path(File.dirname(__FILE__) + '/foundation/application')
|
52
62
|
require File.expand_path(File.dirname(__FILE__) + '/foundation/proxy_factory')
|