The driver untagged tests / the app supervisor use as primary.
A WALLABIDI_DRIVER / WALLABIDI_BROWSER env pin wins (so a pinned CI
lane boots the right supervisor and routes every test there); otherwise
the configured/default :driver.
A concurrent browser automation library — feature testing, and scraping or automating pages outside ExUnit.
Wallabidi supports the following options:
:otp_app - The name of your OTP application. This is used to check out your Ecto repos into the SQL Sandbox.:screenshot_dir - The directory to store screenshots.:screenshot_on_failure - if Wallabidi should take screenshots on test failures (defaults to false).:max_wait_time - The amount of time that Wallabidi should wait to find an element on the page. (defaults to 3_000):js_errors - if Wallabidi should re-throw JavaScript errors in elixir (defaults to true).:js_logger - IO device where JavaScript console logs are written to. Defaults to :stdio. This option can also be set to a file or any other io device. You can disable JavaScript console logging by setting this to nil.Resolves a driver for a capability tier, applying wallabidi's default ladder so the sensible path needs no configuration
Ends a browser session.
The driver pinned via WALLABIDI_DRIVER / WALLABIDI_BROWSER, or nil.
The driver untagged tests / the app supervisor use as primary.
Resolves the driver for an untagged/default session.
Starts a browser session.
Resolves a driver for a capability tier, applying wallabidi's default ladder so the sensible path needs no configuration:
:default — untagged tests / bare sessions. config :driver,
else :live_view (in-process, fastest).:headless — @tag :headless. config :headless, else
Lightpanda when its package is available, else the :browser
driver (so a Chrome-only project still runs headless tests).:browser — @tag :browser. config :browser, else :chrome_cdp.Each config :wallabidi, <key>: <driver> entry is purely an override.
@spec end_session(Wallabidi.Session.t()) :: :ok | {:error, reason()}
Ends a browser session.
The driver pinned via WALLABIDI_DRIVER / WALLABIDI_BROWSER, or nil.
Raises if the env var holds an unknown driver name (loud beats a stray atom / silent wrong-driver run).
The driver untagged tests / the app supervisor use as primary.
A WALLABIDI_DRIVER / WALLABIDI_BROWSER env pin wins (so a pinned CI
lane boots the right supervisor and routes every test there); otherwise
the configured/default :driver.
Resolves the driver for an untagged/default session.
Explicit opts[:driver] wins; otherwise the configured default
(driver_for(:default)). This is what a bare Wallabidi.start_session/1
and untagged feature tests use.
@spec start_session([start_session_opts()]) :: {:ok, Wallabidi.Session.t()} | {:error, reason()}
Starts a browser session.
:driver — which driver runs this session (:live_view,
:lightpanda, :chrome_cdp, :chrome). Defaults to the configured
driver.:user_agent — replace this session's User-Agent. Chrome only; see
below.:window_size — [width: w, height: h].:metadata — BEAM sandbox metadata, appended to the User-Agent so
DB-backed tests can find the sandbox owner. Composes with a custom
User-Agent, which becomes the base.For most cases set it once, in config — this works on every driver:
config :wallabidi, user_agent: "MyScraper/1.0 (+https://example.com/bot)"Pass :user_agent to start_session/1 only when sessions need
different User-Agents at the same time (mobile vs desktop, say):
{:ok, mobile} = Wallabidi.start_session(driver: :chrome_cdp, user_agent: "…iPhone…")
{:ok, desktop} = Wallabidi.start_session(driver: :chrome_cdp)That option is Chrome-only. Lightpanda sets its User-Agent per process
rather than per session, so it can honour the config but not the option —
passing it there logs a warning. Lightpanda also accepts
config :wallabidi, lightpanda_user_agent_suffix: "MyScraper/1.0", which
appends to Lightpanda/X.Y instead of replacing it.
Each session runs in its own browser so that each test runs in isolation. Because of this isolation multiple sessions can be created for a test:
@message_field Query.text_field("Share Message")
@share_button Query.button("Share")
@message_list Query.css(".messages")
test "That multiple sessions work" do
{:ok, user1} = Wallabidi.start_session
user1
|> visit("/page.html")
|> fill_in(@message_field, with: "Hello there!")
|> click(@share_button)
{:ok, user2} = Wallabidi.start_session
user2
|> visit("/page.html")
|> fill_in(@message_field, with: "Hello yourself")
|> click(@share_button)
assert user1 |> find(@message_list) |> List.last |> text == "Hello yourself"
assert user2 |> find(@message_list) |> List.first |> text == "Hello there"
end