Basic Concepts

Selenium's JavaScript Injection Override

WithJavaScript: Bypassing Selenium's Own Methods

By default, a Selenium-based selector interacts through Selenium's own element APIs -- element.Click(), SendKeys(), and so on.

WithJavaScript overrides that for a specific element and instead injects JavaScript that manipulates the element directly: setting .value, dispatching events, or calling .click() in the page's own script context.

This matters for elements that resist Selenium's normal interaction -- inputs controlled by a JS framework that ignores SendKeys, elements visually covered by an overlay that blocks Selenium's click point, or elements Selenium can locate but can't reliably interact with.

// Normal Selenium interaction

browser

.WithSelector((Selector)"#normal-input")

.FillInFrom("value");


// This input ignores SendKeys because a JS framework owns its value -

// inject JS to set the value and fire the events the framework listens for

browser

.WithSelector((Selector)"#framework-controlled-input").WithJavaScript

.FillInFrom("value");

WithSelenium: Switching Back

WithSelenium is the reciprocal of WithJavaScript (and of WithHardware). It asks for Selenium's normal interaction, which is already the default on the Selenium engine. It is set on a reusable Selector definition only. It cannot opt a selector out of a broader setting: hardware turned on globally or for the browser, or the SeleniumJS engine, wins over it. On an engine other than Selenium it logs a WARNING and the engine's own interaction is used.

NOTE

WithJavaScript, WithHardware, and WithSelenium are all ways of choosing how a Selenium-based selector is interacted with. They only make sense because Selenium's default interaction model is something you might want to step around.

Why Puppeteer and OttoMagic Don't Have This

Puppeteer's automation engine talks to the browser via the Chrome DevTools Protocol (CDP). There's no separate 'Selenium-style' element API to override in the first place. CDP itself sometimes uses JavaScript evaluation under the hood for certain operations.

OttoMagic is built entirely on in-page JavaScript via its browser extension. It IS the JavaScript approach, with nothing else to fall back to or override.

WithJavaScript is aimed at Selenium for this reason: for Selenium, it's a real alternative to that engine's own element API.

WithHardware is a different story and remains available on all three engines. It overrides any of them with real OS-level input, so Puppeteer and OttoMagic each have their normal interaction plus the hardware override. Puppeteer also takes WithJavaScript for clicks; OttoMagic has nothing for it to change.

WARNING

Setting WithJavaScript while the base engine is OttoMagic doesn't fail, but it doesn't change anything either; OttoMagic already works through in-page JavaScript. On Puppeteer it changes clicks only, to a JavaScript click that falls back to a Puppeteer click if it fails.

💬 Ask GPAL