rautomation 0.13.0 → 0.14.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/Gemfile.lock +11 -11
- data/History.rdoc +11 -0
- data/VERSION +1 -1
- data/ext/UiaDll/RAutomation.UIA/Controls/TableControl.cs +10 -0
- data/ext/UiaDll/RAutomation.UIA/Extensions/Enumerable.cs +13 -0
- data/ext/UiaDll/UiaDll/ArrayHelper.cpp +14 -0
- data/ext/UiaDll/UiaDll/ArrayHelper.h +7 -0
- data/ext/UiaDll/UiaDll/TableMethods.cpp +69 -54
- data/ext/UiaDll/UiaDll/UiaDll.vcxproj +2 -0
- data/ext/UiaDll/UiaDll/UiaDll.vcxproj.filters +6 -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/WindowsForms.sln +9 -2
- data/ext/WindowsForms/WindowsForms/DataGridView.cs +2 -1
- data/ext/WindowsForms/WindowsForms/WindowsForms.csproj +6 -3
- data/ext/WindowsForms/WindowsForms/packages.config +4 -0
- data/lib/rautomation/adapter/ms_uia/functions.rb +3 -10
- data/lib/rautomation/adapter/ms_uia/select_list.rb +27 -22
- data/lib/rautomation/adapter/ms_uia/table.rb +16 -3
- data/lib/rautomation/adapter/ms_uia/uia_dll.rb +20 -1
- data/rautomation.gemspec +1 -1
- data/spec/adapter/ms_uia/select_list_spec.rb +39 -24
- data/spec/adapter/ms_uia/table_spec.rb +35 -2
- data/spec/adapter/ms_uia/window_spec.rb +0 -3
- data/spec/window_spec.rb +15 -9
- metadata +10 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9f790814402e5dff056890bfd0bc89e90025b5ab
|
4
|
+
data.tar.gz: f0a96181d6654fd874cfa2e7c05da15f139bdf56
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c258b23e4d6b47cc5708590cbdf36a991ce51c30924e2d547f88066a097a2585447359daef244e34153c350bb8577e0287d8e9fc15acbc82575edde0e36931d8
|
7
|
+
data.tar.gz: b74d867f6e09501da80d26cc1852145b8206fc1b21d46165cd92cd9c7c96589cdb887f4298629e6779c0ad16ab2c616cc7e92263e72d9ca2eb94f77de89d4deb
|
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,23 +1,23 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
rautomation (0.
|
4
|
+
rautomation (0.14.0)
|
5
5
|
ffi
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: https://rubygems.org/
|
9
9
|
specs:
|
10
|
-
diff-lcs (1.
|
10
|
+
diff-lcs (1.2.4)
|
11
11
|
ffi (1.9.0-x86-mingw32)
|
12
12
|
rake (0.9.2.2)
|
13
|
-
rspec (2.
|
14
|
-
rspec-core (~> 2.
|
15
|
-
rspec-expectations (~> 2.
|
16
|
-
rspec-mocks (~> 2.
|
17
|
-
rspec-core (2.
|
18
|
-
rspec-expectations (2.
|
19
|
-
diff-lcs (
|
20
|
-
rspec-mocks (2.
|
13
|
+
rspec (2.14.1)
|
14
|
+
rspec-core (~> 2.14.0)
|
15
|
+
rspec-expectations (~> 2.14.0)
|
16
|
+
rspec-mocks (~> 2.14.0)
|
17
|
+
rspec-core (2.14.6)
|
18
|
+
rspec-expectations (2.14.3)
|
19
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
20
|
+
rspec-mocks (2.14.4)
|
21
21
|
yard (0.8.6.1)
|
22
22
|
|
23
23
|
PLATFORMS
|
@@ -26,5 +26,5 @@ PLATFORMS
|
|
26
26
|
DEPENDENCIES
|
27
27
|
rake
|
28
28
|
rautomation!
|
29
|
-
rspec (~> 2.
|
29
|
+
rspec (~> 2.14)
|
30
30
|
yard
|
data/History.rdoc
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
== 0.14.0
|
2
|
+
|
3
|
+
=== MsUia adapter
|
4
|
+
|
5
|
+
* Add SelectList#select and SelectList#clear.
|
6
|
+
* Add Table#select and Table#clear.
|
7
|
+
* Add Table#selected_rows.
|
8
|
+
* Improve performance of table Row lookups.
|
9
|
+
* SelectList#options accepts :index and :text (Regexp or String).
|
10
|
+
* Window#child in ms_uia works for popup windows as well.
|
11
|
+
|
1
12
|
== 0.13.0
|
2
13
|
|
3
14
|
=== MsUia adapter
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.14.0
|
@@ -26,6 +26,11 @@ namespace RAutomation.UIA.Controls
|
|
26
26
|
set { Select(value); }
|
27
27
|
}
|
28
28
|
|
29
|
+
public int[] SelectedIndexes
|
30
|
+
{
|
31
|
+
get { return DataItems.IndexesOf(x => x.AsSelectionItem().Current.IsSelected); }
|
32
|
+
}
|
33
|
+
|
29
34
|
public bool IsRowSelected(int dataItemIndex)
|
30
35
|
{
|
31
36
|
return DataItems.ElementAt(dataItemIndex).AsSelectionItem().Current.IsSelected;
|
@@ -71,6 +76,11 @@ namespace RAutomation.UIA.Controls
|
|
71
76
|
get { return TableOrListItems.Select(x => x.Current.Name).ToArray(); }
|
72
77
|
}
|
73
78
|
|
79
|
+
public void SingleSelect(int value)
|
80
|
+
{
|
81
|
+
DataItems.ElementAt(value).AsSelectionItem().Select();
|
82
|
+
}
|
83
|
+
|
74
84
|
private void Select(int value)
|
75
85
|
{
|
76
86
|
var selectionItem = DataItems.ElementAt(value).AsSelectionItem();
|
@@ -49,6 +49,19 @@ namespace RAutomation.UIA.Extensions
|
|
49
49
|
return -1;
|
50
50
|
}
|
51
51
|
|
52
|
+
public static int[] IndexesOf<T>(this IEnumerable<T> items, Func<T, bool> trueCondition)
|
53
|
+
{
|
54
|
+
var indexes = new List<int>();
|
55
|
+
var foundIndex = 0;
|
56
|
+
foreach (var item in items)
|
57
|
+
{
|
58
|
+
if (trueCondition(item)) indexes.Add(foundIndex);
|
59
|
+
++foundIndex;
|
60
|
+
}
|
61
|
+
|
62
|
+
return indexes.ToArray();
|
63
|
+
}
|
64
|
+
|
52
65
|
public static void ForEach<T>(this IEnumerable<T> items, Action<T> doIt)
|
53
66
|
{
|
54
67
|
foreach (var item in items)
|
@@ -0,0 +1,14 @@
|
|
1
|
+
#include "StdAfx.h"
|
2
|
+
#include "ArrayHelper.h"
|
3
|
+
|
4
|
+
|
5
|
+
int ArrayHelper::Copy(array<int, 1>^ source, int destination[])
|
6
|
+
{
|
7
|
+
if( NULL != destination ) {
|
8
|
+
auto index = 0;
|
9
|
+
for each(auto value in source) {
|
10
|
+
destination[index++] = value;
|
11
|
+
}
|
12
|
+
}
|
13
|
+
return source->Length;
|
14
|
+
}
|
@@ -1,58 +1,73 @@
|
|
1
1
|
#include "stdafx.h"
|
2
2
|
#include "Locator.h"
|
3
|
+
#include "ArrayHelper.h"
|
3
4
|
#include "StringHelper.h"
|
4
5
|
|
5
6
|
using namespace RAutomation::UIA::Controls;
|
6
7
|
|
7
8
|
extern "C" {
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
__declspec ( dllexport ) int Table_GetHeaders(const FindInformation& findInformation, const char* headers[]) {
|
11
|
+
auto tableControl = gcnew TableControl(Locator::FindFor(findInformation));
|
12
|
+
return StringHelper::Copy(tableControl->Headers, headers);
|
13
|
+
}
|
14
|
+
|
15
|
+
__declspec ( dllexport ) int Table_GetValues(const FindInformation& findInformation, const char* values[]) {
|
16
|
+
auto tableControl = gcnew TableControl(Locator::FindFor(findInformation));
|
17
|
+
return StringHelper::Copy(tableControl->Values, values);
|
18
|
+
}
|
13
19
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
20
|
+
__declspec ( dllexport ) int Table_GetSelectedIndexes(const FindInformation& findInformation, int selectedIndexes[]) {
|
21
|
+
auto tableControl = gcnew TableControl(Locator::FindFor(findInformation));
|
22
|
+
return ArrayHelper::Copy(tableControl->SelectedIndexes, selectedIndexes);
|
23
|
+
}
|
18
24
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
+
__declspec ( dllexport ) int Table_RowCount(const FindInformation& findInformation) {
|
26
|
+
try {
|
27
|
+
auto tableControl = gcnew TableControl(Locator::FindFor(findInformation));
|
28
|
+
return tableControl->RowCount;
|
29
|
+
} catch(Exception^ e) {
|
30
|
+
Console::WriteLine(e->ToString());
|
25
31
|
return 0;
|
26
|
-
|
27
|
-
|
32
|
+
}
|
33
|
+
}
|
28
34
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
35
|
+
__declspec ( dllexport ) bool Table_CoordinateIsValid(const FindInformation& findInformation, const int whichItemIndex, const int whichColumnIndex) {
|
36
|
+
try {
|
37
|
+
auto tableControl = gcnew TableControl(Locator::FindFor(findInformation));
|
38
|
+
return tableControl->Exists(whichItemIndex, whichColumnIndex);
|
39
|
+
} catch(Exception^ e) {
|
40
|
+
Console::WriteLine(e->ToString());
|
41
|
+
return false;
|
42
|
+
}
|
43
|
+
}
|
44
|
+
|
45
|
+
__declspec ( dllexport ) void Table_ValueAt(const FindInformation& findInformation, const int row, const int column, char *foundValue, const int foundValueLength) {
|
46
|
+
try {
|
47
|
+
auto tableControl = gcnew TableControl(Locator::FindFor(findInformation));
|
48
|
+
StringHelper::CopyToUnmanagedString(tableControl->ValueAt(row, column), foundValue, foundValueLength);
|
49
|
+
} catch(Exception^ e) {
|
50
|
+
Console::WriteLine(e->ToString());
|
51
|
+
}
|
52
|
+
}
|
38
53
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
54
|
+
__declspec ( dllexport ) void Table_SelectByIndex(const FindInformation& findInformation, const int dataItemIndex, char* errorInfo, const int errorInfoLength) {
|
55
|
+
try {
|
56
|
+
auto tableControl = gcnew TableControl(Locator::FindFor(findInformation));
|
57
|
+
tableControl->SelectedIndex = dataItemIndex;
|
58
|
+
} catch(Exception^ e) {
|
59
|
+
StringHelper::Write(e, errorInfo, errorInfoLength);
|
60
|
+
}
|
61
|
+
}
|
47
62
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
63
|
+
__declspec ( dllexport ) void Table_SingleSelectByIndex(const FindInformation& findInformation, const int dataItemIndex, char* errorInfo, const int errorInfoLength) {
|
64
|
+
try {
|
65
|
+
auto tableControl = gcnew TableControl(Locator::FindFor(findInformation));
|
66
|
+
tableControl->SingleSelect(dataItemIndex);
|
67
|
+
} catch(Exception^ e) {
|
53
68
|
StringHelper::Write(e, errorInfo, errorInfoLength);
|
54
|
-
|
55
|
-
|
69
|
+
}
|
70
|
+
}
|
56
71
|
|
57
72
|
__declspec ( dllexport ) void Table_RemoveRowByIndex(const FindInformation& findInformation, const int dataItemIndex, char* errorInfo, const int errorInfoLength) {
|
58
73
|
try {
|
@@ -72,22 +87,22 @@ extern "C" {
|
|
72
87
|
}
|
73
88
|
}
|
74
89
|
|
75
|
-
|
76
|
-
|
77
|
-
|
90
|
+
__declspec ( dllexport ) bool Table_IsSelectedByIndex(const FindInformation& findInformation, const int dataItemIndex) {
|
91
|
+
try {
|
92
|
+
auto tableControl = gcnew TableControl(Locator::FindFor(findInformation));
|
78
93
|
return tableControl->IsRowSelected(dataItemIndex);
|
79
|
-
|
80
|
-
|
94
|
+
} catch(Exception^ e) {
|
95
|
+
Console::WriteLine(e->ToString());
|
81
96
|
return false;
|
82
|
-
|
83
|
-
|
97
|
+
}
|
98
|
+
}
|
84
99
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
100
|
+
__declspec ( dllexport ) void Table_SelectByValue(const FindInformation& findInformation, const char* dataItemValue, char* errorInfo, const int errorInfoLength) {
|
101
|
+
try {
|
102
|
+
auto tableControl = gcnew TableControl(Locator::FindFor(findInformation));
|
103
|
+
tableControl->Value = gcnew String(dataItemValue);
|
104
|
+
} catch(Exception^ e) {
|
90
105
|
StringHelper::Write(e, errorInfo, errorInfoLength);
|
91
|
-
|
92
|
-
|
106
|
+
}
|
107
|
+
}
|
93
108
|
}
|
@@ -80,6 +80,7 @@
|
|
80
80
|
<Reference Include="WindowsBase" />
|
81
81
|
</ItemGroup>
|
82
82
|
<ItemGroup>
|
83
|
+
<ClInclude Include="ArrayHelper.h" />
|
83
84
|
<ClInclude Include="Locator.h" />
|
84
85
|
<ClInclude Include="DynamicAssemblyResolver.h" />
|
85
86
|
<ClInclude Include="MenuItemSelector.h" />
|
@@ -90,6 +91,7 @@
|
|
90
91
|
<ClInclude Include="UiaDll.h" />
|
91
92
|
</ItemGroup>
|
92
93
|
<ItemGroup>
|
94
|
+
<ClCompile Include="ArrayHelper.cpp" />
|
93
95
|
<ClCompile Include="AssemblyInfo.cpp" />
|
94
96
|
<ClCompile Include="Locator.cpp" />
|
95
97
|
<ClCompile Include="ControlMethods.cpp" />
|
@@ -39,6 +39,9 @@
|
|
39
39
|
<ClInclude Include="MenuItemSelector.h">
|
40
40
|
<Filter>Header Files</Filter>
|
41
41
|
</ClInclude>
|
42
|
+
<ClInclude Include="ArrayHelper.h">
|
43
|
+
<Filter>Header Files</Filter>
|
44
|
+
</ClInclude>
|
42
45
|
</ItemGroup>
|
43
46
|
<ItemGroup>
|
44
47
|
<ClCompile Include="UiaDll.cpp">
|
@@ -89,6 +92,9 @@
|
|
89
92
|
<ClCompile Include="SpinnerMethods.cpp">
|
90
93
|
<Filter>Source Files</Filter>
|
91
94
|
</ClCompile>
|
95
|
+
<ClCompile Include="ArrayHelper.cpp">
|
96
|
+
<Filter>Source Files</Filter>
|
97
|
+
</ClCompile>
|
92
98
|
</ItemGroup>
|
93
99
|
<ItemGroup>
|
94
100
|
<None Include="ReadMe.txt" />
|
Binary file
|
@@ -0,0 +1,136 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
2
|
+
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
3
|
+
<PropertyGroup>
|
4
|
+
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">$(MSBuildProjectDirectory)\..\</SolutionDir>
|
5
|
+
|
6
|
+
<!-- Enable the restore command to run before builds -->
|
7
|
+
<RestorePackages Condition=" '$(RestorePackages)' == '' ">false</RestorePackages>
|
8
|
+
|
9
|
+
<!-- Property that enables building a package from a project -->
|
10
|
+
<BuildPackage Condition=" '$(BuildPackage)' == '' ">false</BuildPackage>
|
11
|
+
|
12
|
+
<!-- Determines if package restore consent is required to restore packages -->
|
13
|
+
<RequireRestoreConsent Condition=" '$(RequireRestoreConsent)' != 'false' ">false</RequireRestoreConsent>
|
14
|
+
|
15
|
+
<!-- Download NuGet.exe if it does not already exist -->
|
16
|
+
<DownloadNuGetExe Condition=" '$(DownloadNuGetExe)' == '' ">false</DownloadNuGetExe>
|
17
|
+
</PropertyGroup>
|
18
|
+
|
19
|
+
<ItemGroup Condition=" '$(PackageSources)' == '' ">
|
20
|
+
<!-- Package sources used to restore packages. By default, registered sources under %APPDATA%\NuGet\NuGet.Config will be used -->
|
21
|
+
<!-- The official NuGet package source (https://www.nuget.org/api/v2/) will be excluded if package sources are specified and it does not appear in the list -->
|
22
|
+
<!--
|
23
|
+
<PackageSource Include="https://www.nuget.org/api/v2/" />
|
24
|
+
<PackageSource Include="https://my-nuget-source/nuget/" />
|
25
|
+
-->
|
26
|
+
</ItemGroup>
|
27
|
+
|
28
|
+
<PropertyGroup Condition=" '$(OS)' == 'Windows_NT'">
|
29
|
+
<!-- Windows specific commands -->
|
30
|
+
<NuGetToolsPath>$([System.IO.Path]::Combine($(SolutionDir), ".nuget"))</NuGetToolsPath>
|
31
|
+
<PackagesConfig>$([System.IO.Path]::Combine($(ProjectDir), "packages.config"))</PackagesConfig>
|
32
|
+
</PropertyGroup>
|
33
|
+
|
34
|
+
<PropertyGroup Condition=" '$(OS)' != 'Windows_NT'">
|
35
|
+
<!-- We need to launch nuget.exe with the mono command if we're not on windows -->
|
36
|
+
<NuGetToolsPath>$(SolutionDir).nuget</NuGetToolsPath>
|
37
|
+
<PackagesConfig>packages.config</PackagesConfig>
|
38
|
+
</PropertyGroup>
|
39
|
+
|
40
|
+
<PropertyGroup>
|
41
|
+
<!-- NuGet command -->
|
42
|
+
<NuGetExePath Condition=" '$(NuGetExePath)' == '' ">$(NuGetToolsPath)\NuGet.exe</NuGetExePath>
|
43
|
+
<PackageSources Condition=" $(PackageSources) == '' ">@(PackageSource)</PackageSources>
|
44
|
+
|
45
|
+
<NuGetCommand Condition=" '$(OS)' == 'Windows_NT'">"$(NuGetExePath)"</NuGetCommand>
|
46
|
+
<NuGetCommand Condition=" '$(OS)' != 'Windows_NT' ">mono --runtime=v4.0.30319 $(NuGetExePath)</NuGetCommand>
|
47
|
+
|
48
|
+
<PackageOutputDir Condition="$(PackageOutputDir) == ''">$(TargetDir.Trim('\\'))</PackageOutputDir>
|
49
|
+
|
50
|
+
<RequireConsentSwitch Condition=" $(RequireRestoreConsent) == 'true' ">-RequireConsent</RequireConsentSwitch>
|
51
|
+
<NonInteractiveSwitch Condition=" '$(VisualStudioVersion)' != '' AND '$(OS)' == 'Windows_NT' ">-NonInteractive</NonInteractiveSwitch>
|
52
|
+
|
53
|
+
<PaddedSolutionDir Condition=" '$(OS)' == 'Windows_NT'">"$(SolutionDir) "</PaddedSolutionDir>
|
54
|
+
<PaddedSolutionDir Condition=" '$(OS)' != 'Windows_NT' ">"$(SolutionDir)"</PaddedSolutionDir>
|
55
|
+
|
56
|
+
<!-- Commands -->
|
57
|
+
<RestoreCommand>$(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)" $(NonInteractiveSwitch) $(RequireConsentSwitch) -solutionDir $(PaddedSolutionDir)</RestoreCommand>
|
58
|
+
<BuildCommand>$(NuGetCommand) pack "$(ProjectPath)" -Properties "Configuration=$(Configuration);Platform=$(Platform)" $(NonInteractiveSwitch) -OutputDirectory "$(PackageOutputDir)" -symbols</BuildCommand>
|
59
|
+
|
60
|
+
<!-- We need to ensure packages are restored prior to assembly resolve -->
|
61
|
+
<BuildDependsOn Condition="$(RestorePackages) == 'true'">
|
62
|
+
RestorePackages;
|
63
|
+
$(BuildDependsOn);
|
64
|
+
</BuildDependsOn>
|
65
|
+
|
66
|
+
<!-- Make the build depend on restore packages -->
|
67
|
+
<BuildDependsOn Condition="$(BuildPackage) == 'true'">
|
68
|
+
$(BuildDependsOn);
|
69
|
+
BuildPackage;
|
70
|
+
</BuildDependsOn>
|
71
|
+
</PropertyGroup>
|
72
|
+
|
73
|
+
<Target Name="CheckPrerequisites">
|
74
|
+
<!-- Raise an error if we're unable to locate nuget.exe -->
|
75
|
+
<Error Condition="'$(DownloadNuGetExe)' != 'true' AND !Exists('$(NuGetExePath)')" Text="Unable to locate '$(NuGetExePath)'" />
|
76
|
+
<!--
|
77
|
+
Take advantage of MsBuild's build dependency tracking to make sure that we only ever download nuget.exe once.
|
78
|
+
This effectively acts as a lock that makes sure that the download operation will only happen once and all
|
79
|
+
parallel builds will have to wait for it to complete.
|
80
|
+
-->
|
81
|
+
<MsBuild Targets="_DownloadNuGet" Projects="$(MSBuildThisFileFullPath)" Properties="Configuration=NOT_IMPORTANT;DownloadNuGetExe=$(DownloadNuGetExe)" />
|
82
|
+
</Target>
|
83
|
+
|
84
|
+
<Target Name="_DownloadNuGet">
|
85
|
+
<DownloadNuGet OutputFilename="$(NuGetExePath)" Condition=" '$(DownloadNuGetExe)' == 'true' AND !Exists('$(NuGetExePath)')" />
|
86
|
+
</Target>
|
87
|
+
|
88
|
+
<Target Name="RestorePackages" DependsOnTargets="CheckPrerequisites">
|
89
|
+
<Exec Command="$(RestoreCommand)"
|
90
|
+
Condition="'$(OS)' != 'Windows_NT' And Exists('$(PackagesConfig)')" />
|
91
|
+
|
92
|
+
<Exec Command="$(RestoreCommand)"
|
93
|
+
LogStandardErrorAsError="true"
|
94
|
+
Condition="'$(OS)' == 'Windows_NT' And Exists('$(PackagesConfig)')" />
|
95
|
+
</Target>
|
96
|
+
|
97
|
+
<Target Name="BuildPackage" DependsOnTargets="CheckPrerequisites">
|
98
|
+
<Exec Command="$(BuildCommand)"
|
99
|
+
Condition=" '$(OS)' != 'Windows_NT' " />
|
100
|
+
|
101
|
+
<Exec Command="$(BuildCommand)"
|
102
|
+
LogStandardErrorAsError="true"
|
103
|
+
Condition=" '$(OS)' == 'Windows_NT' " />
|
104
|
+
</Target>
|
105
|
+
|
106
|
+
<UsingTask TaskName="DownloadNuGet" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
|
107
|
+
<ParameterGroup>
|
108
|
+
<OutputFilename ParameterType="System.String" Required="true" />
|
109
|
+
</ParameterGroup>
|
110
|
+
<Task>
|
111
|
+
<Reference Include="System.Core" />
|
112
|
+
<Using Namespace="System" />
|
113
|
+
<Using Namespace="System.IO" />
|
114
|
+
<Using Namespace="System.Net" />
|
115
|
+
<Using Namespace="Microsoft.Build.Framework" />
|
116
|
+
<Using Namespace="Microsoft.Build.Utilities" />
|
117
|
+
<Code Type="Fragment" Language="cs">
|
118
|
+
<![CDATA[
|
119
|
+
try {
|
120
|
+
OutputFilename = Path.GetFullPath(OutputFilename);
|
121
|
+
|
122
|
+
Log.LogMessage("Downloading latest version of NuGet.exe...");
|
123
|
+
WebClient webClient = new WebClient();
|
124
|
+
webClient.DownloadFile("https://www.nuget.org/nuget.exe", OutputFilename);
|
125
|
+
|
126
|
+
return true;
|
127
|
+
}
|
128
|
+
catch (Exception ex) {
|
129
|
+
Log.LogErrorFromException(ex);
|
130
|
+
return false;
|
131
|
+
}
|
132
|
+
]]>
|
133
|
+
</Code>
|
134
|
+
</Task>
|
135
|
+
</UsingTask>
|
136
|
+
</Project>
|
@@ -1,8 +1,15 @@
|
|
1
1
|
|
2
|
-
Microsoft Visual Studio Solution File, Format Version
|
3
|
-
# Visual Studio
|
2
|
+
Microsoft Visual Studio Solution File, Format Version 12.00
|
3
|
+
# Visual Studio 2012
|
4
4
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WindowsForms", "WindowsForms\WindowsForms.csproj", "{79C33EDA-58C4-41EF-93DC-BA679895BD43}"
|
5
5
|
EndProject
|
6
|
+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{C2B59FF1-0EE8-457F-A808-3B558459DA57}"
|
7
|
+
ProjectSection(SolutionItems) = preProject
|
8
|
+
.nuget\NuGet.Config = .nuget\NuGet.Config
|
9
|
+
.nuget\NuGet.exe = .nuget\NuGet.exe
|
10
|
+
.nuget\NuGet.targets = .nuget\NuGet.targets
|
11
|
+
EndProjectSection
|
12
|
+
EndProject
|
6
13
|
Global
|
7
14
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
8
15
|
Debug|Any CPU = Debug|Any CPU
|
@@ -1,7 +1,7 @@
|
|
1
1
|
using System;
|
2
|
-
using System.Linq;
|
3
2
|
using System.Windows.Forms;
|
4
3
|
using FizzWare.NBuilder;
|
4
|
+
using UIA.Extensions;
|
5
5
|
|
6
6
|
namespace WindowsForms
|
7
7
|
{
|
@@ -10,6 +10,7 @@ namespace WindowsForms
|
|
10
10
|
public DataGridView()
|
11
11
|
{
|
12
12
|
InitializeComponent();
|
13
|
+
dataGridView1.AsTable();
|
13
14
|
}
|
14
15
|
|
15
16
|
public class Person
|
@@ -13,6 +13,8 @@
|
|
13
13
|
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
14
14
|
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
|
15
15
|
<FileAlignment>512</FileAlignment>
|
16
|
+
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
|
17
|
+
<RestorePackages>true</RestorePackages>
|
16
18
|
</PropertyGroup>
|
17
19
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
18
20
|
<PlatformTarget>x86</PlatformTarget>
|
@@ -47,9 +49,8 @@
|
|
47
49
|
<Reference Include="System.Drawing" />
|
48
50
|
<Reference Include="System.Windows.Forms" />
|
49
51
|
<Reference Include="System.Xml" />
|
50
|
-
<Reference Include="UIA.Extensions
|
51
|
-
<
|
52
|
-
<HintPath>.\UIA.Extensions.dll</HintPath>
|
52
|
+
<Reference Include="UIA.Extensions">
|
53
|
+
<HintPath>..\packages\UIA.Extensions.1.0.5.0\lib\net35\UIA.Extensions.dll</HintPath>
|
53
54
|
</Reference>
|
54
55
|
<Reference Include="UIAutomationClient" />
|
55
56
|
<Reference Include="UIAutomationProvider" />
|
@@ -123,6 +124,7 @@
|
|
123
124
|
<AutoGen>True</AutoGen>
|
124
125
|
<DependentUpon>Resources.resx</DependentUpon>
|
125
126
|
</Compile>
|
127
|
+
<None Include="packages.config" />
|
126
128
|
<None Include="Properties\Settings.settings">
|
127
129
|
<Generator>SettingsSingleFileGenerator</Generator>
|
128
130
|
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
@@ -135,6 +137,7 @@
|
|
135
137
|
</ItemGroup>
|
136
138
|
<ItemGroup />
|
137
139
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
140
|
+
<Import Project="$(SolutionDir)\.nuget\nuget.targets" />
|
138
141
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
139
142
|
Other similar extension points exist, see Microsoft.Common.targets.
|
140
143
|
<Target Name="BeforeBuild">
|
@@ -168,20 +168,13 @@ module RAutomation
|
|
168
168
|
def control_hwnd(window_hwnd, locators)
|
169
169
|
case
|
170
170
|
when locators[:id]
|
171
|
-
|
172
|
-
raise UnknownElementException, "#{locators[:id]} does not exist" if hwnd == 0
|
173
|
-
hwnd
|
171
|
+
UiaDll.cached_hwnd(UiaDll::SearchCriteria.from_locator(window_hwnd, locators))
|
174
172
|
when locators[:point]
|
175
|
-
|
176
|
-
raise UnknownElementException, "#{locators[:point]} does not exist" if hwnd == 0
|
177
|
-
hwnd
|
173
|
+
UiaDll::handle_from_point(*locators[:point])
|
178
174
|
else
|
179
|
-
|
175
|
+
find_hwnd(locators, window_hwnd) do |hwnd|
|
180
176
|
locators_match?(locators, control_properties(hwnd, locators))
|
181
177
|
end
|
182
|
-
|
183
|
-
raise UnknownElementException, "Element with #{locators.inspect} does not exist" if (hwnd == 0) or (hwnd == nil)
|
184
|
-
hwnd
|
185
178
|
end
|
186
179
|
end
|
187
180
|
|
@@ -11,8 +11,8 @@ module RAutomation
|
|
11
11
|
|
12
12
|
def initialize(select_list, text, index)
|
13
13
|
@select_list = select_list
|
14
|
-
@text
|
15
|
-
@index
|
14
|
+
@text = text
|
15
|
+
@index = index
|
16
16
|
end
|
17
17
|
|
18
18
|
def selected?
|
@@ -28,22 +28,30 @@ module RAutomation
|
|
28
28
|
UiaDll::remove_from_selection @select_list.search_information, @index
|
29
29
|
end
|
30
30
|
|
31
|
+
def self.locators_match?(locators, item)
|
32
|
+
locators.all? do |locator, value|
|
33
|
+
return item.text =~ value if value.is_a? Regexp
|
34
|
+
return item.send(locator) == value
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
31
38
|
alias_method :set, :select
|
32
39
|
end
|
33
40
|
|
34
|
-
def
|
35
|
-
|
41
|
+
def option(locator)
|
42
|
+
options(locator).first
|
43
|
+
end
|
36
44
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
end
|
45
|
+
def options(locator = {})
|
46
|
+
all_options.select { |item| SelectListOption.locators_match? locator, item }
|
47
|
+
end
|
48
|
+
|
49
|
+
def select(locator = {})
|
50
|
+
options(locator).each(&:select)
|
51
|
+
end
|
45
52
|
|
46
|
-
|
53
|
+
def clear(locator = {})
|
54
|
+
options(locator).each(&:clear)
|
47
55
|
end
|
48
56
|
|
49
57
|
def value
|
@@ -54,14 +62,6 @@ module RAutomation
|
|
54
62
|
UiaDll::selections(search_information)
|
55
63
|
end
|
56
64
|
|
57
|
-
def option(options)
|
58
|
-
UiaDll::select_options(search_information).each_with_index do |item, item_no|
|
59
|
-
return SelectListOption.new(self, item, item_no) if options[:text] == item
|
60
|
-
end
|
61
|
-
|
62
|
-
nil
|
63
|
-
end
|
64
|
-
|
65
65
|
def exist?
|
66
66
|
super && matches_type?(Constants::UIA_COMBOBOX_CONTROL_TYPE)
|
67
67
|
end
|
@@ -69,11 +69,16 @@ module RAutomation
|
|
69
69
|
alias_method :exists?, :exist?
|
70
70
|
|
71
71
|
private
|
72
|
-
|
73
72
|
def item_count
|
74
73
|
UiaDll::select_list_count(search_information)
|
75
74
|
end
|
76
75
|
|
76
|
+
def all_options
|
77
|
+
UiaDll::select_options(search_information).each_with_index.map do |item, index|
|
78
|
+
SelectListOption.new(self, item, index)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
77
82
|
end
|
78
83
|
end
|
79
84
|
end
|
@@ -41,8 +41,9 @@ module RAutomation
|
|
41
41
|
cells(locators).first
|
42
42
|
end
|
43
43
|
|
44
|
-
def initialize(
|
45
|
-
@
|
44
|
+
def initialize(table, locators)
|
45
|
+
@table = table
|
46
|
+
@search_information = table.search_information
|
46
47
|
@locators = extract(locators)
|
47
48
|
end
|
48
49
|
|
@@ -67,7 +68,7 @@ module RAutomation
|
|
67
68
|
end
|
68
69
|
|
69
70
|
def exists?
|
70
|
-
|
71
|
+
@locators[:index].between? 0, @table.row_count - 1
|
71
72
|
end
|
72
73
|
|
73
74
|
def self.locators_match?(locators, item)
|
@@ -98,6 +99,18 @@ module RAutomation
|
|
98
99
|
end
|
99
100
|
end
|
100
101
|
|
102
|
+
def select(locators={})
|
103
|
+
rows(locators).each(&:select)
|
104
|
+
end
|
105
|
+
|
106
|
+
def clear(locators={})
|
107
|
+
rows(locators).each(&:clear)
|
108
|
+
end
|
109
|
+
|
110
|
+
def selected_rows
|
111
|
+
UiaDll.table_selected_indexes(search_information).map {|index| Row.new(self, index: index) }
|
112
|
+
end
|
113
|
+
|
101
114
|
def strings
|
102
115
|
headers = UiaDll.table_headers(search_information)
|
103
116
|
values = UiaDll.table_values(search_information)
|
@@ -94,7 +94,7 @@ module RAutomation
|
|
94
94
|
def data=(value)
|
95
95
|
case how
|
96
96
|
when :hwnd
|
97
|
-
self[:data][:int_data] = value
|
97
|
+
self[:data][:int_data] = value || 0 # cannot accept nil
|
98
98
|
when :id, :value
|
99
99
|
self[:data][:string_data] = value
|
100
100
|
when :point
|
@@ -302,6 +302,8 @@ module RAutomation
|
|
302
302
|
[SearchCriteria.by_ref, :pointer], :int
|
303
303
|
attach_function :Table_GetValues,
|
304
304
|
[SearchCriteria.by_ref, :pointer], :int
|
305
|
+
attach_function :Table_GetSelectedIndexes,
|
306
|
+
[SearchCriteria.by_ref, :pointer], :int
|
305
307
|
attach_function :table_row_count, :Table_RowCount,
|
306
308
|
[SearchCriteria.by_ref], :int
|
307
309
|
attach_function :Table_CoordinateIsValid,
|
@@ -310,6 +312,8 @@ module RAutomation
|
|
310
312
|
[SearchCriteria.by_ref, :int, :int, :pointer, :int], :void
|
311
313
|
attach_function :Table_SelectByIndex,
|
312
314
|
[SearchCriteria.by_ref, :int, :pointer, :int], :void
|
315
|
+
attach_function :Table_SingleSelectByIndex,
|
316
|
+
[SearchCriteria.by_ref, :int, :pointer, :int], :void
|
313
317
|
attach_function :Table_SelectByValue,
|
314
318
|
[SearchCriteria.by_ref, :string, :pointer, :int], :void
|
315
319
|
attach_function :table_row_is_selected, :Table_IsSelectedByIndex,
|
@@ -319,6 +323,10 @@ module RAutomation
|
|
319
323
|
attach_function :Table_RemoveRowByValue,
|
320
324
|
[SearchCriteria.by_ref, :string, :pointer, :int], :void
|
321
325
|
|
326
|
+
def self.table_selected_indexes(search_information)
|
327
|
+
integers_from(:Table_GetSelectedIndexes, search_information)
|
328
|
+
end
|
329
|
+
|
322
330
|
def self.table_select(search_information, which_item)
|
323
331
|
case which_item
|
324
332
|
when Integer
|
@@ -328,6 +336,10 @@ module RAutomation
|
|
328
336
|
end
|
329
337
|
end
|
330
338
|
|
339
|
+
def self.table_single_select(search_information, which_item)
|
340
|
+
can_throw(:Table_SingleSelectByIndex, search_information, which_item)
|
341
|
+
end
|
342
|
+
|
331
343
|
def self.table_value_at(search_information, row, column=0)
|
332
344
|
string_from(:Table_ValueAt, search_information, row, column)
|
333
345
|
end
|
@@ -381,6 +393,13 @@ module RAutomation
|
|
381
393
|
end
|
382
394
|
|
383
395
|
private
|
396
|
+
def self.integers_from(method, search_information)
|
397
|
+
item_count = send method, search_information, nil
|
398
|
+
pointer = FFI::MemoryPointer.new :pointer, item_count
|
399
|
+
send method, search_information, pointer
|
400
|
+
pointer.read_array_of_int(item_count)
|
401
|
+
end
|
402
|
+
|
384
403
|
def self.strings_from(method, hwnd)
|
385
404
|
string_count = send method, hwnd, nil
|
386
405
|
pointer = FFI::MemoryPointer.new :pointer, string_count
|
data/rautomation.gemspec
CHANGED
@@ -27,7 +27,7 @@ RAutomation provides:
|
|
27
27
|
s.require_paths = ["lib"]
|
28
28
|
|
29
29
|
s.add_runtime_dependency("ffi")
|
30
|
-
s.add_development_dependency("rspec", "~>2.
|
30
|
+
s.add_development_dependency("rspec", "~> 2.14")
|
31
31
|
s.add_development_dependency("rake")
|
32
32
|
s.add_development_dependency("yard")
|
33
33
|
end
|
@@ -15,7 +15,7 @@ describe 'MsUia::SelectList', :if => SpecHelper.adapter == :ms_uia do
|
|
15
15
|
about.select_list(:id => 'multiFruitListBox')
|
16
16
|
end
|
17
17
|
|
18
|
-
it '#
|
18
|
+
it '#select_list' do
|
19
19
|
fruits_combo.should exist
|
20
20
|
|
21
21
|
RAutomation::Window.wait_timeout = 0.1
|
@@ -29,37 +29,43 @@ describe 'MsUia::SelectList', :if => SpecHelper.adapter == :ms_uia do
|
|
29
29
|
fruits_combo.should exist
|
30
30
|
end
|
31
31
|
|
32
|
-
|
33
|
-
|
32
|
+
context 'SelectListOption' do
|
33
|
+
it '#selected? & #select' do
|
34
|
+
fruits_combo.options(:text => 'Apple')[0].should_not be_selected
|
35
|
+
fruits_combo.options(:text => 'Apple')[0].select.should be_true
|
36
|
+
fruits_combo.options(:text => 'Apple')[0].should be_selected
|
37
|
+
end
|
34
38
|
|
35
|
-
|
36
|
-
fruits_combo.options.map {|option| option.text}.should == expected_options
|
37
|
-
end
|
39
|
+
it '#value' do
|
38
40
|
|
39
|
-
|
40
|
-
|
41
|
-
fruits_combo.options(:text => 'Apple')[0].select.should be_true
|
42
|
-
fruits_combo.options(:text => 'Apple')[0].should be_selected
|
43
|
-
end
|
41
|
+
#default empty state
|
42
|
+
fruits_combo.value.should == ''
|
44
43
|
|
45
|
-
|
44
|
+
fruits_combo.options(:text => 'Apple')[0].select
|
45
|
+
fruits_combo.value.should == 'Apple'
|
46
46
|
|
47
|
-
|
48
|
-
|
47
|
+
fruits_combo.options(:text => 'Caimito')[0].select
|
48
|
+
fruits_combo.value.should == 'Caimito'
|
49
|
+
end
|
49
50
|
|
50
|
-
|
51
|
-
|
51
|
+
it 'enabled/disabled' do
|
52
|
+
fruits_combo.should be_enabled
|
53
|
+
fruits_combo.should_not be_disabled
|
52
54
|
|
53
|
-
|
54
|
-
|
55
|
+
disabled_combo.should_not be_enabled
|
56
|
+
disabled_combo.should be_disabled
|
57
|
+
end
|
55
58
|
end
|
56
59
|
|
57
|
-
it '
|
58
|
-
|
59
|
-
|
60
|
+
it '#select' do
|
61
|
+
multi_fruits.select text: /ng/
|
62
|
+
multi_fruits.values.should eq(['Orange', 'Mango'])
|
63
|
+
end
|
60
64
|
|
61
|
-
|
62
|
-
|
65
|
+
it '#clear' do
|
66
|
+
multi_fruits.select # select all
|
67
|
+
multi_fruits.clear text: 'Orange'
|
68
|
+
multi_fruits.values.should eq(['Apple', 'Mango'])
|
63
69
|
end
|
64
70
|
|
65
71
|
it '#values' do
|
@@ -73,10 +79,19 @@ describe 'MsUia::SelectList', :if => SpecHelper.adapter == :ms_uia do
|
|
73
79
|
|
74
80
|
it '#option' do
|
75
81
|
fruits_combo.option(:text => 'Apple').should_not be_selected
|
76
|
-
fruits_combo.option(:
|
82
|
+
fruits_combo.option(:index => 0).set
|
77
83
|
fruits_combo.option(:text => 'Apple').should be_selected
|
78
84
|
end
|
79
85
|
|
86
|
+
it '#options' do
|
87
|
+
fruits_combo.options.size.should == 5
|
88
|
+
fruits_combo.options.map(&:text).should eq(['Apple', 'Caimito', 'Coconut', 'Orange', 'Passion Fruit'])
|
89
|
+
|
90
|
+
fruits_combo.options(text: 'Apple').map(&:text).should eq ['Apple']
|
91
|
+
fruits_combo.options(text: /Ap{2}le/).map(&:text).should eq ['Apple']
|
92
|
+
fruits_combo.options(index: 0).map(&:text).should eq ['Apple']
|
93
|
+
end
|
94
|
+
|
80
95
|
it 'cannot select anything on a disabled select list' do
|
81
96
|
expect { disabled_combo.option(:text => 'Apple').set }.to raise_error
|
82
97
|
end
|
@@ -1,12 +1,14 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe
|
3
|
+
describe 'MsUia::Table', :if => SpecHelper.adapter == :ms_uia do
|
4
|
+
let(:window) { RAutomation::Window.new(:title => "MainFormWindow") }
|
4
5
|
let(:data_entry) { RAutomation::Window.new(:title => "DataEntryForm") }
|
6
|
+
let(:data_grid_view) { window.button(value: 'Data Grid View').click {true}; RAutomation::Window.new(title: /DataGridView/) }
|
7
|
+
let(:large_grid) { data_entry.close; data_grid_view.table(id: 'dataGridView1') }
|
5
8
|
let(:table) { data_entry.table(:id => "personListView") }
|
6
9
|
let(:toggle_multi_select) { data_entry.button(:value => 'Toggle Multi').click { true } }
|
7
10
|
|
8
11
|
before :each do
|
9
|
-
window = RAutomation::Window.new(:title => "MainFormWindow")
|
10
12
|
window.button(:value => "Data Entry Form").click { RAutomation::Window.new(:title => "DataEntryForm").exists? }
|
11
13
|
end
|
12
14
|
|
@@ -42,11 +44,42 @@ describe "MsUia::Table", :if => SpecHelper.adapter == :ms_uia do
|
|
42
44
|
table.row_count.should eq(2)
|
43
45
|
end
|
44
46
|
|
47
|
+
it '#select' do
|
48
|
+
large_grid.select value: /^FirstName[1-9]$/
|
49
|
+
first_nine = large_grid.rows.take(9)
|
50
|
+
expect(first_nine.count).to be 9
|
51
|
+
first_nine.should be_all(&:selected?)
|
52
|
+
end
|
53
|
+
|
54
|
+
it '#clear' do
|
55
|
+
first_three = large_grid.rows.take(3)
|
56
|
+
next_six = large_grid.rows.take_while { |r| r.index.between?(3, 9) }
|
57
|
+
large_grid.select value: /^FirstName[1-9]$/
|
58
|
+
|
59
|
+
large_grid.clear value: /^FirstName[1-3]$/
|
60
|
+
|
61
|
+
first_three.all?(&:selected?).should be_false
|
62
|
+
next_six.all?(&:selected?).should be_true
|
63
|
+
end
|
64
|
+
|
65
|
+
it '#selected_rows' do
|
66
|
+
large_grid.select value: /^FirstName[1-5]$/
|
67
|
+
large_grid.selected_rows.map(&:index).should eq([0, 1, 2, 3, 4])
|
68
|
+
end
|
69
|
+
|
45
70
|
context "#rows" do
|
46
71
|
it "has rows" do
|
47
72
|
table.rows.size.should eq 2
|
48
73
|
end
|
49
74
|
|
75
|
+
it 'are quick to find' do
|
76
|
+
large_grid.row_count.should eq(51)
|
77
|
+
|
78
|
+
start = Time.now
|
79
|
+
large_grid.row(index: 50).should exist
|
80
|
+
(Time.now - start).should be < 1.5
|
81
|
+
end
|
82
|
+
|
50
83
|
it "have values" do
|
51
84
|
table.rows.map(&:value).should eq ["John Doe", "Anna Doe"]
|
52
85
|
end
|
@@ -3,8 +3,6 @@ require "spec_helper"
|
|
3
3
|
describe "MsUia::Window", :if => SpecHelper.adapter == :ms_uia do
|
4
4
|
let(:window) {RAutomation::Window.new(:title => /MainFormWindow/i)}
|
5
5
|
|
6
|
-
|
7
|
-
|
8
6
|
it "move and click" do
|
9
7
|
#window = RAutomation::Window.new(:title => /MainFormWindow/i)
|
10
8
|
window.maximize
|
@@ -12,7 +10,6 @@ describe "MsUia::Window", :if => SpecHelper.adapter == :ms_uia do
|
|
12
10
|
sleep 1
|
13
11
|
window.click_mouse
|
14
12
|
sleep 1
|
15
|
-
|
16
13
|
end
|
17
14
|
|
18
15
|
context "#send_keys" do
|
data/spec/window_spec.rb
CHANGED
@@ -130,14 +130,20 @@ describe RAutomation::Window do
|
|
130
130
|
to_not raise_exception
|
131
131
|
end
|
132
132
|
|
133
|
-
|
134
|
-
window
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
133
|
+
context '#child', :if => [:win_32, :ms_uia].include?(SpecHelper.adapter) do
|
134
|
+
let(:window) { RAutomation::Window.new(:title => SpecHelper::DATA[:window1_full_title]) }
|
135
|
+
|
136
|
+
it 'immediate children' do
|
137
|
+
# buttons are windows too. so let's find the button for now
|
138
|
+
child = window.child(:title => '&About')
|
139
|
+
child.should exist
|
140
|
+
child.title.should == "&About"
|
141
|
+
child.adapter.should == SpecHelper.adapter
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'popups' do
|
145
|
+
window.button(:title => '&About').click { true }
|
146
|
+
window.child(:title => 'About').should be_visible
|
147
|
+
end
|
142
148
|
end
|
143
149
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rautomation
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.14.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jarmo Pertman
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2014-02-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ffi
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - ~>
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '2.
|
33
|
+
version: '2.14'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ~>
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '2.
|
40
|
+
version: '2.14'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rake
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -119,6 +119,8 @@ files:
|
|
119
119
|
- ext/UiaDll/RAutomation.UIA/Properties/AutomationProperties.cs
|
120
120
|
- ext/UiaDll/RAutomation.UIA/RAutomation.UIA.csproj
|
121
121
|
- ext/UiaDll/UiaDll.sln
|
122
|
+
- ext/UiaDll/UiaDll/ArrayHelper.cpp
|
123
|
+
- ext/UiaDll/UiaDll/ArrayHelper.h
|
122
124
|
- ext/UiaDll/UiaDll/AssemblyInfo.cpp
|
123
125
|
- ext/UiaDll/UiaDll/ControlMethods.cpp
|
124
126
|
- ext/UiaDll/UiaDll/DynamicAssemblyResolver.cpp
|
@@ -149,6 +151,9 @@ files:
|
|
149
151
|
- ext/UiaDll/UiaDll/stdafx.cpp
|
150
152
|
- ext/UiaDll/UiaDll/stdafx.h
|
151
153
|
- ext/UiaDll/UiaDll/targetver.h
|
154
|
+
- ext/WindowsForms/.nuget/NuGet.Config
|
155
|
+
- ext/WindowsForms/.nuget/NuGet.exe
|
156
|
+
- ext/WindowsForms/.nuget/NuGet.targets
|
152
157
|
- ext/WindowsForms/WindowsForms.sln
|
153
158
|
- ext/WindowsForms/WindowsForms/AboutBox.Designer.cs
|
154
159
|
- ext/WindowsForms/WindowsForms/AboutBox.cs
|
@@ -178,6 +183,7 @@ files:
|
|
178
183
|
- ext/WindowsForms/WindowsForms/UIA.Extensions.dll
|
179
184
|
- ext/WindowsForms/WindowsForms/ValueMonthCalendar.cs
|
180
185
|
- ext/WindowsForms/WindowsForms/WindowsForms.csproj
|
186
|
+
- ext/WindowsForms/WindowsForms/packages.config
|
181
187
|
- lib/rautomation.rb
|
182
188
|
- lib/rautomation/adapter/autoit.rb
|
183
189
|
- lib/rautomation/adapter/autoit/button.rb
|