mohawk 0.1.4 → 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.
- data/.gitmodules +3 -3
- data/Changelog +6 -1
- data/Rakefile +2 -3
- data/cucumber.yml +1 -1
- data/features/combo_box.feature +8 -0
- data/features/menu.feature +8 -0
- data/features/step_definitions/button_steps.rb +1 -1
- data/features/step_definitions/combo_box_steps.rb +13 -1
- data/features/step_definitions/control_steps.rb +1 -1
- data/features/step_definitions/menu_steps.rb +7 -2
- data/features/support/WindowsForms.exe +0 -0
- data/features/support/screens/main_screen.rb +3 -0
- data/features/table.feature +7 -7
- data/features/text.feature +4 -0
- data/lib/mohawk/accessors.rb +3 -0
- data/lib/mohawk/adapters/uia/button.rb +14 -0
- data/lib/mohawk/adapters/uia/checkbox.rb +22 -0
- data/lib/mohawk/adapters/uia/control.rb +83 -0
- data/lib/mohawk/adapters/uia/element_locator.rb +19 -0
- data/lib/mohawk/adapters/uia/menu_item.rb +48 -0
- data/lib/mohawk/adapters/uia/radio.rb +22 -0
- data/lib/mohawk/adapters/uia/select_list.rb +53 -0
- data/lib/mohawk/adapters/uia/spinner.rb +30 -0
- data/lib/mohawk/adapters/uia/tab_control.rb +26 -0
- data/lib/mohawk/adapters/uia/table.rb +62 -0
- data/lib/mohawk/adapters/uia/table_row.rb +73 -0
- data/lib/mohawk/adapters/uia/text_box.rb +47 -0
- data/lib/mohawk/adapters/uia/tree_view.rb +22 -0
- data/lib/mohawk/adapters/uia/value_control.rb +20 -0
- data/lib/mohawk/adapters/uia/window.rb +64 -0
- data/lib/mohawk/adapters/uia_adapter.rb +36 -50
- data/lib/mohawk/version.rb +1 -1
- data/lib/mohawk/waiter.rb +18 -0
- data/lib/mohawk/win_32.rb +12 -0
- data/lib/mohawk.rb +26 -14
- data/mohawk.gemspec +2 -2
- data/spec/lib/mohawk/adapters/uia/control_spec.rb +46 -0
- data/spec/lib/mohawk/adapters/uia/table_row_spec.rb +36 -0
- data/spec/lib/mohawk/waiter_spec.rb +39 -0
- data/spec/lib/mohawk_spec.rb +115 -92
- data/spec/lib/navigation_spec.rb +14 -20
- data/spec/spec_helper.rb +1 -1
- metadata +49 -67
- data/lib/mohawk/accessors/button.rb +0 -20
- data/lib/mohawk/accessors/checkbox.rb +0 -24
- data/lib/mohawk/accessors/combo.rb +0 -37
- data/lib/mohawk/accessors/control.rb +0 -24
- data/lib/mohawk/accessors/label.rb +0 -15
- data/lib/mohawk/accessors/link.rb +0 -9
- data/lib/mohawk/accessors/menu_item.rb +0 -21
- data/lib/mohawk/accessors/radio.rb +0 -19
- data/lib/mohawk/accessors/spinner.rb +0 -27
- data/lib/mohawk/accessors/table.rb +0 -69
- data/lib/mohawk/accessors/table_row.rb +0 -62
- data/lib/mohawk/accessors/tabs.rb +0 -30
- data/lib/mohawk/accessors/text.rb +0 -29
- data/lib/mohawk/accessors/tree_view.rb +0 -32
- data/spec/lib/mohawk/accessors/button_spec.rb +0 -45
- data/spec/lib/mohawk/accessors/checkbox_spec.rb +0 -46
- data/spec/lib/mohawk/accessors/combo_spec.rb +0 -119
- data/spec/lib/mohawk/accessors/control_spec.rb +0 -47
- data/spec/lib/mohawk/accessors/label_spec.rb +0 -29
- data/spec/lib/mohawk/accessors/link_spec.rb +0 -34
- data/spec/lib/mohawk/accessors/menu_spec.rb +0 -32
- data/spec/lib/mohawk/accessors/radio_spec.rb +0 -35
- data/spec/lib/mohawk/accessors/spinner_spec.rb +0 -43
- data/spec/lib/mohawk/accessors/table_row_spec.rb +0 -28
- data/spec/lib/mohawk/accessors/table_spec.rb +0 -262
- data/spec/lib/mohawk/accessors/tabs_spec.rb +0 -58
- data/spec/lib/mohawk/accessors/text_spec.rb +0 -51
- data/spec/lib/mohawk/accessors/tree_view_spec.rb +0 -98
- data/spec/lib/mohawk/adapters/uia_adapter_spec.rb +0 -55
- data/spec/table_stubber.rb +0 -55
data/.gitmodules
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
[submodule "mohawk-testing-app"]
|
2
|
-
path = mohawk-testing-app
|
3
|
-
url = git://github.com/leviwilson/mohawk-testing-app.git
|
1
|
+
[submodule "mohawk-testing-app"]
|
2
|
+
path = mohawk-testing-app
|
3
|
+
url = git://github.com/leviwilson/mohawk-testing-app.git
|
data/Changelog
CHANGED
@@ -1,6 +1,11 @@
|
|
1
|
-
=== Version 0.
|
1
|
+
=== Version 0.2 / 2014-05-09
|
2
|
+
* Enhancements
|
3
|
+
* Swapped out the underlying driver to use the uia gem
|
4
|
+
|
5
|
+
=== Version 0.1.4 / 2014-02-05
|
2
6
|
* Enhancements
|
3
7
|
* make it more explicit if you want to add a row to the selection
|
8
|
+
* added another adapter that uses the uia gem
|
4
9
|
|
5
10
|
=== Version 0.1.0 / 2013-10-03
|
6
11
|
* Enhancments
|
data/Rakefile
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'bundler/setup'
|
1
2
|
require 'bundler/gem_tasks'
|
2
3
|
require 'rspec/core/rake_task'
|
3
4
|
require 'rubygems'
|
@@ -11,8 +12,6 @@ RSpec::Core::RakeTask.new(:spec) do |spec|
|
|
11
12
|
end
|
12
13
|
task :spec
|
13
14
|
|
14
|
-
Cucumber::Rake::Task.new(:features)
|
15
|
-
t.profile = 'default'
|
16
|
-
end
|
15
|
+
Cucumber::Rake::Task.new(:features)
|
17
16
|
|
18
17
|
task :default => :spec
|
data/cucumber.yml
CHANGED
@@ -1 +1 @@
|
|
1
|
-
default: --no-source --color --format pretty
|
1
|
+
default: --no-source --color --format pretty
|
data/features/combo_box.feature
CHANGED
@@ -8,6 +8,10 @@ Feature: Working with combo boxes
|
|
8
8
|
When I select the value "Orange" from the "fruits" combo box
|
9
9
|
Then the "Orange" option should be selected in the "fruits" combo box
|
10
10
|
|
11
|
+
Scenario: Selecting items by regex
|
12
|
+
When I select the regex value "[Or]an" from the "fruits" combo box
|
13
|
+
Then the "Orange" option should be selected in the "fruits" combo box
|
14
|
+
|
11
15
|
Scenario: Selecting multiple items
|
12
16
|
Given we toggle the multi-select button
|
13
17
|
When I select indexes "0, 1, 2" from the "fruits_list" combo box
|
@@ -34,3 +38,7 @@ Feature: Working with combo boxes
|
|
34
38
|
| Coconut |
|
35
39
|
| Orange |
|
36
40
|
| Passion Fruit |
|
41
|
+
|
42
|
+
Scenario: Interacting with ListBox controls
|
43
|
+
When I select the value "Orange" from the "fruits_list" combo box
|
44
|
+
Then the application should know that "Orange" was selected
|
data/features/menu.feature
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
Feature: Working with menu items
|
2
2
|
|
3
|
+
Scenario: Selecting a menu item by text
|
4
|
+
When I select the menu item by text
|
5
|
+
Then I should see the "About" window
|
6
|
+
|
3
7
|
Scenario: Selecting an item from the menu
|
4
8
|
When I select the menu item in the path "File | Roundabout Way | To | About"
|
5
9
|
Then I should see the "About" window
|
10
|
+
|
11
|
+
Scenario: Clicking an item from the menu
|
12
|
+
When I click the menu item in the path "File | Roundabout Way | To | About"
|
13
|
+
Then I should see the "About" window
|
@@ -3,7 +3,7 @@ When /^I click the "(.*?)" button$/ do |name|
|
|
3
3
|
end
|
4
4
|
|
5
5
|
Then /^I should see the "(.*?)" window$/ do |window_title|
|
6
|
-
|
6
|
+
Mohawk::Waiter.wait_until { Uia.find_element title: window_title }
|
7
7
|
end
|
8
8
|
|
9
9
|
When /^I look at the value of the "(.*?)" control$/ do |name|
|
@@ -10,6 +10,10 @@ When /^I select the value "(.*?)" from the "(.*?)" combo box$/ do |index, name|
|
|
10
10
|
on(MainScreen).send "#{name.to_field}=", index
|
11
11
|
end
|
12
12
|
|
13
|
+
When(/^I select the regex value "([^"]*)" from the "([^"]*)" combo box$/) do |regex, name|
|
14
|
+
on(MainScreen).send "#{name.to_field}=", /#{regex}/
|
15
|
+
end
|
16
|
+
|
13
17
|
When(/^I clear the item at index "([^"]*)" from the "([^"]*)" combo box$/) do |which, name|
|
14
18
|
on(MainScreen).send("clear_#{name.to_field}", which.to_i)
|
15
19
|
end
|
@@ -19,7 +23,11 @@ When(/^I clear item "([^"]*)" from the "([^"]*)" combo box$/) do |which, name|
|
|
19
23
|
end
|
20
24
|
|
21
25
|
Then /^the "(.*?)" option(s)? should be selected in the "(.*?)" combo box$/ do |value, has_multiple, name|
|
22
|
-
|
26
|
+
if has_multiple
|
27
|
+
on(MainScreen).send("#{name.to_field}_selections").should eq(value.split(', '))
|
28
|
+
else
|
29
|
+
on(MainScreen).send("#{name.to_field}").should eq(value)
|
30
|
+
end
|
23
31
|
end
|
24
32
|
|
25
33
|
When /^I look at the options for the "(.*?)" combo box"$/ do |name|
|
@@ -34,3 +42,7 @@ end
|
|
34
42
|
Given(/^we toggle the multi-select button$/) do
|
35
43
|
on(MainScreen).toggle_multi
|
36
44
|
end
|
45
|
+
|
46
|
+
Then(/^the application should know that "([^"]*)" was selected$/) do |expected_value|
|
47
|
+
on(MainScreen).fruits_label.should eq(expected_value)
|
48
|
+
end
|
@@ -1,5 +1,10 @@
|
|
1
|
-
When
|
1
|
+
When(/^I select the menu item by text$/) do
|
2
|
+
on(MainScreen).menu_item_by_text
|
3
|
+
end
|
4
|
+
|
5
|
+
When /^I (select|click) the menu item in the path "(.*?)"$/ do |select_or_click, menu_path|
|
2
6
|
menu_item_method = menu_path.gsub(/ (\| )?/, "_").downcase
|
7
|
+
menu_item_method.prepend('click_') if select_or_click == 'click'
|
3
8
|
on(MainScreen).send menu_item_method
|
4
|
-
end
|
9
|
+
end
|
5
10
|
|
Binary file
|
@@ -3,6 +3,7 @@ class MainScreen
|
|
3
3
|
window(:title => /MainFormWindow/)
|
4
4
|
|
5
5
|
text(:text_field, :id => "textField")
|
6
|
+
text(:text_box_field, :id => "multiLineTextField")
|
6
7
|
text(:masked_text_field, :id => "maskedTextBox")
|
7
8
|
button(:data_entry_form_button, :value => "Data Entry Form")
|
8
9
|
button(:about, :value => "About")
|
@@ -16,8 +17,10 @@ class MainScreen
|
|
16
17
|
checkbox(:first_checkbox, :id => "checkBox")
|
17
18
|
radio(:first_radio, :id => "radioButton1")
|
18
19
|
label(:label_control, :id => "label1")
|
20
|
+
label(:fruits_label, :id => 'fruitsLabel')
|
19
21
|
link(:link_control, :id => "linkLabel1")
|
20
22
|
menu_item(:file_roundabout_way_to_about, :path => ["File", "Roundabout Way", "To", "About"])
|
23
|
+
menu_item(:menu_item_by_text, text: 'About')
|
21
24
|
tree_view(:tree_view, :id => "treeView")
|
22
25
|
control(:value_control_field, :id => "automatableMonthCalendar1")
|
23
26
|
spinner(:spinner, :id => 'numericUpDown1')
|
data/features/table.feature
CHANGED
@@ -13,14 +13,14 @@ Feature: Working with tables
|
|
13
13
|
|
14
14
|
Scenario: Selecting a row by matching cell information
|
15
15
|
When we select the table row with the following information:
|
16
|
-
|
|
17
|
-
| Anna Doe
|
16
|
+
| full_name | date_of_birth |
|
17
|
+
| Anna Doe | 3/4/1975 |
|
18
18
|
Then the row with index "1" should be selected
|
19
19
|
|
20
20
|
Scenario: Finding a row
|
21
21
|
Then we can find the row with the following information:
|
22
|
-
|
|
23
|
-
| John Doe
|
22
|
+
| full_name | date_of_birth | state |
|
23
|
+
| John Doe | 12/15/1967 | FL |
|
24
24
|
|
25
25
|
Scenario: Selecting a row from a child item
|
26
26
|
When we select the "1"th table row
|
@@ -41,8 +41,8 @@ Feature: Working with tables
|
|
41
41
|
Scenario: Clearing a row by matching cell information
|
42
42
|
Given we add rows "0, 1" to the selection
|
43
43
|
When we clear the table row with the following information:
|
44
|
-
|
|
45
|
-
| Anna Doe
|
44
|
+
| full_name | date_of_birth |
|
45
|
+
| Anna Doe | 3/4/1975 |
|
46
46
|
Then the row with index "1" should not be selected
|
47
47
|
|
48
48
|
Scenario: Rows have cells
|
@@ -57,7 +57,7 @@ Feature: Working with tables
|
|
57
57
|
| Anna Doe | 1 |
|
58
58
|
|
59
59
|
Scenario: Retrieving the headers
|
60
|
-
Then the table headers are "Name, Date of birth, State"
|
60
|
+
Then the table headers are "Full Name, Date of birth, State"
|
61
61
|
|
62
62
|
Scenario: Retrieving a row value by its header
|
63
63
|
Then the "date_of_birth" for the row at index "1" is "3/4/1975"
|
data/features/text.feature
CHANGED
@@ -4,6 +4,10 @@ Scenario: Setting and getting text
|
|
4
4
|
When I set the "text field" to the value "Some text"
|
5
5
|
Then the "text field" should be "Some text"
|
6
6
|
|
7
|
+
Scenario: Setting and getting text from a text box control
|
8
|
+
When I set the "text box field" to the value "Some text"
|
9
|
+
Then the "text box field" should be "Some text"
|
10
|
+
|
7
11
|
Scenario: Clearing text
|
8
12
|
When I set the "text field" to the value "Text to be cleared"
|
9
13
|
And I clear the "text field"
|
data/lib/mohawk/accessors.rb
CHANGED
@@ -226,6 +226,9 @@ module Mohawk
|
|
226
226
|
define_method("#{name}") do
|
227
227
|
adapter.menu_item(locator).select
|
228
228
|
end
|
229
|
+
define_method("click_#{name}") do
|
230
|
+
adapter.menu_item(locator).click
|
231
|
+
end
|
229
232
|
end
|
230
233
|
|
231
234
|
# Generates methods for working with table or list view controls
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Mohawk
|
2
|
+
module Adapters
|
3
|
+
module UIA
|
4
|
+
class CheckBox < Control
|
5
|
+
valid_patterns :toggle
|
6
|
+
|
7
|
+
def set_check(should_check)
|
8
|
+
toggle.toggle_state = should_check ? :on : :off
|
9
|
+
end
|
10
|
+
|
11
|
+
def checked?
|
12
|
+
toggle.toggle_state == :on
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
def toggle
|
17
|
+
element.as :toggle
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module Mohawk
|
2
|
+
module Adapters
|
3
|
+
module UIA
|
4
|
+
class Control
|
5
|
+
include Mohawk::Waiter
|
6
|
+
|
7
|
+
class << self
|
8
|
+
attr_reader :patterns
|
9
|
+
|
10
|
+
def valid_patterns(*patterns)
|
11
|
+
@patterns = patterns
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(adapter, locator)
|
16
|
+
@parent = adapter.window.element
|
17
|
+
@locator = locator
|
18
|
+
end
|
19
|
+
|
20
|
+
def click
|
21
|
+
element.click
|
22
|
+
end
|
23
|
+
|
24
|
+
def focus
|
25
|
+
element.focus
|
26
|
+
end
|
27
|
+
|
28
|
+
def exist?
|
29
|
+
locate_element != nil
|
30
|
+
end
|
31
|
+
alias_method :exists?, :exist?
|
32
|
+
|
33
|
+
def enabled?
|
34
|
+
exist? && element.enabled?
|
35
|
+
end
|
36
|
+
|
37
|
+
def disabled?
|
38
|
+
!enabled?
|
39
|
+
end
|
40
|
+
|
41
|
+
def visible?
|
42
|
+
exist? && element.visible?
|
43
|
+
end
|
44
|
+
|
45
|
+
def element
|
46
|
+
@element ||= wait_until { locate_element }
|
47
|
+
end
|
48
|
+
|
49
|
+
def handle
|
50
|
+
element.handle
|
51
|
+
end
|
52
|
+
|
53
|
+
def value
|
54
|
+
element.name
|
55
|
+
end
|
56
|
+
alias_method :control_name, :value
|
57
|
+
|
58
|
+
def view
|
59
|
+
self
|
60
|
+
end
|
61
|
+
|
62
|
+
def method_missing(meth, *args, &block)
|
63
|
+
if element.respond_to? meth
|
64
|
+
element.send meth, *args, &block
|
65
|
+
else
|
66
|
+
super
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
def locate_element
|
72
|
+
scope = (@locator.delete(:children_only) && :children) || :descendants
|
73
|
+
locator = @locator.merge(scope: scope)
|
74
|
+
|
75
|
+
patterns = @locator.delete(:pattern) || self.class.patterns
|
76
|
+
locator.merge!(pattern: patterns) if patterns
|
77
|
+
|
78
|
+
@parent.find locator
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Mohawk
|
2
|
+
module Adapters
|
3
|
+
module UIA
|
4
|
+
module ElementLocator
|
5
|
+
private
|
6
|
+
def find_element(value)
|
7
|
+
case value
|
8
|
+
when Regexp
|
9
|
+
all_items.find { |e| e.name =~ value }
|
10
|
+
when String
|
11
|
+
all_items.find { |e| e.name == value }
|
12
|
+
when Fixnum
|
13
|
+
all_items[value]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Mohawk
|
2
|
+
module Adapters
|
3
|
+
module UIA
|
4
|
+
class MenuItem < Control
|
5
|
+
class MenuItemNotFound < StandardError; end
|
6
|
+
|
7
|
+
def select
|
8
|
+
menu_item.as(:invoke).invoke
|
9
|
+
end
|
10
|
+
|
11
|
+
def click
|
12
|
+
menu_item.click_center
|
13
|
+
end
|
14
|
+
|
15
|
+
def exist?
|
16
|
+
!!menu_item
|
17
|
+
rescue MenuItemNotFound
|
18
|
+
false
|
19
|
+
end
|
20
|
+
alias_method :exists?, :exist?
|
21
|
+
|
22
|
+
private
|
23
|
+
def menu_item
|
24
|
+
current_item = @parent
|
25
|
+
path.each_with_index do |menu_item, index|
|
26
|
+
current_item = current_item.filter(control_type: :menu_item, name: menu_item).first
|
27
|
+
raise MenuItemNotFound, menu_item unless current_item
|
28
|
+
try_to_expand current_item unless index == path.count - 1
|
29
|
+
end
|
30
|
+
current_item
|
31
|
+
end
|
32
|
+
|
33
|
+
def path
|
34
|
+
[@locator[:path] || @locator[:text]].flatten
|
35
|
+
end
|
36
|
+
|
37
|
+
def try_to_expand(item)
|
38
|
+
case
|
39
|
+
when item.patterns.include?(:expand_collapse)
|
40
|
+
item.as(:expand_collapse).expand
|
41
|
+
else
|
42
|
+
item.as(:invoke).invoke
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Mohawk
|
2
|
+
module Adapters
|
3
|
+
module UIA
|
4
|
+
class Radio < Control
|
5
|
+
valid_patterns :selection_item
|
6
|
+
|
7
|
+
def set
|
8
|
+
selection_item.select
|
9
|
+
end
|
10
|
+
|
11
|
+
def set?
|
12
|
+
selection_item.selected?
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
def selection_item
|
17
|
+
element.as :selection_item
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Mohawk
|
2
|
+
module Adapters
|
3
|
+
module UIA
|
4
|
+
class SelectList < Control
|
5
|
+
include ElementLocator
|
6
|
+
|
7
|
+
def set(value)
|
8
|
+
which = find_element(value)
|
9
|
+
if select_list.multi_select?
|
10
|
+
which.add_to_selection
|
11
|
+
else
|
12
|
+
click_or_select which
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def clear(value)
|
17
|
+
find_element(value).remove_from_selection
|
18
|
+
end
|
19
|
+
|
20
|
+
def value
|
21
|
+
values.first || ''
|
22
|
+
end
|
23
|
+
|
24
|
+
def values
|
25
|
+
selected_items.map &:name
|
26
|
+
end
|
27
|
+
|
28
|
+
def selected_items
|
29
|
+
select_list.selected_items
|
30
|
+
end
|
31
|
+
|
32
|
+
def options
|
33
|
+
all_items.map &:name
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
def select_list
|
38
|
+
element.as :selection
|
39
|
+
end
|
40
|
+
|
41
|
+
def all_items
|
42
|
+
select_list.selection_items
|
43
|
+
end
|
44
|
+
|
45
|
+
def click_or_select(item)
|
46
|
+
item.click
|
47
|
+
rescue
|
48
|
+
item.select
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Mohawk
|
2
|
+
module Adapters
|
3
|
+
module UIA
|
4
|
+
class Spinner < Control
|
5
|
+
valid_patterns :range_value
|
6
|
+
|
7
|
+
def value=(value)
|
8
|
+
spinner.value = value
|
9
|
+
end
|
10
|
+
|
11
|
+
def value
|
12
|
+
spinner.value
|
13
|
+
end
|
14
|
+
|
15
|
+
def increment
|
16
|
+
self.value = value + spinner.small_change
|
17
|
+
end
|
18
|
+
|
19
|
+
def decrement
|
20
|
+
self.value = value - spinner.small_change
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
def spinner
|
25
|
+
element.as :range_value
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Mohawk
|
2
|
+
module Adapters
|
3
|
+
module UIA
|
4
|
+
class TabControl < Control
|
5
|
+
include ElementLocator
|
6
|
+
|
7
|
+
def selected_tab=(which)
|
8
|
+
find_element(which).select
|
9
|
+
end
|
10
|
+
|
11
|
+
def value
|
12
|
+
all_items.find(&:selected?).name
|
13
|
+
end
|
14
|
+
|
15
|
+
def items
|
16
|
+
all_items.map &:name
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
def all_items
|
21
|
+
element.filter(control_type: :tab_item).map {|e| e.as :selection_item }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Mohawk
|
2
|
+
module Adapters
|
3
|
+
module UIA
|
4
|
+
class Table < Control
|
5
|
+
include ElementLocator, Enumerable
|
6
|
+
valid_patterns :table
|
7
|
+
|
8
|
+
def select(which)
|
9
|
+
find_row_with(which).select
|
10
|
+
end
|
11
|
+
|
12
|
+
def add(which)
|
13
|
+
find_row_with(which).add
|
14
|
+
end
|
15
|
+
|
16
|
+
def clear(which)
|
17
|
+
find_row_with(which).clear
|
18
|
+
end
|
19
|
+
|
20
|
+
def headers
|
21
|
+
element.headers.map &:name
|
22
|
+
end
|
23
|
+
|
24
|
+
def [](index)
|
25
|
+
row_at(index)
|
26
|
+
end
|
27
|
+
|
28
|
+
def each
|
29
|
+
all_items.each { |row| yield row }
|
30
|
+
end
|
31
|
+
|
32
|
+
def find_row_with(row_info)
|
33
|
+
found_row = case row_info
|
34
|
+
when Hash
|
35
|
+
find_by_hash(row_info)
|
36
|
+
else
|
37
|
+
find_element(row_info)
|
38
|
+
end
|
39
|
+
raise "A row with #{row_info} was not found" unless found_row
|
40
|
+
found_row
|
41
|
+
end
|
42
|
+
|
43
|
+
def element
|
44
|
+
super.as(:table)
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
def find_by_hash(hash)
|
49
|
+
find { |r| r.all_match? hash }
|
50
|
+
end
|
51
|
+
|
52
|
+
def row_at(index)
|
53
|
+
TableRow.new self, index
|
54
|
+
end
|
55
|
+
|
56
|
+
def all_items
|
57
|
+
element.row_count.times.map { |index| TableRow.new self, index }
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module Mohawk
|
2
|
+
module Adapters
|
3
|
+
module UIA
|
4
|
+
class TableRow
|
5
|
+
attr_reader :index
|
6
|
+
|
7
|
+
def initialize(table, index)
|
8
|
+
@table, @index = table, index
|
9
|
+
end
|
10
|
+
|
11
|
+
def name
|
12
|
+
element.name
|
13
|
+
end
|
14
|
+
|
15
|
+
def cells
|
16
|
+
element.items.map &:name
|
17
|
+
end
|
18
|
+
|
19
|
+
def select
|
20
|
+
selection_item.select
|
21
|
+
self
|
22
|
+
end
|
23
|
+
|
24
|
+
def add
|
25
|
+
selection_item.add_to_selection
|
26
|
+
self
|
27
|
+
end
|
28
|
+
|
29
|
+
def clear
|
30
|
+
selection_item.remove_from_selection
|
31
|
+
self
|
32
|
+
end
|
33
|
+
|
34
|
+
def selected?
|
35
|
+
selection_item.selected?
|
36
|
+
end
|
37
|
+
|
38
|
+
def all_match?(hash)
|
39
|
+
hash.all? do |key, value|
|
40
|
+
value_from_header(key) == "#{value}"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def to_hash
|
45
|
+
{text: element.name, row: index}
|
46
|
+
end
|
47
|
+
|
48
|
+
def method_missing(name, *args)
|
49
|
+
value_from_header name
|
50
|
+
end
|
51
|
+
|
52
|
+
def value_from_header(name)
|
53
|
+
which_column = header_methods.find_index {|h| h.to_s == name.to_s }
|
54
|
+
raise ArgumentError, "#{name} column does not exist in #{header_methods}" if which_column.nil?
|
55
|
+
cells[which_column]
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
def element
|
60
|
+
@element ||= @table.element.row_at(@index)
|
61
|
+
end
|
62
|
+
|
63
|
+
def selection_item
|
64
|
+
element.as :selection_item
|
65
|
+
end
|
66
|
+
|
67
|
+
def header_methods
|
68
|
+
@headers ||= @table.headers.map(&:to_method)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|