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,70 @@
|
|
1
|
+
module RAutomation
|
2
|
+
module Adapter
|
3
|
+
module Autoit
|
4
|
+
class TextField
|
5
|
+
include WaitHelper
|
6
|
+
include Locators
|
7
|
+
|
8
|
+
# Default locators used for searching text fields.
|
9
|
+
DEFAULT_LOCATORS = {:class => /edit/i}
|
10
|
+
|
11
|
+
# @private
|
12
|
+
# Special-cased locators
|
13
|
+
LOCATORS = {
|
14
|
+
[:class, Regexp] => :regexpclass,
|
15
|
+
:index => :instance,
|
16
|
+
:value => :text
|
17
|
+
}
|
18
|
+
|
19
|
+
# Creates the text field object.
|
20
|
+
# @note this method is not meant to be accessed directly, but only through {RAutomation::Window#text_field}!
|
21
|
+
# @param [RAutomation::Window] window this text field belongs to.
|
22
|
+
# @param [Hash] locators for searching the text field.
|
23
|
+
# @option locators [String, Regexp] :class Internal class name of the text field
|
24
|
+
# @option locators [String, Regexp] :value Value (text) of the text field
|
25
|
+
# @option locators [String, Integer] :id Internal ID of the text field
|
26
|
+
# @option locators [String, Integer] :index 0-based index to specify n-th text field if all other criteria match
|
27
|
+
# @see RAutomation::Window#text_field
|
28
|
+
def initialize(window, locators)
|
29
|
+
@window = window
|
30
|
+
extract(locators)
|
31
|
+
end
|
32
|
+
|
33
|
+
def hwnd
|
34
|
+
Window.autoit.ControlGetHandle(@window.locator_hwnd, "", @autoit_locators).hex
|
35
|
+
end
|
36
|
+
|
37
|
+
# @see RAutomation::TextField#set
|
38
|
+
def set(text)
|
39
|
+
wait_until do
|
40
|
+
@window.activate
|
41
|
+
@window.active? &&
|
42
|
+
Window.autoit.ControlFocus(@window.locator_hwnd, "", @autoit_locators) == 1 &&
|
43
|
+
Window.autoit.ControlSetText(@window.locator_hwnd, "", @autoit_locators, text) == 1 &&
|
44
|
+
value == text
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# @see RAutomation::TextField#clear
|
49
|
+
def clear
|
50
|
+
set ""
|
51
|
+
end
|
52
|
+
|
53
|
+
# @see RAutomation::TextField#value
|
54
|
+
def value
|
55
|
+
Window.autoit.ControlGetText(@window.locator_hwnd, "", @autoit_locators)
|
56
|
+
end
|
57
|
+
|
58
|
+
# @see RAutomation::TextField#exists?
|
59
|
+
def exists?
|
60
|
+
hwnd != 0
|
61
|
+
end
|
62
|
+
|
63
|
+
def hwnd
|
64
|
+
handle = Window.autoit.ControlGetHandle(@window.locator_hwnd, "", @autoit_locators)
|
65
|
+
handle.to_i(16)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,197 @@
|
|
1
|
+
module RAutomation
|
2
|
+
module Adapter
|
3
|
+
module Autoit
|
4
|
+
class Window
|
5
|
+
include WaitHelper
|
6
|
+
include Locators
|
7
|
+
|
8
|
+
class << self
|
9
|
+
# @private
|
10
|
+
def autoit
|
11
|
+
@@autoit
|
12
|
+
end
|
13
|
+
|
14
|
+
# @private
|
15
|
+
def load_autoit
|
16
|
+
@@autoit = WIN32OLE.new('AutoItX3.Control')
|
17
|
+
rescue WIN32OLERuntimeError
|
18
|
+
dll = File.dirname(__FILE__) + "/../../../../ext/AutoItX/AutoItX3.dll"
|
19
|
+
unless system("regsvr32.exe /s #{dll.gsub('/', '\\')}")
|
20
|
+
raise "Start Ruby with administrative rights when using AutoIt adapter for the first time."
|
21
|
+
end
|
22
|
+
@@autoit = WIN32OLE.new('AutoItX3.Control')
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
load_autoit
|
27
|
+
@@autoit.AutoItSetOption("WinWaitDelay", 350)
|
28
|
+
|
29
|
+
# Locators of the window.
|
30
|
+
attr_reader :locators
|
31
|
+
|
32
|
+
# @private
|
33
|
+
# Special-cased locators
|
34
|
+
LOCATORS = {
|
35
|
+
[:title, Regexp] => :regexptitle,
|
36
|
+
:index => :instance,
|
37
|
+
:hwnd => :handle
|
38
|
+
}
|
39
|
+
|
40
|
+
# Creates the window object.
|
41
|
+
# @note this method is not meant to be accessed directly, but only through {RAutomation::Window#initialize}!
|
42
|
+
# @param [Hash] locators for searching the window.
|
43
|
+
# @option locators [String, Regexp] :title Title of the window
|
44
|
+
# @option locators [String, Regexp] :text Visible text of the window
|
45
|
+
# @option locators [String, Regexp] :class Internal class name of the window
|
46
|
+
# @option locators [String, Integer] :hwnd Window handle in decimal format
|
47
|
+
# @option locators [String, Integer] :index 0-based index to specify n-th window if all other criteria match
|
48
|
+
# @see RAutomation::Window#initialize
|
49
|
+
def initialize(container, locators)
|
50
|
+
@container = container
|
51
|
+
@hwnd = locators[:hwnd]
|
52
|
+
@locator_index = locators.delete(:index) if locators[:index] && locators.size == 1
|
53
|
+
@locator_pid = locators.delete(:pid).to_i if locators[:pid]
|
54
|
+
@locator_text = locators.delete(:text)
|
55
|
+
extract(locators)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Retrieves handle of the window.
|
59
|
+
# @note Searches only for visible windows.
|
60
|
+
# @see RAutomation::Window#hwnd
|
61
|
+
def hwnd
|
62
|
+
@hwnd ||= begin
|
63
|
+
locators = @autoit_locators
|
64
|
+
if @locator_index || @locator_pid
|
65
|
+
# @todo Come up with some better solution for this case
|
66
|
+
locators = "[regexptitle:]" # match all, needed for the case when only :index or :pid is used
|
67
|
+
end
|
68
|
+
windows = @@autoit.WinList(locators, @locator_text).pop.compact.
|
69
|
+
map { |handle| RAutomation::Window.new(:hwnd => handle.hex) }
|
70
|
+
windows.delete_if { |window| !window.visible? }
|
71
|
+
|
72
|
+
if @locator_pid
|
73
|
+
window = windows.find { |win| win.pid == @locator_pid }
|
74
|
+
else
|
75
|
+
window = windows[@locator_index || 0]
|
76
|
+
end
|
77
|
+
window ? window.hwnd : nil
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# @see RAutomation::Window#pid
|
82
|
+
def pid
|
83
|
+
@@autoit.WinGetProcess(locator_hwnd).to_i
|
84
|
+
end
|
85
|
+
|
86
|
+
# @see RAutomation::Window#title
|
87
|
+
def title
|
88
|
+
@@autoit.WinGetTitle(locator_hwnd)
|
89
|
+
end
|
90
|
+
|
91
|
+
# @see RAutomation::Window#class_names
|
92
|
+
def class_names
|
93
|
+
@@autoit.WinGetClassList(locator_hwnd).split("\n").sort
|
94
|
+
end
|
95
|
+
|
96
|
+
# @see RAutomation::Window#activate
|
97
|
+
def activate
|
98
|
+
@@autoit.WinWait(locator_hwnd, "", 1)
|
99
|
+
@@autoit.WinActivate(locator_hwnd)
|
100
|
+
sleep 1
|
101
|
+
end
|
102
|
+
|
103
|
+
# @see RAutomation::Window#active?
|
104
|
+
def active?
|
105
|
+
@@autoit.WinActive(locator_hwnd) == 1
|
106
|
+
end
|
107
|
+
|
108
|
+
# @see RAutomation::Window#text
|
109
|
+
def text
|
110
|
+
@@autoit.WinGetText(locator_hwnd)
|
111
|
+
end
|
112
|
+
|
113
|
+
# @see RAutomation::Window#exists?
|
114
|
+
def exists?
|
115
|
+
@@autoit.WinExists(locator_hwnd) == 1
|
116
|
+
end
|
117
|
+
|
118
|
+
# @see RAutomation::Window#visible?
|
119
|
+
def visible?
|
120
|
+
@@autoit.WinGetState(locator_hwnd) & 2 == 2
|
121
|
+
end
|
122
|
+
|
123
|
+
# @see RAutomation::Window#maximize
|
124
|
+
def maximize
|
125
|
+
@@autoit.WinSetState(locator_hwnd, "", @@autoit.SW_MAXIMIZE)
|
126
|
+
sleep 1
|
127
|
+
end
|
128
|
+
|
129
|
+
# @see RAutomation::Window#minimize
|
130
|
+
def minimize
|
131
|
+
@@autoit.WinSetState(locator_hwnd, "", @@autoit.SW_MINIMIZE)
|
132
|
+
sleep 1
|
133
|
+
end
|
134
|
+
|
135
|
+
# @see RAutomation::Window#minimized?
|
136
|
+
def minimized?
|
137
|
+
@@autoit.WinGetState(locator_hwnd) & 16 == 16
|
138
|
+
end
|
139
|
+
|
140
|
+
# @see RAutomation::Window#restore
|
141
|
+
def restore
|
142
|
+
@@autoit.WinSetState(locator_hwnd, "", @@autoit.SW_RESTORE)
|
143
|
+
sleep 1
|
144
|
+
end
|
145
|
+
|
146
|
+
# Activates the window and sends keys to it.
|
147
|
+
#
|
148
|
+
# Refer to AutoIt documentation at http://www.autoitscript.com/autoit3/docs/appendix/SendKeys.htm
|
149
|
+
# for keys syntax.
|
150
|
+
# @see RAutomation::Window#send_keys
|
151
|
+
def send_keys(keys)
|
152
|
+
wait_until do
|
153
|
+
activate
|
154
|
+
active?
|
155
|
+
end
|
156
|
+
@@autoit.Send(keys[0])
|
157
|
+
end
|
158
|
+
|
159
|
+
# @see RAutomation::Window#close
|
160
|
+
def close
|
161
|
+
@@autoit.WinClose(locator_hwnd)
|
162
|
+
@@autoit.WinKill(locator_hwnd)
|
163
|
+
end
|
164
|
+
|
165
|
+
def mouse
|
166
|
+
@container.wait_until_present
|
167
|
+
Mouse.new(self)
|
168
|
+
end
|
169
|
+
|
170
|
+
# @see Button#initialize
|
171
|
+
# @see RAutomation::Window#button
|
172
|
+
def button(locator={})
|
173
|
+
Button.new(self, locator)
|
174
|
+
end
|
175
|
+
|
176
|
+
# @see TextField#initialize
|
177
|
+
# @see RAutomation::Window#text_field
|
178
|
+
def text_field(locator={})
|
179
|
+
TextField.new(self, locator)
|
180
|
+
end
|
181
|
+
|
182
|
+
# Redirects all method calls not part of the public API to the AutoIt directly.
|
183
|
+
# @example execute AutoIt's WinGetTitle function:
|
184
|
+
# RAutomation::Window.new(:hwnd => 123456).WinGetTitle(...)
|
185
|
+
# @see RAutomation::Window#method_missing
|
186
|
+
def method_missing(name, *args)
|
187
|
+
@@autoit.send(name, *args)
|
188
|
+
end
|
189
|
+
|
190
|
+
# @private
|
191
|
+
def locator_hwnd
|
192
|
+
"[HANDLE:#{hwnd.to_i.to_s(16)}]"
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
Kernel.warn "[WARN] RAutomation AutoIt adapter is DEPRECATED and will be removed in the future!"
|
2
|
+
|
3
|
+
require "win32ole"
|
4
|
+
require File.dirname(__FILE__) + "/autoit/locators"
|
5
|
+
require File.dirname(__FILE__) + "/autoit/button"
|
6
|
+
require File.dirname(__FILE__) + "/autoit/text_field"
|
7
|
+
require File.dirname(__FILE__) + "/autoit/window"
|
8
|
+
require File.dirname(__FILE__) + "/autoit/mouse"
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module RAutomation
|
2
|
+
module Adapter
|
3
|
+
autoload :Autoit, File.dirname(__FILE__) + "/autoit.rb"
|
4
|
+
autoload :MsUia, File.dirname(__FILE__) + "/ms_uia.rb"
|
5
|
+
autoload :Win32, File.dirname(__FILE__) + "/win_32.rb"
|
6
|
+
|
7
|
+
module Helper
|
8
|
+
require 'fileutils'
|
9
|
+
require File.expand_path('../../platform', __FILE__)
|
10
|
+
extend self
|
11
|
+
|
12
|
+
# @private
|
13
|
+
# Retrieves default {Adapter} for the current platform.
|
14
|
+
def default_adapter
|
15
|
+
if ENV['OS'] == 'Windows_NT'
|
16
|
+
:win_32
|
17
|
+
else
|
18
|
+
raise "unsupported platform for RAutomation: #{RUBY_PLATFORM}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def supported_for_current_platform?(adapter)
|
23
|
+
Platform.is_x86? || adapter == :win_32
|
24
|
+
end
|
25
|
+
|
26
|
+
def find_missing_externals(externals)
|
27
|
+
externals.select do |ext|
|
28
|
+
path = "#{Dir.pwd}/#{File.dirname(ext)}"
|
29
|
+
file = File.basename(ext)
|
30
|
+
!Dir.exist?(path) && !File.exist?("#{path}/#{file}")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def build_solution(ext)
|
35
|
+
return if ext =~ /RAutomation.UIA.dll/ # skip this since its built in UiaDll.sln
|
36
|
+
|
37
|
+
name = File.basename(ext, File.extname(ext))
|
38
|
+
msbuild_solution(name)
|
39
|
+
end
|
40
|
+
|
41
|
+
def msbuild_solution(name)
|
42
|
+
cmd = "msbuild /p:Configuration=Release ext\\#{name}\\#{name}.sln"
|
43
|
+
cmd += " && #{cmd} /p:Platform=x64" unless name == 'WindowsForms'
|
44
|
+
system(cmd) or raise StandardError, "An error occurred when trying to build solution #{name}. " +
|
45
|
+
"Make sure msbuild binary is in your PATH and the project is configured correctly"
|
46
|
+
end
|
47
|
+
|
48
|
+
def move_adapter_dlls(externals, architecture)
|
49
|
+
raise ArgumentError, "Invalid platform #{architecture}" unless %w[x86 x64].any? { |arch| arch == architecture }
|
50
|
+
puts "Moving #{architecture} dll's into 'Release' folder.."
|
51
|
+
|
52
|
+
externals.each do |dest_path|
|
53
|
+
next if dest_path =~ /WindowsForms/
|
54
|
+
dll_path = dest_path.gsub('Release', "#{architecture}Release")
|
55
|
+
dest_dir = File.dirname(dest_path)
|
56
|
+
FileUtils.mkdir_p(dest_dir) unless Dir.exist?(dest_dir)
|
57
|
+
FileUtils.cp(dll_path, dest_path)
|
58
|
+
end
|
59
|
+
|
60
|
+
externals
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module RAutomation
|
2
|
+
module Adapter
|
3
|
+
module MsUia
|
4
|
+
class Button < Control
|
5
|
+
include WaitHelper
|
6
|
+
include Locators
|
7
|
+
|
8
|
+
# Default locators used for searching buttons.
|
9
|
+
DEFAULT_LOCATORS = {:class => /button/i}
|
10
|
+
|
11
|
+
def exist?
|
12
|
+
super && matches_type?(Constants::UIA_BUTTON_CONTROL_TYPE)
|
13
|
+
end
|
14
|
+
|
15
|
+
alias_method :exists?, :exist?
|
16
|
+
alias_method :value, :control_name
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module RAutomation
|
2
|
+
module Adapter
|
3
|
+
module MsUia
|
4
|
+
module ButtonHelper
|
5
|
+
|
6
|
+
# @todo call a windows function to do this without clicking
|
7
|
+
def clear
|
8
|
+
click {!set?} if set?
|
9
|
+
end
|
10
|
+
|
11
|
+
# @todo call a windows function to do this without clicking
|
12
|
+
def set
|
13
|
+
click {set?} unless set?
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module RAutomation
|
2
|
+
module Adapter
|
3
|
+
module MsUia
|
4
|
+
class Checkbox < Control
|
5
|
+
include WaitHelper
|
6
|
+
include Locators
|
7
|
+
include ButtonHelper
|
8
|
+
|
9
|
+
def exist?
|
10
|
+
super && matches_type?(Constants::UIA_CHECKBOX_CONTROL_TYPE)
|
11
|
+
end
|
12
|
+
|
13
|
+
def set?
|
14
|
+
UiaDll::is_set(search_information)
|
15
|
+
end
|
16
|
+
|
17
|
+
alias_method :exists?, :exist?
|
18
|
+
alias_method :value, :control_name
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
module RAutomation
|
2
|
+
module Adapter
|
3
|
+
module MsUia
|
4
|
+
module Constants
|
5
|
+
WM_GETTEXT = 0xD
|
6
|
+
WM_SETTEXT = 0xC
|
7
|
+
WM_GETTEXTLENGTH = 0xE
|
8
|
+
WM_CLOSE = 0x10
|
9
|
+
|
10
|
+
SW_MAXIMIZE = 3
|
11
|
+
SW_MINIMIZE = 6
|
12
|
+
SW_RESTORE = 9
|
13
|
+
|
14
|
+
SMTO_ABORTIFHUNG = 0x2
|
15
|
+
|
16
|
+
STANDARD_RIGHTS_REQUIRED = 0xF0000
|
17
|
+
SYNCHRONIZE = 0x100000
|
18
|
+
PROCESS_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFF
|
19
|
+
|
20
|
+
BM_CLICK = 0xF5
|
21
|
+
BM_GETSTATE = 0xF2
|
22
|
+
BST_CHECKED = 0x1
|
23
|
+
|
24
|
+
# keybd_event constants
|
25
|
+
KEYEVENTF_EXTENDEDKEY = 0x1
|
26
|
+
KEYEVENTF_KEYUP = 0x2
|
27
|
+
|
28
|
+
VK_BACK = 0x08
|
29
|
+
VK_TAB = 0x09
|
30
|
+
VK_RETURN = 0x0D
|
31
|
+
VK_SPACE = 0x20
|
32
|
+
VK_CAPITAL = 0x14
|
33
|
+
VK_LEFT = 0x25
|
34
|
+
VK_UP = 0x26
|
35
|
+
VK_RIGHT = 0x27
|
36
|
+
VK_DOWN = 0x28
|
37
|
+
VK_SHIFT = 0x10
|
38
|
+
VK_LSHIFT = 0xA0
|
39
|
+
VK_RSHIFT = 0xA1
|
40
|
+
VK_MENU = 0x12
|
41
|
+
VK_LMENU = 0xA4
|
42
|
+
VK_RMENU = 0xA5
|
43
|
+
VK_CONTROL = 0x11
|
44
|
+
VK_LCONTROL = 0xA2
|
45
|
+
VK_RCONTROL = 0xA3
|
46
|
+
VK_ESCAPE = 0x1B
|
47
|
+
VK_END = 0x23
|
48
|
+
VK_HOME = 0x24
|
49
|
+
VK_NUMLOCK = 0x90
|
50
|
+
VK_DELETE = 0x2E
|
51
|
+
VK_INSERT = 0x2D
|
52
|
+
VK_NEXT = 0x22
|
53
|
+
VK_PRIOR = 0x21
|
54
|
+
|
55
|
+
# GetWindow constants
|
56
|
+
GW_ENABLEDPOPUP = 6
|
57
|
+
|
58
|
+
# HRESULT
|
59
|
+
S_OK = 0
|
60
|
+
|
61
|
+
# IAccessible Button States
|
62
|
+
STATE_SYSTEM_UNAVAILABLE = 0x00000001
|
63
|
+
STATE_SYSTEM_SELECTED = 0x00000002
|
64
|
+
STATE_SYSTEM_FOCUSED = 0x00000004
|
65
|
+
STATE_SYSTEM_CHECKED = 0x00000010
|
66
|
+
|
67
|
+
# Combobox
|
68
|
+
CB_GETCOUNT = 0x0146
|
69
|
+
CB_GETTOPINDEX = 0x015b
|
70
|
+
CB_GETLBTEXTLEN = 0x0149
|
71
|
+
CB_GETLBTEXT = 0x0148
|
72
|
+
CB_GETCURSEL = 0x0147
|
73
|
+
CB_GETDROPPEDCONTROLRECT = 0x0152
|
74
|
+
CB_GETITEMHEIGHT = 0x0154
|
75
|
+
CB_ERR = -1
|
76
|
+
CB_SETCURSEL = 0x14E
|
77
|
+
CB_SELECTSTRING = 0x14D
|
78
|
+
CB_SETEDITSEL = 0x142
|
79
|
+
CB_SETTOPINDEX = 0x015c
|
80
|
+
|
81
|
+
#ListBox
|
82
|
+
LB_SETTOPINDEX = 0x0197
|
83
|
+
LB_GETITEMHEIGHT = 0x01A1
|
84
|
+
LB_GETITEMRECT = 0x0198
|
85
|
+
LB_GETTOPINDEX = 0x018E
|
86
|
+
|
87
|
+
# listview
|
88
|
+
LVM_FIRST = 0x1000
|
89
|
+
LVM_GETITEMCOUNT = LVM_FIRST + 4
|
90
|
+
|
91
|
+
# UI Automation control type IDs
|
92
|
+
UIA_LIST_CONTROL_TYPE = 50008
|
93
|
+
UIA_LIST_ITEM_CONTROL_TYPE = 50007
|
94
|
+
UIA_DATA_GRID_CONTROL_TYPE =50028
|
95
|
+
UIA_DATA_ITEM_CONTROL_TYPE =50029
|
96
|
+
UIA_CHECKBOX_CONTROL_TYPE = 50002
|
97
|
+
UIA_BUTTON_CONTROL_TYPE = 50000
|
98
|
+
UIA_TEXT_CONTROL_TYPE = 50020
|
99
|
+
UIA_RADIO_BUTTON_CONTROL_TYPE = 50013
|
100
|
+
UIA_COMBOBOX_CONTROL_TYPE = 50003
|
101
|
+
UIA_EDIT_CONTROL_TYPE = 50004
|
102
|
+
UIA_DOCUMENT_CONTROL_TYPE = 50030
|
103
|
+
UIA_HEADER_CONTROL_TYPE = 50034
|
104
|
+
UIA_HEADER_ITEM_CONTROL_TYPE = 50035
|
105
|
+
UIA_WINDOW_CONTROL_TYPE = 50032
|
106
|
+
UIA_PANE_CONTROL_TYPE = 50033
|
107
|
+
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
module RAutomation
|
2
|
+
module Adapter
|
3
|
+
module MsUia
|
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
|
+
# @option locators [String, Boolean] :children_only limit the scope of the search to children only
|
17
|
+
# @see RAutomation::Window#button
|
18
|
+
def initialize(window, locators)
|
19
|
+
@window = window
|
20
|
+
extract(locators)
|
21
|
+
end
|
22
|
+
|
23
|
+
def cached_hwnd
|
24
|
+
@cached_hwnd ||= UiaDll::cached_hwnd(UiaDll::SearchCriteria.from_locator(@window.hwnd, @locators))
|
25
|
+
@cached_hwnd == 0 ? nil : @cached_hwnd
|
26
|
+
end
|
27
|
+
|
28
|
+
#todo - replace with UIA version
|
29
|
+
def hwnd
|
30
|
+
Functions.control_hwnd(@window.hwnd, @locators)
|
31
|
+
end
|
32
|
+
|
33
|
+
def search_information
|
34
|
+
info = UiaDll::SearchCriteria.from_locator(@window.hwnd, @locators)
|
35
|
+
if info.how == 0 || cached_hwnd
|
36
|
+
info.how = :hwnd
|
37
|
+
info.data = cached_hwnd || hwnd
|
38
|
+
end
|
39
|
+
|
40
|
+
info
|
41
|
+
end
|
42
|
+
|
43
|
+
#todo - replace with UIA version
|
44
|
+
def click
|
45
|
+
assert_enabled
|
46
|
+
clicked = false
|
47
|
+
wait_until do
|
48
|
+
@window.activate
|
49
|
+
@window.active? &&
|
50
|
+
UiaDll::control_click(search_information) &&
|
51
|
+
clicked = true # is clicked at least once
|
52
|
+
|
53
|
+
block_given? ? yield : clicked && !exist?
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def exist?
|
58
|
+
begin
|
59
|
+
UiaDll::exists?(search_information) || !!hwnd
|
60
|
+
rescue UnknownElementException
|
61
|
+
false
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def enabled?
|
66
|
+
UiaDll::is_enabled(search_information)
|
67
|
+
end
|
68
|
+
|
69
|
+
def disabled?
|
70
|
+
!enabled?
|
71
|
+
end
|
72
|
+
|
73
|
+
#todo - replace with UIA version
|
74
|
+
def focused?
|
75
|
+
UiaDll::is_focused(search_information)
|
76
|
+
end
|
77
|
+
|
78
|
+
def focus
|
79
|
+
assert_enabled
|
80
|
+
UiaDll::set_focus(search_information)
|
81
|
+
end
|
82
|
+
|
83
|
+
def bounding_rectangle
|
84
|
+
UiaDll::bounding_rectangle(search_information)
|
85
|
+
end
|
86
|
+
|
87
|
+
def visible?
|
88
|
+
!UiaDll::is_offscreen(search_information)
|
89
|
+
end
|
90
|
+
|
91
|
+
def matches_type?(*classes)
|
92
|
+
classes.include? get_current_control_type
|
93
|
+
end
|
94
|
+
|
95
|
+
def get_current_control_type
|
96
|
+
UiaDll::current_control_type(search_information)
|
97
|
+
end
|
98
|
+
|
99
|
+
def new_pid
|
100
|
+
UiaDll::process_id(search_information)
|
101
|
+
end
|
102
|
+
|
103
|
+
def control_name
|
104
|
+
UiaDll::name(search_information)
|
105
|
+
end
|
106
|
+
|
107
|
+
def help_text
|
108
|
+
UiaDll::help_text(search_information)
|
109
|
+
end
|
110
|
+
|
111
|
+
def control_class
|
112
|
+
UiaDll::class_name(search_information)
|
113
|
+
end
|
114
|
+
|
115
|
+
alias_method :exists?, :exist?
|
116
|
+
|
117
|
+
def assert_enabled
|
118
|
+
raise "Cannot interact with disabled control #{@locators.inspect} on window #{@window.locators.inspect}!" if disabled?
|
119
|
+
end
|
120
|
+
|
121
|
+
def expand(which_item)
|
122
|
+
UiaDll::expand_by_value search_information, which_item if which_item.is_a? String
|
123
|
+
UiaDll::expand_by_index search_information, which_item if which_item.is_a? Integer
|
124
|
+
end
|
125
|
+
|
126
|
+
def collapse(which_item)
|
127
|
+
UiaDll::collapse_by_value search_information, which_item if which_item.is_a? String
|
128
|
+
UiaDll::collapse_by_index search_information, which_item if which_item.is_a? Integer
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|