mohawk 0.0.1 → 0.0.2

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 (41) hide show
  1. data/Changelog +17 -0
  2. data/Gemfile +1 -5
  3. data/README.md +29 -0
  4. data/features/label.feature +4 -0
  5. data/features/menu.feature +5 -0
  6. data/features/mohawk.feature +14 -0
  7. data/features/step_definitions/label_steps.rb +3 -0
  8. data/features/step_definitions/menu_steps.rb +5 -0
  9. data/features/step_definitions/mohawk_steps.rb +15 -0
  10. data/features/step_definitions/table_steps.rb +23 -0
  11. data/features/step_definitions/text_steps.rb +4 -0
  12. data/features/step_definitions/tree_view_steps.rb +31 -0
  13. data/features/support/WindowsForms.exe +0 -0
  14. data/features/support/screens/data_entry_form.rb +6 -0
  15. data/features/support/screens/main_screen.rb +4 -0
  16. data/features/support/string.rb +4 -0
  17. data/features/table.feature +19 -0
  18. data/features/text.feature +4 -0
  19. data/features/tree_view.feature +49 -0
  20. data/lib/mohawk.rb +41 -0
  21. data/lib/mohawk/accessors.rb +182 -1
  22. data/lib/mohawk/accessors/label.rb +13 -0
  23. data/lib/mohawk/accessors/menu_item.rb +21 -0
  24. data/lib/mohawk/accessors/table.rb +50 -0
  25. data/lib/mohawk/accessors/text.rb +6 -0
  26. data/lib/mohawk/accessors/tree_view.rb +30 -0
  27. data/lib/mohawk/adapters/uia_adapter.rb +16 -0
  28. data/lib/mohawk/navigation.rb +4 -3
  29. data/lib/mohawk/version.rb +1 -1
  30. data/mohawk.gemspec +4 -2
  31. data/spec/lib/mohawk/accessors/combo_spec.rb +28 -1
  32. data/spec/lib/mohawk/accessors/label_spec.rb +25 -0
  33. data/spec/lib/mohawk/accessors/menu_spec.rb +32 -0
  34. data/spec/lib/mohawk/accessors/table_spec.rb +96 -0
  35. data/spec/lib/mohawk/accessors/text_spec.rb +9 -0
  36. data/spec/lib/mohawk/accessors/tree_view_spec.rb +86 -0
  37. data/spec/lib/mohawk_spec.rb +26 -0
  38. data/spec/lib/navigation_spec.rb +34 -0
  39. metadata +74 -9
  40. data/features/fado.feature +0 -5
  41. data/features/step_definitions/fado_steps.rb +0 -7
data/Changelog CHANGED
@@ -1,3 +1,20 @@
1
+ === Version 0.2 / 2012-12-26
2
+ * Enhancements
3
+ * Added the following Mohawk module methods:
4
+ * active?
5
+ * has_text?
6
+ * present?
7
+ * wait_until
8
+ * wait_until_present
9
+ * Added more accessors for working with the following controls:
10
+ * label
11
+ * menu_item
12
+ * table
13
+ * tree_view
14
+ * Added method to text accessor to simulate typing into a field (helpful for masked edit controls)
15
+ * Enhanced navigation to wait until the Window is present before working with it
16
+ * Added aliases for table, combo_box and tree_view accessors
17
+
1
18
  === Version 0.1 / 2012-11-07
2
19
  Initial release with support for text, button, combo, radio and checkbox
3
20
  controls
data/Gemfile CHANGED
@@ -1,7 +1,3 @@
1
1
  source 'http://rubygems.org'
2
2
 
3
- gem 'cucumber'
4
- gem 'rspec'
5
- gem 'rake'
6
- gem 'rautomation'
7
- gem 'childprocess'
3
+ gemspec
data/README.md CHANGED
@@ -18,6 +18,35 @@ Or install it yourself as:
18
18
 
19
19
  $ gem install mohawk
20
20
 
21
+ ## Example
22
+
23
+ ### Defining a screen
24
+
25
+ ```ruby
26
+ require 'mohawk'
27
+
28
+ class LoginScreen
29
+ include Mohawk
30
+ window(:title => /Login/)
31
+
32
+ text(:username, :id => "UserNameField")
33
+ text(:password, :id => "PasswordField")
34
+
35
+ button(:login, :value => "Login")
36
+ end
37
+ ```
38
+
39
+ ### Using the Page-Object
40
+ ```ruby
41
+ World(Mohawk::Navigation)
42
+
43
+ on(LoginScreen) do |screen|
44
+ screen.username = "levi"
45
+ screen.password = "secret"
46
+ screen.login
47
+ end
48
+ ```
49
+
21
50
  ## Contributing
22
51
 
23
52
  1. Fork it
@@ -0,0 +1,4 @@
1
+ Feature: Working with label controls
2
+
3
+ Scenario: Getting the value of the control
4
+ Then I know that the "label control" has the value "This is a sample text"
@@ -0,0 +1,5 @@
1
+ Feature: Working with menu items
2
+
3
+ Scenario: Selecting an item from the menu
4
+ When I select the menu item in the path "File | Roundabout Way | To | About"
5
+ Then I should see the "About" window
@@ -0,0 +1,14 @@
1
+ Feature: Using Mohawk
2
+
3
+ Scenario: Determining if a window exists
4
+ When we are using the "MainScreen"
5
+ Then the window should exist
6
+
7
+ Scenario: Determining if a window is active
8
+ When we are using the "MainScreen"
9
+ Then we know that the window is active
10
+
11
+ @wip
12
+ Scenario: Determining if a window has text
13
+ When we are using the "MainScreen"
14
+ Then we can confirm the window has the text "Assorted UI Elements"
@@ -0,0 +1,3 @@
1
+ Then /^I know that the "(.*?)" has the value "(.*?)"$/ do |name, value|
2
+ on(MainScreen).send(name.to_field).should eq(value)
3
+ end
@@ -0,0 +1,5 @@
1
+ When /^I select the menu item in the path "(.*?)"$/ do |menu_path|
2
+ menu_item_method = menu_path.gsub(/ (\| )?/, "_").downcase
3
+ on(MainScreen).send menu_item_method
4
+ end
5
+
@@ -0,0 +1,15 @@
1
+ When /^we are using the "(.*?)"$/ do |expected_screen|
2
+ @screen = on(expected_screen.to_class)
3
+ end
4
+
5
+ Then /^the window should exist$/ do
6
+ @screen.should exist
7
+ end
8
+
9
+ Then /^we know that the window is active$/ do
10
+ @screen.should be_active
11
+ end
12
+
13
+ Then /^we can confirm the window has the text "(.*?)"$/ do |what_text|
14
+ @screen.should have_text(what_text)
15
+ end
@@ -0,0 +1,23 @@
1
+ When /^we are observing the people table$/ do
2
+ on(MainScreen).data_entry_form_button
3
+ on(DataEntryForm).should be_active
4
+ end
5
+
6
+ Then /^the table row information should look like the following:$/ do |row_items|
7
+ row_items.map_column!("row") { |r| r.to_i }
8
+ row_items.map_headers!("text" => :text, "row" => :row)
9
+ on(DataEntryForm).people_rows.should eq row_items.hashes
10
+ end
11
+
12
+ When /^we select the table row with index "(.*?)"$/ do |row_index|
13
+ on(DataEntryForm).people = row_index.to_i
14
+ end
15
+
16
+ Then /^the row with index "(.*?)" should be selected$/ do |which_row|
17
+ on(DataEntryForm).people_row(which_row.to_i).should be_selected
18
+ end
19
+
20
+ Then /^the row with index "(.*?)" should look like the following:$/ do |which_row, table|
21
+ actual_cells = on(DataEntryForm).people_row(which_row.to_i).cells
22
+ actual_cells.should eq table.rows.first
23
+ end
@@ -2,6 +2,10 @@ When /^I set the "(.*)" to the value "(.*)"$/ do |name, value|
2
2
  on(MainScreen).send "#{name.to_field}=", value
3
3
  end
4
4
 
5
+ When /^I enter into "(.*?)" the values "(.*?)"$/ do |name, value|
6
+ on(MainScreen).send "enter_#{name.to_field}", value
7
+ end
8
+
5
9
  When /^I clear the "(.*)"$/ do |name|
6
10
  on(MainScreen).send "clear_#{name.to_field}"
7
11
  end
@@ -0,0 +1,31 @@
1
+ When /^I select the item with index "(.*?)" in the TreeView$/ do |which_index|
2
+ on(MainScreen).tree_view = which_index.to_i
3
+ end
4
+
5
+ When /^I select the item "(.*?)" in the TreeView$/ do |expected_value|
6
+ on(MainScreen).tree_view = expected_value
7
+ end
8
+
9
+ Then /^the selected TreeView value should be "(.*?)"$/ do |expected_value|
10
+ on(MainScreen).tree_view.should eq expected_value
11
+ end
12
+
13
+ Then /^the available tree items should be:$/ do |tree_items|
14
+ on(MainScreen).tree_view_items.should eq tree_items.rows.flatten
15
+ end
16
+
17
+ When /^I expand the tree item with index "(.*?)"$/ do |which_index|
18
+ on(MainScreen).expand_tree_view_item which_index.to_i
19
+ end
20
+
21
+ When /^I expand the tree item "(.*?)"$/ do |which_item|
22
+ on(MainScreen).expand_tree_view_item which_item
23
+ end
24
+
25
+ When /^I collapse the tree item with index "(.*?)"$/ do |which_index|
26
+ on(MainScreen).collapse_tree_view_item which_index.to_i
27
+ end
28
+
29
+ When /^I collapse the tree item "(.*?)"$/ do |which_item|
30
+ on(MainScreen).collapse_tree_view_item which_item
31
+ end
Binary file
@@ -0,0 +1,6 @@
1
+ class DataEntryForm
2
+ include Mohawk
3
+ window(:title => /DataEntry/)
4
+
5
+ table(:people, :id => "personListView")
6
+ end
@@ -3,8 +3,12 @@ class MainScreen
3
3
  window(:title => /MainFormWindow/)
4
4
 
5
5
  text(:text_field, :id => "textField")
6
+ text(:masked_text_field, :id => "maskedTextBox")
6
7
  button(:data_entry_form_button, :value => "Data Entry Form")
7
8
  combo_box(:fruits, :id => "FruitsComboBox")
8
9
  checkbox(:first_checkbox, :id => "checkBox")
9
10
  radio(:first_radio, :id => "radioButton1")
11
+ label(:label_control, :id => "label1")
12
+ menu_item(:file_roundabout_way_to_about, :path => ["File", "Roundabout Way", "To", "About"])
13
+ tree_view(:tree_view, :id => "treeView")
10
14
  end
@@ -2,4 +2,8 @@ class String
2
2
  def to_field
3
3
  self.gsub(/ /, "_").downcase
4
4
  end
5
+
6
+ def to_class
7
+ Object.const_get self
8
+ end
5
9
  end
@@ -0,0 +1,19 @@
1
+ Feature: Working with tables
2
+
3
+ Background:
4
+ Given we are observing the people table
5
+
6
+ Scenario: Selecting a row by index
7
+ When we select the table row with index "1"
8
+ Then the row with index "1" should be selected
9
+
10
+ Scenario: Rows have cells
11
+ Then the row with index "0" should look like the following:
12
+ | Name | Date of Birth | State |
13
+ | John Doe | 12/15/1967 | FL |
14
+
15
+ Scenario: Retrieving the row values
16
+ Then the table row information should look like the following:
17
+ | text | row |
18
+ | John Doe | 0 |
19
+ | Anna Doe | 1 |
@@ -8,3 +8,7 @@ Scenario: Clearing text
8
8
  When I set the "text field" to the value "Text to be cleared"
9
9
  And I clear the "text field"
10
10
  Then the "text field" should be ""
11
+
12
+ Scenario: Entering text
13
+ When I enter into "masked text field" the values "abc12345willnotgoin6789"
14
+ Then the "masked text field" should be "123-45-6789"
@@ -0,0 +1,49 @@
1
+ Feature: Working with TreeView controls
2
+
3
+ Scenario: Selecting an item by index
4
+ When I select the item with index "1" in the TreeView
5
+ Then the selected TreeView value should be "Parent Two"
6
+
7
+ Scenario: Selecting an item by value
8
+ When I select the item "Parent Two" in the TreeView
9
+ Then the selected TreeView value should be "Parent Two"
10
+
11
+ Scenario: Can reveal the available items
12
+ Then the available tree items should be:
13
+ | Tree Items |
14
+ | Parent One |
15
+ | Parent Two |
16
+
17
+ Scenario: Expanding items by index
18
+ When I expand the tree item with index "0"
19
+ Then the available tree items should be:
20
+ | Tree Items |
21
+ | Parent One |
22
+ | Child 1 |
23
+ | Child 2 |
24
+ | Parent Two |
25
+
26
+ Scenario: Expanding items by value
27
+ When I expand the tree item "Parent One"
28
+ Then the available tree items should be:
29
+ | Tree Items |
30
+ | Parent One |
31
+ | Child 1 |
32
+ | Child 2 |
33
+ | Parent Two |
34
+
35
+ Scenario: Collapsing items by index
36
+ When I expand the tree item "Parent One"
37
+ And I collapse the tree item with index "0"
38
+ Then the available tree items should be:
39
+ | Tree Items |
40
+ | Parent One |
41
+ | Parent Two |
42
+
43
+ Scenario: Collapsing items by value
44
+ When I expand the tree item "Parent One"
45
+ And I collapse the tree item "Parent One"
46
+ Then the available tree items should be:
47
+ | Tree Items |
48
+ | Parent One |
49
+ | Parent Two |
data/lib/mohawk.rb CHANGED
@@ -4,8 +4,12 @@ require "mohawk/accessors"
4
4
  require "mohawk/accessors/button"
5
5
  require "mohawk/accessors/checkbox"
6
6
  require "mohawk/accessors/combo"
7
+ require "mohawk/accessors/label"
8
+ require "mohawk/accessors/menu_item"
7
9
  require "mohawk/accessors/radio"
10
+ require "mohawk/accessors/table"
8
11
  require "mohawk/accessors/text"
12
+ require "mohawk/accessors/tree_view"
9
13
  require "mohawk/navigation"
10
14
  require "mohawk/adapters/uia_adapter"
11
15
 
@@ -21,8 +25,45 @@ module Mohawk
21
25
  @adapter = Mohawk::Adapters::UiaAdapter.new(which_window)
22
26
  end
23
27
 
28
+ #
29
+ # Returns whether or not the window exists
30
+ #
24
31
  def exist?
25
32
  adapter.window.exist?
26
33
  end
27
34
 
35
+ #
36
+ # Returns whether or not the window is active
37
+ #
38
+ def active?
39
+ adapter.window.active?
40
+ end
41
+
42
+ #
43
+ # Returns whether or not the window is present
44
+ #
45
+ def present?
46
+ adapter.window.present?
47
+ end
48
+
49
+ #
50
+ # Waits until the window is present
51
+ #
52
+ def wait_until_present
53
+ adapter.window.wait_until_present
54
+ end
55
+
56
+ #
57
+ # Waits until the block returns true
58
+ #
59
+ def wait_until(timeout=RAutomation::Window.wait_timeout, &block)
60
+ RAutomation::WaitHelper.wait_until timeout, &block
61
+ end
62
+
63
+ #
64
+ # Indicates if the window has text or not
65
+ #
66
+ def has_text?(text_to_find)
67
+ adapter.window.text.include? text_to_find
68
+ end
28
69
  end
@@ -1,11 +1,32 @@
1
1
  module Mohawk
2
2
  module Accessors
3
+
4
+ #
5
+ # Defines the locator indicating the top-level window that will be used
6
+ # to find controls in the page
7
+ #
8
+ # @example
9
+ # window(:title => /Title of Some Window/)
10
+ #
11
+ # @param [Hash] locator for the top-level window that hosts the page
12
+ #
3
13
  def window(locator)
4
14
  define_method("which_window") do
5
15
  locator
6
16
  end
7
17
  end
8
18
 
19
+ #
20
+ # Generates methods to enter text into a text field, get its value
21
+ # and clear the text field
22
+ #
23
+ # @example
24
+ # text(:first_name, :id => 'textFieldId')
25
+ # # will generate 'first_name', 'first_name=' and 'clear_first_name' methods
26
+ #
27
+ # @param [String] the name used for the generated methods
28
+ # @param [Hash] locator for how the text is found
29
+ #
9
30
  def text(name, locator)
10
31
  define_method("#{name}") do
11
32
  adapter.text(locator).value
@@ -16,8 +37,22 @@ module Mohawk
16
37
  define_method("clear_#{name}") do
17
38
  adapter.text(locator).clear
18
39
  end
40
+ define_method("enter_#{name}") do |text|
41
+ adapter.text(locator).enter text
42
+ end
19
43
  end
20
-
44
+
45
+ #
46
+ # Generates methods to click on a button as well as get the value of
47
+ # the button text
48
+ #
49
+ # @example
50
+ # button(:close, :value => '&Close')
51
+ # # will generate 'close' and 'close_value' methods
52
+ #
53
+ # @param [String] the name used for the generated methods
54
+ # @param [Hash] locator for how the button is found
55
+ #
21
56
  def button(name, locator)
22
57
  define_method("#{name}") do |&block|
23
58
  adapter.button(locator).click &block
@@ -27,6 +62,22 @@ module Mohawk
27
62
  end
28
63
  end
29
64
 
65
+ #
66
+ # Generates methods to get the value of a combo box, set the selected
67
+ # item by both index and value as well as to see the available options
68
+ #
69
+ # @example
70
+ # combo_box(:status, :id => 'statusComboBox')
71
+ # # will generate 'status', 'status=' and 'status_options' methods
72
+ #
73
+ # @param [String] the name used for the generated methods
74
+ # @param [Hash] locator for how the combo box is found
75
+ #
76
+ # === Aliases
77
+ # * combobox
78
+ # * dropdown / drop_down
79
+ # * select_list
80
+ #
30
81
  def combo_box(name, locator)
31
82
  define_method("#{name}") do
32
83
  adapter.combo(locator).value
@@ -39,6 +90,17 @@ module Mohawk
39
90
  end
40
91
  end
41
92
 
93
+ #
94
+ # Generates methods to get/set the value of a checkbox as well as
95
+ # to get the text value of the control
96
+ #
97
+ # @example
98
+ # checkbox(:include, :id => 'checkBoxId')
99
+ # # will generate 'include', 'include=' and 'include_value' methods
100
+ #
101
+ # @param [String] the name used for the generated methods
102
+ # @param [Hash] locator for how the checkbox is found
103
+ #
42
104
  def checkbox(name, locator)
43
105
  define_method("#{name}") do
44
106
  adapter.checkbox(locator).checked?
@@ -51,6 +113,17 @@ module Mohawk
51
113
  end
52
114
  end
53
115
 
116
+ #
117
+ # Generates methods to set a radio button as well as see if one
118
+ # is selected
119
+ #
120
+ # @example
121
+ # radio(:morning, :id => 'morningRadio')
122
+ # # will generate 'morning' and 'morning?' methods
123
+ #
124
+ # @param [String] the name used for the generated methods
125
+ # @param [Hash] locator for how the radio is found
126
+ #
54
127
  def radio(name, locator)
55
128
  define_method("#{name}") do
56
129
  adapter.radio(locator).set
@@ -59,5 +132,113 @@ module Mohawk
59
132
  adapter.radio(locator).set?
60
133
  end
61
134
  end
135
+
136
+ #
137
+ # Generates methods to get the value of a label control
138
+ #
139
+ # @example
140
+ # label(:login_info, :id => 'loginInfoLabel')
141
+ # # will generate a 'login_info' method
142
+ #
143
+ # @param [String] the name used for the generated methods
144
+ # @param [Hash] locator for how the label is found
145
+ #
146
+ def label(name, locator)
147
+ define_method("#{name}") do
148
+ adapter.label(locator).value
149
+ end
150
+ end
151
+
152
+ # Generates methods to work with menu items
153
+ #
154
+ # @example
155
+ # menu_item(:some_menu_item, :path => ["Path", "To", "A", "Menu Item"])
156
+ # # will generate a 'some_menu_item' method to select a menu item
157
+ #
158
+ # @param [String] the name used for the generated methods
159
+ # @param [Hash] locator for how the label is found
160
+ #
161
+ def menu_item(name, locator)
162
+ define_method("#{name}") do
163
+ adapter.menu_item(locator).select
164
+ end
165
+ end
166
+
167
+ # Generates methods for working with table or list view controls
168
+ #
169
+ # @example
170
+ # table(:some_table, :id => "tableId")
171
+ # # will generate 'some_table=', 'some_table_rows' and 'some_table_row(item)' methods to
172
+ # # select a table item, return all of the rows as well as return an individual row
173
+ #
174
+ # @param [String] the name used for the generated methods
175
+ # @param [Hash] locator for how the label is found
176
+ #
177
+ # === Aliases
178
+ # * listview
179
+ # * list_view
180
+ #
181
+ def table(name, locator)
182
+ define_method("#{name}=") do |which_item|
183
+ adapter.table(locator).select which_item
184
+ end
185
+ define_method("#{name}_rows") do
186
+ adapter.table(locator).rows
187
+ end
188
+ define_method("#{name}_row") do |which_row|
189
+ adapter.table(locator).row which_row
190
+ end
191
+ define_method("#{name}_view") do
192
+ adapter.table(locator).view
193
+ end
194
+ end
195
+
196
+ # Generates methods for working with tree view controls
197
+ #
198
+ # @example
199
+ # tree_view(:tree, :id => "treeId")
200
+ # # will generate 'tree', 'tree=', 'tree_items', 'expand_tree_item' and 'collapse_tree_item'
201
+ # # methods to get the tree value, set the tree value (index or string), get all of the
202
+ # # items, expand an item (index or string) and collapse an item (index or string)
203
+ #
204
+ # @param [String] the name used for the generated methods
205
+ # @param [Hash] locator for how the label is found
206
+ #
207
+ # === Aliases
208
+ # * treeview
209
+ # * tree
210
+ #
211
+ def tree_view(name, locator)
212
+ define_method("#{name}") do
213
+ adapter.tree_view(locator).value
214
+ end
215
+ define_method("#{name}=") do |which_item|
216
+ adapter.tree_view(locator).select which_item
217
+ end
218
+ define_method("#{name}_items") do
219
+ adapter.tree_view(locator).items
220
+ end
221
+ define_method("expand_#{name}_item") do |which_item|
222
+ adapter.tree_view(locator).expand which_item
223
+ end
224
+ define_method("collapse_#{name}_item") do |which_item|
225
+ adapter.tree_view(locator).collapse which_item
226
+ end
227
+ end
228
+
229
+ # combo_box aliases
230
+ alias_method :combobox, :combo_box
231
+ alias_method :dropdown, :combo_box
232
+ alias_method :drop_down, :combo_box
233
+ alias_method :select_list, :combo_box
234
+
235
+ # table aliases
236
+ alias_method :listview, :table
237
+ alias_method :list_view, :table
238
+
239
+ # tree_view aliases
240
+ alias_method :treeview, :tree_view
241
+ alias_method :tree, :tree_view
242
+
62
243
  end
63
244
  end