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