rautomation 2.0.1-x86-mingw32
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.
- checksums.yaml +7 -0
- data/.document +5 -0
- data/.gitignore +41 -0
- data/.rspec +2 -0
- data/.yardopts +8 -0
- data/CHANGES.md +276 -0
- data/Gemfile +3 -0
- data/LICENSE +20 -0
- data/README.md +142 -0
- data/Rakefile +73 -0
- data/ext/AutoItX/AutoItX.chm +0 -0
- data/ext/AutoItX/AutoItX3.dll +0 -0
- data/ext/IAccessibleDLL/IAccessibleDLL/IAccessibleDLL.cpp +30 -0
- data/ext/IAccessibleDLL/IAccessibleDLL/IAccessibleDLL.vcxproj +179 -0
- data/ext/IAccessibleDLL/IAccessibleDLL/IAccessibleDLL.vcxproj.filters +42 -0
- data/ext/IAccessibleDLL/IAccessibleDLL/IAccessibleDLL.vcxproj.user +3 -0
- data/ext/IAccessibleDLL/IAccessibleDLL/ReadMe.txt +48 -0
- data/ext/IAccessibleDLL/IAccessibleDLL/dllmain.cpp +19 -0
- data/ext/IAccessibleDLL/IAccessibleDLL/stdafx.cpp +8 -0
- data/ext/IAccessibleDLL/IAccessibleDLL/stdafx.h +22 -0
- data/ext/IAccessibleDLL/IAccessibleDLL/table_support.cpp +282 -0
- data/ext/IAccessibleDLL/IAccessibleDLL/targetver.h +8 -0
- data/ext/IAccessibleDLL/IAccessibleDLL.sln +31 -0
- data/ext/IAccessibleDLL/IAccessibleDLL.suo +0 -0
- data/ext/IAccessibleDLL/Release/IAccessibleDLL.dll +0 -0
- data/ext/UiaDll/RAutomation.UIA/Controls/Clicker.cs +63 -0
- data/ext/UiaDll/RAutomation.UIA/Controls/SelectList.cs +116 -0
- data/ext/UiaDll/RAutomation.UIA/Controls/Spinner.cs +46 -0
- data/ext/UiaDll/RAutomation.UIA/Controls/TabControl.cs +54 -0
- data/ext/UiaDll/RAutomation.UIA/Controls/TableControl.cs +132 -0
- data/ext/UiaDll/RAutomation.UIA/Controls/TextControl.cs +50 -0
- data/ext/UiaDll/RAutomation.UIA/Expander.cs +59 -0
- data/ext/UiaDll/RAutomation.UIA/Extensions/Element.cs +166 -0
- data/ext/UiaDll/RAutomation.UIA/Extensions/Enumerable.cs +76 -0
- data/ext/UiaDll/RAutomation.UIA/Extensions/Property.cs +27 -0
- data/ext/UiaDll/RAutomation.UIA/Properties/AssemblyInfo.cs +36 -0
- data/ext/UiaDll/RAutomation.UIA/Properties/AutomationProperties.cs +18 -0
- data/ext/UiaDll/RAutomation.UIA/RAutomation.UIA.csproj +77 -0
- data/ext/UiaDll/Release/RAutomation.UIA.dll +0 -0
- data/ext/UiaDll/Release/UiaDll.dll +0 -0
- data/ext/UiaDll/UiaDll/ArrayHelper.cpp +14 -0
- data/ext/UiaDll/UiaDll/ArrayHelper.h +7 -0
- data/ext/UiaDll/UiaDll/AssemblyInfo.cpp +40 -0
- data/ext/UiaDll/UiaDll/ControlMethods.cpp +16 -0
- data/ext/UiaDll/UiaDll/DynamicAssemblyResolver.cpp +24 -0
- data/ext/UiaDll/UiaDll/DynamicAssemblyResolver.h +16 -0
- data/ext/UiaDll/UiaDll/Locator.cpp +93 -0
- data/ext/UiaDll/UiaDll/Locator.h +55 -0
- data/ext/UiaDll/UiaDll/MenuItemSelector.cpp +75 -0
- data/ext/UiaDll/UiaDll/MenuItemSelector.h +24 -0
- data/ext/UiaDll/UiaDll/MenuMethods.cpp +62 -0
- data/ext/UiaDll/UiaDll/ReadMe.txt +38 -0
- data/ext/UiaDll/UiaDll/SelectListMethods.cpp +84 -0
- data/ext/UiaDll/UiaDll/SpinnerMethods.cpp +61 -0
- data/ext/UiaDll/UiaDll/StringHelper.cpp +57 -0
- data/ext/UiaDll/UiaDll/StringHelper.h +15 -0
- data/ext/UiaDll/UiaDll/StringMethods.cpp +8 -0
- data/ext/UiaDll/UiaDll/TabControlMethods.cpp +40 -0
- data/ext/UiaDll/UiaDll/TableMethods.cpp +108 -0
- data/ext/UiaDll/UiaDll/TextMethods.cpp +25 -0
- data/ext/UiaDll/UiaDll/ToggleStateHelper.h +10 -0
- data/ext/UiaDll/UiaDll/UiaDll.cpp +216 -0
- data/ext/UiaDll/UiaDll/UiaDll.h +13 -0
- data/ext/UiaDll/UiaDll/UiaDll.vcxproj +167 -0
- data/ext/UiaDll/UiaDll/UiaDll.vcxproj.filters +110 -0
- data/ext/UiaDll/UiaDll/app.ico +0 -0
- data/ext/UiaDll/UiaDll/app.rc +0 -0
- data/ext/UiaDll/UiaDll/dllmain.cpp +1 -0
- data/ext/UiaDll/UiaDll/resource.h +3 -0
- data/ext/UiaDll/UiaDll/stdafx.cpp +5 -0
- data/ext/UiaDll/UiaDll/stdafx.h +41 -0
- data/ext/UiaDll/UiaDll/targetver.h +8 -0
- data/ext/UiaDll/UiaDll.sln +57 -0
- data/ext/WindowsForms/.nuget/NuGet.Config +6 -0
- data/ext/WindowsForms/.nuget/NuGet.exe +0 -0
- data/ext/WindowsForms/.nuget/NuGet.targets +136 -0
- data/ext/WindowsForms/Release/FizzWare.NBuilder.dll +0 -0
- data/ext/WindowsForms/Release/UIA.Extensions.dll +0 -0
- data/ext/WindowsForms/Release/WindowsForms.exe +0 -0
- data/ext/WindowsForms/WindowsForms/AboutBox.Designer.cs +168 -0
- data/ext/WindowsForms/WindowsForms/AboutBox.cs +103 -0
- data/ext/WindowsForms/WindowsForms/AboutBox.resx +123 -0
- data/ext/WindowsForms/WindowsForms/DataEntryForm.Designer.cs +218 -0
- data/ext/WindowsForms/WindowsForms/DataEntryForm.cs +52 -0
- data/ext/WindowsForms/WindowsForms/DataEntryForm.resx +120 -0
- data/ext/WindowsForms/WindowsForms/DataGridView.Designer.cs +77 -0
- data/ext/WindowsForms/WindowsForms/DataGridView.cs +43 -0
- data/ext/WindowsForms/WindowsForms/DataGridView.resx +120 -0
- data/ext/WindowsForms/WindowsForms/FizzWare.NBuilder.dll +0 -0
- data/ext/WindowsForms/WindowsForms/MainFormWindow.Designer.cs +527 -0
- data/ext/WindowsForms/WindowsForms/MainFormWindow.cs +109 -0
- data/ext/WindowsForms/WindowsForms/MainFormWindow.resx +126 -0
- data/ext/WindowsForms/WindowsForms/PersonForm.Designer.cs +119 -0
- data/ext/WindowsForms/WindowsForms/PersonForm.cs +34 -0
- data/ext/WindowsForms/WindowsForms/PersonForm.resx +120 -0
- data/ext/WindowsForms/WindowsForms/Program.cs +21 -0
- data/ext/WindowsForms/WindowsForms/Properties/AssemblyInfo.cs +36 -0
- data/ext/WindowsForms/WindowsForms/Properties/Resources.Designer.cs +71 -0
- data/ext/WindowsForms/WindowsForms/Properties/Resources.resx +117 -0
- data/ext/WindowsForms/WindowsForms/Properties/Settings.Designer.cs +30 -0
- data/ext/WindowsForms/WindowsForms/Properties/Settings.settings +7 -0
- data/ext/WindowsForms/WindowsForms/SimpleElementsForm.Designer.cs +93 -0
- data/ext/WindowsForms/WindowsForms/SimpleElementsForm.cs +19 -0
- data/ext/WindowsForms/WindowsForms/SimpleElementsForm.resx +120 -0
- data/ext/WindowsForms/WindowsForms/UIA.Extensions.dll +0 -0
- data/ext/WindowsForms/WindowsForms/ValueMonthCalendar.cs +28 -0
- data/ext/WindowsForms/WindowsForms/WindowsForms.csproj +166 -0
- data/ext/WindowsForms/WindowsForms/packages.config +4 -0
- data/ext/WindowsForms/WindowsForms.sln +46 -0
- data/lib/rautomation/adapter/autoit/button.rb +59 -0
- data/lib/rautomation/adapter/autoit/locators.rb +22 -0
- data/lib/rautomation/adapter/autoit/mouse.rb +38 -0
- data/lib/rautomation/adapter/autoit/text_field.rb +70 -0
- data/lib/rautomation/adapter/autoit/window.rb +197 -0
- data/lib/rautomation/adapter/autoit.rb +8 -0
- data/lib/rautomation/adapter/helper.rb +64 -0
- data/lib/rautomation/adapter/ms_uia/button.rb +21 -0
- data/lib/rautomation/adapter/ms_uia/button_helper.rb +19 -0
- data/lib/rautomation/adapter/ms_uia/checkbox.rb +23 -0
- data/lib/rautomation/adapter/ms_uia/constants.rb +111 -0
- data/lib/rautomation/adapter/ms_uia/control.rb +134 -0
- data/lib/rautomation/adapter/ms_uia/functions.rb +279 -0
- data/lib/rautomation/adapter/ms_uia/keys.rb +121 -0
- data/lib/rautomation/adapter/ms_uia/keystroke_converter.rb +122 -0
- data/lib/rautomation/adapter/ms_uia/label.rb +18 -0
- data/lib/rautomation/adapter/ms_uia/list_box.rb +46 -0
- data/lib/rautomation/adapter/ms_uia/list_item.rb +22 -0
- data/lib/rautomation/adapter/ms_uia/locators.rb +23 -0
- data/lib/rautomation/adapter/ms_uia/menu.rb +36 -0
- data/lib/rautomation/adapter/ms_uia/radio.rb +23 -0
- data/lib/rautomation/adapter/ms_uia/select_list.rb +85 -0
- data/lib/rautomation/adapter/ms_uia/spinner.rb +31 -0
- data/lib/rautomation/adapter/ms_uia/tab_control.rb +46 -0
- data/lib/rautomation/adapter/ms_uia/table.rb +140 -0
- data/lib/rautomation/adapter/ms_uia/text_field.rb +39 -0
- data/lib/rautomation/adapter/ms_uia/uia_dll.rb +428 -0
- data/lib/rautomation/adapter/ms_uia/value_control.rb +21 -0
- data/lib/rautomation/adapter/ms_uia/window.rb +289 -0
- data/lib/rautomation/adapter/ms_uia.rb +27 -0
- data/lib/rautomation/adapter/win_32/button.rb +14 -0
- data/lib/rautomation/adapter/win_32/button_helper.rb +24 -0
- data/lib/rautomation/adapter/win_32/checkbox.rb +14 -0
- data/lib/rautomation/adapter/win_32/constants.rb +73 -0
- data/lib/rautomation/adapter/win_32/control.rb +86 -0
- data/lib/rautomation/adapter/win_32/functions.rb +336 -0
- data/lib/rautomation/adapter/win_32/keys.rb +146 -0
- data/lib/rautomation/adapter/win_32/label.rb +10 -0
- data/lib/rautomation/adapter/win_32/list_box.rb +40 -0
- data/lib/rautomation/adapter/win_32/locators.rb +22 -0
- data/lib/rautomation/adapter/win_32/mouse.rb +59 -0
- data/lib/rautomation/adapter/win_32/password_field.rb +15 -0
- data/lib/rautomation/adapter/win_32/radio.rb +11 -0
- data/lib/rautomation/adapter/win_32/select_list.rb +97 -0
- data/lib/rautomation/adapter/win_32/table.rb +25 -0
- data/lib/rautomation/adapter/win_32/text_field.rb +52 -0
- data/lib/rautomation/adapter/win_32/window.rb +277 -0
- data/lib/rautomation/adapter/win_32.rb +23 -0
- data/lib/rautomation/button.rb +55 -0
- data/lib/rautomation/element_collections.rb +55 -0
- data/lib/rautomation/platform.rb +15 -0
- data/lib/rautomation/text_field.rb +60 -0
- data/lib/rautomation/version.rb +3 -0
- data/lib/rautomation/wait_helper.rb +23 -0
- data/lib/rautomation/window.rb +248 -0
- data/lib/rautomation.rb +8 -0
- data/rautomation.gemspec +52 -0
- data/spec/adapter/autoit/mouse_spec.rb +53 -0
- data/spec/adapter/autoit/window_spec.rb +17 -0
- data/spec/adapter/ms_uia/button_spec.rb +39 -0
- data/spec/adapter/ms_uia/checkbox_spec.rb +55 -0
- data/spec/adapter/ms_uia/control_spec.rb +88 -0
- data/spec/adapter/ms_uia/functions_spec.rb +39 -0
- data/spec/adapter/ms_uia/keystroke_converter_spec.rb +48 -0
- data/spec/adapter/ms_uia/label_spec.rb +18 -0
- data/spec/adapter/ms_uia/list_item_spec.rb +14 -0
- data/spec/adapter/ms_uia/listbox_spec.rb +73 -0
- data/spec/adapter/ms_uia/radio_spec.rb +39 -0
- data/spec/adapter/ms_uia/select_list_spec.rb +118 -0
- data/spec/adapter/ms_uia/spinner_spec.rb +44 -0
- data/spec/adapter/ms_uia/tab_control_spec.rb +53 -0
- data/spec/adapter/ms_uia/table_spec.rb +197 -0
- data/spec/adapter/ms_uia/text_field_spec.rb +43 -0
- data/spec/adapter/ms_uia/value_control_spec.rb +11 -0
- data/spec/adapter/ms_uia/window_spec.rb +81 -0
- data/spec/adapter/win_32/button_spec.rb +31 -0
- data/spec/adapter/win_32/checkbox_spec.rb +46 -0
- data/spec/adapter/win_32/label_spec.rb +13 -0
- data/spec/adapter/win_32/listbox_spec.rb +41 -0
- data/spec/adapter/win_32/mouse_spec.rb +49 -0
- data/spec/adapter/win_32/radio_spec.rb +33 -0
- data/spec/adapter/win_32/select_list_spec.rb +65 -0
- data/spec/adapter/win_32/table_spec.rb +27 -0
- data/spec/adapter/win_32/text_field_spec.rb +24 -0
- data/spec/adapter/win_32/window_spec.rb +61 -0
- data/spec/button_spec.rb +67 -0
- data/spec/buttons_spec.rb +21 -0
- data/spec/spec_helper.rb +128 -0
- data/spec/text_field_spec.rb +64 -0
- data/spec/text_fields_spec.rb +22 -0
- data/spec/window_spec.rb +150 -0
- data/spec/windows_spec.rb +76 -0
- metadata +369 -0
@@ -0,0 +1,289 @@
|
|
1
|
+
module RAutomation
|
2
|
+
module Adapter
|
3
|
+
module MsUia
|
4
|
+
autoload :UiaDll, File.dirname(__FILE__) + "/uia_dll"
|
5
|
+
|
6
|
+
class Window
|
7
|
+
include WaitHelper
|
8
|
+
include Locators
|
9
|
+
extend ElementCollections
|
10
|
+
|
11
|
+
has_many :controls
|
12
|
+
|
13
|
+
# Locators of the window.
|
14
|
+
attr_reader :locators
|
15
|
+
|
16
|
+
# Possible locators are :title, :text, :hwnd, :pid, :class and :index.
|
17
|
+
#todo - update list of valid locators for UIA
|
18
|
+
# Creates the window object.
|
19
|
+
# @note this method is not meant to be accessed directly, but only through {RAutomation::Window#initialize}!
|
20
|
+
# @param [Hash] locators for searching the window.
|
21
|
+
# @option locators [String, Regexp] :title Title of the window
|
22
|
+
# @option locators [String, Regexp] :text Visible text of the window
|
23
|
+
# @option locators [String, Regexp] :class Internal class name of the window
|
24
|
+
# @option locators [String, Integer] :hwnd Window handle in decimal format
|
25
|
+
# @option locators [String, Integer] :pid Window process ID (PID)
|
26
|
+
# @option locators [String, Integer] :index 0-based index to specify n-th window if all other criteria match
|
27
|
+
# all other criteria match
|
28
|
+
# @see RAutomation::Window#initialize
|
29
|
+
def initialize(container, locators)
|
30
|
+
@container = container
|
31
|
+
extract(locators)
|
32
|
+
end
|
33
|
+
|
34
|
+
#todo - replace with UIA version
|
35
|
+
# Retrieves handle of the window.
|
36
|
+
# @note Searches only for visible windows.
|
37
|
+
# @see RAutomation::Window#hwnd
|
38
|
+
def hwnd
|
39
|
+
@hwnd ||= Functions.window_hwnd(@locators)
|
40
|
+
end
|
41
|
+
|
42
|
+
#todo - replace with UIA version
|
43
|
+
# @see RAutomation::Window#pid
|
44
|
+
def pid
|
45
|
+
Functions.window_pid(hwnd)
|
46
|
+
end
|
47
|
+
|
48
|
+
#todo - replace with UIA version
|
49
|
+
# @see RAutomation::Window#title
|
50
|
+
def title
|
51
|
+
Functions.window_title(hwnd)
|
52
|
+
end
|
53
|
+
|
54
|
+
# @see RAutomation::Window#class_names
|
55
|
+
def class_names
|
56
|
+
classes = UiaDll::children_class_names(UiaDll::SearchCriteria.from_locator(hwnd, :hwnd => hwnd))
|
57
|
+
classes.delete_if(&:empty?).sort
|
58
|
+
end
|
59
|
+
|
60
|
+
# @see RAutomation::Window#activate
|
61
|
+
def activate
|
62
|
+
return if !exists? || active?
|
63
|
+
restore if minimized?
|
64
|
+
Functions.activate_window(hwnd)
|
65
|
+
restore if minimized?
|
66
|
+
sleep 1
|
67
|
+
end
|
68
|
+
|
69
|
+
#todo - replace with UIA version
|
70
|
+
# @see RAutomation::Window#active?
|
71
|
+
def active?
|
72
|
+
exists? && Functions.foreground_window == hwnd
|
73
|
+
end
|
74
|
+
|
75
|
+
#todo - replace with UIA version
|
76
|
+
# @see RAutomation::Window#text
|
77
|
+
def text
|
78
|
+
Functions.window_text(hwnd)
|
79
|
+
end
|
80
|
+
|
81
|
+
#todo - replace with UIA version
|
82
|
+
# @see RAutomation::Window#exists?
|
83
|
+
def exists?
|
84
|
+
hwnd && Functions.window_exists(hwnd)
|
85
|
+
end
|
86
|
+
|
87
|
+
#todo - replace with UIA version
|
88
|
+
# @see RAutomation::Window#visible?
|
89
|
+
def visible?
|
90
|
+
Functions.window_visible(hwnd)
|
91
|
+
end
|
92
|
+
|
93
|
+
#todo - replace with UIA version
|
94
|
+
# @see RAutomation::Window#maximize
|
95
|
+
def maximize
|
96
|
+
Functions.show_window(hwnd, Constants::SW_MAXIMIZE)
|
97
|
+
sleep 1
|
98
|
+
end
|
99
|
+
|
100
|
+
#todo - replace with UIA version
|
101
|
+
# @see RAutomation::Window#minimize
|
102
|
+
def minimize
|
103
|
+
Functions.show_window(hwnd, Constants::SW_MINIMIZE)
|
104
|
+
sleep 1
|
105
|
+
end
|
106
|
+
|
107
|
+
#todo - replace with UIA version
|
108
|
+
# @see RAutomation::Window#minimized?
|
109
|
+
def minimized?
|
110
|
+
Functions.minimized(hwnd)
|
111
|
+
end
|
112
|
+
|
113
|
+
#todo - replace with UIA version
|
114
|
+
# @see RAutomation::Window#restore
|
115
|
+
def restore
|
116
|
+
Functions.show_window(hwnd, Constants::SW_RESTORE)
|
117
|
+
sleep 1
|
118
|
+
end
|
119
|
+
|
120
|
+
# Activates the window and sends keys to it.
|
121
|
+
#
|
122
|
+
# @example
|
123
|
+
# RAutomation::Window.new(:title => //).send_keys "hello!"
|
124
|
+
# RAutomation::Window.new(:title => //).send_keys [:control, "a"], "world!"
|
125
|
+
# Refer to {Keys::KEYS} for all the special keycodes.
|
126
|
+
# @see RAutomation::Window#send_keys
|
127
|
+
def send_keys(args)
|
128
|
+
Keys.encode(args).each do |arg|
|
129
|
+
wait_until do
|
130
|
+
activate
|
131
|
+
active?
|
132
|
+
end
|
133
|
+
|
134
|
+
if arg.is_a?(Array)
|
135
|
+
arg.reduce([]) do |pressed_keys, k|
|
136
|
+
if k == Keys[:null]
|
137
|
+
pressed_keys.each {|pressed_key| release_key pressed_key}
|
138
|
+
pressed_keys = []
|
139
|
+
else
|
140
|
+
pressed_keys << press_key(k)
|
141
|
+
end
|
142
|
+
pressed_keys
|
143
|
+
end
|
144
|
+
else
|
145
|
+
send_key arg
|
146
|
+
end
|
147
|
+
end
|
148
|
+
sleep 1
|
149
|
+
end
|
150
|
+
|
151
|
+
#todo - replace with UIA version
|
152
|
+
# @see RAutomation::Window#close
|
153
|
+
def close
|
154
|
+
Functions.close_window(hwnd)
|
155
|
+
end
|
156
|
+
|
157
|
+
# @see Button#initialize
|
158
|
+
# @see RAutomation::Window#button
|
159
|
+
def button(locator)
|
160
|
+
Button.new(self, locator)
|
161
|
+
end
|
162
|
+
|
163
|
+
def value_control(locator)
|
164
|
+
ValueControl.new(self, locator)
|
165
|
+
end
|
166
|
+
|
167
|
+
# @see TabControl#initialize
|
168
|
+
def tab_control(locator)
|
169
|
+
TabControl.new(self, locator)
|
170
|
+
end
|
171
|
+
|
172
|
+
# @see Spinner#initialize
|
173
|
+
def spinner(locator)
|
174
|
+
Spinner.new(self, locator)
|
175
|
+
end
|
176
|
+
|
177
|
+
# @see TextField#initialize
|
178
|
+
# @see RAutomation::Window#text_field
|
179
|
+
def text_field(locator)
|
180
|
+
TextField.new(self, locator)
|
181
|
+
end
|
182
|
+
|
183
|
+
# Returns a {Menu} object use to build a path to a menu item to open.
|
184
|
+
# @param [Hash] locator for the {Menu}. Only :text is allowed.
|
185
|
+
def menu(locator)
|
186
|
+
Menu.new(self, locator)
|
187
|
+
end
|
188
|
+
|
189
|
+
# Redirects all method calls not part of the public API to the {Functions} directly.
|
190
|
+
# @see RAutomation::Window#method_missing
|
191
|
+
def method_missing(name, *args)
|
192
|
+
Functions.respond_to?(name) ? Functions.send(name, *args) : super
|
193
|
+
end
|
194
|
+
|
195
|
+
def bounding_rectangle
|
196
|
+
window = UiaDll::element_from_handle(hwnd)
|
197
|
+
|
198
|
+
boundary = FFI::MemoryPointer.new :long, 4
|
199
|
+
UiaDll::bounding_rectangle(window, boundary)
|
200
|
+
|
201
|
+
boundary.read_array_of_long(4)
|
202
|
+
end
|
203
|
+
|
204
|
+
def move_mouse(x, y)
|
205
|
+
UiaDll::move_mouse(x, y)
|
206
|
+
end
|
207
|
+
|
208
|
+
def click_mouse()
|
209
|
+
UiaDll::click_mouse
|
210
|
+
end
|
211
|
+
|
212
|
+
def label(locator)
|
213
|
+
@container.wait_until_present
|
214
|
+
Label.new(self, locator)
|
215
|
+
end
|
216
|
+
|
217
|
+
def control(locator)
|
218
|
+
@container.wait_until_present
|
219
|
+
Control.new(self, locator)
|
220
|
+
end
|
221
|
+
|
222
|
+
def controls(locator)
|
223
|
+
@container.wait_until_present
|
224
|
+
Controls.new(self, locator)
|
225
|
+
end
|
226
|
+
|
227
|
+
def list_box(locator)
|
228
|
+
@container.wait_until_present
|
229
|
+
ListBox.new(self, locator)
|
230
|
+
end
|
231
|
+
|
232
|
+
def list_item(locator)
|
233
|
+
@container.wait_until_present
|
234
|
+
ListItem.new(self, locator)
|
235
|
+
end
|
236
|
+
|
237
|
+
def select_list(locator)
|
238
|
+
@container.wait_until_present
|
239
|
+
SelectList.new(self, locator)
|
240
|
+
end
|
241
|
+
|
242
|
+
def checkbox(locator)
|
243
|
+
@container.wait_until_present
|
244
|
+
Checkbox.new(self, locator)
|
245
|
+
end
|
246
|
+
|
247
|
+
def radio(locator)
|
248
|
+
@container.wait_until_present
|
249
|
+
Radio.new(self, locator)
|
250
|
+
end
|
251
|
+
|
252
|
+
def table(locator)
|
253
|
+
@container.wait_until_present
|
254
|
+
Table.new(self, locator)
|
255
|
+
end
|
256
|
+
|
257
|
+
#todo - replace with UIA version
|
258
|
+
# Creates the child window object.
|
259
|
+
# @note This is an Win32 adapter specific method, not part of the public API
|
260
|
+
# @example
|
261
|
+
# RAutomation::Window.new(:title => /Windows Internet Explorer/i).
|
262
|
+
# child(:title => /some popup/)
|
263
|
+
# @param (see Window#initialize)
|
264
|
+
# @return [RAutomation::Window] child window, popup or regular window.
|
265
|
+
def child(locators)
|
266
|
+
RAutomation::Window.new Functions.child_window_locators(hwnd, locators)
|
267
|
+
end
|
268
|
+
|
269
|
+
private
|
270
|
+
|
271
|
+
def press_key key
|
272
|
+
Functions.send_key(key, 0, 0, nil)
|
273
|
+
key
|
274
|
+
end
|
275
|
+
|
276
|
+
def release_key key
|
277
|
+
Functions.send_key(key, 0, Constants::KEYEVENTF_KEYUP, nil)
|
278
|
+
key
|
279
|
+
end
|
280
|
+
|
281
|
+
def send_key key
|
282
|
+
press_key key
|
283
|
+
release_key key
|
284
|
+
key
|
285
|
+
end
|
286
|
+
end
|
287
|
+
end
|
288
|
+
end
|
289
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
begin
|
2
|
+
gem "ffi"
|
3
|
+
rescue Gem::LoadError
|
4
|
+
raise Gem::LoadError, "Unable to load FFI gem. Install it with:\n\tgem install ffi"
|
5
|
+
end
|
6
|
+
require "ffi"
|
7
|
+
require File.dirname(__FILE__) + "/ms_uia/constants"
|
8
|
+
require File.dirname(__FILE__) + "/ms_uia/keys"
|
9
|
+
require File.dirname(__FILE__) + "/ms_uia/keystroke_converter"
|
10
|
+
require File.dirname(__FILE__) + "/ms_uia/functions"
|
11
|
+
require File.dirname(__FILE__) + "/ms_uia/locators"
|
12
|
+
require File.dirname(__FILE__) + "/ms_uia/window"
|
13
|
+
require File.dirname(__FILE__) + "/ms_uia/button_helper"
|
14
|
+
require File.dirname(__FILE__) + "/ms_uia/control"
|
15
|
+
require File.dirname(__FILE__) + "/ms_uia/value_control"
|
16
|
+
require File.dirname(__FILE__) + "/ms_uia/button"
|
17
|
+
require File.dirname(__FILE__) + "/ms_uia/checkbox"
|
18
|
+
require File.dirname(__FILE__) + "/ms_uia/menu"
|
19
|
+
require File.dirname(__FILE__) + "/ms_uia/radio"
|
20
|
+
require File.dirname(__FILE__) + "/ms_uia/text_field"
|
21
|
+
require File.dirname(__FILE__) + "/ms_uia/select_list"
|
22
|
+
require File.dirname(__FILE__) + "/ms_uia/spinner"
|
23
|
+
require File.dirname(__FILE__) + "/ms_uia/table"
|
24
|
+
require File.dirname(__FILE__) + "/ms_uia/tab_control"
|
25
|
+
require File.dirname(__FILE__) + "/ms_uia/label"
|
26
|
+
require File.dirname(__FILE__) + "/ms_uia/list_box"
|
27
|
+
require File.dirname(__FILE__) + "/ms_uia/list_item"
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module RAutomation
|
2
|
+
module Adapter
|
3
|
+
module Win32
|
4
|
+
module ButtonHelper
|
5
|
+
|
6
|
+
def set?
|
7
|
+
control_hwnd = Functions.control_hwnd(@window.hwnd, @locators)
|
8
|
+
Functions.control_set? control_hwnd
|
9
|
+
end
|
10
|
+
|
11
|
+
# @todo call a windows function to do this without clicking
|
12
|
+
def clear
|
13
|
+
click {!set?} if set?
|
14
|
+
end
|
15
|
+
|
16
|
+
# @todo call a windows function to do this without clicking
|
17
|
+
def set
|
18
|
+
click {set?} unless set?
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module RAutomation
|
2
|
+
module Adapter
|
3
|
+
module Win32
|
4
|
+
# @private
|
5
|
+
module Constants
|
6
|
+
WM_GETTEXT = 0xD
|
7
|
+
WM_SETTEXT = 0xC
|
8
|
+
WM_GETTEXTLENGTH = 0xE
|
9
|
+
WM_CLOSE = 0x10
|
10
|
+
|
11
|
+
SW_MAXIMIZE = 3
|
12
|
+
SW_MINIMIZE = 6
|
13
|
+
SW_RESTORE = 9
|
14
|
+
|
15
|
+
SMTO_ABORTIFHUNG = 0x2
|
16
|
+
|
17
|
+
STANDARD_RIGHTS_REQUIRED = 0xF0000
|
18
|
+
SYNCHRONIZE = 0x100000
|
19
|
+
PROCESS_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFF
|
20
|
+
|
21
|
+
BM_CLICK = 0xF5
|
22
|
+
BM_GETSTATE = 0xF2
|
23
|
+
BST_CHECKED = 0x1
|
24
|
+
|
25
|
+
# keybd_event constants
|
26
|
+
KEYEVENTF_EXTENDEDKEY = 0x1
|
27
|
+
KEYEVENTF_KEYUP = 0x2
|
28
|
+
|
29
|
+
# GetWindow constants
|
30
|
+
GW_ENABLEDPOPUP = 6
|
31
|
+
|
32
|
+
# HRESULT
|
33
|
+
S_OK = 0
|
34
|
+
|
35
|
+
# IAccessible Button States
|
36
|
+
STATE_SYSTEM_UNAVAILABLE = 0x00000001
|
37
|
+
STATE_SYSTEM_SELECTED = 0x00000002
|
38
|
+
STATE_SYSTEM_FOCUSED = 0x00000004
|
39
|
+
STATE_SYSTEM_CHECKED = 0x00000010
|
40
|
+
|
41
|
+
# Combobox
|
42
|
+
CB_GETCOUNT = 0x0146
|
43
|
+
CB_GETTOPINDEX = 0x015b
|
44
|
+
CB_GETLBTEXTLEN = 0x0149
|
45
|
+
CB_GETLBTEXT = 0x0148
|
46
|
+
CB_GETCURSEL = 0x0147
|
47
|
+
CB_GETDROPPEDCONTROLRECT = 0x0152
|
48
|
+
CB_GETITEMHEIGHT = 0x0154
|
49
|
+
CB_ERR = -1
|
50
|
+
CB_SETCURSEL = 0x14E
|
51
|
+
CB_SELECTSTRING = 0x14D
|
52
|
+
CB_SETEDITSEL = 0x142
|
53
|
+
|
54
|
+
# listview
|
55
|
+
LVM_FIRST = 0x1000
|
56
|
+
LVM_GETITEMCOUNT = LVM_FIRST + 4
|
57
|
+
|
58
|
+
# listbox
|
59
|
+
LB_GETCOUNT = 0x18b
|
60
|
+
LB_GETTEXT = 0x189
|
61
|
+
LB_GETTEXTLEN = 0x18a
|
62
|
+
LB_SETCURSEL = 0x186
|
63
|
+
LB_GETSEL = 0x187
|
64
|
+
|
65
|
+
# SendInput
|
66
|
+
INPUT_MOUSE = 0
|
67
|
+
MOUSEEVENTF_LEFTDOWN = 0x2
|
68
|
+
MOUSEEVENTF_LEFTUP = 0x4
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module RAutomation
|
2
|
+
module Adapter
|
3
|
+
module Win32
|
4
|
+
class Control
|
5
|
+
include WaitHelper
|
6
|
+
include Locators
|
7
|
+
|
8
|
+
# Creates the control object.
|
9
|
+
# @note this method is not meant to be accessed directly
|
10
|
+
# @param [RAutomation::Window] window this button belongs to.
|
11
|
+
# @param [Hash] locators for searching the button.
|
12
|
+
# @option locators [String, Regexp] :value Value (text) of the button
|
13
|
+
# @option locators [String, Regexp] :class Internal class name of the button
|
14
|
+
# @option locators [String, Integer] :id Internal ID of the button
|
15
|
+
# @option locators [String, Integer] :index 0-based index to specify n-th button if all other criteria match
|
16
|
+
# @see RAutomation::Window#button
|
17
|
+
def initialize(window, locators)
|
18
|
+
@window = window
|
19
|
+
extract(locators)
|
20
|
+
end
|
21
|
+
|
22
|
+
def hwnd
|
23
|
+
Functions.control_hwnd(@window.hwnd, @locators)
|
24
|
+
end
|
25
|
+
|
26
|
+
def class_name
|
27
|
+
Functions.control_class(hwnd)
|
28
|
+
end
|
29
|
+
|
30
|
+
def click
|
31
|
+
assert_enabled
|
32
|
+
clicked = false
|
33
|
+
wait_until do
|
34
|
+
@window.activate
|
35
|
+
@window.active? &&
|
36
|
+
focus &&
|
37
|
+
Functions.control_click(hwnd) &&
|
38
|
+
clicked = true # is clicked at least once
|
39
|
+
|
40
|
+
block_given? ? yield : clicked && !exist?
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def hwnd
|
45
|
+
Functions.control_hwnd(@window.hwnd, @locators)
|
46
|
+
end
|
47
|
+
|
48
|
+
def exist?
|
49
|
+
!!hwnd
|
50
|
+
rescue UnknownElementException
|
51
|
+
false
|
52
|
+
end
|
53
|
+
|
54
|
+
alias_method :exists?, :exist?
|
55
|
+
|
56
|
+
def enabled?
|
57
|
+
!disabled?
|
58
|
+
end
|
59
|
+
|
60
|
+
def disabled?
|
61
|
+
Functions.unavailable? hwnd
|
62
|
+
end
|
63
|
+
|
64
|
+
def focus
|
65
|
+
assert_enabled
|
66
|
+
@window.activate
|
67
|
+
Functions.set_control_focus hwnd
|
68
|
+
end
|
69
|
+
|
70
|
+
def focused?
|
71
|
+
Functions.has_focus?(hwnd)
|
72
|
+
end
|
73
|
+
|
74
|
+
def value
|
75
|
+
Functions.control_value(hwnd)
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
def assert_enabled
|
81
|
+
raise "Cannot interact with disabled control #{@locators.inspect} on window #{@window.locators.inspect}!" if disabled?
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|