GPAL - Generally Positive Automation Library v1.0
GPAL The Fluent Automation LIbrary
Loading...
Searching...
No Matches
UnitOfWork.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.Linq;
20using System.Text;
21using System.Threading.Tasks;
22using System.Windows.Forms;
23using System.Windows.Automation;
24using OpenQA.Selenium;
25using static GenerallyPositive.Enums;
29
30
31namespace GenerallyPositive
32{
38 public class UnitOfWork
39 {
45 public List<Selector> WithSelectorList { get; internal set; } = null;
46
47 // list of IN (nested) selectors defined
53 public List<Selector> InSelectorList { get; internal set; } = null;
58 public Selector CurrentSelector { get; internal set; } = null;
66 public Selector NextPageButton { get; internal set; } = null;
74 public bool InfiniteScroll { get; internal set; } = false;
80 public int PageCount { get; internal set; } = 1;
81
89 internal IGPALGrid<string> RetGrid { get; set; } = null;
96 public List<string> TokenList { get; internal set; } = null;
97
101 internal class WebElementWithType
102 {
103 internal Selector selector;
104 internal GPALElement gPalElement;
105 internal ElementType elementType;
106 internal bool currentNode;
107
108 // .InElement can match many, and the searches after it run once inside each. These say which
109 // ones it matched and which of them the pass being walked is about
110 internal List<GPALElement> elements;
111 internal int current;
112
113 // What the walk should use for this step: the one being iterated when there are many, the single
114 // element otherwise, which is every step that is not a plural .InElement
115 internal GPALElement CurrentElement =>
116 null != elements && current < elements.Count ? elements[current] : gPalElement;
117
118 internal WebElementWithType(Selector selector, GPALElement webElement, ElementType elementType)
119 {
120 this.gPalElement = webElement;
121 this.elementType = elementType;
122 this.currentNode = true;
123 this.selector = selector;
124 }
125 }
126 internal List<WebElementWithType> ContextPath { get; set; }
127 internal GPALElement ShadowRoot { get; set; }
128 // response bodies from .Fetch, one per page per row of tokens, in the order they were requested
129 internal List<string> FetchResults { get; set; } = new List<string>();
130 // rows of values .Fetch drops into the request's numbered tokens, one row per set of requests
131 internal IGPALGrid<string> FetchTokens { get; set; }
132// internal GPALElement ShadowRootGPALElement { get; set; }
133
134 internal class ElementNode
135 {
136 public AutomationElement AutomationElement { get; internal set; }
137 public Control ControlElement { get; internal set; }
138 public GPALElement GPALElement { get; internal set; }
139 public InteractionType InteractionType { get; internal set; } = InteractionType.Selenium;
140 public int OffsetX { get; internal set; } = 0;
141 public int OffsetY { get; internal set; } = 0;
142 }
143 // data grid of elements rows and columns
144 // used with FillInFrom
145 // used with FillInFromTokens
146 internal GPALGrid<UnitOfWork.ElementNode> ElementGrid { get; set; } = null;
154 public List<string> HeaderList { get; internal set; } = null;
155 // the column names the control supplied for itself, a UIA TablePattern's headers. Kept apart from
156 // HeaderList because WithHeader clears that one, and a name the control gave us is still the best name
157 // for a column the workflow did not name
158 public List<string> ControlHeaderList { get; internal set; } = null;
159 internal SortedDictionary<int, string> MatchedRowIndexes { get; set; } = null;
166 public bool PartialMatch { get; internal set; } = false;
167
168 // toggles, if BrowserAction is called, the next WithSelector will start a new UOW (old UOW saved but no longer in scope)
174 public bool ActionCalled { get; internal set; } = false;
178 internal bool GetGridCalled { get; set; } = false;
184 public int WithAllThatMatch { get; internal set; } = int.MaxValue; // all rows, default
191 internal WaitTime WaitForInMs { get; set; } = WaitTime.Never;
197 internal DateTime? WaitForSatisfied { get; set; } = null;
198 internal string WaitForTitle { get; set; } = null;
199 internal string WaitForTitleRegex { get; set; } = null;
200 internal ElementState WaitForElementState { get; set; } = ElementState.NotSet;
201
202 internal int ColCount { get; set; } = 0;
203 internal int RowCount { get; set; } = 0;
204
205 internal Browser.Browser.CallAfterFillInDelegate CallAfterFillIn { get; set; }
206 internal List<CallIfDelegate> CallIfFound { get; set; }
207 internal List<CallIfDelegate> CallIfNotFound { get; set; }
208 internal Application.Application.CallAfterFillInDelegate AppCallAfterFillIn { get; set; }
209 internal List<Application.Application.CallIfDelegate> AppCallIfFound { get; set; }
210 internal List<Application.Application.CallIfDelegate> AppCallIfNotFound { get; set; }
211
212 public CallIfStatus CallIfFoundHandled { get; internal set; } = CallIfStatus.NotHandled;
213 public CallIfStatus CallIfNotFoundHandled { get; internal set; } = CallIfStatus.NotHandled;
214 public CallIfStatus AppCallIfFoundHandled { get; internal set; } = CallIfStatus.NotHandled;
215 public CallIfStatus AppCallIfNotFoundHandled { get; internal set; } = CallIfStatus.NotHandled;
216
223 public GPALFile InputFile { get; internal set; }
230 public IGPALDatabase InputDatabase { get; internal set; }
231
232 public Browser.Browser Browser { get; internal set; }
233
234 internal UnitOfWork()
235 {
236 WithSelectorList = new List<Selector>();
237 InSelectorList = new List<Selector>();
238 HeaderList = new List<string>();
239 ControlHeaderList = new List<string>();
240 CallIfFound = new List<CallIfDelegate>();
241 CallIfNotFound = new List<CallIfDelegate>();
242 AppCallIfFound = new List<Application.Application.CallIfDelegate>();
243 AppCallIfNotFound = new List<Application.Application.CallIfDelegate>();
244 MatchedRowIndexes = new SortedDictionary<int, string>();
245 ElementGrid = new GPALGrid<UnitOfWork.ElementNode>();
246 ContextPath = new List<WebElementWithType>();
247 WaitForInMs = GPAL.GPALSettings.WaitForInMs; // if globally defined, then set the 'default' waitfor time
248 ShadowRoot = null;
249 RetGrid = GPAL.GridForType<string>();
250 }
251
252 }
253}
254
Browser object that contains the fluent methods to create your Browser workflow. Instatiated using G...
Definition Browser.cs:68
Pseudo element used in Applications and Browser workflows for image matching and unified automation....
GPAL File object instantied with GPAL.File Used to load tokens into a GPALGrid [rows/columns].
Definition GPALFile.cs:36
GPAL Selector used to locate Application and Browser elements. Instantiated with GPAL....
Definition Selector.cs:56
Everything revolves around the Unit of Work. A Unit of Work is defined as one or more selectors betw...
Definition UnitOfWork.cs:39
int WithAllThatMatch
Controls whether the selectors in scope are multiple elements on screen, and to get all Use ....
IGPALDatabase InputDatabase
The input database from which to consume tokens. This is set using any [Append/FillIn/Insert]FromDat...
List< string > HeaderList
Output header list, Defined using .WithHeader or, if not supplied, from the names given to selectors....
List< Selector > InSelectorList
List of iframe or shadow dom selectors. Set using .InFrame() or .InShadowDom() Use ....
Definition UnitOfWork.cs:53
Selector NextPageButton
The next page button. When scraping multiple pages of results, this element is pressed for a new page...
Definition UnitOfWork.cs:66
List< Selector > WithSelectorList
List of With selectors Use .WithSelector to add selectors to this list.
Definition UnitOfWork.cs:45
List< string > TokenList
Input data grid retrieved from a file or database. A grid is rows and columns. Each column value is ...
Definition UnitOfWork.cs:96
int PageCount
Number of pages to retrieve. Default is 1 page. Use .WithPages() to set this value.
Definition UnitOfWork.cs:80
bool PartialMatch
Only relevant if there is a match criteria or matching function. Of all the found selectors,...
bool ActionCalled
Has an action been called on the current unit of work? If true, then the next .WithSelector() will c...
Selector CurrentSelector
The current selector being used from the current UOW. The selectors are iterated in declared order.
Definition UnitOfWork.cs:58
bool InfiniteScroll
Go to page end to get the next page of results. Use with .WithPages() to retrieve multiple pages of ...
Definition UnitOfWork.cs:74
GPALFile InputFile
The input File from which to consume tokens. This is set using any [Append/FillIn/Insert]FromFile me...