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)) takes the href or src off the element and asks for that url rather than clicking it, which is what you want when clicking would open the file inline or raise a dialog. The request is made from inside the page, so it goes out on the connection the browser already earned: its cookies, its user agent, its clearance. Nothing navigates, no tab opens, and the bytes are written where you said rather than landing in the download directory under a name the browser chose. If the page cannot hand the file over, GPAL downloads it in a tab instead, and reports the outcome either way.
Direct mode needs an element that carries a url. A button that downloads by running script carries none, and GPAL says so rather than guessing: leave direct mode off and the click is used.
// Path 1 - Dialog: wait for OS Save As window,
// type filename via hardware, press Enter:
GPAL
// Path 2 - Silent: click, watch default
// download dir, move file when it appears:
// (default - WithPromptForDownload(false))
// Path 3 - Direct: no click, ask for the
// element's url from inside the page:
GPAL
All three paths wait up to WithDownloadTimeoutInSec(int) seconds for the file to arrive before logging an error and continuing. Default is 10 seconds, from downloadTimeoutInSec in GPAL.yaml. 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. Edge has no Save As prompt to answer, so on Edge, and on a hidden desktop, GPAL turns the prompt off and uses silent mode.
GPAL
// Chrome waits for: "Save As"
// Firefox waits for: "Enter name of file
// to save to
// Edge never prompts: GPAL turns the prompt
// off and the download goes the silent way
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 on Chrome or Edge, in a window or headless, uses CDP Page.setDownloadBehavior to send the file to the target folder, then watches that folder until the file is written. Selenium on Firefox watches the browser's download directory, waits for the new file to land, then moves it to your target path.
OttoMagic has the extension name the file, the browser saves it in its download directory, and GPAL moves it to the target path. Puppeteer has the browser save into the target folder and watches it until the file is written.
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 on Chrome or Edge, window or headless:
// CDP Page
// to the target folder, which GPAL watches
//
// Selenium on Firefox: watches the browser's
// download directory, waits for a new file,
// moves it to the target path
//
// OttoMagic: the extension names the file, the
// browser saves it in its download directory,
// GPAL moves it to the target path
//
// Puppeteer: the browser saves into the target
// folder, which GPAL watches until the file
// is written
//
// 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 fetches it from inside the page, on the browser's own connection, and falls back to HttpClient with the live user agent queried from the active engine when the page cannot hand it over.
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();