uia 0.0.6.1 → 0.0.7
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/ChangeLog +14 -0
- data/README.md +127 -46
- data/ext/UiaDll/Release/UIA.Helper.dll +0 -0
- data/ext/UiaDll/Release/UiaDll.dll +0 -0
- data/ext/UiaDll/UiaDll/ElementMethods.cpp +15 -11
- data/ext/UiaDll/UiaDll/ElementStructures.h +15 -1
- data/ext/UiaDll/UiaDll/PatternInformationStructures.h +77 -1
- data/ext/UiaDll/UiaDll/SelectionItemMethods.cpp +1 -0
- data/ext/UiaDll/UiaDll/TableItemMethods.cpp +16 -0
- data/ext/UiaDll/UiaDll/TableMethods.cpp +16 -0
- data/ext/UiaDll/UiaDll/UiaDll.vcxproj +4 -0
- data/ext/UiaDll/UiaDll/UiaDll.vcxproj.filters +9 -0
- data/ext/UiaDll/UiaDll/WindowMethods.cpp +24 -0
- data/ext/UiaDll/UiaDll.Test/ElementInformationTest.cpp +15 -0
- data/ext/UiaDll/UiaDll.Test/PatternInformationTest.cpp +14 -1
- data/ext/UiaDll/UiaDll.Test/UiaDll.Test.vcxproj +2 -0
- data/lib/core_ext/string.rb +5 -0
- data/lib/core_ext/symbol.rb +5 -0
- data/lib/uia/element.rb +26 -17
- data/lib/uia/library/element_structs.rb +95 -0
- data/lib/uia/library/pattern_structs.rb +155 -0
- data/lib/uia/library.rb +36 -12
- data/lib/uia/patterns/expand_collapse.rb +1 -1
- data/lib/uia/patterns/table.rb +32 -0
- data/lib/uia/patterns/table_item.rb +18 -0
- data/lib/uia/patterns/toggle.rb +1 -1
- data/lib/uia/patterns/window.rb +38 -0
- data/lib/uia/version.rb +1 -1
- data/lib/uia.rb +6 -2
- data/spec/uia/element_spec.rb +20 -0
- data/spec/uia/patterns/table_item_spec.rb +21 -0
- data/spec/uia/patterns/table_spec.rb +34 -0
- data/spec/uia/patterns/window_spec.rb +31 -0
- data/uia.gemspec +1 -0
- metadata +36 -5
- data/lib/uia/library/structs.rb +0 -174
data/ChangeLog
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
=== Version 0.0.7 / 2013-11-01
|
2
|
+
* Enhancements
|
3
|
+
* added a base implementation for the Window pattern
|
4
|
+
* added support for WindowPattern, TablePattern and TableItemPattern
|
5
|
+
* Element#as raises UnsupportedPattern if the element does not implement it
|
6
|
+
* added an Element#select method to filter descendants by:
|
7
|
+
- pattern
|
8
|
+
- name
|
9
|
+
- id
|
10
|
+
|
11
|
+
* Bug Fixes
|
12
|
+
* modified ffi calls that return Element arrays to be individually GC'd.
|
13
|
+
This prevents FFI::ManagedStruct from being taken out from underneath you
|
14
|
+
|
1
15
|
=== Version 0.0.6.1 / 2013-10-30
|
2
16
|
* Bug Fixes
|
3
17
|
* Fixed issue when finding root children by RegEx initially
|
data/README.md
CHANGED
@@ -1,46 +1,127 @@
|
|
1
|
-
# Uia
|
2
|
-
|
3
|
-
The `Uia` gem is a low-level driver for interacting with Microsoft UIA elements in a Windows environment.
|
4
|
-
|
5
|
-
## Installation
|
6
|
-
|
7
|
-
Add this line to your application's Gemfile:
|
8
|
-
|
9
|
-
gem 'uia'
|
10
|
-
|
11
|
-
And then execute:
|
12
|
-
|
13
|
-
$ bundle
|
14
|
-
|
15
|
-
Or install it yourself as:
|
16
|
-
|
17
|
-
$ gem install uia
|
18
|
-
|
19
|
-
## Usage
|
20
|
-
|
21
|
-
Getting started with `uia` is easy. Simply require `uia` and then include the `Uia` module wherever you would like to use it.
|
22
|
-
|
23
|
-
```ruby
|
24
|
-
require 'uia'
|
25
|
-
|
26
|
-
include Uia
|
27
|
-
|
28
|
-
main_window = find_element id: 'MainFormWindow'
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
1
|
+
# Uia
|
2
|
+
|
3
|
+
The `Uia` gem is a low-level driver for interacting with Microsoft UIA elements in a Windows environment.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'uia'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install uia
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
Getting started with `uia` is easy. Simply require `uia` and then include the `Uia` module wherever you would like to use it.
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
require 'uia'
|
25
|
+
|
26
|
+
include Uia
|
27
|
+
|
28
|
+
main_window = find_element id: 'MainFormWindow'
|
29
|
+
|
30
|
+
# returns all elements under main_window that are of control type button
|
31
|
+
main_window.select(control_type: :button)
|
32
|
+
|
33
|
+
# returns the values of every element that implements the ValuePattern
|
34
|
+
main_window.select(pattern: :value).map {|e| e.as :value}.map &:value
|
35
|
+
```
|
36
|
+
|
37
|
+
### Finding Elements
|
38
|
+
|
39
|
+
You can locate elements based on the following criteria:
|
40
|
+
|
41
|
+
* `:id` - find by their `AutomationId` (`String` and `Regexp`)
|
42
|
+
* `:pid` - find an element by their process id (`String` and `Regexp`)
|
43
|
+
* `:handle` - find an element by their native window handle (`Fixnum`)
|
44
|
+
* `:runtime_id` - find an element by their `RuntimeId` (i.e. `[42, 12345]`)
|
45
|
+
|
46
|
+
### `Element`
|
47
|
+
The `Element` class is a representation of the [`AutomationElement`](http://msdn.microsoft.com/en-us/library/system.windows.automation.automationelement.aspx) class in Microsoft UIA. It is the object that is returned from the root `Uia#find_element` as well as the `Element#find` and `Element#select` methods.
|
48
|
+
|
49
|
+
#### Properties
|
50
|
+
|
51
|
+
* `id` - returns the automation id of th element
|
52
|
+
* `name` - returns the name of the element
|
53
|
+
* `handle` - returns the native window handle of the element
|
54
|
+
* `class_name` - returns the class name of the element
|
55
|
+
* `patterns` - returns the patterns that element implements (i.e. `[:window, :transform]`)
|
56
|
+
|
57
|
+
#### Methods
|
58
|
+
|
59
|
+
##### #as
|
60
|
+
The `#as` method will decorate the `Element` with the specific pattern that you would like to interact with.
|
61
|
+
|
62
|
+
```ruby
|
63
|
+
button = Uia.find_element(id: /MainForm/).find(id: 'aboutButton').as :invoke
|
64
|
+
button.invoke
|
65
|
+
```
|
66
|
+
|
67
|
+
### Patterns
|
68
|
+
#### Window
|
69
|
+
Decorates your `Element` with the following methods:
|
70
|
+
* `visual_state` - `:minimized, :maximized, :normal`
|
71
|
+
* `visual_state=` - sets the visual state
|
72
|
+
* `can_minimize?` / `can_maximize?`
|
73
|
+
* `modal?`
|
74
|
+
* `topmost?`
|
75
|
+
* `interaction_state` - `:blocked_by_modalwindow, :closing, :not_responding, :ready_for_user_interaction, :running`
|
76
|
+
|
77
|
+
#### Value
|
78
|
+
* `value` - returns the value
|
79
|
+
* `value=` - sets the value
|
80
|
+
* `read_only?`
|
81
|
+
|
82
|
+
#### Invoke
|
83
|
+
* `invoke` - invokes the control
|
84
|
+
|
85
|
+
#### ExpandCollapse
|
86
|
+
* `expand` - expands the element
|
87
|
+
* `collapse` - collapses the element
|
88
|
+
* `expand_collapse_state` - `:collapsed, :expanded, :leaf_node, :partially_expanded`
|
89
|
+
|
90
|
+
#### Toggle
|
91
|
+
* `toggle` - toggles the element
|
92
|
+
* `toggle_state` - `:on, :off, :indeterminate`
|
93
|
+
* `toggle_state=` - sets the toggle state
|
94
|
+
|
95
|
+
#### Table
|
96
|
+
* `row_count`
|
97
|
+
* `column_count`
|
98
|
+
* `headers` - returns the `Element` objects that make up the headers
|
99
|
+
* `rows` - returns all `Element` objects that are of control type `data_item`
|
100
|
+
* extends each `Element` with `Table::Row`
|
101
|
+
|
102
|
+
#### Table::Row
|
103
|
+
* `items` - returns all descendants of the row that implement the `:table_item` pattern
|
104
|
+
|
105
|
+
#### TableItem
|
106
|
+
* `column`
|
107
|
+
* `row`
|
108
|
+
|
109
|
+
#### Selection
|
110
|
+
* `selection_items` - return all descendants of the `Selection` that implement the `:selection_item` pattern
|
111
|
+
* `multi_select?`
|
112
|
+
* `selection_required?`
|
113
|
+
|
114
|
+
#### SelectionItem
|
115
|
+
* `select` - selects the item
|
116
|
+
* `add_to_selection` - adds the element to the selection
|
117
|
+
* `remove_from_selection` - removes the element from the selection
|
118
|
+
* `selected?` - whether or not it is selected
|
119
|
+
* `container` - the `Selection` container
|
120
|
+
|
121
|
+
## Contributing
|
122
|
+
|
123
|
+
1. Fork it
|
124
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
125
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
126
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
127
|
+
5. Create new Pull Request
|
Binary file
|
Binary file
|
@@ -97,33 +97,37 @@ extern "C" {
|
|
97
97
|
return NULL;
|
98
98
|
}
|
99
99
|
|
100
|
-
__declspec(dllexport)
|
100
|
+
__declspec(dllexport) int Root_Children(ElementInformation** children, char* errorInfo, const int errorInfoLength) {
|
101
101
|
try {
|
102
|
-
|
102
|
+
auto windows = Element::Windows;
|
103
|
+
*children = ElementInformation::From(windows);
|
104
|
+
return windows->Length;
|
103
105
|
} catch(Exception^ e) {
|
104
106
|
StringHelper::CopyToUnmanagedString(e->Message, errorInfo, errorInfoLength);
|
105
|
-
return
|
107
|
+
return 0;
|
106
108
|
}
|
107
109
|
}
|
108
110
|
|
109
|
-
__declspec(dllexport)
|
111
|
+
__declspec(dllexport) int Element_Children(ElementInformationPtr parentElement, ElementInformation** children, char* errorInfo, const int errorLength) {
|
110
112
|
try {
|
111
|
-
|
113
|
+
auto elements = Find(parentElement)->Children;
|
114
|
+
*children = ElementInformation::From(elements);
|
115
|
+
return elements->Length;
|
112
116
|
} catch(Exception^ error) {
|
113
117
|
StringHelper::CopyToUnmanagedString(error->Message, errorInfo, errorLength);
|
118
|
+
return 0;
|
114
119
|
}
|
115
|
-
|
116
|
-
return NULL;
|
117
120
|
}
|
118
121
|
|
119
|
-
__declspec(dllexport)
|
122
|
+
__declspec(dllexport) int Element_Descendants(ElementInformationPtr parentElement, ElementInformation** descendants, char* errorInfo, const int errorLength) {
|
120
123
|
try {
|
121
|
-
|
124
|
+
auto elements = Find(parentElement)->Descendants;
|
125
|
+
*descendants = ElementInformation::From(elements);
|
126
|
+
return elements->Length;
|
122
127
|
} catch(Exception^ error) {
|
123
128
|
StringHelper::CopyToUnmanagedString(error->Message, errorInfo, errorLength);
|
129
|
+
return 0;
|
124
130
|
}
|
125
|
-
|
126
|
-
return NULL;
|
127
131
|
}
|
128
132
|
|
129
133
|
__declspec(dllexport) void Element_Click(ElementInformationPtr element, char* errorInfo, const int errorLength) {
|
@@ -25,6 +25,18 @@ typedef struct _ElementInformation {
|
|
25
25
|
return nullptr != element ? new _ElementInformation(element) : NULL;
|
26
26
|
}
|
27
27
|
|
28
|
+
static _ElementInformation* From(...array<Element^>^ elements) {
|
29
|
+
if( nullptr == elements || elements->Length == 0 ) return NULL;
|
30
|
+
|
31
|
+
auto elementInformation = new _ElementInformation[elements->Length];
|
32
|
+
auto index = 0;
|
33
|
+
for each(auto element in elements) {
|
34
|
+
elementInformation[index++].Refresh(element);
|
35
|
+
}
|
36
|
+
|
37
|
+
return elementInformation;
|
38
|
+
}
|
39
|
+
|
28
40
|
void Refresh(Element^ element) {
|
29
41
|
Reset();
|
30
42
|
id = StringHelper::ToUnmanaged(element->Id);
|
@@ -58,7 +70,9 @@ typedef struct _Elements {
|
|
58
70
|
|
59
71
|
_Elements() : length(0), elements(NULL) {}
|
60
72
|
|
61
|
-
_Elements(array<Element^>^ elements) : elements(NULL) {
|
73
|
+
_Elements(array<Element^>^ elements) : length(0), elements(NULL) {
|
74
|
+
if( nullptr == elements ) return;
|
75
|
+
|
62
76
|
length = elements->Length;
|
63
77
|
if( length > 0 ) this->elements = new ElementInformation[length];
|
64
78
|
|
@@ -3,6 +3,8 @@
|
|
3
3
|
#include "StringHelper.h"
|
4
4
|
#include "ElementStructures.h"
|
5
5
|
|
6
|
+
using namespace System;
|
7
|
+
using namespace System::Linq;
|
6
8
|
using namespace System::Windows::Automation;
|
7
9
|
|
8
10
|
typedef struct _ValuePatternInformation {
|
@@ -87,4 +89,78 @@ typedef struct _ExpandCollapseInfo {
|
|
87
89
|
~_ExpandCollapseInfo() {
|
88
90
|
delete[] ExpandCollapseState;
|
89
91
|
}
|
90
|
-
} ExpandCollapseInfo, *ExpandCollapseInfoPtr;
|
92
|
+
} ExpandCollapseInfo, *ExpandCollapseInfoPtr;
|
93
|
+
|
94
|
+
typedef struct _WindowInformation {
|
95
|
+
char* VisualState;
|
96
|
+
char* InteractionState;
|
97
|
+
bool CanMinimize;
|
98
|
+
bool CanMaximize;
|
99
|
+
bool IsModal;
|
100
|
+
bool IsTopmost;
|
101
|
+
|
102
|
+
_WindowInformation(WindowVisualState visualState, WindowInteractionState interactionState) {
|
103
|
+
init(visualState, interactionState);
|
104
|
+
}
|
105
|
+
|
106
|
+
_WindowInformation(WindowPattern::WindowPatternInformation^ windowInformation) {
|
107
|
+
init(windowInformation->WindowVisualState, windowInformation->WindowInteractionState);
|
108
|
+
CanMinimize = windowInformation->CanMinimize;
|
109
|
+
CanMaximize = windowInformation->CanMaximize;
|
110
|
+
IsModal = windowInformation->IsModal;
|
111
|
+
IsTopmost = windowInformation->IsTopmost;
|
112
|
+
}
|
113
|
+
|
114
|
+
~_WindowInformation() {
|
115
|
+
delete[] VisualState;
|
116
|
+
delete[] InteractionState;
|
117
|
+
}
|
118
|
+
|
119
|
+
private:
|
120
|
+
void init(WindowVisualState visualState, WindowInteractionState interactionState) {
|
121
|
+
VisualState = StringHelper::ToUnmanaged(visualState.ToString());
|
122
|
+
InteractionState = StringHelper::ToUnmanaged(interactionState.ToString());
|
123
|
+
}
|
124
|
+
|
125
|
+
} WindowInformation, *WindowInformationPtr;
|
126
|
+
|
127
|
+
typedef struct _TableInformation {
|
128
|
+
int RowCount;
|
129
|
+
int ColumnCount;
|
130
|
+
ElementsPtr Headers;
|
131
|
+
|
132
|
+
_TableInformation(int rowCount, int columnCount, ...array<Element^> ^headers) {
|
133
|
+
init(rowCount, columnCount, headers);
|
134
|
+
}
|
135
|
+
|
136
|
+
_TableInformation(TablePattern::TablePatternInformation^ tableInfo) {
|
137
|
+
auto headers = tableInfo->GetColumnHeaders();
|
138
|
+
auto toElementFunc = gcnew Func<AutomationElement^, Element^>(Element::From);
|
139
|
+
|
140
|
+
init(tableInfo->RowCount, tableInfo->ColumnCount, Enumerable::ToArray(Enumerable::Select<AutomationElement^, Element^>(headers, toElementFunc)));
|
141
|
+
}
|
142
|
+
|
143
|
+
~_TableInformation() {
|
144
|
+
delete Headers;
|
145
|
+
}
|
146
|
+
|
147
|
+
private:
|
148
|
+
void init(int rowCount, int columnCount, ...array<Element^> ^headers) {
|
149
|
+
RowCount = rowCount;
|
150
|
+
ColumnCount = columnCount;
|
151
|
+
|
152
|
+
Headers = new Elements(headers);
|
153
|
+
}
|
154
|
+
|
155
|
+
} TableInformation, *TableInformationPtr;
|
156
|
+
|
157
|
+
typedef struct _TableItemInformation {
|
158
|
+
int Column;
|
159
|
+
int Row;
|
160
|
+
|
161
|
+
_TableItemInformation(TableItemPattern::TableItemPatternInformation^ tableItemInfo) {
|
162
|
+
Column = tableItemInfo->Column;
|
163
|
+
Row = tableItemInfo->Row;
|
164
|
+
}
|
165
|
+
|
166
|
+
} TableItemInformation, *TableItemInformationPtr;
|
@@ -0,0 +1,16 @@
|
|
1
|
+
#include "Stdafx.h"
|
2
|
+
|
3
|
+
extern "C" {
|
4
|
+
__declspec(dllexport) void TableItem_Release(TableItemInformationPtr tableItemInfo) {
|
5
|
+
delete tableItemInfo;
|
6
|
+
}
|
7
|
+
|
8
|
+
__declspec(dllexport) TableItemInformationPtr TableItem_Information(ElementInformationPtr element, char* errorInfo, const int errorInfoLength) {
|
9
|
+
try {
|
10
|
+
return new TableItemInformation(Find(element)->As<TableItemPattern^>(TableItemPattern::Pattern)->Current);
|
11
|
+
} catch(Exception^ e) {
|
12
|
+
StringHelper::CopyToUnmanagedString(e->Message, errorInfo, errorInfoLength);
|
13
|
+
return NULL;
|
14
|
+
}
|
15
|
+
}
|
16
|
+
}
|
@@ -0,0 +1,16 @@
|
|
1
|
+
#include "Stdafx.h"
|
2
|
+
|
3
|
+
extern "C" {
|
4
|
+
__declspec(dllexport) void Table_Release(TableInformationPtr tableInfo) {
|
5
|
+
delete tableInfo;
|
6
|
+
}
|
7
|
+
|
8
|
+
__declspec(dllexport) TableInformationPtr Table_Information(ElementInformationPtr element, char* errorInfo, const int errorInfoLength) {
|
9
|
+
try {
|
10
|
+
return new TableInformation(Find(element)->As<TablePattern^>(TablePattern::Pattern)->Current);
|
11
|
+
} catch(Exception^ e) {
|
12
|
+
StringHelper::CopyToUnmanagedString(e->Message, errorInfo, errorInfoLength);
|
13
|
+
return NULL;
|
14
|
+
}
|
15
|
+
}
|
16
|
+
}
|
@@ -72,6 +72,7 @@
|
|
72
72
|
</ItemDefinitionGroup>
|
73
73
|
<ItemGroup>
|
74
74
|
<Reference Include="System" />
|
75
|
+
<Reference Include="System.Core" />
|
75
76
|
<Reference Include="System.Data" />
|
76
77
|
<Reference Include="System.Xml" />
|
77
78
|
<Reference Include="UIAutomationClient" />
|
@@ -97,9 +98,12 @@
|
|
97
98
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
98
99
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
99
100
|
</ClCompile>
|
101
|
+
<ClCompile Include="TableItemMethods.cpp" />
|
102
|
+
<ClCompile Include="TableMethods.cpp" />
|
100
103
|
<ClCompile Include="ToggleMethods.cpp" />
|
101
104
|
<ClCompile Include="UiaDll.cpp" />
|
102
105
|
<ClCompile Include="ValuePatternMethods.cpp" />
|
106
|
+
<ClCompile Include="WindowMethods.cpp" />
|
103
107
|
</ItemGroup>
|
104
108
|
<ItemGroup>
|
105
109
|
<ProjectReference Include="..\UIA.Helper\UIA.Helper.csproj">
|
@@ -71,5 +71,14 @@
|
|
71
71
|
<ClCompile Include="ExpandCollapseMethods.cpp">
|
72
72
|
<Filter>Source Files\Patterns</Filter>
|
73
73
|
</ClCompile>
|
74
|
+
<ClCompile Include="WindowMethods.cpp">
|
75
|
+
<Filter>Source Files\Patterns</Filter>
|
76
|
+
</ClCompile>
|
77
|
+
<ClCompile Include="TableMethods.cpp">
|
78
|
+
<Filter>Source Files\Patterns</Filter>
|
79
|
+
</ClCompile>
|
80
|
+
<ClCompile Include="TableItemMethods.cpp">
|
81
|
+
<Filter>Source Files\Patterns</Filter>
|
82
|
+
</ClCompile>
|
74
83
|
</ItemGroup>
|
75
84
|
</Project>
|
@@ -0,0 +1,24 @@
|
|
1
|
+
#include "Stdafx.h"
|
2
|
+
|
3
|
+
extern "C" {
|
4
|
+
__declspec(dllexport) void Window_Release(WindowInformationPtr windowInformation) {
|
5
|
+
delete windowInformation;
|
6
|
+
}
|
7
|
+
|
8
|
+
__declspec(dllexport) WindowInformationPtr Window_Information(ElementInformationPtr element, char* errorInfo, const int errorInfoLength) {
|
9
|
+
try {
|
10
|
+
return new WindowInformation(Find(element)->As<WindowPattern^>(WindowPattern::Pattern)->Current);
|
11
|
+
} catch(Exception^ e) {
|
12
|
+
StringHelper::CopyToUnmanagedString(e->Message, errorInfo, errorInfoLength);
|
13
|
+
return NULL;
|
14
|
+
}
|
15
|
+
}
|
16
|
+
|
17
|
+
__declspec(dllexport) void Window_SetVisualState(ElementInformationPtr element, const char* visualState, char* errorInfo, const int errorInfoLength) {
|
18
|
+
try {
|
19
|
+
Find(element)->As<WindowPattern^>(WindowPattern::Pattern)->SetWindowVisualState((WindowVisualState) Enum::Parse(WindowVisualState::typeid, gcnew String(visualState), false));
|
20
|
+
} catch(Exception^ e) {
|
21
|
+
StringHelper::CopyToUnmanagedString(e->Message, errorInfo, errorInfoLength);
|
22
|
+
}
|
23
|
+
}
|
24
|
+
}
|
@@ -103,3 +103,18 @@ TEST_F(ElementInformationTest, ItCanBeRefreshed)
|
|
103
103
|
ASSERT_STREQ("Refreshed", elementInformation.name);
|
104
104
|
ASSERT_EQ(123, elementInformation.nativeWindowHandle);
|
105
105
|
}
|
106
|
+
|
107
|
+
TEST_F(ElementInformationTest, ItCanBeInitializedFromManyElements) {
|
108
|
+
auto elementInformation = ElementInformation::From(gcnew ElementStub("First Element", 123), gcnew ElementStub("Second Element", 456));
|
109
|
+
|
110
|
+
ASSERT_STREQ("First Element", elementInformation[0].name);
|
111
|
+
ASSERT_STREQ("Second Element", elementInformation[1].name);
|
112
|
+
delete[] elementInformation;
|
113
|
+
}
|
114
|
+
|
115
|
+
TEST_F(ElementInformationTest, ItIsNullIfThereAreNoElements) {
|
116
|
+
ASSERT_EQ(NULL, ElementInformation::From(gcnew array<Element^>(0)));
|
117
|
+
|
118
|
+
array<Element^>^ nullElements = nullptr;
|
119
|
+
ASSERT_EQ(NULL, ElementInformation::From(nullElements));
|
120
|
+
}
|
@@ -3,6 +3,8 @@
|
|
3
3
|
#include <PatternInformationStructures.h>
|
4
4
|
#include "ElementStub.h"
|
5
5
|
|
6
|
+
using namespace System::Windows::Automation;
|
7
|
+
|
6
8
|
TEST(ValueInformation, CanBeInitialized)
|
7
9
|
{
|
8
10
|
auto valueInfo = new ValuePatternInformation("Whatever", true);
|
@@ -32,4 +34,15 @@ TEST(SelectionItemInformation, CanBeInitialized)
|
|
32
34
|
TEST(ExpandCollapseInfo, CanBeInitialized) {
|
33
35
|
auto expandCollapseInfo = ExpandCollapseInfo("Collapsed");
|
34
36
|
ASSERT_STREQ("Collapsed", expandCollapseInfo.ExpandCollapseState);
|
35
|
-
}
|
37
|
+
}
|
38
|
+
|
39
|
+
TEST(WindowInformation, CanBeInitialized) {
|
40
|
+
auto windowInformation = WindowInformation(WindowVisualState::Minimized, WindowInteractionState::Closing);
|
41
|
+
ASSERT_STREQ("Minimized", windowInformation.VisualState);
|
42
|
+
ASSERT_STREQ("Closing", windowInformation.InteractionState);
|
43
|
+
}
|
44
|
+
|
45
|
+
TEST(TableInformation, NullHeadersYieldsEmptyElements) {
|
46
|
+
auto tableInformation = TableInformation(0, 0, nullptr);
|
47
|
+
ASSERT_EQ(0, tableInformation.Headers->length);
|
48
|
+
}
|
@@ -84,9 +84,11 @@
|
|
84
84
|
</ItemDefinitionGroup>
|
85
85
|
<ItemGroup>
|
86
86
|
<Reference Include="System" />
|
87
|
+
<Reference Include="System.Core" />
|
87
88
|
<Reference Include="System.Data" />
|
88
89
|
<Reference Include="System.Xml" />
|
89
90
|
<Reference Include="UIAutomationClient" />
|
91
|
+
<Reference Include="UIAutomationTypes" />
|
90
92
|
</ItemGroup>
|
91
93
|
<ItemGroup>
|
92
94
|
<Text Include="ReadMe.txt" />
|
data/lib/uia/element.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
|
-
require 'uia/patterns/expand_collapse'
|
2
|
-
require 'uia/patterns/invoke'
|
3
|
-
require 'uia/patterns/selection'
|
4
|
-
require 'uia/patterns/selection_item'
|
5
|
-
require 'uia/patterns/toggle'
|
6
|
-
require 'uia/patterns/value'
|
7
1
|
require 'uia/library/element_attributes'
|
8
2
|
|
9
3
|
module Uia
|
4
|
+
class UnsupportedPattern < StandardError
|
5
|
+
def initialize(expected, actual)
|
6
|
+
super "Pattern #{expected} not found in #{actual}"
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
10
|
class Element
|
11
11
|
extend ElementAttributes
|
12
12
|
|
@@ -15,7 +15,7 @@ module Uia
|
|
15
15
|
@default = lambda { [:unknown] }
|
16
16
|
end
|
17
17
|
|
18
|
-
element_attr :id, :name, :handle, :runtime_id, :enabled?, :class_name
|
18
|
+
element_attr :id, :name, :handle, :runtime_id, :enabled?, :class_name, :children, :descendants
|
19
19
|
|
20
20
|
def control_type
|
21
21
|
Library::Constants::ControlTypes.find(@default) { |_, v| v == @element.control_type_id }.first
|
@@ -35,23 +35,32 @@ module Uia
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
-
def
|
39
|
-
|
40
|
-
|
38
|
+
def locators_match?(locator)
|
39
|
+
locator.all? do |locator, value|
|
40
|
+
case locator
|
41
|
+
when :pattern
|
42
|
+
patterns.include? value
|
43
|
+
else
|
44
|
+
send(locator) == value
|
45
|
+
end
|
41
46
|
end
|
42
|
-
extend which
|
43
47
|
end
|
44
48
|
|
45
|
-
def
|
46
|
-
|
49
|
+
def select(locator)
|
50
|
+
descendants.select { |e| e.locators_match? locator }
|
47
51
|
end
|
48
52
|
|
49
|
-
def
|
50
|
-
|
53
|
+
def as(pattern)
|
54
|
+
raise UnsupportedPattern.new(pattern, patterns) unless patterns.include? pattern
|
55
|
+
|
56
|
+
which = "Uia::Patterns::#{pattern.to_s.capitalize}".split('::').reduce(Object) do |m, current|
|
57
|
+
m.const_get current.split('_').map(&:capitalize).join
|
58
|
+
end
|
59
|
+
extend which
|
51
60
|
end
|
52
61
|
|
53
|
-
def
|
54
|
-
@element.
|
62
|
+
def patterns
|
63
|
+
@element.pattern_ids.map { |id| Library::Constants::Patterns.find(@default) { |_, v| v == id }.first }
|
55
64
|
end
|
56
65
|
|
57
66
|
def click
|