Automated Browser Version Update - #54
Open
titusfortner wants to merge 3650 commits into
Open
titusfortner wants to merge 3650 commits into
titusfortner wants to merge 3650 commits into
Conversation
* [rust] Change command execution to argv * [rust] Fix dash version constants * [rust] Include trace log in browser path * [rust] Check browser path in driver error logic * [rust] Check fallback flag * [rust] Fix condition for checking fallback
…eleniumHQ#17544) Add BinaryMessage.wrap for transferring an owned byte array BinaryMessage's two public constructors both copy their input defensively: the byte[] constructor calls System.arraycopy, and the ByteBuffer constructor copies into a freshly allocated array. That is the right default when the caller cannot promise ownership, but several call sites already produce a fresh array via ByteArrayOutputStream.toByteArray() and then immediately have it copied a second time by the constructor. For a multi-megabyte payload the second copy is wasted work and a wasted allocation. Add a static BinaryMessage.wrap(byte[]) factory that takes ownership of the array without copying. Its javadoc explicitly states that the caller must not mutate the array afterwards. The two public constructors keep their copy semantics, so existing callers that pass in a borrowed array are unaffected. Use the new factory at two slow-path reassemblers that already produce a fresh array we own: - MessageInboundConverter, when a fragmented binary message finishes via buffer.toByteArray() before being forwarded to WebSocketMessageHandler. - WebSocketFrameProxy, when the inbound frame proxy reassembles a fragmented message for an upstream WebSocket that does not support per-frame sends. The hot path through the Router and Node proxies no longer touches BinaryMessage at all — frames travel end-to-end as Netty WebSocketFrame objects — so the saving here is on the fallback paths that handle fragmented binary messages. A focused unit test pins both the copying behaviour of the existing constructor and the no-copy behaviour of the new factory.
) The Router has had a direct frame-forwarding path between the Netty pipeline and the upstream JDK WebSocket since db9b07a (2026-03-11, "[grid] Router WebSocket handle dropped close frames, idle disconnects, high-latency proxying", SeleniumHQ#17197). Once the client-side handshake completes, an inbound WebSocketFrameProxy forwards each Netty WebSocketFrame straight to the upstream WebSocket, and the outbound DirectForwardingListener writes upstream replies directly to the client channel. Together those removed the per-frame Message allocation and the executor hop in WebSocketMessageHandler on the Router side. The Node still did the full round-trip through MessageInboundConverter, WebSocketMessageHandler, the registered Consumer<Message>, and MessageOutboundConverter in both directions for every frame. Each frame allocated a TextMessage or BinaryMessage and hopped onto the channel executor on delivery. For a busy CDP or VNC session that is measurable allocation and executor-queue pressure on the Node. Apply the same PostUpgradeHook pattern on the Node side: the consumer returned from ProxyNodeWebsockets installs a WebSocketFrameProxy after the handshake so inbound frames forward straight to the browser-side WebSocket, and a DirectForwardingListener writes outbound frames directly to the client channel. Frames received before the handshake are buffered in arrival order and drained on handover, so a frame cannot land in a pipeline that has already had its Message-layer handlers removed. The hardening that the Router-side listener picked up in 8d8cf64 (2026-05-14, "[grid] Close pre-handshake race in WebSocket proxy", SeleniumHQ#17435) is mirrored on the Node listener: the pre-handshake buffer is capped at 128 frames with a 1009 close recorded on overflow; the close code and reason are recorded on pre-handshake close or error so a late onUpgrade can write a clean close frame to the client and tear the channel down rather than leaving it open; and the buffer is released on close so ref-counted frames cannot leak if the handshake never completes. Close-frame reasons coming from the upstream are now truncated to the 123-byte UTF-8 cap that RFC 6455 §5.5.1 imposes. The truncation uses a CharsetEncoder writing into a 120-byte buffer so it stops at a clean character boundary on overflow — a naive byte-truncate-then- decode could split a multi-byte sequence, produce a U+FFFD replacement on decode, and re-encode back over 123 bytes, breaking the close frame. The helper lives as a public static on WebSocketFrameProxy because both DirectForwardingListener classes already depend on that class. The Router-side listener that landed in SeleniumHQ#17435 had the same unchecked path; apply the helper there too so both proxies share the same safe behaviour. The Node-specific behaviour is preserved: - Session-activity heartbeats (sessionConsumer.accept(sessionId)) fire per frame, both pre- and post-handshake. - The connectionReleased CAS still guards a single node.releaseConnection call across the close and error paths, including the overflow path introduced here. - VNC sessions still install a no-op heartbeat consumer so VNC traffic does not mark the session as recently active. The existing ProxyNodeWebsocketsTest continues to exercise the slot accounting, including the regression from SeleniumHQ#17197 where onError without a follow-on onClose used to leak the slot. New unit tests in NodeDirectForwardingListenerTest pin the per-frame heartbeat, the buffer-then-drain ordering, the surface-and-teardown behaviour on a pre-handshake close, the overflow path's clean release of the session slot, and the safe truncation of an overlong upstream close reason that contains multi-byte UTF-8 characters. The shared helper has a focused unit test alongside it in WebSocketFrameProxyTest.
…d-Element (SeleniumHQ#17547) * fix the IIFE so the JS bindings can use the new atoms * [js] Fix wrap-as-global scripts to accept named function expressions The is-displayed and find-elements atoms were restructured from IIFE-returning-closure to named function expressions so all helper functions are in scope when the atom is serialized via toString() for browser injection. The wrap-as-global scripts had a format guard checking for the old parameterless IIFE prefix "(function ()" which now fails. Relax the check to "(function " to accept both patterns. * whitespace change * whitespace change * fix readtest
Update pinned browser versions Co-authored-by: Selenium CI Bot <selenium-ci@users.noreply.github.com>
…eniumHQ#17578) The read-idle close that TcpUpgradeTunnelHandler installs after the tunnel is established (introduced by db9b07a, 2026-03-11, "[grid] Router WebSocket handle dropped close frames, idle disconnects, high-latency proxying", SeleniumHQ#17197) tears down both tunnel channels when no bytes have been received for 120 seconds. That is the right behaviour when an intermediate load balancer has silently dropped the TCP connection, but it interacts badly with the backpressure mirroring added in 5cf2e2a (2026-05-26, "[grid] Apply TCP backpressure across the WebSocket tunnel handler", SeleniumHQ#17543): when the peer's outbound buffer crosses its high-water mark, TcpTunnelHandler sets autoRead=false on this side, no channelRead events fire, and the read-idle timer reaches its threshold even though the stall is by design. A sustained slow consumer for more than two minutes will therefore have the tunnel torn down underneath it. Gate the close in IdleCloseHandler.userEventTriggered on the channel's autoRead flag: while reads are paused by backpressure, log at FINE and ignore the event. As soon as the peer drains and TcpTunnelHandler restores autoRead=true the read-idle clock starts again from a fresh read, so a legitimately dropped connection is still detected within the same window once traffic resumes. IdleCloseHandler is promoted from a private nested class to package-private so a focused EmbeddedChannel unit test can exercise both branches: the close-both-channels behaviour on a normal idle event, and the ignored-while-paused behaviour with autoRead=false.
…oms (SeleniumHQ#17582) * [js] Reduce GC pressure in TypeScript getAttribute and isDisplayed atoms getAttribute: convert BOOLEAN_PROPERTIES from Array to Set for O(1) .has() lookup instead of O(n) .indexOf(), and call element.getAttribute(name) directly at the three call sites that already hold the lowercased name, avoiding a redundant .toLowerCase() in the wrapper. isDisplayed: replace findImageUsingMap's full-DOM getElementsByTagName('*') scan with a single querySelector('[usemap="#..."]') call, using the same CSS attribute-value escaping pattern applied to nameMany in find-elements. * [js] Memoize computed style, client rect, and displayed in isDisplayed atom Add three per-call Maps inside isShownElement, scoped to the single synchronous invocation so there is no stale-data risk and no GC pressure between calls: - computedStyleCache: getEffectiveStyle now fetches getComputedStyle once per element and reuses the CSSStyleDeclaration for subsequent property reads. A typical isShown call queries 5-8 properties on the same element. - clientRectCache: getClientRect caches the Rect after the first getBoundingClientRect (or imageMap rect) computation. Overflow checking and positiveSize both query ancestor rects, so shared containers are only laid out once. - displayedCache: displayed() walks the full ancestor chain on every call. positiveSize iterates all children calling displayedFn on each, so shared ancestors were re-walked N times for N siblings. The cache makes each ancestor node free after the first traversal. * [js] Remove bogus async boolean-property test document.createElement('script').async returns true by default (browser sets the 'force async' flag on script elements created via JS), so the test expecting null was never correct. The absent-boolean-returns-null behaviour is already covered by the existing disabled and readonly tests.
* [py] Handle Data URLs when doing .continue_request(). Fixes SeleniumHQ#16279 * [py] Remove xfail marks from data URL network test The xfail marks were added when continue_request() would throw for data: URLs. Now that continue_request() silently skips data: URLs, the test should pass in all browsers that fire network.beforeRequestSent for data URL sub-resources. * Fix the other linting way
Update pinned browser versions Co-authored-by: Selenium CI Bot <selenium-ci@users.noreply.github.com>
SeleniumHQ#17584) [rust] Improve SM error messages when browser/driver version is not found Add per-browser links to canonical version lists in error messages so users know where to find valid versions when a lookup fails.
- Unify ruff_check.py + ruff_format.py into a single ruff.py that accepts check/format/both modes; eliminates duplicated dirs, excludes, and config references. Adds //py:ruff target for running both at once. - Fix --exit-non-zero-on-fix footgun: ruff_check now exits 0 when all issues are auto-fixed. CI verification mode uses --no-fix explicitly. - Add ruff check to scripts/format.sh (always, not just with --lint), resolving the ruff binary once via --run_under=echo to halve Bazel startup overhead. Auto-fixable lint issues are now committed by the CI bot alongside formatting fixes. - Update py:lint to use --no-fix (pure verification, no side effects). - Split ci-python.yml lint job into parallel lint-ruff / lint-mypy / lint-docs jobs so mypy does not block ruff feedback.
…ry-cache (SeleniumHQ#17575) * [build] add Github Cache workflow and cancel-on-failure guard in bazel.yml * [build] remove cancel-on-failure guard
Update pinned browser versions Co-authored-by: Selenium CI Bot <selenium-ci@users.noreply.github.com>
Co-authored-by: Diego Molina <diemol@users.noreply.github.com>
* [build] surface failures from archive rules * [build] address review feedback on archive rules --------- Co-authored-by: Diego Molina <diemol@users.noreply.github.com>
Co-authored-by: Diego Molina <diemol@users.noreply.github.com>
* [java] publish selenium-devtools-latest alias artifact * remove redundant runtime_deps --------- Co-authored-by: Diego Molina <diemol@users.noreply.github.com>
…nDriver (SeleniumHQ#17559) * [java] Add ElectronDriver and ElectronOptions for testing Electron apps * improved null checking and matching existing conventions * use a custom capability instead of string parsing the class name * fix potential ClassCastException --------- Co-authored-by: Diego Molina <diemol@users.noreply.github.com>
…eleniumHQ#17597) * [rb] improve selenium manager testing * [build] delete pre-installed browsers in CI to force SM to fetch them * [rb] add os-sensitive tag for driver_finder
…mHQ#17603) [rb][py] resolve runfiles JDK realpath on Windows to avoid lib\modules symlink bug
… custom Firefox webExtension options (SeleniumHQ#17840) * [build] add local CDDL overlays for webExtension.install SeleniumHQ#1140 extension point and moz vendor params * [js] implement in schema not in merged cddl file that is sent to cddl2ts * [rb] generate a browser-scoped webExtension vendor subclass (WebExtension::Moz)
…C URLs (SeleniumHQ#17790) * [grid] honor client-advertised se:remoteUrl in the Node with grid-url precedence * [grid] advertise se:remoteUrl from the language bindings * [grid] fix se:remoteUrl on URL constructor, https scheme casing, and builder capability conflict * [grid] strip se:remoteUrl from returned session caps * [grid] use only the origin of se:remoteUrl for proxied URLs
…SE_BIDI_STRICT to escalate (SeleniumHQ#17844)
…licy in AGENTS.md
…Q#17838) * [rust] locate Chrome and Edge in known install directories * [rust] honor --skip-browser-in-path and keep WebView2 out of Edge browser lookup
* [dotnet] throw instead of warn for CDP on Firefox * [py] raise for CDP methods on Firefox * [rb] remove CDP extensions from Firefox so methods are unavailable
… match severity (SeleniumHQ#17848) * [rb] match log entries by id and severity, add missing log ids, drop logger stubs * [rb] match message assertions against entries carrying multiple ids
* [rb] glob spec sources into //rb/spec:spec for rubocop and clear hidden offenses * [rb] remove unnecessary rb_library from rb_integration_test now that //rb/spec:spec globs sources
…date primitives outbound in Ruby (SeleniumHQ#17852) * [build] bump cddl to 0.21.1 so float BiDi ranges type as number, not integer * [build] hoist nullable inline enums to named enums so their vocabulary is validated * [rb] validate outbound BiDi primitive types at construction
…eleniumHQ#17853) * [build] drop preserveExtras schema signal; extensibility alone gates wire extras * [rb] retain wire extras on every extensible BiDi type, not only re-sendable ones * [rb] keep extensible extras without warning and reject extras shadowing declared fields
…e map (SeleniumHQ#17855) * [rb] raise typed WebDriver errors for BiDi from a generated error-code map * [rb] declare RBS only for BiDi-only error classes to avoid redeclaring classic ones
…DEO_SESSION_SUBFOLDER (SeleniumHQ#17856) Signed-off-by: Viet Nguyen Duc <nguyenducviet4496@gmail.com>
…SeleniumHQ#17859) * [rb] add exception-aware pending_if guard matching * [rb] keep pending_exception_guard spec deterministic under SKIP_PENDING
…LE is set (SeleniumHQ#17858) [dotnet][java][py][rb] pass --enable-chrome-logs unless CHROME_LOG_FILE is set or on Windows (SeleniumHQ#16201)
…eleniumHQ#17862) * [rb] add add_chromium_option/add_firefox_option escape hatches and merge hand-built vendor options * [rb] normalize vendor option names to string keys
…eleniumHQ#17861) * [rb] validate BiDi outbound ref fields against their declared type * [rb] reject a non-variant object at a scalar-arm BiDi union * [rb] validate BiDi union bare-scalar arms against their schema literals
…17863) * [rb] capture log matcher output under SE_DEBUG and keep service specs env-agnostic * [rb] drop the SE_DEBUG output lock in the spec log-capture helper
… schema (SeleniumHQ#17864) [bidi] derive per-type inbound/outbound directionality in the shared schema
Co-authored-by: Navin Chandra <navinchandra772@gmail.com>
…#17866) * [build] test JavaScript on oldest and newest supported Node and publish on npm 11 * [build] run JavaScript unit tests on pull requests
Update pinned browser versions Co-authored-by: Selenium CI Bot <selenium-ci@users.noreply.github.com>
github-actions
Bot
force-pushed
the
pinned-browser-updates
branch
from
August 4, 2026 18:55
0a2c00e to
1f33f88
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This is an automated pull request to update pinned browsers and drivers