lebowski 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. data/History.md +17 -1
  2. data/Manifest.txt +8 -0
  3. data/README.md +6 -0
  4. data/lib/lebowski/foundation/application.rb +340 -74
  5. data/lib/lebowski/foundation/core.rb +23 -0
  6. data/lib/lebowski/foundation/dom_element.rb +15 -0
  7. data/lib/lebowski/foundation/errors/timeout.rb +5 -0
  8. data/lib/lebowski/foundation/mixins/collection_item_view_support.rb +5 -0
  9. data/lib/lebowski/foundation/mixins/define_paths_support.rb +318 -0
  10. data/lib/lebowski/foundation/mixins/delegate_support.rb +5 -0
  11. data/lib/lebowski/foundation/mixins/frame_application_context_support.rb +37 -0
  12. data/lib/lebowski/foundation/mixins/inline_text_field_support.rb +5 -0
  13. data/lib/lebowski/foundation/mixins/key_check.rb +5 -0
  14. data/lib/lebowski/foundation/mixins/list_item_view_support.rb +5 -0
  15. data/lib/lebowski/foundation/mixins/positioned_element.rb +24 -0
  16. data/lib/lebowski/foundation/mixins/stall_support.rb +5 -0
  17. data/lib/lebowski/foundation/mixins/user_actions.rb +37 -8
  18. data/lib/lebowski/foundation/mixins/wait_actions.rb +5 -0
  19. data/lib/lebowski/foundation/object_array.rb +96 -1
  20. data/lib/lebowski/foundation/proxy_factory.rb +2 -0
  21. data/lib/lebowski/foundation/proxy_object.rb +128 -130
  22. data/lib/lebowski/foundation/views/select_button.rb +69 -0
  23. data/lib/lebowski/foundation/views/view.rb +10 -0
  24. data/lib/lebowski/foundation/views/web.rb +26 -0
  25. data/lib/lebowski/foundation.rb +10 -0
  26. data/lib/lebowski/runtime/errors/remote_control_command_execution_error.rb +5 -0
  27. data/lib/lebowski/runtime/errors/remote_control_command_timeout_error.rb +5 -0
  28. data/lib/lebowski/runtime/errors/remote_control_error.rb +5 -0
  29. data/lib/lebowski/runtime/errors/selenium_server_error.rb +5 -0
  30. data/lib/lebowski/runtime/object_encoder.rb +5 -0
  31. data/lib/lebowski/runtime/sprout_core_driver.rb +5 -0
  32. data/lib/lebowski/runtime/sprout_core_extensions.rb +114 -0
  33. data/lib/lebowski/runtime.rb +5 -0
  34. data/lib/lebowski/scui/mixins/link_support.rb +32 -0
  35. data/lib/lebowski/scui/mixins/node_item_view_support.rb +50 -13
  36. data/lib/lebowski/scui/mixins/terminal_view_support.rb +30 -0
  37. data/lib/lebowski/scui/views/color_well.rb +48 -0
  38. data/lib/lebowski/scui/views/combo_box.rb +90 -87
  39. data/lib/lebowski/scui/views/content_editable.rb +422 -0
  40. data/lib/lebowski/scui/views/date_picker.rb +70 -58
  41. data/lib/lebowski/scui/views/linkit.rb +8 -0
  42. data/lib/lebowski/scui/views/select_field_tab.rb +30 -0
  43. data/lib/lebowski/scui.rb +18 -0
  44. data/lib/lebowski/version.rb +2 -2
  45. data/resources/user-extensions.js +293 -11
  46. 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 child views this view has
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
@@ -72,6 +72,8 @@ module Lebowski
72
72
  ProxyFactory.proxy CollectionView
73
73
  ProxyFactory.proxy ListView
74
74
  ProxyFactory.proxy ListItemView
75
+ ProxyFactory.proxy WebView
76
+ ProxyFactory.proxy SelectButtonView
75
77
 
76
78
  ProxyFactory.proxy Pane
77
79
  ProxyFactory.proxy MainPane
@@ -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
- @defined_paths = {}
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
- result = unravel_relative_path(rel_path)
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
- rel_path = result
418
- type = sc_type_of(rel_path)
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
- when SC_T_OBJECT
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
- when SC_T_CLASS
449
- return handle_type_class(rel_path, expected_type)
392
+ path_defined = path_defined? rel_path
450
393
 
451
- else
452
- raise StandardError.new "Unrecognized returned type '#{type}' for path #{abs_path_with(rel_path)}"
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
@@ -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')