capybara-simulated 0.0.2 → 0.0.4

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: 2a1b71c5bedf4ee1236631f583accd90b10e71317c00e5b20252c5b8f48477ea
4
- data.tar.gz: b1b3a3bb91e784b579cb4d465f253ed78c3bb606ef9629afe2197693114fa10b
3
+ metadata.gz: edfc03fddab459b5cace9bb3bb3b05ba0ff48adc978eb2c8b401d9311f62d569
4
+ data.tar.gz: 74237a169f1ce04b4fa579936f86622fab1f6fa98190d81bf98caf72974cbcb5
5
5
  SHA512:
6
- metadata.gz: ba4e4836908d7f607c475321edc01592b89e53df666e531330e4283725633201622461df829b4e40c37f1ad9ba5d67d74e71fbaef14efda60c11ec7abaa6441c
7
- data.tar.gz: d6ecc0867f4ae527d483c337a7129e65e6f31fd24a5c507247df66ddb89ac1eeb98060101868f3e43f787caea6e1ad35390afd94504aff8c7f05b095fcaa1a09
6
+ metadata.gz: 80e00f33f9994046daaa5e62b6b08e1b5db4ac425bb94761f8aaa0d9be328fd9ff292f43459d1dd51a2e10a0f20e217f399ce71815d2076cbe121cda0ed29791
7
+ data.tar.gz: 8d0d3309b0bfb141040005a535bef99fa97a01aaf81b7f1e6b247997f9d13b0ae821d6ce53c8ba3ea62e2c10c2aa7b140a0d369e7ebe6bf77c331a58cc5de3ae
data/README.md CHANGED
@@ -12,15 +12,15 @@ forms submit through `Rack::MockRequest`.
12
12
 
13
13
  ## Status
14
14
 
15
- PoC. Against Capybara 3.40's shared `Capybara::SpecHelper.spec` suite the
15
+ Used in production by a Rails 8 app to run ~200 `js: true` system specs
16
+ without spawning a headless Chrome.
17
+
18
+ Against Capybara 3.40's shared `Capybara::SpecHelper.spec` suite the
16
19
  driver passes **1337 / 1357 examples (98.5%)** with the unsupported-
17
20
  capability tags `about_scheme`, `css`, `download`, `frames`, `hover`,
18
21
  `screenshot`, `scroll`, `server`, `spatial`, `windows` filtered out.
19
- Tags that started skipped but now pass: `active_element`, `modals`
20
- (alert/confirm/prompt incl. nested + page-change + async),
21
- `html_validation`, `send_keys`, `shadow_dom`. The remaining 20
22
- failures all need capabilities the driver intentionally does not
23
- implement:
22
+ The remaining 20 failures all need capabilities the driver intentionally
23
+ does not implement:
24
24
 
25
25
  - 19 `#drag_to` tests — Dragula / SortableJS / jsTree resolve drop
26
26
  targets through `elementFromPoint(clientX, clientY)`, which needs a
@@ -541,7 +541,13 @@ module Capybara
541
541
  entries = Array(details['entries'])
542
542
  return if importmap.empty? && entries.empty?
543
543
 
544
- cache_key = Digest::SHA256.hexdigest(JSON.dump([importmap, entries, @current_url]))
544
+ # Importmap + module-script entries are page-content-derived, so
545
+ # keying on them alone covers different pages of the same Rails app
546
+ # — the bundle output is identical when the inputs are. Including
547
+ # `@current_url` only suppressed cache hits across visits without
548
+ # buying any correctness; build_module_bundle was the single biggest
549
+ # cost in the suite (52% of wall time on a hot test).
550
+ cache_key = Digest::SHA256.hexdigest(JSON.dump([importmap, entries]))
545
551
  @module_bundle_cache ||= {}
546
552
  bundle = @module_bundle_cache[cache_key] ||=
547
553
  build_module_bundle(importmap, entries)
@@ -1,5 +1,5 @@
1
1
  module Capybara
2
2
  module Simulated
3
- VERSION = '0.0.2'
3
+ VERSION = '0.0.4'
4
4
  end
5
5
  end
data/vendor/js/runtime.js CHANGED
@@ -1987,6 +1987,12 @@
1987
1987
  // Custom DOM facade for fontoxpath that uses childNodes-based traversal
1988
1988
  // so happy-dom quirks around sibling links don't break root-anchored
1989
1989
  // queries. Mirrors the helper we built for linkedom.
1990
+ // fontoxpath calls into this facade tens of thousands of times per
1991
+ // traversal, so each method needs to delegate to happy-dom's native
1992
+ // pointers rather than reconstructing them. Earlier revisions of
1993
+ // getNextSibling / getPreviousSibling rebuilt childNodes via
1994
+ // Array.from(parent.childNodes) and then indexOf'd the node — quadratic
1995
+ // in tree size, and the dominant cost on any non-trivial page.
1990
1996
  const xpathDomFacade = {
1991
1997
  getAllAttributes(node) {
1992
1998
  if (!node || node.nodeType !== 1 || !node.attributes) return [];
@@ -2006,31 +2012,30 @@
2006
2012
  if (node.nodeType === 2) return node.value || '';
2007
2013
  return node.data || '';
2008
2014
  },
2015
+ // happy-dom 20 has a quirk on `<template>`: `template.childNodes` is
2016
+ // empty (the parsed content lives in `template.content`) but
2017
+ // `template.firstChild` / `template.lastChild` still return the first
2018
+ // text node of `template.content`. Walking into that ghost child
2019
+ // makes fontoxpath traverse content as if it were a regular descendant,
2020
+ // which scrambles every predicate downstream. Verify against
2021
+ // childNodes.length before trusting firstChild / lastChild.
2009
2022
  getFirstChild(node) {
2010
- const cs = this.getChildNodes(node);
2011
- return cs.length ? cs[0] : null;
2023
+ const fc = node?.firstChild ?? null;
2024
+ if (!fc) return null;
2025
+ const cs = node.childNodes;
2026
+ if (cs && cs.length === 0) return null;
2027
+ return fc;
2012
2028
  },
2013
2029
  getLastChild(node) {
2014
- const cs = this.getChildNodes(node);
2015
- return cs.length ? cs[cs.length - 1] : null;
2030
+ const lc = node?.lastChild ?? null;
2031
+ if (!lc) return null;
2032
+ const cs = node.childNodes;
2033
+ if (cs && cs.length === 0) return null;
2034
+ return lc;
2016
2035
  },
2017
- getNextSibling(node) {
2018
- const parent = this.getParentNode(node);
2019
- if (!parent) return null;
2020
- const cs = this.getChildNodes(parent);
2021
- const i = cs.indexOf(node);
2022
- return (i >= 0 && i + 1 < cs.length) ? cs[i + 1] : null;
2023
- },
2024
- getPreviousSibling(node) {
2025
- const parent = this.getParentNode(node);
2026
- if (!parent) return null;
2027
- const cs = this.getChildNodes(parent);
2028
- const i = cs.indexOf(node);
2029
- return (i > 0) ? cs[i - 1] : null;
2030
- },
2031
- getParentNode(node) {
2032
- return node ? node.parentNode || null : null;
2033
- }
2036
+ getNextSibling(node) { return node?.nextSibling ?? null; },
2037
+ getPreviousSibling(node) { return node?.previousSibling ?? null; },
2038
+ getParentNode(node) { return node?.parentNode ?? null; }
2034
2039
  };
2035
2040
 
2036
2041
  function findViaXPathFallback(xpath, root) {
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: capybara-simulated
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Keita Urashima