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 +4 -4
- data/README.md +75 -9
- data/lib/capybara/simulated/browser.rb +410 -72
- data/lib/capybara/simulated/driver.rb +92 -13
- data/lib/capybara/simulated/errors.rb +7 -0
- data/lib/capybara/simulated/js/bridge.bundle.js +402 -51
- data/lib/capybara/simulated/node.rb +19 -3
- data/lib/capybara/simulated/runtime_shared.rb +10 -0
- data/lib/capybara/simulated/v8_runtime.rb +64 -9
- data/lib/capybara/simulated/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 692a6a8f67870e2078ba815a0698831f3cec4ada4dc3d79d9af795156107e37b
|
|
4
|
+
data.tar.gz: 734a4cfe94f4cd93367b95082619e10729cb4ebf1f83a890b4d87c78ce5fd3cf
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|
-
- **
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
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
|
|