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,18 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/scui/views/date_picker')
2
+ require File.expand_path(File.dirname(__FILE__) + '/scui/views/combo_box')
3
+ require File.expand_path(File.dirname(__FILE__) + '/scui/views/linkit')
4
+ require File.expand_path(File.dirname(__FILE__) + '/scui/mixins/node_item_view_support')
5
+ require File.expand_path(File.dirname(__FILE__) + '/scui/mixins/terminal_view_support')
6
+
7
+ module Lebowski
8
+ module SCUI
9
+ module Views
10
+ include Lebowski::Foundation
11
+
12
+ ProxyFactory.proxy DatePickerView
13
+ ProxyFactory.proxy ComboBoxView
14
+ ProxyFactory.proxy CanvasView
15
+
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,136 @@
1
+ module Lebowski
2
+ module SCUI
3
+ module Mixins
4
+
5
+ module NodeItemViewSupport
6
+ include Lebowski::Foundation::Mixins::CollectionItemViewSupport
7
+
8
+ def has_node_item_view_support
9
+ return true
10
+ end
11
+
12
+ def terminal_by_name(name)
13
+ terminal = terminals.find_first({ :terminal => name })
14
+ raise ArgumentError.new "There is no terminal with the name #{name}." if terminal.nil?
15
+ return terminal
16
+ end
17
+
18
+ def terminals
19
+ @terminals = Support::TerminalViewArray.new(self) if @terminals.nil?
20
+ return @terminals
21
+ end
22
+
23
+ def drag_to_coordinates(x, y)
24
+ coord_x = -1*(self.position.x) + self.frame.width + x
25
+ coord_y = -1*(self.position.y) + self.frame.height + y
26
+
27
+ self.drag(coord_x, coord_y)
28
+ end
29
+
30
+ def drag_to_node(item)
31
+ fixed_node = get_fixed_node(item)
32
+ self.drag_on_to(fixed_node)
33
+ end
34
+
35
+ def drag_before_node(item)
36
+ drag_relative_to_node(item, true, -1)
37
+ end
38
+
39
+ def drag_after_node(item)
40
+ drag_relative_to_node(item, true)
41
+ end
42
+
43
+ def drag_above_node(item)
44
+ drag_relative_to_node(item, false, -1)
45
+ end
46
+
47
+ def drag_below_node(item)
48
+ drag_relative_to_node(item, false)
49
+ end
50
+
51
+ private
52
+ def get_fixed_node(item)
53
+ if item.kind_of? Integer
54
+ fixed_node = @parent.item_views[item]
55
+ raise ArgumentError.new "There is no node at index #{item}" if fixed_node.nil?
56
+ return fixed_node
57
+ else
58
+ assert_item_has_node_item_view_support(item)
59
+ return item
60
+ end
61
+ end
62
+
63
+ def drag_relative_to_node(item, horizontal_drag, multiplier = 1)
64
+ fixed_node = get_fixed_node(item)
65
+
66
+ x = horizontal_drag ? (fixed_node.frame.width + 50) * multiplier : 0
67
+ y = horizontal_drag ? 0 : (fixed_node.frame.height + 50) * multiplier
68
+
69
+ self.drag_to(fixed_node, x, y)
70
+ end
71
+
72
+ def assert_item_has_node_item_view_support(item)
73
+ if not item.respond_to? :has_node_item_view_support
74
+ raise ArgumentError.new "The item passed in must have node item view support (#{NodeItemViewSupport})"
75
+ end
76
+ end
77
+
78
+ module Support
79
+
80
+ class TerminalViewArray < Lebowski::Foundation::ObjectArray
81
+ def initialize(parent, *params)
82
+ if params.empty?
83
+ super(parent, 'childViews', 'length', { :prefilter => { :isTerminal => true } })
84
+ else
85
+ super(parent, 'childViews', 'length', *params)
86
+ end
87
+ end
88
+
89
+ def create_object(index, expected_type=nil)
90
+ rel_path = "#{@array_rel_path}.#{index}"
91
+ obj = @parent[rel_path, expected_type]
92
+
93
+ mix_in_support_for_object obj
94
+ return obj
95
+ end
96
+
97
+ def mix_in_support_for_object(obj)
98
+ if not obj.class.ancestors.member? Lebowski::SCUI::Mixins::TerminalViewSupport
99
+ obj.extend Lebowski::SCUI::Mixins::TerminalViewSupport
100
+ end
101
+ end
102
+
103
+ def create_filtered_object_array(parent, array_rel_path, array_length_property_name, prefilter)
104
+ klass = self.class
105
+ return klass.new parent, prefilter
106
+ end
107
+ end
108
+
109
+ class LinksArray < Lebowski::Foundation::ObjectArray
110
+ def initialize(parent)
111
+ links_key = parent['content.linksKey']
112
+ super(parent, "content.#{links_key}")
113
+ end
114
+
115
+ def create_object(index, expected_type=nil)
116
+ rel_path = "#{@array_rel_path}.#{index}"
117
+ obj = @parent[rel_path, expected_type]
118
+
119
+ mix_in_support_for_object obj
120
+ return obj
121
+ end
122
+
123
+ def mix_in_support_for_object(obj)
124
+ if not obj.class.ancestors.member? Lebowski::SCUI::Mixins::LinkSupport
125
+ obj.extend Lebowski::SCUI::Mixins::LinkSupport
126
+ end
127
+ end
128
+ end
129
+
130
+ end
131
+
132
+ end
133
+
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,25 @@
1
+ module Lebowski
2
+ module SCUI
3
+ module Mixins
4
+
5
+ module TerminalViewSupport
6
+ def has_terminal_view_support
7
+ return true
8
+ end
9
+
10
+ def link_to(end_term, x = 0, y = 0)
11
+ assert_item_has_terminal_view_support(end_term)
12
+ self.drag_to(end_term, x, y)
13
+ end
14
+
15
+ private
16
+ def assert_item_has_terminal_view_support(item)
17
+ if not item.respond_to? :has_terminal_view_support
18
+ raise ArgumentError.new "Cannot link to an item without terminal view support (#{TerminalViewSupport})"
19
+ end
20
+ end
21
+ end
22
+
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,119 @@
1
+ module Lebowski
2
+ module SCUI
3
+ module Views
4
+
5
+ class ComboBoxList
6
+ attr_reader :item_views
7
+
8
+ def initialize(parent)
9
+ @parent = parent
10
+ @list_pane = parent['_listPane']
11
+
12
+ list_view_path = 'contentView.listView.contentView'
13
+ if not @list_pane.sc_path_defined?(list_view_path)
14
+ # revert to the old path to access the list view
15
+ list_view_path = 'contentView.contentView'
16
+ end
17
+
18
+ @value_key = @list_pane["#{list_view_path}.contentValueKey"]
19
+ @item_views = @list_pane[list_view_path].item_views
20
+ end
21
+
22
+ def count?(expected_count, item)
23
+ type(item)
24
+ return (@item_views.count == expected_count)
25
+ end
26
+
27
+ def any?(item)
28
+ type(item)
29
+ return @item_views.any?({@value_key => item})
30
+ end
31
+
32
+ alias_method :some?, :any?
33
+
34
+ def one?(item)
35
+ type(item)
36
+ return @item_views.one?({@value_key => item})
37
+ end
38
+
39
+ def none?(item)
40
+ type(item)
41
+ @item_views.none?({@value_key => item})
42
+ end
43
+
44
+ def list_displayed?
45
+ return @list_pane.isPaneAttached
46
+ end
47
+
48
+ def select_item(item)
49
+ @parent.display_list
50
+ if item.kind_of? Integer
51
+ select_item_by_index(item)
52
+ elsif item.kind_of? String
53
+ select_item_by_name(/^#{item}/i)
54
+ elsif item.kind_of? Regexp
55
+ select_item_by_name(item)
56
+ end
57
+ @parent.hide_list
58
+ end
59
+
60
+ private
61
+ def select_item_by_index(index)
62
+ raise ArgumentError.new "Index out of range. The item number must be greater than or equal to zero." if (index < 0)
63
+ raise ArgumentError.new "Index out of range. There are fewer than #{index.to_s} items in the list." if (index >= @item_views.count)
64
+ @item_views[index].select
65
+ end
66
+
67
+ def select_item_by_name(name)
68
+ if one?(name)
69
+ @item_views.find_first({@value_key => name}).select
70
+ end
71
+ end
72
+
73
+ def type(text)
74
+ field = @parent.child_views[0]
75
+ if text.kind_of? Regexp
76
+ field.type_keys(text.inspect.tr('/^', '').tr('/i', ''))
77
+ else
78
+ field.type_keys(text)
79
+ end
80
+ end
81
+ end
82
+
83
+ class ComboBoxView < Lebowski::Foundation::Views::View
84
+ representing_sc_class 'SCUI.ComboBoxView'
85
+
86
+ def empty?
87
+ val = self['value']
88
+ return (val.nil? or val.empty?)
89
+ end
90
+
91
+ def display_list
92
+ click_button if !list.list_displayed?
93
+ end
94
+
95
+ def hide_list
96
+ click_button if list.list_displayed?
97
+ end
98
+
99
+ def list_displayed?
100
+ return list.list_displayed?
101
+ end
102
+
103
+ def select_item(item)
104
+ list.select_item(item)
105
+ end
106
+
107
+ def list
108
+ return ComboBoxList.new(self)
109
+ end
110
+
111
+ private
112
+ def click_button
113
+ self['dropDownButtonView'].click
114
+ end
115
+ end
116
+
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,148 @@
1
+ require 'date'
2
+
3
+ module Lebowski
4
+ module SCUI
5
+ module Views
6
+
7
+ class DatePickerCalendar
8
+ def initialize(parent)
9
+ @today_button = parent['_calendar_popup.contentView.todayButton']
10
+ @none_button = parent['_calendar_popup.contentView.noneButton']
11
+ @calendar = parent['_calendar_popup.contentView.calendar']
12
+ @parent = parent
13
+ end
14
+
15
+ def date_selected?(date)
16
+ curr_year = @calendar['selectedDate.year']
17
+ curr_month = @calendar['selectedDate.month']
18
+ curr_day = @calendar['selectedDate.day']
19
+
20
+ if date.nil?
21
+ return false if !(curr_month.nil? && curr_day.nil? && curr_year.nil?)
22
+ else
23
+ return false if !((curr_month == date.month) && (curr_day == date.day) && (curr_year == date.year))
24
+ end
25
+ return true
26
+ end
27
+
28
+ def showing_month?(month)
29
+ month_displayed = @calendar['monthStartOn.month'] - 1
30
+ return @calendar['monthStrings'][month_displayed] == month
31
+ end
32
+
33
+ def showing_year?(year)
34
+ year_displayed = @calendar['monthStartOn.year']
35
+ return year_displayed == year
36
+ end
37
+
38
+ def select_date(date)
39
+ raise ArgumentError.new "A DateTime object must be provided to the pick_date method." if !(date.class == DateTime || date.class == Time)
40
+
41
+ if @calendar['selectedDate'].nil?
42
+ year_displayed = @calendar['monthStartOn.year']
43
+ month_displayed = @calendar['monthStartOn.month']
44
+ else
45
+ year_displayed = @calendar['selectedDate.year']
46
+ month_displayed = @calendar['selectedDate.month']
47
+ end
48
+
49
+ year_diff = date.year - year_displayed
50
+ month_diff = date.month - month_displayed
51
+
52
+ date_diff = year_diff * 12 + month_diff
53
+
54
+ if date_diff > 0 #date in the future
55
+ date_diff.abs.times { select_next_month }
56
+ elsif date_diff < 0 #date in the past
57
+ date_diff.abs.times { select_previous_month }
58
+ else
59
+ @parent.display_calendar
60
+ end
61
+
62
+ date_int = date.day + @calendar['monthStartOn.dayOfWeek'] + 1
63
+ @calendar.child_views[date_int].click
64
+ end
65
+
66
+ def select_previous_month
67
+ @parent.display_calendar
68
+ prev_month = @calendar.child_views[0]
69
+ prev_month.click
70
+ end
71
+
72
+ def select_next_month
73
+ @parent.display_calendar
74
+ next_month = @calendar.child_views[1]
75
+ next_month.click
76
+ end
77
+
78
+ def select_none
79
+ @parent.display_calendar
80
+ @none_button.click
81
+ end
82
+
83
+ def select_today
84
+ @parent.display_calendar
85
+ @today_button.click
86
+ end
87
+ end
88
+
89
+ class DatePickerView < Lebowski::Foundation::Views::View
90
+ representing_sc_class 'SCUI.DatePickerView'
91
+
92
+ def date_selected?(date)
93
+ return calendar.date_selected?(date)
94
+ end
95
+
96
+ def showing_month?(month)
97
+ return calendar.showing_month?(month)
98
+ end
99
+
100
+ def showing_year?(year)
101
+ return calendar.showing_year?(year)
102
+ end
103
+
104
+ def select_date(date)
105
+ calendar.select_date(date)
106
+ end
107
+
108
+ def select_previous_month
109
+ calendar.select_previous_month
110
+ end
111
+
112
+ def select_next_month
113
+ calendar.select_next_month
114
+ end
115
+
116
+ def select_none
117
+ calendar.select_none
118
+ end
119
+
120
+ def select_today
121
+ calendar.select_today
122
+ end
123
+
124
+ def today_selected?
125
+ return date_selected?(Time.now)
126
+ end
127
+
128
+ def display_calendar
129
+ click_button if !self['isShowingCalendar']
130
+ end
131
+
132
+ def hide_calendar
133
+ click_button if self['isShowingCalendar']
134
+ end
135
+
136
+ private
137
+ def calendar
138
+ @calendar = DatePickerCalendar.new(self) if @calendar.nil?
139
+ return @calendar
140
+ end
141
+
142
+ def click_button
143
+ self['_date_button'].click
144
+ end
145
+ end
146
+ end
147
+ end
148
+ end