capybara-simulated 0.0.5 → 0.0.6

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.
data/vendor/js/entry.mjs CHANGED
@@ -1,8 +1,23 @@
1
- // Bundle entry: brings happy-dom and an XPath engine into one IIFE that
2
- // exposes them on a single `__csim_bundle` global. happy-dom does not
3
- // implement document.evaluate, so we layer fontoxpath on top.
1
+ // Bundle entry: brings happy-dom + wgxpath into one IIFE that exposes them
2
+ // on a single `__csim_bundle` global. happy-dom does not implement
3
+ // `document.evaluate`, so wgxpath layers it onto `Document.prototype`.
4
4
  import {Window} from 'happy-dom';
5
5
  import {URL, URLSearchParams} from 'whatwg-url';
6
- import {evaluateXPathToNodes} from 'fontoxpath';
6
+ import wgxpath from 'wicked-good-xpath';
7
7
 
8
- export {Window, URL, URLSearchParams, evaluateXPathToNodes};
8
+ // happy-dom 20's `document` is an `HTMLDocument` instance and the proto
9
+ // chain doesn't include `Document.prototype` (where wgxpath plants
10
+ // `evaluate` / `createExpression` / `createNSResolver`). Mirror the three
11
+ // methods onto `HTMLDocument.prototype` so `document.evaluate` works.
12
+ function installXPath(win) {
13
+ wgxpath.install(win, /* opt_force */ true);
14
+ if (win.HTMLDocument && win.Document) {
15
+ for (const m of ['evaluate', 'createExpression', 'createNSResolver']) {
16
+ if (win.Document.prototype[m] && !win.HTMLDocument.prototype[m]) {
17
+ win.HTMLDocument.prototype[m] = win.Document.prototype[m];
18
+ }
19
+ }
20
+ }
21
+ }
22
+
23
+ export {Window, URL, URLSearchParams, installXPath};
data/vendor/js/runtime.js CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  (function () {
7
7
  const {Window, URL: WhatwgURL, URLSearchParams: WhatwgURLSearchParams,
8
- evaluateXPathToNodes} = globalThis.__csim_bundle;
8
+ installXPath} = globalThis.__csim_bundle;
9
9
  if (!globalThis.URL) globalThis.URL = WhatwgURL;
10
10
  if (!globalThis.URLSearchParams) globalThis.URLSearchParams = WhatwgURLSearchParams;
11
11
 
@@ -170,6 +170,7 @@
170
170
  installValidationMessages(win);
171
171
  installMutationObserverPin(win);
172
172
  installAttrNodeValue(win);
173
+ installXPath(win);
173
174
  }
174
175
 
175
176
  // happy-dom 20's `Attr` class implements `value` / `textContent` / `name`
@@ -963,7 +964,6 @@
963
964
  patchWindowGlobals(win);
964
965
  installFetchShim(win);
965
966
  installCustomElementUpgrade(win);
966
- installDocumentEvaluate(win.document);
967
967
  installHistoryTracking(win);
968
968
  currentWindow = win;
969
969
  currentDocument = win.document;
@@ -1257,11 +1257,14 @@
1257
1257
  const fast = tryFastXPath(xpath, root);
1258
1258
  if (fast) return fast.map(track);
1259
1259
  try {
1260
- const nodes = evaluateXPathToNodes(xpath, root, xpathDomFacade, null, {
1261
- // happy-dom places elements in the XHTML namespace.
1262
- namespaceResolver: () => 'http://www.w3.org/1999/xhtml'
1263
- });
1264
- return nodes.map(track);
1260
+ const result = currentDocument.evaluate(
1261
+ xpath, root, null,
1262
+ /* UNORDERED_NODE_ITERATOR_TYPE */ 4, null
1263
+ );
1264
+ const ids = [];
1265
+ let n;
1266
+ while ((n = result.iterateNext())) ids.push(track(n));
1267
+ return ids;
1265
1268
  } catch (e) {
1266
1269
  return findViaXPathFallback(xpath, root);
1267
1270
  }
@@ -1955,111 +1958,6 @@
1955
1958
  wrap('replaceState');
1956
1959
  }
1957
1960
 
1958
- // happy-dom does not implement `document.evaluate`. Capybara internals
1959
- // and user scripts both reach for it occasionally. Polyfill it on top of
1960
- // fontoxpath so callers see W3C XPathResult semantics.
1961
- function installDocumentEvaluate(doc) {
1962
- if (typeof doc.evaluate === 'function') return;
1963
- const ANY_TYPE = 0;
1964
- const NUMBER_TYPE = 1;
1965
- const STRING_TYPE = 2;
1966
- const BOOLEAN_TYPE = 3;
1967
- const UNORDERED_NODE_ITERATOR_TYPE = 4;
1968
- const ORDERED_NODE_ITERATOR_TYPE = 5;
1969
- const UNORDERED_NODE_SNAPSHOT_TYPE = 6;
1970
- const ORDERED_NODE_SNAPSHOT_TYPE = 7;
1971
- const ANY_UNORDERED_NODE_TYPE = 8;
1972
- const FIRST_ORDERED_NODE_TYPE = 9;
1973
-
1974
- function makeResult(type, items) {
1975
- return {
1976
- resultType: type,
1977
- snapshotLength: items.length,
1978
- snapshotItem: (i) => items[i] || null,
1979
- get singleNodeValue() { return items[0] || null; },
1980
- iterateNext: (() => { let i = 0; return () => items[i++] || null; })()
1981
- };
1982
- }
1983
-
1984
- doc.evaluate = function (xpath, contextNode, _resolver, type, _result) {
1985
- const root = contextNode || doc.documentElement || doc;
1986
- let nodes = [];
1987
- try {
1988
- nodes = evaluateXPathToNodes(xpath, root, xpathDomFacade, null, {
1989
- namespaceResolver: () => 'http://www.w3.org/1999/xhtml'
1990
- });
1991
- } catch (_) {
1992
- nodes = [];
1993
- }
1994
- switch (type) {
1995
- case FIRST_ORDERED_NODE_TYPE:
1996
- case ANY_UNORDERED_NODE_TYPE:
1997
- return makeResult(type, nodes.slice(0, 1));
1998
- case NUMBER_TYPE:
1999
- case STRING_TYPE:
2000
- case BOOLEAN_TYPE:
2001
- // We do not support primitive XPath results; callers fall back.
2002
- return makeResult(type, []);
2003
- default:
2004
- return makeResult(type || ORDERED_NODE_SNAPSHOT_TYPE, nodes);
2005
- }
2006
- };
2007
- }
2008
-
2009
- // Custom DOM facade for fontoxpath that uses childNodes-based traversal
2010
- // so happy-dom quirks around sibling links don't break root-anchored
2011
- // queries. Mirrors the helper we built for linkedom.
2012
- // fontoxpath calls into this facade tens of thousands of times per
2013
- // traversal, so each method needs to delegate to happy-dom's native
2014
- // pointers rather than reconstructing them. Earlier revisions of
2015
- // getNextSibling / getPreviousSibling rebuilt childNodes via
2016
- // Array.from(parent.childNodes) and then indexOf'd the node — quadratic
2017
- // in tree size, and the dominant cost on any non-trivial page.
2018
- const xpathDomFacade = {
2019
- getAllAttributes(node) {
2020
- if (!node || node.nodeType !== 1 || !node.attributes) return [];
2021
- return Array.from(node.attributes);
2022
- },
2023
- getAttribute(node, name) {
2024
- return node && node.getAttribute ? node.getAttribute(name) : null;
2025
- },
2026
- getChildNodes(node) {
2027
- if (!node) return [];
2028
- if (node.childNodes) return Array.from(node.childNodes);
2029
- if (node.nodeType === 9 && node.documentElement) return [node.documentElement];
2030
- return [];
2031
- },
2032
- getData(node) {
2033
- if (!node) return '';
2034
- if (node.nodeType === 2) return node.value || '';
2035
- return node.data || '';
2036
- },
2037
- // happy-dom 20 has a quirk on `<template>`: `template.childNodes` is
2038
- // empty (the parsed content lives in `template.content`) but
2039
- // `template.firstChild` / `template.lastChild` still return the first
2040
- // text node of `template.content`. Walking into that ghost child
2041
- // makes fontoxpath traverse content as if it were a regular descendant,
2042
- // which scrambles every predicate downstream. Verify against
2043
- // childNodes.length before trusting firstChild / lastChild.
2044
- getFirstChild(node) {
2045
- const fc = node?.firstChild ?? null;
2046
- if (!fc) return null;
2047
- const cs = node.childNodes;
2048
- if (cs && cs.length === 0) return null;
2049
- return fc;
2050
- },
2051
- getLastChild(node) {
2052
- const lc = node?.lastChild ?? null;
2053
- if (!lc) return null;
2054
- const cs = node.childNodes;
2055
- if (cs && cs.length === 0) return null;
2056
- return lc;
2057
- },
2058
- getNextSibling(node) { return node?.nextSibling ?? null; },
2059
- getPreviousSibling(node) { return node?.previousSibling ?? null; },
2060
- getParentNode(node) { return node?.parentNode ?? null; }
2061
- };
2062
-
2063
1961
  // Capybara's xpath gem produces a small set of stable XPath shapes for
2064
1962
  // its built-in selectors (link, button, link_or_button, select, option,
2065
1963
  // field, fillable_field, …). Even after the facade fix fontoxpath spends
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.5
4
+ version: 0.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Keita Urashima