GPAL - Generally Positive Automation Library v1.0
GPAL The Fluent Automation LIbrary
Loading...
Searching...
No Matches
Interfaces.cs
1// =============================================================================
2// GPAL - Generally Positive Automation Library
3// Copyright © 2026 Software Decisions, Inc. All rights reserved.
4//
5// This file is part of GPAL.
6// Licensed under the Business Source License 1.1
7//
8// Primary development, architecture, and vision by Michael B. Vederman,
9// CEO of Software Decisions, Inc., Texas.
10//
11// Internal development maintained privately.
12// Public releases appear on GitHub: https://github.com/SoftwareDecisionsInc/GPAL.
13//
14// See LICENSE for full terms, including Additional Use Grant.
15// =============================================================================
16
17using System;
18using System.Collections.Generic;
19using System.Drawing;
20using System.Linq;
21using System.Text;
22using System.Threading.Tasks;
23using OpenQA.Selenium;
25using static GenerallyPositive.Enums;
26using static GenerallyPositive.GPAL;
28using System.Windows.Automation;
29
31{
32 #region <Application Interfaces>
33 #region <Base Application Interfaces>
34 public interface IAllowPersistentCallBack
35 {
36 // return values
37 // 0 = not handled
38 // 1 = handled
39 // -1 = error
40 [Callback(Description = "GLOBAL based callback if any selector in any UOW is found")]
41 IAllowPersistentCallBack PersistentCallIfFound(Application.CallIfDelegate CallIfFound);
42 [Callback(Description = "GLOBAL based callback if any selector in any UOW is NOT found")]
43 IAllowPersistentCallBack PersistentCallIfNotFound(Application.CallIfDelegate CallIfNotFound);
44 }
45
46 public interface IAllowFileDialog
47 {
48 [Action(Description = "Click the element that raises an Open dialog, then answer it with this file or folder.", Submenu = "Clicks")]
49 IAllowSelectorActionOrAnySelector LeftClickAndOpen(GPALFile file);
50 [Action(Description = "Click the element that raises a Save dialog, then answer it with this file. An existing file of that name is deleted first, so the dialog never asks whether to replace it.", Submenu = "Clicks")]
51 IAllowSelectorActionOrAnySelector LeftClickAndSave(GPALFile file);
52 [Action(Description = "Answer a file dialog that is already on screen with this file or folder.", Submenu = "Windows")]
53 IAllowSelectorActionOrAnySelector AnswerFileDialog(GPALFile file);
54 }
55 public interface IAllowFillInFrom
56 {
57 [Data(Description = "Replace the control's text with this literal string", Submenu = "Fill In")] IAllowSelectorActionOrAnySelector FillInFrom(string textToUse);
58 [Data(Description = "Add this literal string to the end of the control's text", Submenu = "Fill In")] IAllowSelectorActionOrAnySelector AppendFrom(string textToUse);
59 [Data(Description = "Insert this literal string at the control's caret", Submenu = "Fill In")] IAllowSelectorActionOrAnySelector InsertFrom(string textToUse);
60
61 [Data(Description = "Replace the control's text with what the file holds, a value per control matched", Submenu = "Fill In")] IAllowSelectorActionOrAnySelector FillInFrom(GPALFile inputFile);
62 [Data(Description = "Add what the file holds to the end of the control's text", Submenu = "Fill In")] IAllowSelectorActionOrAnySelector AppendFrom(GPALFile inputFile);
63 [Data(Description = "Insert what the file holds at the control's caret", Submenu = "Fill In")] IAllowSelectorActionOrAnySelector InsertFrom(GPALFile inputFile);
64
65 [Data(Description = "Replace the control's text with what the query returns, a value per control matched", Submenu = "Fill In")] IAllowSelectorActionOrAnySelector FillInFrom(GPALDatabase inputDatabase);
66 [Data(Description = "Add what the query returns to the end of the control's text", Submenu = "Fill In")] IAllowSelectorActionOrAnySelector AppendFrom(GPALDatabase inputDatabase);
67 [Data(Description = "Insert what the query returns at the control's caret", Submenu = "Fill In")] IAllowSelectorActionOrAnySelector InsertFrom(GPALDatabase inputDatabase);
68
69 [Data(Description = "Replace the control's text with the grid's values, a value per control matched", Submenu = "Fill In")] IAllowSelectorActionOrAnySelector FillInFrom(IGPALGrid<string> inputGrid);
70 [Data(Description = "Add the grid's values to the end of the control's text", Submenu = "Fill In")] IAllowSelectorActionOrAnySelector AppendFrom(IGPALGrid<string> inputGrid);
71 [Data(Description = "Insert the grid's values at the control's caret", Submenu = "Fill In")] IAllowSelectorActionOrAnySelector InsertFrom(IGPALGrid<string> inputGrid);
72 }
73 public interface IAllowClicks
74 {
75 [Action(Description = "Left click the element. Uses the selector given, or the one already on the unit of work", Submenu = "Clicks")] IAllowSelectorActionOrAnySelector LeftClick(Selector selector = null);
76 [Action(Description = "Left click while holding Ctrl, Shift or Alt", Submenu = "Clicks")] IAllowSelectorActionOrAnySelector LeftClick(ModifierKeys modifierKeys);
77 [Action(Description = "Double click the element. Uses the selector given, or the one already on the unit of work", Submenu = "Clicks")] IAllowSelectorActionOrAnySelector LeftDoubleClick(Selector selector = null);
78 [Action(Description = "Middle click the element. Uses the selector given, or the one already on the unit of work", Submenu = "Clicks")] IAllowSelectorActionOrAnySelector MiddleClick(Selector selector = null);
79 [Action(Description = "Right click the element. Uses the selector given, or the one already on the unit of work", Submenu = "Clicks")] IAllowSelectorActionOrAnySelector RightClick(Selector selector = null);
80 [Action(Description = "Drag-and-drop using selector's DeltaX/DeltaY as the drag distance from the element's origin. Always uses hardware mouse events.", Submenu = "Mouse")] IAllowSelectorActionOrAnySelector DragAndDrop(Selector selector = null);
81 [Action(Description = "Drag-and-drop while holding a modifier key.", Submenu = "Mouse")] IAllowSelectorActionOrAnySelector DragAndDrop(ModifierKeys modifierKeys);
82 }
83 public interface IAllowKeyboardActions
84 {
91 [Data(Description = "Type this text, as if at the keyboard, into whatever has focus", Submenu = "Keyboard")] IAllowSelectorActionOrAnySelector SendString(string textToSend);
92 [Data(Description = "Press one key by its Windows virtual key code", Submenu = "Keyboard")] IAllowSelectorActionOrAnySelector SendKey(byte VKCode);
93 [Data(Description = "Press and hold a modifier key (Alt, Control, Shift) using hardware emulation", Submenu = "Keyboard")]
94 IAllowSelectorActionOrAnySelector PressModifierKey(ModifierKeys modifierKeys);
95 [Data(Description = "Release a previously pressed modifier key (Alt, Control, Shift) using hardware emulation", Submenu = "Keyboard")]
96 IAllowSelectorActionOrAnySelector ReleaseModifierKey(ModifierKeys modifierKeys);
97 }
98 public interface IAllowScrolling
99 {
100 [Scroll(Description = "Scroll horizontally by one notch, this many times")] IAllowSelectorActionOrAnySelector ScrollHorizontalSmall(int iterations);
101 [Scroll(Description = "Scroll horizontally by one page, this many times")] IAllowSelectorActionOrAnySelector ScrollHorizontalLarge(int iterations);
102 [Scroll(Description = "Scroll horizontally to this percentage of the width")] IAllowSelectorActionOrAnySelector ScrollHorizontalPercent(int percent);
103 [Scroll(Description = "Scroll vertically by one notch, this many times")] IAllowSelectorActionOrAnySelector ScrollVerticalSmall(int iterations);
104 [Scroll(Description = "Scroll vertically by one page, this many times")] IAllowSelectorActionOrAnySelector ScrollVerticalLarge(int iterations);
105 [Scroll(Description = "Scroll vertically to this percentage of the height")] IAllowSelectorActionOrAnySelector ScrollVerticalPercent(int percent);
106 }
107 public interface IAllowCallBack
108 {
109 // return values
110 // 0 = not handled
111 // 1 = handled
112 // -1 = error
113 [Callback(Description = "UOW based callback if any selector in the UOW is found")]
114 IAllowAfterAnySelector CallIfFound(Application.CallIfDelegate CallIfFound);
115 [Callback(Description = "UOW based callback if any selector in the UOW is NOT found")]
116 IAllowAfterAnySelector CallIfNotFound(Application.CallIfDelegate CallIfNotFound);
117 [Callback(Description = "UOW based callback when a row of input is consumed and entered.\nUseful for chaining to another workflow")]
118 IAllowAfterAnySelector CallAfterFillIn(Application.CallAfterFillInDelegate CallAfterFillIn);
119 }
120
121 public interface IAllowSizeControl
122 {
123 [Action(Description = "Maximize the window matched by WaitForWindow")]
124 IAllowAllApplicationAndAllSelector Maximize { [Action(Description = "Maximize the application to full-screen", Submenu = "Windows")] get; }
125 [Action(Description = "Minimize the window matched by WaitForWindow")]
126 IAllowAllApplicationAndAllSelector Minimize { [Action(Description = "Minimize the application to the taskbar", Submenu = "Windows")] get; }
127 [Action(Description = "Restore the window matched by WaitForWindow to the size it had before it was maximized or minimized")]
128 IAllowAllApplicationAndAllSelector Restore { [Action(Description = "Restore the application to 'original' size, unminimize", Submenu = "Windows")] get; }
129 [Action(Description = "Resize the window matched by WaitForWindow to the given width and height in pixels.")]
130 IAllowAllApplicationAndAllSelector ResizeWindow(int width, int height);
131 [Action(Description = "Move the window matched by WaitForWindow to the given screen coordinates.")]
132 IAllowAllApplicationAndAllSelector MoveWindow(int x, int y);
133 }
134 public interface IAllowWaitForWindow
135 {
136 [Wait(Description = "Wait for a window with this exact title, for up to WithWaitForWindowTimeout seconds")]
137 IAllowAfterWaitForAndSizeControl WaitForWindow(string windowName);
138 [Wait(Description = "Wait for a window whose title matches this regular expression, for up to WithWaitForWindowTimeout seconds")]
139 IAllowAfterWaitForAndSizeControl WaitForWindowRegex(string windowNameRegex);
140 [Wait(Description = "How long WaitForWindow and WaitForWindowRegex wait, in seconds")]
141 IAllowAfterWaitForAndSizeControl WithWaitForWindowTimeout(int waitTimeInSeconds);
142
143 }
144 public interface IAllowTabActions
145 {
146 [Action(Description = "Bring the tab named by the selector to the front", Submenu = "Windows")] IAllowAllActionAndAnySelector SwitchToTab(Selector selector = null);
147 }
148 public interface IAllowApplicationOpen
149 {
150 [Fluent(Description = "The application to drive, by the path to its executable")]
151 IAllowAllExceptParameters Open([Directory()] string ApplicationPath);
152 }
154 {
155 [Settings(Description = "Name to use in Information and Exception channel messages")]
156 IAllowApplicationSettingsOrOpen WithName(string name);
157 [Settings(Description = "Parameter to pass into the program (will be concatenated to one string)")]
158 IAllowApplicationSettingsOrOpen WithParameter(string parameter);
159 [Settings(Description = "Use hardwre emulation for the entire workflow")]
160 IAllowApplicationSettingsOrOpen WithUseHardware(bool trueFalse);
161 [Settings(Description = "Launch a new copy of the program rather than attaching to one already running")]
162 IAllowApplicationSettingsOrOpen WithNewInstance(bool trueFalse);
163 [Settings(Description = "Run the program on a Win32 desktop of its own, where it is driven by UIAutomation and takes no focus from you")]
164 IAllowApplicationSettingsOrOpen WithHiddenDesktop(bool hiddenDesktop);
165 [Settings(Description = "Run the program on the named Win32 desktop. Programs naming the same one share it")]
166 IAllowApplicationSettingsOrOpen WithHiddenDesktop(string desktopName);
167 }
168 #endregion <Base Application Interfaces>
169 #region <Derived Application Interfaces>
184 // NOTE: Add to this list what is added above
192
193 public interface IAllowSelectorAction
204 , IAllowToGPALObject<Application>
205 { }
206
223 public interface IAllowFileActions
224 {
225 [File(Description = "Save the retrieved grid. Output format and delimiter are determined by the GPALFile (its extension, or explicit file settings).")]
226 IAllowAllActionAndAnySelector SaveTo([GPALFile(Description = "The file to write")] GPALFile file);
227 [File(Description = "Append the retrieved grid. Output format and delimiter are determined by the GPALFile (its extension, or explicit file settings).")]
228 IAllowAllActionAndAnySelector AppendTo([GPALFile(Description = "The file to add to")] GPALFile file);
229 }
255 public interface IAllowApplicationAction
259 { }
260 public interface IAllowAnySelector
262 { }
267
268 #endregion <Derived Application Interfaces>
269 #region <Application Atoms>
270 public interface IAllowToGPALObject<TResult>
271 {
272 [Fluent(Description = "Ends a declaration or workflow, returning a GPAL object which can be assigned. Use instead of an explicit cast. [ Selector mySel = GPAL.Selector.WithCSS(css).ToGPALObject() ]")]
273 TResult ToGPALObject();
274 }
276 {
277 [Selector(Description = "A selector looked for on every action rather than only in this unit of work, so something that can appear at any time is handled wherever it appears")]
278 IAllowPersistence WithPersistentSelector(Selector selector);
279 }
280 public interface IAllowWithSelector
281 {
282 [Selector(Description = "The element the next action works on")]
283 IAllowSelectorActionOrAnySelector WithSelector(Selector selector);
284 }
285 public interface IAllowClose
286 {
287 [Action(Description = "Close the application", Submenu = "Windows")]
288 void Close();
289 }
290 public interface IAllowFocus
291 {
292 [Action(Description = "Give the element keyboard focus", Submenu = "Mouse")] IAllowSelectorActionOrAnySelector Focus(Selector selector = null);
293 }
294 public interface IAllowHover
295 {
296 [Action(Description = "Move the pointer over the element without clicking", Submenu = "Mouse")] IAllowSelectorActionOrAnySelector Hover(Selector selector = null);
297 }
298 public interface IAllowWithAllThatMatch
299 {
300 [Settings(Description = "How many matching elements to act on. Defaults to int.MaxValue, every one that matches")]
301 IAllowAfterAnySelectorExceptWithAll WithAllThatMatch(int rowCount);
302 }
303 public interface IAllowMoveTo
304 {
305 [Action(Description = "Move the pointer to the element", Submenu = "Mouse")] IAllowSelectorActionOrAnySelector MoveTo(Selector selector = null);
306 }
307 public interface IAllowGetGrid
308 {
309 [Action(Description = "Retrieve data and add it into this GPALGrid. Pass a grid configured with .WithDedupeData(true) to skip duplicate rows. GPAL also keeps it internally for SaveTo*.")]
310 IAllowWithHeaderOrFileActions GetGrid(ref IGPALGrid<string> returnGrid);
311 }
312 public interface IAllowWaitFor
313 {
314 [Action(Description = "Wait for the selectors on this unit of work to appear before carrying on, in milliseconds")]
315 IAllowAfterWaitForAndSizeControl WaitFor(int waitForTimeInTicks);
316 }
317 public interface IAllowWithHardware
318 {
319 IAllowAfterAnySelector WithHardware
320 {
321 [Settings(Description = "Use hardware emulation to interact with this element")]
322 get;
323 }
324 }
325 public interface IAllowWithHeader
326 {
327 [Settings(Description = "Column header for exported data. Use this when a selector was not given a name with .WithName, or instead of the name")]
328 IAllowWithHeaderOrFileActions WithHeader(string header);
329 }
330 public interface IAllowWithGridToSave
331 {
332 [Settings(Description = "The grid results are saved into, which could have been built by another workflow")]
333 IAllowWithHeaderOrFileActions WithGridToSave(IGPALGrid<string> _);
334 }
336 {
337 [Data(Description = "When retrieving multiple pages of results, the control to click to load the next page.", Submenu = "Pages")]
338 IAllowWithPagesAndGridActions WithNextPageButton(Selector selector);
339 }
341 {
342 IAllowWithPagesAndGridActions WithInfiniteScroll
343 {
344 [Data(Description = "When retrieving multiple pages of results, scroll to load more rows. Not supported for desktop applications.", Submenu = "Pages")]
345 get;
346 }
347 }
348 public interface IAllowWithPages
349 {
350 [Data(Description = "Number of result pages to retrieve when paging through results.", Submenu = "Pages")]
351 IAllowGetGridAndFillInFrom WithPages(int numberOfPages);
352 }
360 { }
364 { }
365 public interface IAllowSetRange
366 {
367 [Data(Description = "Set the value of an input slider, number and other range/numeric inputs", Submenu = "Keyboard")]
368 IAllowAllActionAndAnySelector SetRange(double rangeValue);
369 }
370
371 #endregion <Application Atoms>
387 {
388 System.Diagnostics.Process Process { get; }
389 object ManagedRootAutomationElement { get; }
393 AutomationElement RootAutomationElement { get; }
394 [Scroll(Description = "Whether the application's scrollable view is at the bottom")]
395 bool IsEndOfPage();
402 string Name { get; }
408 string ApplicationPath { get; }
414
421 IReadOnlyList<string> ColumnNames { get; }
422 }
423 #endregion <Application Interfaces>
424 #region <Element Assistant Interfaces>
429 public interface IAllowElementActions
430 {
431 [Action(Description = "Left click the GPALAutomationElement")]
433 [Action(Description = "Left click the GPALAutomationElement, optionally emulating pressing a modifier key at the same time")]
434 IAllowElementSettingsAndActions LeftClick(ModifierKeys modifierKeys);
435 [Action(Description = "Left double click the GPALAutomationElement")]
436 IAllowElementSettingsAndActions LeftDoubleClick();
437 [Action(Description = "Right click the GPALAutomationElement")]
439 [Data(Description = "Fill In (Ovewrite) text of the input GPALAutomationElement defined with.WithElement")]
440 IAllowElementSettingsAndActions FillInFrom(string inputText);
441 [Data(Description = "Insert text at the beginning of the input GPALAutomationElement defined with.WithElement")]
442 IAllowElementSettingsAndActions InsertFrom(string inputText);
443 [Data(Description = "Appends text to the end of the input GPALAutomationElement defined with.WithElement")]
444 IAllowElementSettingsAndActions AppendFrom(string inputText);
445 [Action(Description = "Emulate pressing a special key like Home, End, Page Down")]
446 IAllowElementSettingsAndActions SendKeyCode(byte keyCode);
447 [Data(Description = "Press a modifier key: Alt, Control, Shift")]
448 IAllowElementSettingsAndActions PressModifierKey(ModifierKeys modifierKeys);
449 [Data(Description = "Release a modifier key: Alt, Control, Shift")]
450 IAllowElementSettingsAndActions ReleaseModifierKey(ModifierKeys modifierKeys);
451 [Scroll(Description = "Scroll the GPALAutomationElement horizontally by an increment amount")]
452 IAllowElementSettingsAndActions ScrollHorizontal(System.Windows.Automation.ScrollAmount scrollAmount);
453 [Scroll(Description = "Scroll the GPALAutomationElement horizontally to the given percentage of its scrollable range")]
454 IAllowElementSettingsAndActions ScrollHorizontalPercent(int percent);
455 [Scroll(Description = "Scroll the GPALAutomationElement vertically by an increment amount")]
456 IAllowElementSettingsAndActions ScrollVertical(System.Windows.Automation.ScrollAmount scrollAmount);
457 [Scroll(Description = "Scroll the GPALAutomationElement vertically to the given percentage of its scrollable range")]
458 IAllowElementSettingsAndActions ScrollVerticalPercent(int percent);
459 }
460 public interface IAllowElementSetting
461 {
462 [ElementAssitant(Description = "Define the GPALAutomationElement to act upon")]
464 IAllowElementSettingsAndActions WithHardware { [Settings(Description = "Interact with the GPALAutomationElement emulating hardware, not using UIAutomation;")] get; }
465 }
466 public interface IAllowForSelector { [Settings(Description = "The selector associated with the webelement(s) you are acting upon")] IAllowElementSetting ForSelector(Selector selector); };
467 #endregion <Element Assistant Interfaces>
468
469
470}
471
Application object that contains the fluent methods to create your Application workflow....
delegate CallIfStatus CallAfterFillInDelegate(Application application, IGPALGrid< string > tokens, int tokenIdx)
Delegate callback for the CallAfterFillIn EventHandler which will be invoked after each row of tokens...
delegate CallIfStatus CallIfDelegate(Application application, List< IGPALAutomationElement > foundElements, List< IGPALAutomationElement > matchedElements, Selector selector, bool matchedAll)
Delegate callback for the CallIfFound/CallIfNotFound EventHandlers which will be invoked when a selec...
Class to define database usage. Currently only used for input from a table, sql or stored procedure....
GPAL File object instantied with GPAL.File Used to load tokens into a GPALGrid [rows/columns].
Definition GPALFile.cs:36
Form object that contains the fluent methods to create interactive forms. Instatiated using GPAL....
Definition GPALForm.cs:64
Everything starts here, all the GPAL controls and global settings using fluent syntax are here....
Definition GPAL.cs:49
GPAL Selector used to locate Application and Browser elements. Instantiated with GPAL....
Definition Selector.cs:56
IAllowSelectorActionOrAnySelector SendString(string textToSend)
Simulates typing via hardware key events, one character at a time. Honors GPAL.TypingDelay (see GPAL....
AutomationElement RootAutomationElement
The starting AutomationElement for the application. All xpath searches start from this AutomationElem...
string Name
A name you provide to be used when publishing events. Use .WithName to provide your own friendly nam...
IReadOnlyList< string > ColumnNames
The column names the last GetGrid read off the control itself, from a TablePattern or from the header...
GenerallyPositive.Browser.IHiddenDesktop HiddenDesktop
The hidden desktop this program runs on, or null when it is on the desktop you are looking at.
string ApplicationPath
The path of the program you Opened. This get is intended for debugging only.
One Win32 desktop object a browser is running on. Reached from the browser that is on it,...