bewildr 0.1.9 → 0.1.10
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +1 -1
- data/Rakefile +1 -1
- data/lib/bewildr/control_patterns/expand_collapse_pattern.rb +7 -0
- data/lib/bewildr/control_patterns/grid_pattern.rb +3 -0
- data/lib/bewildr/control_patterns/range_value_pattern.rb +4 -0
- data/lib/bewildr/control_patterns/scroll_pattern.rb +26 -25
- data/lib/bewildr/control_patterns/selection_item_pattern.rb +3 -0
- data/lib/bewildr/control_patterns/selection_pattern.rb +3 -0
- data/lib/bewildr/control_patterns/table_item_pattern.rb +2 -0
- data/lib/bewildr/control_patterns/table_pattern.rb +2 -0
- data/lib/bewildr/control_patterns/text_pattern.rb +2 -0
- data/lib/bewildr/control_patterns/toggle_pattern.rb +61 -36
- data/lib/bewildr/control_patterns/value_pattern.rb +3 -0
- data/lib/bewildr/control_patterns/window_pattern.rb +8 -0
- data/lib/bewildr/control_type_additions/combo_box_additions.rb +70 -65
- data/lib/bewildr/control_type_additions/data_grid_additions.rb +3 -6
- data/lib/bewildr/control_type_additions/document_additions.rb +21 -22
- data/lib/bewildr/control_type_additions/list_additions.rb +51 -47
- data/lib/bewildr/control_type_additions/menu_additions.rb +49 -44
- data/lib/bewildr/control_type_additions/menu_item_additions.rb +6 -10
- data/lib/bewildr/control_type_additions/scroll_additions.rb +16 -20
- data/lib/bewildr/control_type_additions/tab_additions.rb +17 -17
- data/lib/bewildr/control_type_additions/text_additions.rb +4 -7
- data/lib/bewildr/control_type_additions/tree_additions.rb +45 -41
- data/lib/bewildr/control_type_additions/tree_item_additions.rb +14 -17
- data/lib/bewildr/control_type_additions/window_additions.rb +8 -10
- data/lib/bewildr/element.rb +10 -0
- data/lib/bewildr/windows.rb +1 -0
- metadata +4 -4
data/README.rdoc
CHANGED
@@ -9,7 +9,7 @@ Documentation is on the way; until then, take a look at the tests or read the AP
|
|
9
9
|
==Getting started
|
10
10
|
===Dependencies
|
11
11
|
1. Install .net 3 and 4 (http://www.microsoft.com/downloads/details.aspx?FamilyID=10cc340b-f857-4a14-83f5-25634c3bf043&displaylang=en & http://msdn.microsoft.com/en-us/netframework/aa569263.aspx)
|
12
|
-
2. Install the latest ironruby (http://
|
12
|
+
2. Install the latest ironruby (http://ironruby.codeplex.com/), and for your own sanity install it in c:\\\\ironruby instead of the default location.
|
13
13
|
3. You'll need at least rubygems version 1.3.6:
|
14
14
|
gem update --system
|
15
15
|
|
data/Rakefile
CHANGED
@@ -10,7 +10,7 @@ require 'cucumber/rake/task'
|
|
10
10
|
|
11
11
|
spec = Gem::Specification.new do |s|
|
12
12
|
s.name = 'bewildr'
|
13
|
-
s.version = '0.1.
|
13
|
+
s.version = '0.1.10'
|
14
14
|
s.has_rdoc = true
|
15
15
|
s.extra_rdoc_files = ['README.rdoc', 'LICENSE']
|
16
16
|
s.summary = 'Test WPF UI apps with IronRuby'
|
@@ -3,14 +3,21 @@
|
|
3
3
|
module Bewildr
|
4
4
|
module ControlPatterns
|
5
5
|
module ExpandCollapsePattern
|
6
|
+
#Expands the element - use to open combo boxes
|
6
7
|
def expand
|
7
8
|
@automation_element.get_current_pattern(System::Windows::Automation::ExpandCollapsePattern.pattern).expand unless expand_state == :expanded or expand_state == :leaf
|
8
9
|
end
|
9
10
|
|
11
|
+
#Collapses the element - use to close combo boxes
|
10
12
|
def collapse
|
11
13
|
@automation_element.get_current_pattern(System::Windows::Automation::ExpandCollapsePattern.pattern).collapse unless expand_state == :collapsed or expand_state == :leaf
|
12
14
|
end
|
13
15
|
|
16
|
+
#Returns the expand-state of the element. The available states are:
|
17
|
+
# :collapsed
|
18
|
+
# :expanded
|
19
|
+
# :partially_expanded
|
20
|
+
# :leaf
|
14
21
|
def expand_state
|
15
22
|
case @automation_element.get_current_pattern(System::Windows::Automation::ExpandCollapsePattern.pattern).current.expand_collapse_state
|
16
23
|
when System::Windows::Automation::ExpandCollapseState.collapsed then return :collapsed
|
@@ -3,14 +3,17 @@
|
|
3
3
|
module Bewildr
|
4
4
|
module ControlPatterns
|
5
5
|
module GridPattern
|
6
|
+
#Returns the number of rows in the grid
|
6
7
|
def row_count
|
7
8
|
@automation_element.get_current_pattern(System::Windows::Automation::GridPattern.pattern).current.row_count.to_i
|
8
9
|
end
|
9
10
|
|
11
|
+
#Returns the number of columns in the grid
|
10
12
|
def column_count
|
11
13
|
@automation_element.get_current_pattern(System::Windows::Automation::GridPattern.pattern).current.column_count.to_i
|
12
14
|
end
|
13
15
|
|
16
|
+
#Returns an item from the grid
|
14
17
|
def get_item(row, column)
|
15
18
|
item = @automation_element.get_current_pattern(System::Windows::Automation::GridPattern.pattern).get_item(row, column)
|
16
19
|
Bewildr::Element.new(item)
|
@@ -3,18 +3,22 @@
|
|
3
3
|
module Bewildr
|
4
4
|
module ControlPatterns
|
5
5
|
module RangeValuePattern
|
6
|
+
#Returns the current value of the element
|
6
7
|
def value
|
7
8
|
@automation_element.get_current_pattern(System::Windows::Automation::RangeValuePattern.pattern).current.value.to_f
|
8
9
|
end
|
9
10
|
|
11
|
+
#Sets the value of the element
|
10
12
|
def value=(input)
|
11
13
|
@automation_element.get_current_pattern(System::Windows::Automation::RangeValuePattern.pattern).set_value(input.to_f)
|
12
14
|
end
|
13
15
|
|
16
|
+
#Returns the maximum value of the element
|
14
17
|
def maximum
|
15
18
|
@automation_element.get_current_pattern(System::Windows::Automation::RangeValuePattern.pattern).current.maximum.to_f
|
16
19
|
end
|
17
20
|
|
21
|
+
#Returns the minimum value of the element
|
18
22
|
def minimum
|
19
23
|
@automation_element.get_current_pattern(System::Windows::Automation::RangeValuePattern.pattern).current.minimum.to_f
|
20
24
|
end
|
@@ -3,35 +3,36 @@
|
|
3
3
|
module Bewildr
|
4
4
|
module ControlPatterns
|
5
5
|
module ScrollPattern
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
6
|
+
#Returns true if the element is vertically scrollable, false if it's not
|
7
|
+
def vertically_scrollable
|
8
|
+
@automation_element.get_current_pattern(System::Windows::Automation::ScrollPattern.pattern).current.vertically_scrollable
|
9
|
+
end
|
10
|
+
|
11
|
+
#Returns the current vertical scroll percent
|
12
|
+
def vertical_scroll_percent
|
13
|
+
@automation_element.get_current_pattern(System::Windows::Automation::ScrollPattern.pattern).current.vertical_scroll_percent.to_f
|
14
|
+
end
|
15
|
+
alias :scroll_percent :vertical_scroll_percent
|
12
16
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
+
#Set the scroll percent of the element
|
18
|
+
def set_scroll_percent(percent_horizontal, percent_vertical)
|
19
|
+
@automation_element.get_current_pattern(System::Windows::Automation::ScrollPattern.pattern).set_scroll_percent(percent_horizontal, percent_vertical)
|
20
|
+
end
|
17
21
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
set_scroll_percent(System::Windows::Automation::ScrollPattern.NoScroll, target_percentage)
|
24
|
-
end
|
25
|
-
alias :scroll_to :scroll_vertically_to
|
22
|
+
#Set the vertical scroll percent of the element
|
23
|
+
def scroll_vertically_to(target_percentage)
|
24
|
+
set_scroll_percent(System::Windows::Automation::ScrollPattern.NoScroll, target_percentage)
|
25
|
+
end
|
26
|
+
alias :scroll_to :scroll_vertically_to
|
26
27
|
|
27
|
-
|
28
|
-
|
29
|
-
|
28
|
+
#Set the horizontal scroll percent of the element
|
29
|
+
def scroll_horizontally_to(target_percentage)
|
30
|
+
set_scroll_percent(target_percentage, System::Windows::Automation::ScrollPattern.NoScroll)
|
31
|
+
end
|
30
32
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
end
|
33
|
+
#Scrolls vertically down by one 'page'
|
34
|
+
def scroll_down_one_page
|
35
|
+
@automation_element.get_current_pattern(System::Windows::Automation::ScrollPattern.pattern).scroll_vertical(System::Windows::Automation::ScrollAmount.LargeIncrement)
|
35
36
|
end
|
36
37
|
end
|
37
38
|
end
|
@@ -4,14 +4,17 @@
|
|
4
4
|
module Bewildr
|
5
5
|
module ControlPatterns
|
6
6
|
module SelectionItemPattern
|
7
|
+
#Selects the element
|
7
8
|
def select
|
8
9
|
@automation_element.get_current_pattern(System::Windows::Automation::SelectionItemPattern.pattern).select
|
9
10
|
end
|
10
11
|
|
12
|
+
#Returns true if the element is selected, false if it's not
|
11
13
|
def selected?
|
12
14
|
@automation_element.get_current_pattern(System::Windows::Automation::SelectionItemPattern.pattern).current.is_selected
|
13
15
|
end
|
14
16
|
|
17
|
+
#Returns false if the element is selected, true if it's not
|
15
18
|
def unselected?
|
16
19
|
!selected?
|
17
20
|
end
|
@@ -3,6 +3,7 @@
|
|
3
3
|
module Bewildr
|
4
4
|
module ControlPatterns
|
5
5
|
module SelectionPattern
|
6
|
+
#Returns the elements that are selected
|
6
7
|
def get_selection
|
7
8
|
my_selected_items = @automation_element.get_current_pattern(System::Windows::Automation::SelectionPattern.pattern).current.get_selection
|
8
9
|
|
@@ -13,11 +14,13 @@ module Bewildr
|
|
13
14
|
item_array.to_a.collect {|item| Bewildr::Element.new(item)}
|
14
15
|
end
|
15
16
|
|
17
|
+
#Returns true if more than one selection is possible, false if it's not
|
16
18
|
def multi_selectable?
|
17
19
|
@automation_element.get_current_pattern(System::Windows::Automation::SelectionPattern.pattern).current.can_select_multiple
|
18
20
|
end
|
19
21
|
alias :can_select_multiple? :multi_selectable?
|
20
22
|
|
23
|
+
#Returns the (first - if relevant) selected item
|
21
24
|
def selected
|
22
25
|
multi_selectable? ? get_selection : get_selection.first
|
23
26
|
end
|
@@ -3,10 +3,12 @@
|
|
3
3
|
module Bewildr
|
4
4
|
module ControlPatterns
|
5
5
|
module TableItemPattern
|
6
|
+
#Returns the number of rows the element spans
|
6
7
|
def row_span
|
7
8
|
@automation_element.get_current_pattern(System::Windows::Automation::TableItemPattern.pattern).current.row_span.to_i
|
8
9
|
end
|
9
10
|
|
11
|
+
#Returns the number of columns the element spans
|
10
12
|
def column_span
|
11
13
|
@automation_element.get_current_pattern(System::Windows::Automation::TableItemPattern.pattern).current.column_span.to_i
|
12
14
|
end
|
@@ -3,6 +3,7 @@
|
|
3
3
|
module Bewildr
|
4
4
|
module ControlPatterns
|
5
5
|
module TablePattern
|
6
|
+
#Returns an array of elements containing the column headers
|
6
7
|
def column_headers
|
7
8
|
#the following line seems to prompt the table pattern into giving up the column header
|
8
9
|
#information that's called on the line that follows it. Weird? tell me about it...
|
@@ -12,6 +13,7 @@ module Bewildr
|
|
12
13
|
end
|
13
14
|
end
|
14
15
|
|
16
|
+
#Returns a string array containing the column header names
|
15
17
|
def column_header_names
|
16
18
|
column_headers.collect {|header| header.name }
|
17
19
|
end
|
@@ -3,10 +3,12 @@
|
|
3
3
|
module Bewildr
|
4
4
|
module ControlPatterns
|
5
5
|
module TextPattern
|
6
|
+
#Selects all of the text in the element
|
6
7
|
def select_all
|
7
8
|
@automation_element.get_current_pattern(System::Windows::Automation::TextPattern.pattern).document_range.select
|
8
9
|
end
|
9
10
|
|
11
|
+
#Returns all the element's text
|
10
12
|
def get_text
|
11
13
|
@automation_element.get_current_pattern(System::Windows::Automation::TextPattern.pattern).document_range.get_text(-1).to_s
|
12
14
|
end
|
@@ -2,51 +2,76 @@
|
|
2
2
|
|
3
3
|
module Bewildr
|
4
4
|
module ControlPatterns
|
5
|
-
module
|
5
|
+
module TogglePatternForButton
|
6
|
+
#Toggle on the element
|
7
|
+
def toggle_on
|
8
|
+
set_state_to(:on)
|
9
|
+
end
|
6
10
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
def check
|
12
|
-
set_state_to :on
|
13
|
-
end
|
11
|
+
#Toggle off the element
|
12
|
+
def toggle_off
|
13
|
+
set_state_to(:off)
|
14
|
+
end
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
16
|
+
#Return the toggle state. The available states are:
|
17
|
+
# :on
|
18
|
+
# :off
|
19
|
+
# :indeterminate
|
20
|
+
def toggle_state
|
21
|
+
state
|
22
|
+
end
|
18
23
|
|
19
|
-
|
20
|
-
|
21
|
-
|
24
|
+
#Toggle the element
|
25
|
+
def toggle
|
26
|
+
flip_state
|
27
|
+
end
|
28
|
+
end
|
22
29
|
|
23
|
-
|
24
|
-
|
25
|
-
|
30
|
+
module TogglePatternForCheckBox
|
31
|
+
#Check the element
|
32
|
+
def check
|
33
|
+
set_state_to :on
|
34
|
+
end
|
26
35
|
|
27
|
-
|
28
|
-
|
29
|
-
|
36
|
+
#Uncheck the element
|
37
|
+
def uncheck
|
38
|
+
set_state_to :off
|
39
|
+
end
|
30
40
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
41
|
+
#Return true if the element is checked, false if it's not
|
42
|
+
def checked?
|
43
|
+
state == :on
|
44
|
+
end
|
45
|
+
|
46
|
+
#Return true if the element is unchecked, false if it's not
|
47
|
+
def unchecked?
|
48
|
+
state == :off
|
49
|
+
end
|
38
50
|
|
39
|
-
|
40
|
-
|
41
|
-
|
51
|
+
#Return true if the element is indeterminate, false if it's not
|
52
|
+
def indeterminate?
|
53
|
+
state == :indeterminate
|
54
|
+
end
|
42
55
|
|
43
|
-
|
44
|
-
|
45
|
-
|
56
|
+
#Returns the checked state. The available states are:
|
57
|
+
# :on
|
58
|
+
# :off
|
59
|
+
# :indeterminate
|
60
|
+
def checked_state
|
61
|
+
state
|
62
|
+
end
|
63
|
+
end
|
46
64
|
|
47
|
-
|
48
|
-
|
49
|
-
|
65
|
+
#These are not the toggle patterns you are looking for [wave of the hand/]. If you are dealing with a button, look for Bewildr::ControlPatterns::TogglePatternForButton.
|
66
|
+
#If you're dealing with a checkbox, take a look at Bewildr::ControlPatterns::TogglePatternForCheckBox
|
67
|
+
module TogglePattern
|
68
|
+
def self.extended(base)
|
69
|
+
base.instance_eval do
|
70
|
+
case @control_type
|
71
|
+
when :check_box
|
72
|
+
base.extend(Bewildr::ControlPatterns::TogglePatternForCheckBox)
|
73
|
+
when :button
|
74
|
+
base.extend(Bewildr::ControlPatterns::TogglePatternForButton)
|
50
75
|
end
|
51
76
|
end
|
52
77
|
end
|
@@ -3,15 +3,18 @@
|
|
3
3
|
module Bewildr
|
4
4
|
module ControlPatterns
|
5
5
|
module ValuePattern
|
6
|
+
#Returns true if the element is a password field, false if it's not
|
6
7
|
def password_field?
|
7
8
|
@automation_element.current.class_name.to_s == "PasswordBox" ? true : false
|
8
9
|
end
|
9
10
|
|
11
|
+
#Returns the element's text
|
10
12
|
def text
|
11
13
|
raise Bewildr::PasswordFieldReadAttempt, "You can't get the text of a password field" if password_field?
|
12
14
|
@automation_element.get_current_pattern(System::Windows::Automation::ValuePattern.pattern).current.value.to_s
|
13
15
|
end
|
14
16
|
|
17
|
+
#Sets the element's text
|
15
18
|
def text=(input)
|
16
19
|
raise Bewildr::ElementNotEnabled unless enabled?
|
17
20
|
@automation_element.get_current_pattern(System::Windows::Automation::ValuePattern.pattern).set_value(input)
|
@@ -3,22 +3,30 @@
|
|
3
3
|
module Bewildr
|
4
4
|
module ControlPatterns
|
5
5
|
module WindowPattern
|
6
|
+
#Closes the window
|
6
7
|
def close
|
7
8
|
@automation_element.get_current_pattern(System::Windows::Automation::WindowPattern.pattern).close
|
8
9
|
end
|
9
10
|
|
11
|
+
#Minimizes the window
|
10
12
|
def minimize
|
11
13
|
@automation_element.get_current_pattern(System::Windows::Automation::WindowPattern.pattern).set_window_visual_state(System::Windows::Automation::WindowVisualState.minimized)
|
12
14
|
end
|
13
15
|
|
16
|
+
#Maximizes the window
|
14
17
|
def maximize
|
15
18
|
@automation_element.get_current_pattern(System::Windows::Automation::WindowPattern.pattern).set_window_visual_state(System::Windows::Automation::WindowVisualState.maximized)
|
16
19
|
end
|
17
20
|
|
21
|
+
#Restores the window
|
18
22
|
def restore
|
19
23
|
@automation_element.get_current_pattern(System::Windows::Automation::WindowPattern.pattern).set_window_visual_state(System::Windows::Automation::WindowVisualState.normal)
|
20
24
|
end
|
21
25
|
|
26
|
+
#Returns the visual state of the window. Available states are:
|
27
|
+
# :maximized
|
28
|
+
# :minimized
|
29
|
+
# :normal
|
22
30
|
def visual_state
|
23
31
|
case @automation_element.get_current_pattern(System::Windows::Automation::WindowPattern.pattern).current.window_visual_state
|
24
32
|
when System::Windows::Automation::WindowVisualState.maximized then return :maximized
|
@@ -3,79 +3,84 @@
|
|
3
3
|
module Bewildr
|
4
4
|
module ControlTypeAdditions
|
5
5
|
module ComboBoxAdditions
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
end
|
6
|
+
#Returns a string array containing the element's item names
|
7
|
+
def items
|
8
|
+
my_list_items = list_items
|
9
|
+
return nil if my_list_items.nil?
|
10
|
+
my_list_items.collect {|item| item.name}
|
11
|
+
end
|
13
12
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
13
|
+
#Returns an array containing the combobox items
|
14
|
+
def list_items
|
15
|
+
begin
|
16
|
+
expand_combo
|
17
|
+
bewildr_list_items = get(:type => :list_item, :scope => :children, :how_many => :all)
|
18
|
+
bewildr_list_items.nil? ? nil : bewildr_list_items
|
19
|
+
ensure
|
20
|
+
collapse_combo
|
21
|
+
end
|
22
|
+
end
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
24
|
+
#Returns the number of items in the combobox
|
25
|
+
def count
|
26
|
+
my_items = items
|
27
|
+
my_items.nil? ? 0 : my_items.size
|
28
|
+
end
|
28
29
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
30
|
+
#Selects a combobox item. Takes a string (and selects the first item whose name matches) or an integer and selects the respective element
|
31
|
+
def select(input)
|
32
|
+
case input
|
33
|
+
when String then select_by_name(input)
|
34
|
+
when Integer then select_by_index(input)
|
35
|
+
else raise ArgumentError, "Select by name or by index"
|
36
|
+
end
|
37
|
+
end
|
36
38
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
39
|
+
#Selects the first item whose name matches the input
|
40
|
+
def select_by_name(input)
|
41
|
+
begin
|
42
|
+
expand_combo
|
43
|
+
my_item = list_items.find {|item| item.name == input}
|
44
|
+
raise Bewildr::NoSuchItemInComboBox if my_item.nil?
|
45
|
+
my_item.select
|
46
|
+
ensure
|
47
|
+
collapse_combo
|
48
|
+
end
|
49
|
+
end
|
47
50
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
51
|
+
#Selects the item at the supplied position
|
52
|
+
def select_by_index(input)
|
53
|
+
raise "Index must be 0 or greater" if input < 0
|
54
|
+
begin
|
55
|
+
expand_combo
|
56
|
+
list_items[input].select
|
57
|
+
ensure
|
58
|
+
collapse_combo
|
59
|
+
end
|
60
|
+
end
|
57
61
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
62
|
+
#Returns the selected combobox item
|
63
|
+
def selected
|
64
|
+
#TODO: find a way to not need to expand and collapse before getting the selected item
|
65
|
+
expand_combo
|
66
|
+
collapse_combo
|
67
|
+
#get_selection.first
|
68
|
+
get_selection.first.name
|
69
|
+
end
|
65
70
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
71
|
+
#Expands the combobox
|
72
|
+
def expand_combo
|
73
|
+
expand
|
74
|
+
Timeout.timeout(30) do
|
75
|
+
sleep 0.2 until expand_state == :expanded
|
76
|
+
end
|
77
|
+
end
|
72
78
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
end
|
79
|
+
#Collapses the combobox
|
80
|
+
def collapse_combo
|
81
|
+
collapse
|
82
|
+
Timeout.timeout(30) do
|
83
|
+
sleep 0.2 until expand_state == :collapsed
|
79
84
|
end
|
80
85
|
end
|
81
86
|
end
|
@@ -3,12 +3,9 @@
|
|
3
3
|
module Bewildr
|
4
4
|
module ControlTypeAdditions
|
5
5
|
module DataGridAdditions
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
get_item(row, column)
|
10
|
-
end
|
11
|
-
end
|
6
|
+
#Returns the cell at the supplied row and column
|
7
|
+
def cell(row, column)
|
8
|
+
get_item(row, column)
|
12
9
|
end
|
13
10
|
end
|
14
11
|
end
|
@@ -3,31 +3,30 @@
|
|
3
3
|
module Bewildr
|
4
4
|
module ControlTypeAdditions
|
5
5
|
module DocumentAdditions
|
6
|
-
|
7
|
-
|
6
|
+
#Returns the document text
|
7
|
+
def text
|
8
|
+
get_text
|
9
|
+
end
|
8
10
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
end
|
11
|
+
#Sets the document text to the supplied input
|
12
|
+
def text=(input)
|
13
|
+
cleaned_string = clean_string(input)
|
14
|
+
focus
|
15
|
+
select_all
|
16
|
+
System::Windows::Forms::SendKeys.send_wait("{DEL}")
|
17
|
+
System::Windows::Forms::SendKeys.send_wait(cleaned_string)
|
18
|
+
end
|
18
19
|
|
19
|
-
|
20
|
-
get_text
|
21
|
-
end
|
20
|
+
private
|
22
21
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
22
|
+
def clean_string(input)
|
23
|
+
#add special chars as necessary. Ref: http://msdn.microsoft.com/en-us/library/system.windows.forms.sendkeys.send.aspx
|
24
|
+
replacements = {
|
25
|
+
/\n/ => "{ENTER}"
|
26
|
+
}
|
27
|
+
cleaned_string = input
|
28
|
+
replacements.keys.each {|key| cleaned_string.gsub!(key, replacements[key])}
|
29
|
+
cleaned_string
|
31
30
|
end
|
32
31
|
end
|
33
32
|
end
|
@@ -3,55 +3,59 @@
|
|
3
3
|
module Bewildr
|
4
4
|
module ControlTypeAdditions
|
5
5
|
module ListAdditions
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
def select_by_name(input)
|
39
|
-
my_item = list_items.find {|item| item.name == input}
|
40
|
-
raise Bewildr::NoSuchItemInListBox if my_item.nil?
|
41
|
-
my_item.select
|
42
|
-
end
|
43
|
-
|
44
|
-
def select_by_index(input)
|
45
|
-
raise "Index must be 0 or greater" if input < 0
|
46
|
-
list_items[input].select
|
47
|
-
end
|
48
|
-
|
49
|
-
def selected
|
50
|
-
return nil if get_selection.empty?
|
51
|
-
get_selection.first.name
|
52
|
-
end
|
6
|
+
#Select the list item whose name matches the supplied input
|
7
|
+
def select(input)
|
8
|
+
selectable_elements = get(:type => :list_item, :scope => :children, :how_many => :all)
|
9
|
+
selectable_elements.find {|selectable_element| selectable_element.name == input}.select
|
10
|
+
end
|
11
|
+
|
12
|
+
#Returns a string array containing the list item names
|
13
|
+
def items
|
14
|
+
my_list_items = list_items
|
15
|
+
return nil if my_list_items.nil?
|
16
|
+
my_list_items.collect {|item| item.name}
|
17
|
+
end
|
18
|
+
|
19
|
+
#Returns an array containing the list items
|
20
|
+
def list_items
|
21
|
+
prepare_element
|
22
|
+
bewildr_list_items = get(:type => :list_item, :scope => :children, :how_many => :all)
|
23
|
+
bewildr_list_items.nil? ? nil : bewildr_list_items
|
24
|
+
end
|
25
|
+
|
26
|
+
#Returns the number of items in the list
|
27
|
+
def count
|
28
|
+
my_items = items
|
29
|
+
my_items.nil? ? 0 : my_items.size
|
30
|
+
end
|
31
|
+
|
32
|
+
#Selects a list item. Takes a string (and selects the first item whose name matches) or an integer and selects the respective element
|
33
|
+
def select(input)
|
34
|
+
case input
|
35
|
+
when String then select_by_name(input)
|
36
|
+
when Integer then select_by_index(input)
|
37
|
+
else raise ArgumentError, "Select by name or by index"
|
53
38
|
end
|
54
39
|
end
|
40
|
+
|
41
|
+
#Selects the first item whose name matches the input
|
42
|
+
def select_by_name(input)
|
43
|
+
my_item = list_items.find {|item| item.name == input}
|
44
|
+
raise Bewildr::NoSuchItemInListBox if my_item.nil?
|
45
|
+
my_item.select
|
46
|
+
end
|
47
|
+
|
48
|
+
#Selects the item at the supplied position
|
49
|
+
def select_by_index(input)
|
50
|
+
raise "Index must be 0 or greater" if input < 0
|
51
|
+
list_items[input].select
|
52
|
+
end
|
53
|
+
|
54
|
+
#Returns the selected list item
|
55
|
+
def selected
|
56
|
+
return nil if get_selection.empty?
|
57
|
+
get_selection.first.name
|
58
|
+
end
|
55
59
|
end
|
56
60
|
end
|
57
61
|
end
|
@@ -3,56 +3,61 @@
|
|
3
3
|
module Bewildr
|
4
4
|
module ControlTypeAdditions
|
5
5
|
module MenuAdditions
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
end
|
6
|
+
#Returns an array containing the menu's root items
|
7
|
+
def root_menu_items
|
8
|
+
get(:type => :menu_item, :scope => :children, :how_many => :all)
|
9
|
+
end
|
11
10
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
def select_menu(path)
|
17
|
-
menu_item(path).click
|
18
|
-
end
|
11
|
+
#Returns a string array containing the root items' names
|
12
|
+
def root_menu_item_names
|
13
|
+
root_menu_items.collect {|menu_item| menu_item.name}
|
14
|
+
end
|
19
15
|
|
20
|
-
|
21
|
-
|
22
|
-
|
16
|
+
#Clicks the menu described by the input, eg:
|
17
|
+
# select_menu(["File", "Close"])
|
18
|
+
def select_menu(path)
|
19
|
+
menu_item(path).click
|
20
|
+
end
|
23
21
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
when Array
|
30
|
-
matching_menu_item = current_menu_items.find {|node| node.name == target_menu_item} #TODO: make this work with regexes as well as strings...
|
31
|
-
raise Bewildr::ElementDoesntExist if matching_menu_item.nil?
|
32
|
-
when Bewildr::Element
|
33
|
-
if current_menu_items.name == target_menu_item #TODO: make this work with regexes as well as strings...
|
34
|
-
matching_menu_item = current_menu_items
|
35
|
-
else
|
36
|
-
raise Bewildr::ElementDoesntExist
|
37
|
-
end
|
38
|
-
end
|
39
|
-
raise Bewildr::ElementDoesntExist if matching_menu_item.nil?
|
40
|
-
if path.size != index + 1
|
41
|
-
matching_menu_item.expand
|
42
|
-
current_menu_items = matching_menu_item.sub_menus
|
43
|
-
end
|
44
|
-
end
|
45
|
-
return matching_menu_item
|
46
|
-
end
|
22
|
+
#Selects the menu described by the input, eg:
|
23
|
+
# select_node(["File", "Close"])
|
24
|
+
def select_node(path)
|
25
|
+
node(path).select
|
26
|
+
end
|
47
27
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
28
|
+
#Returns the menu item described by the input, eg:
|
29
|
+
# menu_item(["File", "Close"])
|
30
|
+
def menu_item(path)
|
31
|
+
current_menu_items = root_menu_items
|
32
|
+
matching_menu_item = nil
|
33
|
+
path.each_with_index do |target_menu_item, index|
|
34
|
+
case current_menu_items
|
35
|
+
when Array
|
36
|
+
matching_menu_item = current_menu_items.find {|node| node.name == target_menu_item} #TODO: make this work with regexes as well as strings...
|
37
|
+
raise Bewildr::ElementDoesntExist if matching_menu_item.nil?
|
38
|
+
when Bewildr::Element
|
39
|
+
if current_menu_items.name == target_menu_item #TODO: make this work with regexes as well as strings...
|
40
|
+
matching_menu_item = current_menu_items
|
41
|
+
else
|
42
|
+
raise Bewildr::ElementDoesntExist
|
54
43
|
end
|
55
44
|
end
|
45
|
+
raise Bewildr::ElementDoesntExist if matching_menu_item.nil?
|
46
|
+
if path.size != index + 1
|
47
|
+
matching_menu_item.expand
|
48
|
+
current_menu_items = matching_menu_item.sub_menus
|
49
|
+
end
|
50
|
+
end
|
51
|
+
return matching_menu_item
|
52
|
+
end
|
53
|
+
|
54
|
+
#Returns true if the menu contains the item described by the input, false if it doesn't
|
55
|
+
def contains_menu_item?(path)
|
56
|
+
begin
|
57
|
+
menu_item(path)
|
58
|
+
return true
|
59
|
+
rescue ElementDoesntExist => e
|
60
|
+
return false
|
56
61
|
end
|
57
62
|
end
|
58
63
|
end
|
@@ -3,17 +3,13 @@
|
|
3
3
|
module Bewildr
|
4
4
|
module ControlTypeAdditions
|
5
5
|
module MenuItemAdditions
|
6
|
-
def
|
7
|
-
|
8
|
-
|
9
|
-
get(:type => :menu_item, :scope => :children, :how_many => :all)
|
10
|
-
end
|
6
|
+
def sub_menus
|
7
|
+
get(:type => :menu_item, :scope => :children, :how_many => :all)
|
8
|
+
end
|
11
9
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
end
|
16
|
-
end
|
10
|
+
#menu items like 'invoke', not a proper mouse click
|
11
|
+
def click
|
12
|
+
@automation_element.get_current_pattern(System::Windows::Automation::InvokePattern.pattern).invoke
|
17
13
|
end
|
18
14
|
end
|
19
15
|
end
|
@@ -3,29 +3,25 @@
|
|
3
3
|
module Bewildr
|
4
4
|
module ControlTypeAdditions
|
5
5
|
module ScrollAdditions
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
#the scroll back where it was before we started this nonsense.
|
15
|
-
def load_all_items_hack
|
16
|
-
return unless scrollable?
|
6
|
+
#required because when a list is displayed, UI Automation only knows
|
7
|
+
#about the visible items. This method stores where the scroll value is,
|
8
|
+
#then moves the scroller to the top of the scroll bar and proceeds to
|
9
|
+
#page-down until the bottom of the scroll bar is reached. At this point,
|
10
|
+
#UI Automation knows about all the items in the list and we can put
|
11
|
+
#the scroll back where it was before we started this nonsense.
|
12
|
+
def load_all_items_hack
|
13
|
+
return unless scrollable?
|
17
14
|
|
18
|
-
|
15
|
+
initial_scroll_value = vertical_scroll_percent
|
19
16
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
17
|
+
scroll_to 0.0
|
18
|
+
page_down_to_bottom_of_scroll_bar
|
19
|
+
scroll_to initial_scroll_value
|
20
|
+
end
|
24
21
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
end
|
22
|
+
#Scrolls down to the bottom, page by page
|
23
|
+
def page_down_to_bottom_of_scroll_bar
|
24
|
+
scroll_down_one_page while vertical_scroll_percent < 99.99
|
29
25
|
end
|
30
26
|
end
|
31
27
|
end
|
@@ -3,26 +3,26 @@
|
|
3
3
|
module Bewildr
|
4
4
|
module ControlTypeAdditions
|
5
5
|
module TabAdditions
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
end
|
6
|
+
#Selects the tab whose name matches the input
|
7
|
+
def select(input)
|
8
|
+
raise Bewildr::NoSuchTab unless tab_names.include?(input)
|
9
|
+
selectable_elements = tabs
|
10
|
+
selectable_elements.find {|selectable_element| selectable_element.name == input}.select
|
11
|
+
end
|
13
12
|
|
14
|
-
|
15
|
-
|
16
|
-
|
13
|
+
#Returns an array containing the tab items belonging to the tab control
|
14
|
+
def tabs
|
15
|
+
get(:type => :tab_item, :scope => :children, :how_many => :all)
|
16
|
+
end
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
18
|
+
#Returns a string array containing the names of all the tabs in the tab control
|
19
|
+
def tab_names
|
20
|
+
tabs.collect {|tab| tab.name}
|
21
|
+
end
|
21
22
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
end
|
23
|
+
#Returns the selected tab
|
24
|
+
def selected
|
25
|
+
tabs.find {|tab| tab.selected?}
|
26
26
|
end
|
27
27
|
end
|
28
28
|
end
|
@@ -3,13 +3,10 @@
|
|
3
3
|
module Bewildr
|
4
4
|
module ControlTypeAdditions
|
5
5
|
module TextAdditions
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
name
|
11
|
-
end
|
12
|
-
end
|
6
|
+
#Returns the element's text
|
7
|
+
def text
|
8
|
+
existence_check
|
9
|
+
name
|
13
10
|
end
|
14
11
|
end
|
15
12
|
end
|
@@ -3,54 +3,58 @@
|
|
3
3
|
module Bewildr
|
4
4
|
module ControlTypeAdditions
|
5
5
|
module TreeAdditions
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
end
|
6
|
+
#Returns an array containing the tree's root nodes
|
7
|
+
def root_nodes
|
8
|
+
prepare_element
|
9
|
+
get(:type => :tree_item, :scope => :children)
|
10
|
+
end
|
12
11
|
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
#Returns the root node
|
13
|
+
def root_node
|
14
|
+
root_nodes.first
|
15
|
+
end
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
17
|
+
#Selects the tree node described by the input, eg:
|
18
|
+
# select_node(["parent node", "child node"])
|
19
|
+
def select_node(path)
|
20
|
+
node(path).select
|
21
|
+
end
|
20
22
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
raise Bewildr::ElementDoesntExist if matching_node.nil?
|
37
|
-
if path.size != index + 1
|
38
|
-
matching_node.expand
|
39
|
-
current_nodes = matching_node.child_nodes
|
40
|
-
end
|
23
|
+
#Returns the tree node described by the input, eg:
|
24
|
+
# node(["parent node", "child node"])
|
25
|
+
def node(path)
|
26
|
+
current_nodes = root_nodes
|
27
|
+
matching_node = nil
|
28
|
+
path.each_with_index do |target_node, index|
|
29
|
+
case current_nodes
|
30
|
+
when Array
|
31
|
+
matching_node = current_nodes.find {|node| node.name == target_node} #TODO: make this work with regexes as well as strings...
|
32
|
+
raise Bewildr::ElementDoesntExist if matching_node.nil?
|
33
|
+
when Bewildr::Element
|
34
|
+
if current_nodes.name == target_node #TODO: make this work with regexes as well as strings...
|
35
|
+
matching_node = current_nodes
|
36
|
+
else
|
37
|
+
raise Bewildr::ElementDoesntExist
|
41
38
|
end
|
42
|
-
return matching_node
|
43
39
|
end
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
rescue ElementDoesntExist => e
|
50
|
-
return false
|
51
|
-
end
|
40
|
+
raise Bewildr::ElementDoesntExist if matching_node.nil?
|
41
|
+
if path.size != index + 1
|
42
|
+
matching_node.expand
|
43
|
+
load_all_items_hack
|
44
|
+
current_nodes = matching_node.child_nodes
|
52
45
|
end
|
53
46
|
end
|
47
|
+
return matching_node
|
48
|
+
end
|
49
|
+
|
50
|
+
#Returns true if the tree contains the item described by the input, false if it doesn't
|
51
|
+
def contains_node?(path)
|
52
|
+
begin
|
53
|
+
node(path)
|
54
|
+
return true
|
55
|
+
rescue ElementDoesntExist => e
|
56
|
+
return false
|
57
|
+
end
|
54
58
|
end
|
55
59
|
end
|
56
60
|
end
|
@@ -3,24 +3,21 @@
|
|
3
3
|
module Bewildr
|
4
4
|
module ControlTypeAdditions
|
5
5
|
module TreeItemAdditions
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
end
|
6
|
+
#Returns the tree item's child nodes
|
7
|
+
def child_nodes
|
8
|
+
get(:type => :tree_item, :scope => :children)
|
9
|
+
end
|
11
10
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
end
|
23
|
-
end
|
11
|
+
#horrible, but necessary - clickable point for tree items doesn't work like you think it would...
|
12
|
+
#I've added 7 to y and 22 to x... that's working for now... this is hardly the ideal solution...
|
13
|
+
#To see what's going on with the following code, take a look at a tree node under uispy - you'll
|
14
|
+
#understand - a picture paints a thousand words and all that.
|
15
|
+
def clickable_point
|
16
|
+
existence_check
|
17
|
+
ae_top_left_point = @automation_element.current.bounding_rectangle.top_left
|
18
|
+
ae_top_left_point.x += 22
|
19
|
+
ae_top_left_point.y += 7
|
20
|
+
ae_top_left_point
|
24
21
|
end
|
25
22
|
end
|
26
23
|
end
|
@@ -3,17 +3,15 @@
|
|
3
3
|
module Bewildr
|
4
4
|
module ControlTypeAdditions
|
5
5
|
module WindowAdditions
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
end
|
6
|
+
#Returns true if the window is open, false if it's not
|
7
|
+
def open?
|
8
|
+
exists?
|
9
|
+
end
|
11
10
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
end
|
11
|
+
#Waits up to 30 seconds for the window to close
|
12
|
+
def wait_for_close
|
13
|
+
Timeout::timeout(30) do
|
14
|
+
sleep 0.2 while open?
|
17
15
|
end
|
18
16
|
end
|
19
17
|
end
|
data/lib/bewildr/element.rb
CHANGED
@@ -177,6 +177,16 @@ module Bewildr
|
|
177
177
|
end
|
178
178
|
end
|
179
179
|
|
180
|
+
#Returns the height of the element in pixels
|
181
|
+
def height
|
182
|
+
@automation_element.current.bounding_rectangle.height.to_i
|
183
|
+
end
|
184
|
+
|
185
|
+
#Returns the width of the element in pixels
|
186
|
+
def width
|
187
|
+
@automation_element.current.bounding_rectangle.width.to_i
|
188
|
+
end
|
189
|
+
|
180
190
|
private
|
181
191
|
|
182
192
|
#Raises an exception if this element no longer exists
|
data/lib/bewildr/windows.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bewildr
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 15
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 10
|
10
|
+
version: 0.1.10
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Nat Ritmeyer
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-02-08 00:00:00 +00:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|