Dialog mode (WithPromptForDownload(true)) waits for the OS Save As window to appear, then uses hardware emulation to type the target filename into it and press Enter -- no mouse needed, no manual interaction. Silent mode (the default) clicks the element and watches the filesystem for a new file of the matching extension in the browser default download directory, then moves it to the path you specified. Direct mode (WithUseDirectDownload(true)) bypasses the browser download mechanism and fetches the file via WebClient using the href or src attribute of the clicked element -- useful when the browser would show a dialog or open the file inline instead of saving it. Note that WebClient does not carry the active browser user agent, so sites that gate downloads on UA matching may reject it.
// Path 1 - Dialog: wait for OS Save As window,
// type filename via hardware, press Enter:
GPAL
GPAL
// Path 2 - Silent: click, watch default
// download dir, move file when it appears:
// (default - WithPromptForDownload(false))
// Path 3 - Direct: bypass the browser entirely,
// fetch via websocket:
GPAL
GPAL
All three paths wait up to WithDownloadTimeoutInSec(int) seconds for the file to arrive before logging an error and continuing. Default is 60 seconds. Increase it for large files or slow connections.
When the Save As dialog opens, GPAL calls HardwareHelper.SendString with the target filename, then SendKey(VK_RETURN). If the dialog is still present after the first Enter (some browsers need two), it sends Enter again. GPAL then waits for the file to fully write to disk before returning. This path requires the browser to be running in headed mode -- it cannot work headless because the OS dialog has nowhere to render.
GPAL
GPAL
// Chrome/Edge waits for: "Save As"
// Firefox waits for: "Enter name of file
// to save to
Some sites show a consent or confirmation modal between the click and the actual download starting. Define those as persistent selectors and GPAL will automatically dismiss them before waiting for the Save As dialog.
In silent mode, each engine handles the download in its own way. Selenium in headed mode sets up a filesystem watcher on the default download directory, clicks the element, waits for a file with the matching extension to land, then moves it to your target path. Selenium in headless mode uses CDP Page.setDownloadBehavior to route the file directly to the target location without a dialog or watcher. OttoMagic intercepts the download natively inside the Chrome extension and routes the file to the target path without any OS dialog involvement. Puppeteer uses its own built-in download handling to intercept the response and write the file directly. In every case the call is identical -- WithPromptForDownload and WithUseDirectDownload apply consistently and GPAL selects the correct internal path for the active engine automatically.
// Silent mode -- what each engine does internally:
//
// Selenium (headed): sets up a filesystem watcher
// on the default download directory, clicks,
// waits for a new file, moves it to target path
//
// Selenium (headless): CDP Page
// routes the file directly to the target location
// -- no dialog, no watcher needed
//
// OttoMagic: native download intercept inside
// the Chrome extension routes the file directly
// to the target path without OS involvement
//
// Puppeteer: built-in Puppeteer download handling
// intercepts the response and writes the file
// to the target path directly
//
// Same LeftClickAndDownload call in all cases
// GPAL selects the correct engine path for you
When a click produces no downloaded file but the browser navigates to a new URL, GPAL checks automatically whether that URL is a PDF -- first by looking for a .pdf extension, then by issuing an HttpClient HEAD request and inspecting the Content-Type and Content-Disposition response headers. If a PDF is confirmed, GPAL checks the target directory and the default download directory in case the browser already placed it there, and moves it into position. If it is not there, GPAL downloads it directly via HttpClient -- using the live user agent queried from the active engine so the out-of-band request presents the same identity as the browser session.
Showing off some plain text in these paragraphs eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo veniam mollitia excepturi animi eum illum non libero sapiente provident assumenda, delectus voluptatum nobis sed dolorem adipisci laudantium incidunt. Error, ratione?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo veniam mollitia excepturi animi eum illum non libero sapiente provident assumenda, delectus voluptatum nobis sed dolorem adipisci laudantium incidunt. Error, ratione?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo veniam mollitia excepturi animi eum illum non libero sapiente provident assumenda, delectus voluptatum nobis sed dolorem adipisci laudantium incidunt. Error, ratione?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo veniam mollitia excepturi animi eum illum non libero sapiente provident assumenda, delectus voluptatum nobis sed dolorem adipisci laudantium incidunt. Error, ratione?
Here you can find different accents and emphasis sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
This is a link and how it could look like bestlinkinthebeautifulworld. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Here's just some classic bold text adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam notBoldSecondbestlinkinthebeautifulworld illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Obcaecati, iste distinctio veritatis eligendi laboriosam adipisicing elit illo nostrum corporis at adipisicing elit libero vel voluptas? Expedita, adipisicing facere dolores voluptatem ad ab rem assumenda soluta!
Other cuple of colors in case we want to emphasize several ways adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam adipisicing elit illo nostrum corporis at voluptatem libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta! Lorem ipsum dolor, sit amet consectetur adipisicing elit. Quod veniam, quam ad expedita laborum sed at voluptates culpa ipsam ut vel. Ullam temporibus a mollitia quod aliquam ratione exercitationem nesciunt.
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta! Lorem ipsum dolor, sit amet consectetur adipisicing elit. Quod veniam, quam ad expedita laborum sed at voluptates culpa ipsam ut vel. Ullam temporibus a mollitia quod aliquam ratione exercitationem nesciunt.
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Repudiandae quas consequuntur illo numquam assumenda autem exercitationem distinctio perspiciatis in natus. Eius dicta similique ipsam ipsa minima, nemo quae enim tempore.
GPAL
.CallIfNotFound(GenericCallIfNotFound)
.WithPublishToConsole();
//System.Drawing.Rectangle windowSize = new System.Drawing.Rectangle(10, 10, 1500, 1024);
// NOTE: we have to set browser = before we execute any steps
// this is due to the 'GenericCallIfNotFound' which might throw an exception, and BankScraper will not have the browser set when it calls scraper.Close()
// until the complete fluent line gets executed (meaning every step, meaning browser is not set until everything else succeeds)
browser = GPAL.Browser
.WithBrowserType(Enums.BrowserType.Chrome)
.WithProfileDataDirectory(ChromeProfileLocation)
.WithUseAutomationEngine(AutomationEngine.Selenium)
.WithWindowSize(new System.Drawing.Rectangle(0,0,1920,1080))
.ToGPALObject();