Browser Automation

Left Click and Upload: Attaching Files to a File Input

Complete Program

Here's the whole workflow, start to finish. Each piece is broken down and explained below.

using GenerallyPositive;

using GenerallyPositive.Browser;

using static GenerallyPositive.Enums;


GPAL

.WithPublishToConsole()

.WithDriverLocation("c:\drivers\");


IBrowser browser = GPAL.Browser

.WithBrowserType(BrowserType.Chrome)

.WithAutomationEngine(AutomationEngine.OttoMagic)

.WithUseStealth(StealthType.PatchDriver | StealthType.DarkMode | StealthType.CDP)

.WithLoadImages(true)

.ToGPALObject();


browser

.GoTo("https://example.com/file-upload")

.WithSelector((Selector)"#fileupload > div > div.col-lg-7 > span.btn.btn-success.fileinput-button > input[type=file]")

.WaitFor(5_000);


GPALFile uploadFiles = GPAL.File

.WithFileName("C:\temp\photo1.jpg")

.WithFileName("C:\temp\photo2.jpg")

.ToGPALObject();


browser

.LeftClickAndUpload(uploadFiles)

.LeftClick("#fileupload > div > div.col-lg-7 > button.btn.btn-primary.start > span")

.WaitFor(10_000);


browser.Close(true);

Configure GPAL and Launch the Browser

WithDriverLocation tells GPAL where to find browser drivers. The browser itself is launched with stealth options on (patched chromedriver, dark mode, CDP leak handling) and images enabled, since the upload widget needs to render correctly.

GPAL

.WithPublishToConsole()

.WithDriverLocation("c:\drivers\");


IBrowser browser = GPAL.Browser

.WithBrowserType(BrowserType.Chrome)

.WithAutomationEngine(AutomationEngine.OttoMagic)

.WithUseStealth(StealthType.PatchDriver | StealthType.DarkMode | StealthType.CDP)

.WithLoadImages(true)

.ToGPALObject();

NOTE

The real test program loops over every AutomationEngine value, skipping only Firefox with the Puppeteer engines, since Puppeteer drives Chromium only. For a single workflow, just pick the engine you want - the rest of the chain doesn't change. See Automation Engines.

Navigate and Target the File Input

GoTo loads the page, WithSelector points at the hidden file input element the page uses for its upload button, and WaitFor gives the page up to 5 seconds to finish rendering before GPAL tries to interact with it.

browser

.GoTo("https://example.com/file-upload")

.WithSelector((Selector)"#fileupload > div > div.col-lg-7 > span.btn.btn-success.fileinput-button > input[type=file]")

.WaitFor(5_000);

Build a GPALFile and Upload It

GPAL.File.WithFileName lets you stack up multiple file paths into one GPALFile object. LeftClickAndUpload attaches the files described by the GPALFile to the targeted file input - all in one call. Without hardware, no dialog opens: GPAL sets the files on the input directly (Puppeteer and OttoMagic upload them, Selenium sends the paths to the input). Only a hardware run in a visible window clicks the input and types into the OS-native file picker.

GPALFile uploadFiles = GPAL.File

.WithFileName("C:\temp\photo1.jpg")

.WithFileName("C:\temp\photo2.jpg")

.ToGPALObject();


browser

.LeftClickAndUpload(uploadFiles)

.LeftClick("#fileupload > div > div.col-lg-7 > button.btn.btn-primary.start > span")

.WaitFor(10_000);


browser.Close(true);

WARNING

When hardware is asked for (a hardware engine, GPAL's hardware setting, or a WithHardware selector) and the run is not headless, LeftClickAndUpload clicks the input and drives the native file picker, a Windows dialog that is not part of the page DOM. That needs the browser window focused and not covered by other windows while it runs. Headless has no dialog, so the files are set on the input directly. See Hardware-Level Interaction.

💬 Ask GPAL