-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBaseMethods.cs
More file actions
260 lines (243 loc) · 8.8 KB
/
BaseMethods.cs
File metadata and controls
260 lines (243 loc) · 8.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
using System.Windows.Automation;
public class BaseMethods
{
/// <summary>
/// Calls the current invoke pattern for the automation element. Ex: Click for a button
/// </summary>
/// <param name="element">
/// Element to be invoked
/// </param>
/// <returns>
/// Boolean true if works, false if failed
/// </returns>
public static bool InvokeElement(AutomationElement element)
{
try
{
if (element.TryGetCurrentPattern(InvokePattern.Pattern, out object pattern))
{
if (pattern != null)
{
InvokePattern? actualPattern = pattern as InvokePattern;
if (actualPattern != null)
{
actualPattern.Invoke();
// Console.WriteLine(actualPattern.ToString());
return true;
}
}
}
return false;
}
catch (Exception ex)
{
Console.WriteLine($"Failed to invoke control: {element.Current.Name})");
Console.WriteLine(ex.Message);
return false;
}
}
/// <summary>
/// Sets the text of an automation element. Works for document or edit control types.
/// </summary>
/// <param name="editorElement">
/// The automation element whose text is to be set.
/// </param>
/// <param name="text">
/// The text to be set in the automation element.
/// </param>
/// <returns>
/// True if the setting is successful, false otherwise.
/// </returns>
public static bool SetElementText(AutomationElement editorElement, string text)
{
try
{
// Try to get the ValuePattern from the element.
if (editorElement.TryGetCurrentPattern(ValuePattern.Pattern, out object valuePatternObj))
{
// Cast the returned object to the ValuePattern type.
ValuePattern valuePattern = (ValuePattern)valuePatternObj;
// Prepare the text you want to input.
// Environment.NewLine creates a cross-platform new line character.
string textToInput = text;
// Use SetValue to instantly place the text into the editor.
// This will overwrite any text that was already there.
valuePattern.SetValue(textToInput);
// Console.WriteLine("Successfully entered text into the editor.");
return true;
}
else
{
Console.WriteLine("Could not get ValuePattern from the editor element.");
return false;
}
}
catch (Exception ex)
{
Console.WriteLine($"An error occurred while trying to input text: {ex.Message}");
return false;
}
}
/// <summary>
/// Find a descendant whose name includes the specified string. First searches
/// immediate children, then does a deep dive under each child in order.
/// </summary>
/// <param name="parent">
/// The root element in which to search for the descendant
/// </param>
/// <param name="name">
/// The string to find inside the name
/// </param>
/// <returns>
/// The element which includes the specified string
/// </returns>
public static AutomationElement? FindDescendantWithName(AutomationElement parent, string name)
{
AutomationElement? search = FindChildWithName(parent, name);
if (search != null)
{
return search;
}
AutomationElement currentElement = TreeWalker.ContentViewWalker.GetFirstChild(parent);
while (currentElement != null)
{
search = FindDescendantWithName(currentElement, name);
if (search != null)
{
return search;
}
currentElement = TreeWalker.ContentViewWalker.GetNextSibling(currentElement);
}
return null;
}
/// <summary>
/// Find a descendant whose name perfectly matches the specified string. First searches
/// immediate children, then does a deep dive under each child in order.
/// </summary>
/// <param name="parent">
/// The root element in which to search for the descendant
/// </param>
/// <param name="name">
/// The exact name of the descendant
/// </param>
/// <returns>
/// The element with the matching name
/// </returns>
public static AutomationElement? FindDescendantWithExactName(AutomationElement parent, string name)
{
// UncoverChildrenNames(parent);
AutomationElement? search = FindChildWithExactName(parent, name);
if (search != null)
{
return search;
}
AutomationElement currentElement = TreeWalker.ControlViewWalker.GetFirstChild(parent);
while (currentElement != null)
{
search = FindDescendantWithExactName(currentElement, name);
if (search != null)
{
return search;
}
currentElement = TreeWalker.ControlViewWalker.GetNextSibling(currentElement);
}
return null;
}
/// <summary>
/// Finds only a direct child with the specified string in the name, can return null.
/// </summary>
/// <param name="parent">
/// The parent in which to search for the automation element
/// </param>
/// <param name="name">
/// The string to find in the name
/// </param>
/// <returns>
/// The first child automation element that contains that string in the name
/// </returns>
public static AutomationElement? FindChildWithName(AutomationElement parent, string name)
{
AutomationElement currentElement = TreeWalker.ContentViewWalker.GetFirstChild(parent);
while (currentElement != null)
{
if (currentElement.Current.Name.Contains(name))
{
return currentElement;
}
currentElement = TreeWalker.ContentViewWalker.GetNextSibling(currentElement);
}
return null;
}
/// <summary>
/// Finds only a direct child whose name is exactly the specified string. Returns first child with those conditions only.
/// </summary>
/// <param name="parent">
/// The parent in which to search for the automation element
/// </param>
/// <param name="name">
/// The name of the child element
/// </param>
/// <returns>
/// The child with the matching name, or null if there is none
/// </returns>
///
public static AutomationElement? FindChildWithExactName(AutomationElement parent, string name)
{
AutomationElement currentElement = TreeWalker.ControlViewWalker.GetFirstChild(parent);
while (currentElement != null)
{
// Console.WriteLine($"Checking name: {name} against {currentElement.Current.Name}");
if (currentElement.Current.Name == name)
{
return currentElement;
}
currentElement = TreeWalker.ControlViewWalker.GetNextSibling(currentElement);
}
return null;
}
/// <summary>
/// Prints the names of all of the children under the automation element
/// </summary>
/// <param name="parent">
/// Parent automation element
/// </param>
public static void UncoverChildrenNames(AutomationElement parent)
{
AutomationElement currentElement = TreeWalker.ContentViewWalker.GetFirstChild(parent);
while (currentElement != null)
{
Console.WriteLine(currentElement.Current.Name + " + " + currentElement.Current.AutomationId);
currentElement = TreeWalker.ContentViewWalker.GetNextSibling(currentElement);
}
}
/// <summary>
/// Finds a descendant with the specified name under the automation, waiting for it to appear if not found.
/// </summary>
/// <param name="parent">
/// Automation element that is root of the search
/// </param>
/// <param name="name">
/// The string to find within the children AutomationElement names
/// </param>
/// <param name="timeout">
/// Timout of the process
/// </param>
/// <returns>
/// The first AutomationElement with the matching name
/// </returns>
public static AutomationElement? WaitForChildWithName(AutomationElement parent, string name, int timeout)
{
AutomationElement? targetElement = null;
for (int i = 0; i < timeout / 100; i++)
{
targetElement = FindChildWithName(parent, name);
if (targetElement != null)
{
return targetElement;
}
Thread.Sleep(100);
// Console.WriteLine("Waited 0.1s");
}
return targetElement;
}
}