rautomation 0.13.0 → 0.14.0
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 +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
|