All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog.
[Unreleased]
[0.13.0] 2026-10-01
Added
Connection.unsubscribe_sync/3removes channel delivery and managed event ownership before returning. Both synchronous and asynchronous removal leave other recipients and explicit subscriptions intact.- Page
:frame_navigatedevents cover main and child frames, including frames created after registration, through existing subscriptions andEventWaiter.
[0.12.1] 2026-09-21
Fixed
- Restore
js_logger: falseas an alias fornilto disable JavaScript logging. Console messages and page errors no longer crash the connection withfalse.
[0.12.0] 2026-09-16
Added
- Add
Locator.evaluate/2, with strict lazy resolution under the locator timeout, unlimited JavaScript evaluation and disposal, and Playwright JS cleanup error precedence. - Add
ElementHandle.evaluate/2anddispose/2. - Add
Frame.expect_result/2to retain assertion diagnostics;expect/2keeps its boolean behavior.
[0.11.0] 2026-09-15
Added
Frame.snapshot/2for an atomic read of the cached URL, document request, and client-generated document identity.- Optional
EventWaitertransforms that run on capture inside the waiting task. - Managed opt-in event subscriptions: the first waiter enables an event and the last releases it. Explicit channel subscriptions remain active independently.
Frame.document_request/2to read the committed document's request without event subscriptions, preserving it across same-document navigation.Request.response/2to retrieve a request's response without subscribing to response events, returningnilwhen the request fails without a response.
Changed
- Frame URL/load-state waits use a separate task for each caller. The connection caches current frame state; per-frame recorder processes are removed. Public results stay synchronous, and URL predicate errors affect only that caller.
Fixed
- Download waiters validate their own options, excluding raw event transforms and
subscription overrides to preserve the
Downloadresult. - Clean up abandoned frame waits when callers exit and discard recorded frame state when the connection closes.
[0.10.0] 2026-09-15
Added
- Download handles with browser-provided filename and URL, reusable through
Download.from_event/2,Download.save_as/3, and explicitDownload.delete/2. Page.expect_download/2andPage.await_download/1for explicit arm/action/await download capture, with an optional predicate on download metadata.EventWaiter.arm/3,await/1, andcancel/1for one-shot protocol events, using linked tasks and ref-tagged replies, with synchronous registration, one deadline from arming, optional event predicates, and owner/connection lifecycle handling.:infinitydisables the event timeout.
Changed
- Breaking:
timeout: 0now means no waiting throughout the client. Protocol commands time out without being sent; frame URL/load-state waits check cached state once. Replacetimeout: 0withtimeout: :infinitywhere unlimited waiting was intended. - Missing connections, normal stops, supervisor shutdowns, and response timeouts return error results at the connection boundary. Other process exits and URL predicate bugs propagate instead of being converted to ordinary error results.
Fixed
- Discard unrelated protocol events from event waiters without extending their deadline, preventing mailbox growth while waiting on busy channels.
- Support
:infinityin frame URL/load-state waits and keyboard actions without timeout arithmetic errors. Keyboard delays cannot extend a zero timeout. - Artifact saves share one timeout across stream reads, clean up failed
transfers, create parent directories, and preserve existing destinations on
failure. Stream cleanup runs in an
afterblock and preserves the transfer result. Saving leaves the source artifact available to other readers. - Support
:infinitycommand timeouts using Playwright's zero-timeout wire value.
[0.9.0] 2026-09-08
Added
- Typed local and
PlaywrightEx.FilePayloadin-memory uploads throughFrame.set_input_files/2and the newElementHandle.set_input_files/2, including file-chooser handles and empty selections. #80 - Playwright 1.63 APIs for structured ARIA snapshots, OPFS and WebAuthn storage
state, browser-context event subscriptions (including
dialog_closed), visible and cross-frame selectors, and expanded browser launch options.
Changed
- Require Playwright 1.63 or newer and use it as the sole protocol baseline. Older local drivers are rejected, and remote connections advertise 1.63 and reset their protocol state after disconnects.
- Adopt Playwright 1.63's HTTP-credential and tracing wire formats while retaining the existing map-or-list public credential API.
Fixed
- Align channel options, events, and results with Playwright 1.63, including headers, enums, cookies, frame polling and selection, subscriptions, tracing modes, void results, and protocol logs.
- Correct channel lifecycle tracking across initialization, creation, adoption, disposal, and page/frame ownership; console and page errors now reach subscribers.
- Support every Playwright 1.63 serialized-value variant without altering opaque JSON keys or creating atoms from untrusted data.
- Harden port framing, stderr isolation, and remote artifact cleanup.
[0.8.0] 2026-08-27
Changed
- Require Playwright 1.62 or newer. Command timeouts are now sent as protocol metadata, matching the Playwright 1.62 driver contract. The bundled development dependency is updated to 1.62, and the local port transport warns when an older driver is detected.
- Preserve both the protocol error and
error_detailsinPage.expect_screenshot/2errors as{:error, {error, error_details}}. #58
Removed
- Support for the Playwright 1.60 expectation response format. #58
[0.7.1] 2026-06-19
Added
- Warn about playwright version < 1.61.0 (port transport only). Commit cd9e98e
[0.7.0] 2026-06-16
Fixed
- Support the Playwright 1.61
Frame.expectwire contract. 1.61 stopped returning%{matches: boolean}and now signals the assertion outcome by success-vs-error: a non-match returns a protocol error carryingerror_details.Frame.expect/2now yields a plain{:ok, boolean}under both 1.60 and 1.61, sophoenix_test_playwright'sassert_has/refute_haskeep working.Serialization.deserialize_arg/1also raises a descriptive error on unknown serialized shapes instead of a bareCaseClauseError. Commit d6d9ddc, #57, @oliver-kriska
[0.6.1] 2026-06-16
Added
- Accept all supported options to
Frame.goto. Commit 8e96071, #49, @s3cur3 Page.expect_screenshot/2. Commit 929b90e, #56, @Wigny
Fixed
- Handle
viewport: nilto disable default viewport. Commit 8139523, #46
[0.6.0] 2026-05-05
Added
PlaywrightEx.Artifactfor saving and deleting Playwright artifact files. Commit 8178f7cPlaywrightEx.BrowserContextclock helpers:clock_install/2andclock_fast_forward/2. Commit 7b6b977, #30PlaywrightEx.BrowserContext.storage_state/2andPlaywrightEx.BrowserContext.set_storage_state/2. Commit bcb5b16, #35, @probably-not:envoption for local Port transport environment variables. Commit 0095f7f, #34, @probably-notPlaywrightEx.Page.bring_to_front/2to activate a page tab. Commit 7348fa4, #32
Removed
- Frame
url/2helper, which is not a supported Playwright server operation. Commit 9490384
Fixed
:ignore_https_errorsnow serializes to Playwright's requiredignoreHTTPSErrorscasing. Commit 80f28be, #45
[0.5.0] 2026-03-06
Added
PlaywrightEx.Frame:is_visible/2,is_checked/2,is_disabled/2,is_enabled/2,is_editable/2,get_attribute/2,input_value/2,text_content/2,inner_text/2,focus/2,dispatch_event/2,wait_for_function/2. Commit 8684fda, #22, @oliver-kriskaPlaywrightEx.Frame.wait_for_selector/2:stateandstrictoptions. Commit 8684fda, #22, @oliver-kriskaPlaywrightEx.BrowserContext.add_init_script/2andPlaywrightEx.Page.add_init_script/2. Commit 74e93f6, #23, @probably-notPlaywrightEx.unsubscribe/2and connection-level unsubscribe support. Commit 319a69bPlaywrightEx.Frame.wait_for_load_state/2andPlaywrightEx.Frame.wait_for_url/2with event-based navigation waiting. Commit 027b0fa- Per-frame event recorder process to keep waiter subscriptions continuous across waits. Commit 027b0fa
PlaywrightEx.Page.expect_url/2for explicit URL expectations on pages. Commit 027b0fa- Regex support in argument serialization/deserialization using protocol-native
{r: %{p, f}}values. Commit 027b0fa PlaywrightEx.Page.reload/2to reload current page. Commit f3c5b21, #25, @wjrtz
Fixed
PlaywrightEx.Frame.wait_for_selector/2: crash whenstateis"hidden"or"detached"(result has no element). Commit 8684fda, #22PlaywrightEx.BrowserContext.add_init_script/2andPlaywrightEx.Page.add_init_script/2: usesourceparameter name required by Playwright protocol (instead ofcontent). Commit 3fd54a1- URL regex expectations now send Playwright-compatible string regex flags. Commit 027b0fa
- Frame waiter exit errors preserve normalized reason atoms in error metadata. Commit 027b0fa
[0.4.0] 2026-02-09
Added
- Support remote Playwright server via websocket. Commit 63fc6eb, @carsoncall
[0.3.2] 2026-01-30
Fixed
- Typespec bugs. Commit 7275ef9
[0.3.1] 2026-01-30
Added
- Tracing groups in preparation for
PhoenixTest.Playwright.step/3:PlaywrightEx.Tracing.group/3. Commit 545bc4d, @nathanl
[0.3.0] 2025-12-24
Added
PlaywrightEx.Page.mouse_move/2,mouse_down/2,mouse_up/2for low-level mouse control. Commit 530e362, @nathanlPlaywrightEx.Frame.hover/2for hovering over elements (supports manual drag operations). Commit 530e362, @nathanl
Fixed
- Serialization of args given to
PlaywrightEx.Frame.evaluate/2. Commit fecf965, @nathanl
[0.2.1] 2025-11-28
Changed
- Suppress node.js errors on termination
[0.2.0] 2025-11-19
Changed
- Add typespecs and docs
- Make channel function input and output consistent
[0.1.2] 2025-11-14
Changed
- Extract
PlaywrightEx.Supervisor(spawnPortServeroutside ofConnection)
[0.1.1] 2025-11-14
Fixed
- Memory leak: Free memory when playwright resource is destroyed (handle
__dispose__messages)
[0.1.0] 2025-11-13
Added
- First draft