A common real-world pattern: before you can log in, you have to pick an option from a dropdown menu (like choosing which portal to log into), then fill in a username and password. This tutorial walks through clicking a native menu, selecting an option, filling in credentials, and using StealthLeftClick on the final submit button.
The workflow opens the site, clicks a menu to reveal portal options, picks one, then waits for the login form to appear before filling in a username and password and clicking the final submit button.
using GenerallyPositive;
using GenerallyPositive.Browser;
using static GenerallyPositive.Enums;
GPAL
.WithPublishToConsole(GPALEventType.All & ~GPALEventType.DEEPDEBUG)
.WithPublishToDebug();
IBrowser browser = GPAL.Browser
.WithBrowserType(BrowserType.Chrome)
.WithUseStealth(StealthType.GoogleReferrer)
.WithLoadImages(true)
.ToGPALObject();
browser.GoTo("https://www.example-bank.com/");
Selector loginMenuSelector = GPAL.Selector.WithCSS("span.login-select-toggle").WithSelectorName("Login Menu").ToGPALObject();
Selector cashManagerOptionSelector = GPAL.Selector.WithCSS("#login-select > option:nth-child(3)").WithSelectorName("Cash Manager Option").ToGPALObject();
Selector usernameSelector = GPAL.Selector.WithCSS("input[name='txtUsername']").WithSelectorName("Username").ToGPALObject();
Selector passwordSelector = GPAL.Selector.WithCSS("#txtPassword").WithSelectorName("Password").ToGPALObject();
Selector loginButtonSelector = GPAL.Selector.WithValue("LOG IN").WithSelectorName("Login Button").ToGPALObject();
Selector finalLoginButtonSelector = GPAL.Selector.WithCSS("#btnLogin").WithSelectorName("Final Login Button").ToGPALObject();
browser
.WaitFor(5_000)
.LeftClick(loginMenuSelector);
browser
.LeftClick(cashManagerOptionSelector);
// some automation engines select the entry but leave the menu open, which can interfere with the username field
browser
.WaitFor(5_000)
.LeftClick(loginMenuSelector);
browser
.WithSelector(usernameSelector)
.FillInFrom("SampleUser");
browser
.LeftClick(loginButtonSelector)
.WaitFor(1_000);
browser
.WithSelector(passwordSelector)
.FillInFrom("SamplePassword123!")
.StealthLeftClick(finalLoginButtonSelector)
.WaitFor(5_000);
browser.Close(true);
WithUseStealth(StealthType.GoogleReferrer) sets a Chrome DevTools Protocol leak handler and makes the browser look like it arrived via a Google search rather than a fresh automated session. WithLoadImages(true) keeps image loading on so the page's signature looks like a normal browser, not a stripped-down automation profile.
IBrowser browser = GPAL.Browser
.WithBrowserType(BrowserType.Chrome)
.WithUseStealth(StealthType.GoogleReferrer)
.WithLoadImages(true)
.ToGPALObject();
Banking and financial sites often run bot-detection scripts that check referrer headers, image loading, and CDP fingerprints. WithUseStealth and WithLoadImages(true) help the automated browser blend in with normal traffic.
This site's login portal selector is a two-step interaction: clicking the menu toggle reveals the option list, then clicking the desired option (here, a native select option located by nth-child) makes the selection. The workflow clicks the menu toggle again afterward because some automation engines leave the menu visually open after selecting, which can block the username field underneath.
Selector loginMenuSelector = GPAL.Selector.WithCSS("span.login-select-toggle").WithSelectorName("Login Menu").ToGPALObject();
Selector cashManagerOptionSelector = GPAL.Selector.WithCSS("#login-select > option:nth-child(3)").WithSelectorName("Cash Manager Option").ToGPALObject();
browser
.WaitFor(5_000)
.LeftClick(loginMenuSelector);
browser
.LeftClick(cashManagerOptionSelector);
// some automation engines select the entry but leave the menu open
browser
.WaitFor(5_000)
.LeftClick(loginMenuSelector);
Different automation engines can handle the same dropdown differently - one might close the menu after selecting an option, another might not. If a workflow that fills in a field right after a menu selection intermittently fails, try clicking the menu toggle again first to confirm it's closed.
WithSelector plus FillInFrom types the username into the field. The first login button click moves to the password step, with a short WaitFor afterward to let the next field render.
browser
.WithSelector(usernameSelector)
.FillInFrom("SampleUser");
browser
.LeftClick(loginButtonSelector)
.WaitFor(1_000);
StealthLeftClick performs the click using the same stealth-aware interaction as the rest of the session, which matters for the final submit button on sites that scrutinize login attempts. The WaitFor(5_000) afterward gives the page time to process the login before the workflow continues.
browser
.WithSelector(passwordSelector)
.FillInFrom("SamplePassword123!")
.StealthLeftClick(finalLoginButtonSelector)
.WaitFor(5_000);
browser.Close(true);
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();