mohawk 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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