rdp-rautomation 0.6.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +5 -0
- data/.rspec +2 -0
- data/.yardopts +6 -0
- data/History.rdoc +103 -0
- data/LICENSE +20 -0
- data/README.rdoc +114 -0
- data/Rakefile +43 -0
- data/VERSION +1 -0
- data/ext/AutoItX/AutoItX.chm +0 -0
- data/ext/AutoItX/AutoItX3.dll +0 -0
- data/ext/IAccessibleDLL/IAccessibleDLL.sln +20 -0
- data/ext/IAccessibleDLL/IAccessibleDLL.suo +0 -0
- data/ext/IAccessibleDLL/IAccessibleDLL/IAccessibleDLL.cpp +30 -0
- data/ext/IAccessibleDLL/IAccessibleDLL/IAccessibleDLL.vcxproj +102 -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/Release/IAccessibleDLL.dll +0 -0
- data/ext/ListViewExplorer/ListViewExplorer.sln +20 -0
- data/ext/ListViewExplorer/ListViewExplorer.suo +0 -0
- data/ext/ListViewExplorer/ListViewExplorer/ListViewExplorer.cpp +174 -0
- data/ext/ListViewExplorer/ListViewExplorer/ListViewExplorer.vcxproj +95 -0
- data/ext/ListViewExplorer/ListViewExplorer/ListViewExplorer.vcxproj.filters +42 -0
- data/ext/ListViewExplorer/ListViewExplorer/ListViewExplorer.vcxproj.user +3 -0
- data/ext/ListViewExplorer/ListViewExplorer/ReadMe.txt +40 -0
- data/ext/ListViewExplorer/ListViewExplorer/stdafx.cpp +8 -0
- data/ext/ListViewExplorer/ListViewExplorer/stdafx.h +17 -0
- data/ext/ListViewExplorer/ListViewExplorer/table_support.cpp +250 -0
- data/ext/ListViewExplorer/ListViewExplorer/table_support.h +2 -0
- data/ext/ListViewExplorer/ListViewExplorer/targetver.h +8 -0
- data/ext/UiaDll/Release/UiaDll.dll +0 -0
- data/ext/UiaDll/UiaDll.sln +20 -0
- data/ext/UiaDll/UiaDll.suo +0 -0
- data/ext/UiaDll/UiaDll/ReadMe.txt +48 -0
- data/ext/UiaDll/UiaDll/UiaDll.cpp +205 -0
- data/ext/UiaDll/UiaDll/UiaDll.vcxproj +104 -0
- data/ext/UiaDll/UiaDll/UiaDll.vcxproj.filters +42 -0
- data/ext/UiaDll/UiaDll/dllmain.cpp +39 -0
- data/ext/UiaDll/UiaDll/globals.h +3 -0
- data/ext/UiaDll/UiaDll/stdafx.cpp +8 -0
- data/ext/UiaDll/UiaDll/stdafx.h +19 -0
- data/ext/UiaDll/UiaDll/targetver.h +8 -0
- data/ext/WindowsForms/bin/WindowsForms.exe +0 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms.sln +20 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms.suo +0 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/AboutBox.Designer.cs +80 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/AboutBox.cs +103 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/AboutBox.resx +120 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/DataEntryForm.Designer.cs +187 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/DataEntryForm.cs +46 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/DataEntryForm.resx +120 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/MainFormWindow.Designer.cs +377 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/MainFormWindow.cs +78 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/MainFormWindow.resx +120 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/PersonForm.Designer.cs +119 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/PersonForm.cs +34 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/PersonForm.resx +120 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/Program.cs +21 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/Properties/AssemblyInfo.cs +36 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/Properties/Resources.Designer.cs +71 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/Properties/Resources.resx +117 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/Properties/Settings.Designer.cs +30 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/Properties/Settings.settings +7 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/SimpleElementsForm.Designer.cs +93 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/SimpleElementsForm.cs +19 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/SimpleElementsForm.resx +120 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/WindowsForms.csproj +123 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/bin/Release/WindowsForms.exe +0 -0
- data/lib/rautomation.rb +6 -0
- data/lib/rautomation/adapter/autoit.rb +5 -0
- data/lib/rautomation/adapter/autoit/button.rb +59 -0
- data/lib/rautomation/adapter/autoit/locators.rb +22 -0
- data/lib/rautomation/adapter/autoit/text_field.rb +61 -0
- data/lib/rautomation/adapter/autoit/window.rb +184 -0
- data/lib/rautomation/adapter/helper.rb +20 -0
- data/lib/rautomation/adapter/win_ffi.rb +21 -0
- data/lib/rautomation/adapter/win_ffi/button.rb +25 -0
- data/lib/rautomation/adapter/win_ffi/button_helper.rb +24 -0
- data/lib/rautomation/adapter/win_ffi/checkbox.rb +19 -0
- data/lib/rautomation/adapter/win_ffi/constants.rb +94 -0
- data/lib/rautomation/adapter/win_ffi/control.rb +79 -0
- data/lib/rautomation/adapter/win_ffi/functions.rb +333 -0
- data/lib/rautomation/adapter/win_ffi/keystroke_converter.rb +67 -0
- data/lib/rautomation/adapter/win_ffi/label.rb +21 -0
- data/lib/rautomation/adapter/win_ffi/list_box.rb +60 -0
- data/lib/rautomation/adapter/win_ffi/locators.rb +22 -0
- data/lib/rautomation/adapter/win_ffi/ms_uia/uia_dll.rb +36 -0
- data/lib/rautomation/adapter/win_ffi/radio.rb +19 -0
- data/lib/rautomation/adapter/win_ffi/select_list.rb +87 -0
- data/lib/rautomation/adapter/win_ffi/table.rb +57 -0
- data/lib/rautomation/adapter/win_ffi/text_field.rb +52 -0
- data/lib/rautomation/adapter/win_ffi/window.rb +226 -0
- data/lib/rautomation/button.rb +55 -0
- data/lib/rautomation/element_collections.rb +47 -0
- data/lib/rautomation/text_field.rb +60 -0
- data/lib/rautomation/wait_helper.rb +23 -0
- data/lib/rautomation/window.rb +234 -0
- data/spec/adapter/win_ffi/button_spec.rb +41 -0
- data/spec/adapter/win_ffi/checkbox_spec.rb +48 -0
- data/spec/adapter/win_ffi/keystroke_converter_spec.rb +47 -0
- data/spec/adapter/win_ffi/label_spec.rb +21 -0
- data/spec/adapter/win_ffi/listbox_spec.rb +52 -0
- data/spec/adapter/win_ffi/radio_spec.rb +37 -0
- data/spec/adapter/win_ffi/select_list_spec.rb +66 -0
- data/spec/adapter/win_ffi/table_spec.rb +39 -0
- data/spec/adapter/win_ffi/text_field_spec.rb +23 -0
- data/spec/adapter/win_ffi/window_spec.rb +43 -0
- data/spec/button_spec.rb +68 -0
- data/spec/buttons_spec.rb +21 -0
- data/spec/spec_helper.rb +96 -0
- data/spec/text_field_spec.rb +65 -0
- data/spec/text_fields_spec.rb +22 -0
- data/spec/window_spec.rb +122 -0
- data/spec/windows_spec.rb +55 -0
- metadata +207 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
3
|
+
<PropertyGroup>
|
|
4
|
+
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
|
5
|
+
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
|
|
6
|
+
<ProductVersion>8.0.30703</ProductVersion>
|
|
7
|
+
<SchemaVersion>2.0</SchemaVersion>
|
|
8
|
+
<ProjectGuid>{79C33EDA-58C4-41EF-93DC-BA679895BD43}</ProjectGuid>
|
|
9
|
+
<OutputType>WinExe</OutputType>
|
|
10
|
+
<AppDesignerFolder>Properties</AppDesignerFolder>
|
|
11
|
+
<RootNamespace>WindowsForms</RootNamespace>
|
|
12
|
+
<AssemblyName>WindowsForms</AssemblyName>
|
|
13
|
+
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
|
14
|
+
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
|
|
15
|
+
<FileAlignment>512</FileAlignment>
|
|
16
|
+
</PropertyGroup>
|
|
17
|
+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
|
18
|
+
<PlatformTarget>x86</PlatformTarget>
|
|
19
|
+
<DebugSymbols>true</DebugSymbols>
|
|
20
|
+
<DebugType>full</DebugType>
|
|
21
|
+
<Optimize>false</Optimize>
|
|
22
|
+
<OutputPath>bin\Debug\</OutputPath>
|
|
23
|
+
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
|
24
|
+
<ErrorReport>prompt</ErrorReport>
|
|
25
|
+
<WarningLevel>4</WarningLevel>
|
|
26
|
+
</PropertyGroup>
|
|
27
|
+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
|
28
|
+
<PlatformTarget>x86</PlatformTarget>
|
|
29
|
+
<DebugType>pdbonly</DebugType>
|
|
30
|
+
<Optimize>true</Optimize>
|
|
31
|
+
<OutputPath>bin\Release\</OutputPath>
|
|
32
|
+
<DefineConstants>TRACE</DefineConstants>
|
|
33
|
+
<ErrorReport>prompt</ErrorReport>
|
|
34
|
+
<WarningLevel>4</WarningLevel>
|
|
35
|
+
</PropertyGroup>
|
|
36
|
+
<ItemGroup>
|
|
37
|
+
<Reference Include="System" />
|
|
38
|
+
<Reference Include="System.Core" />
|
|
39
|
+
<Reference Include="System.Xml.Linq" />
|
|
40
|
+
<Reference Include="System.Data.DataSetExtensions" />
|
|
41
|
+
<Reference Include="Microsoft.CSharp" />
|
|
42
|
+
<Reference Include="System.Data" />
|
|
43
|
+
<Reference Include="System.Deployment" />
|
|
44
|
+
<Reference Include="System.Drawing" />
|
|
45
|
+
<Reference Include="System.Windows.Forms" />
|
|
46
|
+
<Reference Include="System.Xml" />
|
|
47
|
+
</ItemGroup>
|
|
48
|
+
<ItemGroup>
|
|
49
|
+
<Compile Include="AboutBox.cs">
|
|
50
|
+
<SubType>Form</SubType>
|
|
51
|
+
</Compile>
|
|
52
|
+
<Compile Include="AboutBox.Designer.cs">
|
|
53
|
+
<DependentUpon>AboutBox.cs</DependentUpon>
|
|
54
|
+
</Compile>
|
|
55
|
+
<Compile Include="DataEntryForm.cs">
|
|
56
|
+
<SubType>Form</SubType>
|
|
57
|
+
</Compile>
|
|
58
|
+
<Compile Include="DataEntryForm.Designer.cs">
|
|
59
|
+
<DependentUpon>DataEntryForm.cs</DependentUpon>
|
|
60
|
+
</Compile>
|
|
61
|
+
<Compile Include="SimpleElementsForm.cs">
|
|
62
|
+
<SubType>Form</SubType>
|
|
63
|
+
</Compile>
|
|
64
|
+
<Compile Include="SimpleElementsForm.Designer.cs">
|
|
65
|
+
<DependentUpon>SimpleElementsForm.cs</DependentUpon>
|
|
66
|
+
</Compile>
|
|
67
|
+
<Compile Include="PersonForm.cs">
|
|
68
|
+
<SubType>Form</SubType>
|
|
69
|
+
</Compile>
|
|
70
|
+
<Compile Include="PersonForm.Designer.cs">
|
|
71
|
+
<DependentUpon>PersonForm.cs</DependentUpon>
|
|
72
|
+
</Compile>
|
|
73
|
+
<Compile Include="MainFormWindow.cs">
|
|
74
|
+
<SubType>Form</SubType>
|
|
75
|
+
</Compile>
|
|
76
|
+
<Compile Include="MainFormWindow.Designer.cs">
|
|
77
|
+
<DependentUpon>MainFormWindow.cs</DependentUpon>
|
|
78
|
+
</Compile>
|
|
79
|
+
<Compile Include="Program.cs" />
|
|
80
|
+
<Compile Include="Properties\AssemblyInfo.cs" />
|
|
81
|
+
<EmbeddedResource Include="AboutBox.resx">
|
|
82
|
+
<DependentUpon>AboutBox.cs</DependentUpon>
|
|
83
|
+
</EmbeddedResource>
|
|
84
|
+
<EmbeddedResource Include="DataEntryForm.resx">
|
|
85
|
+
<DependentUpon>DataEntryForm.cs</DependentUpon>
|
|
86
|
+
</EmbeddedResource>
|
|
87
|
+
<EmbeddedResource Include="SimpleElementsForm.resx">
|
|
88
|
+
<DependentUpon>SimpleElementsForm.cs</DependentUpon>
|
|
89
|
+
</EmbeddedResource>
|
|
90
|
+
<EmbeddedResource Include="PersonForm.resx">
|
|
91
|
+
<DependentUpon>PersonForm.cs</DependentUpon>
|
|
92
|
+
</EmbeddedResource>
|
|
93
|
+
<EmbeddedResource Include="MainFormWindow.resx">
|
|
94
|
+
<DependentUpon>MainFormWindow.cs</DependentUpon>
|
|
95
|
+
</EmbeddedResource>
|
|
96
|
+
<EmbeddedResource Include="Properties\Resources.resx">
|
|
97
|
+
<Generator>ResXFileCodeGenerator</Generator>
|
|
98
|
+
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
|
99
|
+
<SubType>Designer</SubType>
|
|
100
|
+
</EmbeddedResource>
|
|
101
|
+
<Compile Include="Properties\Resources.Designer.cs">
|
|
102
|
+
<AutoGen>True</AutoGen>
|
|
103
|
+
<DependentUpon>Resources.resx</DependentUpon>
|
|
104
|
+
</Compile>
|
|
105
|
+
<None Include="Properties\Settings.settings">
|
|
106
|
+
<Generator>SettingsSingleFileGenerator</Generator>
|
|
107
|
+
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
|
108
|
+
</None>
|
|
109
|
+
<Compile Include="Properties\Settings.Designer.cs">
|
|
110
|
+
<AutoGen>True</AutoGen>
|
|
111
|
+
<DependentUpon>Settings.settings</DependentUpon>
|
|
112
|
+
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
|
113
|
+
</Compile>
|
|
114
|
+
</ItemGroup>
|
|
115
|
+
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
|
116
|
+
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
|
117
|
+
Other similar extension points exist, see Microsoft.Common.targets.
|
|
118
|
+
<Target Name="BeforeBuild">
|
|
119
|
+
</Target>
|
|
120
|
+
<Target Name="AfterBuild">
|
|
121
|
+
</Target>
|
|
122
|
+
-->
|
|
123
|
+
</Project>
|
data/lib/rautomation.rb
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
module RAutomation
|
|
2
|
+
module Adapter
|
|
3
|
+
module Autoit
|
|
4
|
+
class Button
|
|
5
|
+
include WaitHelper
|
|
6
|
+
include Locators
|
|
7
|
+
|
|
8
|
+
# Default locators used for searching buttons.
|
|
9
|
+
DEFAULT_LOCATORS = {:class => /button/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 button object.
|
|
20
|
+
# @note this method is not meant to be accessed directly, but only through {RAutomation::Window#button}!
|
|
21
|
+
# @param [RAutomation::Window] window this button belongs to.
|
|
22
|
+
# @param [Hash] locators for searching the button.
|
|
23
|
+
# @option locators [String, Regexp] :value Value (text) of the button
|
|
24
|
+
# @option locators [String, Regexp] :class Internal class name of the button
|
|
25
|
+
# @option locators [String, Fixnum] :id Internal ID of the button
|
|
26
|
+
# @option locators [String, Fixnum] :index 0-based index to specify n-th button if all other criteria match
|
|
27
|
+
# @see RAutomation::Window#button
|
|
28
|
+
def initialize(window, locators)
|
|
29
|
+
@window = window
|
|
30
|
+
extract(locators)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# @see RAutomation::Button#click
|
|
34
|
+
def click
|
|
35
|
+
clicked = false
|
|
36
|
+
wait_until do
|
|
37
|
+
@window.activate
|
|
38
|
+
@window.active? &&
|
|
39
|
+
Window.autoit.ControlFocus(@window.locator_hwnd, "", @autoit_locators) == 1 &&
|
|
40
|
+
Window.autoit.ControlClick(@window.locator_hwnd, "", @autoit_locators) == 1 &&
|
|
41
|
+
clicked = true # is clicked at least once
|
|
42
|
+
|
|
43
|
+
block_given? ? yield : clicked && !exists?
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# @see RAutomation::Button#value
|
|
48
|
+
def value
|
|
49
|
+
Window.autoit.ControlGetText(@window.locator_hwnd, "", @autoit_locators)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# @see RAutomation::Button#exists?
|
|
53
|
+
def exists?
|
|
54
|
+
not Window.autoit.ControlGetHandle(@window.locator_hwnd, "", @autoit_locators).empty?
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module RAutomation
|
|
2
|
+
module Adapter
|
|
3
|
+
module Autoit
|
|
4
|
+
# @private
|
|
5
|
+
module Locators
|
|
6
|
+
|
|
7
|
+
private
|
|
8
|
+
|
|
9
|
+
def extract(locators)
|
|
10
|
+
locators = self.class::DEFAULT_LOCATORS.merge(locators) if self.class.const_defined?(:DEFAULT_LOCATORS)
|
|
11
|
+
@locators = locators
|
|
12
|
+
@autoit_locators = "[#{@locators.map do |locator, value|
|
|
13
|
+
locator_key = self.class::LOCATORS[locator] || self.class::LOCATORS[[locator, value.class]]
|
|
14
|
+
value = value.to_i + 1 if locator == :index # use 0-based indexing
|
|
15
|
+
value = value.to_s(16) if locator == :hwnd
|
|
16
|
+
"#{(locator_key || locator)}:#{value}"
|
|
17
|
+
end.join(";")}]"
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
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, Fixnum] :id Internal ID of the text field
|
|
26
|
+
# @option locators [String, Fixnum] :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
|
+
# @see RAutomation::TextField#set
|
|
34
|
+
def set(text)
|
|
35
|
+
wait_until do
|
|
36
|
+
@window.activate
|
|
37
|
+
@window.active? &&
|
|
38
|
+
Window.autoit.ControlFocus(@window.locator_hwnd, "", @autoit_locators) == 1 &&
|
|
39
|
+
Window.autoit.ControlSetText(@window.locator_hwnd, "", @autoit_locators, text) == 1 &&
|
|
40
|
+
value == text
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# @see RAutomation::TextField#clear
|
|
45
|
+
def clear
|
|
46
|
+
set ""
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# @see RAutomation::TextField#value
|
|
50
|
+
def value
|
|
51
|
+
Window.autoit.ControlGetText(@window.locator_hwnd, "", @autoit_locators)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# @see RAutomation::TextField#exists?
|
|
55
|
+
def exists?
|
|
56
|
+
not Window.autoit.ControlGetHandle(@window.locator_hwnd, "", @autoit_locators).empty?
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,184 @@
|
|
|
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
|
+
system("regsvr32.exe /s #{dll.gsub('/', '\\')}")
|
|
20
|
+
@@autoit = WIN32OLE.new('AutoItX3.Control')
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
load_autoit
|
|
25
|
+
@@autoit.AutoItSetOption("WinWaitDelay", 350)
|
|
26
|
+
|
|
27
|
+
# Locators of the window.
|
|
28
|
+
attr_reader :locators
|
|
29
|
+
|
|
30
|
+
# @private
|
|
31
|
+
# Special-cased locators
|
|
32
|
+
LOCATORS = {
|
|
33
|
+
[:title, Regexp] => :regexptitle,
|
|
34
|
+
:index => :instance,
|
|
35
|
+
:hwnd => :handle
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
# Creates the window object.
|
|
39
|
+
# @note this method is not meant to be accessed directly, but only through {RAutomation::Window#initialize}!
|
|
40
|
+
# @param [Hash] locators for searching the window.
|
|
41
|
+
# @option locators [String, Regexp] :title Title of the window
|
|
42
|
+
# @option locators [String, Regexp] :text Visible text of the window
|
|
43
|
+
# @option locators [String, Regexp] :class Internal class name of the window
|
|
44
|
+
# @option locators [String, Fixnum] :hwnd Window handle in decimal format
|
|
45
|
+
# @option locators [String, Fixnum] :index 0-based index to specify n-th window if all other criteria match
|
|
46
|
+
# @see RAutomation::Window#initialize
|
|
47
|
+
def initialize(locators)
|
|
48
|
+
@hwnd = locators[:hwnd]
|
|
49
|
+
@locator_index = locators.delete(:index) if locators[:index] && locators.size == 1
|
|
50
|
+
@locator_pid = locators.delete(:pid).to_i if locators[:pid]
|
|
51
|
+
@locator_text = locators.delete(:text)
|
|
52
|
+
extract(locators)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Retrieves handle of the window.
|
|
56
|
+
# @note Searches only for visible windows.
|
|
57
|
+
# @see RAutomation::Window#hwnd
|
|
58
|
+
def hwnd
|
|
59
|
+
@hwnd ||= begin
|
|
60
|
+
locators = @autoit_locators
|
|
61
|
+
if @locator_index || @locator_pid
|
|
62
|
+
# @todo Come up with some better solution for this case
|
|
63
|
+
locators = "[regexptitle:]" # match all, needed for the case when only :index or :pid is used
|
|
64
|
+
end
|
|
65
|
+
windows = @@autoit.WinList(locators, @locator_text).pop.compact.
|
|
66
|
+
map {|handle| self.class.new(:hwnd => handle.hex)}
|
|
67
|
+
windows.delete_if {|window| !window.visible?}
|
|
68
|
+
|
|
69
|
+
if @locator_pid
|
|
70
|
+
window = windows.find {|win| win.pid == @locator_pid}
|
|
71
|
+
else
|
|
72
|
+
window = windows[@locator_index || 0]
|
|
73
|
+
end
|
|
74
|
+
window ? window.hwnd : nil
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# @see RAutomation::Window#pid
|
|
79
|
+
def pid
|
|
80
|
+
@@autoit.WinGetProcess(locator_hwnd).to_i
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# @see RAutomation::Window#title
|
|
84
|
+
def title
|
|
85
|
+
@@autoit.WinGetTitle(locator_hwnd)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# @see RAutomation::Window#activate
|
|
89
|
+
def activate
|
|
90
|
+
@@autoit.WinWait(locator_hwnd, "", 1)
|
|
91
|
+
@@autoit.WinActivate(locator_hwnd)
|
|
92
|
+
sleep 1
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# @see RAutomation::Window#active?
|
|
96
|
+
def active?
|
|
97
|
+
@@autoit.WinActive(locator_hwnd) == 1
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# @see RAutomation::Window#text
|
|
101
|
+
def text
|
|
102
|
+
@@autoit.WinGetText(locator_hwnd)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# @see RAutomation::Window#exists?
|
|
106
|
+
def exists?
|
|
107
|
+
@@autoit.WinExists(locator_hwnd) == 1
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# @see RAutomation::Window#visible?
|
|
111
|
+
def visible?
|
|
112
|
+
@@autoit.WinGetState(locator_hwnd) & 2 == 2
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# @see RAutomation::Window#maximize
|
|
116
|
+
def maximize
|
|
117
|
+
@@autoit.WinSetState(locator_hwnd, "", @@autoit.SW_MAXIMIZE)
|
|
118
|
+
sleep 1
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# @see RAutomation::Window#minimize
|
|
122
|
+
def minimize
|
|
123
|
+
@@autoit.WinSetState(locator_hwnd, "", @@autoit.SW_MINIMIZE)
|
|
124
|
+
sleep 1
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# @see RAutomation::Window#minimized?
|
|
128
|
+
def minimized?
|
|
129
|
+
@@autoit.WinGetState(locator_hwnd) & 16 == 16
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# @see RAutomation::Window#restore
|
|
133
|
+
def restore
|
|
134
|
+
@@autoit.WinSetState(locator_hwnd, "", @@autoit.SW_RESTORE)
|
|
135
|
+
sleep 1
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
# Activates the window and sends keys to it.
|
|
139
|
+
#
|
|
140
|
+
# Refer to AutoIt documentation at http://www.autoitscript.com/autoit3/docs/appendix/SendKeys.htm
|
|
141
|
+
# for keys syntax.
|
|
142
|
+
# @see RAutomation::Window#send_keys
|
|
143
|
+
def send_keys(keys)
|
|
144
|
+
wait_until do
|
|
145
|
+
activate
|
|
146
|
+
active?
|
|
147
|
+
end
|
|
148
|
+
@@autoit.Send(keys)
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# @see RAutomation::Window#close
|
|
152
|
+
def close
|
|
153
|
+
@@autoit.WinClose(locator_hwnd)
|
|
154
|
+
@@autoit.WinKill(locator_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
|
+
# @see TextField#initialize
|
|
164
|
+
# @see RAutomation::Window#text_field
|
|
165
|
+
def text_field(locator)
|
|
166
|
+
TextField.new(self, locator)
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
# Redirects all method calls not part of the public API to the AutoIt directly.
|
|
170
|
+
# @example execute AutoIt's WinGetTitle function:
|
|
171
|
+
# RAutomation::Window.new(:hwnd => 123456).WinGetTitle(...)
|
|
172
|
+
# @see RAutomation::Window#method_missing
|
|
173
|
+
def method_missing(name, *args)
|
|
174
|
+
@@autoit.send(name, *args)
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
# @private
|
|
178
|
+
def locator_hwnd
|
|
179
|
+
"[HANDLE:#{hwnd.to_i.to_s(16)}]"
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
end
|