lebowski 0.1.1 → 0.2.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/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')
|