ff-dom 1.0.18-beta.2 → 1.0.18-beta.3

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.
@@ -3,8 +3,8 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  const reWhiteSpace$1 = /^[\S]+( [\S]+)*$/gi;
6
+ let cspEnabled = false;
6
7
  const xpathCache$1 = {};
7
- let multiElementReferenceMode = false;
8
8
  let relativeXPathCache = new Map();
9
9
  let modifiedElementAttributes$1 = [];
10
10
  let mutationObserver;
@@ -63,7 +63,7 @@ const getTextContent = (targetElement) => {
63
63
  const getFilteredText = (element) => {
64
64
  return element?.childNodes[0]?.nodeValue || "";
65
65
  };
66
- const getCountOfXPath = (xpath, element, docmt) => {
66
+ const getCountOfXPath = (xpath, element, docmt, multiElementReferenceMode = false) => {
67
67
  try {
68
68
  let count;
69
69
  // Check if result is cached
@@ -77,7 +77,23 @@ const getCountOfXPath = (xpath, element, docmt) => {
77
77
  count = owner.evaluate(`count(${xpath})`, docmt, null, XPathResult.NUMBER_TYPE, null).numberValue;
78
78
  xpathCache$1[xpath] = count;
79
79
  }
80
- if (multiElementReferenceMode && Array.isArray(element)) ;
80
+ if (multiElementReferenceMode && Array.isArray(element)) {
81
+ if (count > 1) {
82
+ const elementsFromXpath = getElementFromXpath(xpath, docmt, true);
83
+ let nodex, matchedCount = 0;
84
+ if (elementsFromXpath instanceof XPathResult) {
85
+ while ((nodex = elementsFromXpath?.iterateNext())) {
86
+ if (element.includes(nodex)) {
87
+ matchedCount += 1;
88
+ if (matchedCount === 2)
89
+ break;
90
+ }
91
+ }
92
+ }
93
+ if (matchedCount !== 2)
94
+ return 0;
95
+ }
96
+ }
81
97
  else {
82
98
  // Short-circuit if we only need to match one element
83
99
  if (count === 1) {
@@ -216,12 +232,6 @@ const getRelationship = (a, b) => {
216
232
  ? "self"
217
233
  : "";
218
234
  };
219
- const findRoot = (node) => {
220
- while (node && node.parentNode) {
221
- node = node.parentNode;
222
- }
223
- return node;
224
- };
225
235
  const isSvg = (element) => {
226
236
  return element instanceof SVGElement;
227
237
  };
@@ -859,12 +869,12 @@ const getReferenceElementsXpath = (domNode, docmt, isTarget) => {
859
869
  }
860
870
  return xpaths1;
861
871
  };
862
- function parseXml(xmlStr) {
872
+ const parseXml = (xmlStr) => {
863
873
  if (window.DOMParser) {
864
874
  return new window.DOMParser().parseFromString(xmlStr, "text/xml");
865
875
  }
866
876
  return null;
867
- }
877
+ };
868
878
  const normalizeXPath = (xpath) => {
869
879
  // Replace text() = "value" or text()='value'
870
880
  xpath = xpath.replace(/text\(\)\s*=\s*(['"])(.*?)\1/g, "normalize-space(.)=$1$2$1");
@@ -912,6 +922,7 @@ const xpathUtils = {
912
922
  startObserver,
913
923
  stopObserver,
914
924
  modifiedElementAttributes: modifiedElementAttributes$1,
925
+ cspEnabled
915
926
  };
916
927
 
917
928
  let xpathData$1 = [];
@@ -1621,7 +1632,7 @@ const parseDOM = (element, doc, isIndex, isTarget) => {
1621
1632
  const len = xpathData$1.length;
1622
1633
  for (let i = 0; i < len; i++) {
1623
1634
  let xpth = xpathData$1[i].value;
1624
- xpth = xpth.replace(tag, "*");
1635
+ xpth = "//*" + xpth.substring(xpth.indexOf("//") + 2 + tag.length);
1625
1636
  const count = getCountOfXPath(xpth, element, docmt);
1626
1637
  if (count === 1) {
1627
1638
  xpathData$1.push({
@@ -1656,13 +1667,12 @@ const xpath = {
1656
1667
  let xpathDataWithIndex = [];
1657
1668
  let xpathData = [];
1658
1669
  const reWhiteSpace = /^[\S]+( [\S]+)*$/gi;
1659
- const findRelativeXpath = (element1, element2, docmt, xpaths1, xpaths2, isIndex) => {
1670
+ const findRelativeXpath = (element1, element2, docmt, xpaths1, xpaths2, isIndex, multiElementReferenceMode = false) => {
1660
1671
  // debugger;
1661
1672
  const par1 = element1.parentElement;
1662
1673
  const par2 = element2.parentElement;
1663
1674
  let rel_xpath = [];
1664
1675
  let tempElement;
1665
- findRoot(element1);
1666
1676
  let finalXpaths = [];
1667
1677
  if (isIndex) {
1668
1678
  if (xpathDataWithIndex.length) {
@@ -1682,14 +1692,14 @@ const findRelativeXpath = (element1, element2, docmt, xpaths1, xpaths2, isIndex)
1682
1692
  // both are same
1683
1693
  if (element1.isSameNode(element2)) {
1684
1694
  // rel_xpath = xpath1 + "/self::" + element1.tagName;
1685
- rel_xpath = getXpathRelationExpression(element1, element2, "self", xpaths1, xpaths2, isIndex);
1695
+ rel_xpath = getXpathRelationExpression(element1, element2, "self", xpaths1, xpaths2, isIndex, multiElementReferenceMode);
1686
1696
  if (rel_xpath)
1687
1697
  finalXpaths = finalXpaths.concat(rel_xpath);
1688
1698
  }
1689
1699
  // parent
1690
1700
  tempElement = element1.parentElement;
1691
1701
  if (tempElement === element2) {
1692
- rel_xpath = getXpathRelationExpression(element1, element2, "parent", xpaths1, xpaths2, isIndex);
1702
+ rel_xpath = getXpathRelationExpression(element1, element2, "parent", xpaths1, xpaths2, isIndex, multiElementReferenceMode);
1693
1703
  if (rel_xpath)
1694
1704
  finalXpaths = finalXpaths.concat(rel_xpath);
1695
1705
  }
@@ -1697,7 +1707,7 @@ const findRelativeXpath = (element1, element2, docmt, xpaths1, xpaths2, isIndex)
1697
1707
  tempElement = element1.parentElement;
1698
1708
  while (tempElement !== null) {
1699
1709
  if (tempElement === element2) {
1700
- rel_xpath = getXpathRelationExpression(element1, element2, "ancestor", xpaths1, xpaths2, isIndex);
1710
+ rel_xpath = getXpathRelationExpression(element1, element2, "ancestor", xpaths1, xpaths2, isIndex, multiElementReferenceMode);
1701
1711
  if (rel_xpath) {
1702
1712
  finalXpaths = finalXpaths.concat(rel_xpath);
1703
1713
  break;
@@ -1709,7 +1719,7 @@ const findRelativeXpath = (element1, element2, docmt, xpaths1, xpaths2, isIndex)
1709
1719
  tempElement = element1;
1710
1720
  do {
1711
1721
  if (tempElement === element2) {
1712
- rel_xpath = getXpathRelationExpression(element1, element2, "ancestor-or-self", xpaths1, xpaths2, isIndex);
1722
+ rel_xpath = getXpathRelationExpression(element1, element2, "ancestor-or-self", xpaths1, xpaths2, isIndex, multiElementReferenceMode);
1713
1723
  if (rel_xpath) {
1714
1724
  finalXpaths = finalXpaths.concat(rel_xpath);
1715
1725
  break;
@@ -1721,7 +1731,7 @@ const findRelativeXpath = (element1, element2, docmt, xpaths1, xpaths2, isIndex)
1721
1731
  if (par1?.isSameNode(par2)) {
1722
1732
  for (let m = element1.nextElementSibling; m != null; m = m.nextElementSibling) {
1723
1733
  if (m != null && m.isSameNode(element2)) {
1724
- rel_xpath = getXpathRelationExpression(element1, element2, "following-sibling", xpaths1, xpaths2, isIndex);
1734
+ rel_xpath = getXpathRelationExpression(element1, element2, "following-sibling", xpaths1, xpaths2, isIndex, multiElementReferenceMode);
1725
1735
  if (rel_xpath) {
1726
1736
  finalXpaths = finalXpaths.concat(rel_xpath);
1727
1737
  break;
@@ -1730,7 +1740,7 @@ const findRelativeXpath = (element1, element2, docmt, xpaths1, xpaths2, isIndex)
1730
1740
  }
1731
1741
  for (let n = element1.previousElementSibling; n != null; n = n.previousElementSibling) {
1732
1742
  if (n != null && n.isSameNode(element2)) {
1733
- rel_xpath = getXpathRelationExpression(element1, element2, "preceding-sibling", xpaths1, xpaths2, isIndex);
1743
+ rel_xpath = getXpathRelationExpression(element1, element2, "preceding-sibling", xpaths1, xpaths2, isIndex, multiElementReferenceMode);
1734
1744
  if (rel_xpath) {
1735
1745
  finalXpaths = finalXpaths.concat(rel_xpath);
1736
1746
  break;
@@ -1742,7 +1752,7 @@ const findRelativeXpath = (element1, element2, docmt, xpaths1, xpaths2, isIndex)
1742
1752
  if (element1?.children?.length) {
1743
1753
  for (let m = element1.children[0]; m !== null; m = m?.nextElementSibling) {
1744
1754
  if (m === element2) {
1745
- rel_xpath = getXpathRelationExpression(element1, element2, "child", xpaths1, xpaths2, isIndex);
1755
+ rel_xpath = getXpathRelationExpression(element1, element2, "child", xpaths1, xpaths2, isIndex, multiElementReferenceMode);
1746
1756
  if (rel_xpath) {
1747
1757
  finalXpaths = finalXpaths.concat(rel_xpath);
1748
1758
  break;
@@ -1753,18 +1763,18 @@ const findRelativeXpath = (element1, element2, docmt, xpaths1, xpaths2, isIndex)
1753
1763
  // following
1754
1764
  const relation = element1.compareDocumentPosition(element2);
1755
1765
  if (relation === 2) {
1756
- rel_xpath = getXpathRelationExpression(element1, element2, "preceding", xpaths1, xpaths2, isIndex);
1766
+ rel_xpath = getXpathRelationExpression(element1, element2, "preceding", xpaths1, xpaths2, isIndex, multiElementReferenceMode);
1757
1767
  }
1758
1768
  if (relation === 4) {
1759
- rel_xpath = getXpathRelationExpression(element1, element2, "following", xpaths1, xpaths2, isIndex);
1769
+ rel_xpath = getXpathRelationExpression(element1, element2, "following", xpaths1, xpaths2, isIndex, multiElementReferenceMode);
1760
1770
  }
1761
1771
  if (rel_xpath) {
1762
1772
  finalXpaths = finalXpaths.concat(rel_xpath);
1763
1773
  }
1764
- const descendantXpath = getDescendantXpath([element1, element2], docmt, xpaths1, xpaths2, "descendant", isIndex);
1774
+ const descendantXpath = getDescendantXpath([element1, element2], docmt, xpaths1, xpaths2, "descendant", isIndex, multiElementReferenceMode);
1765
1775
  if (descendantXpath)
1766
1776
  finalXpaths = finalXpaths.concat(descendantXpath);
1767
- const descendantSelfXpath = getDescendantXpath([element1, element2], docmt, xpaths1, xpaths2, "descedant-or-self", isIndex);
1777
+ const descendantSelfXpath = getDescendantXpath([element1, element2], docmt, xpaths1, xpaths2, "descedant-or-self", isIndex, multiElementReferenceMode);
1768
1778
  if (descendantSelfXpath) {
1769
1779
  finalXpaths = finalXpaths.concat(descendantSelfXpath);
1770
1780
  }
@@ -1781,7 +1791,7 @@ const findRelativeXpath = (element1, element2, docmt, xpaths1, xpaths2, isIndex)
1781
1791
  return [finalXpaths[0]];
1782
1792
  }
1783
1793
  };
1784
- const descendantExpression = (refExpectElement, xpath2, relation, docmt, isIndex, expCommonParentXpathElements, step4, refCommonParentXpathElementLength) => {
1794
+ const descendantExpression = (refExpectElement, xpath2, relation, docmt, isIndex, expCommonParentXpathElements, step4, refCommonParentXpathElementLength = 0, multiElementReferenceMode = false) => {
1785
1795
  let finalExpectedElementXpath = "";
1786
1796
  if (xpath2.split(/\/(?=(?:[^']*\'[^\']*\')*[^\']*$)/g)?.length >=
1787
1797
  expCommonParentXpathElements.length) {
@@ -1795,7 +1805,7 @@ const descendantExpression = (refExpectElement, xpath2, relation, docmt, isIndex
1795
1805
  const traverseXpath = getTraverseXpathExpression(`${step4 +
1796
1806
  (refCommonParentXpathElementLength
1797
1807
  ? "]".repeat(refCommonParentXpathElementLength)
1798
- : "")}`, xpaths2Els, refExpectElement[refExpectElement.length - 1], refExpectElement, docmt, relation, isIndex);
1808
+ : "")}`, xpaths2Els, refExpectElement[refExpectElement.length - 1], refExpectElement, docmt, relation, isIndex, multiElementReferenceMode);
1799
1809
  if (traverseXpath) {
1800
1810
  return traverseXpath;
1801
1811
  }
@@ -1832,7 +1842,7 @@ const descendantExpression = (refExpectElement, xpath2, relation, docmt, isIndex
1832
1842
  }
1833
1843
  }
1834
1844
  };
1835
- const getDescendantXpath = (refExpectElement, docmt, xpaths1, xpaths2, relation, isIndex) => {
1845
+ const getDescendantXpath = (refExpectElement, docmt, xpaths1, xpaths2, relation, isIndex = false, multiElementReferenceMode = false) => {
1836
1846
  const refElement = refExpectElement[refExpectElement.length - 2];
1837
1847
  const expElement = refExpectElement[refExpectElement.length - 1];
1838
1848
  const expElementDocmnt = getShadowRoot(expElement) ?? expElement.ownerDocument;
@@ -1896,7 +1906,7 @@ const getDescendantXpath = (refExpectElement, docmt, xpaths1, xpaths2, relation,
1896
1906
  xpath2 = xpathData[i].value; // No need to modify the value
1897
1907
  }
1898
1908
  if (xpath2) {
1899
- return descendantExpression(refExpectElement, xpath2, relation, expElementDocmnt || docmt, isIndex, expCommonParentXpathElements, step4, refCommonParentXpathElementLength);
1909
+ return descendantExpression(refExpectElement, xpath2, relation, expElementDocmnt || docmt, isIndex, expCommonParentXpathElements, step4, refCommonParentXpathElementLength, multiElementReferenceMode);
1900
1910
  }
1901
1911
  }
1902
1912
  }
@@ -1923,7 +1933,7 @@ const getDescendantXpath = (refExpectElement, docmt, xpaths1, xpaths2, relation,
1923
1933
  else {
1924
1934
  xpath2 = xpathData[i].value; // No need to modify the value
1925
1935
  }
1926
- return descendantExpression(refExpectElement, xpath2, relation, expElementDocmnt || docmt, isIndex, expCommonParentXpathElements, step4, refCommonParentXpathElementLength);
1936
+ return descendantExpression(refExpectElement, xpath2, relation, expElementDocmnt || docmt, isIndex, expCommonParentXpathElements, step4, refCommonParentXpathElementLength, multiElementReferenceMode);
1927
1937
  }
1928
1938
  }
1929
1939
  }
@@ -1954,7 +1964,7 @@ const getDescendantXpath = (refExpectElement, docmt, xpaths1, xpaths2, relation,
1954
1964
  else {
1955
1965
  xpath2 = xpathData[i].value; // No need to modify the value
1956
1966
  }
1957
- return descendantExpression(refExpectElement, xpath2, relation, expElementDocmnt || docmt, isIndex, expCommonParentXpathElements, step4, refCommonParentXpathElementLength);
1967
+ return descendantExpression(refExpectElement, xpath2, relation, expElementDocmnt || docmt, isIndex, expCommonParentXpathElements, step4, refCommonParentXpathElementLength, multiElementReferenceMode);
1958
1968
  }
1959
1969
  }
1960
1970
  }
@@ -1967,12 +1977,12 @@ const getDescendantXpath = (refExpectElement, docmt, xpaths1, xpaths2, relation,
1967
1977
  const traverseXpath = getTraverseXpathExpression(`${step4 +
1968
1978
  (refCommonParentXpathElementLength
1969
1979
  ? "]".repeat(refCommonParentXpathElementLength)
1970
- : "")}`, expCommonParentXpathElements.reverse(), refExpectElement[refExpectElement.length - 1], refExpectElement, docmt, relation, isIndex);
1980
+ : "")}`, expCommonParentXpathElements, refExpectElement[refExpectElement.length - 1], refExpectElement, docmt, relation, isIndex, multiElementReferenceMode);
1971
1981
  if (traverseXpath) {
1972
1982
  return traverseXpath;
1973
1983
  }
1974
1984
  };
1975
- const getXpathRelationExpression = (element1, element2, relation, xpath1, xpath2, isIndex) => {
1985
+ const getXpathRelationExpression = (element1, element2, relation, xpath1, xpath2, isIndex, multiElementReferenceMode) => {
1976
1986
  let xpaths1;
1977
1987
  let xpaths2;
1978
1988
  console.log('getXpathRelationExpression', relation);
@@ -2039,7 +2049,7 @@ const getXpathRelationExpression = (element1, element2, relation, xpath1, xpath2
2039
2049
  if (xpath2Elements.length > 1) {
2040
2050
  const traverseXpath = getTraverseXpathExpression(`${xpaths1[i].value.indexOf("//") !== 0
2041
2051
  ? replaceActualAttributes(xpaths1[i].value, element1)
2042
- : replaceActualAttributes(xpaths1[i].value.substring(xpaths1[i].value.indexOf("//") + 2), element1)}`, xpath2Elements, element2, [element1, element2], element2.ownerDocument, relation, isIndex);
2052
+ : replaceActualAttributes(xpaths1[i].value.substring(xpaths1[i].value.indexOf("//") + 2), element1)}`, xpath2Elements, element2, [element1, element2], element2.ownerDocument, relation, isIndex, multiElementReferenceMode);
2043
2053
  console.log('getXpathRelationExpression traverseXpath', traverseXpath);
2044
2054
  if (traverseXpath) {
2045
2055
  finalXpaths.concat(traverseXpath);
@@ -2112,9 +2122,9 @@ const getReferenceElementXpath = (element) => {
2112
2122
  });
2113
2123
  return xpaths1;
2114
2124
  };
2115
- const getTraverseXpathExpression = (xpathe1, absoluteXpathElements, element2, refExpectElement, docmt, relation, isIndex) => {
2125
+ const getTraverseXpathExpression = (xpathe1, absoluteXpathElements, element2, refExpectElement, docmt, relation, isIndex, multiElementReferenceMode) => {
2116
2126
  let finalExpectedElementXpath;
2117
- {
2127
+ if (!multiElementReferenceMode) {
2118
2128
  for (let x = 1; x <= absoluteXpathElements.length; x++) {
2119
2129
  const xpath2 = absoluteXpathElements
2120
2130
  .slice(absoluteXpathElements.length - x, absoluteXpathElements.length)
@@ -2144,6 +2154,32 @@ const getTraverseXpathExpression = (xpathe1, absoluteXpathElements, element2, re
2144
2154
  }
2145
2155
  }
2146
2156
  }
2157
+ else {
2158
+ const xpath2 = absoluteXpathElements.join("/");
2159
+ finalExpectedElementXpath = `//${xpathe1}/${relation}::${replaceActualAttributes(xpath2)}`;
2160
+ const rel_count = getCountOfXPath(finalExpectedElementXpath, element2, docmt);
2161
+ if (rel_count === 1) {
2162
+ return [
2163
+ {
2164
+ key: `dynamic ${relation}`,
2165
+ value: replaceTempAttributes(finalExpectedElementXpath),
2166
+ },
2167
+ ];
2168
+ }
2169
+ if (rel_count > 1) {
2170
+ if (isIndex) {
2171
+ finalExpectedElementXpath = findXpathWithIndex(finalExpectedElementXpath, refExpectElement[refExpectElement.length - 1], docmt, rel_count);
2172
+ if (finalExpectedElementXpath) {
2173
+ return [
2174
+ {
2175
+ key: `dynamic ${relation}${isIndex ? " index" : ""}`,
2176
+ value: replaceTempAttributes(finalExpectedElementXpath),
2177
+ },
2178
+ ];
2179
+ }
2180
+ }
2181
+ }
2182
+ }
2147
2183
  };
2148
2184
  const referenceXpath = {
2149
2185
  findRelativeXpath,