capybara-lightpanda 0.11.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6b898fd26a9e25f95263b605f022264cd2a132bbca82081bd931fe542c88673e
4
- data.tar.gz: 4776e1326f56cd6f123538b130dfb7de1edb1a745a45574e31520a1a5227ce94
3
+ metadata.gz: 2515195575d1146f7cd14f479801360770c65d39d84c2bdc58be987e503bda88
4
+ data.tar.gz: ab94aba998ccafb870e109504e7f33dd22a35bcd2ba79750cfd2bb79226feaf1
5
5
  SHA512:
6
- metadata.gz: 025d4fd23a6f0b4379c6e34d878610b657a06dcf33ab5490b606e5e42ed2e452475860283df232f8c397bbf1b48144f0d89be33bf7e5a70fe430a14e26bfb1a7
7
- data.tar.gz: 16193011f9ea880c74300a45491ab5dbe36abe55e0a080fe1f65edf36d9722daf6e9842de361f498068952970f3f2d975a64d8b92eb8ecaf2600c01b342caf34
6
+ metadata.gz: 3eadd479f7c543354a89c3f69a1be6ee94be6067b52171766c3da1b3c9b091a9e404c987e9af11c5230c89e8df319013822748b0bd6ba0e7e56ebd143f3e7689
7
+ data.tar.gz: fec1bbad25a59b177b6ac117e82bf65eef995196f233aa96742f71b2def90133132b913c0591bf40f2ca554d09cb4e6b26cbb132a0f3ae5e7ab811efa4504914
data/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.12.0] - 2026-08-28
4
+
5
+ > **Update Lightpanda before upgrading.** This release requires a Lightpanda nightly build ≥ 8875, and the rolling `nightly` tag now carries it (8982 as of 2026-08-28), so updating the browser is all it takes. **No tagged Lightpanda release is new enough yet**: 0.3.7 is below the floor, so version pinning stays unavailable until Lightpanda ships its next release.
6
+
7
+ ### Added
8
+
9
+ - **The keyboard activates things.** Pressing Enter on a button, link or submit input — and Space on a button, checkbox or radio — now does what it does in a real browser: the control activates, forms submit, checkboxes toggle. Previously `send_keys(:enter)` and `send_keys(:space)` were silently ignored on those controls, so keyboard-accessibility specs passed by doing nothing. Printable keys also emit `keypress` now, and a handler that cancels `keypress` correctly suppresses Enter's implicit form submission.
10
+ - **A closed `<dialog>` is properly hidden.** Text and controls inside a `<dialog>` that has never been opened no longer match Capybara's default visibility filter. Suites using the `<dialog>`-as-confirmation idiom (Turbo, Spree 5's admin) could previously "find" and click a confirm button that was not on screen — passing where Chrome would have raised `ElementNotFound`.
11
+ - **Uppercase inline styles hide elements.** `style="display: NONE"` and `style="visibility: HIDDEN"` are now treated as hidden, matching the CSS spec's case-insensitive keywords. Legacy templates and CMS output that upcase keywords no longer read as visible.
12
+ - **`ws_url:` accepts `localhost`.** Connecting to an externally-managed Lightpanda over `ws://localhost:PORT/` works; previously only an IP literal such as `ws://127.0.0.1:PORT/` was accepted by the browser's handshake.
13
+
14
+ ### Fixed
15
+
16
+ - **Keyboard-triggered navigation is waited for.** Now that Enter activates a submit button, pressing it starts a real navigation — but `send_keys` returned without waiting for it, so the very next `current_url` (or any non-waiting assertion) could still report the previous page. Keystrokes now settle the page the same way a click does. As with a click, a navigation whose server round-trip is slow still needs one of Capybara's waiting matchers, such as `have_current_path`.
17
+
18
+ - **Iframes keep working when the browser stops loading them by default.** Lightpanda build 8946 turns off `<iframe>` and Web Worker loading unless asked: the parser still puts the iframe in the DOM, but no frame is ever created, so `within_frame` and `switch_to_frame` find nothing and report no cause. The driver now asks for both on every session, which holds today's behavior across the change and needs no newer browser — the request is understood by every build the gem supports. Nothing to configure. If you run the rolling nightly, take this before your browser passes 8946.
19
+
20
+ - **A browser you manage yourself is version-checked like one the gem spawns.** `ws_url:` was the only way into the driver that skipped the version floor: a Lightpanda too old for the gem connected happily, then failed further along as a CDP error naming neither the version nor the option that let it through. The driver now reads the version over CDP at connect and refuses anything below the floor, with the same message the spawn path produces. An endpoint that cannot report a version at all — a Lightpanda older than the command, or a Chrome pointed at by mistake — is refused for the same reason. `page.driver.browser.version`, `.nightly_build` and `.release` report the browser on this path now instead of returning `nil`.
21
+
3
22
  ## [0.11.0] - 2026-08-25
4
23
 
5
24
  > **Update Lightpanda before upgrading.** This release requires a Lightpanda nightly build ≥ 8796 (2026-08-25 or newer). **No tagged Lightpanda release is new enough yet**: 0.3.7 is below the floor and is now refused, so version pinning is unavailable until Lightpanda ships its next release — CI runs on the rolling nightly in the meantime.
data/README.md CHANGED
@@ -57,7 +57,7 @@ driven_by :lightpanda
57
57
  > Lightpanda is a headless agentic browser, not a layout engine. External `<link rel="stylesheet">` **are** fetched and applied (the gem enables this by default), and `@media` / `window.matchMedia()` evaluate against the `window_size` you configure — so a mobile-only CTA gated by `@media (max-width: …)` resolves at the width you ask for. What's missing is *layout*: nothing reflows, `getBoundingClientRect` stays synthetic, and there is no real scroll. Specs that assert on pixel geometry, scrolling, or screenshots — plus the two that catch people out, a second browser tab and a menu revealed purely by CSS `:hover` — should stay on Cuprite (or whichever full-browser driver you were already using). The [per-spec dual-driver setup](https://navidemad.github.io/capybara-lightpanda/docs/#dual-per-spec) routes that minority to Cuprite and the structural majority to Lightpanda for speed.
58
58
 
59
59
  > [!TIP]
60
- > For reproducible CI, pin the browser: `Capybara::Lightpanda::Binary.required_version = "0.3.8"`. (0.3.8 is the first release that will clear the gem's current floor, nightly build 8796 — until upstream tags it, the driver needs the rolling `nightly` tag.) Without a pin the driver tracks Lightpanda's rolling `nightly` tag, which moves under you. See [Pinning the browser version](https://navidemad.github.io/capybara-lightpanda/docs/#pinning).
60
+ > For reproducible CI, pin the browser: `Capybara::Lightpanda::Binary.required_version = "0.3.8"`. (0.3.8 is the first release that will clear the gem's current floor, nightly build 8875 — until upstream tags it, the driver needs the rolling `nightly` tag.) Without a pin the driver tracks Lightpanda's rolling `nightly` tag, which moves under you. See [Pinning the browser version](https://navidemad.github.io/capybara-lightpanda/docs/#pinning).
61
61
 
62
62
  ## Credits
63
63
 
@@ -73,28 +73,34 @@ module Capybara
73
73
  end
74
74
  end
75
75
 
76
- # Lightpanda binary version (e.g. "lightpanda 0.2.9 nightly.5267") and
77
- # parsed nightly build number, captured at Process startup. nil when
78
- # the gem is connecting to an externally-managed Lightpanda via ws_url.
76
+ # Lightpanda version string (e.g. "1.0.0-nightly.8925+a7bda0ea5") and its
77
+ # parsed build number. Learned from `lightpanda version` at Process
78
+ # startup on the spawn path, and from the CDP `LP.version` command when
79
+ # connecting to an externally-managed browser via ws_url — so these are
80
+ # populated either way, and a caller inspecting them does not have to
81
+ # know which path built the session.
79
82
  def version
80
- @process&.version
83
+ @process&.version || @remote_version
81
84
  end
82
85
 
83
86
  # Set on the nightly/dev channel only; nil for a tagged release, which
84
87
  # carries no build counter. `release` is its mirror image — exactly one of
85
- # the two is non-nil once the process has started.
88
+ # the two is non-nil once the session is up.
86
89
  def nightly_build
87
- @process&.nightly_build
90
+ @process&.nightly_build || @remote_nightly_build
88
91
  end
89
92
 
90
93
  def release
91
- @process&.release
94
+ @process&.release || @remote_release
92
95
  end
93
96
 
94
97
  def initialize(options = {})
95
98
  @options = Options.new(options)
96
99
  @process = nil
97
100
  @client = nil
101
+ @remote_version = nil
102
+ @remote_nightly_build = nil
103
+ @remote_release = nil
98
104
  @target_id = nil
99
105
  @session_id = nil
100
106
  @browser_context_id = nil
@@ -121,6 +127,7 @@ module Capybara
121
127
 
122
128
  if @options.ws_url?
123
129
  @client = Client.new(@options.ws_url, @options)
130
+ check_remote_version
124
131
  else
125
132
  @process = Process.new(@options)
126
133
  @process.start
@@ -152,6 +159,9 @@ module Capybara
152
159
  attach_result = @client.command("Target.attachToTarget", { targetId: @target_id, flatten: true })
153
160
  @session_id = attach_result["sessionId"]
154
161
 
162
+ # Must precede the first navigation: sub-resource loading is a
163
+ # per-BrowserContext setting read while the document loads.
164
+ configure_loading
155
165
  @turbo_event.set
156
166
  subscribe_to_console_logs
157
167
  subscribe_to_console_capture
@@ -498,6 +508,34 @@ module Capybara
498
508
 
499
509
  private
500
510
 
511
+ # Keep iframes and workers loading.
512
+ #
513
+ # Upstream #3305 (build 8946) turned `Config.LoadResources` into a
514
+ # four-field struct defaulting every sub-resource to false, so
515
+ # `Frame.iframeAddedCallback` now returns early unless `iframe` is set:
516
+ # the parser still registers the `<iframe>` in the DOM, but no child
517
+ # frame is ever created. That silently breaks `switch_to_frame` and
518
+ # Capybara's `within_frame` — core driver API, not an optional extra —
519
+ # and there is no CLI opt-in the gem can use below 8946, because the
520
+ # `--load-resources` *value* `iframe` only parses from that build.
521
+ #
522
+ # The `subFrame`/`worker` params predate #3305 and simply write a
523
+ # different field after it, which makes this the one form that spans the
524
+ # whole supported range: a no-op below 8946 where both already defaulted
525
+ # on, load-bearing above it, and no MINIMUM_NIGHTLY_BUILD bump either way.
526
+ #
527
+ # Workers are included to hold the gem's behavior still across the flip
528
+ # rather than to satisfy a feature we ship: a worker that silently never
529
+ # runs is the same debugging trap as an iframe that silently never loads.
530
+ #
531
+ # Not rescued on purpose. LP.configureLoading predates the floor by a
532
+ # wide margin, so a failure here means the endpoint is not a Lightpanda
533
+ # we understand, and swallowing it would restore the exact silence this
534
+ # call exists to prevent.
535
+ def configure_loading
536
+ page_command("LP.configureLoading", subFrame: true, worker: true)
537
+ end
538
+
501
539
  def register_auto_scripts
502
540
  page_command("Page.addScriptToEvaluateOnNewDocument", source: AutoScripts::JS)
503
541
  end
@@ -590,6 +628,44 @@ module Capybara
590
628
  end
591
629
  end
592
630
 
631
+ # Binary.update_hint would be a lie here: it prints a curl into a path the
632
+ # gem controls, and under ws_url the browser is somebody else's process on
633
+ # possibly another host.
634
+ REMOTE_UPDATE_HINT = "the gem does not manage that browser — " \
635
+ "update the Lightpanda serving ws_url yourself."
636
+ private_constant :REMOTE_UPDATE_HINT
637
+
638
+ # The spawn path runs `lightpanda version` before the browser is even up
639
+ # (Process#check_minimum_version). An externally-managed browser has no
640
+ # binary to shell out to, so the same floor is enforced over CDP instead:
641
+ # `LP.version` returns the identical string the CLI prints, and
642
+ # Process.check_version! is the one parser both channels share.
643
+ #
644
+ # Without this, `ws_url:` was the one way into the driver that skipped the
645
+ # floor entirely — an old browser connected happily and then failed later
646
+ # as an unrelated-looking CDP error, with nothing naming the real cause.
647
+ #
648
+ # A browser that cannot answer `LP.version` is refused rather than assumed
649
+ # new enough, matching the spawn path's rule that an unidentifiable binary
650
+ # never passes. Two things land here: a Lightpanda predating the LP domain,
651
+ # and a Chrome someone pointed ws_url at by mistake — the second being easy
652
+ # to do and previously diagnosable only by watching later commands fail.
653
+ #
654
+ # Only #start calls this. #reconnect deliberately does not: it re-dials the
655
+ # same endpoint, whose version cannot have changed, and the crash-recovery
656
+ # path should not spend a round-trip re-asking.
657
+ def check_remote_version
658
+ result = @client.command("LP.version")
659
+ @remote_version, @remote_nightly_build, @remote_release =
660
+ Process.check_version!(result["version"]) { REMOTE_UPDATE_HINT }
661
+ rescue BrowserError, TimeoutError => e
662
+ raise BinaryError,
663
+ "Could not read the Lightpanda version at #{@options.ws_url} " \
664
+ "(LP.version failed: #{e.message}). ws_url: must point at a " \
665
+ "Lightpanda CDP endpoint new enough to answer LP.version; the gem " \
666
+ "cannot verify a browser it does not manage."
667
+ end
668
+
593
669
  def restart_process_if_dead
594
670
  return unless @process && !@process.alive?
595
671
 
@@ -256,9 +256,25 @@ module Capybara
256
256
  raise Capybara::UnselectNotAllowed, "Cannot unselect option from single select box."
257
257
  end
258
258
 
259
+ # The trailing `wait_for_idle` mirrors #click, and for the same reason.
260
+ # Since upstream #3264 (build >= 8842) `Input.dispatchKeyEvent` builds a
261
+ # *trusted* KeyboardEvent, so Enter on a submit input / <a href> and
262
+ # Space on a button or checkbox synthesize a real activation click —
263
+ # which means a keystroke can now start a navigation. Before #3264 it
264
+ # could not, which is why this settle step was historically absent; its
265
+ # absence then showed up as `current_url` being read against the
266
+ # outgoing document (test/features/keyboard_activation_test.rb).
267
+ #
268
+ # Caveat, shared with #click: `wait_for_idle` only sniffs for ~50 ms
269
+ # (Browser::SNIFF_WINDOW) and watches Runtime.executionContextsCleared,
270
+ # which Lightpanda emits when the *response* lands, not when the request
271
+ # starts. A navigation whose server round-trip exceeds that window is
272
+ # therefore still not awaited here — use Capybara's waiting matchers
273
+ # (`have_current_path`) for those, as you would after a click.
259
274
  def send_keys(*)
260
275
  call("function() { this.focus() }")
261
276
  driver.browser.keyboard.type(*)
277
+ driver.browser.wait_for_idle
262
278
  end
263
279
 
264
280
  def tag_name
@@ -201,7 +201,37 @@ module Capybara
201
201
  # this bump — and drag events carry integer clientX/Y (the shared spec
202
202
  # asserting that runs un-skipped). Build 8796 = the #3259 merge
203
203
  # (341a01570), which is also the 2026-08-25 nightly cut.
204
- MINIMUM_NIGHTLY_BUILD = Gem::Version.new("8796")
204
+ #
205
+ # 2026-08-26 bump 8796 -> 8875, four fixes the gem now asserts on:
206
+ # #3264 (8842) CDP Input.dispatchKeyEvent builds a *trusted*
207
+ # KeyboardEvent, so frame/user_input.zig fires `keypress` on
208
+ # printable/Enter keydowns and synthesizes a trusted PointerEvent
209
+ # click for Enter on <button>/<a href>/input[submit|button|reset|
210
+ # image] and Space-keyup on those plus checkbox/radio. That click is
211
+ # a real activation event (PointerEvent.Proto = MouseEvent), so
212
+ # Node#send_keys(:enter) submits/navigates and send_keys(:space)
213
+ # toggles a checkbox — both were no-ops below 8842. No gem code
214
+ # drives it; Keyboard never sends CDP `type: "char"`, so nothing
215
+ # double-fires. Pinned by test/features/keyboard_activation_test.rb.
216
+ # #3269 (8868) adds `dialog:not([open]) { display: none }` to the
217
+ # UA-stylesheet truth checkVisibility() and getComputedStyle().display
218
+ # share, so a closed <dialog> AND its subtree read as non-visible.
219
+ # Below 8868 Capybara matched text and controls inside a never-opened
220
+ # dialog. Pinned by test/features/upstream_bugs_test.rb (Bug #4).
221
+ # #3270 (8857) inline-style keyword matching in checkVisibility /
222
+ # getComputedStyle is case-insensitive for display / visibility /
223
+ # opacity / pointer-events, so `style="display: NONE"` hides.
224
+ # Feeds _lightpanda.isVisible. Pinned by visibility_keywords_test.rb.
225
+ # #3256 (8875) the CDP WS handshake accepts the exact lowercase
226
+ # `Host: localhost:<port>` form (bare `localhost`, `LOCALHOST:<port>`
227
+ # and `localhost.evil.com:<port>` still 403). Below 8875 only an IP
228
+ # literal passed, so a user-supplied `ws_url:` had to say 127.0.0.1.
229
+ # Pinned by test/features/ws_url_host_test.rb.
230
+ # Build 8875 = the #3256 merge (f2169836e). NOTE: this floor leads the
231
+ # nightly channel — the 2026-08-26 nightly is 8855 — so it lands with the
232
+ # next nightly cut. #3267 (8880, Authorization stripped on cross-origin
233
+ # redirects) arrives with the same floor but drives nothing gem-side.
234
+ MINIMUM_NIGHTLY_BUILD = Gem::Version.new("8875")
205
235
 
206
236
  # Second, equivalent floor for the *release* channel.
207
237
  #
@@ -210,15 +240,15 @@ module Capybara
210
240
  # bare "0.3.6" carrying no commit counter at all, and MINIMUM_NIGHTLY_BUILD
211
241
  # has nothing to compare against. Releases are cut from the same trunk, so
212
242
  # a release is acceptable exactly when its own commit count clears the
213
- # nightly floor. As of 2026-08-25 NO published release clears the 8796
214
- # floor — 0.3.7 (build 8671) predates the draggable-IDL and
215
- # coordinate-flooring fixes the floor exists for so this pin names the
216
- # NEXT release. 0.3.8 is not tagged yet; any future tag is cut from a
217
- # trunk already past build 8834, so it clears the floor by construction.
218
- # Until upstream tags it, the release channel is deliberately unusable
219
- # (nightly-only), reported with the standard too-old error. When 0.3.8
220
- # ships: verify `git rev-list --count 0.3.8` >= 8796 and update the
221
- # lockstep table in process_test.rb.
243
+ # nightly floor. As of 2026-08-26 NO published release clears the 8875
244
+ # floor — 0.3.7 (build 8671) predates every fix the floor exists for — so
245
+ # this pin names the NEXT release. 0.3.8 is not tagged yet; any future tag
246
+ # is cut from a trunk already past build 8886, so it clears the floor by
247
+ # construction. Until upstream tags it, the release channel is
248
+ # deliberately unusable (nightly-only), reported with the standard
249
+ # too-old error. When 0.3.8 ships: verify
250
+ # `git rev-list --count 0.3.8` >= 8875 and update the lockstep table in
251
+ # process_test.rb.
222
252
  #
223
253
  # INVARIANT: every MINIMUM_NIGHTLY_BUILD bump must also move this to the
224
254
  # first release containing that build (`git rev-list --count <tag>` in the
@@ -226,6 +256,56 @@ module Capybara
226
256
  # silently accept a binary the nightly channel rejects.
227
257
  MINIMUM_RELEASE = Gem::Version.new("0.3.8")
228
258
 
259
+ class << self
260
+ # `lightpanda version` prints one of two shapes, and the gem supports
261
+ # both so a suite can either track nightly or pin a reproducible
262
+ # release:
263
+ #
264
+ # "1.0.0-nightly.8285+de85a51d" rolling nightly (also "dev.NNNN" for
265
+ # a locally compiled tree — same
266
+ # `git rev-list --count HEAD` counter,
267
+ # different label). Checked against
268
+ # MINIMUM_NIGHTLY_BUILD.
269
+ # "0.3.5" a tagged release: bare semver, no
270
+ # build metadata. Checked against
271
+ # MINIMUM_RELEASE.
272
+ #
273
+ # The release form is matched anchored — a bare semver and nothing else
274
+ # — so a stray "1.2.3" inside some other string can never be mistaken
275
+ # for a release. Anything that matches neither shape stays a hard
276
+ # failure: a version we cannot identify is never assumed to be new
277
+ # enough.
278
+ #
279
+ # Lives on the class, not the instance, because there are two ways to
280
+ # learn a version and only one of them involves a Process: the spawn
281
+ # path shells out to the binary, while an externally-managed browser
282
+ # (`ws_url:`) is asked over CDP. `LP.version` returns the identical
283
+ # string the CLI prints, so both channels share this one parser rather
284
+ # than drifting apart — the drift being how `ws_url:` shipped with no
285
+ # floor check at all.
286
+ #
287
+ # Returns [version, nightly_build, release]; exactly one of the latter
288
+ # two is non-nil. The update hint is yielded rather than passed so the
289
+ # caller's hint-building only runs on the failure path.
290
+ def check_version!(raw)
291
+ version = raw.to_s.strip
292
+
293
+ if (build = version[/(?:nightly|dev)\.(\d+)/, 1])
294
+ nightly_build = Gem::Version.new(build)
295
+ return [version, nightly_build, nil] if nightly_build >= MINIMUM_NIGHTLY_BUILD
296
+ elsif (tag = version[/\A\d+\.\d+\.\d+\z/])
297
+ release = Gem::Version.new(tag)
298
+ return [version, nil, release] if release >= MINIMUM_RELEASE
299
+ end
300
+
301
+ raise BinaryError,
302
+ "Lightpanda #{version} is too old. " \
303
+ "This gem requires nightly build >= #{MINIMUM_NIGHTLY_BUILD} " \
304
+ "or release >= #{MINIMUM_RELEASE}. " \
305
+ "Update: #{yield}"
306
+ end
307
+ end
308
+
229
309
  attr_reader :pid, :ws_url, :version, :nightly_build, :release
230
310
 
231
311
  def initialize(options)
@@ -273,38 +353,12 @@ module Capybara
273
353
 
274
354
  private
275
355
 
276
- # `lightpanda version` prints one of two shapes, and the gem supports both
277
- # so a suite can either track nightly or pin a reproducible release:
278
- #
279
- # "1.0.0-nightly.8285+de85a51d" rolling nightly (also "dev.NNNN" for a
280
- # locally compiled tree — same
281
- # `git rev-list --count HEAD` counter,
282
- # different label). Checked against
283
- # MINIMUM_NIGHTLY_BUILD.
284
- # "0.3.5" a tagged release: bare semver, no build
285
- # metadata. Checked against MINIMUM_RELEASE.
286
- #
287
- # The release form is matched anchored — a bare semver and nothing else —
288
- # so a stray "1.2.3" inside some other string can never be mistaken for a
289
- # release. Anything that matches neither shape stays a hard failure: a
290
- # binary we cannot identify is never assumed to be new enough.
356
+ # Shells the floor check out to the binary. The ws_url path can't — see
357
+ # Browser#check_remote_version, which feeds the same parser from CDP.
291
358
  def check_minimum_version(binary_path)
292
359
  stdout, = Open3.capture3(binary_path, "version")
293
- @version = stdout.strip
294
-
295
- if (build = @version[/(?:nightly|dev)\.(\d+)/, 1])
296
- @nightly_build = Gem::Version.new(build)
297
- return if @nightly_build >= MINIMUM_NIGHTLY_BUILD
298
- elsif (tag = @version[/\A\d+\.\d+\.\d+\z/])
299
- @release = Gem::Version.new(tag)
300
- return if @release >= MINIMUM_RELEASE
301
- end
302
-
303
- raise BinaryError,
304
- "Lightpanda #{@version} is too old. " \
305
- "This gem requires nightly build >= #{MINIMUM_NIGHTLY_BUILD} " \
306
- "or release >= #{MINIMUM_RELEASE}. " \
307
- "Update: #{Binary.update_hint(binary_path)}"
360
+ @version, @nightly_build, @release =
361
+ self.class.check_version!(stdout) { Binary.update_hint(binary_path) }
308
362
  rescue Errno::ENOENT
309
363
  # Binary not runnable — let attempt_start handle it
310
364
  end
@@ -371,7 +425,7 @@ module Capybara
371
425
  "info",
372
426
  # External stylesheet fetch (PR #2487, build >= 6353 — enforced by the
373
427
  # floor). Always on so linked CSS contributes to checkVisibility /
374
- # getComputedStyle; see .claude/rules/lightpanda-io.md limitation #6.
428
+ # getComputedStyle; see .claude/rules/lightpanda-io.md limitation #5.
375
429
  "--enable-external-stylesheets",
376
430
  # Raise the inbound CDP WebSocket message cap from Lightpanda's 1 MiB
377
431
  # default (Config.zig `cdp_max_message_size`) to 100 MiB, matching
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Capybara
4
4
  module Lightpanda
5
- VERSION = "0.11.0"
5
+ VERSION = "0.12.0"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: capybara-lightpanda
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.0
4
+ version: 0.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Navid Emad