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
19using MimeKit;
20using OpenQA.Selenium;
21using System;
22using System.Collections.Generic;
23using System.Diagnostics;
24using System.Drawing;
25using System.Linq;
26using System.Text;
27using System.Threading.Tasks;
28using System.Windows.Forms.DataVisualization.Charting;
29using static GenerallyPositive.Enums;
30using static GenerallyPositive.GPAL;
33using static GenerallyPositive.RESTClient;
34
35namespace GenerallyPositive
36{
37 #region <Selector Settings>
38 [Interface(Description = "Selector Settings")]
39 public interface IAllowSelectorSettings : IAllowCallBack, IAllowToGPALObject<Selector>
40 {
42 //[Selector(Description = "Locate element with OCR using the text to find")]
43 //IAllowSelectorSettings WithOCR(string textToFind);
44 [Selector(Description = "Locate element using a CSS path (browser only)")]
45 IAllowSelectorSettings WithCSS(string CSS);
46 [Selector(Description = "Locate element matching a partial or full HRef (browser only)")]
47 IAllowSelectorSettings WithHRef(string HRefFullOrPartial);
48 [Selector(Description = "Locate element using an XPath")]
49 IAllowSelectorSettings WithXPath(string xpath);
50 [Selector(Description = "Locate element searching visible text to find")]
51 IAllowSelectorSettings WithText(string textToFind);
52 [Selector(Description = "Locate element with the given value")]
53 IAllowSelectorSettings WithValue(string valueToFind);
54 [Selector(Description = "Locate element with the given name")]
55 IAllowSelectorSettings WithName(string nameToFind);
56 [Selector(Description = "Locate element with the given class name")]
57 IAllowSelectorSettings WithClassName(string nameToFind);
58 [Selector(Description = "Locate element with the given placeholder (browser only)")]
59 IAllowSelectorSettings WithPlaceholder(string placeholderToFind);
60 [Selector(Description = "Locate element using an AutomationID (application only)")]
61 IAllowSelectorSettings WithAutomationID(string nameToFind);
62 [Selector(Description = "Locate element loading the given image file to match")]
63 IAllowSelectorSettings WithImage(GPALFile imageToFindPath);
64 [Selector(Description = "Locate element loading the given image file to match")]
65 IAllowSelectorSettings WithImage(string dataURL);
66 [Selector(Description = "Locate element using the supplied image to match")]
67 IAllowSelectorSettings WithImage(Image imageToFine);
68 [Settings(Description = "Name of selector (used in messages and column names)")]
69 IAllowSelectorSettings WithSelectorName(string name);
70 [Settings(Description = "X offset to click inside element, also starting X location in element for drag-and-drop")]
71 IAllowSelectorSettings WithOffsetX(int offsetX);
72 [Settings(Description = "Y offset to click inside element, also starting X location in element for drag-and-drop")]
73 IAllowSelectorSettings WithOffsetY(int offsetY);
74 [Settings(Description = "X delta for drag-and-drop")]
75 IAllowSelectorSettings WithDeltaX(int offsetX);
76 [Settings(Description = "Y delta for drag-and-drop")]
77 IAllowSelectorSettings WithDeltaY(int offsetY);
78 [Settings(Description = "Scroll down a page to see if the selector comes into view [image/ocr]")]
79 IAllowSelectorSettings WithSearchForSelector(bool trueFalse = true);
80 IAllowSelectorSettings WithHardware { [Settings(Description = "Use hardware emulation to interact with this element [mouse/keyboard]")] get; }
81 IAllowSelectorSettings WithJavaScript { [Settings(Description = "Use javascript injection to interact with this element")] get; }
82 IAllowSelectorSettings WithSelenium { [Settings(Description = "Use selenium to interact with this element [default]")] get; }
83 [Settings(Description = "Smoothly move mouse to interact with this element [instead of jump to]. Implies .WithHardware")]
84 IAllowSelectorSettings WithSimulateMouse(bool moveWithArc = false);
85 [Settings(Description = "Stop the workflow if this selector is not found")]
86 IAllowSelectorSettings WithStopOnNotFound(bool trueFalse = false);
87 [Data(Description = "When retrieving data from the element, get data from the named attribute. [visible text is default]")]
88 IAllowSelectorSettings UseAttribute(string attributeName);
89 [Data(Description = "Located elements will match only if the text contains the supplied string")]
90
91 IAllowSelectorSettings ContainsAttribute(string text);
92 [Data(Description = "Located elements will match only if they have this named attribute")]
93 IAllowSelectorSettings MatchAttribute(string href);
94 [Data(Description = "Located elements will match only if the attribute name matches this regular expression")]
95 IAllowSelectorSettings MatchAttributeRegex(string href);
96 [Data(Description = "Located elements will match only if the text contains the supplied string")]
97
98 IAllowSelectorSettings ContainsHRef(string text);
99 [Data(Description = "Located elements will match only if they have this href")]
100 IAllowSelectorSettings MatchHRef(string href);
101 [Data(Description = "Located elements will match only if the href matches this regular expression")]
102 IAllowSelectorSettings MatchHRefRegex(string href);
103 [Data(Description = "Located elements will match only if the text contains the supplied string")]
104
105 IAllowSelectorSettings ContainsPlaceholder(string text);
106 [Data(Description = "Located elements will match only if the placeholder value matches the supplied string")]
107 IAllowSelectorSettings MatchPlaceholder(string placeholder);
108 [Data(Description = "Located elements will match only if the placebolder value matches this regular expression")]
109 IAllowSelectorSettings MatchPlaceholderRegex(string placeholder);
110 [Data(Description = "Located elements will match only if the text contains the supplied string")]
111
112 IAllowSelectorSettings ContainsSrc(string text);
113 [Data(Description = "Located elements will match only if the src matches the supplied string")]
114 IAllowSelectorSettings MatchSrc(string src);
115 [Data(Description = "Located elements will match only if the src matched the regular expression")]
116 IAllowSelectorSettings MatchSrcRegex(string src);
117 [Data(Description = "Located elements will match only if the text contains the supplied string")]
118
119 IAllowSelectorSettings ContainsText(string text);
120 [Data(Description = "Located elements will match only if the text matches the regular expression")]
121 IAllowSelectorSettings MatchText(string text);
122 [Data(Description = "Located elements will match only if the text matches the regular expression")]
123 IAllowSelectorSettings MatchTextRegex(string text);
124
125 [Data(Description = "Located elements will match only if the text contains the supplied string")]
126 IAllowSelectorSettings ContainsValue(string text);
127 [Data(Description = "Located elements will match only if the value matches the supplied string")]
128 IAllowSelectorSettings MatchValue(string value);
129 [Data(Description = "Located elements will match only if the value matches the regular expression")]
130 IAllowSelectorSettings MatchValueRegex(string value);
131 [Data(Description = "Custom Application UIAutomation Element matching method to examine and 'match' located elements using your algorithm.")]
132 IAllowSelectorSettings MatchFunction(Selector.appMatchingFunction AppMatchingFunction);
133 [Data(Description = "Custom browser webElement matching method to examine and 'match' located elements using your algorithm")]
134 IAllowSelectorSettings MatchFunction(Selector.webMatchingFunction WebMatchingFunction);
135 }
136 public interface IAllowCallBack
137 {
138 // return values
139 // 0 = not handled
140 // 1 = handled
141 // -1 = error
142 [Callback(Description = "Selector based callback if this selector is found")]
143 IAllowSelectorSettings CallIfFound(Browser.Browser.CallIfDelegate CallIfFound);
144 [Callback(Description = "Selector based callback if this selector is NOT found")]
145 IAllowSelectorSettings CallIfNotFound(Browser.Browser.CallIfDelegate CallIfNotFound);
146 // TODO: might we want to have an element called directly after it is filled in rather than the whole row? NOT YET
147 // IAllowAfterAnySelector CallAfterFillIn(Browser.Browser.CallAfterFillInDelegate CallAfterFillIn);
148 }
149
150 #endregion <Selector Settings>
151 #region <GPAL Interfaces>
152 [Interface(Description = "Global Settings")]
153 public interface IAllowGPALSettings
154 {
155 [GPALSettings(Description = "Print GPAL published information or exception messages to the supplied database. One column for each GPALEventArgs property. ")]
156 IAllowGPALSettings WithPublishToLogger(IGPALLogger logger);
157 [GPALSettings(Description = "Stops publishing events to a logger, for a workflow that logged a stretch of work to its own place and is done with it")]
158 IAllowGPALSettings RemoveLogger(IGPALLogger logger);
159 [GPALSettings(Description = "Print GPAL published information or exception messages to the output window in VisualStudio. [true (default)]")]
160 IAllowGPALSettings WithPublishToDebug(GPALEventType eventTypes = GPALEventType.INFO | GPALEventType.WARNING | GPALEventType.ERROR | GPALEventType.EXCEPTION | GPALEventType.NOTICE | GPALEventType.CAUTION | GPALEventType.FAILURE);
161 [GPALSettings(Description = "Indicate which published events to print to the console. [None (default)]")]
162 IAllowGPALSettings WithPublishToConsole(GPALEventType eventTypes = GPALEventType.INFO | GPALEventType.WARNING | GPALEventType.ERROR | GPALEventType.EXCEPTION | GPALEventType.NOTICE | GPALEventType.CAUTION | GPALEventType.FAILURE);
163 [Settings(Description = "Write specified GPAL events to a text area on a form. [none (default)]")]
164 IAllowGPALSettings WithPublishToControl(GPALTextArea control);
165 [Settings(Description = "Which GPAL events reach an attached handler. [all (default)]")]
166 IAllowGPALSettings WithHandlerEvents(GPALEventType eventTypes);
167 [Settings(Description = "Which GPAL events reach the information handler. [all (default)]")]
168 IAllowGPALSettings WithInformationHandlerEvents(GPALEventType eventTypes);
169 [Settings(Description = "Which GPAL events reach the exception handler. [all (default)]")]
170 IAllowGPALSettings WithExceptionHandlerEvents(GPALEventType eventTypes);
171 [Settings(Description = "Which GPAL events reach the form control. [all (default)]")]
172 IAllowGPALSettings WithControlEvents(GPALEventType eventTypes);
173 [GPALSettings(Description = "Print stack track when GPAL prints it's own published messages (PublishToConsole/PublishToDebug == true). [false (default)]")]
174 IAllowGPALSettings WithPublishStackTrace(bool trueFalse = true);
175 [GPALSettings(Description = "Callback for failures a workflow can decide about, used by any browser without its own CallOnFail")]
177 [GPALSettings(Description = "Intercharacter typing delay [0ms (default), no pacing]")]
178 IAllowGPALSettings WithTypingDelay(int delayInTicks = 0);
179 [GPALSettings(Description = "Handler to receive GPAL Exception events")]
180 IAllowGPALSettings WithExceptionHandler(EventHandler<GPALEventArgs> ExceptionEventHandler);
181 [GPALSettings(Description = "Handler to receive GPAL Information events")]
182 IAllowGPALSettings WithInformationHandler(EventHandler<GPALEventArgs> InformationEventHandler);
183 [GPALSettings(Description = "Image matching similarity percentage. [80 (default)]")]
184 IAllowGPALSettings WithImageMatchingPercentage(int matchPercent = 80);
185 [GPALSettings(Description = "How many nodes a YAML payload may hold before GPAL stops writing aliases for shared references. Above it a shared reference is written out again instead of as an alias, which is what keeps a large flat collection from stalling. A graph that holds a cycle always keeps its aliases, because YAML cannot write a cycle without them. 0 never stops")]
186 IAllowGPALSettings WithYamlAliasLimit(int nodeLimit = 5000);
187 [GPALSettings(Description = "Simulate moving the mouse for every action (implies .WithHardware). [false (default)]")]
188 IAllowGPALSettings WithSimulateMouseMovement(bool trueFalse = true);
189 [GPALSettings(Description = "Stop workflow if any selector is not found")]
190 IAllowGPALSettings WithStopOnNotFound(bool trueFalse = true);
191 [GPALSettings(Description = "Global location for browser drivers. [./ (default)(same dir as exe)]")]
192 IAllowGPALSettings WithDriverLocation([Directory(Description = "Global location for browser drivers. [./ (default)(same dir as exe)]")] string driverPath = "./");
193 [GPALSettings(Description = "The folder GPAL writes its own throwaway files to")]
194 IAllowGPALSettings WithTempDirectory([Directory(Description = "Where GPAL writes files it created itself and nobody asked to keep. [GPALfilesSafeToDelete beside the exe (default)]")] string tempPath);
195 [GPALSettings(Description = "Set the default location to store temporary profiles if WithDefaultDataDir is not used. default [C:\\profiles]. Also saved in GPAL.yaml that loads on startup.")]
196 IAllowGPALSettings WithTempProfileParentDirectory([Directory(Description = "Global location for temp profiles. [c:\\profiles (default)(saved in GPAL.yaml that is loaded on startup)]")] string tempProfileDirectory);
197 [GPALSettings(Description = "Substitue string when data cannot be retrieved for an element [##UNABLE TO GET## (default)]")]
198 IAllowGPALSettings WithDefaultErrorPlaceholder(string message = "##UNABLE TO GET##");
199 [GPALSettings(Description = "Automatically update the Chrome webdriver when running a GPAL application. Manually deploy first Chrome driver, tho.")]
200 IAllowGPALSettings WithAutomationEngine(AutomationEngine automationEngine = AutomationEngine.PuppeteerPort);
201 [GPALSettings(Description = "Automatically update the Chrome webdriver when running a GPAL application. Manually deploy first Chrome driver, tho.")]
202 IAllowGPALSettings WithAutoUpdateWebDriver(bool trueFalse = true);
203 [GPALSettings(Description = "Do not try alternate methods to interact with an element if an error occurs.")]
204 IAllowGPALSettings WithNoFallbackActions(bool trueFalse = true);
205 [GPALSettings(Description = "Ticks to wait for element to show up before continuing. Applies to every element in every workflow. Override in a Unit of Work with .WaitFor().")]
206 IAllowGPALSettings WithWaitFor(int waitForInTicks);
207 [GPALSettings(Description = "Global CallIfFound handler for all selectors in any Unit of Work")]
208 IAllowGPALSettings CallIfFound(Browser.Browser.CallIfDelegate CallIfFound);
209 [GPALSettings(Description = "Global CallIfFound handler for all selectors in any Unit of Work")]
210 IAllowGPALSettings CallIfNotFound(Browser.Browser.CallIfDelegate CallIfNotFound);
211 [GPALSettings(Description = "Global CallIfFound handler for all application selectors in any Unit of Work")]
212 IAllowGPALSettings AppCallIfFound(Application.Application.CallIfDelegate CallIfFound);
213 [GPALSettings(Description = "Global CallIfFound handler for all application selectors in any Unit of Work")]
214 IAllowGPALSettings AppCallIfNotFound(Application.Application.CallIfDelegate CallIfNotFound);
215 }
216 #endregion <GPAL Interfaces>
217 #region <Clipboard Interfaces>
219 , IAllowToGPALObject<IGPALClipboard>
220 { }
221 public interface IAllowClipboardInput
222 {
223 [Settings(Description = "Text to put on the clipboard")]
224 IAllowClipboardSet WithInput(string text);
225 [Settings(Description = "Grid to put on the clipboard, rows as lines and cells separated by tabs")]
226 IAllowClipboardSet WithInput(IGPALGrid<string> grid);
227 [Settings(Description = "File whose text goes on the clipboard, or the file itself for a FileList")]
228 IAllowClipboardSet WithInput(GPALFile file);
229 [Action(Description = "Read the clipboard. Text when no type is given.")]
230 IAllowClipboardInto GetClipboard(ClipboardType clipboardType = ClipboardType.Text);
231 [Action(Description = "Empty the clipboard")]
232 IGPALClipboard Clear();
233 }
234 public interface IAllowClipboardSet
235 {
236 [Action(Description = "Put what WithInput named on the clipboard. Text when no type is given.")]
237 IGPALClipboard SetClipboard(ClipboardType clipboardType = ClipboardType.Text);
238 }
239 public interface IAllowClipboardInto
240 {
241 [Action(Description = "What is on the clipboard, as text")]
242 IGPALClipboard SaveTo(out string text);
243 [Action(Description = "What is on the clipboard, split into a grid")]
244 IGPALClipboard SaveTo(out IGPALGrid<string> grid);
245 [Action(Description = "Writes what is on the clipboard to a file")]
246 IGPALClipboard SaveTo(GPALFile file);
247 }
248 #endregion <Clipboard Interfaces>
249 #region <Database Interfaces>
251 , IAllowParametersAndUsing, IAllowParametersAndInto, IAllowDatabaseExecute, IAllowToGPALObject<IGPALDatabase>, System.IDisposable
252 {
253 IGPALGrid<string> Tokens { [Data(Description = "The rows/columns returned from the database")] get; }
254 }
255 public interface IAllowParameterLength { [Settings(Description = "The length of the last parameter named", Submenu = "Parameters")] IAllowDatabaseSettings WithParameterLength(int columnLength); };
256 public interface IAllowColumnPrecision { [Settings(Description = "The precision of the last parameter named", Submenu = "Parameters")] IAllowPrecsionScaleAndSettings WithParameterPrecision(int columnPrecision); };
257 public interface IAllowColumnScale { [Settings(Description = "The scale of the last parameter named", Submenu = "Parameters")] IAllowPrecsionScaleAndSettings WithParameterScale(int columnScale); };
262 public interface IAllowDatabaseExecute
263 {
264 [Fluent(Description = "Per-statement breakdown (via SqlCommand.StatementCompleted) instead of the single aggregate count")]
265 IAllowParametersAndActions Execute(out int rowCount);
267 [Fluent(Description = "Per-statement breakdown (via SqlCommand.StatementCompleted) instead of the single aggregate count")]
268 IAllowParametersAndActions Execute(out List<int> rowCountsPerStatement);
269 }
270
276 {
283 [Data(Description = "Only SaveTo(out IGPALGrid<string>) returns this - meaningless for SaveTo(DataTable)/SaveTo(DataSet), which already separate results by table")]
284 IAllowDatabaseSettings GetRowCount(out List<int> rowCountsPerTable);
285 }
286
294 public interface IAllowDatabaseSettings : IAllowToGPALObject<IGPALDatabase>
295 {
296 [Settings(Description = "Set the connectrion string used to connect to the database", Submenu = "Connection")]
297 IAllowDatabaseSettings WithConnectionString(string connectionString);
298 [Settings(Description = "How long a command may run before the provider gives up. [the provider's own default]", Submenu = "Connection")]
299 IAllowDatabaseSettings WithCommandTimeout(int timeoutInSeconds);
300 [Action(Description = "Close the connection and roll back a transaction still open on it. The database can be used again after.")]
302 [Settings(Description = "Set the username used to connect to the database", Submenu = "Connection")]
303 IAllowDatabaseSettings WithUsername(string userName);
304 [Settings(Description = "Set the password used to connect to the database", Submenu = "Connection")]
305 IAllowDatabaseSettings WithPassword(string password);
306 [Settings(Description = "Set the database servername", Submenu = "Connection")]
307 IAllowDatabaseSettings WithServerName(string serverName);
308 [Settings(Description = "Set the database instance name", Submenu = "Connection")]
309 IAllowDatabaseSettings WithDatabaseName(string databaseName);
310 [Settings(Description = "Set the type of database GPAL is interacting with", Submenu = "Connection")]
311 IAllowDatabaseSettings WithDatabaseType(DatabaseType databaseType);
312 [Settings(Description = "Set the table name to query for input", Submenu = "SQL")]
313 IAllowDatabaseSettings WithTableName(string tableName);
314 [Settings(Description = "The SQL command to execute for the input data grid (tokens)", Submenu = "SQL")]
315 IAllowDatabaseSettings WithSQLCommand(string sqlCommand);
316 [Settings(Description = "The stored procedure to execute for the input data grid (tokens)", Submenu = "SQL")]
317 IAllowDatabaseSettings WithStoredProcedure(string storedProcedure);
318 [Settings(Description = "Add a parameter name to the parameter names list", Submenu = "Parameters")]
319 IAllowDatabaseSettings WithParameterName(string parameterName);
320 [Settings(Description = "Define a DateTime column", Submenu = "Parameters")]
321 IAllowDatabaseSettings WithDatetimeParameter(string parameterName);
322 [Settings(Description = "Define a Time column", Submenu = "Parameters")]
323 IAllowDatabaseSettings WithTimeParameter(string parameterName);
324 [Settings(Description = "Define a Timestamp column", Submenu = "Parameters")]
325 IAllowDatabaseSettings WithTimestampParameter(string parameterName);
326 [Settings(Description = "Define a Decimal column", Submenu = "Parameters")]
327 IAllowPrecsionScaleAndSettings WithDecimalParameter(string parameterName);
328 [Settings(Description = "Define a Float column [Double/Real]", Submenu = "Parameters")]
329 IAllowDatabaseSettings WithFloatParameter(string parameterName);
330 [Settings(Description = "Define an Image column", Submenu = "Parameters")]
331 IAllowDatabaseSettings WithImageParameter(string parameterName);
332 [Settings(Description = "Define an Integer column", Submenu = "Parameters")]
333 IAllowDatabaseSettings WithIntegerParameter(string parameterName);
334 [Settings(Description = "Define a Money column", Submenu = "Parameters")]
335 IAllowDatabaseSettings WithMoneyParameter(string parameterName);
336 [Settings(Description = "Define a VarChar column", Submenu = "Parameters")]
337 IAllowParameterLength WithVarCharParameter(string parameterName);
338 [Settings(Description = "Define an NVarChar column", Submenu = "Parameters")]
339 IAllowParameterLength WithNVarCharParameter(string parameterName);
340 [Settings(Description = "Define a Char column", Submenu = "Parameters")]
341 IAllowParameterLength WithCharParameter(string parameterName);
342 [Settings(Description = "Define an NChar column", Submenu = "Parameters")]
343 IAllowParameterLength WithNCharParameter(string parameterName);
344 [Settings(Description = "Define a Text column", Submenu = "Parameters")]
345 IAllowParameterLength WithTextParameter(string parameterName);
346 [Settings(Description = "Define a NText column", Submenu = "Parameters")]
347 IAllowParameterLength WithNTextParameter(string parameterName);
348 [Settings(Description = "Pass a table to a stored procedure as a table-valued parameter with this name", Submenu = "Parameters")]
349 IAllowDatabaseSettings WithTableParameter(string parameterName); // Structured columns
350 [Settings(Description = "How many rows to read", Submenu = "SQL")]
351 IAllowDatabaseSettings WithRowCount(int rowCount);
352 [Settings(Description = "The SQL that Create runs, in place of the one GPAL builds", Submenu = "SQL")]
353 IAllowDatabaseSettings WithCreateAs(string createSQL);
354 [Settings(Description = "The SQL that Read runs, in place of the one GPAL builds", Submenu = "SQL")]
355 IAllowDatabaseSettings WithReadAs(string selectSQL);
356 [Settings(Description = "The SQL that Update runs, in place of the one GPAL builds", Submenu = "SQL")]
357 IAllowDatabaseSettings WithUpdateAs(string updateSQL);
358 [Settings(Description = "The SQL that Delete runs, in place of the one GPAL builds", Submenu = "SQL")]
359 IAllowDatabaseSettings WithDeleteAs(string deleteSQL);
360 [Settings(Description = "Callback for a database error the workflow can decide about", Submenu = "SQL")]
361 IAllowDatabaseSettings WithErrorCallback(GPALDatabase.CallOnError CallOnError);
362 [Settings(Description = "The user-defined table type of the table parameter", Submenu = "Parameters")]
363 IAllowDatabaseSettings WithUDTTName(string typeName); // Structured column UDTT name
364 }
365 public interface IAllowDatabaseInto
366 {
367 [Action(Description = "Reads a single value: the first column of the first row, without building a grid around it")]
368 IAllowDatabaseGridSettings SaveTo(out IGPALGrid<string> dataGrid);
369 [Action(Description = "Reads a single value: the first column of the first row, without building a grid around it")]
370 IAllowDatabaseSettings SaveTo(out System.Data.DataTable dataTable);
371 [Action(Description = "Reads a single value: the first column of the first row, without building a grid around it")]
372 IAllowDatabaseSettings SaveTo(out System.Data.DataSet dataSet);
373 [Action(Description = "Reads a single value: the first column of the first row, without building a grid around it")]
374 IAllowDatabaseSettings SaveTo(out string value);
375 }
376 public interface IAllowDatabaseUsing
377 {
378 [Settings(Description = "The rows to write", Submenu = "SQL")]
379 IAllowDatabaseExecute Using(IGPALGrid<string> dataGrid);
380 [Settings(Description = "The rows to write", Submenu = "SQL")]
381 IAllowDatabaseExecute Using(System.Data.DataTable dataTable);
382 }
383 public interface IAllowParameters
384 {
385 IAllowParameters ClearParameters { [Action(Description = "If you have already defined parameter objectss on a GPAL.Database, you can clear them and add new parameter objects;")] get; }
386 [Settings(Description = "Add a parameter to the parameters list", Submenu = "Parameters")]
387 IAllowParametersAndActions WithParameter(string parameter);
388 [Settings(Description = "Add a parameter to the parameters list", Submenu = "Parameters")]
389 IAllowParametersAndActions WithParameterGrid(IGPALGrid<string> parameter);
390 }
392 {
393 IAllowParametersAndUsing Create { [Action(Description = "Insert a row", Submenu = "Rows")] get; }
394 IAllowParametersAndInto Read { [Action(Description = "Read rows", Submenu = "Rows")] get; }
395 IAllowParametersAndUsing Update { [Action(Description = "Update rows", Submenu = "Rows")] get; }
396 IAllowParametersAndUsing Delete { [Action(Description = "Delete rows", Submenu = "Rows")] get; }
397 IAllowParametersAndActions BeginTransaction { [Action(Description = "Start a transaction", Submenu = "Transactions")] get; }
398 IAllowDatabaseActions Rollback { [Action(Description = "Undo the transaction", Submenu = "Transactions")] get; }
399 IAllowDatabaseActions Commit { [Action(Description = "Commit the transaction", Submenu = "Transactions")] get; }
400
401 }
410 public interface IAllowParametersAndInto
413 { }
414
415 #endregion <DatabaseInterfaces>
416 #region Credentials
426 {
427 [Settings(Description = "The login for the credential service itself, built once and handed to every request that queries it")]
428 IAllowCredentialSettings WithMasterCredentials(ICredentials masterCredentials);
429 }
430
432 {
433 [Settings(Description = "Selects which password manager or cloud identity service this credentials request targets")]
434 IAllowCredentialMethod WithService(CredentialServiceType serviceType);
435 }
436
437 public interface IAllowUsernameOrKey : IAllowToGPALObject<ICredentials>
438 {
439 [Settings(Description = "Sets the username, either as a credential to retrieve directly (with CredentialServiceType.None) or as part of WithCredentials' master login")]
440 IAllowCredentialsPassword WithUsername(string username);
441
442 // Alternative to WithUsername/WithPassword/etc: supply the login (master) credentials for the
443 // credential service itself (e.g. your Bitwarden/LastPass account), previously built with
444 // GPAL.CredentialsFor(CredentialServiceType.None).WithUsername(...).WithPassword(...).
445
446 // Static API key - supply the key directly, from an env variable, or from an internal REST endpoint:
447 // GPAL.CredentialsFor(CredentialServiceType.StaticKey).WithServiceKey("sk-ant-...").ToGPALObject()
448 [Settings(Description = "Service key is a custom string consisting of your ClientID:ClientSecret")]
449 IAllowCredentialSettings WithServiceKey(string key);
450
451 // Like WithServiceKey, but reads the key from an environment variable instead of a literal string:
452 // GPAL.CredentialsFor(CredentialServiceType.StaticKey).WithKeyFromEnv("ANTKEY").ToGPALObject()
453 [Settings(Description = "Like WithServiceKey, but reads the key from an environment variable (checking process, user, then machine scope) instead of taking it as a literal string")]
454 IAllowCredentialSettings WithKeyFromEnv(string envVariableName);
455
456 // Like WithServiceKey, but fetches the key via a GET request made with an already-configured RESTClient.
457 // Must be followed by .WithEndpoint(endpoint) to specify which endpoint returns the key:
458 // GPAL.CredentialsFor(CredentialServiceType.StaticKey).WithKeyFromApi(restClient).WithEndpoint("ANTKEY").ToGPALObject()
459 [Settings(Description = "Like WithServiceKey, but fetches the key via a GET request made with the supplied, already-configured RESTClient")]
460 IAllowKeyFromApiEndpoint WithKeyFromApi(IRESTClient restClient);
461 }
462
464 {
465 [Settings(Description = "Call this endpoint on the RESTClient given to WithKeyFromApi and use the answer as the service key")]
466 IAllowCredentialSettings WithEndpoint(string endpoint);
467 }
468
469 public interface IAllowCredentialsPassword : IAllowToGPALObject<ICredentials>
470 {
471 [Settings(Description = "Sets the password, either as a credential to retrieve directly (with CredentialServiceType.None) or as part of WithCredentials' master login")]
472 IAllowOAuthClient WithPassword(string password);
473 }
474 public interface IAllowClientId
475 {
476 [Settings(Description = "Sets the OAuth client ID used to authenticate to ServiceType")]
477 IAllowClientSecret WithClientId(string clientId);
478 [Settings(Description = "Loads a Google Cloud service account key from a JSON key file, used to fetch an access token without an interactive OAuth flow")]
479 IAllowCredentialSettings WithServiceAccountKey(GPALFile serviceAccountKeyFile);
480 [Settings(Description = "Supplies a Google Cloud service account key as a raw JSON string, used to fetch an access token without an interactive OAuth flow")]
481 IAllowCredentialSettings WithServiceAccountKey(string serviceAccountKey);
482 [Settings(Description = "Supplies a Google Cloud service account key as a deserialized object, used to fetch an access token without an interactive OAuth flow")]
483 IAllowCredentialSettings WithServiceAccountKey(GoogleServiceAccountKey serviceAccountKey);
484 }
485 public interface IAllowClientSecret
486 {
487 [Settings(Description = "Sets the OAuth client secret and derives ServiceKey as 'ClientId:ClientSecret'")]
488 IAllowCredentialSettings WithClientSecret(string clientSecret);
489 }
490 public interface IAllowOAuthClient : IAllowClientId, IAllowToGPALObject<ICredentials>
491 {
492 [Settings(Description = "How the site expects to be told who you are, which decides what a browser given this credential does with it")]
493 IAllowOAuthClient WithWebAuth(WebAuthType webAuthType);
494 [Settings(Description = "A token the workflow already holds, presented according to the WebAuthType")]
495 IAllowOAuthClient WithAccessToken(string accessToken);
496 [Settings(Description = "Where the OAuth redirect lands, which has to be the URI registered with the provider")]
497 IAllowOAuthClient WithAuthRedirectUrl(string redirectUrl);
498 }
499
500 public interface IAllowCredentialSettings : IAllowGetCredentials, IAllowToGPALObject<ICredentials>
501 {
502 [Data(Description = "Find the vault item matching this search term, such as a site name or url")]
503 IAllowCredentialSettings GetCredentialsFor(string target);
504 [Settings(Description = "Restricts GetCredentialsFor/SaveTo results to vault items whose URL contains this domain")]
505 IAllowCredentialSettings WithDomain(string domain);
506 [Action(Description = "Looks up the credential matching.GetCredentialsFor's target (filtered by.WithDomain if set) and appends a [Username, Password] row to the given grid")]
507 IAllowGetCredentials SaveTo(IGPALGrid<string> grid);
508 [Settings(Description = "Supplies a previously-obtained OAuth authorization code, skipping the interactive authorization step")]
509 IAllowCredentialSettings WithAuthCode(string authCode);
510 [Settings(Description = "Supplies a previously-obtained OAuth refresh token, used to fetch a new access token without re-authorizing")]
511 IAllowCredentialSettings WithRefreshToken(string refreshToken);
512 [Settings(Description = "Sets the OAuth scope to request when an access token is fetched")]
513 IAllowCredentialSettings WithScope(OAuthScope scope);
514 }
515
516 public interface IAllowGetCredentials
517 {
518 // No methods, placeholder for Into completion
519 [Action(Description = "Fetches a new access token for ServiceType using the credentials/configuration supplied so far, and stores it in AccessToken/IssueTime/ExpiresIn")]
520 void FetchAccessToken(out string accessToken);
521 }
522
527 #endregion Credentials
528 #region AI
529 public interface IAllowAICredentials
530 {
531 [Settings(Description = "The API key for the AI provider")]
532 IAllowAITask WithCredentials(ICredentials credentials);
533 [Settings(Description = "The API key for the AI provider")]
534 IAllowAITask WithCredentials(string staticApiKey);
535 }
536 public interface IAllowAIModel
537 {
538 // Accepts AIModel.ClaudeSonnet46 etc, or any freehand model ID string via implicit conversion.
539 [Settings(Description = "Which model to call")]
540 IAllowAITask WithModel(AIModel model);
541 }
542 public interface IAllowAITaskConfig
543 {
544 [Settings(Description = "What to ask the AI to do")]
545 IAllowAIConfig WithTask(AITask task);
546 [Settings(Description = "Settings for the task")]
547 IAllowAIConfig WithTaskConfig(ClassificationConfig config);
548 [Settings(Description = "The kind of classification")]
549 IAllowAIConfig WithClassificationType(AIClassificationType type);
550 [Settings(Description = "Your own categories for a custom classification")]
551 IAllowAIConfig WithCustomClassification(ClassificationConfig config);
552 }
553 public interface IAllowAIOutput
554 {
555 [Settings(Description = "Where the answers go")]
556 IAllowAIExecution WithOutputTo(out IGPALGrid<string> target);
557 [Settings(Description = "Where the answers go")]
558 IAllowAIExecution WithOutputTo(object target);
559 }
560 public interface IAllowAIConfig : IAllowAITaskConfig, IAllowAIOutput, IAllowToGPALObject<IGPALAI>
561 {
562 [Settings(Description = "What the AI works on: text, a file or a grid")]
563 IAllowAIOutput WithInputFrom(object source);
569 IAllowAIOutput WithLiveInputFrom(GPALForm.GPALInput input, int debounceMilliseconds = 500);
575 IAllowAIOutput WithLiveInputFrom(GPALForm.GPALTextArea textArea, int debounceMilliseconds = 500);
576 }
577 public interface IAllowAIExecution : IAllowToGPALObject<IGPALAI>
578 {
579 [Callback(Description = "Callback for each answer the AI gives")]
580 IAllowAIConfig CallAfterAIResponse(AIResponseDelegate callback);
581 [Fluent(Description = "Send the task to the AI")]
582 IAllowAIConfig Execute();
583
584 // Reports "Sending request...", "Waiting for response...", "Response received", and any
585 // error encountered, to the given status strip while the AI task runs.
586 [Settings(Description = "A status strip to show progress in")]
587 IAllowAIExecution WithStatusTo(GPALForm.GPALStatusStrip statusStrip);
588 }
589 public interface IAllowAITask : IAllowAICredentials, IAllowAIModel, IAllowToGPALObject<IGPALAI>
590 {
591 [Settings(Description = "What to ask the AI to do")]
592 IAllowAIConfig WithTask(AITask task);
593 }
594 public interface IAllowAIProvider : IAllowToGPALObject<IGPALAI>
595 {
596 [Settings(Description = "Which AI provider to call")]
597 IAllowAITask WithProvider(AIProviderType provider);
598 }
602 #endregion AI
603 #region <Converter Interfaces>
604 public interface IGPALConverter : IAllowConverterInput, IAllowConverterSettings, IAllowConverterActions, IAllowToGPALObject<IGPALConverter>
606 {
607 // internal ConverterSettings ConverterSettings { get; set; }
608 }
609 public interface IAllowConverterInput : IAllowToGPALObject<IGPALConverter>
610 {
611 [Settings(Description = "Get input data to convert using the Database object")]
612 IAllowConverterSettingsAndActions WithInput(IGPALDatabase inputDatabase);
613 [Settings(Description = "Input data is contained in this GPALGrid")]
614 IAllowConverterSettingsAndActions WithInput(IGPALGrid<string> inputGrid);
615 [Settings(Description = "Input data is in this string")]
616 IAllowConverterSettingsAndActions WithInput(string inputData);
617 [Settings(Description = "Input data file (extension denotes type, override using WithInputType)")]
618 IAllowConverterSettingsAndActions WithInput(GPALFile inputFile);
619 [Settings(Description = "Input class, uses reflection to map to output format")]
620 IAllowConverterSettingsAndActions WithInput(dynamic inputClass);
621 [Settings(Description = "[Global] Register a custom struct type for the converter to recognize. Structs cannot be reliably determined. If you have a custom struct to convert, register it first.")]
622 IAllowConverterInput RegisterKnownStructType(Type knownStructType);
623 }
624 public interface IAllowConverterSettings : IAllowToGPALObject<IGPALConverter>
625 {
626 [Settings(Description = "Specify input data format")]
627 IAllowConverterSettingsAndActions WithInputType(DataFormat inDataType);
628 [Settings(Description = "Specify output data format")]
629 IAllowConverterSettingsAndActions WithOutputType(DataFormat outDataType);
630 [Settings(Description = "[Global] First line is a column name list (for flat files: csv, txt, prn)")]
631 IAllowConverterSettingsAndActions WithFirstLineHasColumnNames(bool firstLineHeaders = true);
632 [Settings(Description = "[Global] Ignore first line column name list (for flat files: csv, txt, prn)")]
633 IAllowConverterSettingsAndActions WithIgnoreFirstLineColumnNames(bool ignoreFirstLine = true);
634 [Settings(Description = "[Global] Each field is contained in quotes (for flat files: csv, txt, prn)")]
635 IAllowConverterSettingsAndActions WithColumnsEnclosedInQuotes(bool fieldsEnclosedInQuote = true);
636 [Settings(Description = "Column names for this conversion. Overrides the input source's own columns positionally; unsupplied columns are backfilled from the source.")]
637 IAllowConverterSettingsAndActions WithColumnNames(List<string> columnNames);
638 [Settings(Description = "Append a single column name for this conversion. Repeated calls build the list in order.")]
639 IAllowConverterSettingsAndActions WithColumnName(string parameterName);
640 }
641 public interface IAllowConverterActions
642 {
643 [Action(Description = "Write the converted data into this database")]
644 IAllowConverterInputAndActions SaveTo(IGPALDatabase outputDatabase);
645 [Action(Description = "Write the converted data into this grid")]
646 IAllowConverterInputAndActions SaveTo(ref IGPALGrid<string> outputGrid);
647 [Action(Description = "Add the converted data to the end of this file, keeping what is already there")]
648 IAllowConverterInputAndActions AppendTo(GPALFile outputFile);
649 [Action(Description = "Write the converted data to this file, replacing what is there. The output format comes from the file's extension")]
650 IAllowConverterInputAndActions SaveTo(GPALFile outputFile);
651 [Action(Description = "Fill this object's properties from the converted data")]
652 IAllowConverterInputAndActions SaveTo<T>(ref T outputClass);
653 // RenderTo is the presentation half of the converter and is not built. The four declarations threw
654 // NotImplementedException, so a workflow could write a chain that compiled, appeared in GPAL Studio's
655 // action menu and then fell over at run time. Commented out until there is something behind them
656 //[Action(Description = "")]
657 //IAllowConverterInputAndActions RenderTo(IGPALDatabase outputDatabase);
658 //[Action(Description = "")]
659 //IAllowConverterInputAndActions RenderTo(string outputData);
660 //[Action(Description = "")]
661 //IAllowConverterInputAndActions RenderTo(GPALFile outputFile);
662 //[Action(Description = "")]
663 //IAllowConverterInputAndActions RenderToClass(out dynamic outputClass);
664 [Action(Description ="Pretty print the input to a new string.")]
665 IAllowConverterInputAndActions PrettyPrintTo(out string outputData);
666 }
667 public interface IAllowBase64Save
668 {
669 [Action("Save to a string the decoded Base64 content")]
670 IAllowBase64SaveOrInput SaveTo(string base64Output);
671 [Action("Save to a file based upon content type")]
672 IAllowBase64SaveOrInput SaveTo(GPALFile base64OutputFile);
673 }
674
684
685 #endregion <Converter Interfaces>
686 #region <File Interfaces>
688 {
689 string First { get; }
690 string Last { get; }
691 GPALFile Next { get; }
692 string Filename { get; }
693 List<string> Filenames { get; }
694 string DirectoryPart { get; }
695 string FilePart { get; }
696 List<string> DirectoryParts { get; }
697 List<string> FileParts { get; }
698 List<string> ReturnFilenames { get; }
699 string SourceUrl { get; }
700 int Count { get; }
701
702 }
703 internal interface IGPALFileInternal
704 {
705 internal GPALFileSettings FileSettings { get; set; }
706 internal List<IGPALGrid<string>> TokenList { get; set; }
707 internal List<string> FileData { get; set; }
708 internal List<char?> Delimiter { get; set; }
709 internal List<bool> FieldsEnclosedInQuotes { get; set; }
710 internal List<bool> FirstLineIsColumnNames { get; set; }
711 internal List<bool> IgnoreFirstLineColumnNames { get; set; }
712 internal bool UseOneHeaderForAllFiles { get; set; }
713 internal List<Dictionary<object, dynamic>> FileDictionary { get; set; }
714 internal List<IGPALGrid<string>> FileGrid { get; set; }
715 internal bool AlreadyTokenized { get; set; }
716 }
717 public interface IAllowFileSettings : IAllowFileName, IAllowToGPALObject<GPALFile>
718 {
719 [Settings(Description = "IF this file is delimited, the delimiter used.")]
720 IAllowFileSettings WithDelimiter(char delimiter);
721 [Settings(Description = "Add a column name to the column name list. (If no header in file or to override.)")]
722 IAllowFileSettings WithColumnName(string parameterName);
723 [Settings(Description = "Add column names to the column name list using the .WithDelimiter. Use this to add headers for multiple files.")]
724 IAllowFileSettings WithColumnNames(string columnNames);
725 [Settings(Description = "Add column names to the column name list using the supplied array. One column per element. Use this to add headers for multiple files.")]
726 IAllowFileSettings WithColumnNames(string[] columnNames);
727 [Settings(Description = "Each field is contained in quotes (for flat files: csv, txt, prn)")]
728 IAllowFileSettings WithColumnsEnclosedInQuotes(bool fieldsEnclosedInQuote = true);
729 [Settings(Description = "First line is a column name list (for flat files: csv, txt, prn)")]
730 IAllowFileSettings WithFirstLineIsColumnNames(bool firstLineIsHeader = true);
731 [Settings(Description = "Ignore first line header list")]
732 IAllowFileSettings WithIgnoreFirstLineColumnNames(bool ignoreFirstLine = true);
733 [Settings(Description = "Overwrite the file or generate a new filename. Overwrite is default.")]
734 IAllowFileSettings WithOverwriteFile(bool overwriteFile = false);
735 [Settings(Description = "One column list is defined, use it for all files in the file list. Without it each file takes the column list given for it, in file order.")]
736 IAllowFileSettings WithUseSameColumnNamesForAllFiles(bool useHeaderForAllFiles = true);
737 [Settings(Description = "Order in which files matched by a wildcard (e.g. *.csv) are added to the file list. Default is Name (alphabetical).")]
738 IAllowFileSettings WithFileSortOrder(Enums.FileSortOrder fileSortOrder);
739 [Settings(Description = "How Next builds a new unique filename (timestamp, date, or an incrementing counter). Default is CounterPadded.")]
740 IAllowFileSettings WithNextFilePattern(Enums.NextFilePattern nextFilePattern = Enums.NextFilePattern.CounterPadded);
741 }
742 public interface IAllowFileActions
743 {
744 [Action(Description = "Copy the defined GPALFile(s) to a destination file or directory")]
745 void CopyTo(string destination);
746 [Action(Description = "Move the defined GPALFile(s) to a destination file or directory")]
747 void MoveTo(string destination);
748 [Action(Description = "Delete the destination file or files (wildcard) or all in the directory (no filename)")]
749 void Delete(string destination);
750 [Action(Description = "Delete the defined GPALFile underlying file(s)")]
751 void Delete();
752 }
753 public interface IAllowFileName : IAllowToGPALObject<GPALFile>
754 {
755 [Settings(Description = "Add a filename to the GPALFile list. Actual output filenames added to end.")]
756 IAllowFileSettings WithFileName(string filename); // a wildcard pattern expands to the matching files; an http/https url is fetched to a local file and used from there
757 [Settings(Description = "A browser already holding the session a url needs. Set before .WithFileName. GPAL tries its own connection first and falls back to this browser, downloading in a new tab.")]
758 IAllowFileSettings WithBrowser(Browser.IBrowser browser);
759 }
760 #endregion <File Interfaces>
761 #region Grid
762 public interface IGPALGrid<T> : IAllowGridActions<T>, IEnumerable<List<T>> // , ICloneable
763 {
764 [Data(Description = "The rows as a list")]
765 List<T> ToList();
766 [Settings(Description = "Enable duplicate-row detection for this grid when it is passed into GetGrid (off by default).")]
767 IGPALGrid<T> WithDedupeData(bool useDedupe = true);
768 }
769 public interface IAllowGridActions<T> : IAllowToGPALObject<IGPALGrid<T>>
770 {
771 [Action(Description = "Add the rows of another grid")]
772 IAllowGridActions<T> Add(IGPALGrid<T> grid);
773 [Action(Description = "Add a row")]
774 IAllowGridActions<T> AddRow(List<T> row);
775 [Action(Description = "Add a column")]
776 IAllowGridActions<T> AddColumn(List<T> column);
777 int Rows { [Data(Description = "How many rows the grid has")] get; }
778 int Columns { [Data(Description = "How many columns the grid has")] get; }
779 IAllowGridActions<T> AddCell(T value, int row, int column);
780 T GetCell(int row, int column);
781 [Action(Description = "Remove every row")]
782 IAllowGridActions<T> Clear();
783 [Action(Description = "Remove the first or the last row")]
784 IAllowGridActions<T> DeleteRow(RowPosition rowPosition = RowPosition.Last);
785 [Action(Description = "Read rows from a file")]
786 IAllowGridActions<T> InputFrom(GPALFile input);
787 [Action(Description = "Write the rows to a file")]
788 IAllowGridActions<T> SaveTo(GPALFile output);
789 [Action(Description = "Read rows from a database")]
790 IAllowGridActions<T> InputFrom(IGPALDatabase input);
791 [Action(Description = "Write the rows to a database")]
792 IAllowGridActions<T> SaveTo(IGPALDatabase output);
793 List<T> this[int index] { [Data(Description = "The row at the given index")] get; set; }
794 T this[int row, int column] { get; set; }
795 [Data(Description = "How many rows the grid has")]
796 int Count();
797 [Data(Description = "Whether any row holds the given value")]
798 bool Contains(T value);
799 [Action(Description = "A copy of the grid")]
800 public object Clone();
801 }
802 #endregion
803 #region <Email Interfaces>
805 {
806 // what a settings file holds, readable so a form can show what LoadSettings brought in
807 string SMTPServerName { [Data(Description = "The SMTP server mail is sent through, as set by WithSMTPServerName or read from a settings file")] get; }
808 int SMTPPortNum { [Data(Description = "The port used to reach SMTPServerName")] get; }
809 string IMAPServerName { [Data(Description = "The IMAP server mail is read from, null when a POP server is the one named")] get; }
810 int IMAPPortNum { [Data(Description = "The port used to reach IMAPServerName")] get; }
811 string POPServerName { [Data(Description = "The POP server mail is read from, null when an IMAP server is the one named")] get; }
812 int POPPortNum { [Data(Description = "The port used to reach POPServerName")] get; }
813 string FromAddress { [Data(Description = "The address messages are sent from, as text, with the display name when there is one")] get; }
814 // when the last Send went out. null says it did not, and LastError says why
815 DateTime? Sent { [Data(Description = "When the last Send went out, null when it did not")] get; }
816 // why the last Send or Receive failed, or null when it did not
817 GPALMail.MailError LastError { [Data(Description = "The last failure, or null when the last call did not fail")] get; }
818 }
819 public interface IAllowEmailServerSettings : IAllowToGPALObject<IGPALMail>
820 {
821 [Settings(Description = "The IMAP server to receive from, by host name")]
822 IAllowEmailServerSettingsAndName WithIMAPServerName(string serverName);
823 [Settings(Description = "The port the IMAP server listens on")]
824 IAllowEmailServerSettingsAndName WithIMAPPortNum(int portNum);
825 [Settings(Description = "The POP3 server to receive from, by host name")]
826 IAllowEmailServerSettingsAndName WithPOPServerName(string serverName);
827 [Settings(Description = "The port the POP3 server listens on")]
828 IAllowEmailServerSettingsAndName WithPOPPortNum(int portNum);
829 [Settings(Description = "The SMTP server to send through, by host name")]
830 IAllowEmailServerSettingsAndName WithSMTPServerName(string serverName);
831 [Settings(Description = "The port the SMTP server listens on")]
832 IAllowEmailServerSettingsAndName WithSMTPPortNum(int portNum);
833 [Settings(Description = "Send even when the server's certificate cannot be validated. Off unless asked for, and it means nothing checks who is on the other end")]
834 IAllowEmailServerSettingsAndName WithAcceptAnyCertificate(bool acceptAnyCertificate);
835 [Settings(Description = "The credential to authenticate with, whose username and password win over WithUserName and WithPassword")]
836 IAllowEmailServerSettingsAndName WithCredentials(ICredentials credentials);
837 [Settings(Description = "The account name to sign in to the mail server with")]
838 IAllowEmailServerSettingsAndName WithUserName(string userName);
839 [Settings(Description = "The password to sign in to the mail server with")]
840 IAllowEmailServerSettingsAndName WithPassword(string password);
841 }
842 public interface IAllowEmailActions
843 {
844 [Action(Description = "Send the message the envelope settings built")]
846 [Action(Description = "Read waiting mail from the IMAP or POP server")]
848 [Action(Description = "Read the mail and hand back the messages")]
849 IAllowEmailEnvelopeAndActions Receive(out List<ReceivedEmail> receivedEmails);
850 [Action(Description = "Write every attachment on every message received into the given directory")]
851 IAllowEmailEnvelopeAndActions SaveTo(GPALFile directory);
852 [Action(Description = "Mark every message Receive collected as read on the server, in one connection. IMAP only.")]
853 IAllowEmailEnvelopeAndActions MarkAllAsRead();
854 [Action(Description = "Delete every message Receive collected from the server, in one connection. IMAP only.")]
856 [Action(Description = "Empty the envelope so the next message starts from nothing")]
858 [Action(Description = "Read the mail server settings from a file, or from the default settings file when none is named")]
859 IAllowEmailEnvelopeAndActions LoadSettings(GPALFile mailSettingsFile = null);
860 [Action(Description = "Write the mail server settings to a file, or to the default settings file when none is named")]
861 IAllowEmailEnvelopeAndActions SaveSettings(GPALFile mailSettingsFile = null);
862 }
863 public interface IAllowEmailEnvelope
864 {
865 [Settings(Description = "The address the mail is sent from")]
866 IAllowNameEnvelopeAndActions WithFromEmailAddress(string mailAddress);
867 [Settings(Description = "Add a recipient")]
868 IAllowNameEnvelopeAndActions WithToEmailAddress(string mailAddress);
869 [Settings(Description = "Add a copy recipient")]
870 IAllowNameEnvelopeAndActions WithCcEmailAddress(string mailAddress);
871 [Settings(Description = "Add a blind copy recipient")]
872 IAllowNameEnvelopeAndActions WithBccEmailAddress(string mailAddress);
873 [Settings(Description = "Add recipients, one per entry")]
874 IAllowNameEnvelopeAndActions WithToEmailAddress(string[] emailParts);
875 [Settings(Description = "Add copy recipients, one per entry")]
876 IAllowNameEnvelopeAndActions WithCcEmailAddress(string[] emailParts);
877 [Settings(Description = "Add blind copy recipients, one per entry")]
878 IAllowNameEnvelopeAndActions WithBccEmailAddress(string[] emailParts);
879 [Settings(Description = "Attach a file to the message. Call it again for each further attachment")]
880 IAllowEmailEnvelopeAndActions WithAttachment(GPALFile attachmentFile);
881 [Settings(Description = "The body text of the message")]
882 IAllowEmailEnvelopeAndActions WithBody(string bodyText);
883 [Settings(Description = "The subject line of the message")]
884 IAllowEmailEnvelopeAndActions WithSubject(string subject);
885 }
887 {
888 [Settings(Description = "Fetch only the messages the server still has as unread. Every message when false, which is the default.")]
889 IAllowEmailEnvelopeAndActions WithUnreadOnly(bool unreadOnly);
890 [Settings(Description = "The most messages one Receive may fetch, newest first. Every message by default.")]
891 IAllowEmailEnvelopeAndActions WithMaxMessages(int maxMessages);
892 }
893 public interface IAllowName { [Settings(Description = "Sets the display name on the address added just before this call, whether that was the from, a to, a cc or a bcc")] IAllowEmailEnvelopeAndActions WithName(string name); }
898 , IAllowToGPALObject<IGPALMail>
899 { }
903 , IAllowToGPALObject<IGPALMail>
904 { }
905 public interface IAllowEmailServerSettingsAndName : IAllowToGPALObject<IGPALMail>
909 { }
910 #endregion <Email Interfaces>
911 #region Logger
912 public interface IGPALLogger : IAllowLoggingSettings, IAllowToGPALObject<IGPALLogger>
913 {
914 // where the last entry was written, which is the logger's answer rather than the workflow's guess
915 string LogDirectory { [Data(Description = "The folder the last entry was written to, with DirectoryStructure applied, e.g. logs/231")] get; }
916 string LogFilename { [Data(Description = "The name of the file the last entry was written to, with FilenamePattern applied, e.g. DeadMikes_20260819.log")] get; }
917 string LogFullPath { [Data(Description = "LogDirectory and LogFilename joined: the file the last entry went into")] get; }
918 }
919 public interface IAllowLoggingSettings : IAllowToGPALObject<IGPALLogger>
920 {
921 [Settings(Description = "Write log entries to this database rather than to a file")]
922 IAllowLoggingSettings WithDatabase(GPALDatabase database);
923 [Settings(Description = "The directory the log files are written under")]
924 IAllowLoggingSettings WithRootDirectory(string path);
925 [Settings(Description = "How the directories under the root are named, by year, month, day and hour in the combination chosen. None writes them all in the root")]
926 IAllowLoggingSettings WithDirectoryStructure(DirectoryStructure type);
927 [Settings(Description = "The name of the log file")]
928 IAllowLoggingSettings WithFilename(string name);
929 [Settings(Description = "How the filename varies from one file to the next, by date and time down to the part chosen. None keeps one file")]
930 IAllowLoggingSettings WithFilenamePattern(FilenamePattern pattern);
931 [Settings(Description = "Which event types this logger writes, published or called directly. Defaults to all")]
932 IAllowLoggingSettings WithLogEventTypes(GPALEventType logEventTypes);
933 [Settings(Description = "The character written between the fields on a line")]
934 IAllowLoggingSettings WithDelimiter(char delimiter);
935 [Settings(Description = "How the date and time are written at the start of each entry")]
936 IAllowLoggingSettings WithLoggingFormat(LogDateFormat logDateFormat);
937 }
938 #endregion Logger
939 #region Excel
940 // Core operations
941 public interface IAllowExcelCore
942 {
943 [Action(Description = "Saves the loaded workbook(s) to the file(s) matching gpalFile's filenames (which may include wildcard patterns), or to _gpalFile if gpalFile is null")]
944 IAllowExcelOperations SaveTo(GPALFile gpalFile);
945 [Action(Description = "Append every row read into this grid. Pass null and GPAL makes one, the same as GetGrid")]
946 IAllowExcelOperations SaveTo(ref IGPALGrid<string> grid);
947 [Action(Description = "Write the range read into the sheet at this 1-based index, creating it if it is missing")]
948 IAllowExcelOperations SaveTo(int sheetIndex);
949 [Action(Description = "Writes the previously read range data into the sheet named sheetName of every loaded workbook, creating the sheet if it does not exist")]
950 IAllowExcelOperations SaveTo(string sheetName);
951 [Action(Description = "Closes every loaded workbook, optionally saving each back to its source path first, and clears all cached state")]
952 void Close(bool saveOnClose);
953 }
954
955 // File selection state
957 {
958 [Settings(Description = "The workbook to read, by name or by a wildcard naming several")]
959 IAllowExcelSheetSelection WithFile(GPALFile gpalFile);
960 [Settings(Description = "Start a workbook of your own at this name, with one sheet and nothing in it. Nothing is written until SaveTo or Close(true)")]
961 IAllowExcelSheetSelection WithNewFile(GPALFile gpalFile);
962 }
963
964 // Sheet selection state
965 public interface IAllowExcelSheetSelection : IAllowExcelCore, IAllowToGPALObject<IGPALExcel>
966 {
967 [Settings(Description = "The sheet to work on, counting from 1, which is the sheet a workbook opens on")]
968 IAllowExcelOperations WithSheet(int sheetIndex);
969 [Settings(Description = "The sheet to work on, by name")]
970 IAllowExcelOperations WithSheet(string sheetName);
971 [Settings(Description = "Add a sheet of this name and work on it. Called once per tab a workbook is to hold")]
972 IAllowExcelOperations WithNewSheet(string sheetName);
973 }
974
975 // Comparison results state
977 {
978 [Data(Description = "Compares each previously read range against grid, recording any cell-level differences for retrieval via GetCompareResults")]
979 IAllowExcelOperations CompareToGrid(IGPALGrid<string> grid);
980 [Data(Description = "Compare each range read against the same range in another workbook, recording the differences")]
981 IAllowExcelOperations CompareToFile(GPALFile gpalFile);
982 [Data(Description = "Compare each range read against the same range on the selected sheet, recording the differences")]
983 IAllowExcelOperations CompareToRange(string range);
984 }
985
986 // General operations state
988 {
989 [Action(Description = "Write a grid into the sheet, at the cell WithCell named or A1. This is how data of your own gets into a workbook")]
990 IAllowExcelOperations InputFrom(IGPALGrid<string> grid);
991 [Settings(Description = "Read the cell range from the selected sheet of every loaded workbook, for the steps that follow")]
992 IAllowExcelOperations WithRange(string range);
993 [Action(Description = "Writes the range data previously read via WithRange (or another data-producing operation) to range on the currently selected sheet of every loaded workbook")]
994 IAllowExcelOperations WriteRange(string range);
995 [Action(Description = "Clears any range data read via WithRange, WithColumn, or WithRowNumber, along with any comparison differences accumulated by the CompareTo* methods")]
996 IAllowExcelOperations ClearRanges();
997 [Settings(Description = "The cell, such as B3, that the cell steps that follow work on")]
998 IAllowExcelCellSettings WithCell(string cell);
999 [Settings(Description = "Sets the value to search for in subsequent ReplaceWith operations")]
1000 IAllowExcelSearchAndReplaceSettings WithSearchValue(string value);
1001 [Settings(Description = "Read every value in the column from the selected sheet")]
1002 IAllowExcelOperations WithColumn(string column);
1003 [Settings(Description = "Read every value in the row from the selected sheet")]
1004 IAllowExcelOperations WithRowNumber(int rowNumber);
1005 [Action(Description = "Sums every numeric value across all previously read range data (non-numeric values are ignored)")]
1006 IAllowExcelOperations CalculateSum(out string result);
1007 [Action(Description = "Counts every non-empty value across all previously read range data")]
1008 IAllowExcelOperations CalculateCount(out string result);
1009 [Data(Description = "The differences the CompareTo steps found, as a grid")]
1010 IAllowExcelOperations GetCompareResults(out IGPALGrid<string> results);
1011 }
1012
1013 // Cell operations state
1015 {
1016 [Settings(Description = "Sets where InsertValue places its value relative to the current cell content: 0 inserts before the existing content, any other value inserts after")]
1017 IAllowExcelCellSettings WithInsertPosition(int position);
1018 [Settings(Description = "Sets the separator that InsertValue places between the inserted value and the cell's existing content")]
1019 IAllowExcelCellSettings WithInsertSeparator(string separator);
1020 [Action(Description = "Insert the value into the cell chosen with WithCell, joined to what is there by the WithInsertSeparator text")]
1021 IAllowExcelOperations InsertValue(string value);
1022 [Action(Description = "Sets the value of the cell selected via WithCell on every loaded workbook, replacing any existing content")]
1023 IAllowExcelOperations SetValue(string value);
1024 [Action(Description = "Appends value to the end of the existing content of the cell selected via WithCell on every loaded workbook")]
1025 IAllowExcelOperations AppendValue(string value);
1026 [Action(Description = "Prepends value to the beginning of the existing content of the cell selected via WithCell on every loaded workbook")]
1027 IAllowExcelOperations PrependValue(string value);
1028 }
1029
1030 // Search and replace settings state
1032 {
1033 [Action(Description = "Replace every cell in the range holding the search value with this one")]
1034 IAllowExcelOperations ReplaceWith(string value);
1035 [Action(Description = "Every cell in the range holding the search value, as a grid of File, Sheet, Cell, Row, Column, with a header row. Empty apart from the header when nothing matched")]
1036 IAllowExcelOperations GetSearchResults(out IGPALGrid<string> results);
1037 }
1038
1039 // Unified interface
1043 #endregion Excel
1044 #region Launcher
1045 // written by Grok
1046 public interface IAllowExecutableSetup : IAllowToGPALObject<Launcher>
1047 {
1048 [Settings(Description = "The executable to run, or a url or document to open with whatever is registered for it")]
1049 IAllowExecutableSetup WithExecutable(string executable);
1050 [Settings(Description = "Add one argument. Called once per argument, so a path with a space in it needs nothing done to it")]
1051 IAllowExecutableSetup WithArgument(string argument);
1052 [Settings(Description = "A name for this launcher, used in the events it publishes")]
1053 IAllowExecutableSetup WithName(string argument);
1054 [Settings(Description = "The directory the process starts in. Set before Launch, because that is when the process is built")]
1055 IAllowExecutableSetup WithWorkingDirectory(string directory);
1056 [Settings(Description = "An environment variable the process starts with. Called once per variable")]
1057 IAllowExecutableSetup WithEnvironmentVariable(string name, string value);
1058 [Settings(Description = "Where each line the process writes to standard output goes")]
1059 IAllowExecutableSetup WithOutputTo(Action<string> outputHandler);
1060 [Settings(Description = "Where each line the process writes to standard error goes")]
1061 IAllowExecutableSetup WithErrorTo(Action<string> errorHandler);
1062 [Action(Description = "Start the process with everything set above it")]
1063 IAllowRunningExecutable Launch();
1064 }
1065
1066 // Post-launch: Running state
1067 public interface IAllowRunningExecutable : IAllowToGPALObject<Launcher>, IAllowWaitingExecutable
1068 {
1069 // what a process is given has to be given before it starts, so the settings live on
1070 // IAllowExecutableSetup rather than here
1071 [Action(Description = "Whether the process is still running")]
1072 bool IsRunning();
1073 [Action(Description = "Wait up to this many milliseconds for the process to end")]
1074 IAllowWaitingExecutable WaitForExit(int milliseconds);
1075 }
1076
1077 // Post-wait/exit: Limited to termination
1079 {
1080 [Action(Description = "Stop the process. What it started keeps running; KillTree is for those")]
1081 void Kill();
1082 [Action(Description = "Stop the process and everything it started, children first so nothing is orphaned")]
1083 void KillTree();
1084 }
1085 #endregion Launcher
1086 #region REST
1087 // generated by grok
1088 public interface IAllowRESTEndpoint
1089 {
1090 [Settings(Description = "Sets the API base URL with download path", Submenu = "Request")]
1091 IAllowRESTEndpointDetails WithAPIBase(string url);
1092 IAllowRESTEndpointDetails WithAPIBase(string url, TimeSpan httpTimeout);
1093 [Action(Description = "Load an OpenAPI description so its endpoints can be called by name")]
1094 IAllowRESTEndpointDetails LoadOpenAPIMap(string yamlOrUrl);
1095 [Action(Description = "Load an OpenAPI description so its endpoints can be called by name")]
1096 IAllowRESTEndpointDetails LoadOpenAPIMap(GPALFile openSpiMapFile);
1097 }
1098
1099 public interface IAllowRESTEndpointDetails : IAllowRESTExecution, IAllowRESTParameters, IAllowToGPALObject<IRESTClient>
1100 {
1101 [Settings(Description = "Sets the endpoint as a string", Submenu = "Request")]
1102 IAllowRESTParametersOrExecution WithEndpoint(string endpoint);
1103 [Settings(Description = "Sets the endpoint from an ApiEndpoint enum", Submenu = "Request")]
1104 IAllowRESTParametersOrExecution WithEndpoint(ApiEndpoint endpoint);
1105 [Settings(Description = "Sets the result name for the next execution", Submenu = "Request")]
1106 IAllowRESTParametersOrExecution WithResultName(string name);
1107 [Settings(Description = "Sets the client name", Submenu = "Request")]
1108 IAllowRESTEndpointDetails WithName(string name);
1109 [Action(Description = "List the endpoints the loaded OpenAPI description offers")]
1110 IAllowRESTEndpointDetails ListOpenAPIEndPoints();
1111 }
1112
1114 {
1115 [Settings(Description = "Sets the URL parameter", Submenu = "Navigation")]
1116 IAllowRESTParametersOrExecution WithUrl(string url);
1117 [Data(Description = "Sets the URL from a result by index", Submenu = "From Result")]
1118 IAllowRESTParametersOrExecution WithUrlFromResult(int resultIndex);
1119 [Data(Description = "Sets the URL from a result by name", Submenu = "From Result")]
1120 IAllowRESTParametersOrExecution WithUrlFromResult(string name);
1121 [Settings(Description = "Sets the tab ID parameter", Submenu = "Navigation")]
1122 IAllowRESTParametersOrExecution WithTabId(int tabId);
1123 [Data(Description = "Sets the tab ID from a result by index", Submenu = "From Result")]
1124 IAllowRESTParametersOrExecution WithTabIdFromResult(int resultIndex);
1125 [Data(Description = "Sets the tab ID from a result by name", Submenu = "From Result")]
1126 IAllowRESTParametersOrExecution WithTabIdFromResult(string name);
1127 [Settings(Description = "Sets the window ID parameter", Submenu = "Navigation")]
1128 IAllowRESTParametersOrExecution WithWindowId(int windowId);
1129 [Data(Description = "Sets the window ID from a result by index", Submenu = "From Result")]
1130 IAllowRESTParametersOrExecution WithWindowIdFromResult(int resultIndex);
1131 [Data(Description = "Sets the window ID from a result by name", Submenu = "From Result")]
1132 IAllowRESTParametersOrExecution WithWindowIdFromResult(string name);
1133 [Settings(Description = "Sets the storage path parameter", Submenu = "Storage")]
1134 IAllowRESTStorageOptions WithStorageType(WebsiteStorageType storageType);
1135 [Settings(Description = "Sets the key parameter", Submenu = "Storage")]
1136 IAllowRESTParametersOrExecution WithKey(string key);
1137 [Data(Description = "Sets the key from a result by index", Submenu = "From Result")]
1138 IAllowRESTParametersOrExecution WithKeyFromResult(int resultIndex);
1139 [Data(Description = "Sets the key from a result by name", Submenu = "From Result")]
1140 IAllowRESTParametersOrExecution WithKeyFromResult(string name);
1141 [Settings(Description = "Sets the CSS parameter", Submenu = "Element")]
1142 IAllowRESTParametersOrExecution WithCss(string css);
1143 [Data(Description = "Sets the CSS from a result by index", Submenu = "From Result")]
1144 IAllowRESTParametersOrExecution WithCssFromResult(int resultIndex);
1145 [Data(Description = "Sets the CSS from a result by name", Submenu = "From Result")]
1146 IAllowRESTParametersOrExecution WithCssFromResult(string name);
1147 [ElementAssitant(Description = "Sets the element parameter")]
1148 IAllowRESTParametersOrExecution WithElement(IGPALElement gPALElement);
1149 [Settings(Description = "Sets the XPath parameter", Submenu = "Element")]
1150 IAllowRESTParametersOrExecution WithXPath(string xpath);
1151 [Data(Description = "Sets the XPath from a result by index", Submenu = "From Result")]
1152 IAllowRESTParametersOrExecution WithXPathFromResult(int resultIndex);
1153 [Data(Description = "Sets the XPath from a result by name", Submenu = "From Result")]
1154 IAllowRESTParametersOrExecution WithXPathFromResult(string name);
1155 [Settings(Description = "Sets the pixels parameter", Submenu = "Drag and Scroll")]
1156 IAllowRESTParametersOrExecution WithPixels(int pixels);
1157 [Data(Description = "Sets the pixels from a result by index", Submenu = "From Result")]
1158 IAllowRESTParametersOrExecution WithPixelsFromResult(int resultIndex);
1159 [Data(Description = "Sets the pixels from a result by name", Submenu = "From Result")]
1160 IAllowRESTParametersOrExecution WithPixelsFromResult(string name);
1161 [Settings(Description = "Sets the referrer parameter", Submenu = "Navigation")]
1162 IAllowRESTParametersOrExecution WithReferrer(string referrer);
1163 [Data(Description = "Sets the referrer from a result by index", Submenu = "From Result")]
1164 IAllowRESTParametersOrExecution WithReferrerFromResult(int resultIndex);
1165 [Data(Description = "Sets the referrer from a result by name", Submenu = "From Result")]
1166 IAllowRESTParametersOrExecution WithReferrerFromResult(string name);
1167 [Settings(Description = "Sets the text parameter", Submenu = "Element")]
1168 IAllowRESTExecution WithText(string text);
1169 [Data(Description = "Sets the text from a result by index", Submenu = "From Result")]
1170 IAllowRESTExecution WithTextFromResult(int resultIndex);
1171 [Data(Description = "Sets the text from a result by name", Submenu = "From Result")]
1172 IAllowRESTExecution WithTextFromResult(string name);
1173 [Action(Description = "Where a file the browser downloads should end up")]
1175 [Action(Description = "Saves the response to a file if the endpoint returns a downloadable content")]
1176 IAllowRESTParametersOrExecution SaveResultsTo(GPALFile file);
1177 [Settings(Description = "Sets the element ID parameter", Submenu = "Element")]
1178 IAllowRESTParametersOrExecution WithElementId(string elementId);
1179 [Data(Description = "Sets the element from a result by index", Submenu = "From Result")]
1180 IAllowRESTParametersOrExecution WithElementIdFromResult(int resultIndex);
1181 [Data(Description = "Sets the element from a result by name", Submenu = "From Result")]
1182 IAllowRESTParametersOrExecution WithElementIdFromResult(string name);
1183 [Action(Description = "Sets the value of the destination element identified by destSelector from the source element identified by the preceding WithCss or WithElementId call")]
1184 IAllowRESTParametersOrExecution SetValueFrom(string destSelector);
1185 [Data(Description = "Sets the horizontal pixels from a result by index", Submenu = "From Result")]
1186 IAllowRESTScrollElement WithHPixelsFromResult(int resultIndex);
1187 [Data(Description = "Sets the horizontal pixels from a result by name", Submenu = "From Result")]
1188 IAllowRESTScrollElement WithHPixelsFromResult(string name);
1189 [Data(Description = "Sets the vertical pixels from a result by index", Submenu = "From Result")]
1190 IAllowRESTScrollElement WithVPixelsFromResult(int resultIndex);
1191 [Data(Description = "Sets the vertical pixels from a result by name", Submenu = "From Result")]
1192 IAllowRESTScrollElement WithVPixelsFromResult(string name);
1193 [Settings(Description = "Sets the CSS parameter", Submenu = "Request")]
1194 IAllowRESTExecution WithDeviceName(string deviceNameOrId);
1195
1196 }
1197 public interface IAllowRESTMethod
1198 {
1199 [Settings(Description = "Sets the HTTP method", Submenu = "Request")]
1200 IAllowRESTExecution WithHttpMethod(string method);
1201 }
1202
1203 public interface IAllowRangeValue
1204 {
1205 [Settings(Description = "Specifies the value for SetRange operation", Submenu = "Element")]
1206 IAllowRESTExecution WithRangeValue(int rangeValue);
1207 }
1209 {
1210 [Fluent(Description = "Executes the request synchronously with type")]
1211 string Execute(bool publishEvent = true);
1212 [Fluent(Description = "Executes the request synchronously with type")]
1213 T Execute<T>(bool publishEvent = true);
1214 [Fluent(Description = "Executes and chains the request with type")]
1215 IRESTClient AndThen(bool publishEvent = true);
1216 [Fluent(Description = "Executes and chains the request with type")]
1217 IRESTClient AndThen<T>(bool publishEvent = true);
1218 [Action(Description = "Executes the request asynchronously with type")]
1219 Task<string> ExecuteAsync(bool publishEvent = true);
1220 [Action(Description = "Executes the request asynchronously with type")]
1221 Task<T> ExecuteAsync<T>(bool publishEvent = true);
1222 [Data(Description = "The results of the calls made so far")]
1223 ResultCollection GetExecutionResults();
1224 [Data(Description = "Every result stored under name, in the order it was stored, so a loop that ran five times answers with five")]
1225 IReadOnlyList<object> GetExecutionResults(string name);
1226 [Action(Description = "Empties what WithResultName has stored, so GetExecutionResults answers about what has happened since rather than everything since the client was made")]
1227 IAllowRESTExecution ClearResults();
1228 IAllowRESTExecution WithHeader(string name, string value);
1229 [Settings(Description = "How long one attempt is given before it is abandoned", Submenu = "Request")]
1230 IAllowRESTExecution WithTimeout(TimeSpan httpTimeout);
1231 }
1232
1234 {
1235 [Settings(Description = "Sets parameters as a variable argument list", Submenu = "Request")]
1236 IAllowRESTParametersOrExecution WithParameters(params object[] parameters);
1237 [Settings(Description = "Sets parameters as a single object", Submenu = "Request")]
1238 IAllowRESTParametersOrExecution WithParameters(object parameters);
1239 [Data(Description = "Sets parameters from a result by index", Submenu = "From Result")]
1240 IAllowRESTParametersOrExecution WithParametersFromResult(int resultIndex);
1241 [Data(Description = "Sets parameters from a result by name", Submenu = "From Result")]
1242 IAllowRESTParametersOrExecution WithParametersFromResult(string name);
1243 [Settings(Description = "Specifiy the encoiding type for posted parameters: json or urlencoded", Submenu = "Request")]
1244 IAllowRESTParametersOrExecution WithEncoding(Enums.ContentEncoding encoding);
1245 }
1246
1247 public interface IAllowRESTWorkflow
1248 {
1249 [Workflow(Description = "Adds a workflow definition")]
1250 IAllowRESTWorkflow WithWorkflow(Action<RESTClient> workflow);
1251 [Workflow(Description = "Gets the execution results")]
1252 IAllowRESTWorkflow ClearWorkflows();
1253 [Workflow(Description = "Executes workflows while condition holds")]
1254 IAllowRESTParametersOrExecution While(Func<bool> condition);
1255 [Workflow(Description = "Executes workflows until condition holds")]
1256 IAllowRESTParametersOrExecution Until(Func<bool> condition);
1257 }
1258
1260 {
1261 [Settings(Description = "Sets the timeout in milliseconds", Submenu = "Network Idle")]
1262 IAllowCheckNetworkIdleOrExecution WithTimeoutMs(int timeoutMs);
1263 [Settings(Description = "Sets the prune interval in milliseconds", Submenu = "Network Idle")]
1264 IAllowCheckNetworkIdleOrExecution WithPruneMs(int pruneMs);
1265 [Settings(Description = "Sets the maximum connections", Submenu = "Network Idle")]
1266 IAllowCheckNetworkIdleOrExecution WithMaxConnections(int maxConnections);
1267 }
1268
1270 {
1271 [Settings(Description = "Sets the horizontal pixels parameter", Submenu = "Drag and Scroll")]
1272 IAllowRESTScrollElement WithHPixels(int hPixels);
1273 [Settings(Description = "Sets the vertical pixels parameter", Submenu = "Drag and Scroll")]
1274 IAllowRESTScrollElement WithVPixels(int vPixels);
1275 }
1276
1278 {
1279 [Settings(Description = "Sets the horizontal drop offset for a drag-and-drop operation", Submenu = "Drag and Scroll")]
1280 IAllowRESTDragAndDrop WithDeltaX(int deltaX);
1281 [Settings(Description = "Sets the vertical drop offset for a drag-and-drop operation", Submenu = "Drag and Scroll")]
1282 IAllowRESTDragAndDrop WithDeltaY(int deltaY);
1283 [Settings(Description = "Sets the horizontal grab offset within the element for a drag-and-drop operation", Submenu = "Drag and Scroll")]
1284 IAllowRESTDragAndDrop WithOffsetX(int offsetX);
1285 [Settings(Description = "Sets the vertical grab offset within the element for a drag-and-drop operation", Submenu = "Drag and Scroll")]
1286 IAllowRESTDragAndDrop WithOffsetY(int offsetY);
1287 }
1288
1290 {
1291 [Data(Description = "Specifies the attribute name for get or set operation")]
1292 IAllowRESTAttribute WithAttribute(string attribute);
1293 [Settings(Description = "Specifies the value for set operation", Submenu = "Element")]
1294 IAllowRESTAttribute WithValue(string value);
1295 }
1296
1297 public interface IAllowRESTInputText
1298 {
1299 [Settings(Description = "Sets the text parameter")]
1300 IAllowRESTExecution WithText(string text);
1301 }
1302
1303 public interface IAllowSelectOptions
1304 {
1305 [Settings(Description = "Set the value to choose from the Select menu", Submenu = "Element")]
1306 IAllowRESTExecution WithSelectValue(string value);
1307 [Settings(Description = "Pick the option at this index", Submenu = "Element")]
1308 IAllowRESTExecution WithSelectIndex(int index);
1309 }
1311 {
1312 [Settings(Description = "The name the download is saved as", Submenu = "Files")]
1313 IAllowRESTExecution WithDownloadFile(string downloadPath);
1314 }
1316 {
1317 [Settings(Description = "Sets the timeout in milliseconds", Submenu = "Files")]
1318 IAllowRESTExecution WithUploadFile(string uploadFilenameAndPath);
1319 [Settings(Description = "Sets the timeout in milliseconds", Submenu = "Files")]
1320 IAllowRESTExecution WithUploadFiles(GPALFile uploadFilenamesAndPaths);
1321 }
1322
1324 {
1325 [Settings(Description = "Records only the calls whose url holds this, so a page that talks to a dozen places narrows to the one worth having", Submenu = "Calls")]
1326 IAllowRESTCaptureOptions WithCallFilter(string urlFragment);
1327 [Settings(Description = "Forgets what was already recorded before starting, so a second capture is not read as the first", Submenu = "Calls")]
1328 IAllowRESTCaptureOptions WithClearCalls(bool clear = true);
1329 }
1330
1332 {
1333 [Browser(Description = "Sets the storage domain parameter")]
1334 IAllowRESTStorageOptions WithStorageDomain(string domain);
1335 [Browser(Description = "Sets the storage path parameter")]
1336 IAllowRESTStorageOptions WithStoragePath(string path);
1337 [Browser(Description = "Sets the storage key parameter")]
1338 IAllowRESTStorageOptions WithStorageKey(string key);
1339 [Browser(Description = "Sets the storage domain parameter")]
1340 IAllowRESTStorageOptions WithStorageStoreName(string storeName);
1341 [Settings(Description = "Sets the set storage data parameter", Submenu = "Request")]
1342 IAllowRESTStorageOptions WithData(string data);
1343 [Settings(Description = "Delete the storage on every origin, not only the current one", Submenu = "Storage")]
1344 IAllowRESTStorageOptions WithDeleteAcrossOrigins(bool trueFalse);
1345 }
1346
1347 public interface IAllowRestMethods
1348 {
1349 // Single-parameter methods with direct Execute
1350 [Browser(Description = "Navigates browser history back", Submenu = "Navigation")]
1351 IAllowRESTExecution Back();
1352 [Action(Description = "Get a screenshot of the current tab visble contents", Submenu = "Page")]
1353 IAllowRESTExecution CaptureVisibleTab(ImageFormat imageFormat = ImageFormat.JPEG);
1354 [Browser(Description = "Closes a tab by URL", Submenu = "Tabs")]
1355 IAllowRESTExecution CloseTab(GPALUrl url = null);
1356 [Browser(Description = "Closes a tab by tab ID", Submenu = "Tabs")]
1357 IAllowRESTExecution CloseTab(int tabId);
1358 [Browser(Description = "Closes a window by URL, optionally switching to the main window", Submenu = "Windows")]
1359 IAllowRESTExecution CloseWindow(GPALUrl url = null);
1360 [Browser(Description = "Closes every window the browser has, which is how it is asked to quit", Submenu = "Windows")]
1361 IAllowRESTExecution CloseBrowser();
1362 [Browser(Description = "Closes a window by window ID, optionally switching to the main window", Submenu = "Windows")]
1363 IAllowRESTExecution CloseWindow(int tabId);
1364 [Action(Description = "Delete the specified storage type", Submenu = "Storage")]
1365 IAllowRESTStorageOptions DeleteStorage(WebsiteStorageType storageType);
1366 [Action(Description = "Executes JavaScript code", Submenu = "Page")]
1367 IAllowRESTParameters ExecuteJavaScript(string script); // Removed params version as noted
1368 [Browser(Description = "Registers a script to run on every new document load", Submenu = "Scripts")]
1369 IAllowRESTParameters InjectScript(string script);
1370 [Browser(Description = "Removes all scripts previously registered via InjectScript", Submenu = "Scripts")]
1371 IAllowRESTParameters ClearInjectedScripts();
1372 [Action(Description = "Appends text to an element", Submenu = "Input")]
1373 IAllowRESTInputText FillInAppend(string elementId);
1374 [Action(Description = "Appends text to an element", Submenu = "Input")]
1375 IAllowRESTInputText FillInInsert(string elementId);
1376 [Action(Description = "Appends text to an element", Submenu = "Input")]
1377 IAllowRESTInputText FillInOverwrite(string elementId);
1378 [Browser(Description = "Navigates browser history forward", Submenu = "Navigation")]
1379 IAllowRESTExecution Forward();
1380 [Browser(Description = "Sets browser to full screen", Submenu = "Windows")]
1381 IAllowRESTExecution FullScreen();
1382 [Data(Description = "Gets the ready status", Submenu = "Page")]
1383 IAllowRESTExecution GetReadyStatus();
1384 [Action(Description = "Checks if network is idle with max connections", Submenu = "Page")]
1385 IAllowRESTExecution CheckNetworkIdle(int maxConnections = 0);
1386 [Data(Description = "Gets the shadow root for a CSS selector", Submenu = "Find Elements")]
1387 IAllowRESTExecution GetShadowRoot(string css);
1388 [Data(Description = "Get the specified storage type", Submenu = "Page")]
1389 IAllowRESTStorageOptions GetStorage(WebsiteStorageType storageType);
1390 [Browser(Description = "Gets the current URL", Submenu = "Navigation")]
1391 IAllowRESTExecution GetCurrentUrl();
1392 [Browser(Description = "Gets the current window's ID and URL", Submenu = "Windows")]
1393 IAllowRESTExecution GetCurrentWindow();
1394 [Data(Description = "Gets the current URL and the document identity in one call", Submenu = "Page")]
1395 IAllowRESTExecution GetDocumentStamp();
1396 [Data(Description = "Gets the page title, the __NEXT_DATA__ payload and any React Flight chunks, read from the document rather than its markup", Submenu = "Page")]
1397 IAllowRESTExecution GetHydrationScripts();
1398 [Data(Description = "Get the options in a Select manue", Submenu = "Element")]
1399 IAllowRESTExecution GetOptions(string elementId);
1400 [Data(Description = "Gets the browser's preferred languages, most preferred first", Submenu = "Page")]
1401 IAllowRESTExecution GetLanguages();
1402 [Action(Description = "Starts or stops recording what the page asks for", Submenu = "Page")]
1403 IAllowRESTCaptureOptions CaptureCalls(bool capture = true);
1404 [Data(Description = "Everything recorded so far, oldest first, as the json the extension keeps", Submenu = "Page")]
1405 IAllowRESTExecution GetCapturedCalls();
1406 [Data(Description = "Gets the user agent", Submenu = "Page")]
1407 IAllowRESTExecution GetUserAgent();
1408 [Browser(Description = "Navigates to a URL", Submenu = "Navigation")]
1409 IAllowRESTExecution GoTo(GPALUrl url);
1410 [Browser(Description = "Navigates to a tab by URL", Submenu = "Tabs")]
1411 IAllowRESTExecution GoToTab(GPALUrl url);
1412 [Browser(Description = "Navigates to a tab by tab ID", Submenu = "Tabs")]
1413 IAllowRESTExecution GoToTab(int tabId);
1414 [Browser(Description = "Switches to a window by URL", Submenu = "Windows")]
1415 IAllowRESTExecution GoToWindow(GPALUrl url);
1416 [Browser(Description = "Switches to a window by window ID", Submenu = "Windows")]
1417 IAllowRESTExecution GoToWindow(int tabId);
1418 [Browser(Description = "Maximizes the browser window", Submenu = "Windows")]
1419 IAllowRESTExecution Maximize();
1420 [Browser(Description = "Minimizes the browser window", Submenu = "Windows")]
1421 IAllowRESTExecution Minimize();
1422 [Action(Description = "Moves to an element", Submenu = "Mouse")]
1423 IAllowRESTExecution MoveTo(string elementId);
1424 [Action(Description = "Opens a new tab with optional URL", Submenu = "Tabs and Windows")]
1425 IAllowRESTExecution NewTab(GPALUrl url = null);
1426 [Browser(Description = "Switches to the next tab", Submenu = "Tabs")]
1427 IAllowRESTExecution NextTab();
1428 [Browser(Description = "How many tabs the browser actually has open, which is not the same as how many GPAL opened", Submenu = "Tabs")]
1429 IAllowRESTExecution TabCount();
1430 [Browser(Description = "Switches to the next window", Submenu = "Windows")]
1431 IAllowRESTExecution NextWindow();
1432 [Browser(Description = "Restores the browser window to normal", Submenu = "Windows")]
1433 IAllowRESTExecution Normal();
1434 [Action(Description = "Opens a new window with the specified URL", Submenu = "Tabs and Windows")]
1435 IAllowRESTExecution OpenWindow(GPALUrl url = null);
1436 [Action(Description = "Overrides the referrer URL", Submenu = "Referrer and User Agent")]
1437 IAllowRESTExecution OverrideReferrer(string referrer);
1438 [Scroll(Description = "Scrolls the page down by pages")]
1439 IAllowRESTExecution PageDown(int pagesToScroll = 1);
1440 [Scroll(Description = "Scrolls to the page end")]
1441 IAllowRESTExecution PageEnd();
1442 [Scroll(Description = "Scrolls to the page top")]
1443 IAllowRESTExecution PageTop();
1444 [Scroll(Description = "Scrolls the page up by pages")]
1445 IAllowRESTExecution PageUp(int pagesToScroll = 1);
1446 [Data(Description = "Press the modifier keys specified", Submenu = "Keyboard")]
1447 IAllowRESTExecution PressModifierKey(ModifierKeys modifierKeys);
1448 [Browser(Description = "Switches to the previous tab", Submenu = "Tabs")]
1449 IAllowRESTExecution PreviousTab();
1450 [Browser(Description = "Switches to the next window", Submenu = "Windows")]
1451 IAllowRESTExecution PreviousWindow();
1452 [Browser(Description = "Refreshes the current page", Submenu = "Navigation")]
1453 IAllowRESTExecution Refresh();
1454 [Data(Description = "Press the modifier keys specified", Submenu = "Keyboard")]
1455 IAllowRESTExecution ReleaseModifierKey(ModifierKeys modifierKeys);
1456 [Browser(Description = "Restores the browser window", Submenu = "Windows")]
1457 IAllowRESTExecution Restore();
1458 [Scroll(Description = "Scrolls the window horizontally by pixels")]
1459 IAllowRESTExecution ScrollWindowByHorizontal(int pixels);
1460 [Scroll(Description = "Scrolls the window vertically by pixels")]
1461 IAllowRESTExecution ScrollWindowByVertical(int pixels);
1467 IAllowRESTExecution SendString(string text, int delayMs = 0);
1468 [Data(Description = "Sends a key", Submenu = "Keyboard")]
1469 IAllowRESTExecution SendKey(byte vkcode);
1470 [Data(Description = "Starts setting an attribute of an element by ID", Submenu = "Keyboard")]
1471 IAllowRangeValue SetRange(string elementId);
1472 [Action(Description = "Set data for the specified storage type", Submenu = "Storage")]
1473 IAllowRESTStorageOptions SetStorage(WebsiteStorageType storageType);
1474 [Action(Description = "Overrides the browser's user agent string", Submenu = "Referrer and User Agent")]
1475 IAllowRESTExecution SetUserAgent(string userAgent);
1476 [Action(Description = "Overrides referrer stealthily - sets to google.com", Submenu = "Referrer and User Agent")]
1477 IAllowRESTExecution SetGoogleReferrer();
1478 [Browser(Description = "Switches to default content", Submenu = "Frames")]
1479 IAllowRESTExecution SwitchToDefaultContent();
1480 [Browser(Description = "Switches to an element to search for selectors contained", Submenu = "Frames")]
1481 IAllowRESTExecution SwitchToElement(string elementId); // same as switch to iframe
1482 [Browser(Description = "Switches to a frame", Submenu = "Frames")]
1483 IAllowRESTExecution SwitchToFrame(string elementId); // same as switch to element
1484 [Browser(Description = "Switches to a shadow root", Submenu = "Frames")]
1485 IAllowRESTExecution SwitchToShadowRoot(string elementId);
1486 [Data(Description = "Gets the workflow", Submenu = "Recorder")]
1487 IAllowRESTExecution GetWorkflow();
1488 [Data(Description = "Gets settings", Submenu = "Recorder")]
1489 IAllowRESTExecution GetSettings();
1490 [Data(Description = "Gets GPAL settings", Submenu = "Recorder")]
1491 IAllowRESTExecution GetGpalSettings();
1492 [Data(Description = "Gets browser settings", Submenu = "Recorder")]
1493 IAllowRESTExecution GetBrowserSettings();
1494 [Action(Description = "Fires a change event on an element by ID", Submenu = "Input")]
1495 IAllowRESTExecution FireChangeEvent(string elementId);
1496 [Action(Description = "Focuses an element by ID", Submenu = "Mouse")]
1497 IAllowRESTExecution Focus(string elementId);
1498 [Data(Description = "Gets the bounding client rect of an element by ID", Submenu = "Element")]
1499 IAllowRESTExecution GetBoundingClientRect(string elementId);
1500 IAllowRESTExecution ElementFromPoint(string elementId, int x, int y);
1501 IAllowRESTExecution TrustedLeftClick(int x, int y, int holdMs = 0);
1502 IAllowRESTExecution TrustedMiddleClick(int x, int y, int holdMs = 0);
1503 [Data(Description = "Gets the attribute hash of an element", Submenu = "Element")]
1504 IAllowRESTExecution GetElementAttributeHash(string elementId);
1505 [Action(Description = "The HTML of the page", Submenu = "Page")]
1506 IAllowRESTExecution GetPageSource();
1507 [Data(Description = "Gets the parent node of an element by ID", Submenu = "Find Elements")]
1508 IAllowRESTExecution GetParentNode(string elementId);
1509 [Data(Description = "The content and styles of the element", Submenu = "Element")]
1510 IAllowRESTExecution GetContentAndCss(string selector);
1511 [Data(Description = "The computed styles of the element", Submenu = "Element")]
1512 IAllowRESTExecution GetCssAttributes(string selector);
1513 [Data(Description = "The attributes of the element", Submenu = "Element")]
1514 IAllowRESTExecution GetDomAttributes(string selector);
1515 [Data(Description = "The DOM properties of the element", Submenu = "Element")]
1516 IAllowRESTExecution GetDomProperties(string selector);
1517 [Browser(Description = "The position and size of the browser window", Submenu = "Windows")]
1518 IAllowRESTExecution GetWindowRectangle();
1519 [Action(Description = "Hides an element by ID", Submenu = "Input")]
1520 IAllowRESTExecution HideElement(string elementId);
1521 [Data(Description = "Checks if an element is clickable by ID", Submenu = "Element")]
1522 IAllowRESTExecution IsClickable(string elementId);
1523 [Data(Description = "Checks if an element is displayed by ID", Submenu = "Element")]
1524 IAllowRESTExecution IsDisplayed(string elementId);
1525 [Data(Description = "Checks if an element is enabled by ID", Submenu = "Element")]
1526 IAllowRESTExecution IsEnabled(string elementId);
1527 [Scroll(Description = "Checks if the page is at the end")]
1528 IAllowRESTExecution IsEndOfPage();
1529 [Data(Description = "Checks if an element is visible in viewport by ID", Submenu = "Element")]
1530 IAllowRESTExecution IsVisibleInViewport(string elementId);
1531 [Action(Description = "Performs a left click on an element by ID", Submenu = "Clicks")]
1532 IAllowRESTExecution LeftClick(string elementId);
1533 [Action(Description = "Performs a left click and download on an element", Submenu = "Files")]
1534 IAllowRESTWithDownloadFilename LeftClickAndDownload(string elementId);
1535 [Action(Description = "The name the next download is saved as", Submenu = "Files")]
1536 IAllowRESTExecution SetDownloadFilename(string downloadPath);
1537 [Action(Description = "Purely headless mode, attaches the file to the input[type=file]", Submenu = "Files")]
1538 IAllowRESTWithUploadFilename LeftClickAndUpload(string elementId);
1539 [Action(Description = "Performs a left double click on an element by ID", Submenu = "Clicks")]
1540 IAllowRESTExecution LeftDoubleClick(string elementId);
1541 [Action(Description = "Performs a left click on an element by ID", Submenu = "Clicks")]
1542 IAllowRESTExecution MiddleClick(string elementId);
1543 [Action(Description = "Performs a right click on an element by ID", Submenu = "Clicks")]
1544 IAllowRESTExecution RightClick(string elementId);
1545 [Scroll(Description = "Scrolls an element into view by ID")]
1546 IAllowRESTExecution ScrollIntoView(string elementId);
1547 [Data(Description = "Gets the window inner height", Submenu = "Window")]
1548 IAllowRESTExecution WindowInnerHeight();
1549 [Data(Description = "Gets the window inner width", Submenu = "Window")]
1550 IAllowRESTExecution WindowInnerWidth();
1551 [Data(Description = "Gets the window outer height", Submenu = "Window")]
1552 IAllowRESTExecution WindowOuterHeight();
1553 [Data(Description = "Gets the window outer width", Submenu = "Window")]
1554 IAllowRESTExecution WindowOuterWidth();
1555 [Fluent(Description = "Send an API request from inside the page, carrying the browser's cookies, TLS fingerprint and headers")]
1556 IAllowRESTParametersOrExecution Fetch(string url);
1557 [Settings(Description = "Sets the verb of the request being fetched", Submenu = "Request")]
1558 IAllowRESTParametersOrExecution WithVerb(string method);
1559 [Settings(Description = "Sets the body of the request being fetched", Submenu = "Request")]
1560 IAllowRESTParametersOrExecution WithBody(string body);
1561 [Settings(Description = "Sets the content type of the body of the request being fetched", Submenu = "Request")]
1562 IAllowRESTParametersOrExecution WithContentType(string contentType);
1563 [Settings(Description = "Sets extra headers for the request being fetched, flattened to name, value, name, value", Submenu = "Request")]
1564 IAllowRESTParametersOrExecution WithHeaders(string[] headers);
1565 [Settings(Description = "True to bring the fetched response body back base64 encoded, which is what a file needs", Submenu = "Request")]
1566 IAllowRESTParametersOrExecution WithBytes(bool bytes);
1567 [Data(Description = "Gets the window page offset X", Submenu = "Window")]
1568 IAllowRESTExecution WindowPageOffsetX();
1569 [Data(Description = "Gets the window page offset Y", Submenu = "Window")]
1570 IAllowRESTExecution WindowPageOffsetY();
1571 [Data(Description = "Gets the window screen left position", Submenu = "Window")]
1572 IAllowRESTExecution WindowScreenLeft();
1573 [Data(Description = "Gets the window screen top position", Submenu = "Window")]
1574 IAllowRESTExecution WindowScreenTop();
1575 [Action(Description = "Hovers over an element by ID", Submenu = "Mouse")]
1576 IAllowRESTExecution Hover(string elementId);
1577 [Data(Description = "Evaluates an XPath expression", Submenu = "Find Elements")]
1578 IAllowRESTExecution EvaluatePersistent(string xpath);
1579 [Data(Description = "Evaluates an XPath expression for multiple elements", Submenu = "Find Elements")]
1580 IAllowRESTExecution EvaluateAllPersistent(string xpath);
1581 [Data(Description = "Queries a single element using a CSS selector", Submenu = "Find Elements")]
1582 IAllowRESTExecution QueryPersistentSelector(string css);
1583 [Data(Description = "Queries multiple elements using a CSS selector", Submenu = "Find Elements")]
1584 IAllowRESTExecution QueryPersistentSelectors(string css);
1585 [Data(Description = "Evaluates an XPath expression", Submenu = "Find Elements")]
1586 IAllowRESTExecution Evaluate(string xpath);
1587 [Data(Description = "Evaluates an XPath expression for multiple elements", Submenu = "Find Elements")]
1588 IAllowRESTExecution EvaluateAll(string xpath);
1589 [Data(Description = "Queries a single element using a CSS selector", Submenu = "Find Elements")]
1590 IAllowRESTExecution QuerySelector(string css);
1591 [Data(Description = "Queries multiple elements using a CSS selector", Submenu = "Find Elements")]
1592 IAllowRESTExecution QuerySelectors(string css);
1593 IAllowRESTExecution ScrollWindow(int hPixels, int vPixels);
1594 [Browser(Description = "Top the browser, bring it into focus", Submenu = "Windows")]
1595 IAllowRESTExecution TopBrowser();
1596 [Action(Description = "Clears the referrer", Submenu = "Referrer and User Agent")]
1597 IAllowRESTExecution ClearReferrer();
1598
1599
1600 // Multi-parameter methods with fluent steps
1601 [Action(Description = "Click a Select menu option", Submenu = "Clicks")]
1602 IAllowSelectOptions SelectClick(string elementId);
1603 [Action(Description = "Starts setting an attribute of an element by ID", Submenu = "Input")]
1604 IAllowRESTAttribute SetAttribute(string elementId);
1605 [Scroll(Description = "Starts scrolling an element by ID")]
1606 IAllowRESTScrollElement ScrollElement(string elementId);
1607 IAllowRESTExecution ScrollElement(int hPixels, int vPixels);
1608 [Action(Description = "Drags an element from its current position by the given offset and drops it", Submenu = "Mouse")]
1609 IAllowRESTDragAndDrop DragAndDrop(string elementId);
1610 [Data(Description = "Starts getting an attribute of an element by ID", Submenu = "Element")]
1611 IAllowRESTAttribute GetAttribute(string elementId); // Returns IAllowRESTAttribute, skips WithValue
1612 }
1613
1617 {
1618 string Name { [Data(Description = "Gets or sets the client name")] get; }
1619
1621 int StatusCode { [Data(Description = "The HTTP status code the last call came back with")] get; }
1622
1624 int RetryAfterSeconds { [Data(Description = "The seconds the last call was asked to wait before asking again, zero when it was not asked")] get; }
1625 }
1626 #endregion REST
1627 #region GPALElement
1628 public interface IGPALElement
1629 {
1630 // Complete element contract. These were previously reached only by inheriting Selenium's
1631 // IWebElement, which leaked a Selenium reference onto every consumer. GPALElement implements
1632 // all of them natively, and every signature uses GPAL/BCL types only, never a Selenium type.
1633 // Consumers program against IGPALElement and cast to GPALElement only for the plumbing
1634 // (WrappedDriver, WebElement, node ids, ToDictionary, Dispose).
1635 string TagName { get; }
1636 string Text { get; }
1637 bool Enabled { get; }
1638 bool Selected { get; }
1639 bool? Checked { get; }
1640 bool Displayed { get; }
1641 Point Location { get; }
1642 Size Size { get; }
1643 string GetAttribute(string attributeName);
1644 void SetAttribute(string attributeName, string value);
1645 string GetCssValue(string propertyName);
1646 string GetDomAttribute(string attributeName);
1647 string GetDomProperty(string propertyName);
1648 void Click();
1649 void Click(ModifierKeys modifierKeys);
1650 void MiddleClick(ModifierKeys modifierKeys = ModifierKeys.NONE);
1651 void Clear();
1652 void SendKeys(string text);
1653 void Submit();
1654 void Hide();
1655 Dictionary<string, object> Attributes { get; }
1656 Dictionary<string, object> CssAttributes { get; }
1657 Dictionary<string, object> DomAttributes { get; }
1658 Dictionary<string, object> DomProperties{ get; }
1659 string AttributeName { get; }
1660 string Href { get; }
1661 string Src { get; }
1662 string Value { get; }
1663 string Placeholder { get; }
1664 string Xpath { get; }
1665 XPathInfo[] Xpaths { get; }
1666 string Css { get; }
1667 string FullXPath { get; }
1668 //string SelectorName { get; set; }
1669 //int OffsetX { get; set; }
1670 //int OffsetY { get; set; }
1671 //int DeltaX { get; set; }
1672 //int DeltaY { get; set; }
1673 //string ImageData { get; set; }
1674 ClientRectangle BoundingRect { get; }
1675 string PageURL { get; }
1676 GPALElement ShadowRoot { get; }
1677 dynamic WebElement { get; }
1678 bool IsClickable(bool publishEvent = true);
1679 bool IsDisabled();
1680 bool IsEnabled();
1681
1682 }
1683 #endregion GPALElement
1684 #region Cryptography
1685 public interface IAllowCryptoGenerateIV
1686 {
1687 [Action(Description = "Generate a random initialization vector")]
1688 IAllowCryptoConfig GenerateIV(out byte[] iv);
1689 }
1690
1691 public interface IAllowCryptoInput
1692 {
1693 [Settings(Description = "The data to work on")]
1694 IAllowCryptoAction WithInputData(byte[] data);
1695 }
1696
1697 public interface IAllowCryptoEncrypt
1698 {
1699 [Action(Description = "Encrypt the data")]
1700 IAllowCryptoConfig Encrypt(out byte[] encryptedData);
1701 }
1702
1703 public interface IAllowCryptoDecrypt
1704 {
1705 [Action(Description = "Decrypt the data")]
1706 IAllowCryptoConfig Decrypt(out string decryptedValue);
1707 }
1708
1709 public interface IAllowCryptoSign
1710 {
1711 [Action(Description = "Sign the data")]
1712 IAllowCryptoConfig Sign(out byte[] signature);
1713 }
1714
1715 public interface IAllowCryptoVerify
1716 {
1717 [Action(Description = "Check the signature against the data")]
1718 IAllowCryptoConfig Verify(out bool isValid);
1719 }
1720
1721 public interface IAllowCryptoHash
1722 {
1723 [Action(Description = "Hash the data")]
1724 IAllowCryptoConfig Hash(out byte[] hash);
1725 }
1726
1728 {
1729 [Action(Description = "Generate a random key")]
1730 IAllowCryptoConfig GenerateKey(out byte[] key);
1731 }
1732
1733 public interface IAllowCryptoConfig :
1738 {
1739 [Settings(Description = "The algorithm to use")]
1740 IAllowCryptoConfig WithAlgorithm(CryptoAlgorithm alg);
1741 [Settings(Description = "The key to use")]
1742 IAllowCryptoConfig WithKey(byte[] key);
1743 [Settings(Description = "The initialization vector to use")]
1744 IAllowCryptoConfig WithIV(byte[] iv);
1745 [Settings(Description = "The cipher mode")]
1746 IAllowCryptoConfig WithMode(CryptoMode mode);
1747 [Settings(Description = "The padding mode")]
1748 IAllowCryptoConfig WithPadding(CryptoPadding padding);
1749 [Settings(Description = "The salt for deriving a key from a password")]
1750 IAllowCryptoConfig WithSalt(byte[] salt);
1751 [Settings(Description = "How many rounds of key derivation")]
1752 IAllowCryptoConfig WithIterationCount(int count);
1753 [Settings(Description = "The signature to verify")]
1754 IAllowCryptoConfig WithSignature(byte[] signature);
1755 }
1756
1757 public interface IAllowCryptoKeyGenInput :
1760 {
1761 }
1762
1773
1774 public interface ICryptography : IAllowCryptoAction, IAllowCryptoKeyGenInput, IAllowCryptoConfig, IAllowToGPALObject<ICryptography>
1775 {
1776 }
1777 #endregion Cryptography
1778 #region Gherkin
1779 public interface IAllowGiven
1780 {
1781 [Action(Description = "Runs the 'Given' precondition step immediately")]
1782 IAllowWhen Given(Action step);
1783 IAllowWhen Given<T1>(Action<T1> step, T1 arg1);
1784 IAllowWhen Given<T1, T2>(Action<T1, T2> step, T1 arg1, T2 arg2);
1785 IAllowWhen Given<T1, T2, T3>(Action<T1, T2, T3> step, T1 arg1, T2 arg2, T3 arg3);
1786 }
1787
1788 public interface IAllowWhen
1789 {
1790 [Fluent(Description = "Runs the 'When' action step immediately")]
1791 IAllowAnd When(Action step);
1792 IAllowAnd When<T1>(Action<T1> step, T1 arg1);
1793 IAllowAnd When<T1, T2>(Action<T1, T2> step, T1 arg1, T2 arg2);
1794 IAllowAnd When<T1, T2, T3>(Action<T1, T2, T3> step, T1 arg1, T2 arg2, T3 arg3);
1795 }
1796
1797 public interface IAllowAnd
1798 {
1799 [Fluent(Description = "Runs an additional 'And' step immediately")]
1800 IAllowThen And(Action step);
1801 IAllowThen And<T1>(Action<T1> step, T1 arg1);
1802 IAllowThen And<T1, T2>(Action<T1, T2> step, T1 arg1, T2 arg2);
1803 IAllowThen And<T1, T2, T3>(Action<T1, T2, T3> step, T1 arg1, T2 arg2, T3 arg3);
1804 }
1805
1806 public interface IAllowThen : IAllowAnd
1807 {
1808 [Fluent(Description = "Runs the 'Then' assertion/outcome step immediately")]
1809 IAllowThen Then(Action step);
1810 IAllowThen Then<T1>(Action<T1> step, T1 arg1);
1811 IAllowThen Then<T1, T2>(Action<T1, T2> step, T1 arg1, T2 arg2);
1812 IAllowThen Then<T1, T2, T3>(Action<T1, T2, T3> step, T1 arg1, T2 arg2, T3 arg3);
1813 }
1814 #endregion Gherkin
1815 #region <Request Settings>
1816 [Interface(Description = "Describe an API request for .Fetch to issue from inside the page")]
1817 public interface IAllowRequestSettings : IAllowToGPALObject<GPALRequest>
1818 {
1819 [Settings(Description = "Replace a query parameter's value with the next numbered token")]
1820 IAllowRequestSettings WithTokenFor(string parameterName);
1821 [Settings(Description = "Path or full URL to request. A path rides the origin the browser is already on")]
1822 IAllowRequestSettings WithPath(string path);
1823 [Settings(Description = "HTTP method, for example GET, POST, PUT, DELETE. [GET (default)]")]
1824 IAllowRequestSettings WithHttpMethod(Enums.HttpVerb method);
1825 [Settings(Description = "Add a query parameter written as \"name=value\". Call once per parameter")]
1826 IAllowRequestSettings WithParameter(string nameValue);
1827 [Settings(Description = "Add a request header written as \"Name: value\". Call once per header")]
1828 IAllowRequestSettings WithHeader(string nameValue);
1829 [Settings(Description = "Body to send, used as-is")]
1830 IAllowRequestSettings WithBody(string body);
1831 [Settings(Description = "Content type of the body. [application/json (default)]")]
1832 IAllowRequestSettings WithContentType(Enums.ContentType contentType);
1833 [Settings(Description = "What this API calls its first page, which the page token counts on from. [0 (default)]")]
1834 IAllowRequestSettings WithFirstPage(int firstPage);
1835 [Settings(Description = "The marker replaced with the page number, wherever it appears in the path, a parameter value, a header value or the body. Give it a numbered token to hand GPAL one of the token positions. [{page} (default)]")]
1836 IAllowRequestSettings WithPageToken(string token = "{page}");
1837 [Settings(Description = "Handler called after each row of tokens is fetched, with that row's pages. Return -1 to stop")]
1838 IAllowRequestSettings CallAfterFetch(Browser.Browser.CallAfterFetchDelegate callAfterFetch);
1839 [Settings(Description = "Name of request (used in messages and errors)")]
1840 IAllowToGPALObject<GPALRequest> WithName(string name);
1841 }
1842 #endregion <Request Settings>
1843 public interface IAllowToGPALObject<TResult>
1844 {
1845 [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() ]")]
1846 TResult ToGPALObject();
1847 }
1848
1849 #region YouTube
1850 public interface IGPALYouTube
1851 {
1852 // Upload phase
1853 [Settings(Description = "The Google account to upload as")]
1854 IGPALYouTube WithCredentials(ICredentials credentials);
1855 [Settings(Description = "The title of the video")]
1856 IGPALYouTube WithTitle(string title);
1857 [Settings(Description = "The description of the video")]
1858 IGPALYouTube WithDescription(string description);
1859 [Settings(Description = "The tags for the video")]
1860 IGPALYouTube WithTags(params string[] tags);
1861 [Settings(Description = "Public, unlisted or private")]
1862 IGPALYouTube WithPrivacy(Enums.YouTubePrivacy privacy);
1863 [Settings(Description = "The YouTube category for the video")]
1864 IGPALYouTube WithCategory(Enums.YouTubeCategory category);
1865 [Action(Description = "Upload the video file with the title, description and settings given")]
1867 // Schedule phase: collect upload results, set poll interval, then ScheduleAt fires a background thread
1868 [Settings(Description = "The uploaded video the next steps work on")]
1869 IGPALYouTube WithVideo(Browser.YouTubeUploadResult result);
1870 [Settings(Description = "The uploaded videos the next steps work on")]
1871 IGPALYouTube WithVideos(IEnumerable<Browser.YouTubeUploadResult> results);
1872 [Wait(Description = "Wait for YouTube to finish processing, checking every so many seconds")]
1873 IGPALYouTube WaitForProcessing(int pollIntervalSeconds = 60);
1874 [Settings(Description = "Pipes scheduling status to a TextBox or RichTextBox on a WinForms form")]
1875 IGPALYouTube WithOutputTo(System.Windows.Forms.TextBoxBase control);
1876 [Action(Description = "Starts a background thread that polls each video's processing status and schedules a premiere as each one completes")]
1877 IGPALYouTube ScheduleAt(Browser.PremiereTime premiereTime);
1878 [Wait(Description = "Blocks the calling thread until ScheduleAt finishes scheduling all videos")]
1879 void WaitForCompletion();
1880 // Playlist phase
1881 [Settings(Description = "The playlist the next steps work on")]
1882 IGPALYouTube WithPlaylist(string playlistId);
1883 [Action(Description = "Create the playlist")]
1884 Browser.YouTubePlaylistResult CreatePlaylist();
1885 [Action(Description = "Add the videos to the playlist")]
1886 IGPALYouTube AddToPlaylist(string playlistId);
1887 // Lookup / Search phase
1888 [Settings(Description = "The id of an existing video to work on")]
1889 IGPALYouTube WithVideoId(string videoId);
1890 [Settings(Description = "What to search YouTube for")]
1891 IGPALYouTube WithSearchTerms(string query);
1892 [Settings(Description = "What to search YouTube for")]
1893 IGPALYouTube WithSearchTerms(IGPALGrid<string> grid);
1894 [Data(Description = "The videos the search found")]
1895 IGPALYouTube GetResults(out Browser.YouTubeVideoInfo info);
1896 [Data(Description = "The videos the search found")]
1897 IGPALYouTube GetResults(out System.Collections.Generic.List<Browser.YouTubeVideoInfo> results);
1898 // Channel management phase
1899 [Data(Description = "Every video on your channel, with its privacy, category and thumbnail")]
1900 IGPALYouTube GetMyVideos(out System.Collections.Generic.List<Browser.YouTubeVideoInfo> videos);
1901 [Data(Description = "Every playlist on your channel")]
1902 IGPALYouTube GetMyPlaylists(out System.Collections.Generic.List<Browser.YouTubePlaylistInfo> playlists);
1903 [Data(Description = "Every entry in the playlist, in playlist order")]
1904 IGPALYouTube GetPlaylistItems(out System.Collections.Generic.List<Browser.YouTubePlaylistItem> items);
1905 [Settings(Description = "The place in the playlist, counted from 0, that the videos are added at. [the end (default)]")]
1906 IGPALYouTube WithPosition(int position);
1907 [Action(Description = "Take the videos out of the playlist")]
1908 IGPALYouTube RemoveFromPlaylist();
1909 [Action(Description = "Change the video's title, description, tags, category or privacy, keeping whatever is not given")]
1910 IGPALYouTube UpdateVideo();
1911 [Action(Description = "Set the image as the video's thumbnail")]
1912 IGPALYouTube SetThumbnail(GPALFile image);
1913 [Action(Description = "Delete the video from YouTube")]
1914 IGPALYouTube DeleteVideo();
1915 [Action(Description = "Upload a new file in place of the video, keeping its details, thumbnail and playlist places")]
1916 Browser.YouTubeUploadResult ReplaceVideo(GPALFile newVideo);
1917 }
1918 #endregion YouTube
1919
1920}
Application object that contains the fluent methods to create your Application workflow....
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...
Browser object that contains the fluent methods to create your Browser workflow. Instatiated using G...
Definition Browser.cs:68
delegate CallIfStatus CallOnFailDelegate(IBrowser browser, GPALFailure failure, string detail)
Delegate for the CallOnFail handler, invoked when something fails that the workflow,...
delegate CallIfStatus CallAfterFetchDelegate(IBrowser browser, List< string > results, IGPALGrid< string > tokens, int tokenIdx)
Delegate callback for the CallAfterFetch handler declared on a GPALRequest, invoked after each row of...
delegate CallIfStatus CallIfDelegate(IBrowser browser, List< IGPALElement > foundElements, List< IGPALElement > matchedElements, Selector selector, bool matchedAll)
Delegate callback for the CallIfFound/CallIfNotFound EventHandlers which will be invoked when a selec...
Represents a URL with optional pre-navigation storage cleanup / inspection actions....
Definition GPALUrl.cs:53
A playlist on the authenticated channel, returned by GPALYouTube.GetMyPlaylists.
Definition YouTube.cs:118
One entry in a playlist, returned by GPALYouTube.GetPlaylistItems. PlaylistItemId names the entry,...
Definition YouTube.cs:141
Result returned by GPALYouTube.CreatePlaylist containing the playlist ID and public URL.
Definition YouTube.cs:68
Result returned by GPALYouTube.Upload containing the assigned video ID, public URL,...
Definition YouTube.cs:161
Video metadata returned by GPALYouTube.GetResults and GPALYouTube.GetMyVideos. Tags,...
Definition YouTube.cs:84
Represents a client-side bounding rectangle (similar to DOMRect) with additional convenience properti...
Class to define database usage. Currently only used for input from a table, sql or stored procedure....
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
Form object that contains the fluent methods to create interactive forms. Instatiated using GPAL....
Definition GPALForm.cs:64
A GPAL single line input instantiated with GPAL.Input for use on GPAL forms. Callback EventHandler i...
A status bar (usually docked at the bottom of the form) that displays real-time messages,...
A GPAL multiline textare instantiated with GPAL.TextArea for use on GPAL forms. Callback EventHandle...
Everything starts here, all the GPAL controls and global settings using fluent syntax are here....
Definition GPAL.cs:49
What went wrong on the last call, and enough about it to act on. Sent says whether the mail went....
Definition GPALMail.cs:199
Deserialized contents of a Google Cloud service account JSON key file, used by GoogleHandler....
Fluent REST client for making API calls with a chained interface. Supports defining workflows,...
Definition RESTClient.cs:56
GPAL Selector used to locate Application and Browser elements. Instantiated with GPAL....
Definition Selector.cs:56
delegate CallIfStatus webMatchingFunction(List< IGPALElement > foundElements, out List< IGPALElement > matchedElements, out bool matchedAll, Selector selector, bool ExactMatch=true)
Custom matching function, must return all matched elements and an indicator as to whether all element...
delegate CallIfStatus appMatchingFunction(List< GPALAutomationElement > foundElements, out List< GPALAutomationElement > matchedElements, out bool matchedAll, Selector selector, bool ExactMatch=true)
Custom matching function, must return all matched elements and an indicator as to whether all element...
Represents XPath matching information returned by advanced selector strategies.
IAllowAIOutput WithLiveInputFrom(GPALForm.GPALTextArea textArea, int debounceMilliseconds=500)
Like WithInputFrom(object), but also wires the control's TextChanged event (debounced) to call Execut...
IAllowAIOutput WithLiveInputFrom(GPALForm.GPALInput input, int debounceMilliseconds=500)
Like WithInputFrom(object), but also wires the control's TextChanged event (debounced) to call Execut...
The ways a credential can identify itself, which is everything WithService leads to.
IAllowParametersAndActions Execute(out List< int > rowCountsPerStatement)
Per-statement breakdown (via SqlCommand.StatementCompleted) instead of the single aggregate count.
SaveTo(...) already ran the read (an out parameter forces that), so chaining .Execute() afterward wou...
IAllowDatabaseSettings GetRowCount(out List< int > rowCountsPerTable)
Only SaveTo(out IGPALGrid<string>) returns this - meaningless for SaveTo(DataTable)/SaveTo(DataSet),...
What a database is, not what to do with it: the connection, the command, and the definitions of the p...
IAllowRESTExecution SendString(string text, int delayMs=0)
Simulates typing in OttoMagic: dispatches key events character-by-character. Honors GPAL....
int StatusCode
The HTTP status code the last call came back with.
int RetryAfterSeconds
The seconds the last call was asked to wait before asking again, zero when it was not asked.
Represents a premiere schedule time. Presets (In5Minutes, In1Hour, etc.) store a relative offset and ...
Definition YouTube.cs:37