Why Browser
What the library actually does.
Four ideas do most of the work: waiting belongs to the keyword, getters assert, selectors chain, and one process drives every engine. Each one below is followed by the code that shows it.
Waiting is a property of the keyword, not your problem
Before it acts, every keyword waits for the element to be actionable: attached to the DOM, visible, stable — not animating — enabled, and not covered by something else. Only then does it click or type.
This is why there is no Sleep in a Browser suite, and no Wait Until Element Is Visible in front of every action. The waiting is not something you remember to add; it is what the keyword does.
When it does time out, the failure names which of those conditions was never met.
# No Sleep. No Wait Until Element Is Visible.Click text=Sign inFill Text id=search robot
Getters assert, so one line replaces three
Every getter takes an optional operator and expected value. Get Text reads the text and checks it in the same call, and the assertion retries until the timeout, so a value that arrives late still passes.
The failure message names the selector, the actual value and the expected one — you rarely need to re-run with logging to find out what happened.
The operators cover the comparisons that matter: equality, containment, regular expressions, and numeric greater/less on keywords that return numbers.
Get Text h1 == WelcomeGet Title contains RobotGet Element Count .row > 3Get Attribute a#next href matches /page/\d+
Selectors chain, and cross boundaries CSS cannot
Strategies combine in a single string with >>. You can start from a text match and walk to a sibling, cross into an iframe, or pierce shadow DOM — without switching context first and switching back afterwards.
A selector that is not obviously CSS or XPath is inferred: text in quotes is a text selector, a leading // is XPath. That keeps the common cases short without making the uncommon ones impossible.
Click text=Sign inClick "Sign in" >> xpath=../inputGet Text iframe#preview >>> h1Get Text css=my-widget >> css=button
One process for three engines
Browser talks to a single Node process, which drives Chromium, Firefox and WebKit through Playwright. There is no driver binary per browser to install, and no driver version to keep in step with a browser update.
Practically, that means testing WebKit — and therefore Safari behaviour — costs you a keyword argument rather than a machine.
The browser, context and page layers are separate, so a context can carry its own viewport, locale, geolocation, permissions or HTTP credentials without launching a new browser.
New Browser chromium headless=TrueNew Browser firefoxNew Browser webkitNew Context viewport={'width': 390, 'height': 844} locale=de-DE
A failure comes with a recording
Contexts can record video and a Playwright trace. On failure the library attaches them to the Robot Framework log alongside a screenshot, so a red build in CI comes with what the browser actually did rather than a stack trace.
The trace is the useful one: it steps through the run with a DOM snapshot at each action.
New Context tracing=True videosPath=videosNew Browser chromium# On failure the trace and video land in the log.
Comparison
Let the code speak.
Three tools, three honest pages. Each one shows the same scenario written both ways — the real files from this repository — and then makes its case: where Browser is genuinely better, and where the other tool is the one we would pick.