lebowski 0.1.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.
Files changed (85) hide show
  1. data/History.md +3 -0
  2. data/License.txt +20 -0
  3. data/Manifest.txt +84 -0
  4. data/README.md +146 -0
  5. data/Rakefile +42 -0
  6. data/bin/lebowski +26 -0
  7. data/bin/lebowski-spec +29 -0
  8. data/bin/lebowski-start-server +24 -0
  9. data/lib/lebowski.rb +15 -0
  10. data/lib/lebowski/core.rb +35 -0
  11. data/lib/lebowski/foundation.rb +52 -0
  12. data/lib/lebowski/foundation/application.rb +315 -0
  13. data/lib/lebowski/foundation/core.rb +61 -0
  14. data/lib/lebowski/foundation/core_query.rb +231 -0
  15. data/lib/lebowski/foundation/dom_element.rb +114 -0
  16. data/lib/lebowski/foundation/errors/argument_invalid_type.rb +31 -0
  17. data/lib/lebowski/foundation/errors/unexpected_type.rb +30 -0
  18. data/lib/lebowski/foundation/mixins/collection_item_view_support.rb +87 -0
  19. data/lib/lebowski/foundation/mixins/delegate_support.rb +22 -0
  20. data/lib/lebowski/foundation/mixins/inline_text_field_support.rb +29 -0
  21. data/lib/lebowski/foundation/mixins/key_check.rb +35 -0
  22. data/lib/lebowski/foundation/mixins/list_item_view_support.rb +36 -0
  23. data/lib/lebowski/foundation/mixins/positioned_element.rb +20 -0
  24. data/lib/lebowski/foundation/mixins/stall_support.rb +79 -0
  25. data/lib/lebowski/foundation/mixins/user_actions.rb +302 -0
  26. data/lib/lebowski/foundation/mixins/wait_actions.rb +44 -0
  27. data/lib/lebowski/foundation/object_array.rb +305 -0
  28. data/lib/lebowski/foundation/panes/alert.rb +117 -0
  29. data/lib/lebowski/foundation/panes/main.rb +20 -0
  30. data/lib/lebowski/foundation/panes/menu.rb +100 -0
  31. data/lib/lebowski/foundation/panes/modal.rb +21 -0
  32. data/lib/lebowski/foundation/panes/palette.rb +21 -0
  33. data/lib/lebowski/foundation/panes/pane.rb +24 -0
  34. data/lib/lebowski/foundation/panes/panel.rb +25 -0
  35. data/lib/lebowski/foundation/panes/picker.rb +43 -0
  36. data/lib/lebowski/foundation/panes/sheet.rb +21 -0
  37. data/lib/lebowski/foundation/proxy_factory.rb +87 -0
  38. data/lib/lebowski/foundation/proxy_object.rb +670 -0
  39. data/lib/lebowski/foundation/sc_object.rb +38 -0
  40. data/lib/lebowski/foundation/views/button.rb +20 -0
  41. data/lib/lebowski/foundation/views/checkbox.rb +63 -0
  42. data/lib/lebowski/foundation/views/collection.rb +304 -0
  43. data/lib/lebowski/foundation/views/container.rb +32 -0
  44. data/lib/lebowski/foundation/views/disclosure.rb +59 -0
  45. data/lib/lebowski/foundation/views/grid.rb +21 -0
  46. data/lib/lebowski/foundation/views/label.rb +30 -0
  47. data/lib/lebowski/foundation/views/list.rb +67 -0
  48. data/lib/lebowski/foundation/views/list_item.rb +280 -0
  49. data/lib/lebowski/foundation/views/menu_item.rb +27 -0
  50. data/lib/lebowski/foundation/views/radio.rb +32 -0
  51. data/lib/lebowski/foundation/views/segmented.rb +97 -0
  52. data/lib/lebowski/foundation/views/select_field.rb +139 -0
  53. data/lib/lebowski/foundation/views/support/simple_item_array.rb +249 -0
  54. data/lib/lebowski/foundation/views/text_field.rb +108 -0
  55. data/lib/lebowski/foundation/views/view.rb +108 -0
  56. data/lib/lebowski/runtime.rb +7 -0
  57. data/lib/lebowski/runtime/errors/remote_control_command_execution_error.rb +9 -0
  58. data/lib/lebowski/runtime/errors/remote_control_command_timeout_error.rb +9 -0
  59. data/lib/lebowski/runtime/errors/remote_control_error.rb +9 -0
  60. data/lib/lebowski/runtime/errors/selenium_server_error.rb +9 -0
  61. data/lib/lebowski/runtime/object_encoder.rb +123 -0
  62. data/lib/lebowski/runtime/sprout_core_driver.rb +14 -0
  63. data/lib/lebowski/runtime/sprout_core_extensions.rb +600 -0
  64. data/lib/lebowski/scui.rb +18 -0
  65. data/lib/lebowski/scui/mixins/node_item_view_support.rb +136 -0
  66. data/lib/lebowski/scui/mixins/terminal_view_support.rb +25 -0
  67. data/lib/lebowski/scui/views/combo_box.rb +119 -0
  68. data/lib/lebowski/scui/views/date_picker.rb +148 -0
  69. data/lib/lebowski/scui/views/linkit.rb +36 -0
  70. data/lib/lebowski/spec.rb +17 -0
  71. data/lib/lebowski/spec/core.rb +21 -0
  72. data/lib/lebowski/spec/matchers/be.rb +63 -0
  73. data/lib/lebowski/spec/matchers/has.rb +40 -0
  74. data/lib/lebowski/spec/matchers/match_supporters/has_object_function.rb +67 -0
  75. data/lib/lebowski/spec/matchers/match_supporters/has_predicate_with_no_prefix.rb +50 -0
  76. data/lib/lebowski/spec/matchers/match_supporters/has_predicate_with_prefix_has.rb +50 -0
  77. data/lib/lebowski/spec/matchers/match_supporters/match_supporter.rb +29 -0
  78. data/lib/lebowski/spec/matchers/method_missing.rb +24 -0
  79. data/lib/lebowski/spec/operators/operator.rb +20 -0
  80. data/lib/lebowski/spec/operators/that.rb +116 -0
  81. data/lib/lebowski/spec/util.rb +26 -0
  82. data/lib/lebowski/version.rb +17 -0
  83. data/resources/selenium-server.jar +0 -0
  84. data/resources/user-extensions.js +1421 -0
  85. metadata +198 -0
@@ -0,0 +1,27 @@
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 menu item view (SC.MenuItemview)
12
+ #
13
+ class MenuItemView < Lebowski::Foundation::Views::View
14
+
15
+ representing_sc_class 'SC.MenuItemView'
16
+
17
+ def click()
18
+ mouse_move
19
+ mouse_down
20
+ mouse_up
21
+ end
22
+
23
+ end
24
+
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,32 @@
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 radio view (SC.RadioView)
12
+ #
13
+ class RadioView < Lebowski::Foundation::Views::View
14
+
15
+ representing_sc_class 'SC.RadioView'
16
+
17
+ def in_mixed_state?()
18
+ value = self['value']
19
+ return value.kind_of?(Array)
20
+ end
21
+
22
+ def buttons()
23
+ if @items.nil?
24
+ @items = Support::SimpleItemArray.new self, '.sc-radio-button'
25
+ end
26
+ return @items
27
+ end
28
+
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,97 @@
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 segemented view (SC.SegmentedView)
12
+ #
13
+ class SegmentedView < Lebowski::Foundation::Views::View
14
+
15
+ representing_sc_class 'SC.SegmentedView'
16
+
17
+ def allowed_empty_selection?()
18
+ return self['allowsEmptySelection']
19
+ end
20
+
21
+ def allowed_multiple_selection?()
22
+ return self['allowsMultipleSelection']
23
+ end
24
+
25
+ def buttons()
26
+ @items = create_simple_item_array if @items.nil?
27
+ return @items
28
+ end
29
+
30
+ protected
31
+
32
+ def create_simple_item_array()
33
+ return Support::SegmentItemArray.new self, '.sc-segment'
34
+ end
35
+
36
+ end
37
+
38
+ module Support
39
+
40
+ class SegmentItem < SimpleItem
41
+
42
+ def deselect()
43
+ view = @parent.segmented_view
44
+ allow_empty = view.allowed_empty_selection?
45
+ allow_multiple = view.allowed_multiple_selection?
46
+ if allow_empty and allow_multiple
47
+ click if selected?
48
+ elsif allow_empty
49
+ click if selected?
50
+ elsif allow_multiple
51
+ click if (selected? and @parent.selected_count > 1)
52
+ end
53
+ end
54
+
55
+ end
56
+
57
+ class SegmentItemArray < SimpleItemArray
58
+
59
+ def segmented_view()
60
+ return @parent
61
+ end
62
+
63
+ def deselect(value)
64
+ if value.kind_of? Integer
65
+ deselect_with_index(value)
66
+ elsif value.kind_of? String
67
+ deselect_with_title(value)
68
+ else
69
+ raise ArgumentInvalidTypeError.new "value", value, Integer, String
70
+ end
71
+ end
72
+
73
+ def deselect_with_index(index)
74
+ item = self[index]
75
+ item.deselect
76
+ end
77
+
78
+ def deselect_with_title(value)
79
+ index = find_index_with_title(value)
80
+ return if (index == :no_index)
81
+ item = self[index]
82
+ item.deselect
83
+ end
84
+
85
+ protected
86
+
87
+ def create_simple_item(title, value)
88
+ return SegmentItem.new self, title, value
89
+ end
90
+
91
+ end
92
+
93
+ end
94
+
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,139 @@
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 field view (SC.SelectFieldView)
12
+ #
13
+ class SelectFieldView < Lebowski::Foundation::Views::View
14
+ # include Lebowski::Foundation
15
+
16
+ representing_sc_class 'SC.SelectFieldView'
17
+
18
+ EMPTY_VALUE = '***'
19
+
20
+ def selected?()
21
+ val = self['value']
22
+ return false if val.nil?
23
+ return false if (val.kind_of?(String) and (val.empty? or val == EMPTY_VALUE))
24
+ return true
25
+ end
26
+
27
+ #
28
+ # Use to check if this view has an empty item
29
+ #
30
+ def has_empty_option?()
31
+ empty = self['emptyName']
32
+ return (not (empty.nil? or empty.empty?))
33
+ end
34
+
35
+ def selected_with_name?(value)
36
+ objs = self['objects']
37
+ val = self['value']
38
+ objs.each do |obj|
39
+ name = get_object_name(obj)
40
+ return (val == get_object_value(obj)) if (not (name =~ /^#{value}$/i).nil?)
41
+ end
42
+ return false
43
+ end
44
+
45
+ def selected_with_value?(value)
46
+ objs = self['objects']
47
+ val = self['value']
48
+ objs.each do |obj|
49
+ if value.kind_of? String
50
+ return true if (not (val =~ /^#{get_object_value(obj)}$/i).nil?)
51
+ else
52
+ return true if (value == val)
53
+ end
54
+ end
55
+ return false
56
+ end
57
+
58
+ def selected_with_index?(index)
59
+ # TODO
60
+ end
61
+
62
+ def select(val)
63
+ return if val.nil?
64
+
65
+ if val.kind_of? Integer
66
+ select_with_index(val)
67
+ elsif val == :empty
68
+ select_empty
69
+ else
70
+ select_with_name(val.to_s)
71
+ end
72
+ end
73
+
74
+ #
75
+ # Used to select an item via its index
76
+ #
77
+ # @see #select
78
+ #
79
+ def select_with_index(val)
80
+ option_locator = "index=#{val}"
81
+ @driver.sc_select(:view, option_locator, self.abs_path)
82
+ stall :select
83
+ end
84
+
85
+ #
86
+ # Used to select an item via its label
87
+ #
88
+ # @see #select
89
+ #
90
+ def select_with_name(val)
91
+ option_locator = "label=regexi:^#{val}$"
92
+ @driver.sc_select(:view, option_locator, self.abs_path)
93
+ stall :select
94
+ end
95
+
96
+ #
97
+ # Used to select an item via its value
98
+ #
99
+ # @see #select
100
+ #
101
+ def select_with_value(val)
102
+ option_locator = "value=regexi:^(nu|st|sc)#{val}$"
103
+ @driver.sc_select(:view, option_locator, self.abs_path)
104
+ stall :select
105
+ end
106
+
107
+ #
108
+ # Used to select the empty item, if there is one
109
+ #
110
+ # @see #select
111
+ #
112
+ def select_empty()
113
+ option_locator = "value=#{EMPTY_VALUE}"
114
+ @driver.sc_select(:view, option_locator, self.abs_path)
115
+ stall :select
116
+ end
117
+
118
+ private
119
+
120
+ def get_object_name(obj)
121
+ if obj.kind_of?(ProxyObject)
122
+ @nameKey = self["nameKey"] if @nameKey.nil?
123
+ return obj[@nameKey]
124
+ end
125
+ return obj
126
+ end
127
+
128
+ def get_object_value(obj)
129
+ if obj.kind_of?(ProxyObject)
130
+ @valueKey = self["valueKey"] if @valueKey.nil?
131
+ return obj[@valueKey]
132
+ end
133
+ return obj
134
+ end
135
+
136
+ end
137
+ end
138
+ end
139
+ end
@@ -0,0 +1,249 @@
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
+ module Support
10
+
11
+ class SimpleItem
12
+
13
+ attr_reader :title, :value
14
+
15
+ def initialize(parent, title, value)
16
+ @title = title
17
+ @value = value
18
+ @parent = parent
19
+ end
20
+
21
+ def click()
22
+ @parent.click @title
23
+ end
24
+
25
+ def selected?()
26
+ return @parent.selected?(@title)
27
+ end
28
+
29
+ def select()
30
+ click if not selected?
31
+ end
32
+
33
+ def to_s()
34
+ return "SimpleItem<title: #{title}, value: #{value}>"
35
+ end
36
+
37
+ end
38
+
39
+ class SimpleItemArray
40
+ include Lebowski::Foundation
41
+ include Lebowski::Foundation::Views
42
+
43
+ def initialize(parent, item_selector, value_rel_path=nil, items_rel_path=nil, item_title_key=nil, item_value_key=nil)
44
+ if not parent.kind_of? View
45
+ raise ArgumentInvalidTypeError.new "parent", parent, View
46
+ end
47
+
48
+ if not item_selector.kind_of? String
49
+ raise ArgumentInvalidTypeError.new "item_selector", item_selector, String
50
+ end
51
+
52
+ @parent = parent
53
+ @driver = parent.driver
54
+ @item_selector = item_selector
55
+ @value_rel_path = value_rel_path.nil? ? 'value' : value_rel_path
56
+ @items_rel_path = items_rel_path.nil? ? 'items' : items_rel_path
57
+ @item_title_key = item_title_key.nil? ? parent['itemTitleKey'] : parent[item_title_key]
58
+ @item_value_key = item_value_key.nil? ? parent['itemValueKey'] : parent[item_value_key]
59
+ end
60
+
61
+ def selected?(value)
62
+ return selected_with_index?(value) if (value.kind_of? Integer)
63
+ return selected_with_title?(value) if (value.kind_of? String)
64
+ raise ArgumentInvalidTypeError.new "value", value, Integer, String
65
+ end
66
+
67
+ def selected_count()
68
+ value = @parent[@value_rel_path]
69
+ return 0 if value.nil?
70
+ return value.length if value.kind_of?(Array)
71
+ return 1
72
+ end
73
+
74
+ def any_selected?()
75
+ return (selected_count > 0)
76
+ end
77
+
78
+ alias_method :some_selected?, :any_selected?
79
+
80
+ def all_selected?()
81
+ return (selected_count == count)
82
+ end
83
+
84
+ def one_selected?()
85
+ return (selected_count == 1)
86
+ end
87
+
88
+ def none_selected?()
89
+ return (selected_count == 0)
90
+ end
91
+
92
+ def [](index)
93
+ if index < 0 or index > count
94
+ raise ArgumentError "index must be between 0 and #{count}"
95
+ end
96
+
97
+ items = @parent[@items_rel_path]
98
+ return __create_simple_item(items[index])
99
+ end
100
+
101
+ def each(&block)
102
+ items = @parent[@items_rel_path]
103
+
104
+ items.each_with_index do |item, index|
105
+ item = __create_simple_item(item)
106
+ yield item, index
107
+ end
108
+ end
109
+
110
+ def count(&block)
111
+ return @parent["#{@items_rel_path}.length"] if (not block_given?)
112
+ counter = 0
113
+ each do |item, index|
114
+ result = yield item, index
115
+ counter = counter.next if (result == true)
116
+ end
117
+ return counter
118
+ end
119
+
120
+ def all?(&block)
121
+ raise ArgumentError "require block" if (not block_given?)
122
+ return (count(&block) == count)
123
+ end
124
+
125
+ def any?(&block)
126
+ raise ArgumentError "require block" if (not block_given?)
127
+ return (count(&block) > 0)
128
+ end
129
+
130
+ alias_method :some?, :any?
131
+
132
+ def one?(&block)
133
+ raise ArgumentError "require block" if (not block_given?)
134
+ return (count(&block) == 1)
135
+ end
136
+
137
+ def none?(&block)
138
+ raise ArgumentError "require block" if (not block_given?)
139
+ return (count(&block) == 0)
140
+ end
141
+
142
+ def selected_with_index?(index)
143
+ value = @parent[@value_rel_path]
144
+ items = @parent[@items_rel_path]
145
+
146
+ items.each_with_index do |item, idx|
147
+ item_value = get_item_value(item)
148
+ if index == idx
149
+ return (value == item_value) if (not value.kind_of? Array)
150
+ return (value.member? item_value) if value.kind_of?(Array)
151
+ end
152
+ end
153
+
154
+ return false
155
+ end
156
+
157
+ def selected_with_title?(value)
158
+ index = find_index_with_title value
159
+ return false if (index == :no_index)
160
+ return selected_with_index?(index)
161
+ end
162
+
163
+ def click(value)
164
+ if value.kind_of? Integer
165
+ click_with_index(value)
166
+ elsif value.kind_of? String
167
+ click_with_title(value)
168
+ else
169
+ raise ArgumentInvalidTypeError.new "value", value, Integer, String
170
+ end
171
+ end
172
+
173
+ def click_with_index(value)
174
+ cq = @parent.core_query(@item_selector)
175
+ cq[value].mouse_down
176
+ cq[value].basic_click # Required for slightly older versions of SC (pre 1.0)
177
+ cq.done
178
+
179
+ cq = @parent.core_query(@item_selector)
180
+ cq[value].mouse_up
181
+ cq.done
182
+ end
183
+
184
+ def click_with_title(value)
185
+ index = find_index_with_title value
186
+ return if (index == :no_index)
187
+ click_with_index index
188
+ end
189
+
190
+ def select(value)
191
+ if value.kind_of? Integer
192
+ select_with_index(value)
193
+ elsif value.kind_of? String
194
+ select_with_title(value)
195
+ else
196
+ raise ArgumentInvalidTypeError.new "value", value, Integer, String
197
+ end
198
+ end
199
+
200
+ def select_with_index(index)
201
+ item = self[index]
202
+ item.select
203
+ end
204
+
205
+ def select_with_title(value)
206
+ index = find_index_with_title(value)
207
+ return if (index == :no_index)
208
+ item = self[index]
209
+ item.select
210
+ end
211
+
212
+ def find_index_with_title(value)
213
+ items = @parent[@items_rel_path]
214
+ items.each_with_index do |item, index|
215
+ title = get_item_title(item)
216
+ return index if (title =~ /^#{value}/i)
217
+ end
218
+
219
+ return :no_index
220
+ end
221
+
222
+ protected
223
+
224
+ def create_simple_item(title, value)
225
+ return SimpleItem.new self, title, value
226
+ end
227
+
228
+ def get_item_title(item)
229
+ return item if item.kind_of? String
230
+ return item[@item_title_key]
231
+ end
232
+
233
+ def get_item_value(item)
234
+ return item if item.kind_of? String
235
+ return item[@item_value_key]
236
+ end
237
+
238
+ private
239
+
240
+ def __create_simple_item(item)
241
+ return create_simple_item(get_item_title(item), get_item_value(item))
242
+ end
243
+
244
+ end
245
+
246
+ end
247
+ end
248
+ end
249
+ end