capybara-simulated 0.1.1 → 0.2.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: 8f13ed6ad46dbf9e9537d89bc384c5ef7386242fa28c9e4fc549b1fda04fd7d8
4
- data.tar.gz: 2cd0e24a3eb808728d7a533369b3ac2beafc99accf8fa4c1ec9f9b4af1b60f03
3
+ metadata.gz: 692a6a8f67870e2078ba815a0698831f3cec4ada4dc3d79d9af795156107e37b
4
+ data.tar.gz: 734a4cfe94f4cd93367b95082619e10729cb4ebf1f83a890b4d87c78ce5fd3cf
5
5
  SHA512:
6
- metadata.gz: b26b98c5b972110458565e0a60b6292cd6a446e331636d662e34aed1a4c9456a130aa67f52499f4954820c30a0b9ae22dff2870b25f50556bb577a37a719b042
7
- data.tar.gz: cf2cb128d6187eff1fa4c3fd06b928e933cbc1d4c0ec062f4885f3bd31ad847136e8736e604879e0fdb9eba629647802133265d596e3abc451238f499dfb0be3
6
+ metadata.gz: 9c9bfde944aad7339e4d7153e2d49b3b6834662fc5bcaf945a63899ca580493d1c67bfbd625ce7e06683bdbfacab83fa8192af7f02a73d5228f080dc22fc1dda
7
+ data.tar.gz: da6971ee07edd867e00baa4e6d382ff291d5d0c8c437084f6f4d7dba50ae5c0596e4726db9be58f1d7a6847340fccff847d06d0056fdb8de3847a703887a4c28
data/README.md CHANGED
@@ -14,6 +14,57 @@ resolve through css-select (CSS) and xpathway (XPath) running in the
14
14
  same context as the page's JS, so `find` / `has_css?` / `within` see
15
15
  exactly the tree the app sees.
16
16
 
17
+ ## Is it a fit?
18
+
19
+ **A good fit when** your tests are JavaScript-driven but don't depend on
20
+ visual layout:
21
+
22
+ - **Fast, in-process** — no Chrome to boot, no WebDriver, no Node
23
+ toolchain. About **1.9× faster** than a headless browser on
24
+ server-rendered / Hotwire apps, and roughly at parity on JS-heavy SPAs
25
+ (with rusty_racer).
26
+ - **Deterministic** — a virtual clock and synchronous in-process execution
27
+ remove the wall-clock timing, network, and rendering races that make
28
+ headless-browser suites flaky.
29
+ - **Real front-end JS runs**: inline `<script>` + event handlers,
30
+ MutationObserver, custom elements, `<template>`, Shadow DOM, ES modules
31
+ + importmap, **Hotwire (Stimulus + Turbo)**, Trix.
32
+ - **Drop-in**: the Capybara DSL is unchanged — register `:simulated` and
33
+ go. Just this gem plus one JS-engine gem.
34
+ - **Held to spec**: a vendored
35
+ [web-platform-tests](https://github.com/web-platform-tests/wpt)
36
+ conformance gate plus five real app suites (see [Status](#status)).
37
+
38
+ **Reach for a real browser** (Selenium / Cuprite) **when** your tests need
39
+ what this driver doesn't simulate **by design** — there's no rendering
40
+ engine or real network stack, the same ground Selenium covers via a real
41
+ browser:
42
+
43
+ - **Pixel layout** — `getBoundingClientRect()` returns zeros and
44
+ `elementFromPoint()` isn't implemented, so visual hit-testing,
45
+ coordinate drag-and-drop, and sticky-scroll math don't work.
46
+ - **Real networking** — `fetch` / XHR are synchronous through Rack: no
47
+ streaming, no concurrency, no WebSocket.
48
+ - **Screenshots**.
49
+
50
+ **`within_frame` / `switch_to_frame`** work on the V8 (rusty_racer) engine:
51
+ each `<iframe>` runs its own scripts in its own per-frame realm, and the DSL
52
+ routes finds, reads, interactions, `evaluate_script`, and self-targeted
53
+ navigation (a link or form submit inside the frame) into the active frame —
54
+ nested frames included. (QuickJS keeps a same-realm fallback, so
55
+ `within_frame` is V8-only.)
56
+
57
+ **Multiple windows / tabs** work on both engines: each window is its own
58
+ Browser + JS VM (own DOM, sessionStorage, history; cookies + localStorage
59
+ shared). `open_new_window` / `within_window` / `switch_to_window` /
60
+ `window_opened_by` drive them, and JS `window.open` opens a real window,
61
+ `window.opener` points back to the opener, and `postMessage` is delivered
62
+ across windows. (`target="_blank"` defaults to no-opener, matching modern
63
+ browsers; cross-window `postMessage` data is JSON-shaped, not a full
64
+ structured clone.)
65
+
66
+ See [Known limits](#known-limits) for the full picture.
67
+
17
68
  ## Status
18
69
 
19
70
  The architecture and behaviour are stable. Correctness is held to two
@@ -305,15 +356,30 @@ referenced page-specific DOM.
305
356
  but there's no real network, no streaming, no `Request#body`
306
357
  ReadableStream, and no concurrent requests. XHR is implemented
307
358
  with the same Rack pass-through.
308
- - **Multi-window** is URL-tracking only `target="_blank"` clicks
309
- open a window-handle and `current_window` / `switch_to_window`
310
- work, but each aux window only records its URL (no per-window JS
311
- context or cross-window `postMessage`).
312
- - **`within_frame`, WebSocket, screenshots, and drag pixel
313
- coordinates** are out of scope — use Selenium / Cuprite. There's no
314
- frame-switching DSL to drive a test into an `<iframe>`, though an
315
- iframe's own scripts do run, in a per-frame JS realm. (EventSource
316
- and Web Workers *are* implemented.)
359
+ - **WebSocket, screenshots, and drag pixel coordinates** are out of
360
+ scope by design use Selenium / Cuprite. (EventSource and Web
361
+ Workers *are* implemented.)
362
+ - **`within_frame` / `switch_to_frame`** work on the V8 engine: each
363
+ `<iframe>` runs in its own per-frame realm and the DSL routes finds,
364
+ reads, interactions, `evaluate_script`, and self-targeted navigation
365
+ (link / form submit) into the active frame (nested frames included) — the
366
+ frame's realm is rebuilt from the fetched document, leaving the top page
367
+ untouched. `_top` navigates the main page; a `_parent` target from a
368
+ frame nested ≥2 levels falls back to navigating the main page, and
369
+ cross-origin frame locality resolves against the main origin. QuickJS has
370
+ no nested browsing context, so `within_frame` raises there.
371
+ - **Multiple windows / tabs** work on both engines: each window is its own
372
+ Browser + JS VM (own DOM, sessionStorage, history; cookies + localStorage
373
+ shared across windows). `open_new_window` / `within_window` /
374
+ `switch_to_window` / `window_opened_by` drive them; JS `window.open` opens
375
+ a real window, `window.opener` links back, and `postMessage` is routed
376
+ across windows (delivered as a `message` event when the target window next
377
+ settles). Caveats: `target="_blank"` opens with no opener (modern-browser
378
+ no-opener default); cross-window `postMessage` data is JSON-shaped, not a
379
+ full structured clone (no `DataCloneError`, `undefined`→`null`); and only
380
+ the active window's event loop runs, so a message is delivered when you
381
+ switch to its window. Window viewport APIs (`maximize` / `fullscreen` /
382
+ pixel-exact `resize_to`) are no-ops — no layout engine.
317
383
 
318
384
  ## Architecture
319
385